from django.core.cache import cache
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import render
from django.utils import timezone, http
from qrurls.models import URL, URLItem
import calendar # timegm
"""
Public frontend UI.
"""
class URLNotFound (Http404):
pass
class URLItemNotFound (Http404):
pass
def http_datetime (dt) :
return http.http_date(calendar.timegm(dt.utctimetuple()))
def _get_url_item (shorturl=None, shorturl_id=None, item_id=None, related=()) :
# JOIN against shorturl, urlimage
url_item = URLItem.objects.select_related(*related)
if shorturl:
url_item = url_item.filter(shorturl__shorturl=shorturl)
elif shorturl_id:
shorturl_id = int(shorturl_id)
url_item = url_item.filter(shorturl__id=shorturl_id)
else:
raise URLNotFound()
# match for published items
now = timezone.now()
url_item = url_item.filter(published__lt=now).order_by('-published')
if item_id :
return url_item.get(id=int(item_id))
else :
# most recent
try:
return url_item[0]
except IndexError:
raise URLItemNotFound()
def index (request) :
urls = URL.objects.all()
return render(request, 'qrurls/index.html', dict(
urls = urls,
))
def shorturl (request, shorturl=None, shorturl_id=None) :
"""
Primary frontend for redirecting based on current time.
"""
key = 'qrurls/urlfeed/{shorturl}'.format(shorturl=(shorturl or shorturl_id)) # format as dict
data = cache.get(key)
if data :
url, modified = data
else:
url_item = _get_url_item(shorturl=shorturl, shorturl_id=shorturl_id)
modified = url_item.last_modified()
url = url_item.get_absolute_url()
cache.set(key, (url, modified)) # XXX: expiry
# redirect, either directly, or to image()
response = HttpResponseRedirect(url)
response['Vary'] = ''
response['Last-Modified'] = http_datetime(modified)
return response
def item (request, shorturl, item_id) :
"""
Frontend for a specific item.
"""
url_item = _get_url_item(
shorturl=shorturl, item_id=item_id,
related=('shorturl', 'image')
)
if url_item.url :
response = HttpResponseRedirect(url_item.url)
elif url_item.image :
title = url_item.image.title or url_item.shorturl.title
response = render(request, 'qrurls/image.html', dict(
title = title,
image = url_item.image,
))
else :
raise Http404()
# set cache
response['Vary'] = ''
response['Last-Modified'] = http_datetime(url_item.last_modified())
return response