FileNotFoundError on python3, even though the File does exist - python

Looking at other people with a similar issue, it's usually that they only have a relative path, which is no the case, I'm using the full path which I'm getting with os.join().
This is my code:
def reencode(file):
global DEFAULT_GFORMAT
global DEFAULT_VCODEC
global DEFAULT_ACODEC
global containerformat
global input
filename = os.path.join(input, file)
Container = 0
Video = 0
Audio = 0
if changeContainer: # The container needs to be changed
Container = DEFAULT_GFORMAT
else: # Container is already fine
Container = "copy"
if reencodeVideo: # Video codec needs to be changed
Video = DEFAULT_VCODEC
else: # Video codec is already fine
Video = "copy"
if reencodeAudio: # Audio codec needs to be changed
Audio = DEFAULT_ACODEC
else: # Audio codec is already fine
Audio = "copy"
if(Container == "copy" and Video == "copy" and Audio == "copy"):
print("{}: File is playable by the fire tv stick".format(file))
print()
else: # File needs to be reencoded
name = os.path.splitext(file)[0] # This removes the file extension from the name
if(containerformat == "MPEG-4"): # We only need to check for mp4 since if it's not mp4 it's either mkv or it's gonna be reencoded to mkv
newName = name + ".mp4" # This is the new name for the output file
else:
newName = name + ".mkv" # This is the new name for the output file
print("Reencoding file...")
filename2 = shlex.quote(filename)
print(filename2)
os.rename(filename2, (filename + ".bak")) # File needs to be renamed so it's not overwritten
x = (input) + ".bak"
y = shlex.quote(x)
z = shlex.quote(newName)
command = "ffmpeg -loglevel error -stats -i " + y + " -map 0 -scodec copy -vcodec " + Video + " -acodec " + Audio + " " + z
try:
subprocess.call(command, shell=True) # Run the command
except OSError as e: # Some error happened
if e.errno == os.errno.ENOENT: # ffmpeg is not installed
print("ffmpeg does not seem to be installed. Please install it if you want to run this script")
else: # Something else went wrong
raise
print() # Just to make it look a little nicer
The error happens here:
os.rename(filename2, (filename + ".bak"))
The full error message is this:
line 153, in reencode
os.rename(filename2, (filename + ".bak")) # File needs to be renamed so it's not overwritten
FileNotFoundError: [Errno 2] No such file or directory: "'/home/robert/Filme/sex school.mkv'" -> '/home/robert/Filme/sex school.mkv.bak'
As you can see, the path '/home/robert/Filme/sex school.mkv' is the full path, not just a relative one. When I try something like
mpv '/home/robert/Filme/sex school.mkv'
on the command line, the file plays without issue, so the path is definitely correct. Why am I still getting this error though?

You don't need the shell extension quoting, because you are not renaming via the shell.
Ergo, remove this line:
filename2 = shlex.quote(filename)
And just use:
os.rename(filename, filename + ".bak")
Now, enjoy your sex school video.

Related

Is there a way to put the main.py file into a folder?

I have been working on an assignment with several text files, but an getting the file not found error. I was told to put all the text files into a folder as well as the main program. How can I put the main.py file into a folder with the rest of the files?
Code:
def main():
process_file("good_data.txt")
process_file("bad_data.txt")
process_file("empty_file.txt")
process_file("does_not_exist.txt")
def process_file(param_str_file_name):
#Variables
num_rec = 0
total = 0
average = 0
try:
file_name = open('param_str_file_name', 'r')
print("Processing file", file_name)
variable = file_name.readline()
while variable != "":
file_name_int = int(file_name)
num_rec = num_rec + 1
variable = file_name.readline()
total += file_name_int
average = total / num_rec
file_name.close()
print("\tRecord count = ", num_rec)
print("\tTotal = ", total)
print("\tAverage = " , f"{average:.2f}", "\n")
except EOFError:
print("\tError!", param_str_file_name, " is empty. Cannot calculate average\n")
except FileNotFoundError:
print("\tError!", param_str_file_name, " File not found\n")
except ValueError:
print("\tError!", param_str_file_name, "contains non-numeric data\n")
if __name__ == "__main__":
main()
Thanks for the help guys
Problem #1
This may have nothing to do with your code, but just move your main.py file into the same folder as your text files.
If you want to keep your text files in a different directory however, try using this code:
import os
os.chdir('/path/to/the/folder')
This will change where your program looks. This is called change directory (also known as cd or chdir).
Problem #2
You use "param_str_file_name" as a string instead of using the argument in the
file_name = open('param_str_file_name', 'r')
line.
With most text editors, you can simply create a file in a folder, or you could drag a code file into a folder.

