Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Replaces the BaseConverter class by the SequenceMapper #3

Closed
wants to merge 1 commit into from

2 participants

@arthurfurlan

Hi Jacob,

I needed to create a ShortURL application for Django and decided to not use "django-shorturls" because I have some different ideas for my project and would have to make lots of changes in the code of your application.

Based on that I started to look about some base converters algorithms to use but all of them are based in the mathematical chains of numbers and, becasue of that, excludes a lot of possible ShortURL codes. I decided to create my own "base converter", which I called "SequenceMapper" because it doesn't convert number between bases in fact, it just maps a number to its respective chain of chars. I created a gist in Github to try to explain what I'm talking about: https://gist.github.com/789720. This code is open source and my application is also hosted in Github: https://github.com/valvim/django-shortim.

So what my patch do is basically change the "BaseConverter" that is currently being used in the "django-shorturls" by the "SequenceMapper" that I'm using in my application. This application is already working in http://va.mu (Brazilian portuguese only, sorry).

Hope my code could be useful. :)
Thanks.

@bfirsh
Owner

#8 now includes something like this. See how base 32 does mapping of characters.

Thanks for the contribution!

@bfirsh bfirsh closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 21, 2011
This page is out of date. Refresh to see the latest.
View
49 src/shorturls/sequencemapper.py
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+
+# Code extracted from the project "django-shortim":
+# * https://github.com/valvim/django-shortim/
+# * https://github.com/valvim/django-shortim/blob/master/src/shortim/models.py
+#
+# Author: Arthur Furlan <afurlan@valv.im>
+
+from django.db import models
+from django.conf import settings
+import string
+
+## set the default shorturl chars
+DEFAULT_SHORTURL_CHARS = string.uppercase
+DEFAULT_SHORTURL_CHARS += string.lowercase
+DEFAULT_SHORTURL_CHARS += string.digits
+
+## allow user to configure a different chars chain
+SHORTURL_CHARS = getattr(settings,
+ 'SHORTURL_CHARS', DEFAULT_SHORTURL_CHARS)
+
+class SequenceMapper(object):
+
+ @staticmethod
+ def from_decimal(number):
+ base = len(SHORTURL_CHARS)
+ code = ''
+
+ ## generate the respective code of the sequence
+ index = 1
+ while number > 0 and index+1 > 0:
+ index = number % base - 1
+ code = SHORTURL_CHARS[index] + code
+ number = number / base
+ if number > 0 and index < 0:
+ number -= 1
+ index = 0
+ return code
+
+ @staticmethod
+ def to_decimal(code):
+ base = len(SHORTURL_CHARS)
+ number = 0
+
+ ## calculate the respective number of the code
+ for i, c in enumerate(code[::-1]):
+ index = SHORTURL_CHARS.index(c)
+ number += base ** i * (index+1)
+ return number
View
10 src/shorturls/tests/test_sequencemapper.py
@@ -0,0 +1,10 @@
+import unittest
+from shorturls.sequencemapper import SequenceMapper
+
+class SequenceMapperTests(unittest.TestCase):
+
+ def test_mapper(self):
+ nums = [-10 ** 10, 10 ** 10] + range(-100, 100)
+ for before in nums:
+ after = SequenceMapper.to_decimal(converter.from_decimal(before))
+ self.assertEqual(before, after)
View
6 src/shorturls/views.py
@@ -4,7 +4,7 @@
from django.db import models
from django.http import HttpResponsePermanentRedirect, Http404
from django.shortcuts import get_object_or_404
-from shorturls.baseconv import base62
+from shorturls.sequencemapper import SequenceMapper
def redirect(request, prefix, tiny):
"""
@@ -18,7 +18,7 @@ def redirect(request, prefix, tiny):
app_label, model_name = settings.SHORTEN_MODELS[prefix].split('.')
model = models.get_model(app_label, model_name)
if not model: raise ValueError
- id = base62.to_decimal(tiny)
+ id = SequenceMapper.to_decimal(tiny)
except (AttributeError, ValueError, KeyError):
raise Http404('Bad prefix, model, SHORTEN_MODELS, or encoded ID.')
@@ -50,4 +50,4 @@ def redirect(request, prefix, tiny):
else:
base = 'http://%s/' % RequestSite(request).domain
- return HttpResponsePermanentRedirect(urlparse.urljoin(base, url))
+ return HttpResponsePermanentRedirect(urlparse.urljoin(base, url))
Something went wrong with that request. Please try again.