Gaudi Framework, version v23r6

Home   Generated: Wed Jan 30 2013
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Classes | Functions
ZipPythonDir Namespace Reference

Classes

class  ZipdirError
 Class for generic exception coming from the zipdir() function. More...
 

Functions

def _zipChanges
 Collect the changes to be applied to the zip file.
 
def checkEncoding
 
def zipdir
 Make a zip file out of a directory containing python modules.
 
def main
 Main function of the script.
 

Function Documentation

def ZipPythonDir._zipChanges (   directory,
  infolist 
)
private

Collect the changes to be applied to the zip file.

Parameters
directory,:directory to be packed in the zip file
infolist,:list of ZipInfo objects already contained in the zip archive
Returns
: tuple of (added, modified, untouched, removed) entries in the directory with respect to the zip file

Definition at line 30 of file ZipPythonDir.py.

30 
31 def _zipChanges(directory, infolist):
32  # gets the dates of the files in the zip archive
33  infos = {}
34  for i in infolist:
35  fn = i.filename
36  if fn.endswith(".pyc"):
37  fn = fn[:-1]
38  infos[fn] = i.date_time
39 
40  # gets the changes
41  added = []
42  modified = []
43  untouched = []
44  removed = []
45  all_files = set()
46 
47  log = logging.getLogger("zipdir")
48  dirlen = len(directory) + 1
49  for root, dirs, files in os.walk(directory):
50  if "lib-dynload" in dirs:
51  # exclude the directory containing binary modules
52  dirs.remove("lib-dynload")
53  arcdir = root[dirlen:]
54  for f in files:
55  ext = os.path.splitext(f)[1]
56  if ext == ".py": # extensions that can enter the zip file
57  filename = os.path.join(arcdir, f)
58  all_files.add(filename)
59  if filename not in infos:
60  action = "A"
61  added.append(filename)
62  else:
63  filetime = time.localtime(os.stat(os.path.join(directory,filename))[stat.ST_MTIME])[:6]
64  if filetime > infos[filename]:
65  action = "M"
66  modified.append(filename)
67  else:
68  action = "U"
69  untouched.append(filename)
70  if action in ['U']:
71  log.debug(" %s -> %s", action, filename)
72  else:
73  log.info(" %s -> %s", action, filename)
74  # cases that can be ignored
75  elif ext not in [".pyc", ".pyo", ".stamp", ".cmtref"] and not f.startswith('.__afs'):
76  raise ZipdirError("Cannot add '%s' to the zip file, only '.py' are allowed." % os.path.join(arcdir, f))
77  # check for removed files
78  for filename in infos:
79  if filename not in all_files:
80  removed.append(filename)
81  log.info(" %s -> %s", "R", filename)
82  return (added, modified, untouched, removed)
def ZipPythonDir.checkEncoding (   path)
Check that a file honors the declared encoding (default ASCII for Python 2
and UTF-8 for Python 3).

Raises a UnicodeDecodeError in case of problems.

See http://www.python.org/dev/peps/pep-0263/

Definition at line 83 of file ZipPythonDir.py.

83 
84 def checkEncoding(path):
85  '''
86  Check that a file honors the declared encoding (default ASCII for Python 2
87  and UTF-8 for Python 3).
88 
89  Raises a UnicodeDecodeError in case of problems.
90 
91  See http://www.python.org/dev/peps/pep-0263/
92  '''
93  # default encoding
94  if sys.version_info[0] <= 2:
95  enc = 'ascii'
96  else:
97  enc = 'utf-8'
98 
99  # find the encoding of the file, if specified
100  enc_exp = re.compile(r"coding[:=]\s*([-\w.]+)")
101  f = open(path)
102  count = 2 # number of lines
103  while count:
104  m = enc_exp.search(f.readline())
105  if m:
106  enc = m.group(1)
107  break
108  count -= 1
109 
110  logging.getLogger('checkEncoding').debug('checking encoding %s on %s', enc, path)
111  # try to read the file with the declared encoding
112  codecs.open(path, encoding=enc).read()
113 
def ZipPythonDir.main (   argv = None)

