I am trying this example from Byte of Python, Chapter 10. I can't seem to get this zip to work. I am not sure if the syntax for windows is written correctly or not. I have tried running from interpreter and as a script and both return Backup FAILED. Anyone have any clues?

#!/usr/bin/python/Trident Module saves
# Filename: backup_ver1.py
import sys
import os
import time

# 1. The files and directories to be backed up are specified in a list.
source = [r'C:\Python32', r'C:\Python27'] 

# If you are using Windows, use source = [r'C:\Documents', r'D:\Work'] or something
# 2. The backup must be stored in a main backup directory

target_dir = r'C:\TestBackup\Backup'

# 3. The files are backed up into a zip file.
# 4. The name of the zip archive is the current date and time
target = target_dir + time.strftime('%Y%m%d%H%M%S') + 'zip'

# 5. We use the zip command (in Unix/Linux) to put the files in a zip archive
zip_command = "zip '%s' %s" % (target, ' '.join(source))

# Run the backup
if os.system(zip_command) == 0:
    print 'Successful backup to', target
else:
    print 'Backup FAILED'

Use the Command class in this code snippet to get your shell command's output

com = Command(zip_command).run()
print(com.output)
print(com.error)
if com.failed:
    print('BACKUP FAILED!')
else:
    print('Successful backup to ' + target)

os.system() is deprecated in favor of the subprocess module.

You may also consider using module zipfile instead of an external command.

Edited 3 Years Ago by Gribouillis

Thank you, Gribouillis. This does help me understand what is going on. It returns, 'zip' is not recognized as an internal or external command, operable program or batch file.
BACKUP FAILED! Am I missing an module import or is zip not recognized properly in this coding? zip shows up as purple when I type it in so it seems to be built-in to me.

#!/usr/bin/python/Trident Module saves
# Filename: backup_ver1.py
import sys, os, time, itertools

class Command(object):
    """Run a command and capture it's output string, error string and exit status"""

    def __init__(self, command):
        self.command = command

    def run(self, shell=True):
        import subprocess as sp
        process = sp.Popen(self.command, shell = shell, stdout = sp.PIPE, stderr = sp.PIPE)
        self.pid = process.pid
        self.output, self.error = process.communicate()
        self.failed = process.returncode
        return self

    @property
    def returncode(self):
        return self.failed

source = [r'C:\Python32', r'C:\Python27'] 
target_dir = r'C:\TestBackup\Backup'
target = target_dir + time.strftime('%Y%m%d%H%M%S') + 'zip'
zip_command="zip -qr '%s' %s" % (target, ' '.join(source))
com = Command(zip_command).run()
print(com.output)
print(com.error)
if com.failed:
    print('BACKUP FAILED!')
else:
    print('Successful backup to ' + target)

It returns, 'zip' is not recognized as an internal or external command

zip command works only on linux.
You can get it in windows by install GnuWin32 project,and to PATH in environment variables,
you need to add ;C:\%PROGRAMFILES%\GnuWin32\bin

But you shold really use module zipfile as suggsest by Grib.
zipfile is crossplatform and work on all system.

A fast rewrite of code to something like,with use of zipfile module.

import glob, os, time
import zipfile

source = r'C:\test_1\*'
target_dir = r'C:\test_2/'
target = target_dir + time.strftime('%Y%m%d') + '.zip'

f_zip = zipfile.ZipFile(target, "w")
for name in glob.glob(source):
    f_zip.write(name, os.path.basename(name), zipfile.ZIP_DEFLATED)
f_zip.close()

Edited 3 Years Ago by snippsat

Comments
good help
import zlib, os, zipfile

def zipdir(path, zf):
    for root, dirs, files in os.walk(path):
        for file in files:
            zf.write(os.path.join(root, file))

if __name__ == '__main__':
    zf = zipfile.ZipFile('C:\\TestBackup\\Python.zip', mode='w')
    zipdir('C:\\Python32', zf)
    zipdir('C:\\Python27', zf)
    zf.close()

Got it. It took me a little while to figure out how to get 2 different files in the zip but this works. Yeah, the differences in operating systems and between 32 bit and 64 bit modules is pretty annoying. Just annoyed that an example from the online book doesn't work and I spend half a day trying to figure out how to do it. I guess that's one way to learn but making this class very hard to keep up.

Thank you!

Went back to the example and added in how to set the name to include time and provide Success feedback.

import zlib, os, zipfile, time

def zipdir(path, zf):
    for root, dirs, files in os.walk(path):
        for file in files:
            zf.write(os.path.join(root, file))

if __name__ == '__main__':
    source1='C:\\Python32'
    source2='C:\\Python27'
    target_dir='C:\\TestBackup'
    target = target_dir+'\\'+'Python'+time.strftime('%Y%m%d%H%M%S') + '.zip'
    zf = zipfile.ZipFile(target, mode='w')
    zipdir(source1, zf)
    zipdir(source2, zf)
    print 'Zipped', source1,'+', source2, 'to', target
    # Zipped C:\Python32 + C:\Python27 to C:\TestBackup\Python20130312123156.zip
    zf.close()
else:
    print 'Backup FAILED'

Edited 3 Years Ago by jeremywduncan

This question has already been answered. Start a new discussion instead.