def __init__(self, path, flags, *mode): rwflags = flags & (os.O_RDONLY | os.O_WRONLY | os.O_RDWR) if rwflags != os.O_RDONLY: raise NOTFOUND if path == _cfgpath: self.data = wp._cfgfile return spath = path.split("/") metam = metamd5re.match(spath[-1]) if metam: self.data = wp._generate_meta(metam.group(1)) return if spath[-1][: len(_cloudname)] == _cloudname: self.data = wp._generate_cloud(spath[1:-1], spath[-1]) return if spath[-3:-1] in _thumbpaths: self.data = self._make_thumb(spath) else: fn = spath[-1].split(".") m = fn[-2][-32:] fh = self._open(m) if fh: if wp._raw2jpeg and fn[-1] in _rawext_r: # @@ Check wp._stat(m).version self._fh = RawWrapper(fh, True) else: self._fh = fh self._lock = Lock()
def serve(fn, ext): if not exists(fn): abort(404) if ext in raw_exts: fh = RawWrapper(open(fn, "rb"), True) fh.seek(0, 2) z = fh.tell() fh.seek(0) ext = "jpeg" else: z = stat(fn).st_size fh = open(fn, "rb") response.content_type = "image/" + ext response.set_header("Content-Length", str(z)) response.set_header("Expires", fmttime(time() + 60*60*24 * 10)) response.set_header("Date", fmttime(time())) return fh
class FakeFile: keep_cache = False direct_io = False _fh = None data = "" def __init__(self, path, flags, *mode): rwflags = flags & (os.O_RDONLY | os.O_WRONLY | os.O_RDWR) if rwflags != os.O_RDONLY: raise NOTFOUND if path == _cfgpath: self.data = wp._cfgfile return spath = path.split("/") metam = metamd5re.match(spath[-1]) if metam: self.data = wp._generate_meta(metam.group(1)) return if spath[-1][: len(_cloudname)] == _cloudname: self.data = wp._generate_cloud(spath[1:-1], spath[-1]) return if spath[-3:-1] in _thumbpaths: self.data = self._make_thumb(spath) else: fn = spath[-1].split(".") m = fn[-2][-32:] fh = self._open(m) if fh: if wp._raw2jpeg and fn[-1] in _rawext_r: # @@ Check wp._stat(m).version self._fh = RawWrapper(fh, True) else: self._fh = fh self._lock = Lock() def _open(self, m): try: dest = wp._stat(m).dest return open(dest, "rb") except Exception: pass try: p = wp._client.image_path(m) dest = os.readlink(p) fh = open(dest, "rb") wp._stat_cache[m] = wp._stat(m)._replace(dest=dest) return fh except Exception: pass # FUSE doesn't seem to like destroying these objects. # But it does call release, so I'll do what I can. def __del__(self): self.release(0) def release(self, flags): if self._fh: self._fh.close() self.data = self._fh = self._Lock = None def _make_thumb(self, spath): search = wp._path2search("/".join(spath[:-3])) if not search: raise NOTFOUND orgmd5, fn = wp._resolve_thumb(search, spath[-1]) ext = fn.split(".")[-1] tfn = wp._client.thumb_path(orgmd5, spath[-2]) fh = open(tfn) data = fh.read() fh.close() if not (search.order or ext in _rawext_r): return data data = data.split("tEXtThumb::URI\0") if len(data) != 2: raise NOTFOUND pre, post = data clen, = unpack(">I", pre[-4:]) if search.order: # It's longer only of search was ordered pre = pre[:-4] + pack(">I", clen + 7) post = post[clen - 7 :] tEXt = "tEXtThumb::URI\0" + fn crc = crc32(tEXt) if crc < 0: crc += 0x100000000 tEXt += pack(">I", crc) return pre + tEXt + post def read(self, length, offset): if self._fh: with self._lock: self._fh.seek(offset) return self._fh.read(length) else: return self.data[offset : offset + length]