def render(self, context): try: # This evaluates to a ImageWithThumbsField, as long as the # user specified a valid model field. relative_source = Variable(self.source_var).resolve(context) except VariableDoesNotExist: if settings.TEMPLATE_DEBUG: raise VariableDoesNotExist("Variable '%s' does not exist." % self.source_var) else: relative_source = None try: requested_name = Variable(self.thumb_name_var).resolve(context) except VariableDoesNotExist: if settings.TEMPLATE_DEBUG: raise TemplateSyntaxError("Name argument '%s' is not a valid thumbnail." % self.thumb_name_var) else: requested_name = None if relative_source is None or requested_name is None: # Couldn't resolve the given template variable. Fail silently. thumbnail = '' else: # Spaces at the end of sizes is just not OK. requested_name = requested_name.strip() # This is typically a athumb.fields.ImageWithThumbsFieldFile object. try: # Allow the user to override the protocol in the tag. force_ssl = self.kwargs.get('force_ssl', False) # Try to detect SSL mode in the request context. Front-facing # server or proxy must be passing the correct headers for # this to work. Also, factor in force_ssl. ssl_mode = self.is_secure(context) or force_ssl # Get the URL for the thumbnail from the # ImageWithThumbsFieldFile object. try: thumbnail = relative_source.generate_url(requested_name, ssl_mode=ssl_mode) except: #import traceback #traceback.print_stack() print "ERROR: Using {% thumbnail %} tag with " \ "a regular ImageField instead of ImageWithThumbsField:", self.source_var return '' except ValueError: # This file object doesn't actually have a file. Probably # model field with a None value. thumbnail = '' # Return the thumbnail class, or put it on the context if self.context_name is None: return thumbnail # We need to get here so we don't have old values in the context # variable. context[self.context_name] = thumbnail return ''
def render(self, context): # Note that this isn't a global constant because we need to change the # value for tests. raise_errors = getattr(settings, 'TEMPLATE_DEBUG', False) # Get the source file. try: source = self.source_var.resolve(context) if isinstance(source, FileNode): source = source.file except VariableDoesNotExist: if raise_errors: raise VariableDoesNotExist("Variable '%s' does not exist." % self.source_var) return self.bail_out(context) # Resolve the thumbnail option values. try: opts = {} for key, value in self.opts.iteritems(): if hasattr(value, 'resolve'): value = value.resolve(context) opts[str(key)] = value except: if raise_errors: raise return self.bail_out(context) # Size variable can be either a tuple/list of two integers or a # valid string, only the string is checked. size = opts['size'] if isinstance(size, basestring): m = RE_SIZE.match(size) if m: opts['size'] = (int(m.group(1)), int(m.group(2))) else: if THUMBNAIL_SIZES.has_key(size): opts['size'] = THUMBNAIL_SIZES[size] else: if raise_errors: raise TemplateSyntaxError( "Variable '%s' was resolved " "but '%s' is not a valid size." % (self.size_var, size)) return self.bail_out(context) try: thumbnail = MEDIA_BACKEND.get_thumbnail(source, opts) except: if raise_errors: raise return self.bail_out(context) # Return the thumbnail file url, or put the file on the context. if self.context_name is None: return escape(thumbnail.url) else: # Prepopulate ImageFile dimensions cache to skip reading of # thumbnail image and prevent IOError in case of missing file thumbnail._dimensions_cache = opts['size'] context[self.context_name] = thumbnail return ''
def render(self, context): # Note that this isn't a global constant because we need to change the # value for tests. DEBUG = get_thumbnail_setting('DEBUG') try: # A file object will be allowed in DjangoThumbnail class relative_source = self.source_var.resolve(context) except VariableDoesNotExist: if DEBUG: raise VariableDoesNotExist("Variable '%s' does not exist." % self.source_var) else: relative_source = None try: requested_size = self.size_var.resolve(context) except VariableDoesNotExist: if DEBUG: raise TemplateSyntaxError("Size argument '%s' is not a" " valid size nor a valid variable." % self.size_var) else: requested_size = None # Size variable can be either a tuple/list of two integers or a valid # string, only the string is checked. else: if isinstance(requested_size, basestring): m = size_pat.match(requested_size) if m: requested_size = (int(m.group(1)), int(m.group(2))) elif DEBUG: raise TemplateSyntaxError("Variable '%s' was resolved but " "'%s' is not a valid size." % (self.size_var, requested_size)) else: requested_size = None if relative_source is None or requested_size is None: thumbnail = '' else: try: kwargs = {} for key, value in self.kwargs.items(): kwargs[key] = value.resolve(context) opts = dict([(k, v and v.resolve(context)) for k, v in self.opts.items()]) thumbnail = DjangoThumbnail(relative_source, requested_size, opts=opts, processors=PROCESSORS, **kwargs) except: if DEBUG: raise else: thumbnail = '' # Return the thumbnail class, or put it on the context if self.context_name is None: return thumbnail # We need to get here so we don't have old values in the context # variable. context[self.context_name] = thumbnail return ''
def render(self, context): # Note that this isn't a global constant because we need to change the # value for tests. raise_errors = settings.THUMBNAIL_DEBUG # Get the source file. try: source = self.source_var.resolve(context) except VariableDoesNotExist: if raise_errors: raise VariableDoesNotExist("Variable '%s' does not exist." % self.source_var) return self.bail_out(context) if not source: if raise_errors: raise TemplateSyntaxError( "Variable '%s' is an invalid source." % self.source_var) return self.bail_out(context) # Resolve the thumbnail option values. try: opts = {} for key, value in self.opts.iteritems(): if hasattr(value, 'resolve'): value = value.resolve(context) opts[str(key)] = value except Exception: if raise_errors: raise return self.bail_out(context) # Size variable can be either a tuple/list of two integers or a # valid string. size = opts['size'] if isinstance(size, basestring): m = RE_SIZE.match(size) if m: opts['size'] = (int(m.group(1)), int(m.group(2))) else: if raise_errors: raise TemplateSyntaxError("%r is not a valid size." % size) return self.bail_out(context) # Ensure the quality is an integer. if 'quality' in opts: try: opts['quality'] = int(opts['quality']) except (TypeError, ValueError): if raise_errors: raise TemplateSyntaxError("%r is an invalid quality." % opts['quality']) return self.bail_out(context) try: thumbnail = get_thumbnailer(source).get_thumbnail(opts) except Exception, e: if raise_errors: raise TemplateSyntaxError( u"Couldn't get the thumbnail %s: %s" % (source, e)) return self.bail_out(context)
def render(self, context): # Note that this isn't a global constant because we need to change the # value for tests. raise_errors = utils.get_setting('DEBUG') # Get the source file. try: source = self.source_var.resolve(context) except VariableDoesNotExist: if raise_errors: raise VariableDoesNotExist("Variable '%s' does not exist." % self.source_var) return self.bail_out(context) if not source: if raise_errors: raise TemplateSyntaxError( "Variable '%s' is an invalid source." % self.source_var) return self.bail_out(context) # Resolve the thumbnail option values. try: opts = {} for key, value in self.opts.iteritems(): if hasattr(value, 'resolve'): value = value.resolve(context) opts[str(key)] = value except Exception: if raise_errors: raise return self.bail_out(context) # Size variable can be either a tuple/list of two integers or a # valid string. size = opts['size'] if isinstance(size, basestring): m = RE_SIZE.match(size) if m: opts['size'] = (int(m.group(1)), int(m.group(2))) else: if raise_errors: raise TemplateSyntaxError("%r is not a valid size." % size) return self.bail_out(context) try: thumbnail = get_thumbnailer(source).get_thumbnail(opts) except Exception: if raise_errors: raise return self.bail_out(context) # Return the thumbnail file url, or put the file on the context. if self.context_name is None: return escape(thumbnail.url) else: context[self.context_name] = thumbnail return ''
def _resolve_lookup(self, context): """ Performs resolution of a real variable (i.e. not a literal) against the given context. As indicated by the method's name, this method is an implementation detail and shouldn't be called by external code. Use Variable.resolve() instead. """ current = context try: # catch-all for silent variable failures for bit in self.lookups: if callable(current): if getattr(current, 'alters_data', False): current = settings.TEMPLATE_STRING_IF_INVALID else: try: # method call (assuming no args required) current = current() except TypeError: # arguments *were* required # GOTCHA: This will also catch any TypeError # raised in the function itself. current = settings.TEMPLATE_STRING_IF_INVALID # invalid method call try: # dictionary lookup current = current[bit] except (TypeError, AttributeError, KeyError): try: # attribute lookup current = getattr(current, bit) except (TypeError, AttributeError): try: # list-index lookup current = current[int(bit)] except ( IndexError, # list index out of range ValueError, # invalid literal for int() KeyError, # current is a dict without `int(bit)` key TypeError, # unsubscriptable object ): raise VariableDoesNotExist( "Failed lookup for key [%s] in %r", (bit, current)) # missing attribute except Exception, e: if getattr(e, 'silent_variable_failure', False): current = settings.TEMPLATE_STRING_IF_INVALID else: raise
def test_str(self): exc = VariableDoesNotExist(msg='Failed lookup in %r', params=({'foo': 'bar'},)) self.assertEqual(str(exc), "Failed lookup in {'foo': 'bar'}")
def render(self, context): # Note that this isn't a global constant because we need to change the # value for tests. raise_errors = settings.THUMBNAIL_DEBUG # Get the source file. try: source = self.source_var.resolve(context) except VariableDoesNotExist: if raise_errors: raise VariableDoesNotExist( "Variable '%s' does not exist." % self.source_var) return self.bail_out(context) if not source: if raise_errors: raise TemplateSyntaxError( "Variable '%s' is an invalid source." % self.source_var) return self.bail_out(context) # Resolve the thumbnail option values. try: opts = {} for key, value in six.iteritems(self.opts): if hasattr(value, 'resolve'): value = value.resolve(context) opts[str(key)] = value except Exception: if raise_errors: raise return self.bail_out(context) # Size variable can be either a tuple/list of two integers or a # valid string. size = opts['size'] if isinstance(size, six.string_types): m = RE_SIZE.match(size) if m: opts['size'] = (int(m.group(1)), int(m.group(2))) else: # Size variable may alternatively be referencing an alias. alias = aliases.get(size, target=source) if alias: del opts['size'] opts = dict(alias, **opts) else: if raise_errors: raise TemplateSyntaxError( "%r is not a valid size." % size) return self.bail_out(context) # Ensure the quality is an integer. if 'quality' in opts: try: opts['quality'] = int(opts['quality']) except (TypeError, ValueError): if raise_errors: raise TemplateSyntaxError( "%r is an invalid quality." % opts['quality']) return self.bail_out(context) # Ensure the subsampling level is an integer. if 'subsampling' in opts: try: opts['subsampling'] = int(opts['subsampling']) except (TypeError, ValueError): if raise_errors: raise TemplateSyntaxError( "%r is an invalid subsampling level." % opts['subsampling']) return self.bail_out(context) try: thumbnail = get_thumbnailer(source).get_thumbnail(opts) except Exception: if raise_errors: raise return self.bail_out(context) # Return the thumbnail file url, or put the file on the context. if self.context_name is None: return escape(thumbnail.url) else: context[self.context_name] = thumbnail return ''
def resolve_object_property_reference(context, reference, separator=VARIABLE_ATTRIBUTE_SEPARATOR, default=None, error_if_not_found=True, accept_unknown_reference=True): """ Resolve the given object/property reference based on the given context and return the resulting object instance, the property name and its value. If no such property exists and error_if_not_found is True then an exception is raised; otherwise the given default value is returned. """ bits = reference.split(separator) current = context instance = None property_name = None for bit in bits: v = None # dictionary lookup try: v = current[bit] except (TypeError, AttributeError, KeyError, ValueError, IndexError): pass # attribute lookup if v is None: try: v = getattr(current, bit) except (TypeError, AttributeError): pass # list-index lookup if v is None: try: current = current[int(bit)] except (IndexError, ValueError, KeyError, TypeError): pass # unable to resolve if v is None: # if we already resolved the instance, we accept this as a valid # property name anyway, perhabs the property belongs to the form # and not to the model directly... if instance is not None and accept_unknown_reference: property_name = bit break else: if error_if_not_found: raise VariableDoesNotExist( 'Failed lookup for key \'%s\' in object \'%s\'.', (bit, current)) else: return (instance, property_name, default) # callable if callable(v) and not isinstance(current, object): # method call (assuming no args required) v = current() # collect object instance / property name if isinstance(v, models.Model): instance = v property_name = None elif instance is not None and property_name is None: property_name = bit # current value becomes context for next reference in sequence current = v return (instance, property_name, current)