aboutsummaryrefslogtreecommitdiffstats
path: root/src/shorturls/views.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/shorturls/views.py')
-rw-r--r--src/shorturls/views.py53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/shorturls/views.py b/src/shorturls/views.py
new file mode 100644
index 0000000..d56ee1f
--- /dev/null
+++ b/src/shorturls/views.py
@@ -0,0 +1,53 @@
+import urlparse
+from django.conf import settings
+from django.contrib.sites.models import Site, RequestSite
+from django.db import models
+from django.http import HttpResponsePermanentRedirect, Http404
+from django.shortcuts import get_object_or_404
+from shorturls.baseconv import base62
+
+def redirect(request, prefix, tiny):
+ """
+ Redirect to a given object from a short URL.
+ """
+ # Resolve the prefix and encoded ID into a model object and decoded ID.
+ # Many things here could go wrong -- bad prefix, bad value in
+ # SHORTEN_MODELS, no such model, bad encoding -- so just return a 404 if
+ # any of that stuff goes wrong.
+ try:
+ 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)
+ except (AttributeError, ValueError, KeyError):
+ raise Http404('Bad prefix, model, SHORTEN_MODELS, or encoded ID.')
+
+ # Try to look up the object. If it's not a valid object, or if it doesn't
+ # have an absolute url, bail again.
+ obj = get_object_or_404(model, pk=id)
+ try:
+ url = obj.get_absolute_url()
+ except AttributeError:
+ raise Http404("'%s' models don't have a get_absolute_url() method." % model.__name__)
+
+ # We might have to translate the URL -- the badly-named get_absolute_url
+ # actually returns a domain-relative URL -- into a fully qualified one.
+
+ # If we got a fully-qualified URL, sweet.
+ if urlparse.urlsplit(url).scheme:
+ return HttpResponsePermanentRedirect(url)
+
+ # Otherwise, we need to make a full URL by prepending a base URL.
+ # First, look for an explicit setting.
+ if hasattr(settings, 'SHORTEN_FULL_BASE_URL') and settings.SHORTEN_FULL_BASE_URL:
+ base = settings.SHORTEN_FULL_BASE_URL
+
+ # Next, if the sites app is enabled, redirect to the current site.
+ elif Site._meta.installed:
+ base = 'http://%s/' % Site.objects.get_current().domain
+
+ # Finally, fall back on the current request.
+ else:
+ base = 'http://%s/' % RequestSite(request).domain
+
+ return HttpResponsePermanentRedirect(urlparse.urljoin(base, url)) \ No newline at end of file