Example #1
0
    def shorten_url(self, original_url):
        """
        :raises: ImproperlyConfigured, django.core.exceptions.ValidationError
        :raises: brevisurl.backends.local.TokensExhaustedError
        """

        if self.kwargs.get('domain') is not None:
            # Domain is present in keyword arguments supplied by constructor.
            domain = self.kwargs.get('domain')
        elif brevisurl.settings.LOCAL_BACKEND_DOMAIN is not None:
            # Domain is defined in settings.
            domain = brevisurl.settings.LOCAL_BACKEND_DOMAIN
        else:
            # Domain is taken from django site framework.
            domain = Site.objects.get_current().domain

        try:
            shortened_url = self.__generate_shortened_url(domain)
            try:
                short_url, created = ShortUrl.objects.get_or_create(
                    backend=self.class_path,
                    original_url=original_url,
                    original_url_hash=ShortUrl.url_hash(original_url),
                    defaults={'shortened_url': shortened_url})
                if created:
                    log.info('Url "%s" shortened to "%s"', original_url,
                             shortened_url)
                else:
                    log.info('Url "%s" already shortened to "%s"',
                             original_url, short_url.shortened_url)
                return short_url
            except (IntegrityError, ValidationError) as e:
                # Check if the error is an URL validation error.
                if isinstance(e, ValidationError) and e.message_dict.has_key(
                        'original_url'):
                    raise

                # Generate another token.
                self.__check_tokens_exhausted()
                while True:
                    shortened_url = self.__generate_shortened_url(domain)
                    sid = transaction.savepoint()
                    try:
                        short_url = ShortUrl.objects.create(
                            backend=self.class_path,
                            original_url=original_url,
                            shortened_url=shortened_url)
                        log.info('Url "%s" shortened to "%s"', original_url,
                                 shortened_url)
                        transaction.savepoint_commit(sid)
                        return short_url
                    except (IntegrityError, ValidationError) as e:
                        transaction.savepoint_rollback(sid)
                        self.__check_tokens_exhausted()
        except Exception:
            if self.fail_silently:
                return None
            else:
                log.exception(
                    'Unknown exception raised while shortening url "%s"',
                    original_url)
                raise