jar.py

Go to the documentation of this file.
00001 import silme.io
00002 import silme.format
00003 from silme.io.clients import IOClient, FileFormatClient
00004 from silme.core.object import L10nPackage, L10nObject, Blob
00005 
00006 import os
00007 import zipfile
00008 import re
00009 import shutil
00010 import tempfile
00011 
00012 def register(Manager):
00013     Manager.register(JarClient)
00014 
00015 class JarClient(FileFormatClient):
00016     name = 'jar'
00017     desc = "Jar Client"
00018     type = IOClient.__name__
00019     zfile = None
00020 
00021     @classmethod
00022     def matches_path(cls, path):
00023         """
00024         tests if the ioclient should be used for this type of path
00025         example: jar:browser.jar!/content/branding/
00026         """
00027         return path.startswith('jar:') or path.endswith('.jar')
00028 
00029     @classmethod
00030     def get_blob(cls, path, source=True):
00031         (p, j, i) = cls._explode_path(path)
00032         return FileFormat.get_blob(cls, path, uri=i, source=source)
00033 
00034     @classmethod
00035     def get_entitylist(cls, path, source=False, code='default', parser=None):
00036         (p, j, i) = cls._explode_path(path)
00037         return FileFormat.get_entitylist(cls, path, uri=i, source=source, code=code, parser=parser)
00038 
00039     @classmethod
00040     def get_l10nobject(cls, path, source=False, code='default', parser=None):
00041         (p, j, i) = cls._explode_path(path)
00042         return FileFormat.get_l10nobject(cls, path, uri=i, source=source, code=code, parser=parser)
00043 
00044     @classmethod
00045     def get_l10npackage(cls, path,
00046                         code='default',
00047                         object_type='l10nobject',
00048                         source=None,
00049                         ignore=['CVS','.svn','.DS_Store', '.hg']):
00050         l10npackage = FileFormatClient.get_l10npackage(path, code, object_type, source, ignore)
00051         (b_source, oe_source) = cls._get_source_policy(source)
00052 
00053         try:
00054             if not cls.zfile:
00055                 cls._open_jar(path)
00056         except Exception,e:
00057             raise Exception('Could not load a jar file: ' + path + ': ' + str(e))
00058         for name in cls.zfile.namelist():
00059             dirname = os.path.dirname(name)
00060             filename =    os.path.basename(name)
00061             # @var relpath: relative-path to the given path'
00062             relpath = re.sub(os.path.dirname(path), '', dirname, 1)
00063             if relpath.startswith('/'):
00064                 relpath = os.path.split(relpath)[1]
00065 
00066             if cls._should_ignore(ignore, path=relpath, elem=[filename, dirname]):
00067                 continue
00068 
00069             try:
00070                 parser = silme.format.Manager.get(path=filename)
00071             except Exception, e:
00072                 l10npackage.add_object(cls.get_blob(name, source=True), relpath)
00073             else:
00074                 if object_type=='blob':
00075                     l10npackage.add_object(cls.get_blob(name, source=True), relpath)
00076                 elif object_type=='entitylist':
00077                     l10npackage.add_object(cls.get_entitylist(name, source=source,
00078                                             parser=parser), relpath)
00079                 else:
00080                     l10npackage.add_object(cls.get_l10nobject(name, source=source,
00081                                             parser=parser), relpath)
00082         cls._close_jar()
00083         return l10npackage
00084 
00085     @classmethod
00086     def write_blob(cls, blob, path):
00087         cls.write_source(blob.source,
00088                         path,
00089                         blob.id,
00090                         encoding=None)
00091 
00092     @classmethod
00093     def write_entitylist(cls, elist, path, encoding=None):
00094         if encoding is None and hasattr(elist, 'encoding'):
00095             encoding = elist.encoding
00096         try:
00097             format_parser = silme.format.Manager.get(path=elist.id)
00098         except Exception:
00099             raise Exception('No parser for given object type')
00100         string = format_parser.dump_entitylist(elist)
00101         cls.write_source(string,
00102                         path,
00103                         elist.id,
00104                         encoding)
00105         return True
00106 
00107     @classmethod
00108     def write_l10nobject(cls, object, path, encoding=None):
00109         if encoding is None and hasattr(object, 'encoding'):
00110             encoding = object.encoding
00111         try:
00112             format_parser = silme.format.Manager.get(path=object.id)
00113         except Exception:
00114             raise Exception('No parser for given object type ('+object.id+')')
00115         string = format_parser.dump_l10nobject(object)
00116         cls.write_source(string,
00117                         path,
00118                         object.id,
00119                         format_parser.encoding)
00120         return True
00121 
00122     @classmethod
00123     def write_object(cls, object, path, encoding=None):
00124         if isinstance(object, L10nObject):
00125             cls.write_l10nobject(object, path, encoding=encoding)
00126         elif isinstance(object, EntityList):
00127             cls.write_entitylist(object, path, encoding=encoding)
00128         elif isinstance(object, Blob):
00129             cls.write_blob(object, path)
00130 
00131     @classmethod
00132     def write_l10npackage(cls, l10npack, path, ipath=''):
00133         if not cls.zfile:
00134             cls._open_jar(os.path.join(path, l10npack.id+'.jar'), mode='w')
00135 
00136         for object in l10npack.get_objects():
00137             cls.write_object(object, os.path.join(ipath, object.id))
00138         for pack in l10npack.get_packages():
00139             cls.write_l10npackage(pack, path, os.path.join(ipath, pack.id))
00140 
00141         if cls.zfile:
00142             cls._close_jar()
00143 
00144     @classmethod
00145     def write_source(cls, content, path, name, encoding=None):
00146         if not cls.zfile:
00147             (p, j, i) = cls._explode_path(path)
00148             cls._open_jar(j, mode='a')
00149             cls.zfile.writestr(os.path.join(i, name), content)
00150             cls._close_jar()
00151         else:
00152             cls.zfile.writestr(path, content)
00153         return True
00154 
00155 #========================================================================
00156 
00157     @classmethod
00158     def _explode_path(cls, path):
00159         if path.startswith('jar:'):
00160             try:
00161                 delim = path.index('!')
00162             except:
00163                 delim = None
00164             protocol = path[0:4]
00165             jarpath = path[4:delim]
00166             internalpath = delim and path[delim+1:] or ''
00167         elif path.endswith('.jar'):
00168             protocol = None
00169             jarpath = path
00170             internalpath = None
00171         else:
00172             protocol = None
00173             jarpath = None
00174             internalpath = path
00175         return (protocol, jarpath, internalpath)
00176 
00177     @classmethod
00178     def _open_jar(cls, path, mode='r'):
00179         '''
00180         Opens the given jar-file and returns a zipfile instance
00181         @param path: path to a jar-file
00182         '''
00183         if cls.zfile is not None:
00184             if cls.zfile.mode == mode:
00185                 return True
00186             else:
00187                 cls._close_jar()
00188         if mode is not 'w' and not zipfile.is_zipfile(path):
00189             raise Exception('Not a valid JAR-file: ' + path + ' !')
00190         cls.zfile = zipfile.ZipFile(path, mode)
00191 
00192     @classmethod
00193     def _close_jar(cls):
00194         '''
00195         Close an open jar-file instance
00196         '''
00197         if cls.zfile is None:
00198             raise KeyError('It looks like there is nothing to be closed!')
00199         cls.zfile.close()
00200         cls.zfile = None
00201 
00202     @classmethod
00203     def _read_with_encoding(cls, path, encoding):
00204         if cls.zfile is None:
00205             (protocol, jpath, ipath) = cls._explode_path(path)
00206             cls._open_jar(jpath)
00207             text = cls.zfile.read(ipath).decode(encoding)
00208             cls._close_jar()
00209             return text
00210         else:
00211             return cls.zfile.read(path).decode(encoding)
00212 
00213     @classmethod
00214     def _read_without_encoding(cls, path):
00215         if cls.zfile is None:
00216             (protocol, jpath, ipath) = cls._explode_path(path)
00217             cls._open_jar(jpath)
00218             text = cls.zfile.read(ipath)
00219             cls._close_jar()
00220             return text
00221         else:
00222             return cls.zfile.read(path)
00223 
00224 def zipfile_delete(self, file):
00225     # create temporary file
00226     f = tempfile.mkstemp()
00227     os.remove(f[1])
00228     zfile = zipfile.ZipFile(f[1], mode='w')
00229     for item in self.infolist():
00230         buf = self.read(item.filename)
00231         if not item.filename==file:
00232             zfile.writestr(item, buf)
00233     zfile.close()
00234     shutil.move(zfile.filename, self.filename)
00235 
00236 zipfile.ZipFile.delete = zipfile_delete

Generated on Tue May 12 17:37:27 2009 for silme by  doxygen 1.5.8