Hello ,
I am trying to modify a backup script , using the zipfile module , it creates the folder of the day , and inside it the zip file that contains the two source folders , but not the underfolders and the files inside them . here is all the code :

#!/usr/bin/python
#-*- coding:Utf-8 -*-



import os
import time
import sys
import zipfile

target_dir = 'C:\Dossier_target'
today = target_dir + os.sep + time.strftime('%Y%m%d')
now = time.strftime('%H%M%S')

# Creer le sous-repertoire s'il n'existe pas

if not os.path.exists(today):
    os.mkdir(today) # cree le repertoire


source = ['C:\Dossier_source1','C:\Dossier_source2' ]


today = target_dir + os.sep + time.strftime('%Y%m%d')

# L'heure courante est le nom de l'archive zip

now = time.strftime('%H%M%S')

 # Creer le sous-repertoire s'il n'existe pas

if not os.path.exists(today):
    os.mkdir(today) # cree le repertoire

print 'Sauvegarde reussie vers', today

 # Le nom du fichier zip

target = today + os.sep + now 

# 5. Nous utilisons la commande zip pour creer une archive

f = zipfile.ZipFile('%s.zip' %target , 'w')


for i in range(len(source)) :
    f.write(source[i])

Can i know how should i do to have a complete zipping of the two folders source ..

Recommended Answers

All 8 Replies

Here is an example of creating a hierarchies of folders and files and zipping them in an archive. The main argument is to generate the correct sequence of arguments for ZipFile.write(). This is done by post-processing the output of os.walk().

#!/usr/bin/env python
# -*-coding: utf8-*-
import contextlib
import itertools
import os.path
import zipfile

ROOT = 'Haplorhini'
ROOT_TREE = {
    'Tarsiiformes':{
        'Tarsiidae.txt': None,
    },
    'Simiiformes':{
        'Platyrrhini':{
            'Callitrichidae.txt':None,
            'Cebidae.txt':None,
            'Aotidae.txt':None,
            'Pitheciidae.txt':None,
            'Atelidae.txt':None,
        },
        'Catarrhini':{
            'Cercopithecoidea':{
                'Cercopithecidae.txt':None,
            },
            'Hominoidea':{
                'Hylobatidae.txt':None,
                'Hominidae.txt':None,
            },
        },
    },
}

@contextlib.contextmanager
def aswd(path):
    fold = os.getcwd()
    os.chdir(path)
    try:
        yield
    finally:
        os.chdir(fold)

def make_hierarchy(name, dic):
    if not os.path.isdir(name):
        os.mkdir(name)
    with aswd(name):
        for key, value in dic.items():
            if isinstance(value, dict):
                make_hierarchy(key, value)
            else:
                with open(key, 'w') as ofh:
                    ofh.write(key)

def raw_os_walk_sequence(dirs):
    return list(itertools.chain.from_iterable(os.walk(d) for d in dirs))

def modified_sequence(dirs):
    for d, dd, f in raw_os_walk_sequence(dirs):
            for x in f:
                yield os.path.join(d, x)

if __name__ == '__main__':
    make_hierarchy(ROOT, ROOT_TREE)
    with aswd(ROOT):
        dirs = [d for d in os.listdir('.') if os.path.isdir(d)]
        print('RAW OS:WALK() SEQUENCE:')
        for x in raw_os_walk_sequence(dirs):
            print(x)
        print('MODIFIED SEQUENCE:')
        for x in modified_sequence(dirs):
            print(x)

        zip = zipfile.ZipFile(os.path.join(os.path.expanduser('~'), 'result.zip'), 'w')
        for x in modified_sequence(dirs):
            zip.write(x, '/'.join(os.path.split(x)))

''' my output -->
RAW OS:WALK() SEQUENCE:
('Tarsiiformes', [], ['Tarsiidae.txt'])
('Simiiformes', ['Platyrrhini', 'Catarrhini'], [])
('Simiiformes/Platyrrhini', [], ['Atelidae.txt', 'Pitheciidae.txt', 'Callitrichidae.txt', 'Aotidae.txt', 'Cebidae.txt'])
('Simiiformes/Catarrhini', ['Hominoidea', 'Cercopithecoidea'], [])
('Simiiformes/Catarrhini/Hominoidea', [], ['Hylobatidae.txt', 'Hominidae.txt'])
('Simiiformes/Catarrhini/Cercopithecoidea', [], ['Cercopithecidae.txt'])
MODIFIED SEQUENCE:
Tarsiiformes/Tarsiidae.txt
Simiiformes/Platyrrhini/Atelidae.txt
Simiiformes/Platyrrhini/Pitheciidae.txt
Simiiformes/Platyrrhini/Callitrichidae.txt
Simiiformes/Platyrrhini/Aotidae.txt
Simiiformes/Platyrrhini/Cebidae.txt
Simiiformes/Catarrhini/Hominoidea/Hylobatidae.txt
Simiiformes/Catarrhini/Hominoidea/Hominidae.txt
Simiiformes/Catarrhini/Cercopithecoidea/Cercopithecidae.txt

and of course, the file ~/result.zip !
'''

The next step is to handle unicode system paths.

Thank you for the reply , but i just want to modify the code i have putted .

To add the files in the subfolders, you must generate their paths.

Hello again Gribouillis , thank you for explanation , i could fix that issue using a function that zip entire folder , i found it while googling , here again the local back up script that works :

#!/usr/local/bin/python

import shutil
import zipfile
import os
import time
import sys

target_dir = "C:/Documents and Settings/PC/Bureau/Dossier_target"
source= ["C:/Documents and Settings/PC/Bureau/Dossier_source1","C:/Documents and Settings/PC/Bureau/Dossier_source2" ]

string_date = time.strftime('%Y%m%d')
today = os.path.join(target_dir , string_date)

now = time.strftime('%H%M%S')

print today

if not os.path.exists(today):
    os.mkdir(today)            # cree le repertoire



# Le nom du fichier zip
target = today + os.sep + now

print target

source_folder_name = []
target_folder_names = []

for i in range(len(source)) :
    source_folder_name = source[i].split("/")
    print source_folder_name[-1]
    target_folder_names.append("%s/%s"%(target,source_folder_name[-1]))

for i in range(len(target_folder_names)):
    print target_folder_names[i]
    shutil.copytree(source[i],"%s"%target_folder_names[i])

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) + "/")                        
            outFile.writestr(zipInfo, "")

    outFile.close()

zipdir("%s"%target)
shutil.rmtree('%s'%target)
print 'Sauvegarde reussie vers', today

To use it , just put the path of the folder you want to have the backups in , as value of "target_dir" , and put the paths of the folders you want to backup in the list "source" .
for next step , i just need to know a better way to send the file ( . the zip file created ) to an other computer (on windows environnement).

for next step , i just need to know a better way to send the file ( . the zip file created ) to an other computer (on windows environnement).

The easiest way I know to do that is to have a ssh server running on the remote computer and connect using module paramiko.

yes , you have right , but maybe ssh don't work in windows environnement , it could be solved using win32wnet module .

In the past I used copssh on windows and it was very easy to install and use.

Hello , I don't know copssh , thank you for your help .

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.