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
Related
I have the following code to get messages from group:
getmessage = client.get_messages(dialog, limit=1000)
for message in getmessage:
try:
if message.media == None:
print("message")
continue
else:
print("Media**********")
client.download_media(message)
The code above write the media.
I need to know the file name/file type before I write the file, How can I get it?
You can use a filename of your choosing to ensure that said filename will be used:
filename = 'some-file'
filename = client.download_media(message, filename)
Then filename will be some-file with the correct extension.
Otherwise, Telethon will generate a file name for the file (it will try the original name, and if it exists, append (n) to avoid overwriting existing files), so you can't really know where it will be saved beforehand (but the method does return the final filename).
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.
I am trying to send each file from a disk image to a remote server using paramiko.
class Server:
def __init__(self):
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.ssh.connect('xxx', username='xxx', password='xxx')
def send_file(self, i_node, name):
sftp = self.ssh.open_sftp()
serverpath = '/home/paul/Testing/'
try:
sftp.chdir(serverpath)
except IOError:
sftp.mkdir(serverpath)
sftp.chdir(serverpath)
serverpath = '/home/Testing/' + name
sftp.putfo(fs.open_meta(inode = i_node), serverpath)
However when I run this I get an error saying that "pytsk.File has no attribute read".
Is there any other way of sending this file to the server?
After a quick investigation I think I found what your problem is. Paramiko's sftp.putfo expects a Python file object as the first parameter. The file object of Pytsk3 is a completely different thing. Your sftp object tries to perform "read" on this, but Pytsk3 file object does not have a method "read", hence the error.
You could in theory try expanding Pytsk3.File class and adding this method but I would not hold my breath that it actually works.
I would just read the file to a temporary one and send that. Something like this (you would need to make temp file name handling more clever and delete the file afterwards but you will get the idea):
serverpath = '/home/Testing/' + name
tmp_path = "/tmp/xyzzy"
file_obj = fs.open_meta(inode = i_node)
# Add here tests to confirm this is actually a file, not a directory
tha = open(tmp_path, "wb")
tha.write(file_obj.read_random(0, file_obj.info.meta.size))
tha.close()
rha = open(tmp_path, "rb")
sftp.putfo(rha, serverpath)
rha.close()
# Delete temp file here
Hope this helps. This will read the whole file in memory from fs image to be written to temp file, so if the file is massive you would run out of memory.
To work around that, you should read the file in chunks looping through it with read_random in suitable chunks (the parameters are start offset and amount of data to read), allowing you to construct the temp file in a chunks of for example a couple of megabytes.
This is just a simple example to illustrate your problem.
Hannu
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))
I am working on python and biopython right now. I have a file upload form and whatever file is uploaded suppose(abc.fasta) then i want to pass same name in execute (abc.fasta) function parameter and display function parameter (abc.aln). Right now i am changing file name manually, but i want to have it automatically.
Workflow goes like this.
----If submit is not true then display only header and form part
--- if submit is true then call execute() and get file name from form input
--- Then displaying result file name is same as executed file name but only change in extension
My raw code is here -- http://pastebin.com/FPUgZSSe
Any suggestions, changes and algorithm is appreciated
Thanks
You need to read the uploaded file out of the cgi.FieldStorage() and save it onto the server. Ususally a temp directory (/tmp on Linux) is used for this. You should remove these files after processing or on some schedule to clean up the drive.
def main():
import cgi
import cgitb; cgitb.enable()
f1 = cgi.FieldStorage()
if "dfile" in f1:
fileitem = f1["dfile"]
pathtoTmpFile = os.path.join("path/to/temp/directory", fileitem.filename)
fout = file(pathtoTmpFile, 'wb')
while 1:
chunk = fileitem.file.read(100000)
if not chunk: break
fout.write (chunk)
fout.close()
execute(pathtoTmpFile)
os.remove(pathtoTmpFile)
else:
header()
form()
This modified the execute to take the path to the newly saved file.
cline = ClustalwCommandline("clustalw", infile=pathToFile)
For the result file, you could also stream it back so the user gets a "Save as..." dialog. That might be a little more usable than displaying it in HTML.