qrurls/views.py
author Tero Marttila <terom@fixme.fi>
Mon, 02 Sep 2013 03:50:50 +0300
changeset 74 b8f1ae4247ad
parent 73 66b572c06b0a
child 75 839410915625
permissions -rw-r--r--
override views to drop Vary header, as we don't care about the session
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, **opts) :
    """
        Primary frontend for redirecting based on current time.
    """
    
    key = 'qrurls/urlfeed/{}/url'.format(opts)
    data = cache.get(key)
    
    if data :
        url, modified = data
    else:
        url_item = _get_url_item(**opts)
        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)

    # set cache
    response['Vary'] = ''
    response['Last-Modified'] = http_datetime(modified)
    return response
    
def item (request, **opts) :
    """
        Frontend for a specific item.
    """

    url_item = _get_url_item(related=('shorturl', 'image',), **opts)

    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