def _gatherLiveFileUrls(self, part, relativeDir, extradir): #_getImportConfig(self, recursive=0, type="makeFlat") if not part.live: return [] config = part._getImportConfig(recursive=1, type="useFolders") include = config[0] exclude = config[1] recursive = config[2] type = config[3] path = config[4] if not path: return [] importService = components.classes["@activestate.com/koFileImportingService;1"].\ getService(components.interfaces.koIFileImportingService) filenames = set(importService.findCandidateFiles(part, path, include, exclude, recursive)) flist = [] for name in filenames: diskfile = os.path.abspath(name) if not os.path.isfile(diskfile): continue url = uriparse.localPathToURI(diskfile) dest = uriparse.RelativizeURL(relativeDir, url) if extradir: dest = os.path.join(extradir, dest) flist.append((diskfile, dest)) return flist
def serializePref(stream, pref, prefType, prefName=None, basedir=None): """Serialize one preference to a stream as appropriate for its type. Some preferences, e.g. those in ordered preferences, may not have names. """ log.debug("Serialzing: '%s', with type '%s', value '%s'", prefName, prefType, pref) if prefType == "string": attrs = {} if prefName: attrs['id'] = cgi_escape(prefName, 1) # serialize string prefs as UTF-8 if basedir: try: relative = uriparse.RelativizeURL(basedir, pref) if relative != pref: if pref.find("://") > -1: attrs['relative'] = 'url' else: attrs['relative'] = 'path' if not pref.endswith(relative): # The problem with relativizing is that it also %-encodes # the usual characters, but that will happen later in # the serialization process, so don't do it here. relative2 = urllib.unquote(relative) if pref.endswith(relative2): pref = relative2 else: log.warn(("Possible problem in serializePref: " + "RelativizeURL(pref:%s) => %s not " + "found at end of pref, unquoted to %s"), pref, relative, relative2) pref = relative else: pref = relative except Exception, e: # XXX quick fix bug 65913 log.exception(e) pass # pass and use original value # This line causes multiple-entification, as _xmlencode # will also call cgi_escape #pref = cgi_escape(pref) data = u' <string' for a, v in attrs.items(): data += ' %s="%s"' % (a, v) data += u'>%s</string>%s' % (_xmlencode(pref), newl) data = data.encode("utf-8") stream.write(data)
def serializePref(stream, pref, prefType, prefName=None, basedir=None): """Serialize one preference to a stream as appropriate for its type. Some preferences, e.g. those in ordered preferences, may not have names. """ log.debug("Serialzing: '%s', with type '%s', value '%s'", prefName, prefType, pref ) if prefType == "string": attrs = {} if prefName: attrs['id'] = cgi_escape(prefName,1) if basedir: try: relative = uriparse.RelativizeURL(basedir, pref) if relative != pref: if pref.find("://") > -1: attrs['relative']='url' else: attrs['relative']='path' if not pref.endswith(relative): # The problem with relativizing is that it also %-encodes # the usual characters, but that will happen later in # the serialization process, so don't do it here. relative2 = urllib.unquote(relative) if pref.endswith(relative2): pref = relative2 else: log.warn(("Possible problem in serializePref: " + "RelativizeURL(pref:%s) => %s not " + "found at end of pref, unquoted to %s"), pref, relative, relative2) pref = relative else: pref = relative except Exception as e: # XXX quick fix bug 65913 log.exception(e) pass # pass and use original value # This line causes multiple-entification, as _xmlencode # will also call cgi_escape #pref = cgi_escape(pref) data = u' <string' for a,v in attrs.items(): data += ' %s="%s"' % (a,v) data += u'>%s</string>%s' % (_xmlencode(pref), newl) stream.write(data) elif prefType in ("boolean"): if prefName is None: stream.write(' <%s>%d</%s>%s' % (prefType, pref, prefType, newl)) else: stream.write(' <%s id="%s">%d</%s>%s'\ % (prefType, cgi_escape(prefName,1), pref, prefType, newl)) elif prefType in ("long", "double"): if prefName is None: stream.write(' <%s>%s</%s>%s' % (prefType, cgi_escape(str(pref)), prefType, newl)) else: stream.write(' <%s id="%s">%s</%s>%s'\ % (prefType, cgi_escape(prefName,1), cgi_escape(str(pref)), prefType, newl)) else: try: pref.serialize(stream, basedir) except AttributeError: # 'pref' cannot be serialized (Because of PyXPCOM interface # flattening we do not need to QI to koISerializable to check.) log.error("preference '%s' (a %s) is unserializable", prefName, pref) raise except TypeError as e: log.error("cannot serialize %r %s", pref, str(e))
def _packageParts(self, packagePath, partList=None, orig_project=None, live=0, extradir=1, overwrite=0): # setup a temporary project file, as we may need to do modifications # that shoule only be in the packaged version if packagePath.find('.kpz') == -1: zipfilename = packagePath+'.kpz' else: zipfilename = packagePath if self.debug: print "zipfilename [%s]" % zipfilename if os.path.exists(zipfilename): if overwrite: os.unlink(zipfilename) else: err = 'A package with the same name already exists at that location.' self.lastErrorSvc.setLastError(1, err) raise ServerException(nsError.NS_ERROR_ILLEGAL_VALUE, err) try: projectName = os.path.splitext(os.path.basename(packagePath))[0] if orig_project: newproject = orig_project.clone() else: newproject = UnwrapObject(components.classes["@activestate.com/koProject;1"] .createInstance(components.interfaces.koIProject)) newproject.create() newproject.live = live newproject._url = os.path.join(os.path.dirname(zipfilename), 'package.kpf') tmp_project_localPath = uriparse.URIToLocalPath(newproject._url) newproject.name = projectName if self.debug: print "newproject._url [%s]" % newproject._url if partList: # clone parts and add them to the project self._clonePartList(newproject, partList) # figure out a base path for all the parts newproject._relativeBasedir = os.path.commonprefix(newproject._urlmap.keys()) if not newproject._relativeBasedir: newproject._relativeBasedir = os.path.dirname(newproject._url) if self.debug: print "using relative base [%s]" % newproject._relativeBasedir import zipfile if not self.test: zf = zipfile.ZipFile(str(zipfilename), 'w') # look at all the url's in the project, copy files, remove parts, etc. # as necessary extraDirName = None if extradir: extraDirName = newproject.name fix_drive_re = re.compile(r'^(?:file:\/\/\/)?(?:(\w):)?(.*)$') flist = set() for source in newproject._urlmap: part = newproject._urlmap[source] # gather files from live folders if part.live and hasattr(part, 'refreshChildren'): if newproject.live or part._parent.live: continue flist = flist.union(self._gatherLiveFileUrls(part, newproject._relativeBasedir, extraDirName)) continue if 'url' in part._tmpAttributes and \ part._tmpAttributes['url'] == part._attributes['url']: dest = part._tmpAttributes['relativeurl'] else: dest = uriparse.RelativizeURL(newproject._relativeBasedir, part._attributes['url']) diskfile = uriparse.URIToLocalPath(part._attributes['url']) # XXX FIXME this is *VERY HACKY*. I've done a quick fix, but what the !? # we should never get a full path in dest, it should be relative if dest.find('file:')==0: try: dest = fix_drive_re.sub(r'\1\2',dest) except Exception, e: dest = fix_drive_re.sub(r'\2',dest) # we do not add directories if os.path.isfile(diskfile): part._attributes['url'] = dest if extraDirName: dest = os.path.join(extraDirName, dest) if self.debug: print "diskfile [%r] dest[%r]" % (diskfile, dest) flist.add((diskfile, dest)) if orig_project: koProjectFile = orig_project.getFile() projectDirName = koProjectFile.dirName if koProjectFile.isLocal: # For each file in # .../.komodotools/D/f # write out fullpath => .komodotools/D/f ktools = koToolbox2.PROJECT_TARGET_DIRECTORY toolboxPath = os.path.join(projectDirName, ktools) if os.path.exists(toolboxPath): self._archiveDir(zf, projectDirName, toolboxPath) # Now write out any referenced local files and folders, # but only if they're relative to the project's home. pathPairs = [(uriparse.URIToLocalPath(x), x) for x in orig_project.getAllContainedURLs() if x.startswith("file://")] for p, url in pathPairs: if os.path.isdir(p): if p.startswith(projectDirName): self._archiveDir(zf, projectDirName, p) else: self._archiveDirUnderBasename(zf, p) part = newproject.getChildByURL(url) part.url = UnwrapObject(part).name elif os.path.isfile(p): if p.startswith(projectDirName): zf.write(p, p[len(projectDirName) + 1:]) else: zf.write(p, os.path.basename(p)) part = newproject.getChildByURL(url) part.url = UnwrapObject(part).get_name() # get a list of all the icons that are not in chrome so we can package # them iconlist = self._gatherIcons(newproject) for icondata in iconlist: source = icondata[0] if extraDirName: dest = os.path.join(extraDirName, icondata[1]) else: dest = icondata[1] if self.debug: print "icon diskfile [%r] dest[%r]" % (source,dest) if not self.test: zf.write(str(source), str(dest)) # save the temporary project file, add it to the zipfile, then delete it newproject.save() # save the new project if extraDirName: project_filename = os.path.join(extraDirName, os.path.basename(tmp_project_localPath)) else: project_filename = os.path.basename(tmp_project_localPath) if self.debug: print "writing project to zip as [%r]" % project_filename if not self.test: zf.write(str(tmp_project_localPath), str(project_filename)) zf.close()
def test_relativize(self): for base, rel, fullpath, common in self.relative: path = uriparse.RelativizeURL(base, fullpath) self.failUnlessSamePath(path, rel)