comparison gpp/downloads/views.py @ 1:dbd703f7d63a

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