1
$\begingroup$

I want to write a script that saves all the text files inside a Blender file. Is there a way I can access the text files as a list and then select them individually?

Heres my script so far:

import bpy
import datetime

file_destination = 'D:\\Sync Cloud\\Sync\\BLENDER PYTHON SCRIPTS\\Mass Saves By Date'

# GET SCRIPTS
all_scripts = bpy.data.texts
num_of_scripts = int((str(all_scripts).split('[')[1]).split(']')[0])

# GET DATE AND TIME
now = datetime.datetime.now()
date = str(now).split(' ')[0]
time = (str(now).split(' ')[1]).split('.')[0]

# GET BLENDER FILE NAME
path = str(bpy.data.filepath).split('\\')
file_path_num = len(path) - 1
file_name = path[file_path_num].split('.blend')[0]

i=0
for x in range(0,num_of_scripts):
    txt_script = bpy.data.texts[i]

    # DELETE A .py
    script_name = (str(txt_script).split("\"")[1]).split('.py')[0]
    if 'Text' not in script_name:

        py_filename = date +'_'+time+'_'+file_name+'_'+script_name+'.py'

        # SAVE SCRIPT
        bpy.ops.text.save_as(filepath=str(file_destination)+'\\'+str(py_filename),
        hide_props_region=True,
        check_existing=True,
        filter_blender=False,
        filter_backup=False,
        filter_image=False,
        filter_movie=False,
        filter_python=True,
        filter_font=False,
        filter_sound=False,
        filter_text=True,
        filter_archive=False,
        filter_btx=False,
        filter_collada=False,
        filter_alembic=False,
        filter_usd=False,
        filter_folder=True,
        filter_blenlib=False,
        filemode=9,
        display_type='DEFAULT',
        sort_method='FILE_SORT_ALPHA')

    i+=1

This keeps giving me an error:

Error: Unable to save '': Invalid argument Traceback (most recent call last): File "D:\Sync Cloud\Sync\BLENDER PYTHON SCRIPTS\Save Scripts.blend\Export Scripts.py", line 43, in File "C:\Program Files\Blender Foundation\Blender 2.82\2.82\scripts\modules\bpy\ops.py", line 201, in call ret = op_call(self.idname_py(), None, kw) RuntimeError: Error: Unable to save '': Invalid argument

Error: Python script failed, check the message in the system console

$\endgroup$
  • 1
    $\begingroup$ Sure. bpy.data.texts returns a collection of all text files created. Can you elaborate what you'd like to do? Text files going to be stored to the blend by default so I don't get your q. $\endgroup$ – brockmann Feb 18 at 22:50
  • $\begingroup$ Thank you! this is what I needed. I'm writing a script to save all my scripts in a blender file. $\endgroup$ – TYLRwithspaces Feb 19 at 2:33
  • $\begingroup$ They are already stored per .blend, I don't get your idea. Why you need to save them twice? I'd suggest add the current state of your code to the post so we can have a look at @TYLRwithspaces $\endgroup$ – brockmann Feb 19 at 9:51
  • $\begingroup$ @brockmann I updated the post with my script. I keep getting that error, should I make a new post? I'm new here. Im new to scripting in blender and python but ive been writing a lot of scripts across a bunch of different blender files for a project. I've been updating the scripts as I go, its been a learning process so sometimes I mess things up. I want to use this as a way to easily backup all my scripts. $\endgroup$ – TYLRwithspaces Feb 20 at 1:58
3
$\begingroup$

Pathlib

Here is a script that writes all text files in blend with suffix .py to a designated folder.

IMO there is no need to timestamp a file name, since it is given a date when written to or touched. Timestamp a containing folder name if need be.

import bpy
from pathlib import Path

destination_folder = "/tmp/texts"
df = Path(destination_folder)

#create if doesn't exist
if not df.exists():
    df.mkdir(parents=True, exist_ok=True)

for text in bpy.data.texts:
    p = df / text.name
    if p.suffix == ".py":
        p.write_text(text.as_string())

On getting the path from the blend file name

>>> bpy.data.filepath
'/home/batfinger/Documents/blender/tests/snurf.blend'

>>> Path(bpy.data.filepath)
PosixPath('/home/batfinger/Documents/blender/tests/snurf.blend')

>>> bp = Path(bpy.data.filepath)

>>> bp.stem
'snurf'

If the file is new and has not been saved the datapath will be "". The folder will revert to the base path blender was started from. In my case blender was launched from the terminal in the folder "foo".

>>> dp = Path('')
>>> dp
PosixPath('.')

>>> dp.absolute()
PosixPath('/home/batfinger/foo')
| improve this answer | |
$\endgroup$
  • $\begingroup$ Thanks, this helped a lot. But I'm getting an error when I try to make the directory. <<File "C:\Program Files\Blender Foundation\Blender 2.82\2.82\python\lib\pathlib.py", line 1258, in mkdir self._accessor.mkdir(self, mode) NotADirectoryError: [WinError 267] The directory name is invalid: 'D:\\Sync Cloud\\Sync\\BLENDER PYTHON SCRIPTS\\Mass Saves By Date\\Save Scripts\\Save Scripts_2020-02-21_15:23' Error: Python script failed, check the message in the system console>> $\endgroup$ – TYLRwithspaces Feb 21 at 20:26
  • $\begingroup$ Actually i figured it out $\endgroup$ – TYLRwithspaces Feb 21 at 20:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.