diff options
Diffstat (limited to 'brevisurl/backends')
| -rw-r--r-- | brevisurl/backends/__init__.py | 0 | ||||
| -rw-r--r-- | brevisurl/backends/base.py | 41 | ||||
| -rw-r--r-- | brevisurl/backends/local.py | 53 |
3 files changed, 94 insertions, 0 deletions
diff --git a/brevisurl/backends/__init__.py b/brevisurl/backends/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/brevisurl/backends/__init__.py diff --git a/brevisurl/backends/base.py b/brevisurl/backends/base.py new file mode 100644 index 0000000..3fc053a --- /dev/null +++ b/brevisurl/backends/base.py @@ -0,0 +1,41 @@ +from abc import ABCMeta + + +class BaseBrevisUrlBackend(object): + """Base class for brevisurl backend implementations. Subclasses must at least overwrite shorten_url().""" + + __metaclass__ = ABCMeta + + + def __init__(self, fail_silently=False, **kwargs): + self.fail_silently = fail_silently + self.class_path = '{0}.{1}'.format(self.__module__, self.__class__.__name__) + + def open(self): + """Open a network connection. + + This method can be overwritten by backend implementations to + open a network connection. + + It's up to the backend implementation to track the status of + a network connection if it's needed by the backend. + + The default implementation does nothing. + + """ + pass + + def close(self): + """Close a network connection.""" + pass + + def shorten_url(self, original_url): + """Shortens url into more compact form. + + :param original_url: url that will be shortened + :type original_url: string + :returns: shortened url from original url + :rtype: brevisurl.models.ShortUrl + + """ + raise NotImplementedError
\ No newline at end of file diff --git a/brevisurl/backends/local.py b/brevisurl/backends/local.py new file mode 100644 index 0000000..42d0263 --- /dev/null +++ b/brevisurl/backends/local.py @@ -0,0 +1,53 @@ +import string +import random +import logging + +from django.contrib.sites.models import Site + +from brevisurl.backends.base import BaseBrevisUrlBackend +from brevisurl.models import ShortUrl + + +log = logging.getLogger(__name__) + + +class BrevisUrlBackend(BaseBrevisUrlBackend): + + PROTOCOL = 'http' + + def shorten_url(self, original_url): + """ + :raises: ImproperlyConfigured, django.core.exceptions.ValidationError + """ + try: + short_url = ShortUrl.objects.get(backend=self.class_path, original_url=original_url) + log.info('Url "%s" already shortened to "%s"', original_url, short_url.shortened_url) + return short_url + except ShortUrl.DoesNotExist: + pass + + try: + current_site = Site.objects.get_current() + short_url = ShortUrl() + short_url.original_url = original_url + short_url.shortened_url = '{0}://{1}/{2}'.format(self.PROTOCOL, current_site.domain, + self.__generate_token()) + short_url.backend = self.class_path + short_url.save() + log.info('Url "%s" shortened to "%s"', original_url, short_url.shortened_url) + return short_url + except Exception: + if self.fail_silently: + return None + else: + log.exception('Unknown exception raised while shortening url "%s"', original_url) + raise + + def __generate_token(self, size=5): + chars = list(string.ascii_letters + string.digits) + random.shuffle(chars) + while True: + token = ''.join([random.choice(chars) for x in range(size)]) + if not ShortUrl.objects.filter(backend=self.class_path, shortened_url__endswith=token).count(): + break + return token
\ No newline at end of file |
