Adding folders to a zip file using python - python

I want to create a zip file. Add a folder to the zip file and then add a bunch of files to that folder.
So I want to end up with a zip file with a single folder with files in.
I dont know if its bad practice to have folders in zip files or something but google gives me nothing on the subject.
I started out with this:
def addFolderToZip(myZipFile,folder):
folder = folder.encode('ascii') #convert path to ascii for ZipFile Method
for file in glob.glob(folder+"/*"):
if os.path.isfile(file):
print file
myZipFile.write(file, os.path.basename(file), zipfile.ZIP_DEFLATED)
elif os.path.isdir(file):
addFolderToZip(myZipFile,file)
def createZipFile(filename,files,folders):
curTime=strftime("__%Y_%m_%d", time.localtime())
filename=filename+curTime;
print filename
zipFilename=utils.getFileName("files", filename+".zip")
myZipFile = zipfile.ZipFile( zipFilename, "w" ) # Open the zip file for writing
for file in files:
file = file.encode('ascii') #convert path to ascii for ZipFile Method
if os.path.isfile(file):
(filepath, filename) = os.path.split(file)
myZipFile.write( file, filename, zipfile.ZIP_DEFLATED )
for folder in folders:
addFolderToZip(myZipFile,folder)
myZipFile.close()
return (1,zipFilename)
(success,filename)=createZipFile(planName,files,folders);
Taken from: http://mail.python.org/pipermail/python-list/2006-August/396166.html
Which gets rid of all folders and puts all files in the target folder (and its subfolders) into a single zip file. I couldnt get it to add an entire folder.
If I feed the path to a folder in myZipFile.write, I get
IOError: [Errno 13] Permission denied: '..\packed\bin'
Any help is much welcome.
Related question: How do I zip the contents of a folder using python (version 2.5)?

You can also use shutil
import shutil
zip_name = 'path\to\zip_file'
directory_name = 'path\to\directory'
# Create 'path\to\zip_file.zip'
shutil.make_archive(zip_name, 'zip', directory_name)
This will put the whole folder in the zip.

Ok, after i understood what you want, it is as simple as using the second argument of zipfile.write, where you can use whatever you want:
import zipfile
myZipFile = zipfile.ZipFile("zip.zip", "w" )
myZipFile.write("test.py", "dir\\test.py", zipfile.ZIP_DEFLATED )
creates a zipfile where test.py would be extracted to a directory called dir
EDIT:
I once had to create an empty directory in a zip file: it is possible.
after the code above just delete the file test.py from the zipfile, the file is gone, but the empty directory stays.

A zip file has no directory structure, it just has a bunch of pathnames and their contents. These pathnames should be relative to an imaginary root folder (the ZIP file itself). "../" prefixes have no defined meaning in a zip file.
Consider you have a file, a and you want to store it in a "folder" inside a zip file. All you have to do is prefix the filename with a folder name when storing the file in the zipfile:
zipi= zipfile.ZipInfo()
zipi.filename= "folder/a" # this is what you want
zipi.date_time= time.localtime(os.path.getmtime("a"))[:6]
zipi.compress_type= zipfile.ZIP_DEFLATED
filedata= open("a", "rb").read()
zipfile1.writestr(zipi, filedata) # zipfile1 is a zipfile.ZipFile instance
I don't know of any ZIP implementations allowing the inclusion of an empty folder in a ZIP file. I can think of a workaround (storing a dummy filename in the zip "folder" which should be ignored on extraction), but not portable across implementations.

