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.7KB

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