-
Notifications
You must be signed in to change notification settings - Fork 0
/
unzipr.py
136 lines (110 loc) · 4.27 KB
/
unzipr.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# unzipR - A library for recursively extracting files.
# Copyright (C) 2014 Stoney Jackson <dr.stoney@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
Unzipr determines a files compression algorithm based on the file's
extension. Zip files are extracted into the a directory by the same name as
the zip file minus its extension. So foo.zip is extracted in to a directory
named foo.
New formats can be supports via Unzipr.registerUnzipFormat().
See installRarSupport() at the end of this file for an example.
'''
import pathlib
import shutil
import logging
logger = logging.getLogger(__name__)
def deleteZipFilesFromDirectoryRecursively(directory):
directory = pathlib.Path(directory)
for a_file in directory.iterdir():
if isZipFile(a_file):
a_file.unlink()
elif a_file.is_dir():
deleteZipFilesFromDirectoryRecursively(a_file)
def unzipFileRecursively(zipfile, toDir=None):
'''
If toDir is None, zipfile is extracted to a directory whose name is the same
as the zipfile's name minus its extensions.
'''
zipfile = pathlib.Path(zipfile)
toDir = unzipFile(zipfile, toDir)
unzipFilesInDirectoryRecursively(toDir)
return toDir
def unzipFilesInDirectoryRecursively(directory):
directory = pathlib.Path(directory)
for a_file in directory.iterdir():
logger.debug("processing " + str(a_file))
if isZipFile(a_file):
logger.debug("unzipping " + str(a_file))
unzipFileRecursively(a_file)
elif a_file.is_dir():
logger.debug("recursing " + str(a_file))
unzipFilesInDirectoryRecursively(a_file)
def unzipFile(zipfile, toDir=None):
'''
If toDir is None, zipfile is extracted to a directory whose name is the same
as the zipfile's name minus its extensions.
'''
zipfile = pathlib.Path(zipfile)
if toDir:
toDir = pathlib.Path(toDir)
else:
toDir = zipfile.parent / getFileNameWithoutExtension(zipfile)
shutil.unpack_archive(str(zipfile), str(toDir))
return toDir
def getFileNameWithoutExtension(theFile):
theFile = pathlib.Path(theFile)
extension = getFileExtension(theFile)
return theFile.name[:-len(extension)]
def isZipFile(zipfile):
zipfile = pathlib.Path(zipfile)
isZipFile = zipfile.is_file() and fileHasSupportedExtension(zipfile)
return isZipFile
def fileHasSupportedExtension(zipfile):
zipfile = pathlib.Path(zipfile)
extension = getFileExtension(zipfile)
return isSupportedExtension(extension)
def getFileExtension(theFile):
if len(theFile.suffixes) >= 2:
lastTwoSuffixes = ''.join(theFile.suffixes[-2:])
if lastTwoSuffixes == '.tar.gz':
return lastTwoSuffixes
else:
return theFile.suffix
def isSupportedExtension(extension):
return extension in getSupportedExtensions()
def getSupportedExtensions():
supported_extensions = []
for format_ in shutil.get_unpack_formats():
supported_extensions += format_[1]
return supported_extensions
def registerUnzipFormat(name, extensions, function):
shutil.register_unpack_format(name, extensions, function)
def installRarSupport():
try:
import rarfile
def unrar(zipFile, toDir):
with rarfile.RarFile(zipFile) as rf:
rf.extractall(path=toDir)
registerUnzipFormat('rar', ['.rar'], unrar)
except ImportError:
pass
def install7zipSupport():
if shutil.which('7z'):
import subprocess
def un7zip(zipFile, toDir):
subprocess.call(['7z', 'x', str(zipFile), '-o' + str(toDir)])
registerUnzipFormat('7zip', ['.7z'], un7zip)
installRarSupport()
install7zipSupport()