Why I cannot extract file with Python - python

I don't understand why I cannot extract file and why Python print KeyError: There is no item named eurofxref.zip in the archive lang interpreter see file as eurofxref.csv
import os
import zipfile
from file_from_web_class import FileFromWeb
if __name__ == "__main__":
url = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref.zip"
dir = point_file_from_cwd("temp", "eurofxref.zip")
with FileFromWeb(url, dir) as f:
with zipfile.ZipFile(f.temp_file, "r") as z:
path = point_from_cwd("temp")
a_file = z.namelist()[0]
print(a_file) #? eurofxref.csv
os.chdir(path)
z.extract("eurofxref.zip", '.', None) #? I don't understand.
More details:
import os
import zipfile
import requests
class FileFromWeb:
def __init__(self, url, temp_file):
self.url = url
self.temp_file = temp_file
def __enter__(self):
response = requests.get(self.url)
with open(self.temp_file, "wb") as reading_file:
reading_file.write(response.content)
return self
def __exit__(self, exc_type, exc_val, exc_tb):
pass
Method on main.py file:
def point_from_cwd(rel_path):
defined_path = os.getcwd() + "\\" + rel_path
print("You want point dir: ", os.getcwd() + "\\" + rel_path)
return defined_path
def point_file_from_cwd(rel_path, file_name):
defined_path = os.getcwd() + "\\" + rel_path + "\\" + file_name
print("You want point file in dir: ", os.getcwd() + "\\" + rel_path + "\\" + file_name)
return defined_path

KeyError is a self-explanatory exception and it basically says "there is no item named eurofxref.zip in the archive" so probably you are trying to extract eurofxref.csv but providing wrong item.
It should be fine when you change this line if I understand your question with given details:
z.extract("eurofxref.zip", '.', None) #? I don't understand.
as:
z.extract("eurofxref.csv", '.', None) #? I don't understand.

ZipFile.extract extracts only specified member from the archive. Try:
z.extract("eurofxref.csv", '.', None)
or:
z.extractall()

Related

How to create file base of condition using python

I am bit stuck with this approach not getting how to proceed with it
Case 1 : Check directory present or not , if not present create Directory and one file inside it and return that filename : ABC_20210730.txt
Case 2 : If Directory present, return the filename inside it [ Only 1 latest file name which as current date in it , example : ABC_20210730.txt ]
Case 3 : If Directory present but no file present inside it create the new file and return filename : ABC_20210730.txt
My code :
import os
import logging
import sys
import glob
logging.basicConfig(filename='C:\\Users\\admin\\Desktop\\JUL\\log.txt', level=logging.INFO,
format='%(asctime)s : %(message)s', filemode='w')
def checkfileexist(file_path, search_file_name):
try:
var_pth = str(file_path)
var_fle = str(file_name)
var_full = var_pth + var_fle
if var_pth is None or var_pth == '':
logging.error("Path parameter is empty")
raise TypeError('Path parameter is empty')
else:
pass
logging.info(f'Path : {var_pth}')
if search_file_name is None or search_file_name == '':
logging.error("Search file name parameter is empty")
raise TypeError('Search file name parameter is empty')
else:
pass
logging.info(f'Path : {search_file_name}')
if os.path.exists(var_full):
sfilename=glob.glob(file_path + '/' + search_file_name + '*' + '*.txt' )
return sfilename
if not os.path.exists(var_full):
os.mkdir(var_full)
with open(var_full+'/'+'ABC_20210730.txt',"w") as f:
f.write('')
return f
if not os.file.exists(var_full+'/'+search_file_name):
with open(var_full+'/'+'ABC_20210730.txt',"w") as f:
f.write('')
return f
except:
logging.error(f"ERRO : {erron} ")
sys.exit()
checkfileexist('C:\\Users\\admin\\Desktop\\JUL\\', 'ABX')
Finally I was able to write code
Thanks to all the contributors for helping : #Derek and #Tõnis Piip
I case require any modification in code , feel free to edit and had working code
This below code work for me and tested on my system
My code :
import os
import glob
import logging
path_name = 'C:\\Users\\admin\\Desktop\\JUL\\'
sfilename = 'log'
logging.basicConfig(filename='C:\\Users\\admin\\Desktop\\JUL\\demo.txt', level=logging.INFO,
format='%(asctime)s : %(message)s', filemode='w')
def returnfilename(path_name, sfilename):
varname = ''
try:
if path_name is None or path_name == '':
raise TypeError('Path parameter is empty')
else:
pass
if sfilename is None or sfilename == '':
raise TypeError('Search parameter is empty')
else:
pass
# If path does not exist then create folder and file inside it
if not os.path.exists(path_name):
os.mkdir(path_name)
fullname = path_name + '/' + sfilename + '.txt'
with open(fullname, 'w') as fd:
fd.write('')
varname = fullname
# If path exist , then return latest file name from that path
if os.path.exists(path_name):
var = glob.glob(f'{path_name}/{sfilename}.*')
var.sort(), var.reverse()
newpickname = var[0]
head, tail = os.path.split(newpickname)
varname = tail
# If path exist , then return latest file name from that path , if not exist it will throw exception IndexError
except IndexError:
fullname = path_name + '/' + sfilename + '.txt'
with open(fullname, 'w') as fd:
fd.write('')
varname = fullname
except Exception as er:
logging.error(f"{er}")
return varname
getfile = returnfilename('', sfilename)
print(getfile)

