Ejemplo n.º 1
0
    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 ''
Ejemplo n.º 2
0
    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 ''
Ejemplo n.º 3
0
 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 ''
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
    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
Ejemplo n.º 7
0
 def test_str(self):
     exc = VariableDoesNotExist(msg='Failed lookup in %r', params=({'foo': 'bar'},))
     self.assertEqual(str(exc), "Failed lookup in {'foo': 'bar'}")
Ejemplo n.º 8
0
    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 ''
Ejemplo n.º 9
0
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)