qrurls/views.py
author Tero Marttila <terom@fixme.fi>
Fri, 06 Sep 2013 01:36:33 +0300
changeset 79 b125b3fcd52d
parent 78 7e40b1d2be3e
child 80 3aaac91a6654
permissions -rw-r--r--
fix 404 for invalid id in urlitem
73
66b572c06b0a caching for shorturl redirect
Tero Marttila <terom@fixme.fi>
parents: 72
diff changeset
     1
from django.core.cache import cache
2
e838dda048a6 qrurls: basic functionality
Tero Marttila <terom@fixme.fi>
parents: 0
diff changeset
     2
from django.http import HttpResponse, HttpResponseRedirect, Http404
12
7605af83cb14 add qrurls index
Tero Marttila <terom@fixme.fi>
parents: 7
diff changeset
     3
from django.shortcuts import render
72
ea7a5a5ce7d4 add Last-Modified to urlitem responses (redirect and html)
Tero Marttila <terom@fixme.fi>
parents: 71
diff changeset
     4
from django.utils import timezone, http
2
e838dda048a6 qrurls: basic functionality
Tero Marttila <terom@fixme.fi>
parents: 0
diff changeset
     5
e838dda048a6 qrurls: basic functionality
Tero Marttila <terom@fixme.fi>
parents: 0
diff changeset
     6
from qrurls.models import URL, URLItem
e838dda048a6 qrurls: basic functionality
Tero Marttila <terom@fixme.fi>
parents: 0
diff changeset
     7
72
ea7a5a5ce7d4 add Last-Modified to urlitem responses (redirect and html)
Tero Marttila <terom@fixme.fi>
parents: 71
diff changeset
     8
import calendar # timegm
ea7a5a5ce7d4 add Last-Modified to urlitem responses (redirect and html)
Tero Marttila <terom@fixme.fi>
parents: 71
diff changeset
     9
54
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
    10
"""
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
    11
    Public frontend UI.
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
    12
"""
Tero Marttila <terom@fixme.fi>
parents: 51
diff changeset
    13
71
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    14
class URLNotFound (Http404):
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    15
    pass
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    16
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    17
class URLItemNotFound (Http404):
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    18
    pass
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    19
72
ea7a5a5ce7d4 add Last-Modified to urlitem responses (redirect and html)
Tero Marttila <terom@fixme.fi>
parents: 71
diff changeset
    20
def http_datetime (dt) :
ea7a5a5ce7d4 add Last-Modified to urlitem responses (redirect and html)
Tero Marttila <terom@fixme.fi>
parents: 71
diff changeset
    21
    return http.http_date(calendar.timegm(dt.utctimetuple()))
ea7a5a5ce7d4 add Last-Modified to urlitem responses (redirect and html)
Tero Marttila <terom@fixme.fi>
parents: 71
diff changeset
    22
71
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    23
def _get_url_item (shorturl=None, shorturl_id=None, item_id=None, related=()) :
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    24
    # JOIN against shorturl, urlimage
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    25
    url_item = URLItem.objects.select_related(*related)
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    26
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    27
    if shorturl:
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    28
        url_item = url_item.filter(shorturl__shorturl=shorturl)
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    29
    elif shorturl_id:
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    30
        shorturl_id = int(shorturl_id)
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    31
        url_item = url_item.filter(shorturl__id=shorturl_id)
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    32
    else:
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    33
        raise URLNotFound()
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    34
    
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    35
    # match for published items
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    36
    now = timezone.now()
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    37
    url_item = url_item.filter(published__lt=now).order_by('-published')
73
66b572c06b0a caching for shorturl redirect
Tero Marttila <terom@fixme.fi>
parents: 72
diff changeset
    38
   
66b572c06b0a caching for shorturl redirect
Tero Marttila <terom@fixme.fi>
parents: 72
diff changeset
    39
    if item_id :
79
b125b3fcd52d fix 404 for invalid id in urlitem
Tero Marttila <terom@fixme.fi>
parents: 78
diff changeset
    40
        try :
b125b3fcd52d fix 404 for invalid id in urlitem
Tero Marttila <terom@fixme.fi>
parents: 78
diff changeset
    41
            return url_item.get(id=int(item_id))
