Based on *.blend file I have to write a script that gets informations about objects and saves them to json. This script can be opened in Blender, or running. The launch should save the json file with the data in the current directory.
So I created this:
import bpy
import json
objects = bpy.context.scene.objects
data = {}
for ob in objects:
item = {}
item['location'] = ob.location
if ob.name == 'Cube':
item['material_name'] = ob.active_material.name
data[ob.name] = item
elif ob.name == 'Camera':
item['camera_type'] = ob.data.type
data[ob.name] = item
elif ob.name == 'Lamp':
item['lamp_type'] = ob.data.type
data[ob.name] = item
with open('scene_objects.json', 'w') as json_file:
json.dump(data, json_file)
However, when I run the script in Blender, I received the following error:
PermissionError: [Errno 13] Permission denied: 'scene_objects.json'
I'm a beginner in using Blender so maybe it's impossible to write to file from Blender? However, if I can do it, I am asking for advice on how?
Your issue isn't with blender, the OS is preventing the creation (or writability) of the file based on file system permissions.
The line -
with open('scene_objects.json', 'w') as json_file:
will create a new file (or open existing) in the current working directory. When running blender that could be one of several options, depending on which OS you are using. It is also possible that starting blender from a GUI can leave you without a valid CWD, or a temporary dir that a user does not have permission to write to.
You can use os.chdir() to change the CWD to one that you know exists and that you can write to. You can also specify a full path instead of just a filename.
Related
I have a function that should create a VBScript and save (overwrite) the Excel file, specified in this script with a password on modifying.
The function:
def setPassword(self, excel_file_path, password):
"""Locks excel file with password. Modification allowed only when password is entered"""
excel_file_path = Path(excel_file_path)
vbs_script = \
f"""' Save with password required upon opening
Set excel_object = CreateObject("Excel.Application")
Set workbook = excel_object.Workbooks.Open(FileName:="{excel_file_path}", ReadOnly:=False, Notify:=False)
excel_object.DisplayAlerts = False
excel_object.Visible = False
workbook.SaveAs "{excel_file_path}",,, "{password}"
excel_object.Application.Quit
"""
# write
vbs_script_path = excel_file_path.parent.joinpath("set_password.vbs")
with open(vbs_script_path, "w") as file:
file.write(vbs_script)
# execute
result = subprocess.Popen(['cscript.exe', str(vbs_script_path)], creationflags=subprocess.CREATE_NO_WINDOW, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, err = result.communicate()
res = {
"result": output.decode(encoding='cp866'),
"err": self._errMessage(err.decode(encoding='cp866'))
}
# remove
vbs_script_path.unlink()
return res
The issue is that on my PC it does it correctly. However, if I run it on my work PC, the VBS throws an exception that it can't access the file when trying to save it.
If I use a different name to save the file with password, it works just fine.
Sure, I could save the file with a different name, delete the initial file and then rename the new file. But it is a duck tape and I want a good solution.
PS
I saw information that it is impossible to overwrite the file this way. But since it works on one computer, I suppose there should be a way to make it work on another.
PPS
Inserting this XlSaveConflictResolution argument into the save func didn't help as well
What is wrong with this VBS and how to make it work properly?
Solved it by saving the file under a new name, then deleting the initial file and renaming the new file with the initial name.
For example, I have a file named foo.xlsx. I run the script and save the processed file as foe.xlsx. Then I delete foo.xlsx with os.os.unlink(). Finally, I rename the foe.xlsx back to foo.xlsx with os.rename()
Hope one day this helps someone
I have been struggling with this problem for a while but can't seem to find a solution for it. The situation is that I need to open a file in browser and after the user closes the file the file is removed from their machine. All I have is the binary data for that file. If it matters, the binary data comes from Google Storage using the download_as_string method.
After doing some research I found that the tempfile module would suit my needs, but I can't get the tempfile to open in browser because the file only exists in memory and not on the disk. Any suggestions on how to solve this?
This is my code so far:
import tempfile
import webbrowser
# grabbing binary data earlier on
temp = tempfile.NamedTemporaryFile()
temp.name = "example.pdf"
temp.write(binary_data_obj)
temp.close()
webbrowser.open('file://' + os.path.realpath(temp.name))
When this is run, my computer gives me an error that says that the file cannot be opened since it is empty. I am on a Mac and am using Chrome if that is relevant.
You could try using a temporary directory instead:
import os
import tempfile
import webbrowser
# I used an existing pdf I had laying around as sample data
with open('c.pdf', 'rb') as fh:
data = fh.read()
# Gives a temporary directory you have write permissions to.
# The directory and files within will be deleted when the with context exits.
with tempfile.TemporaryDirectory() as temp_dir:
temp_file_path = os.path.join(temp_dir, 'example.pdf')
# write a normal file within the temp directory
with open(temp_file_path, 'wb+') as fh:
fh.write(data)
webbrowser.open('file://' + temp_file_path)
This worked for me on Mac OS.
I am splitting a large wordlist by length of the word
i didn't find a different approach for it so i decided to write a script in python for it.
say test.txt has
word
words
i want it to make new text files based on length of line and write the line to it
4.txt
word
5.txt
words
CODE
import os
import sys
basefile = open(sys.argv[1],'rt')
print("Writing.....")
os.mkdir(str(os.path.splitext(sys.argv[1])[0]))
os.chdir(os.path.splitext(sys.argv[1])[0])
#print(basefile)
for line in basefile:
cpyfile=open(str(len(line.strip()))+'.txt',mode = 'a',encoding = 'utf-8')
cpyfile.write(line)
cpyfile.close()
print("Done")
basefile.close()
It works for small files but for larger files it gives out an error after a while
PermissionError: [Errno 13] Permission denied: '10.txt'
or
PermissionError: [Errno 13] Permission denied: '11.txt'
the error file is completely random too and the previous lines written are perfectly okay.
I have tried it on windows using powershell and using gitbash
Any help is appreciated and thanks
I suspect you are running into the issue that Windows does not allow two programs to open the same file at once. I'm not sure what the second program would be. Maybe a virus scanner? Your program works unaltered on Ubuntu using /usr/share/dict/american-english, so I think this may be a Windows thing.
In any case, I think you can solve this by keeping the files open while the program is running.
import os
import sys
basefile = open(sys.argv[1], 'rt')
print("Writing.....")
os.mkdir(str(os.path.splitext(sys.argv[1])[0]))
os.chdir(os.path.splitext(sys.argv[1])[0])
# print(basefile)
files = {}
try:
for line in basefile:
cpyfilename = str(len(line.strip()))+'.txt'
cpyfile = files.get(cpyfilename)
if cpyfile is None:
cpyfile = open(cpyfilename, mode='a', encoding='utf-8')
files[cpyfilename] = cpyfile
cpyfile.write(line)
finally:
for cpyfile in files.values():
# Not strictly necessary because the program is about to end and
# auto-close the files.
cpyfile.close()
print("Done")
basefile.close()
In my code, user uploads file which is saved on server and read using the server path. I'm trying to delete the file from that path after I'm done reading it. But it gives me following error instead:
An error occurred while reading file. [WinError 32] The process cannot access the file because it is being used by another process
I'm reading file using with, and I've tried f.close() and also f.closed but its the same error every time.
This is my code:
f = open(filePath)
with f:
line = f.readline().strip()
tempLst = line.split(fileSeparator)
if(len(lstHeader) != len(tempLst)):
headerErrorMsg = "invalid headers"
hjsonObj["Line No."] = 1
hjsonObj["Error Detail"] = headerErrorMsg
data['lstErrorData'].append(hjsonObj)
data["status"] = True
f.closed
return data
f.closed
after this code I call the remove function:
os.remove(filePath)
Edit: using with open(filePath) as f: and then trying to remove the file gives the same error.
Instead of:
f.closed
You need to say:
f.close()
closed is just a boolean property on the file object to indicate if the file is actually closed.
close() is method on the file object that actually closes the file.
Side note: attempting a file delete after closing a file handle is not 100% reliable. The file might still be getting scanned by the virus scanner or indexer. Or some other system hook is holding on to the file reference, etc... If the delete fails, wait a second and try again.
Use below code:
import os
os.startfile('your_file.py')
To delete after completion:
os.remove('your_file.py')
This
import os
path = 'path/to/file'
with open(path) as f:
for l in f:
print l,
os.remove(path)
should work, with statement will automatically close the file after the nested block of code
if it fails, File could be in use by some external factor. you can use Redo pattern.
while True:
try:
os.remove(path)
break
except:
time.sleep(1)
There is probably an application that is opening the file; check and close the application before executing your code:
os.remove(file_path)
Delete files that are not used by another application.
I'm new to python and the following piece of code is driving me crazy. It lists the files in a directory and for each file does some stuff. I get a IOError: [Errno2] No such file or directory: my_file_that_is_actually_there!
def loadFile(aFile):
f_gz = gzip.open(aFile, 'rb')
data = f_gz.read()
#do some stuff...
f_gz.close()
return data
def main():
inputFolder = '../myFolder/'
for aFile in os.listdir(inputFolder):
data = loadFile(aFile)
#do some more stuff
The file exists and it's not corrupted. I do not understand how it's possible that python first finds the file when it checks the content of myFolder, and then it cannot find itanymore... This happens on the second iteration of my for loop only with any files.
NOTE: Why does this exception happen ONLY at the second iteration of the loop?? The first file in the folder is found and opened without any issues...
This is because open receives the local name (returned from os.listdir). It doesn't know that you mean that it should look in ../myFolder. So it receives a relative path and applies it to the current dir. To fix it, try:
data = loadFile(os.path.join(inputFolder, aFile))