why the python file handling not recognizing file name?

I want to replace a string with another string in a file. I have below program to perform the task.
import os
import sys
import traceback
from glob import iglob
def usage():
print('Usage: python FindAndReplace.py [Old String] [New String] '
'[File Filters(default:".txt,.xml")] [Directory To Check(.)]')
def search_replace_string(fileName, old_str, new_str):
if not(os.path.isfile(fileName) and os.access(fileName, os.W_OK)):
print("Warning: Skipping..File does not exist or and is not writeable:" + filename)
return False
fileupdated = False
# Read the old file
with open(fileName, 'r') as f:
newlines = []
for lines in f.readlines():
if old_str in lines:
fileupdated = True
line = lines.replace(old_str, new_str)
newlines.append(line)
# Write changes to same file
if fileupdated:
print("string Found and Updating File: " + fileName)
try:
with open(fileName, 'w') as f:
for line in newlines:
f.write(line)
except:
print("Error: Cannot open/access existing file for writing: " + fileName)
return fileupdated
def main():
try:
DEFAULT_PATH = iglob(str('<path_to_file.xml'))
if len(sys.argv) < 3:
usage()
# old/new string required parameters, exit if not supplied
sys.exit(-1)
else:
oldString = sys.argv[1]
newString = sys.argv[2]
if len(sys.argv) < 4:
patterns = ['.xml', '.txt']
else:
stringFilter = sys.argv[3]
patterns = stringFilter.split(',')
if len(sys.argv) < 5:
path = DEFAULT_PATH
else:
path = sys.argv[4]
print('[Old String] :' + oldString)
print('[New String] :' + newString)
print('[File Filters] :' + ', '.join(patterns))
print('[Directory To Check] :' + path)
if not os.path.exists(path):
raise Exception("Selected path does not exist: " + path)
# Walk through directory structure looking for files matching patterns
matchingFileList = [os.path.join(dp, f) for dp, dn, filenames in os.walk(path) for f in filenames if os.path.splitext(f)[1] in patterns]
print('Files found matching patterns: ' + str(len(matchingFileList)))
filecount = 0
filesReplaced = 0
for currFile in matchingFileList:
filecount += 1
filesReplaced = search_replace_string(currFile, old_str, new_str)
if filesReplaced:
filesReplaced += 1
print("Total Files Searched :" + str(filecount))
print("Total Files Replaced/Updated :" + str(filesReplaced))
except Exception as err:
print(traceback.format_exception_only(type(err), err)[0].rstrip())
sys.exit(-1)
if __name__ == '__main__':
main()
When I am executing it from a command line I am getting below error:
(null): can't open file 'uro.py': [Errno 2] No such file or directory
Below is the command line argument I am giving
python uro.py <file_path> <old_str> <new_str>
NOTE: I am using xml file.
I wanted to develop a logic that will take file_name, old and new string as a command line argument. In the error one can see that the program is considering the python file a input file. While it should take the path of the file that I give with CMD argument.
What's the mistake here? Please suggest. Thank you
I got it fixed, there was some path issue. Thank you.