Issues with python path

I am working on a program in Arcgis however, I have a python issue.
While trying to run the following script I am getting an invalid MXD error which seems to suggest that it cannot find the location of my MXD file.
# modified by ESRI for use as a toolbox script tool
## imported sys to get the raw inputs and os to use for path separator
import arcpy, sys, os
# Set OverWrite if files already exist
arcpy.OverWriteOutput = 1
print "Enter folder path:"
mapDoc = raw_input()
#mapDoc = sys.argv[1]
print os.path.dirname(mapDoc)
# set a variable to the full path and file name of the MXD
fullnam = os.path.basename(mapDoc)
# Strip off the MXD file extension and store as string variable for use in the 'out_pdf'
nam = fullnam.strip(".mxd")
print nam
# Commented this out, since it doesnt need to be a parameter when you use the MXD name as the PDF name
##print "Enter save as name:"
##mapName = sys.argv[2]
map = arcpy.mapping
mxd = map.MapDocument(mapDoc)
map_document = mxd
#out_pdf = r"K:\projects" + "\\" + mapName + ".pdf"
#out_pdf = r"K:\projects" + os.sep + mapName + ".pdf"
#out_pdf = os.path.dirname(mapDoc) + os.sep + mapName + ".pdf"
out_pdf = os.path.dirname(mapDoc) + os.sep + nam + ".pdf"
# Set all the parameters as variables here:
data_frame = 'PAGE_LAYOUT'
resolution = "300"
image_quality = "NORMAL"
colorspace = "RGB"
compress_vectors = "True"
image_compression = "DEFLATE"
picture_symbol = 'RASTERIZE_BITMAP'
convert_markers = "False"
embed_fonts = "True"
layers_attributes = "NONE"
georef_info = "False"
# Due to a known issue, the df_export_width and df_export_height must be set to integers in the code:
map.ExportToPDF(map_document, out_pdf, data_frame, 640, 480, resolution, image_quality, colorspace, compress_vectors, image_compression, picture_symbol, convert_markers, embed_fonts, layers_attributes, georef_info)
# This gives feedback in the script tool dialog:
arcpy.GetMessages()
Now please look at the command prompt.
(arcgispro-py3) C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3>"C:\Us
ers\ant\Documents\MyCensus_Files\Python script\Export2PDF.py"
Enter folder path:
C:\Users\ant\Documents\MyCensus_Files\Python script
C:\Users\ant\Documents\MyCensus_Files
Python script
Traceback (most recent call last):
File "C:\Users\ant\Documents\MyCensus_Files\Python script\Export2PDF.py
", line 22, in <module>
mxd = map.MapDocument(mapDoc)
File "C:\Program Files (x86)\ArcGIS\Desktop10.6\ArcPy\arcpy\arcobjects\mixins.
py", line 651, in __init__
assert (os.path.isfile(mxd) or (mxd.lower() == "current")), gp.getIDMessage(
89004, "Invalid MXD filename")
AssertionError: Invalid MXD filename.
As you can see, the path I enter is different from what is being returned by print and I think that is what's causing my issue. Would appreciate it anyone could assist fixing handling this path error or with a python script that accomplishes converting MXD to PDF.
Regards
If you print out mapDoc right before the line map.MapDocument(mapDoc), you would see that you're trying to pass C:\Users\ant\Documents\MyCensus_Files\Python script as a mxd file. That's a directory, not a mxd file.
Try this:
import arcpy, sys, os
arcpy.OverWriteOutput = 1
mapDoc = os.path.join("C:/", "Users", "ant", "Documents", "MyCensus_Files", "Python_script", "test.mxd")
map = arcpy.mapping
mxd = map.MapDocument(mapDoc)
# ...

Throttling FTP download with Python ftplib

