diff downloads/views.py @ 581:ee87ea74d46b

For Django 1.4, rearranged project structure for new manage.py.
author Brian Neal <bgneal@gmail.com>
date Sat, 05 May 2012 17:10:48 -0500
parents gpp/downloads/views.py@1a7ca5fa494f
children 89b240fe9297
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/downloads/views.py	Sat May 05 17:10:48 2012 -0500
@@ -0,0 +1,244 @@
+"""
+Views for the downloads application.
+"""
+import random
+
+from django.shortcuts import render_to_response, get_object_or_404
+from django.template import RequestContext
+from django.contrib.auth.decorators import login_required
+from django.http import Http404
+from django.http import HttpResponse
+from django.http import HttpResponseRedirect
+from django.http import HttpResponseForbidden
+from django.http import HttpResponseBadRequest
+from django.http import HttpResponseNotFound
+from django.core.paginator import InvalidPage
+from django.core.urlresolvers import reverse
+from django.db.models import Q
+from django.views.decorators.http import require_POST
+import django.utils.simplejson as json
+
+from core.paginator import DiggPaginator
+from core.functions import email_admins
+from core.functions import get_page
+from downloads.models import Category
+from downloads.models import Download
+from downloads.models import VoteRecord
+from downloads.forms import AddDownloadForm
+
+#######################################################################
+
+DLS_PER_PAGE = 10
+
+def create_paginator(dls):
+   return DiggPaginator(dls, DLS_PER_PAGE, body=5, tail=3, margin=3, padding=2)
+
+#######################################################################
+
+@login_required
+def index(request):
+    categories = Category.objects.all()
+    total_dls = Download.public_objects.all().count()
+    return render_to_response('downloads/index.html', {
+        'categories': categories,
+        'total_dls': total_dls,
+        },
+        context_instance = RequestContext(request))
+
+#######################################################################
+# Maps URL component to database field name for the Download table:
+
+DOWNLOAD_FIELD_MAP = {
+   'title': 'title',
+   'date': '-date_added',
+   'rating': '-average_score',
+   'hits': '-hits'
+}
+
+@login_required
+def category(request, slug, sort='title'):
+
+    cat = get_object_or_404(Category, slug=slug)
+
+    if sort not in DOWNLOAD_FIELD_MAP:
+        sort = 'title'
+    order_by = DOWNLOAD_FIELD_MAP[sort]
+
+    downloads = Download.public_objects.filter(category=cat.pk).order_by(
+            order_by)
+    paginator = create_paginator(downloads)
+    page = get_page(request.GET)
+    try:
+        the_page = paginator.page(page)
+    except InvalidPage:
+        raise Http404
+
+    return render_to_response('downloads/download_list.html', {
+        's' : sort,
+        'category' : cat,
+        'page' : the_page,
+        },
+        context_instance = RequestContext(request))
+
+#######################################################################
+
+@login_required
+def new(request):
+    """Display new downloads with pagination."""
+
+    downloads = Download.public_objects.order_by('-date_added')
+
+    paginator = create_paginator(downloads)
+    page = get_page(request.GET)
+    try:
+        the_page = paginator.page(page)
+    except InvalidPage:
+        raise Http404
+
+    return render_to_response('downloads/download_summary.html', {
+        'page': the_page,
+        'title': 'Newest Downloads',
+        },
+        context_instance = RequestContext(request))
+
+#######################################################################
+
+@login_required
+def popular(request):
+    """Display popular downloads with pagination."""
+
+    downloads = Download.public_objects.order_by('-hits')
+
+    paginator = create_paginator(downloads)
+    page = get_page(request.GET)
+    try:
+        the_page = paginator.page(page)
+    except InvalidPage:
+        raise Http404
+
+    return render_to_response('downloads/download_summary.html', {
+        'page': the_page,
+        'title': 'Popular Downloads',
+        },
+        context_instance = RequestContext(request))
+
+#######################################################################
+
+@login_required
+def rating(request):
+    """Display downloads by rating with pagination."""
+
+    downloads = Download.public_objects.order_by('-average_score')
+    paginator = create_paginator(downloads)
+    page = get_page(request.GET)
+    try:
+        the_page = paginator.page(page)
+    except InvalidPage:
+        raise Http404
+
+    return render_to_response('downloads/download_summary.html', {
+        'page': the_page,
+        'title': 'Highest Rated Downloads',
+        },
+        context_instance = RequestContext(request))
+
+#######################################################################
+
+@login_required
+def details(request, id):
+    download = get_object_or_404(Download.public_objects, pk=id)
+    return render_to_response('downloads/download_detail.html', {
+        'download' : download,
+        },
+        context_instance = RequestContext(request))
+
+#######################################################################
+
+@login_required
+def add(request):
+    if request.method == 'POST':
+        form = AddDownloadForm(request.POST, request.FILES)
+        if form.is_valid():
+            dl = form.save(commit=False)
+            dl.user = request.user
+            dl.ip_address = request.META.get('REMOTE_ADDR', None)
+            dl.save()
+            email_admins('New download for approval', """Hello,
+
+A user has uploaded a new download for your approval.
+""")
+            return HttpResponseRedirect(reverse('downloads-add_thanks'))
+    else:
+        form = AddDownloadForm()
+
+    return render_to_response('downloads/add.html', {
+        'add_form': form,
+        },
+        context_instance=RequestContext(request))
+
+#######################################################################
+
+@login_required
+def thanks(request):
+    return render_to_response('downloads/thanks.html', {
+        },
+        context_instance=RequestContext(request))
+
+#######################################################################
+
+@require_POST
+def rate_download(request):
+    """This function is called by AJAX to rate a download."""
+    if request.user.is_authenticated():
+        id = request.POST.get('id', None)
+        rating = request.POST.get('rating', None)
+        if id is None or rating is None:
+            return HttpResponseBadRequest('Missing id or rating.')
+
+        try:
+            rating = int(rating)
+        except ValueError:
+            return HttpResponseBadRequest('Invalid rating.')
+
+        # rating will be from 0-4
+        rating = min(5, max(1, rating))
+
+        download = get_object_or_404(Download.public_objects, pk=id)
+
+        # prevent multiple votes from the same user
+        vote_record, created = VoteRecord.objects.get_or_create(
+                download=download, user=request.user)
+        if created:
+            new_score = download.vote(rating)
+            download.save()
+            return HttpResponse(str(new_score))
+        else:
+            return HttpResponse('-1')
+
+    return HttpResponseForbidden('You must be logged in to rate a download.')
+
+#######################################################################
+
+@require_POST
+def request_download(request):
+    """
+    This function is called by AJAX to request a download. We update the hit
+    count and then return a JSON object of the form:
+        { id: download-id, 'url': link-to-download }
+
+    """
+    if request.user.is_authenticated():
+        dl_id = request.POST.get('id')
+        if dl_id:
+            try:
+                dl = Download.public_objects.get(pk=dl_id)
+            except Download.DoesNotExist:
+                return HttpResponseNotFound("Download not found")
+
+            dl.hits += 1
+            dl.save()
+
+            s = json.dumps({'id': dl_id, 'url': dl.file.url})
+            return HttpResponse(s, content_type='application/json')
+
+    return HttpResponseForbidden('An error occurred.')