24 from io
import BytesIO
47 if fn.endswith(
".pyc"):
49 infos[fn] = i.date_time
58 log = logging.getLogger(
"zipdir")
59 dirlen = len(directory) + 1
60 for root, dirs, files
in os.walk(directory):
61 if "lib-dynload" in dirs:
63 dirs.remove(
"lib-dynload")
64 arcdir = root[dirlen:]
66 ext = os.path.splitext(f)[1]
68 filename = os.path.join(arcdir, f)
69 all_files.add(filename)
70 if filename
not in infos:
72 added.append(filename)
74 filetime = time.localtime(
75 os.stat(os.path.join(directory,
76 filename))[stat.ST_MTIME])[:6]
77 if filetime > infos[filename]:
79 modified.append(filename)
82 untouched.append(filename)
84 log.debug(
" %s -> %s", action, filename)
86 log.info(
" %s -> %s", action, filename)
88 elif (ext
not in [
".pyc",
".pyo",
".stamp",
".cmtref",
".confdb"]
89 and not f.startswith(
'.__afs')):
91 "Cannot add '%s' to the zip file, only '.py' are allowed." 92 % os.path.join(arcdir, f))
94 for filename
in infos:
95 if filename
not in all_files:
96 removed.append(filename)
97 log.info(
" %s -> %s",
"R", filename)
98 return (added, modified, untouched, removed)
103 Check that a file honors the declared encoding (default ASCII for Python 2 104 and UTF-8 for Python 3). 106 Raises a UnicodeDecodeError in case of decoding problems and LookupError if 107 the specified codec does not exists. 109 See http://www.python.org/dev/peps/pep-0263/ 111 from itertools
import islice
114 if sys.version_info[0] <= 2:
120 enc_exp = re.compile(
r"coding[:=]\s*([-\w.]+)")
121 for l
in islice(fileObj, 2):
122 m = enc_exp.search(l.decode(
'ascii'))
127 if hasattr(fileObj,
'name'):
128 logging.getLogger(
'checkEncoding').debug(
'checking encoding %s on %s',
131 logging.getLogger(
'checkEncoding').debug(
132 'checking encoding %s on file object', enc)
135 codecs.getreader(enc)(fileObj).
read()
140 filename = os.path.realpath(directory +
".zip")
141 log = logging.getLogger(
"zipdir")
142 if not os.path.isdir(directory):
143 log.warning(
'directory %s missing, creating empty .zip file',
145 open(filename,
"ab").close()
147 msg =
"Zipping directory '%s'" 149 msg +=
" (without pre-compilation)" 150 log.info(msg, directory)
153 if os.path.exists(filename):
154 zipFile = open(filename,
"r+b")
159 zipFile = open(filename,
"ab")
162 if zipfile.is_zipfile(filename):
163 infolist = zipfile.ZipFile(filename).infolist()
166 (added, modified, untouched, removed) =
_zipChanges(
168 if added
or modified
or removed:
170 z = zipfile.PyZipFile(tempBuf,
"w", zipfile.ZIP_DEFLATED)
171 for f
in added + modified + untouched:
172 src = os.path.join(directory, f)
175 log.debug(
"adding '%s'", f)
179 if os.path.exists(src +
'c'):
180 log.debug(
"removing old .pyc for '%s'", f)
182 log.debug(
"adding '%s'", f)
183 z.writepy(src, os.path.dirname(f))
186 zipFile.write(tempBuf.getvalue())
188 log.info(
"File '%s' closed", filename)
190 log.info(
"Nothing to do on '%s'", filename)
191 except UnicodeDecodeError
as x:
192 log.error(
"Wrong encoding in file '%s':", src)
194 log.error(
"Probably you forgot the line '# -*- coding: utf-8 -*-'")
205 from optparse
import OptionParser
206 parser = OptionParser(usage=
"%prog [options] directory1 [directory2 ...]")
210 help=
"copy the .py files without pre-compiling them")
212 "--quiet", action=
"store_true", help=
"do not print info messages")
216 help=
"print debug messages (has priority over --quiet)")
220 opts, args = parser.parse_args(argv[1:])
223 parser.error(
"Specify at least one directory to zip")
228 level = logging.WARNING
230 level = logging.DEBUG
231 logging.basicConfig(level=level)
238 if __name__ ==
'__main__':
def checkEncoding(fileObj)
def read(f, regex='.*', skipevents=0)
def _zipChanges(directory, infolist)
def zipdir(directory, no_pyc=False)