How do I throttle the FTP download with Python ftplib? For example put a cap on the speed to be 20Mb/s?
I'm using the following code to download files with Python ftplib:
from ftplib import FTP
import os
download_list = 'testlist.txt' # inital list of directories to be downloaded
path_list = [] # initalize a list of all the pathes from download_list
local_folder = 'testStorage' #where files are going to be downloaded to
downloaded_list = 'completedownload.txt' # list of completed downloads
error_list = 'incomplete_downloads.txt' # list of paths that are incomplete
ftp=FTP("ftp.address.com")
ftp.login("user_name","password") #login to FTP account
print "Successfully logged in"
# make a list of files to download from a file
with open(download_list, 'r') as f:
content = f.readlines()
path_list = [x.strip() for x in content]
for path in path_list:
path = path.replace("*","") # strips the * found in the source file
print '\nChanging directory to ' + path + ':\n'
#ftp.cwd('/AAA/BBB/CCC/logic-1/') #the format to change into path note the * is omitted
#if ftp.cwd(path) == True:
try: # tries the path in the file
ftp.cwd(path)
#ftp.retrlines('LIST')
filenames = ftp.nlst()
for filename in filenames:
local_directory = local_folder+path # create the local path ie : testStorage/AAA/BBB/CCC/logic-1/
local_filename = os.path.join(local_directory,filename) #
if os.path.exists(local_filename) == False: # checks if file already exists
if not os.path.exists(local_directory): # mimic the remote path locally
os.makedirs(local_directory)
file = open(local_filename,'wb')
ftp.retrbinary('RETR '+ filename, file.write)
print filename
file.close()
elif os.path.exists(local_filename) == True: # skip the file if it exits
print 'File ' +filename + ' already exists, skipping this file'
except: #if path in text file does not exist write to error_list.txt
print 'Path ' + path + ' does not exist writing path to error_list.txt'
with open(error_list, 'a') as f2:
f2.write(path+'\n')
continue
print "all done closing connection"
ftp.close() #CLOSE THE FTP CONNECTION
To throttle the download, just implement a function that does file.write and time.sleep as needed. Pass that function to ftp.retrbinary as callback (instead of file.write directly).
This pseudo code (I do not do Python) should give you some idea:
total_length = 0
start_time = time.time()
def write_and_sleep(buf):
global file
global total_length
global start_time
file.write(buf)
total_length += sys.getsizeof(buf)
while (total_length / (time.time() - start_time)) > 100000000:
time.sleep(0.1)
ftp.retrbinary('RETR '+ filename, write_and_sleep)
Reducing maxblocksize (the 3rd argument of ftp.retrbinary) may help achieving more smooth "download curve".

Python script is called but not executed from batch file