b125b3fcd52d fix 404 for invalid id in urlitem
Tero Marttila <terom@fixme.fi>
parents: 78
diff changeset
    42
        except URLItem.DoesNotExist:
b125b3fcd52d fix 404 for invalid id in urlitem
Tero Marttila <terom@fixme.fi>
parents: 78
diff changeset
    43
            raise URLItemNotFound()
73
66b572c06b0a caching for shorturl redirect
Tero Marttila <terom@fixme.fi>
parents: 72
diff changeset
    44
    else :
71
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    45
        # most recent
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    46
        try:
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    47
            return url_item[0]
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    48
        except IndexError:
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    49
            raise URLItemNotFound()
33
b714115da724 use seprate frontend view for url_images in url_items
Tero Marttila <terom@fixme.fi>
parents: 19
diff changeset
    50
12
7605af83cb14 add qrurls index
Tero Marttila <terom@fixme.fi>
parents: 7
diff changeset
    51
def index (request) :
7605af83cb14 add qrurls index
Tero Marttila <terom@fixme.fi>
parents: 7
diff changeset
    52
    urls = URL.objects.all()
7605af83cb14 add qrurls index
Tero Marttila <terom@fixme.fi>
parents: 7
diff changeset
    53
    return render(request, 'qrurls/index.html', dict(
7605af83cb14 add qrurls index
Tero Marttila <terom@fixme.fi>
parents: 7
diff changeset
    54
        urls    = urls,
7605af83cb14 add qrurls index
Tero Marttila <terom@fixme.fi>
parents: 7
diff changeset
    55
    ))
7605af83cb14 add qrurls index
Tero Marttila <terom@fixme.fi>
parents: 7
diff changeset
    56
76
04b5035f5775 touchup cache keys
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    57
def shorturl (request, shorturl=None, shorturl_id=None) :
70
e8a8d490df2f optimize shorturl() to use a single SELECT JOIN query
Tero Marttila <terom@fixme.fi>
parents: 54
diff changeset
    58
    """
e8a8d490df2f optimize shorturl() to use a single SELECT JOIN query
Tero Marttila <terom@fixme.fi>
parents: 54
diff changeset
    59
        Primary frontend for redirecting based on current time.
e8a8d490df2f optimize shorturl() to use a single SELECT JOIN query
Tero Marttila <terom@fixme.fi>
parents: 54
diff changeset
    60
    """
73
66b572c06b0a caching for shorturl redirect
Tero Marttila <terom@fixme.fi>
parents: 72
diff changeset
    61
    
76
04b5035f5775 touchup cache keys
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    62
    key = 'qrurls/urlfeed/{shorturl}'.format(shorturl=(shorturl or shorturl_id)) # format as dict
73
66b572c06b0a caching for shorturl redirect
Tero Marttila <terom@fixme.fi>
parents: 72
diff changeset
    63
    data = cache.get(key)
66b572c06b0a caching for shorturl redirect
Tero Marttila <terom@fixme.fi>
parents: 72
diff changeset
    64
    
66b572c06b0a caching for shorturl redirect
Tero Marttila <terom@fixme.fi>
parents: 72
diff changeset
    65
    if data :
66b572c06b0a caching for shorturl redirect
Tero Marttila <terom@fixme.fi>
parents: 72
diff changeset
    66
        url, modified = data
66b572c06b0a caching for shorturl redirect
Tero Marttila <terom@fixme.fi>
parents: 72
diff changeset
    67
    else:
76
04b5035f5775 touchup cache keys
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    68
        url_item = _get_url_item(shorturl=shorturl, shorturl_id=shorturl_id)
04b5035f5775 touchup cache keys
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    69
73
66b572c06b0a caching for shorturl redirect
Tero Marttila <terom@fixme.fi>
parents: 72
diff changeset
    70
        modified = url_item.last_modified()
66b572c06b0a caching for shorturl redirect
Tero Marttila <terom@fixme.fi>
parents: 72
diff changeset
    71
        url = url_item.get_absolute_url()
71
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    72
73
66b572c06b0a caching for shorturl redirect
Tero Marttila <terom@fixme.fi>
parents: 72
diff changeset
    73
        cache.set(key, (url, modified)) # XXX: expiry
33
b714115da724 use seprate frontend view for url_images in url_items
Tero Marttila <terom@fixme.fi>
parents: 19
diff changeset
    74
