gremmie@1: """ gremmie@1: Views for the downloads application. gremmie@1: """ gremmie@1: import random gremmie@1: gremmie@1: from django.shortcuts import render_to_response gremmie@1: from django.template import RequestContext gremmie@1: from django.contrib.auth.decorators import login_required gremmie@1: from django.http import Http404 gremmie@1: from django.http import HttpResponse gremmie@1: from django.http import HttpResponseRedirect gremmie@1: from django.http import HttpResponseForbidden gremmie@1: from django.http import HttpResponseBadRequest bgneal@92: from django.core.paginator import InvalidPage gremmie@1: from django.core.urlresolvers import reverse gremmie@1: from django.db.models import Q gremmie@1: from django.views.decorators.http import require_POST gremmie@1: gremmie@1: from core.paginator import DiggPaginator gremmie@1: from core.functions import email_admins bgneal@241: from core.functions import get_page gremmie@1: from downloads.models import Category gremmie@1: from downloads.models import Download gremmie@1: from downloads.models import VoteRecord gremmie@1: from downloads.forms import AddDownloadForm gremmie@1: gremmie@1: ####################################################################### gremmie@1: bgneal@242: DLS_PER_PAGE = 10 gremmie@1: gremmie@1: def create_paginator(dls): gremmie@1: return DiggPaginator(dls, DLS_PER_PAGE, body=5, tail=3, margin=3, padding=2) gremmie@1: gremmie@1: ####################################################################### gremmie@1: gremmie@1: @login_required gremmie@1: def index(request): gremmie@1: categories = Category.objects.all() gremmie@1: total_dls = Download.public_objects.all().count() gremmie@1: return render_to_response('downloads/index.html', { gremmie@1: 'categories': categories, gremmie@1: 'total_dls': total_dls, gremmie@1: }, gremmie@1: context_instance = RequestContext(request)) gremmie@1: gremmie@1: ####################################################################### gremmie@1: # Maps URL component to database field name for the Download table: gremmie@1: gremmie@1: DOWNLOAD_FIELD_MAP = { gremmie@1: 'title': 'title', gremmie@1: 'date': '-date_added', gremmie@1: 'rating': '-average_score', gremmie@1: 'hits': '-hits' gremmie@1: } gremmie@1: gremmie@1: @login_required bgneal@241: def category(request, slug, sort='title'): gremmie@1: try: bgneal@241: cat = Category.objects.get(slug=slug) gremmie@1: except Category.DoesNotExist: gremmie@1: raise Http404 gremmie@1: gremmie@1: if sort not in DOWNLOAD_FIELD_MAP: gremmie@1: sort = 'title' gremmie@1: order_by = DOWNLOAD_FIELD_MAP[sort] gremmie@1: bgneal@190: downloads = Download.public_objects.filter(category=cat.pk).order_by( bgneal@190: order_by) gremmie@1: paginator = create_paginator(downloads) bgneal@241: page = get_page(request.GET) gremmie@1: try: bgneal@241: the_page = paginator.page(page) gremmie@1: except InvalidPage: gremmie@1: raise Http404 gremmie@1: gremmie@1: return render_to_response('downloads/download_list.html', { gremmie@1: 's' : sort, gremmie@1: 'category' : cat, gremmie@1: 'page' : the_page, gremmie@1: }, gremmie@1: context_instance = RequestContext(request)) gremmie@1: gremmie@1: ####################################################################### gremmie@1: gremmie@1: @login_required gremmie@1: def new(request): bgneal@243: """Display new downloads with pagination.""" bgneal@243: bgneal@243: downloads = Download.public_objects.order_by('-date_added') bgneal@243: bgneal@243: paginator = create_paginator(downloads) bgneal@243: page = get_page(request.GET) bgneal@243: try: bgneal@243: the_page = paginator.page(page) bgneal@243: except InvalidPage: bgneal@243: raise Http404 bgneal@243: gremmie@1: return render_to_response('downloads/download_summary.html', { bgneal@243: 'page': the_page, bgneal@243: 'title': 'Newest Downloads', gremmie@1: }, gremmie@1: context_instance = RequestContext(request)) gremmie@1: gremmie@1: ####################################################################### gremmie@1: gremmie@1: @login_required gremmie@1: def popular(request): bgneal@243: """Display popular downloads with pagination.""" bgneal@243: bgneal@243: downloads = Download.public_objects.order_by('-hits') bgneal@243: bgneal@243: paginator = create_paginator(downloads) bgneal@243: page = get_page(request.GET) bgneal@243: try: bgneal@243: the_page = paginator.page(page) bgneal@243: except InvalidPage: bgneal@243: raise Http404 bgneal@243: gremmie@1: return render_to_response('downloads/download_summary.html', { bgneal@243: 'page': the_page, bgneal@243: 'title': 'Popular Downloads', gremmie@1: }, gremmie@1: context_instance = RequestContext(request)) gremmie@1: gremmie@1: ####################################################################### gremmie@1: gremmie@1: @login_required gremmie@1: def rating(request): bgneal@243: """Display downloads by rating with pagination.""" bgneal@243: bgneal@243: downloads = Download.public_objects.order_by('-average_score') bgneal@243: paginator = create_paginator(downloads) bgneal@243: page = get_page(request.GET) bgneal@243: try: bgneal@243: the_page = paginator.page(page) bgneal@243: except InvalidPage: bgneal@243: raise Http404 bgneal@243: gremmie@1: return render_to_response('downloads/download_summary.html', { bgneal@243: 'page': the_page, bgneal@243: 'title': 'Highest Rated Downloads', gremmie@1: }, gremmie@1: context_instance = RequestContext(request)) gremmie@1: gremmie@1: ####################################################################### gremmie@1: gremmie@1: @login_required bgneal@208: @require_POST gremmie@1: def download(request, id): gremmie@1: download = Download.public_objects.get(pk=id) gremmie@1: if download is None: gremmie@1: raise Http404 gremmie@1: return _redirect_download(download) gremmie@1: gremmie@1: ####################################################################### gremmie@1: gremmie@1: def _redirect_download(download): gremmie@1: download.hits += 1 gremmie@1: download.save() gremmie@1: return HttpResponseRedirect(download.file.url) gremmie@1: gremmie@1: ####################################################################### gremmie@1: gremmie@1: @login_required bgneal@23: def details(request, id): gremmie@1: download = Download.public_objects.get(pk=id) gremmie@1: if download is None: gremmie@1: raise Http404 bgneal@23: return render_to_response('downloads/download_detail.html', { gremmie@1: 'download' : download, gremmie@1: }, gremmie@1: context_instance = RequestContext(request)) gremmie@1: gremmie@1: ####################################################################### gremmie@1: gremmie@1: @login_required bgneal@208: @require_POST gremmie@1: def random_download(request): gremmie@1: ids = Download.public_objects.values_list('id', flat=True) gremmie@1: if not ids: gremmie@1: raise Http404 gremmie@1: id = random.choice(ids) gremmie@1: download = Download.objects.get(pk=id) gremmie@1: return _redirect_download(download) gremmie@1: gremmie@1: ####################################################################### gremmie@1: gremmie@1: @login_required gremmie@1: def add(request): gremmie@1: if request.method == 'POST': gremmie@1: form = AddDownloadForm(request.POST, request.FILES) gremmie@1: if form.is_valid(): gremmie@1: dl = form.save(commit=False) gremmie@1: dl.user = request.user gremmie@1: dl.ip_address = request.META.get('REMOTE_ADDR', None) gremmie@1: dl.save() gremmie@1: email_admins('New download for approval', """Hello, gremmie@1: gremmie@1: A user has uploaded a new download for your approval. gremmie@1: """) gremmie@1: return HttpResponseRedirect(reverse('downloads-add_thanks')) gremmie@1: else: gremmie@1: form = AddDownloadForm() gremmie@1: gremmie@1: return render_to_response('downloads/add.html', { gremmie@1: 'add_form': form, gremmie@1: }, gremmie@1: context_instance=RequestContext(request)) gremmie@1: gremmie@1: ####################################################################### gremmie@1: gremmie@1: @login_required gremmie@1: def thanks(request): gremmie@1: return render_to_response('downloads/thanks.html', { gremmie@1: }, gremmie@1: context_instance=RequestContext(request)) gremmie@1: gremmie@1: ####################################################################### gremmie@1: gremmie@1: @require_POST gremmie@1: def rate_download(request): gremmie@1: """This function is called by AJAX to rate a download.""" gremmie@1: if request.user.is_authenticated(): gremmie@1: id = request.POST.get('id', None) gremmie@1: rating = request.POST.get('rating', None) gremmie@1: if id is None or rating is None: gremmie@1: return HttpResponseBadRequest('Missing id or rating.') gremmie@1: gremmie@1: try: gremmie@1: rating = int(rating) gremmie@1: except ValueError: gremmie@1: return HttpResponseBadRequest('Invalid rating.') gremmie@1: gremmie@1: # rating will be from 0-4 gremmie@1: rating = min(5, max(1, rating)) gremmie@1: gremmie@1: try: gremmie@1: download = Download.public_objects.get(pk=id) gremmie@1: except Download.DoesNotExist: gremmie@1: return HttpResponseBadRequest('Invalid download id.') gremmie@1: gremmie@1: # prevent multiple votes from the same user bgneal@241: vote_record, created = VoteRecord.objects.get_or_create( bgneal@241: download=download, user=request.user) gremmie@1: if created: gremmie@1: new_score = download.vote(rating) gremmie@1: download.save() gremmie@1: return HttpResponse(str(new_score)) gremmie@1: else: gremmie@1: return HttpResponse('-1') gremmie@1: gremmie@1: return HttpResponseForbidden('You must be logged in to rate a download.')