pygal/views/xnail.py

139 líneas
4.7 KiB
Python

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()