import zipfile
import os
class ZipUtilities:
def toZip(self, file, filename):
zip_file = zipfile.ZipFile(filename, 'w')
if os.path.isfile(file):
zip_file.write(file)
else:
self.addFolderToZip(zip_file, file)
zip_file.close()
def addFolderToZip(self, zip_file, folder):
for file in os.listdir(folder):
full_path = os.path.join(folder, file)
if os.path.isfile(full_path):
print 'File added: ' + str(full_path)
zip_file.write(full_path)
elif os.path.isdir(full_path):
print 'Entering folder: ' + str(full_path)
self.addFolderToZip(zip_file, full_path)
def main():
utilities = ZipUtilities()
filename = 'TEMP.zip'
directory = 'TEMP'
utilities.toZip(directory, filename)
main()
I'm running:
python tozip.py
This is the log:
havok#fireshield:~$ python tozip.py
File added: TEMP/NARF (7ª copia)
Entering folder: TEMP/TEMP2
File added: TEMP/TEMP2/NERF (otra copia)
File added: TEMP/TEMP2/NERF (copia)
File added: TEMP/TEMP2/NARF
File added: TEMP/TEMP2/NARF (copia)
File added: TEMP/TEMP2/NARF (otra copia)
Entering folder: TEMP/TEMP2/TEMP3
File added: TEMP/TEMP2/TEMP3/DOCUMENTO DEL FINAL
File added: TEMP/TEMP2/TEMP3/DOCUMENTO DEL FINAL (copia)
File added: TEMP/TEMP2/NERF
File added: TEMP/NARF (copia) (otra copia)
File added: TEMP/NARF (copia) (copia)
File added: TEMP/NARF (6ª copia)
File added: TEMP/NERF (copia) (otra copia)
File added: TEMP/NERF (4ª copia)
File added: TEMP/NERF (otra copia)
File added: TEMP/NERF (3ª copia)
File added: TEMP/NERF (6ª copia)
File added: TEMP/NERF (copia)
File added: TEMP/NERF (5ª copia)
File added: TEMP/NARF (8ª copia)
File added: TEMP/NARF (3ª copia)
File added: TEMP/NARF (5ª copia)
File added: TEMP/NERF (copia) (3ª copia)
File added: TEMP/NARF
File added: TEMP/NERF (copia) (copia)
File added: TEMP/NERF (8ª copia)
File added: TEMP/NERF (7ª copia)
File added: TEMP/NARF (copia)
File added: TEMP/NARF (otra copia)
File added: TEMP/NARF (4ª copia)
File added: TEMP/NERF
File added: TEMP/NARF (copia) (3ª copia)
As you can see, it work, the archive is ok too. This is a recursive function that can zip an entire folder. The only problem is that it doesn't create a empty folder.
Cheers.

