comparison 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
comparison
equal deleted inserted replaced
580:c525f3e0b5d0 581:ee87ea74d46b
1 """
2 Views for the downloads application.
3 """
4 import random
5
6 from django.shortcuts import render_to_response, get_object_or_404
7 from django.template import RequestContext
8 from django.contrib.auth.decorators import login_required
9 from django.http import Http404
10 from django.http import HttpResponse
11 from django.http import HttpResponseRedirect
12 from django.http import HttpResponseForbidden
13 from django.http import HttpResponseBadRequest
14 from django.http import HttpResponseNotFound
15 from django.core.paginator import InvalidPage
16 from django.core.urlresolvers import reverse
17 from django.db.models import Q
18 from django.views.decorators.http import require_POST
19 import django.utils.simplejson as json
20
21 from core.paginator import DiggPaginator
22 from core.functions import email_admins
23 from core.functions import get_page
24 from downloads.models import Category
25 from downloads.models import Download
26 from downloads.models import VoteRecord
27 from downloads.forms import AddDownloadForm
28
29 #######################################################################
30
31 DLS_PER_PAGE = 10
32
33 def create_paginator(dls):
34 return DiggPaginator(dls, DLS_PER_PAGE, body=5, tail=3, margin=3, padding=2)
35
36 #######################################################################
37
38 @login_required
39 def index(request):
40 categories = Category.objects.all()
41 total_dls = Download.public_objects.all().count()
42 return render_to_response('downloads/index.html', {
43 'categories': categories,
44 'total_dls': total_dls,
45 },
46 context_instance = RequestContext(request))
47
48 #######################################################################
49 # Maps URL component to database field name for the Download table:
50
51 DOWNLOAD_FIELD_MAP = {
52 'title': 'title',
53 'date': '-date_added',
54 'rating': '-average_score',
55 'hits': '-hits'
56 }
57
58 @login_required
59 def category(request, slug, sort='title'):
60
61 cat = get_object_or_404(Category, slug=slug)
62
63 if sort not in DOWNLOAD_FIELD_MAP:
64 sort = 'title'
65 order_by = DOWNLOAD_FIELD_MAP[sort]
66
67 downloads = Download.public_objects.filter(category=cat.pk).order_by(
68 order_by)
69 paginator = create_paginator(downloads)
70 page = get_page(request.GET)
71 try:
72 the_page = paginator.page(page)
73 except InvalidPage:
74 raise Http404
75
76 return render_to_response('downloads/download_list.html', {
77 's' : sort,
78 'category' : cat,
79 'page' : the_page,
80 },
81 context_instance = RequestContext(request))
82
83 #######################################################################
84
85 @login_required
86 def new(request):
87 """Display new downloads with pagination."""
88
89 downloads = Download.public_objects.order_by('-date_added')
90
91 paginator = create_paginator(downloads)
92 page = get_page(request.GET)
93 try:
94 the_page = paginator.page(page)
95 except InvalidPage:
96 raise Http404
97
98 return render_to_response('downloads/download_summary.html', {
99 'page': the_page,
100 'title': 'Newest Downloads',
101 },
102 context_instance = RequestContext(request))
103
104 #######################################################################
105
106 @login_required
107 def popular(request):
108 """Display popular downloads with pagination."""
109
110 downloads = Download.public_objects.order_by('-hits')
111
112 paginator = create_paginator(downloads)
113 page = get_page(request.GET)
114 try:
115 the_page = paginator.page(page)
116 except InvalidPage:
117 raise Http404
118
119 return render_to_response('downloads/download_summary.html', {
120 'page': the_page,
121 'title': 'Popular Downloads',
122 },
123 context_instance = RequestContext(request))
124
125 #######################################################################
126
127 @login_required
128 def rating(request):
129 """Display downloads by rating with pagination."""
130
131 downloads = Download.public_objects.order_by('-average_score')
132 paginator = create_paginator(downloads)
133 page = get_page(request.GET)
134 try:
135 the_page = paginator.page(page)
136 except InvalidPage:
137 raise Http404
138
139 return render_to_response('downloads/download_summary.html', {
140 'page': the_page,
141 'title': 'Highest Rated Downloads',
142 },
143 context_instance = RequestContext(request))
144
145 #######################################################################
146
147 @login_required
148 def details(request, id):
149 download = get_object_or_404(Download.public_objects, pk=id)
150 return render_to_response('downloads/download_detail.html', {
151 'download' : download,
152 },
153 context_instance = RequestContext(request))
154
155 #######################################################################
156
157 @login_required
158 def add(request):
159 if request.method == 'POST':
160 form = AddDownloadForm(request.POST, request.FILES)
161 if form.is_valid():
162 dl = form.save(commit=False)
163 dl.user = request.user
164 dl.ip_address = request.META.get('REMOTE_ADDR', None)
165 dl.save()
166 email_admins('New download for approval', """Hello,
167
168 A user has uploaded a new download for your approval.
169 """)
170 return HttpResponseRedirect(reverse('downloads-add_thanks'))
171 else:
172 form = AddDownloadForm()
173
174 return render_to_response('downloads/add.html', {
175 'add_form': form,
176 },
177 context_instance=RequestContext(request))
178
179 #######################################################################
180
181 @login_required
182 def thanks(request):
183 return render_to_response('downloads/thanks.html', {
184 },
185 context_instance=RequestContext(request))
186
187 #######################################################################
188
189 @require_POST
190 def rate_download(request):
191 """This function is called by AJAX to rate a download."""
192 if request.user.is_authenticated():
193 id = request.POST.get('id', None)
194 rating = request.POST.get('rating', None)
195 if id is None or rating is None:
196 return HttpResponseBadRequest('Missing id or rating.')
197
198 try:
199 rating = int(rating)
200 except ValueError:
201 return HttpResponseBadRequest('Invalid rating.')
202
203 # rating will be from 0-4
204 rating = min(5, max(1, rating))
205
206 download = get_object_or_404(Download.public_objects, pk=id)
207
208 # prevent multiple votes from the same user
209 vote_record, created = VoteRecord.objects.get_or_create(
210 download=download, user=request.user)
211 if created:
212 new_score = download.vote(rating)
213 download.save()
214 return HttpResponse(str(new_score))
215 else:
216 return HttpResponse('-1')
217
218 return HttpResponseForbidden('You must be logged in to rate a download.')
219
220 #######################################################################
221
222 @require_POST
223 def request_download(request):
224 """
225 This function is called by AJAX to request a download. We update the hit
226 count and then return a JSON object of the form:
227 { id: download-id, 'url': link-to-download }
228
229 """
230 if request.user.is_authenticated():
231 dl_id = request.POST.get('id')
232 if dl_id:
233 try:
234 dl = Download.public_objects.get(pk=dl_id)
235 except Download.DoesNotExist:
236 return HttpResponseNotFound("Download not found")
237
238 dl.hits += 1
239 dl.save()
240
241 s = json.dumps({'id': dl_id, 'url': dl.file.url})
242 return HttpResponse(s, content_type='application/json')
243
244 return HttpResponseForbidden('An error occurred.')