40
5eefe5a294dc qrurl image title
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
    75
    # redirect, either directly, or to image()
73
66b572c06b0a caching for shorturl redirect
Tero Marttila <terom@fixme.fi>
parents: 72
diff changeset
    76
    response = HttpResponseRedirect(url)
74
b8f1ae4247ad override views to drop Vary header, as we don't care about the session
Tero Marttila <terom@fixme.fi>
parents: 73
diff changeset
    77
    response['Vary'] = ''
73
66b572c06b0a caching for shorturl redirect
Tero Marttila <terom@fixme.fi>
parents: 72
diff changeset
    78
    response['Last-Modified'] = http_datetime(modified)
72
ea7a5a5ce7d4 add Last-Modified to urlitem responses (redirect and html)
Tero Marttila <terom@fixme.fi>
parents: 71
diff changeset
    79
    return response
2
e838dda048a6 qrurls: basic functionality
Tero Marttila <terom@fixme.fi>
parents: 0
diff changeset
    80
    
76
04b5035f5775 touchup cache keys
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    81
def item (request, shorturl, item_id) :
71
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    82
    """
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    83
        Frontend for a specific item.
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    84
    """
76
04b5035f5775 touchup cache keys
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    85
    
04b5035f5775 touchup cache keys
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    86
    url_item = _get_url_item(
04b5035f5775 touchup cache keys
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    87
            shorturl=shorturl, item_id=item_id,
04b5035f5775 touchup cache keys
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    88
            related=('shorturl', 'image')
04b5035f5775 touchup cache keys
Tero Marttila <terom@fixme.fi>
parents: 75
diff changeset
    89
    )
71
04f4f312d4ad optimize item view to JOIN across models, using common _get_url_item for both views
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
    90
43
3b1f1a928283 rename qrurls image view to item view
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
    91
    if url_item.url :
72
ea7a5a5ce7d4 add Last-Modified to urlitem responses (redirect and html)
Tero Marttila <terom@fixme.fi>
parents: 71
diff changeset
    92
        response = HttpResponseRedirect(url_item.url)
43
3b1f1a928283 rename qrurls image view to item view
Tero Marttila <terom@fixme.fi>
parents: 42
diff changeset
    93
    elif url_item.image :
72
ea7a5a5ce7d4 add Last-Modified to urlitem responses (redirect and html)
Tero Marttila <terom@fixme.fi>
parents: 71
diff changeset
    94
        response = render(request, 'qrurls/image.html', dict(
78
7e40b1d2be3e move urlitem title logic to URLItem.title()
Tero Marttila <terom@fixme.fi>
parents: 76
diff changeset
    95
            title   = url_item.title(),
40
5eefe5a294dc qrurl image title
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
    96
            image   = url_item.image,
5eefe5a294dc qrurl image title
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
    97
        ))
5eefe5a294dc qrurl image title
Tero Marttila <terom@fixme.fi>
parents: 37
diff changeset
    98
    else :
33
b714115da724 use seprate frontend view for url_images in url_items
Tero Marttila <terom@fixme.fi>
parents: 19
diff changeset
    99
        raise Http404()
72
ea7a5a5ce7d4 add Last-Modified to urlitem responses (redirect and html)
Tero Marttila <terom@fixme.fi>
parents: 71
diff changeset
   100
ea7a5a5ce7d4 add Last-Modified to urlitem responses (redirect and html)
Tero Marttila <terom@fixme.fi>
parents: 71
diff changeset
   101
    # set cache
74
b8f1ae4247ad override views to drop Vary header, as we don't care about the session
Tero Marttila <terom@fixme.fi>
parents: 73
diff changeset
   102
    response['Vary'] = ''
72
ea7a5a5ce7d4 add Last-Modified to urlitem responses (redirect and html)
Tero Marttila <terom@fixme.fi>
parents: 71
diff changeset
   103
    response['Last-Modified'] = http_datetime(url_item.last_modified())
ea7a5a5ce7d4 add Last-Modified to urlitem responses (redirect and html)
Tero Marttila <terom@fixme.fi>
parents: 71
diff changeset
   104
    return response
ea7a5a5ce7d4 add Last-Modified to urlitem responses (redirect and html)
Tero Marttila <terom@fixme.fi>
parents: 71
diff changeset
   105