Below is some code for zipping an entire directory into a zipfile.
This seems to work OK creating zip files on both windows and linux. The output
files seem to extract properly on windows (built-in Compressed Folders feature,
WinZip, and 7-Zip) and linux. However, empty directories in a zip file appear
to be a thorny issue. The solution below seems to work but the output of
"zipinfo" on linux is concerning. Also the directory permissions are not set
correctly for empty directories in the zip archive. This appears to require
some more in depth research.
I got some info from this velocity reviews thread and this python mailing list thread.
Note that this function is designed to put files in the zip archive with
either no parent directory or just one parent directory, so it will trim any
leading directories in the filesystem paths and not include them inside the
zip archive paths. This is generally the case when you want to just take a
directory and make it into a zip file that can be extracted in different
locations.
Keyword arguments:
dirPath -- string path to the directory to archive. This is the only
required argument. It can be absolute or relative, but only one or zero
leading directories will be included in the zip archive.
zipFilePath -- string path to the output zip file. This can be an absolute
or relative path. If the zip file already exists, it will be updated. If
not, it will be created. If you want to replace it from scratch, delete it
prior to calling this function. (default is computed as dirPath + ".zip")
includeDirInZip -- boolean indicating whether the top level directory should
be included in the archive or omitted. (default True)
(Note that StackOverflow seems to be failing to pretty print my python with
triple quoted strings, so I just converted my doc strings to the post text here)
#!/usr/bin/python
import os
import zipfile
def zipdir(dirPath=None, zipFilePath=None, includeDirInZip=True):
if not zipFilePath:
zipFilePath = dirPath + ".zip"
if not os.path.isdir(dirPath):
raise OSError("dirPath argument must point to a directory. "
"'%s' does not." % dirPath)
parentDir, dirToZip = os.path.split(dirPath)
#Little nested function to prepare the proper archive path
def trimPath(path):
archivePath = path.replace(parentDir, "", 1)
if parentDir:
archivePath = archivePath.replace(os.path.sep, "", 1)
if not includeDirInZip:
archivePath = archivePath.replace(dirToZip + os.path.sep, "", 1)
return os.path.normcase(archivePath)
outFile = zipfile.ZipFile(zipFilePath, "w",
compression=zipfile.ZIP_DEFLATED)
for (archiveDirPath, dirNames, fileNames) in os.walk(dirPath):
for fileName in fileNames:
filePath = os.path.join(archiveDirPath, fileName)
outFile.write(filePath, trimPath(filePath))
#Make sure we get empty directories as well
if not fileNames and not dirNames:
zipInfo = zipfile.ZipInfo(trimPath(archiveDirPath) + "/")
#some web sites suggest doing
#zipInfo.external_attr = 16
#or
#zipInfo.external_attr = 48
#Here to allow for inserting an empty directory. Still TBD/TODO.
outFile.writestr(zipInfo, "")
outFile.close()
Here's some sample usages. Note that if your dirPath argument has several leading directories, only the LAST one will be included by default. Pass includeDirInZip=False to omit all leading directories.
zipdir("foo") #Just give it a dir and get a .zip file
zipdir("foo", "foo2.zip") #Get a .zip file with a specific file name
zipdir("foo", "foo3nodir.zip", False) #Omit the top level directory
zipdir("../test1/foo", "foo4nopardirs.zip")

Easiest way for me is using zipfile CLI (Command-Line Interface). The zipfile CLI can take either files or folders as arguments, and add them recursively to the archive.
So if you have a file hierarcy of:
- file1.txt
- folder1
- file2.txt
- file3.txt
And you want all of it to be archived into 'result.zip', you simply write:
python -m zipfile -c result.zip file1.txt folder
In case you want to use it within python code and use the zipfile module imported, you can call its main function in the following way:
import zipfile
zipfile.main(['-c', 'result.zip', 'file1.md', 'folder'])

here is my function i use to zip a folder:
import os
import os.path
import zipfile
def zip_dir(dirpath, zippath):
fzip = zipfile.ZipFile(zippath, 'w', zipfile.ZIP_DEFLATED)
basedir = os.path.dirname(dirpath) + '/'
for root, dirs, files in os.walk(dirpath):
if os.path.basename(root)[0] == '.':
continue #skip hidden directories
dirname = root.replace(basedir, '')
for f in files:
if f[-1] == '~' or (f[0] == '.' and f != '.htaccess'):
#skip backup files and all hidden files except .htaccess
continue
fzip.write(root + '/' + f, dirname + '/' + f)
fzip.close()

If you look at a zip file created with Info-ZIP, you'll see that directories are indeed listed:
$ zip foo.zip -r foo
adding: foo/ (stored 0%)
adding: foo/foo.jpg (deflated 84%)
$ less foo.zip
Archive: foo.zip
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
0 Stored 0 0% 2013-08-18 14:32 00000000 foo/
476320 Defl:N 77941 84% 2013-08-18 14:31 55a52268 foo/foo.jpg
-------- ------- --- -------
476320 77941 84% 2 files
Notice that the directory entry has zero length and is not compressed. It seems you can achieve the same thing with Python by writing the directory by name, but forcing it to not use compression.
if os.path.isdir(name):
zf.write(name, arcname=arcname, compress_type=zipfile.ZIP_STORED)
else:
zf.write(name, arcname=arcname, compress_type=zipfile.ZIP_DEFLATED)
It might be worth making sure arcname ends in a /.

