annotate gpp/downloads/views.py @ 197:2baadae33f2e

Got autocomplete working for the member search. Updated django and ran into a bug where url tags with comma separated kwargs starting consuming tons of CPU throughput. The work-around is to cut over to using spaces between arguments. This is now allowed to be consistent with other tags. Did some query optimization for the news app.
author Brian Neal <bgneal@gmail.com>
date Sat, 10 Apr 2010 04:32:24 +0000
parents 0e4961833cdf
children b4305e18d3af
rev   line source
gremmie@1 1 """
gremmie@1 2 Views for the downloads application.
gremmie@1 3 """
gremmie@1 4 import random
gremmie@1 5
gremmie@1 6 from django.shortcuts import render_to_response
gremmie@1 7 from django.template import RequestContext
gremmie@1 8 from django.contrib.auth.decorators import login_required
gremmie@1 9 from django.http import Http404
gremmie@1 10 from django.http import HttpResponse
gremmie@1 11 from django.http import HttpResponseRedirect
gremmie@1 12 from django.http import HttpResponseForbidden
gremmie@1 13 from django.http import HttpResponseBadRequest
bgneal@92 14 from django.core.paginator import InvalidPage
gremmie@1 15 from django.core.urlresolvers import reverse
gremmie@1 16 from django.db.models import Q
gremmie@1 17 from django.views.decorators.http import require_POST
gremmie@1 18
gremmie@1 19 from core.paginator import DiggPaginator
gremmie@1 20 from core.functions import email_admins
gremmie@1 21 from downloads.models import Category
gremmie@1 22 from downloads.models import Download
gremmie@1 23 from downloads.models import VoteRecord
gremmie@1 24 from downloads.forms import AddDownloadForm
gremmie@1 25 from downloads.forms import SearchForm
gremmie@1 26
gremmie@1 27 #######################################################################
gremmie@1 28
gremmie@1 29 DLS_PER_PAGE = 10
gremmie@1 30
gremmie@1 31 def create_paginator(dls):
gremmie@1 32 return DiggPaginator(dls, DLS_PER_PAGE, body=5, tail=3, margin=3, padding=2)
gremmie@1 33
gremmie@1 34 #######################################################################
gremmie@1 35
gremmie@1 36 @login_required
gremmie@1 37 def index(request):
gremmie@1 38 categories = Category.objects.all()
gremmie@1 39 total_dls = Download.public_objects.all().count()
gremmie@1 40 return render_to_response('downloads/index.html', {
gremmie@1 41 'categories': categories,
gremmie@1 42 'total_dls': total_dls,
gremmie@1 43 },
gremmie@1 44 context_instance = RequestContext(request))
gremmie@1 45
gremmie@1 46 #######################################################################
gremmie@1 47 # Maps URL component to database field name for the Download table:
gremmie@1 48
gremmie@1 49 DOWNLOAD_FIELD_MAP = {
gremmie@1 50 'title': 'title',
gremmie@1 51 'date': '-date_added',
gremmie@1 52 'rating': '-average_score',
gremmie@1 53 'hits': '-hits'
gremmie@1 54 }
gremmie@1 55
gremmie@1 56 @login_required
gremmie@1 57 def category(request, category, sort='title', page='1'):
gremmie@1 58 try:
gremmie@1 59 cat = Category.objects.get(pk=category)
gremmie@1 60 except Category.DoesNotExist:
gremmie@1 61 raise Http404
gremmie@1 62
gremmie@1 63 if sort not in DOWNLOAD_FIELD_MAP:
gremmie@1 64 sort = 'title'
gremmie@1 65 order_by = DOWNLOAD_FIELD_MAP[sort]
gremmie@1 66
bgneal@190 67 downloads = Download.public_objects.filter(category=cat.pk).order_by(
bgneal@190 68 order_by)
gremmie@1 69 paginator = create_paginator(downloads)
gremmie@1 70 try:
gremmie@1 71 the_page = paginator.page(int(page))
gremmie@1 72 except InvalidPage:
gremmie@1 73 raise Http404
gremmie@1 74
gremmie@1 75 return render_to_response('downloads/download_list.html', {
gremmie@1 76 's' : sort,
gremmie@1 77 'category' : cat,
gremmie@1 78 'page' : the_page,
gremmie@1 79 },
gremmie@1 80 context_instance = RequestContext(request))
gremmie@1 81
gremmie@1 82 #######################################################################
gremmie@1 83
gremmie@1 84 @login_required
gremmie@1 85 def new(request):
gremmie@1 86 downloads = Download.public_objects.order_by('-date_added')[:DLS_PER_PAGE]
gremmie@1 87 return render_to_response('downloads/download_summary.html', {
gremmie@1 88 'downloads' : downloads,
gremmie@1 89 'title' : 'Newest Downloads',
gremmie@1 90 },
gremmie@1 91 context_instance = RequestContext(request))
gremmie@1 92
gremmie@1 93 #######################################################################
gremmie@1 94
gremmie@1 95 @login_required
gremmie@1 96 def popular(request):
gremmie@1 97 downloads = Download.public_objects.order_by('-hits')[:DLS_PER_PAGE]
gremmie@1 98 return render_to_response('downloads/download_summary.html', {
gremmie@1 99 'downloads' : downloads,
gremmie@1 100 'title' : 'Popular Downloads',
gremmie@1 101 },
gremmie@1 102 context_instance = RequestContext(request))
gremmie@1 103
gremmie@1 104 #######################################################################
gremmie@1 105
gremmie@1 106 @login_required
gremmie@1 107 def rating(request):
gremmie@1 108 downloads = Download.public_objects.order_by('-average_score')[:DLS_PER_PAGE]
gremmie@1 109 return render_to_response('downloads/download_summary.html', {
gremmie@1 110 'downloads' : downloads,
gremmie@1 111 'title' : 'Highest Rated Downloads',
gremmie@1 112 },
gremmie@1 113 context_instance = RequestContext(request))
gremmie@1 114
gremmie@1 115 #######################################################################
gremmie@1 116
gremmie@1 117 @login_required
gremmie@1 118 def download(request, id):
gremmie@1 119 download = Download.public_objects.get(pk=id)
gremmie@1 120 if download is None:
gremmie@1 121 raise Http404
gremmie@1 122 return _redirect_download(download)
gremmie@1 123
gremmie@1 124 #######################################################################
gremmie@1 125
gremmie@1 126 def _redirect_download(download):
gremmie@1 127 download.hits += 1
gremmie@1 128 download.save()
gremmie@1 129 return HttpResponseRedirect(download.file.url)
gremmie@1 130
gremmie@1 131 #######################################################################
gremmie@1 132
gremmie@1 133 @login_required
bgneal@23 134 def details(request, id):
gremmie@1 135 download = Download.public_objects.get(pk=id)
gremmie@1 136 if download is None:
gremmie@1 137 raise Http404
bgneal@23 138 return render_to_response('downloads/download_detail.html', {
gremmie@1 139 'download' : download,
gremmie@1 140 },
gremmie@1 141 context_instance = RequestContext(request))
gremmie@1 142
gremmie@1 143 #######################################################################
gremmie@1 144
gremmie@1 145 @login_required
gremmie@1 146 def random_download(request):
gremmie@1 147 ids = Download.public_objects.values_list('id', flat=True)
gremmie@1 148 if not ids:
gremmie@1 149 raise Http404
gremmie@1 150 id = random.choice(ids)
gremmie@1 151 download = Download.objects.get(pk=id)
gremmie@1 152 return _redirect_download(download)
gremmie@1 153
gremmie@1 154 #######################################################################
gremmie@1 155
gremmie@1 156 @login_required
gremmie@1 157 def add(request):
gremmie@1 158 if request.method == 'POST':
gremmie@1 159 form = AddDownloadForm(request.POST, request.FILES)
gremmie@1 160 if form.is_valid():
gremmie@1 161 dl = form.save(commit=False)
gremmie@1 162 dl.user = request.user
gremmie@1 163 dl.ip_address = request.META.get('REMOTE_ADDR', None)
gremmie@1 164 dl.is_public = False
gremmie@1 165 dl.save()
gremmie@1 166 email_admins('New download for approval', """Hello,
gremmie@1 167
gremmie@1 168 A user has uploaded a new download for your approval.
gremmie@1 169 """)
gremmie@1 170 return HttpResponseRedirect(reverse('downloads-add_thanks'))
gremmie@1 171 else:
gremmie@1 172 form = AddDownloadForm()
gremmie@1 173
gremmie@1 174 return render_to_response('downloads/add.html', {
gremmie@1 175 'add_form': form,
gremmie@1 176 },
gremmie@1 177 context_instance=RequestContext(request))
gremmie@1 178
gremmie@1 179 #######################################################################
gremmie@1 180
gremmie@1 181 @login_required
gremmie@1 182 def thanks(request):
gremmie@1 183 return render_to_response('downloads/thanks.html', {
gremmie@1 184 },
gremmie@1 185 context_instance=RequestContext(request))
gremmie@1 186
gremmie@1 187 #######################################################################
gremmie@1 188
gremmie@1 189 @login_required
gremmie@1 190 def search(request, page=1):
gremmie@1 191 if request.method == 'POST':
gremmie@1 192 form = SearchForm(request.POST)
gremmie@1 193 if form.is_valid():
gremmie@1 194 query_text = form.query()
gremmie@1 195 page = 1
gremmie@1 196 else:
gremmie@1 197 return HttpResponseRedirect(reverse('downloads-index'))
gremmie@1 198 else:
gremmie@1 199 if 'query' in request.GET:
gremmie@1 200 query_text = request.GET['query']
gremmie@1 201 else:
gremmie@1 202 return HttpResponseRedirect(reverse('downloads-index'))
gremmie@1 203
gremmie@1 204 dls = Download.objects.filter(
gremmie@1 205 Q(title__icontains = query_text) |
bgneal@190 206 Q(description__icontains = query_text)).order_by(
bgneal@190 207 'title').select_related()
gremmie@1 208 paginator = create_paginator(dls)
gremmie@1 209 try:
gremmie@1 210 the_page = paginator.page(int(page))
gremmie@1 211 except EmptyPage:
gremmie@1 212 dls = Download.objects.none()
gremmie@1 213 except InvalidPage:
gremmie@1 214 raise Http404
gremmie@1 215
gremmie@1 216 return render_to_response('downloads/search_results.html', {
gremmie@1 217 'query': query_text,
gremmie@1 218 'page': the_page,
gremmie@1 219 },
gremmie@1 220 context_instance = RequestContext(request))
gremmie@1 221
gremmie@1 222 #######################################################################
gremmie@1 223
gremmie@1 224 @require_POST
gremmie@1 225 def rate_download(request):
gremmie@1 226 """This function is called by AJAX to rate a download."""
gremmie@1 227 if request.user.is_authenticated():
gremmie@1 228 id = request.POST.get('id', None)
gremmie@1 229 rating = request.POST.get('rating', None)
gremmie@1 230 if id is None or rating is None:
gremmie@1 231 return HttpResponseBadRequest('Missing id or rating.')
gremmie@1 232
gremmie@1 233 try:
gremmie@1 234 rating = int(rating)
gremmie@1 235 except ValueError:
gremmie@1 236 return HttpResponseBadRequest('Invalid rating.')
gremmie@1 237
gremmie@1 238 # rating will be from 0-4
gremmie@1 239 rating = min(5, max(1, rating))
gremmie@1 240
gremmie@1 241 try:
gremmie@1 242 download = Download.public_objects.get(pk=id)
gremmie@1 243 except Download.DoesNotExist:
gremmie@1 244 return HttpResponseBadRequest('Invalid download id.')
gremmie@1 245
gremmie@1 246 # prevent multiple votes from the same user
gremmie@1 247 vote_record, created = VoteRecord.objects.get_or_create(download=download, user=request.user)
gremmie@1 248 if created:
gremmie@1 249 new_score = download.vote(rating)
gremmie@1 250 download.save()
gremmie@1 251 return HttpResponse(str(new_score))
gremmie@1 252 else:
gremmie@1 253 return HttpResponse('-1')
gremmie@1 254
gremmie@1 255 return HttpResponseForbidden('You must be logged in to rate a download.')