Package advene :: Package model :: Package parsers :: Module advene_zip
[hide private]
[frames] | no frames]

Source Code for Module advene.model.parsers.advene_zip

  1  """ 
  2  Unstable and experimental parser implementation. 
  3   
  4  See `advene.model.parsers.advene_xml` for the reference implementation. 
  5  """ 
  6   
  7  from tempfile import mkdtemp 
  8  from os import path, tmpfile 
  9  from zipfile import BadZipfile, ZipFile 
 10   
 11  from advene.model.consts import PACKAGED_ROOT 
 12  import advene.model.parsers.advene_xml as advene_xml 
 13  import advene.model.serializers.advene_zip as serializer 
 14  from advene.util.files import get_path, recursive_mkdir 
 15  from advene.util.session import tempdir_list 
16 17 -class Parser(object):
18 19 NAME = serializer.NAME 20 EXTENSION = serializer.EXTENSION 21 MIMETYPE = serializer.MIMETYPE 22 SERIALIZER = serializer # may be None for some parsers 23 24 @classmethod
25 - def claims_for_parse(cls, file_):
26 """Is this parser likely to parse that file-like object? 27 28 `file_` is a readable file-like object. It is the responsability of the 29 caller to close it. 30 """ 31 r = 0 32 33 if hasattr(file_, "seek"): 34 # try to open it as zip file and get the mimetype from archive 35 t = file_.tell() 36 try: 37 z = ZipFile(file_, "r") 38 except BadZipfile: 39 return 0 40 else: 41 if "mimetype" in z.namelist(): 42 if z.read("mimetype").startswith(cls.MIMETYPE): 43 return 80 44 else: 45 return 0 46 elif "content.xml" in z.nameslit(): 47 r = 20 48 # wait for other information to make up our mind 49 else: 50 return 0 51 z.close() 52 file_.seek(t) 53 54 info = getattr(file_, "info", lambda: {})() 55 mimetype = info.get("content-type", "") 56 if mimetype.startswith(cls.MIMETYPE): 57 r = 80 # overrides extension 58 elif mimetype.startswith("application/x-zip"): 59 r += 30 60 fpath = get_path(file_) 61 raise Exception 62 if fpath.endswith(cls.EXTENSION): 63 r += 40 64 elif fpath.endswith(".zip"): 65 r += 20 66 print "+++", r 67 return r
68 69 @classmethod
70 - def make_parser(cls, file_, package):
71 """Return a parser that will parse `url` into `package`. 72 73 `file_` is a writable file-like object. It is the responsability of the 74 caller to close it. 75 76 The returned object must implement the interface for which 77 :class:`_Parser` is the reference implementation. 78 """ 79 return cls(file_, package)
80 81 @classmethod
82 - def parse_into(cls, file_, package):
83 """A shortcut for ``make_parser(url, package).parse()``. 84 85 See also `make_parser`. 86 """ 87 cls(file_, package).parse()
88
89 - def parse(self):
90 "Do the actual parsing." 91 backend = self.package._backend 92 pid = self.package._id 93 backend.set_meta(pid, "", "", PACKAGED_ROOT, self.dir, False) 94 # TODO use notification to clean it when package is closed 95 f = open(self.content) 96 self._XML_PARSER.parse_into(f, self.package) 97 f.close()
98 99 # end of public interface 100 101 _XML_PARSER = advene_xml.Parser 102
103 - def __init__(self, file_, package):
104 assert self.claims_for_parse(file_) > 0 105 self.dir = d = mkdtemp() 106 tempdir_list.append(d) 107 108 if hasattr(file_, "seek"): 109 g = None 110 z = ZipFile(file_, "r") 111 else: 112 # ZipFile requires seekable file, dump it in tmpfile 113 g = tmpfile() 114 g.write(file_.read()) 115 g.seek(0) 116 z = ZipFile(g, "r") 117 names = z.namelist() 118 for zname in names: 119 seq = zname.split("/") 120 dirname = recursive_mkdir(d, seq[:-1]) 121 if seq[-1]: 122 fname = path.join(dirname, seq[-1]) 123 h = open(fname, "w") 124 h.write(z.read(zname)) 125 h.close() 126 z.close() 127 if g is not None: 128 g.close() 129 130 self.content = path.join(d, "content.xml") 131 self.package = package
132