after adding some imports your code runs fine for me, how do you call the script, maybe you could tell us the folder structure of the '..\packed\bin' directory.
I called your code with the following arguments:
planName='test.zip'
files=['z.py',]
folders=['c:\\temp']
(success,filename)=createZipFile(planName,files,folders)
`

Heres the edited code I ran. Its based on the code above, taken from the mailing list. I added the imports and made a main routine. I also cut out the fiddling with the output filename to make the code shorter.
#!/usr/bin/env python
import os, zipfile, glob, sys
def addFolderToZip(myZipFile,folder):
folder = folder.encode('ascii') #convert path to ascii for ZipFile Method
for file in glob.glob(folder+"/*"):
if os.path.isfile(file):
print file
myZipFile.write(file, os.path.basename(file), zipfile.ZIP_DEFLATED)
elif os.path.isdir(file):
addFolderToZip(myZipFile,file)
def createZipFile(filename,files,folders):
myZipFile = zipfile.ZipFile( filename, "w" ) # Open the zip file for writing
for file in files:
file = file.encode('ascii') #convert path to ascii for ZipFile Method
if os.path.isfile(file):
(filepath, filename) = os.path.split(file)
myZipFile.write( file, filename, zipfile.ZIP_DEFLATED )
for folder in folders:
addFolderToZip(myZipFile,folder)
myZipFile.close()
return (1,filename)
if __name__=="__main__":
#put everything in sys.argv[1] in out.zip, skip files
print createZipFile("out.zip", [], sys.argv[1])
At work, on my Windows box, this code ran fine but didnt create any "folders" in the zipfile. At least I recall it did. Now at home, on my Linux box, the zip file created seems to be bad:
$ unzip -l out.zip
Archive: out.zip
End-of-central-directory signature not found. Either this file is not
a zipfile, or it constitutes one disk of a multi-part archive. In the
latter case the central directory and zipfile comment will be found on
the last disk(s) of this archive.
unzip: cannot find zipfile directory in one of out.zip or
out.zip.zip, and cannot find out.zip.ZIP, period.
I dont know if I accidently broke the code, I think its the same. Crossplatform issues? Either way, its not related to my original question; getting folders in the zip file. Just wanted to post the code I actually ran, not the code I based my code on.

Thank you wery much for this useful function! I found it very useful as I was also searching for help. However, maybe it would be useful to change it a little bit so that
basedir = os.path.dirname(dirpath) + '/'
would be
basedir = os.path.dirname(dirpath + '/')
Because found that if I want to zip folder 'Example' which is located at 'C:\folder\path\notWanted\to\zip\Example',
I got in Windows:
dirpath = 'C:\folder\path\notWanted\to\zip\Example'
basedir = 'C:\folder\path\notWanted\to\zip\Example/'
dirname = 'C:\folder\path\notWanted\to\zip\Example\Example\Subfolder_etc'
But I suppose your code should give
dirpath = 'C:\folder\path\notWanted\to\zip\Example'
basedir = 'C:\folder\path\notWanted\to\zip\Example\'
dirname = '\Subfolder_etc'

import os
import zipfile
zf = zipfile.ZipFile("file.zip", "w")
for file in os.listdir(os.curdir):
if not file.endswith('.zip') and os.path.isfile(os.curdir+'/'+file):
print file
zf.write(file)
elif os.path.isdir(os.curdir+'/'+file):
print f
for f in os.listdir(os.curdir+'/'+file):
zf.write(file+'\\'+f)
zf.close()

When you wanna create an empty folder, you can do it like this:
storage = api.Storage.open("empty_folder.zip","w")
res = storage.open_resource("hannu//","w")
storage.close()
Folder not showe in winextractor, but when you extract it it is showed.

Related

Using Python, able to iterate files from another directory but unable to read contents

I need to iterate through all the .txt files inside another directory from current directory and read the contents.
Am able to iterate thw filenames, but when tried to read the contents, the output is blabk while there is data in the files.
To do that here is an example of how to iterate on every text file in the current directory
# Import the module OS
import os
# Choose Current Directory
directory = os.getcwd()
# Iterate over every file in the directory
for filename in os.listdir(directory):
# get the full path by concatenating the file name with the directory
path = directory + "\\" + filename
# Check if this file is a text file
if path.endswith(".txt"):
# Open the text files in the path
text_file = open(path, 'r')
# Read and print the contents of these files (Including the Python Script)
print(text_file.read())
You can change the current directory with any directory you need.
If you have a problem with other Directories try using double backslashes in the URL like this
directory = 'C:\\Users\\USER\\Desktop\\Text Files'
for file in files :
print(file)
print("printing success file")
k = open(extracted_files_path+file,"r")
print(extracted_files_path + file)
print("ending printing success file")
print(k.read())
print(type(file))
Output:
printing success file ending printing success file
//below is blank, whereas the file contents are expected// <class
'str'>
The above is the code and the actual output I'm getting for the question - raven.

Read in multiple folder and combine multiple text files contents to one file per folder - Python

I'm new to Python. I have 100's of multiple folders in the same Directory inside each folder i have multiple text files each. i want to combine all text files contents to one per folder.
Folder1
text1.txt
text2.txt
text3.txt
.
.
Folder2
text1.txt
text2.txt
text3.txt
.
.
i need output as copy all text files content in to one text1.txt + text2.txt + text3.txt ---> Folder1.txt
Folder1
text1.txt
text2.txt
text3.txt
Folder1.txt
Folder2
text1.txt
text2.txt
text3.txt
Folder2.txt
i have below code which just list out the text files.
for path,subdirs, files in os.walk('./data')
for filename in files:
if filename.endswith('.txt'):
please help me how to proceed on the task. Thank you.
Breaking down the problem we need the solution to:
Find all files in a directory
Merge contents of all the files into one file - with the same name as the name of the directory.
And then apply this solution to every sub directory in the base directory. Tested the code below.
Assumption: the subfolders have only text files and no directories
import os
# Function to merge all files in a folder
def merge_files(folder_path):
# get all files in the folder,
# assumption: folder has no directories and all text files
files = os.listdir(folder_path)
# form the file name for the new file to create
new_file_name = os.path.basename(folder_path) + '.txt'
new_file_path = os.path.join(folder_path, new_file_name)
# open new file in write mode
with open(new_file_path, 'w') as nf:
# open files to merge in read mode
for file in files:
file = os.path.join(folder_path, file)
with open(file, 'r') as f:
# read all lines of a file and write into new file
lines_in_file = f.readlines()
nf.writelines(lines_in_file)
# insert a newline after reading each file
nf.write("\n")
# Call function from the main folder with the subfolders
folders = os.listdir("./test")
for folder in folders:
if os.path.isdir(os.path.join('test', folder)):
merge_files(os.path.join('test', folder))
First you will need to get all folder names, which can be done with os.listdir(path_to_dir). Then you iterate over all of them, and for each you will need to iterate over all of its children using the same function, while concatenating contents using this: https://stackoverflow.com/a/13613375/13300960
Try writing it by yourself and update the answer with your code if you will need more help.
Edit: os.walk might not be the best solution since you know your folder structure and just two listdirs will do the job.
import os
basepath = '/path/to/directory' # maybe just '.'
for dir_name in os.listdir(basepath):
dir_path = os.path.join(basepath, dir_name)
if not os.path.isdir(dir_path):
continue
with open(os.path.join(dir_path, dir_name+'.txt') , 'w') as outfile:
for file_name in os.listdir(dir_path):
if not file_name.endswith('.txt'):
continue
file_path = os.path.join(dir_path, file_name)
with open(file_path) as infile:
for line in infile:
outfile.write(line)
This is not the best code, but it should get the job done and it is the shortest.

Python doesn't recognize zip files as zip files

I iterate through the directories and want to find all zip files and add them to download_all.zip
I am sure there are zip files, but Python doesn't recognize those zip files as zip files. Why is that?
my code:
os.chdir(boardpath)
# zf = zipfile.ZipFile('download_all.zip', mode='w')
z = zipfile.ZipFile('download_all.zip', 'w') #creating zip download_all.zip file
for path, dirs, files in os.walk(boardpath):
for file in files:
print file
if file.endswith('.zip'): # find all zip files
print ('adding', file)
z.write(file) # error shows: doesn't file is a str object, not a zip file
z.close()
z = zipfile.ZipFile("download_all.zip")
z.printdir()
I tried:
file.printdir()
# I got the following error: AttributeError: 'str' object has no attribute 'printdir'
zipfile.Zipfile.write(name), name actually stands for full file path, not just filename.
import os #at the top
if file.endswith('.zip'): # find all zip files
filepath = os.path.join(path, file)
print ('adding', filepath)
z.write(filepath) # no error
As stated in the ZipFile.write's doc, the filename argument must be relative to the archive root. So the following line:
z.write(file)
Should be:
z.write(os.path.relpath(os.path.join(path, file)))
The files that os/walk() yields are lists of filenames. These filenames are just strings (which don't have a printdir() method).
You want to use the context management while opening up the zip file archive and writing to it for each file that you find, hence the use of with. In addition, since you're walking through a directory structure, you need to full qualify each file's path.
import os
import Zipfile
with zipfile.ZipFile('download_all.zip', 'w') as zf:
for path, dirs, files in os.walk('/some_path'):
for file in files:
if file.endswith('.zip'):
zf.write(os.path.join(path, file))

How to extract a file within a folder within a zip?

I need to extract a file called Preview.pdf from a folder called QuickLooks inside of a zip file.
Right now my code looks a little like this:
with ZipFile(newName, 'r') as newName:
newName.extract(\QuickLooks\Preview.pdf)
newName.close()
(In this case, newName has been set equal to the full path to the zip).
It's important to note that the backslash is correct in this case because I'm on Windows.
The code doesn't work; here's the error it gives:
Traceback (most recent call last):
File "C:\Users\Asit\Documents\Evam\Python_Scripts\pageszip.py", line 18, in <module>
ZF.extract("""QuickLooks\Preview.pdf""")
File "C:\Python33\lib\zipfile.py", line 1019, in extract
member = self.getinfo(member)
File "C:\Python33\lib\zipfile.py", line 905, in getinfo
'There is no item named %r in the archive' % name)
KeyError: "There is no item named 'QuickLook/Preview.pdf' in the archive"
I'm running the Python script from inside Notepad++, and taking the output from its console.
How can I accomplish this?
Alternatively, how could I extract the whole QuickLooks folder, move out Preview.pdf, and then delete the folder and the rest of it's contents?
Just for context, here's the rest of the script. It's a script to get a PDF of a .pages file. I know there are bonified converters out there; I'm just doing this as an excercise with some sort of real-world application.
import os.path
import zipfile
from zipfile import *
import sys
file = raw_input('Enter the full path to the .pages file in question. Please note that file and directory names cannot contain any spaces.')
dir = os.path.abspath(os.path.join(file, os.pardir))
fileName, fileExtension = os.path.splitext(file)
if fileExtension == ".pages":
os.chdir(dir)
print (dir)
fileExtension = ".zip"
os.rename (file, fileName + ".zip")
newName = fileName + ".zip" #for debugging purposes
print (newName) #for debugging purposes
with ZipFile(newName, 'w') as ZF:
print("I'm about to list names!")
print(ZF.namelist()) #for debugging purposes
ZF.extract("QuickLook/Preview.pdf")
os.rename('Preview.pdf', fileName + '.pdf')
finalPDF = fileName + ".pdf"
print ("Check out the PDF! It's located at" + dir + finalPDF + ".")
else:
print ("Sorry, this is not a valid .pages file.")
sys.exit
I'm not sure if the import of Zipfile is redundant; I read on another SO post that it was better to use from zipfile import * than import zipfile. I wasn't sure, so I used both. =)
EDIT: I've changed the code to reflect the changes suggested by Blckknght.
Here's something that seems to work. There were several issues with your code. As I mentioned in a comment, the zipfile must be opened with mode 'r' in order to read it. Another is that zip archive member names always use forward slash / characters in their path names as separators (see section 4.4.17.1 of the PKZIP Application Note). It's important to be aware that there's no way to extract a nested archive member to a different subdirectory with Python's currentzipfilemodule. You can control the root directory, but nothing below it (i.e. any subfolders within the zip).
Lastly, since it's not necessary to rename the .pages file to .zip — the filename you passZipFile() can have any extension — I removed all that from the code. However, to overcome the limitation on extracting members to a different subdirectory, I had to add code to first extract the target member to a temporary directory, and then copy that to the final destination. Afterwards, of course, this temporary folder needs to deleted. So I'm not sure the net result is much simpler...
import os.path
import shutil
import sys
import tempfile
from zipfile import ZipFile
PREVIEW_PATH = 'QuickLooks/Preview.pdf' # archive member path
pages_file = input('Enter the path to the .pages file in question: ')
#pages_file = r'C:\Stack Overflow\extract_test.pages' # hardcode for testing
pages_file = os.path.abspath(pages_file)
filename, file_extension = os.path.splitext(pages_file)
if file_extension == ".pages":
tempdir = tempfile.gettempdir()
temp_filename = os.path.join(tempdir, PREVIEW_PATH)
with ZipFile(pages_file, 'r') as zipfile:
zipfile.extract(PREVIEW_PATH, tempdir)
if not os.path.isfile(temp_filename): # extract failure?
sys.exit('unable to extract {} from {}'.format(PREVIEW_PATH, pages_file))
final_PDF = filename + '.pdf'
shutil.copy2(temp_filename, final_PDF) # copy and rename extracted file
# delete the temporary subdirectory created (along with pdf file in it)
shutil.rmtree(os.path.join(tempdir, os.path.split(PREVIEW_PATH)[0]))
print('Check out the PDF! It\'s located at "{}".'.format(final_PDF))
#view_file(final_PDF) # see Bonus below
else:
sys.exit('Sorry, that isn\'t a .pages file.')
Bonus: If you'd like to actually view the final pdf file from the script, you can add the following function and use it on the final pdf created (assuming you have a PDF viewer application installed on your system):
import subprocess
def view_file(filepath):
subprocess.Popen(filepath, shell=True).wait()

python tarfile without full path

I made a small script as below to read group of files and tar them, its all working fine accept that the compressed file contain full path of the files when uncompressed. Is there a way to do it without the directory structure?
compressor = tarfile.open(PATH_TO_ARCHIVE + re.sub('[\s.:"-]+', '',
str(datetime.datetime.now())) + '.tar.gz', 'w:gz')
for file in os.listdir(os.path.join(settings.MEDIA_ROOT, PATH_CSS_DB_OUT)):
compressor.add(os.path.join(settings.MEDIA_ROOT, PATH_CSS_DB_OUT) + file)
compressor.close()
Take a look at the TarFile.add signature:
... If given, arcname specifies an alternative name for the file in the archive.
I created a context manager for changing the current working directory fo handling this with tar files.
import contextlib
#contextlib.contextmanager
def cd_change(tmp_location):
cd = os.getcwd()
os.chdir(tmp_location)
try:
yield
finally:
os.chdir(cd)
Then, to package everything up in your case:
with cd_change(os.path.join(settings.MEDIA_ROOT, PATH_CSS_DB_OUT)):
for file in os.listdir('.'):
compressor.add(file)

Categories