How to zip a folder in python with password?

With pyminizip i am able to zip a file with password in python :
filepath=r"C:\Users\xxx\Desktop\myFolder\file.txt"
import pyminizip
pyminizip.compress(filepath, None,"output.zip", "password", 0)
But how do I zip the whole folder 'myFolder' into a zip file with password?
I tried removing the filename from the path but it gives the error
OSError: error in opening C:\Users\xxx\Desktop\myFolder for reading
EDIT :
The below link has a function which will zip the directory. But It wont add a password.
https://www.calazan.com/how-to-zip-an-entire-directory-with-python/
If anyone can let me know if it is possible to add a password to an existing zip file, that will solve my problem. Is that possible?
I was finally able to accomplish encryping the whole directory(including all subfolder struncture and files) using a library called 'pyzipper' suggested by Anupam Chaplot.
Here is the solution :
def zip_folderPyzipper(folder_path, output_path):
"""Zip the contents of an entire folder (with that folder included
in the archive). Empty subfolders will be included in the archive
as well.
"""
parent_folder = os.path.dirname(folder_path)
# Retrieve the paths of the folder contents.
contents = os.walk(folder_path)
try:
zip_file = pyzipper.AESZipFile('new_test.zip','w',compression=pyzipper.ZIP_DEFLATED,encryption=pyzipper.WZ_AES)
zip_file.pwd=b'PASSWORD'
for root, folders, files in contents:
# Include all subfolders, including empty ones.
for folder_name in folders:
absolute_path = os.path.join(root, folder_name)
relative_path = absolute_path.replace(parent_folder + '\\',
'')
print ("Adding '%s' to archive." % absolute_path)
zip_file.write(absolute_path, relative_path)
for file_name in files:
absolute_path = os.path.join(root, file_name)
relative_path = absolute_path.replace(parent_folder + '\\',
'')
print ("Adding '%s' to archive." % absolute_path)
zip_file.write(absolute_path, relative_path)
print ("'%s' created successfully." % output_path)
except IOError as message:
print (message)
sys.exit(1)
except OSError as message:
print(message)
sys.exit(1)
except zipfile.BadZipfile as message:
print (message)
sys.exit(1)
finally:
zip_file.close()
Since I am new in python i cant explain the code in detail. Here are the references :
https://pypi.org/project/pyzipper/
https://www.calazan.com/how-to-zip-an-entire-directory-with-python/
To extract the Generated ZIP file in windows :
Right Click - > Unzip(Encripted)
If you directly click Extract All option, then it will give error
Try this:
Firstly check here please for pynzip. After that try it.
import pyminizip as pyzip
compression = 8
pyzip.compress("test.txt", "test.zip", "Pswrd", compression)
Here is how to copy all a directory with its subdirectories and its files, then compress it and encrypt a zip, with password and without needing an associated backup file, here we will see how to authorize a mac address to execute the decryption. So then it's up to you to change or improve the script.
But the essentials work very well.
After a lot of research, testing and thinking, I created this effective solution
my setup:
Python 3.8 64:bits on windows 7 64:bits
Usage terminology:
First step, we need to import the cryptography module
check for support or other is here https://cryptography.io/en/latest/installation/
command:
pip install cryptography
Then we will use the fernet object resulting from this module
https://cryptography.io/en/latest/fernet/
with password
https://cryptography.io/en/latest/fernet/#using-passwords-with-fernet
and shutil:
https://docs.python.org/3/library/shutil.html
file second.py:
import os
import re, uuid
import string
import shutil
import zlib
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
import base64
import zipfile
class zipy:
def __init__(self, pathDir=None):
"""If pathDir optional is none, this script copy all directory in current execution."""
if pathDir != None:
if os.path.isdir(pathDir):
pathDir = pathDir.replace(os.sep, '/')
if pathDir.endswith('/'):
self.root = pathDir
else:
self.root = pathDir + '/'
else:
self.root = os.getcwd()+os.sep
self.root = self.root.replace(os.sep, '/')
else:
self.root = os.getcwd()+os.sep
self.root = self.root.replace(os.sep, '/')
os.chdir(self.root)
self.name = 'sauvegarde'
self.dirSauvegarde = self.root+self.name
self.dirSauvegarde = self.dirSauvegarde.replace(os.sep, '/')
lectureDossier = os.listdir(self.root)
print(lectureDossier)
self.path_system = {}
for element in lectureDossier:
if os.path.isdir(element):
if element != '__pycache__':
self.path_system[element] = self.root + element + os.sep.replace(os.sep, '/')
self.path_system[element] = self.path_system[element].replace(os.sep, '/')
else:
pass
elif os.path.isfile(element):
self.path_system[element] = self.root + element
self.path_system[element] = self.path_system[element].replace(os.sep, '/')
else:
pass
self.zipi = myZip(self.dirSauvegarde)
def save(self):
"""sauvegarde le fichier"""
self.createDir(self.dirSauvegarde)
chemin_src = ""
chemin_dist = ""
for element in self.path_system:
if element != self.dirSauvegarde:
chemin_src = self.root+element
chemin_dest = self.dirSauvegarde + os.sep + element
chemin_dest = chemin_dest.replace(os.sep, '/')
if os.path.isdir(chemin_src):
self.copyDir(chemin_src, chemin_dest)
else:
self.copyFile(chemin_src, chemin_dest)
self.zipi.zip(zip_exist=True)
self.delDir(self.dirSauvegarde)
def copyDir(self, src, dest):
try:
shutil.copytree(src, dest, dirs_exist_ok=True)
except:
pass
def copyFile(self, src, dest):
try:
shutil.copyfile(src, dest)
except:
pass
def createDir(self, dirPath):
if os.path.isdir(dirPath):
self.delDir(dirPath)
else:
pass
os.makedirs(dirPath, exist_ok=True)
def delDir(self, dir):
if os.path.isdir(dir):
if len(os.listdir(dir)) > 0:
try:
print('rmtree')
shutil.rmtree(dir, ignore_errors=True)
except:
pass
else:
try:
os.rmdir(dir)
except:
pass
def decrypt(self):
self.zipi.unzip()
class myZip:
def __init__(self, dir):
self.pathDir = dir
self.nom = os.path.basename(dir)
self.pathZip = self.pathDir + '.zip'
self.crypt = Encryptor()
def zip(self, zip_exist=False):
if zip_exist == False:
pass
else:
if os.path.isfile(self.pathZip):
try:
os.remove(self.pathZip)
except:
pass
shutil.make_archive(os.path.splitext(self.pathZip)[0], 'zip', self.pathDir)
key = self.crypt.key_create()
#TEST
self.crypt.file_encrypt(key, self.pathZip, self.pathZip)
self.crypt.key_write(self.pathZip, key)
def unzip(self):
#TEST
if self.crypt.checkPass(self.pathZip):
#print('ok adresse mac autoriser')
key = self.crypt.key_load(self.pathZip)
self.crypt.file_decrypt(key, self.pathZip, self.pathZip)
else:
print('pas ok adresse mac erroner')
class Encryptor:
def __init__(self):
self.salto = None
def key_create(self):
password = self.getMac()
password = bytes(password, encoding="utf-8")
self.salto = os.urandom(16)
print(self.salto)
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=self.salto,
iterations=100,
)
key = base64.urlsafe_b64encode(kdf.derive(password))
return key
def key_write(self, pathZip, key):
with zipfile.ZipFile(pathZip, 'a') as zip:
zip.comment = key + bytes(' byMe ', encoding="utf-8") + self.salto
def key_load(self, pathZip):
stri = []
with zipfile.ZipFile(pathZip, 'a') as zip:
stri = zip.comment.split(b' byMe ')
print(stri[0])
print(stri[1])
key = stri[0]
self.salto = stri[1]
return key
def checkPass(self, pathZip):
key = base64.urlsafe_b64decode(self.key_load(pathZip))
salt = self.salto
mdp = self.getMac()
mdp = bytes(mdp, encoding="utf-8")
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=100,
)
retour = False
try:
kdf.verify(mdp, key)
retour = True
except:
retour = False
return retour
def file_encrypt(self, key, original_file, encrypted_file):
f = Fernet(key)
with open(original_file, 'rb') as file:
original = file.read()
encrypted = f.encrypt(original)
with open (encrypted_file, 'wb') as file:
file.write(encrypted)
def file_decrypt(self, key, encrypted_file, decrypted_file):
f = Fernet(key)
with open(encrypted_file, 'rb') as file:
encrypted = file.read()
decrypted = f.decrypt(encrypted)
with open(decrypted_file, 'wb') as file:
file.write(decrypted)
def getMac(self):
return "".join(re.findall('..', '%012x' % uuid.getnode()))
Use like this:
file : main.py
from second import zipy
#If the argument is empty, the script will make a copy of the directory being executed, otherwise the script will work and output the zip in the place indicated in argument
dd = zipy("E:/path")
#or dd = zipy("E:/path/") or dd = zipy() if you give arg, give absolute path
#Save the zip and encrypt it. Change second.py to directly give it a password as an argument
dd.save()
#decrypt zip
dd.decrypt()
Here's a snippet with pyminizip: gets a list of files and zips the whole thing.
import pyminizip
import os
def get_paths_recursively(src_root_path):
files = []
if src_root_path is not None:
for root, directories, filenames in os.walk(src_root_path):
entries = []
for filename in filenames:
full_file_name = os.path.join(root, filename)
if os.path.isfile(full_file_name) and not filename.startswith('.'):
files.append(os.path.join(root, filename))
return files
def pyminizip_zipper(folder_path, output_path, password):
paths = get_paths_recursively(folder_path)
roots = []
for path in paths:
roots.append(os.path.dirname(path.replace(os.path.dirname(folder_path), './')))
pyminizip.compress_multiple(paths, roots, output_path, password, 5)

