Reputation: 21
I'm writing a function that decrypts encrypted word files. I am using the MSOffCrypto package. I would like the function to decrypt the file if it is encrypted and to create the decrypted file in a new folder. I would like for the program to close the file and delete it. If the file is not encrypted, I would like for the program to move the original file to the same folder as the decrypted files. Here is what I have written so far:
def DecryptFile(listdir):
#Create a new directory for decrypted report files.
#Decryption is necessary to scrape embedded documents.
DecryptReportPath = dir + "\\ParentReportFiles\\"
os.mkdir(DecryptReportPath)
#Loop iterates through each file in the selected directory
for filename in listdir:
if (filename[-3:] == 'doc') | (filename[-4:] == 'docx'):
p = Path(filename)
PathParts = p.parts
try:
#Try to decrypt the MSOffice File.
try:
file = msoffcrypto.OfficeFile(open(filename, "rb"))
if file.is_encrypted():
# Use password
file.load_key(password="Viking1234!")
#Create the decrypted file in a new folder called ParentReportFiles
file.decrypt(open(DecryptReportPath + PathParts[-1][0:-5] + "decrypted.docx", "wb"))
file.close()
os.remove(filename)
else:
file.close()
os.rename(filename, DecryptReportPath+PathParts[-1])
except:
traceback.print_exc()
continue
except:
print("File is not doc")
The problem is that I get the following error message:
Traceback (most recent call last):
File "C:/Users/.../Filing Master File 16 Dec 20.py", line 37, in DecryptFile
file.close()
AttributeError: 'OOXMLFile' object has no attribute 'close'
Without the file.close() line, I get the following error:
Traceback (most recent call last):
File "C:/Users/.../Filing Master File 16 Dec 20.py", line 38, in DecryptFile
os.remove(filename)
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\...\\myfile.docx'
I've tried to substitute file.close() with os.close(file), but it doesn't work either:
Traceback (most recent call last):
File "C:/Users/.../Filing Master File 16 Dec 20.py", line 37, in DecryptFile
os.close(file)
TypeError: an integer is required (got type OOXMLFile)
Please advise, thank you very much!
Upvotes: 0
Views: 861
Reputation: 5709
I guess the problem is here
file = msoffcrypto.OfficeFile(open(filename, "rb"))
msoffcrypto.OfficeFile
does not return a file-like object which implements close()
method, but object of type OOXMLFile
Most probably what you wanted to close was result of open(filename, "rb")
operation. So what I would try is
org_file = open(filename, "rb")
file = msoffcrypti.OfficeFile(org_file)
...
org_file.close()
Please also take a note that you can use open
operation as a contex manager and simply don't care explicit closing files. It would be:
with open(filename, "rb") as org_file:
file = msoffcrypti.OfficeFile(org_file)
...
os.remove(filename)
Upvotes: 2