#!/usr/bin/env python # Copyright (C) 2008 Willi Richert # # $Id: AlbumFS.py,v 6cbb32764ed9 2009/04/05 12:39:52 w $ # import os, tempfile, sys, shutil, errno, fuse from PIL import Image fuse.fuse_python_api = (0, 2) IMG_SUFFIX=[".png", ".jpg", ".jpeg", ".gif"] flat2real = {} def get_real_path(path): real_path, flat_file = os.path.split(path) if path!="/": try: real_path = os.path.join(real_path, flat2real[flat_file]) except: return None return real_path class AlbumFS(fuse.Fuse): def __init__(self, root_path, *args, **kw): fuse.Fuse.__init__(self, *args, **kw) self.root_path = root_path self.file_class = AlbumFSFile os.chdir(self.root_path) self.parse(values=self, errex=1) self.thumb_temp_dir = tempfile.mkdtemp() self.statfs() def getattr(self, path): real_path = get_real_path(path) if real_path: return os.lstat(real_path) def readdir(self, path, offset): for target_name in flat2real.iterkeys(): yield fuse.Direntry(target_name) def _create_thumb(self, unique_name): fn, ext = os.path.splitext(unique_name) im = Image.open(flat2real[unique_name]) im.thumbnail((128, 128), Image.ANTIALIAS) thumb_fn = os.path.join(self.thumb_temp_dir, fn+"_thumbnail"+ext) im.save(thumb_fn) self.flat2thumb[unique_name] = thumb_fn def _reset_mapping(self): global flat2real flat2real = {} self.flat2thumb = {} for parent, dirs, files in os.walk("."): for fn in [fn for fn in files if os.path.splitext(fn)[1] in IMG_SUFFIX and os.path.isfile(os.path.join(parent,fn))]: elements = parent.split("/") if elements[0]==".": elements = elements[1:] parent = "_".join(elements) if parent: unique_name = parent+"_"+fn flat2real[unique_name] = os.path.join(self.root_path,parent,fn) else: uniqe_name = fn flat2real[unique_name] = os.path.join(self.root_path,fn) self._create_thumb(unique_name) flat2real["album.html"] = os.path.join(self.thumb_temp_dir, "album.html") def _gen_album_html(self): html_content = ['

Album %s

'%self.root_path] max_items = len(self.flat2thumb) for idx, (unique_name, thumb_fn) in enumerate(self.flat2thumb.items()): img_info = Image.open(flat2real[unique_name]).size row_content = ''%\ (flat2real[unique_name], unique_name, thumb_fn, unique_name, img_info) if 0

%s

Size: %s
") f=file(os.path.join(self.thumb_temp_dir, "album.html"), "w") f.writelines(html_content) f.close() def fsdestroy(self): shutil.rmtree(self.thumb_temp_dir) def statfs(self): self._reset_mapping() self._gen_album_html() return os.statvfs(".") def flag2mode(flags): md = {os.O_RDONLY: 'r', os.O_WRONLY: 'w', os.O_RDWR: 'w+'} m = md[flags & (os.O_RDONLY | os.O_WRONLY | os.O_RDWR)] if flags | os.O_APPEND: m = m.replace('w', 'a', 1) return m class AlbumFSFile(object): def __init__(self, path, flags, *mode): self.file = os.fdopen(os.open(get_real_path(path), flags, *mode), flag2mode(flags)) self.fd = self.file.fileno() def read(self, length, offset): self.file.seek(offset) return self.file.read(length) def release(self, flags): self.file.close() if __name__ == '__main__': server = AlbumFS(sys.argv[2]) server.main()