Python multiple functions with the same decorator execute in main

I created a decorator to walk through directories for several functions to do some file operations. Every time when more than one functions with the decorator in the script, only the first one will execute.
import os
import re
import sys
def oswalk_deco(func):
def wrapper(filename, *args):
subdirs = [os.path.abspath(x[0]) for x in os.walk(target_dir)]
subdirs.remove(os.path.abspath(target_dir))
for dir in subdirs:
os.chdir(dir)
for item in os.listdir('.'):
p = re.match(filename, item)
if isinstance(p, re.Match):
match = p.group()
func(match, *args)
return wrapper
def str2uni(string):
if isinstance(string, str):
return string.encode('utf8').decode('unicode_escape')
else:
print('Function "str2uni(string)" only accept strings.')
exit()
#oswalk_deco
def sub_string(filename, regex, substr):
with open(filename, 'r') as file:
content = file.read()
with open(filename, 'w') as file:
content = re.sub(regex, substr, content)
file.write(content)
#oswalk_deco
def regex_print(filename, string):
with open(filename, 'r') as file:
content = file.read()
relist = re.findall(string, content)
if filename[0] == 'u':
print({str2uni(f'\\u{filename[1:-4]}'): relist})
elif isinstance(re.match(r'code\d{2}-u.+', filename), re.Match):
print({str2uni(f'\\{re.search("u[0-9a-z]{4,5}", filename).group()}'): relist})
#oswalk_deco
def docname_format(filename):
with open(filename, 'r') as file:
content = file.read()
with open(filename, 'w') as file:
content = re.sub(r'docname=".*"', f'docname="{filename}"', content)
file.write(content)
if __name__ == '__main__':
if len(sys.argv) == 1:
target_dir = '.'
else:
target_dir = sys.argv[1]
regex_print('.*\.svg', 'docname=".*"')
regex_print('.*\.svg', 'stroke:none')
sub_string('.*\.svg', 'docname=".*"', 'docname="stackoverflow.svg')
It seems like I've missed some important properties in Python?
Your target_dir defaults to ., the current working directory, if there's no command line argument given, and in your wrapper function, the os.walk function is always called with target_dir, which, after the os.chdir call, would refer to one of the subfolders of the first call to the decorated function, so os.walk naturally would not be able to find any more subfolders under ., which is already a subfolder.
You can fix this by getting the absolute path of target_dir first:
if len(sys.argv) == 1:
target_dir = '.'
else:
target_dir = sys.argv[1]
target_dir = os.path.abspath(target_dir)