Main function of the script.

Parse arguments and call zipdir() for each directory passed as argument

Definition at line 175 of file ZipPythonDir.py.

176 def main(argv = None):
177  from optparse import OptionParser
178  parser = OptionParser(usage = "%prog [options] directory1 [directory2 ...]")
179  parser.add_option("--no-pyc", action = "store_true",
180  help = "copy the .py files without pre-compiling them")
181  parser.add_option("--quiet", action = "store_true",
182  help = "do not print info messages")
183  parser.add_option("--debug", action = "store_true",
184  help = "print debug messages (has priority over --quiet)")
185 
186  if argv is None:
187  argv = sys.argv
188  opts, args = parser.parse_args(argv[1:])
189 
190  if not args:
191  parser.error("Specify at least one directory to zip")
192 
193  # Initialize the logging module
194  level = logging.INFO
195  if opts.quiet:
196  level = logging.WARNING
197  if opts.debug:
198  level = logging.DEBUG
199  logging.basicConfig(level = level)
200 
201  if "GAUDI_BUILD_LOCK" in os.environ:
202  _scopedLock = locker.LockFile(os.environ["GAUDI_BUILD_LOCK"], temporary = True)
203  # zip all the directories passed as arguments
204  for d in args:
205  zipdir(d, opts.no_pyc)
def ZipPythonDir.zipdir (   directory,
  no_pyc = False 
)

Make a zip file out of a directory containing python modules.

Definition at line 115 of file ZipPythonDir.py.

116 def zipdir(directory, no_pyc = False):
117  log = logging.getLogger("zipdir")
118  if not os.path.isdir(directory):
119  raise OSError(20, "Not a directory", directory)
120  msg = "Zipping directory '%s'"
121  if no_pyc:
122  msg += " (without pre-compilation)"
123  log.info(msg, directory)
124  filename = os.path.realpath(directory + ".zip")
125 
126  # Open the file in read an update mode
127  if os.path.exists(filename):
128  zipFile = open(filename, "r+b")
129  else:
130  # If the file does not exist, we need to create it.
131  # "append mode" ensures that, in case of two processes trying to
132  # create the file, they do not truncate each other file
133  zipFile = open(filename, "ab")
134 
135  locker.lock(zipFile)
136  try:
137  if zipfile.is_zipfile(filename):
138  infolist = zipfile.ZipFile(filename).infolist()
139  else:
140  infolist = []
141  (added, modified, untouched, removed) = _zipChanges(directory, infolist)
142  if added or modified or removed:
143  tempBuf = StringIO()
144  z = zipfile.PyZipFile(tempBuf, "w", zipfile.ZIP_DEFLATED)
145  for f in added + modified + untouched:
146  src = os.path.join(directory, f)
147  checkEncoding(src)
148  if no_pyc:
149  log.debug("adding '%s'", f)
150  z.write(src, f)
151  else:
152  # Remove the .pyc file to always force a re-compilation
153  if os.path.exists(src + 'c'):
154  log.debug("removing old .pyc for '%s'", f)
155  os.remove(src + 'c')
156  log.debug("adding '%s'", f)
157  z.writepy(src, os.path.dirname(f))
158  z.close()
159  zipFile.seek(0)
160  zipFile.write(tempBuf.getvalue())
161  zipFile.truncate()
162  log.info("File '%s' closed", filename)
163  else:
164  log.info("Nothing to do on '%s'", filename)
165  except UnicodeDecodeError, x:
166  log.error("Wrong encoding in file '%s':", src)
167  log.error(" %s", x)
168  log.error("Probably you forgot the line '# -*- coding: utf-8 -*-'")
169  sys.exit(1)
170  finally:
171  locker.unlock(zipFile)
172  zipFile.close()

Generated at Wed Jan 30 2013 17:13:53 for Gaudi Framework, version v23r6 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004