Python etree xml write issues - python

I'm trying to write multiple files to a directory with very little changed in between each file (eg. incremental id numbers) When I try run my program, it fails after writing about 5 files. But when I try it again and re-select the source file, it works. Here's my code:
if not os.path.isdir(self.fDirectory + "/AutoGen" + strftime("%Y-%m-%d %H:%M:%S", gmtime())):
os.mkdir(self.fDirectory + "/AutoGen" + strftime("%Y-%m-%d_%H.%M.%S", gmtime()))
anum = 0
for x in range(len(self.csvdata)-1):
for y in range(len(self.csvdata[x+1])):
self.myRoot.find(self.csvdata[0][y]).text = self.csvdata[x][y]
anum+=1
myTree.write(self.fDirectory + "/AutoGen" + strftime("%Y-%m-%d_%H.%M.%S", gmtime()) + "/" + self.filename + "_" + str(anum) + ".xml")
And here's the error I'm getting:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python32\lib\tkinter\__init__.py", line 1399, in __call__
return self.func(*args)
File "C:\Users\CNash\Documents\XML Generator\XMLGen.py", line 148, in doIt
myTree.write(self.fDirectory + "/AutoGen" + strftime("%Y-%m-%d_%H.%M.%S", gmtime()) + "/" + self.filename + "_" + str(anum) + ".xml")
File "C:\Python32\lib\xml\etree\ElementTree.py", line 836, in write
file = open(file_or_filename, "wb")
IOError: [Errno 2] No such file or directory: 'C:/Users/CNash/Documents/XML Generator/AutoGen2012-07-31_20.23.52/EXuTest_DOCD00140_6.xml'
Any ideas much appreciated!

For one, use os.path.join, it will make your life easier.
And it looks to me that the first and last calls to strftime happen at different times (and you left out an underscore in your first one). The script can't find the directory, because it doesn't exist. One named with a time a few seconds before probably, even suspiciously, does, I bet.
Try replacing your first if-statement with
dirname = os.path.join(self.fDirectory,strftime("AutoGen%Y-%m-%d_%H.%M.%S",gmtime()))
if not os.path.isdir(dirname):
os.mkdir(dirname)
and the last line with:
myTree.write(os.path.join(dirname, self.filename + "_" + str(anum) + ".xml"))

Related

How to make a file with a variable as the name

I am trying to make a log file for my application but when I try to make the file with a variable as the name I get a "FileNotFound" error.
Example:
log_file_name = str("log" + "/" + str(current_time.month) + "/" + str(current_time.day) + "/" + str(current_time.year) + ".txt")
log_txt = open(log_file_name, "a")
This gives me a FileNotFound error like this
Traceback (most recent call last):
File "C:\Users\taco\PycharmProjects\pythonProject\mygame.py", line 7, in <module>
log_txt = open(log_file_name, "a")
FileNotFoundError: [Errno 2] No such file or directory: 'log/8/14/2022.txt'
The below method would give me the same error.
log_txt = open (str("log" + "/" + str(current_time.month) + "/" + str(current_time.day) + "/" + str(current_time.year)) + ".txt", "a")
But if I do something simple like this it creates the file as it should:
log_txt = open("log.txt", "a")
Edit I forgot to add that the same happens above when using "a+" instead of "a"
Firstly, instead of concatenating multiple strings, just use f-string which would make your code look something like this:
log_file_name = f"log/{current_time.month}/{current_time.day}/{current_time.year}.txt")
It does the same thing but is a bit easier on the eyes.
Now to answer your question, the reason you're getting this exception is you're using / to seperate the variables which would trick python into thinking the variables are directories.
To fix this, remove the / in your filename string, so that it would look like this:
f"log{current_time.month}{current_time.day}{current_time.year}.txt"

Python: Check if files exist and copy only the missing files

