easy_thumbnails.templatetags.thumbnail: 115 total statements, 0.0% covered

Generated: Wed 2013-03-13 10:33 CET

Source file: /media/Envs/Envs/filer-gallery/lib/python2.7/site-packages/easy_thumbnails/templatetags/thumbnail.py

Stats: 0 executed, 109 missed, 6 excluded, 152 ignored

  1. import re
  2. from django.template import Library, Node, VariableDoesNotExist, \
  3. TemplateSyntaxError
  4. from django.utils.html import escape
  5. from easy_thumbnails import utils
  6. from easy_thumbnails.conf import settings
  7. from easy_thumbnails.files import get_thumbnailer
  8. register = Library()
  9. RE_SIZE = re.compile(r'(\d+)x(\d+)$')
  10. VALID_OPTIONS = utils.valid_processor_options()
  11. VALID_OPTIONS.remove('size')
  12. def split_args(args):
  13. """
  14. Split a list of argument strings into a dictionary where each key is an
  15. argument name.
  16. An argument looks like ``crop``, ``crop="some option"`` or ``crop=my_var``.
  17. Arguments which provide no value get a value of ``True``.
  18. """
  19. args_dict = {}
  20. for arg in args:
  21. split_arg = arg.split('=', 1)
  22. if len(split_arg) > 1:
  23. value = split_arg[1]
  24. else:
  25. value = True
  26. args_dict[split_arg[0]] = value
  27. return args_dict
  28. class ThumbnailNode(Node):
  29. def __init__(self, source_var, opts, context_name=None):
  30. self.source_var = source_var
  31. self.opts = opts
  32. self.context_name = context_name
  33. def render(self, context):
  34. # Note that this isn't a global constant because we need to change the
  35. # value for tests.
  36. raise_errors = settings.THUMBNAIL_DEBUG
  37. # Get the source file.
  38. try:
  39. source = self.source_var.resolve(context)
  40. except VariableDoesNotExist:
  41. if raise_errors:
  42. raise VariableDoesNotExist("Variable '%s' does not exist." %
  43. self.source_var)
  44. return self.bail_out(context)
  45. if not source:
  46. if raise_errors:
  47. raise TemplateSyntaxError(
  48. "Variable '%s' is an invalid source." % self.source_var
  49. )
  50. return self.bail_out(context)
  51. # Resolve the thumbnail option values.
  52. try:
  53. opts = {}
  54. for key, value in self.opts.iteritems():
  55. if hasattr(value, 'resolve'):
  56. value = value.resolve(context)
  57. opts[str(key)] = value
  58. except Exception:
  59. if raise_errors:
  60. raise
  61. return self.bail_out(context)
  62. # Size variable can be either a tuple/list of two integers or a
  63. # valid string.
  64. size = opts['size']
  65. if isinstance(size, basestring):
  66. m = RE_SIZE.match(size)
  67. if m:
  68. opts['size'] = (int(m.group(1)), int(m.group(2)))
  69. else:
  70. if raise_errors:
  71. raise TemplateSyntaxError("%r is not a valid size." % size)
  72. return self.bail_out(context)
  73. # Ensure the quality is an integer.
  74. if 'quality' in opts:
  75. try:
  76. opts['quality'] = int(opts['quality'])
  77. except (TypeError, ValueError):
  78. if raise_errors:
  79. raise TemplateSyntaxError("%r is an invalid quality." %
  80. opts['quality'])
  81. return self.bail_out(context)
  82. try:
  83. thumbnail = get_thumbnailer(source).get_thumbnail(opts)
  84. except Exception, e:
  85. if raise_errors:
  86. raise TemplateSyntaxError(u"Couldn't get the thumbnail %s: %s" %
  87. (source, e))
  88. return self.bail_out(context)
  89. # Return the thumbnail file url, or put the file on the context.
  90. if self.context_name is None:
  91. return escape(thumbnail.url)
  92. else:
  93. context[self.context_name] = thumbnail
  94. return ''
  95. def bail_out(self, context):
  96. if self.context_name:
  97. context[self.context_name] = ''
  98. return ''
  99. def thumbnail(parser, token):
  100. """
  101. Creates a thumbnail of an ImageField.
  102. Basic tag Syntax::
  103. {% thumbnail [source] [size] [options] %}
  104. *source* must be a ``File`` object, usually an Image/FileField of a model
  105. instance.
  106. *size* can either be:
  107. * the size in the format ``[width]x[height]`` (for example,
  108. ``{% thumbnail person.photo 100x50 %}``) or
  109. * a variable containing a valid size (i.e. either a string in the
  110. ``[width]x[height]`` format or a tuple containing two integers):
  111. ``{% thumbnail person.photo size_var %}``.
  112. *options* are a space separated list of options which are used when
  113. processing the image to a thumbnail such as ``sharpen``, ``crop`` and
  114. ``quality=90``.
  115. The thumbnail tag can also place a
  116. :class:`~easy_thumbnails.files.ThumbnailFile` object in the context,
  117. providing access to the properties of the thumbnail such as the height and
  118. width::
  119. {% thumbnail [source] [size] [options] as [variable] %}
  120. When ``as [variable]`` is used, the tag doesn't output anything.
  121. **Debugging**
  122. By default, if there is an error creating the thumbnail or resolving the
  123. image variable then the thumbnail tag will just return an empty string (and
  124. if there was a context variable to be set then it will also be set to an
  125. empty string).
  126. For example, you will not see an error if the thumbnail could not
  127. be written to directory because of permissions error. To display those
  128. errors rather than failing silently, set ``THUMBNAIL_DEBUG = True`` in
  129. your Django project's settings module.
  130. """
  131. args = token.split_contents()
  132. tag = args[0]
  133. # Check to see if we're setting to a context variable.
  134. if len(args) > 4 and args[-2] == 'as':
  135. context_name = args[-1]
  136. args = args[:-2]
  137. else:
  138. context_name = None
  139. if len(args) < 3:
  140. raise TemplateSyntaxError("Invalid syntax. Expected "
  141. "'{%% %s source size [option1 option2 ...] %%}' or "
  142. "'{%% %s source size [option1 option2 ...] as variable %%}'" %
  143. (tag, tag))
  144. opts = {}
  145. # The first argument is the source file.
  146. source_var = parser.compile_filter(args[1])
  147. # The second argument is the requested size. If it's the static "10x10"
  148. # format, wrap it in quotes so that it is compiled correctly.
  149. size = args[2]
  150. match = RE_SIZE.match(size)
  151. if match:
  152. size = '"%s"' % size
  153. opts['size'] = parser.compile_filter(size)
  154. # All further arguments are options.
  155. args_list = split_args(args[3:]).items()
  156. for arg, value in args_list:
  157. if arg in VALID_OPTIONS:
  158. if value and value is not True:
  159. value = parser.compile_filter(value)
  160. opts[arg] = value
  161. else:
  162. raise TemplateSyntaxError("'%s' tag received a bad argument: "
  163. "'%s'" % (tag, arg))
  164. return ThumbnailNode(source_var, opts=opts, context_name=context_name)
  165. def thumbnailer(obj):
  166. """
  167. Creates a thumbnailer from an object (usually a ``FileField``).
  168. Example usage::
  169. {% with photo=person.photo|thumbnailer %}
  170. {% if photo %}
  171. <a href="{{ photo.large.url }}">
  172. {{ photo.square.tag }}
  173. </a>
  174. {% else %}
  175. <img href="{% static 'template/fallback.png' %}" alt="" />
  176. {% endif %}
  177. {% endwith %}
  178. """
  179. return get_thumbnailer(obj)
  180. def thumbnailer_passive(obj):
  181. """
  182. Creates a thumbnailer from an object (usually a ``FileFile``) that won't
  183. generate new thumbnails.
  184. This is useful if you are using another process to generate the thumbnails
  185. rather than having them generated on the fly if they are missing.
  186. Example usage::
  187. {% with avatar=person.avatar|thumbnailer_passive %}
  188. {% with avatar_thumb=avatar.small %}
  189. {% if avatar_thumb %}
  190. <img src="{{ avatar_thumb.url }}" alt="" />
  191. {% else %}
  192. <img src="{% static 'img/default-avatar-small.png' %}" alt="" />
  193. {% endif %}
  194. {% endwith %}
  195. {% endwith %}
  196. """
  197. thumbnailer = get_thumbnailer(obj)
  198. thumbnailer.generate = False
  199. return thumbnailer
  200. def thumbnail_url(source, alias):
  201. """
  202. Return the thumbnail url for a source file using an aliased set of
  203. thumbnail options.
  204. If no matching alias is found, returns an empty string.
  205. Example usage::
  206. <img href="{{ person.photo|thumbnail_url:'small' }}" alt="">
  207. """
  208. try:
  209. thumb = get_thumbnailer(source)[alias]
  210. except Exception:
  211. return ''
  212. return thumb.url
  213. register.tag(thumbnail)
  214. register.filter(thumbnailer)
  215. register.filter(thumbnailer_passive)
  216. register.filter(thumbnail_url)