from django.conf import settings import fstools import logging import mimetypes import media from ..models import get_item_type, TYPE_IMAGE, TYPE_VIDEO import os import pygal # Get a logger instance try: from config import APP_NAME as ROOT_LOGGER_NAME except ImportError: ROOT_LOGGER_NAME = 'root' logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__) def get_image_class(full_path): return { TYPE_IMAGE: image, TYPE_VIDEO: video, }.get(get_item_type(full_path), other) def get_image_instance(full_path, request): return get_image_class(full_path)(full_path, request) class base_item(object): MIME_TYPES = { '.ada': 'text/x/adasrc', '.hex': 'text/x/hex', '.jpg': 'image/x/generic', '.jpeg': 'image/x/generic', '.jpe': 'image/x/generic', '.png': 'image/x/generic', '.tif': 'image/x/generic', '.tiff': 'image/x/generic', '.gif': 'image/x/generic', '.avi': 'video/x/generic', '.mpg': 'video/x/generic', '.mpeg': 'video/x/generic', '.mpe': 'video/x/generic', '.mov': 'video/x/generic', '.qt': 'video/x/generic', '.mp4': 'video/x/generic', '.webm': 'video/x/generic', '.ogv': 'video/x/generic', '.flv': 'video/x/generic', '.3gp': 'video/x/generic', } def __init__(self, full_path, request): self.full_path = full_path self.request = request self.rel_path = pygal.get_rel_path(full_path) # ext = os.path.splitext(self.full_path)[1].lower() self.mime_type = self.MIME_TYPES.get(ext, mimetypes.types_map.get(ext, 'unknown')) def __cache_image_folder__(self, rel_path): return os.path.join(settings.XNAIL_ROOT, rel_path.replace('_', '__').replace('/', '_')) def __cache_image_name__(self, max_size): filename = '%04d_%02x_%s.jpg' % (max_size, self.XNAIL_VERSION_NUMBER, fstools.uid(self.full_path, None)) return os.path.join(self.__cache_image_folder__(self.rel_path), filename) def __delete_cache_image__(self, max_size): folder = self.__cache_image_folder__(self.rel_path) if os.path.isdir(folder): for fn in fstools.filelist(folder, '%04d*' % max_size): try: os.remove(fn) except OSError: pass # possibly file is already removed by another process class image(base_item): XNAIL_VERSION_NUMBER = 1 def __init__(self, *args, **kwargs): base_item.__init__(self, *args, **kwargs) self.mime_type_xnails = mimetypes.types_map.get('.jpg', 'unknown') def get_resized_image_data(self, max_size): cache_filename = self.__cache_image_name__(max_size) if not os.path.exists(cache_filename): logger.info('Creating xnail-%d for %s', max_size, self.rel_path) self.__delete_cache_image__(max_size) im = media.image(self.full_path) im.resize(max_size) im.rotate_by_orientation() # # create cache file # fstools.mkdir(os.path.dirname(cache_filename)) im.save(cache_filename) return im.image_data() return open(cache_filename, 'rb').read() def thumbnail_picture(self): return self.get_resized_image_data(pygal.get_thumbnail_max_size(self.request)) def webnail_picture(self): return self.get_resized_image_data(pygal.get_webnail_size(self.request)) class video(image): def get_resized_image_data(self, max_size): cache_filename = self.__cache_image_name__(max_size) if not os.path.exists(cache_filename): logger.info('Creating xnail-%d for %s', max_size, self.rel_path) self.__delete_cache_image__(max_size) im = media.image(self.full_path) im.resize(max_size) im.join(os.path.join(os.path.dirname(__file__), 'video.png')) # # create cache file # fstools.mkdir(os.path.dirname(cache_filename)) im.save(cache_filename) return im.image_data() return open(cache_filename, 'rb').read() class other(base_item): def __init__(self, *args, **kwargs): base_item.__init__(self, *args, **kwargs) self.mime_type_xnails = mimetypes.types_map.get('.png', 'unknown') def thumbnail_picture(self): fn = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'mimetype_icons', '%s.png' % (self.mime_type).replace('/', '-')) if not os.path.exists(fn): fn = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'mimetype_icons', 'unknown.png') return open(fn, 'rb').read() def webnail_picture(self): return self.thumbnail_picture()