2

I have a functionality in my Python which backups a particular directory everyday. The backup steps include compressing the directory. I am using shutil.make_archive to compress the directory.

But now I am facing a permission issue when the directory I compress contains files which I do not have access to.

In this case, I just want to skip that file and then go ahead with compression of the remaining files. How do I achieve this ?

I searched SO and came across this answer, which shows how to zip a directory from using zipfile library. In this case, I can just check if a particular file throws an exception and ignore it.

Is this the only way or is there an easier way ?

My code (just uses shutil.make_archive):

shutil.make_archive(filename, "zip", foldername)

The code in the answer which I have modified for my use:

def zipdir(path, ziph):
    # ziph is zipfile handle
    for root, dirs, files in os.walk(path):
        for file in files:
            try:
                ziph.write(os.path.join(root, file))
            except PermissionError as e:
                continue

if __name__ == '__main__':
    zipf = zipfile.ZipFile('Python.zip', 'w', zipfile.ZIP_DEFLATED)
    zipdir('tmp/', zipf)
    zipf.close()

Please tell me if there is an easier/efficient solution to my issue.

Community
  • 1
  • 1
v1shnu
  • 2,211
  • 8
  • 39
  • 68

1 Answers1

0

I know this is ancient history, but you can use copytree and pass in a custom copy function that suppresses the permissions errors:

import os

#Adapted from python shutil source code.
def copyIgnorePermissionError(src, dst, *, follow_symlinks=True):
"""Copy data and metadata. Return the file's destination.
Metadata is copied with copystat(). Please see the copystat function
for more information.
The destination may be a directory.
If follow_symlinks is false, symlinks won't be followed. This
resembles GNU's "cp -P src dst".
"""
if os.path.isdir(dst):
    dst = os.path.join(dst, os.path.basename(src))

#try the copy. If it gives us any lip about permission errors, 
#we're going to just suppress them here. If for some reason 
#a non-permission error happens, then raise it.
try:
  copyfile(src, dst, follow_symlinks=follow_symlinks)
  copystat(src, dst, follow_symlinks=follow_symlinks)
except PermissionError:
  pass
except Exception as e:
  raise(e)

finally:
  return dst

#copy the source to some safe destination
shutil.copytree(aSource, aCopyDestination, copy_function=copyIgnorePermissionError)

That will make a copy of all the files and directories that you can access at your permission level. Then you can use shutil.make_archive to create the archive of this copy, then delete the copy.

CodeOwl
  • 662
  • 2
  • 9
  • 23