import string import pprint import sys import os import ConfigParser import pprint import shutil import tempfile import ltoc import tocfilter import resource import archive import archivebuilder import carchive logfile = None autopath = [] built = {} copyFile = None class Target: def __init__(self, cfg, sectnm, cnvrts): self.children = [] self._dependencies = ltoc.lTOC() # the stuff an outer package will need to use me self.cfg = cfg self.__name__ = 'joe' for optnm in cfg.options(sectnm): cnvrt = cnvrts.get(optnm, 'getstringlist') if cnvrt: f = getattr(self, cnvrt, None) if f: self.__dict__[optnm] = f(cfg.get(sectnm, optnm)) if not hasattr(self, 'name'): self.name = self.__name__ print "Initializing", self.__name__ self.pathprefix = autopath + self.pathprefix self.pathprefix.append(os.path.join(pyinsthome, 'support')) for z in self.zlib: if z in self.cfg.sections(): self.children.append(z) else: raise ValueError, "%s - zlib '%s' does not refer to a sections" \ % (self.name, z) for i in range(len(self.misc)): x = self.misc[i] if x in self.cfg.sections(): if self.cfg.get(x, "type") == 'PYZ': self.zlib.append(x) self.misc[i] = None self.children.append(x) self.misc = filter(None, self.misc) self.edit() self.toc = ltoc.lTOC() for thingie in self.excludes: try: fltr = tocfilter.makefilter(thingie, self.pathprefix) except ValueError: print "Warning: '%s' not found - no filter created" % thingie else: self.toc.addFilter(fltr) if self.exstdlib: self.toc.addFilter(tocfilter.StdLibFilter()) if self.extypes: self.toc.addFilter(tocfilter.ExtFilter(self.extypes)) if self.expatterns: self.toc.addFilter(tocfilter.PatternFilter(self.expatterns)) ##------utilities------## def dump(self): logfile.write("---- %s: %s -----\n" % (self.__class__.__name__, self.name)) pprint.pprint(self.__dict__, logfile) def getstringlist(self, opt): tmp = string.split(opt, ',') return filter(None, map(string.strip, tmp)) def getstring(self, opt): return opt def getbool(self, opt): if opt in ('0','f','F','n','N'): return 0 return 1 ##-----framework-----## def build(self): print "Gathering components of %s" % self.name self.gather() logfile.write("Final Table of Contents for %s:\n" % self.name) pprint.pprint(self.toc.toList(), logfile) print "Creating %s" % self.name self.assemble() ##-----overrideables-----## def edit(self): pass def gather(self): pass def assemble(self): pass class PYZTarget(Target): def __init__(self, cfg, sectnm, cnvrts): Target.__init__(self, cfg, sectnm, cnvrts) # to use a PYZTarget, you'll need imputil and archive archivebuilder.GetCompiled([os.path.join(pyinsthome, 'imputil.py')]) print "pyinsthome:", pyinsthome imputil = resource.makeresource('imputil.py', [pyinsthome]) self._dependencies.append(imputil) archivebuilder.GetCompiled([os.path.join(pyinsthome, 'archive_rt.py')]) archmodule = resource.makeresource('archive_rt.py', [pyinsthome]) self._dependencies.merge(archmodule.dependencies()) self._dependencies.append(archmodule) self.toc.addFilter(archmodule) self.toc.addFilter(imputil) for mod in archmodule.modules: self.toc.addFilter(mod) def edit(self): if self.extypes: print "PYZ target %s ignoring extypes = %s" % (self.__name__, self.extypes) def gather(self): for script in self.dependencies: rsrc = resource.makeresource(script, self.pathprefix) if not isinstance(rsrc, resource.scriptresource): print "Bug alert - Made %s from %s!" % (rsrc, script) self.toc.merge(rsrc.modules) logfile.write("lTOC after expanding 'depends':\n") pprint.pprint(self.toc.toList(), logfile) for thingie in self.includes + self.directories + self.packages: rsrc = resource.makeresource(thingie, self.pathprefix) ## if not isinstance(rsrc, resource.pythonresource): ## print "PYZ target %s ignoring include %s" % (self.name, thingie) ## else: self.toc.merge(rsrc.contents()) logfile.write("lTOC after includes, dir, pkgs:\n") pprint.pprint(self.toc.toList(), logfile) self.toc.addFilter(tocfilter.ExtFilter(['.py', '.pyc', '.pyo'], 1)) logfile.write("Applying the following filters:\n") pprint.pprint(self.toc.filters, logfile) self.toc.filter() def assemble(self): contents = self.toc.toList() if contents: lib = archive.ZlibArchive() lib.build(self.name, archivebuilder.GetCompiled(self.toc.toList())) class CollectTarget(Target): def __init__(self, cfg, sectnm, cnvrts): Target.__init__(self, cfg, sectnm, cnvrts) _rsrcdict = {'COLLECT': resource.dirresource, 'PYZ': resource.zlibresource, 'CARCHIVE': resource.archiveresource} def gather(self): if self.support: # the bare minimum self.toc.merge([resource.makeresource('python20.dll')]) self.toc.merge([resource.makeresource('exceptions.pyc').asBinary()]) # zlib, bindepends, misc, trees, destdir for i in range(len(self.zlib)): # z refers to the section name z = self.zlib[i] nm = self.cfg.get(z, 'name') try: self.toc.merge([resource.makeresource(nm, ['.'])]) except ValueError: # zlibs aren't written if they turn out to be empty self.zlib[i] = None self.zlib = filter(None, self.zlib) if self.zlib: target = built.get(self.zlib[0], None) if target: self.toc.merge(target._dependencies) for script in self.bindepends: rsrc = resource.makeresource(script, self.pathprefix) self.toc.merge(rsrc.binaries) logfile.write('ltoc after bindepends:\n') pprint.pprint(self.toc.toList(), logfile) for thingie in self.misc: if thingie in self.cfg.sections(): name = self.cfg.get(thingie, "name") typ = self.cfg.get(thingie, "type") klass = self._rsrcdict.get(typ, resource.dataresource) rsrc = apply(klass, (name, name)) #now make sure we have the stuff the resource requires target = built.get(thingie, None) if target: self.toc.merge(target._dependencies) else: rsrc = resource.makeresource(thingie, self.pathprefix) self.toc.merge(rsrc.contents()) logfile.write('ltoc after misc:\n') pprint.pprint(self.toc.toList(), logfile) for script in self.script: if string.find(script, '.') == -1: script = script + '.py' rsrc = resource.makeresource(script, self.pathprefix) if rsrc.typ == 'm': rsrc.typ = 's' self.toc.merge([rsrc]) logfile.write('ltoc after scripts:\n') pprint.pprint(self.toc.toList(), logfile) for tree in self.trees: try: rsrc = resource.treeresource('.', tree) except ValueError: print "tree %s not found" % tree else: self.toc.merge(rsrc.contents()) logfile.write('ltoc after trees:\n') pprint.pprint(self.toc.toList(), logfile) self.toc.addFilter(tocfilter.TypeFilter(['d'])) logfile.write("Applying the following filters:\n") pprint.pprint(self.toc.filters, logfile) self.toc.filter() #don't dupe stuff in a zlib that's part of this target if self.zlib: ztoc = ltoc.lTOC() for zlibnm in self.zlib: target = built.get(zlibnm, None) if target: ztoc.merge(target.toc) for i in range(len(self.toc)-1, -1, -1): rsrc = self.toc[i] if isinstance(rsrc, resource.moduleresource) and rsrc in ztoc: del self.toc[i] def assemble(self): if os.path.exists(self.name): if os.path.isdir(self.name): for fnm in os.listdir(self.name): try: os.remove(os.path.join(self.name, fnm)) except: print "Could not delete file %s" % os.path.join(self.name, fnm) else: os.makedirs(self.name) mysite = [] for nm, path, typ in self.toc.toList(): shutil.copy2(path, self.name) if typ == 'z': mysite.append('imputil.FuncImporter(archive.ZlibArchive("%s", 0).get_code).install()' % nm) if mysite: mysite.insert(0, 'import archive, imputil') open(os.path.join(self.name, 'site.py'),'w').write(string.join(mysite, '\n')) class ArchiveTarget(CollectTarget): usefullname = 1 def __init__(self, cfg, sectnm, cnvrts): CollectTarget.__init__(self, cfg, sectnm, cnvrts) archivebuilder.GetCompiled([os.path.join(pyinsthome, 'carchive_rt.py')]) carchmodule = resource.makeresource('carchive_rt.py', [pyinsthome]) self._dependencies.merge(carchmodule.dependencies()) self._dependencies.append(carchmodule) def edit(self): if self.destdir: print "Warning 'destdir = %s' ignored for %s" % (self.destdir, self.name) def gather(self): CollectTarget.gather(self) _cdict = {'s':2,'m':1,'b':1,'x':1,'a':0,'z':0, 'p':1} def assemble(self, pkgnm=None): if pkgnm is None: pkgnm = self.name arch = carchive.CArchive() toc = [] pytoc = [] for nm, path, typ in self.toc.toList(): compress = self._cdict[typ] if typ == 'b' or (self.usefullname and typ in 'ms'): nm = os.path.basename(path) if typ == 'm': pytoc.append((nm, path, compress, typ)) else: toc.append((nm, path, compress, typ)) toc = toc + archivebuilder.GetCompiled(pytoc) arch.build(pkgnm, toc) return arch class FullExeTarget(ArchiveTarget): usefullname = 0 def __init__(self, cfg, sectnm, cnvrts): ArchiveTarget.__init__(self, cfg, sectnm, cnvrts) def gather(self): for script in self.script: #print "FullExeTarget.gather: script is", repr(script) rsrc = resource.makeresource(script, self.pathprefix) rsrc = resource.scriptresource(rsrc.name, rsrc.path) #print " resource is", repr(rsrc) self.toc.merge(rsrc.binaries) ArchiveTarget.gather(self) if not self.zlib: self.toc.merge(rsrc.modules) self._dependencies = ltoc.lTOC() _cdict = {'s':2,'m':0,'b':1,'x':0,'a':0,'z':0} _edict = { (1, 1):'Runw_d.exe', (1, 0):'Runw.exe', (0, 1):'Run_d.exe', (0, 0):'Run.exe'} def assemble(self): pkgname = tempfile.mktemp() arch = ArchiveTarget.assemble(self, pkgname) exe = self._edict[(self.userunw, self.debug)] exe = os.path.normpath(os.path.join(pyinsthome, 'support', exe)) ## copyFile([exe, pkgname], self.name) ## os.remove(pkgname) # Thomas Heller's icon code # my version if self.icon: myexe = tempfile.mktemp() copyFile (exe, myexe) try: from icon import CopyIcons CopyIcons(myexe, self.icon) except ImportError: print "win32api is required for updating icons" print "You should have win32api.pyd and PyWinTypes20.dll" print "in the installation directory." print "Please copy them to Python's DLLS subdirectory" print "(or install Mark Hammond's Win32 extensions)." ## iconfile = None ## for name in self.cfg.sections(): ## if self.cfg.get (name, "type") == "STANDALONE": ## try: ## iconfile = self.cfg.get (name, "iconfile") ## except: ## pass ## if iconfile: ## from icon import CopyIcons ## CopyIcons (myexe, iconfile) copyFile ([myexe, pkgname], self.name) os.remove(myexe) else: copyFile([exe, pkgname], self.name) #os.remove(pkgname) class ExeTarget(FullExeTarget): def __init__(self, cfg, sectnm, cnvrts): FullExeTarget.__init__(self, cfg, sectnm, cnvrts) def edit(self): if not self.script: raise ValueError, "EXE target %s requires 'script=