How to unzip a file with Python 2.4?

I'm having a hard time figuring out how to unzip a zip file with 2.4. extract() is not included in 2.4. I'm restricted to using 2.4.4 on my server.
Can someone please provide a simple code example?
You have to use namelist() and extract(). Sample considering directories
import zipfile
import os.path
import os
zfile = zipfile.ZipFile("test.zip")
for name in zfile.namelist():
(dirname, filename) = os.path.split(name)
print "Decompressing " + filename + " on " + dirname
if not os.path.exists(dirname):
os.makedirs(dirname)
zfile.extract(name, dirname)
There's some problem with Vinko's answer (at least when I run it). I got:
IOError: [Errno 13] Permission denied: '01org-webapps-countingbeads-422c4e1/'
Here's how to solve it:
# unzip a file
def unzip(path):
zfile = zipfile.ZipFile(path)
for name in zfile.namelist():
(dirname, filename) = os.path.split(name)
if filename == '':
# directory
if not os.path.exists(dirname):
os.mkdir(dirname)
else:
# file
fd = open(name, 'w')
fd.write(zfile.read(name))
fd.close()
zfile.close()
Modifying Ovilia's answer so that you can specify the destination directory as well:
def unzip(zipFilePath, destDir):
zfile = zipfile.ZipFile(zipFilePath)
for name in zfile.namelist():
(dirName, fileName) = os.path.split(name)
if fileName == '':
# directory
newDir = destDir + '/' + dirName
if not os.path.exists(newDir):
os.mkdir(newDir)
else:
# file
fd = open(destDir + '/' + name, 'wb')
fd.write(zfile.read(name))
fd.close()
zfile.close()
Not fully tested, but it should be okay:
import os
from zipfile import ZipFile, ZipInfo
class ZipCompat(ZipFile):
def __init__(self, *args, **kwargs):
ZipFile.__init__(self, *args, **kwargs)
def extract(self, member, path=None, pwd=None):
if not isinstance(member, ZipInfo):
member = self.getinfo(member)
if path is None:
path = os.getcwd()
return self._extract_member(member, path)
def extractall(self, path=None, members=None, pwd=None):
if members is None:
members = self.namelist()
for zipinfo in members:
self.extract(zipinfo, path)
def _extract_member(self, member, targetpath):
if (targetpath[-1:] in (os.path.sep, os.path.altsep)
and len(os.path.splitdrive(targetpath)[1]) > 1):
targetpath = targetpath[:-1]
if member.filename[0] == '/':
targetpath = os.path.join(targetpath, member.filename[1:])
else:
targetpath = os.path.join(targetpath, member.filename)
targetpath = os.path.normpath(targetpath)
upperdirs = os.path.dirname(targetpath)
if upperdirs and not os.path.exists(upperdirs):
os.makedirs(upperdirs)
if member.filename[-1] == '/':
if not os.path.isdir(targetpath):
os.mkdir(targetpath)
return targetpath
target = file(targetpath, "wb")
try:
target.write(self.read(member.filename))
finally:
target.close()
return targetpath
I am testing in Python 2.7.3rc2 and the the ZipFile.namelist() is not returning an entry with just the sub directory name for creating a sub directory, but only a list of file names with sub directory, as follows:
['20130923104558/control.json', '20130923104558/test.csv']
Thus the check
if fileName == '':
does not evaluate to True at all.
So I modified the code to check if the dirName exists inside destDir and to create dirName if it does not exist. File is extracted only if fileName part is not empty. So this should take care of the condition where a directory name can appear in ZipFile.namelist()
def unzip(zipFilePath, destDir):
zfile = zipfile.ZipFile(zipFilePath)
for name in zfile.namelist():
(dirName, fileName) = os.path.split(name)
# Check if the directory exisits
newDir = destDir + '/' + dirName
if not os.path.exists(newDir):
os.mkdir(newDir)
if not fileName == '':
# file
fd = open(destDir + '/' + name, 'wb')
fd.write(zfile.read(name))
fd.close()
zfile.close()

Categories

Resources