Django Library PyGal
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

xnail.py 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. from django.conf import settings
  2. import fstools
  3. import logging
  4. import mimetypes
  5. import media
  6. from ..models import get_item_type, TYPE_IMAGE, TYPE_VIDEO
  7. import os
  8. import pygal
  9. logger = logging.getLogger(settings.ROOT_LOGGER_NAME).getChild(__name__)
  10. def get_image_class(full_path):
  11. return {
  12. TYPE_IMAGE: image,
  13. TYPE_VIDEO: video,
  14. }.get(get_item_type(full_path), other)
  15. def get_image_instance(full_path, request):
  16. return get_image_class(full_path)(full_path, request)
  17. class base_item(object):
  18. MIME_TYPES = {
  19. '.ada': 'text/x/adasrc',
  20. '.hex': 'text/x/hex',
  21. '.jpg': 'image/x/generic',
  22. '.jpeg': 'image/x/generic',
  23. '.jpe': 'image/x/generic',
  24. '.png': 'image/x/generic',
  25. '.tif': 'image/x/generic',
  26. '.tiff': 'image/x/generic',
  27. '.gif': 'image/x/generic',
  28. '.avi': 'video/x/generic',
  29. '.mpg': 'video/x/generic',
  30. '.mpeg': 'video/x/generic',
  31. '.mpe': 'video/x/generic',
  32. '.mov': 'video/x/generic',
  33. '.qt': 'video/x/generic',
  34. '.mp4': 'video/x/generic',
  35. '.webm': 'video/x/generic',
  36. '.ogv': 'video/x/generic',
  37. '.flv': 'video/x/generic',
  38. '.3gp': 'video/x/generic',
  39. }
  40. def __init__(self, full_path, request):
  41. self.full_path = full_path
  42. self.request = request
  43. self.rel_path = pygal.get_rel_path(full_path)
  44. #
  45. ext = os.path.splitext(self.full_path)[1].lower()
  46. self.mime_type = self.MIME_TYPES.get(ext, mimetypes.types_map.get(ext, 'unknown'))
  47. def __cache_image_folder__(self, rel_path):
  48. return os.path.join(settings.XNAIL_ROOT, rel_path.replace('_', '__').replace('/', '_'))
  49. def __cache_image_name__(self, max_size):
  50. filename = '%04d_%02x_%s.jpg' % (max_size, self.XNAIL_VERSION_NUMBER, fstools.uid(self.full_path, None))
  51. return os.path.join(self.__cache_image_folder__(self.rel_path), filename)
  52. def __delete_cache_image__(self, max_size):
  53. folder = self.__cache_image_folder__(self.rel_path)
  54. if os.path.isdir(folder):
  55. for fn in fstools.filelist(folder, '%04d*' % max_size):
  56. try:
  57. os.remove(fn)
  58. except OSError:
  59. pass # possibly file is already removed by another process
  60. class image(base_item):
  61. XNAIL_VERSION_NUMBER = 1
  62. def __init__(self, *args, **kwargs):
  63. base_item.__init__(self, *args, **kwargs)
  64. self.mime_type_xnails = mimetypes.types_map.get('.jpg', 'unknown')
  65. def get_resized_image_data(self, max_size):
  66. cache_filename = self.__cache_image_name__(max_size)
  67. if not os.path.exists(cache_filename):
  68. logger.info('Creating xnail-%d for %s', max_size, self.rel_path)
  69. self.__delete_cache_image__(max_size)
  70. im = media.image(self.full_path)
  71. im.resize(max_size)
  72. im.rotate_by_orientation()
  73. #
  74. # create cache file
  75. #
  76. fstools.mkdir(os.path.dirname(cache_filename))
  77. im.save(cache_filename)
  78. return im.image_data()
  79. return open(cache_filename, 'rb').read()
  80. def thumbnail_picture(self):
  81. return self.get_resized_image_data(pygal.get_thumbnail_max_size(self.request))
  82. def webnail_picture(self):
  83. return self.get_resized_image_data(pygal.get_webnail_size(self.request))
  84. class video(image):
  85. def get_resized_image_data(self, max_size):
  86. cache_filename = self.__cache_image_name__(max_size)
  87. if not os.path.exists(cache_filename):
  88. logger.info('Creating xnail-%d for %s', max_size, self.rel_path)
  89. self.__delete_cache_image__(max_size)
  90. im = media.image(self.full_path)
  91. im.resize(max_size)
  92. im.join(os.path.join(os.path.dirname(__file__), 'video.png'))
  93. #
  94. # create cache file
  95. #
  96. fstools.mkdir(os.path.dirname(cache_filename))
  97. im.save(cache_filename)
  98. return im.image_data()
  99. return open(cache_filename, 'rb').read()
  100. class other(base_item):
  101. def __init__(self, *args, **kwargs):
  102. base_item.__init__(self, *args, **kwargs)
  103. self.mime_type_xnails = mimetypes.types_map.get('.png', 'unknown')
  104. def thumbnail_picture(self):
  105. fn = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'mimetype_icons', '%s.png' % (self.mime_type).replace('/', '-'))
  106. if not os.path.exists(fn):
  107. fn = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'mimetype_icons', 'unknown.png')
  108. return open(fn, 'rb').read()
  109. def webnail_picture(self):
  110. return self.thumbnail_picture()