i have a python script that when is run from eclipse it does what i want without any errors or anything.
I want now to create a batch file, that will run my script in a loop (infinitely).
The first problem is that i when i run the bat file, i get a second cmd window that shows the logging from my python script (which shows me that it is running) but when the main process of the script starts(which can take from 1 minute to some hours) it exits within a few second without actually running all the script. I have used start wait/ but it doesn't seem to work. Here is the simple batch file i have created:
#echo off
:start
start /wait C:\Python32\python.exe C:\Users\some_user\workspace\DMS_GUI\CheckCreateAdtf\NewTest.py
goto start
So i want the bat file to run my script, wait for it to finish(even if it takes some hours) and then run it again.
I have also tried creating a bat file that calls with start wait/ the bat file shown above with no success.
Optimally i would like it to keep the window open with all the logging that i have in my script, but that is another issue that can be solved later.
def _open_read_file(self):
logging.debug("Checking txt file with OLD DB-folder sizes")
content = []
with open(self._pathToFileWithDBsize) as f:
content = f.read().splitlines()
for p in content:
name,size = (p.split(","))
self._folder_sizes_dic[name] = size
def _check_DB(self):
logging.debug("Checking current DB size")
skippaths = ['OtherData','Aa','Sss','asss','dss','dddd']
dirlist = [ item for item in os.listdir(self._pathToDBparentFolder) if os.path.isdir(os.path.join(self._pathToDBparentFolder, item)) ]
for skip in skippaths:
if skip in dirlist:
dirlist.remove(skip)
MB=1024*1024.0
for dir in dirlist:
folderPath = self._pathToDBparentFolder +"\\"+str(dir)
fso = com.Dispatch("Scripting.FileSystemObject")
folder = fso.GetFolder(folderPath)
size = str("%.5f"%(folder.Size/MB))
self._DB_folder_sizes_dic[dir] = size
def _compare_fsizes(self):
logging.debug("Comparing sizes between DB and txt file")
for (key, value) in self._DB_folder_sizes_dic.items():
if key in self._folder_sizes_dic:
if (float(self._DB_folder_sizes_dic.get(key)) - float(self._folder_sizes_dic.get(key)) < 100.0 and float(self._DB_folder_sizes_dic.get(key)) - float(self._folder_sizes_dic.get(key)) > -30.0):
pass
else:
self._changed_folders.append(key)
else:
self._changed_folders.append(key)
def _update_file_with_new_folder_sizes(self):
logging.debug("Updating txt file with new DB sizes")
file = open(self._pathToFileWithDBsize,'w')
for key,value in self._DB_folder_sizes_dic.items():
file.write(str(key)+","+str(value)+"\n")
def _create_paths_for_changed_folders(self):
logging.debug("Creating paths to parse for the changed folders")
full_changed_folder_parent_paths = []
for folder in self._changed_folders:
full_changed_folder_parent_paths.append(self._pathToDBparentFolder +"\\"+str(folder))
for p in full_changed_folder_parent_paths:
for path, dirs, files in os.walk(p):
if not dirs:
self._full_paths_to_check_for_adtfs.append(path)
def _find_dat_files_with_no_adtf(self):
logging.debug("Finding files with no adtf txt")
for path in self._full_paths_to_check_for_adtfs:
for path, dirs, files in os.walk(path):
for f in files:
if f.endswith('_AdtfInfo.txt'):
hasAdtfFilename = f.replace('_AdtfInfo.txt', '.dat')
self.hasADTFinfos.add(path + "\\" + hasAdtfFilename)
self.adtf_files = self.adtf_files + 1
elif f.endswith('.dat'):
self.dat_files = self.dat_files + 1
self._dat_file_paths.append(path + "\\" + f)
logging.debug("Checking which files have AdtfInfo.txt, This will take some time depending on the number of .dat files ")
for file in self._dat_file_paths:
if file not in self.hasADTFinfos:
self._dat_with_no_adtf.append(file)
self.files_with_no_adtf = len(self._dat_with_no_adtf)
#self.unique_paths_from_log = set(full_paths_to_check_for_adtfs)
logging.debug("Files found with no adtf " + str(self.files_with_no_adtf))
def _create_adtf_info(self):
logging.debug("Creating Adtf txt for dat files")
files_numbering = 0
for file in self._dat_with_no_adtf:
file_name = str(file)
adtf_file_name_path = file.replace('.dat','_AdtfInfo.txt')
exe_path = r"C:\Users\some_user\Desktop\some.exe "
path_to_dat_file = file_name
path_to_adtf_file = adtf_file_name_path
command_to_subprocess = exe_path + path_to_dat_file + " -d "+ path_to_adtf_file
#Call VisionAdtfInfoToCsv
subprocess.Popen(command_to_subprocess,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
process_response = subprocess.check_output(command_to_subprocess)
#if index0 in response, adtf could not be created because .dat file is probably corrupted
if "index0" in str(process_response):
self._corrupted_files_paths.append(path_to_dat_file)
self._files_corrupted = self._files_corrupted + 1
self._corrupted_file_exist_flag = True
else:
self._files_processed_successfully = self._files_processed_successfully + 1
files_numbering = files_numbering + 1
The functions are called in this order
self._open_read_file()
self._check_DB()
self._compare_fsizes()
self._create_paths_for_changed_folders()
self._find_dat_files_with_no_adtf()
self._create_adtf_info()
self._check_DB()
self._update_file_with_new_folder_sizes()
Ok it seems that the .exe in the script was returning an error and that is why it the script was finishing so fast. I thought that the bat file did not wait. I should have placed the .bat file in the .exe folder and now the whole thing runs perfect.

Not recognized non existant file

im getting a weird error using this code (part of a class):
from sys import path as workingDIR
from os import system, path
image = '' # some jpeg image data
keep = 0
DIR = workingDIR[0] + '\\image'
if path.isfile(DIR + '.jpeg'): # adding numbers to end of file name like how windows prevents multiple files having the same name
x = 2
while path.isfile(DIR + ' (' + str(x) + ').jpeg'):
x += 1
DIR += ' (' + str(x) + ')'
DIR += '.jpeg'
f = open(DIR, 'w+b')
f.write(image)
f.close()
system(DIR)
system('pause')
if not(keep):
remove(DIR)
cmd is telling me '...\image' is not recognized as an internal or external command, operable program or batch file. (ignore the ...), which doesnt make sense, because DIR has already been changed to ...\image.jpeg and yet it is getting image. what am i doing wrong here?
You have an extra white space in the image filename - "..\image (1).jpeg"
so when you call system(DIR), "..\image" becomes the command and "(1).jpeg" is the first argument.

Categories

Resources