I'm a begynder in python and trying to make a script that does the following:
Check number of files, if they exist in the destFile
If they all exist, exit the script (don't do anything)
If some files are missing, copy only the missing files from the srcFile to the destFile
The script that I have made is working, but the issue that I would like your help with is to make my script only copies the file/files missing and not as my script is doing now, which copies from file 1 (test1.txt) to the file missing. Example if test4.txt & test5.txt files are missing in destFile, my script will copy from test1.txt to test5.txt, in stead of only copying the two missing files test4.txt & test5.txt.
import os, shutil
from datetime import datetime
count = 0
error = "ERROR! file is missing! (files have been copied)"
sttime = datetime.now().strftime('%d/%m/%Y - %H:%M:%S - ')
os.chdir("C:\log")
log = "log.txt"
srcFile = [r"C:\srcFile\test1.txt",
r"C:\srcFile\test2.txt",
r"C:\srcFile\test3.txt",
r"C:\srcFile\test4.txt",
r"C:\srcFile\test5.txt"]
destFile = [r"C:\destFile\test1.txt",
r"C:\destFile\test2.txt",
r"C:\destFile\test3.txt",
r"C:\destFile\test4.txt",
r"C:\destFile\test5.txt"]
for file in destFile:
if not os.path.exists(file):
for file_sr in srcFile:
if not os.path.exists(file):
shutil.copy(file_sr, 'C:\destFile')
count +=1
with open(log, 'a') as logfile:
logfile.write(sttime + error + " " + str(count) + " => " + file + '\n')
The problem is that you're iterating over all of the source files whenever you detect a missing destination file: for file_sr in srcFile:. Instead, you can copy just the missing file by keeping track of the position (in the array) of the missing destination file:
for position, file in enumerate(destFile):
if not os.path.exists(file):
file_sr = srcFile[position]
if not os.path.exists(file):
shutil.copy(file_sr, 'C:\destFile')
Using your code, you can do:
import os, shutil
from datetime import datetime
count = 0
error = "ERROR! file is missing! (files have been copied)"
sttime = datetime.now().strftime('%d/%m/%Y - %H:%M:%S - ')
os.chdir("C:\log")
log = "log.txt"
srcFile = [r"C:\srcFile\test1.txt",
r"C:\srcFile\test2.txt",
r"C:\srcFile\test3.txt",
r"C:\srcFile\test4.txt",
r"C:\srcFile\test5.txt"]
destFile = [r"C:\destFile\test1.txt",
r"C:\destFile\test2.txt",
r"C:\destFile\test3.txt",
r"C:\destFile\test4.txt",
r"C:\destFile\test5.txt"]
for file in destFile:
if not os.path.exists(file):
src_file = destFile.replace("destFile","srcFile")
shutil.copy(src_file, file)
count +=1
with open(log, 'a') as logfile:
logfile.write(sttime + error + " " + str(count) + " => " + file + '\n')
Thank you for your help guys. Exactly my problem was that I was iterating over all of the source files whenever I detected a missing destination file. The following logic from mackorone is doing what I was looking for.
for position, file in enumerate(destFile):
if not os.path.exists(file):
file_sr = srcFile[position]
shutil.copy(file_sr, 'C:\destFile')
I have updated the script, so now this script compares two folders, source folder and destination folder. If destination folder is missing files from the source folder, it will be copied. The script is working fine.
import os
import shutil
from datetime import datetime
sttime = datetime.now().strftime('%d/%m/%Y - %H:%M:%S - ')
error = "ERROR! file is missing! (files have been copied)"
des_path = 'C:\des_folder'
sr_path = 'C:\sr_folder'
des_folder = os.listdir(des_path)
sr_folder = os.listdir(sr_path)
count = 0
os.chdir("C:\log")
log = "log.txt"
def compare_folder(folder1,folder2):
files_in_sr_folder = set(sr_folder) - set(des_folder)
return files_in_sr_folder
files_missing = compare_folder(sr_folder,des_folder)
if len(files_missing) != 0:
for file in files_missing:
full_path_files = os.path.join(sr_path,file)
shutil.copy(full_path_files,des_path)
count +=1
with open(log, 'a') as logfile:
logfile.write(sttime + error + " " + str(count) + " => " + file + '\n')
else:
exit

FileNotFoundError: [Errno 2] No such file or directory: 'file of Bin\\S-1-5-21-1966573187-186149680-2580014948-1001\\$I0SFVU6.txt'

I am making a program to go through my whole windows drive and index every file.
Here is my code :
import os
import time
cTime = (int(time.time())/3600)
os.makedirs(f"C:\\fileDoucumentation\\{cTime}")
os.chdir(f"C:\\fileDoucumentation\\{cTime}")
numberOfFilesChecked = 0
def documentFile(path):
global numberOfFilesChecked
for i in range(len(path) - 1, -1, -1): #search from the back to the front of
#the file name for the period which marks the extension.
if path[i] == ".":
# the following line is the one that produces an error
fObject = open(f"file of {path[i + 1:]}.txt", "a+")
#we create a file named "file of extension", and we set it to append
# mode
numberOfFilesChecked += 1
print(numberOfFilesChecked)
fObject.write(path + "\n")
#we then write the name of the file being indexed to the file we just
# opened, then add a line break.
fObject.close()
break
def loopThroughDir(path):
try:
for i in os.listdir(path):
if os.path.isdir(path + "\\" + i): #if the path is a folder
loopThroughDir(path + "\\" + i)
else: #if it's a regular file
print(path + "\\" + i)
documentFile(path + "\\" + i)
except PermissionError:
pass
if __name__ == '__main__':
loopThroughDir("C:\\")
print(numberOfFilesChecked)
The problem is, it constantly says that whenever I create a file, it says that it cannot find it, and it raises an exception:
FileNotFoundError: [Errno 2] No such file or directory: 'file of Bin\S-1-5-21-1966573187-186149680-2580014948-1001\$I0SFVU6.txt'!
I am not sure what the issue is, since according to tutorialspoint the file mode "a+" will create a file if it does not exist!
EDIT:
I tried the code without any of the "\" and it worked perfectly... I think that it thought I was trying to create a file in a nonexistent directory, so it raised the error.

Rename duplicate files using Python

I'm trying to write a Python script that renames all duplicate file names recursively (i.e. inside all directories)
I already searched the web and Stack Overflow but I couldn't find any answer...
Here's my code:
#!/usr/bin/env python3.6
import os
import glob
path = os.getcwd()
file_list = []
duplicates={}
# remove filename duplicates
for file_path in glob.glob(path + "/**/*.c", recursive=True):
file = file_path.rsplit('/', 1)[1]
if file not in file_list:
file_list.append(file)
else:
if file in duplicates.keys():
duplicates[file] += 1
lista = []
lista.append(file_path)
os.rename(file_path, file_path.rsplit('/', 1)[:-1] + '/' + str(duplicates[file]) + file)
else:
duplicates[file] = 1
os.rename(file_path, file_path.rsplit('/', 1)[:-1] + '/' + str(duplicates[file]) + file)
And this is the error I'm getting:
Traceback (most recent call last):
File "/home/andre/Development/scripts/removeDuplicates.py", line 22, in <module>
os.rename(file_path, file_path.rsplit('/', 1)[:-1] + '/' + str(duplicates[file]) + file)
TypeError: can only concatenate list (not "str") to list
I know why I'm getting this error, but my question is: Is there a more clever way to do this? I'd also like to rename all duplicate directory names, but I still didn't figure it out...

No such file or directory: '<root>\n

I keep getting the followinge error whenever there is a function call to xml(productline), but if I replace the functioncall with file = open('config\\' + productLine + '.xml','r'), it seems to work, why?
def xml(productLine):
with open('config\\' + productLine + '.xml','r') as f:
return f.read()
def getsanityresults(productline):
xmlfile=xml(productline) // replace with file = open('config\\' + productLine + '.xml','r')
dom = minidom.parse(xmlfile)
data=dom.getElementsByTagName('Sanity_Results')
#print "DATA"
#print data
textnode = data[0].childNodes[0]
testresults=textnode.data
#print testresults
for line in testresults.splitlines():
#print line
line = line.strip('\r,\n')
#print line
line = re.sub(r'(http://[^\s]+|//[^\s]+|\\\\[^\s]+)', r'\1', line)
print line
#print line
resultslis.append(line)
print resultslis
return resultslis
Error:
Traceback (most recent call last):
File "C:\Dropbox\scripts\announce_build_wcn\wcnbuild_release.py", line 910, in <module>
main()
File "C:\Dropbox\scripts\announce_build_wcn\wcnbuild_release.py", line 858, in main
testresults=getsanityresults(pL)
File "C:\Dropbox\scripts\announce_build_wcn\wcnbuild_release.py", line 733, in getsanityresults
dom = minidom.parse(xmlfile)
File "C:\python2.7.3\lib\xml\dom\minidom.py", line 1920, in parse
return expatbuilder.parse(file)
File "C:\python2.7.3\lib\xml\dom\expatbuilder.py", line 922, in parse
fp = open(file, 'rb')
IOError: [Errno 2] No such file or directory: '<root>\n <PL name = "MSM8930.LA.2.0-PMIC-8917">\n
minidom.parse() expects either filename or file-object as a parameter but you are passing the content of the file, try this:
import os
from xml.dom import minidom
doc = minidom.parse(os.path.join('config', productline + '.xml'))
Unless you have specific requirements that favors minidom; use xml.etree.cElementTree to work with xml in Python. It is more pythonic and lxml that you might need in more complex cases supports its API so you don't need to learn twice.
I replace the functioncall with file = open('config\\' + productLine + '.xml','r'), it seems to work, why?
You've got two variables, with subtly different names:
xmlfile=xml(productline) // replace with file = open('config\\' + productLine + '.xml','r')
There's productline (lowercase l) and productLine (uppercase L).
If you use the same variable in both cases, you'll likely see more consistent results.

Categories