bgneal@1
|
1 #######################################################################
|
bgneal@1
|
2 #
|
bgneal@28
|
3 # PyBand Copyright (C) 2008 - 2011 by Brian Neal
|
bgneal@1
|
4 #
|
bgneal@1
|
5 #######################################################################
|
bgneal@28
|
6 import collections
|
bgneal@28
|
7 import datetime
|
bgneal@28
|
8 import random
|
bgneal@28
|
9
|
bgneal@1
|
10 from django import forms
|
bgneal@1
|
11 from django.core.urlresolvers import reverse
|
bgneal@1
|
12 from django.http import HttpResponse
|
bgneal@1
|
13 from django.http import HttpResponseRedirect
|
bgneal@1
|
14 from django.shortcuts import render_to_response
|
bgneal@1
|
15 from django.shortcuts import get_object_or_404
|
bgneal@1
|
16 from django.template import RequestContext
|
bgneal@1
|
17 from django.template.loader import render_to_string
|
bgneal@1
|
18 from django.core.mail import send_mail
|
bgneal@28
|
19 from django.db import connection
|
bgneal@28
|
20
|
bgneal@1
|
21 from mysite.band.models import Article
|
bgneal@1
|
22 from mysite.band.models import Album
|
bgneal@28
|
23 from mysite.band.models import Band
|
bgneal@1
|
24 from mysite.band.models import Fan
|
bgneal@1
|
25 from mysite.band.models import Gear
|
bgneal@1
|
26 from mysite.band.models import Gig
|
bgneal@1
|
27 from mysite.band.models import Member
|
bgneal@1
|
28 from mysite.band.models import Merchandise
|
bgneal@1
|
29 from mysite.band.models import Mp3
|
bgneal@1
|
30 from mysite.band.models import Mp3_Set
|
bgneal@1
|
31 from mysite.band.models import News
|
bgneal@1
|
32 from mysite.band.models import SiteConfig
|
bgneal@1
|
33 from mysite.band.models import Video_Set
|
bgneal@1
|
34 from mysite.photologue.models import Gallery
|
bgneal@1
|
35 from mysite.photologue.models import Photo
|
bgneal@1
|
36
|
bgneal@1
|
37 #######################################################################
|
bgneal@1
|
38
|
bgneal@1
|
39 def index(request):
|
bgneal@1
|
40 config = SiteConfig.objects.get(pk = 1)
|
bgneal@1
|
41 carpe = Photo.objects.get(title_slug = 'carpe-noctem')
|
bgneal@1
|
42 sandstorm = Photo.objects.get(title_slug = 'sandstorm-cover')
|
bgneal@1
|
43 ruins = Photo.objects.get(title_slug = 'ruins-cover')
|
bgneal@1
|
44
|
bgneal@1
|
45 upcomingDates = Gig.objects.filter(date__gte = datetime.date.today).order_by('date')[:5]
|
bgneal@1
|
46
|
bgneal@1
|
47 return render_to_response('band/index.html',
|
bgneal@1
|
48 {
|
bgneal@1
|
49 'config' : config,
|
bgneal@1
|
50 'carpe' : carpe,
|
bgneal@1
|
51 'sandstorm' : sandstorm,
|
bgneal@1
|
52 'ruins' : ruins,
|
bgneal@1
|
53 'upcomingDates' : upcomingDates,
|
bgneal@1
|
54 # 'tourPhotos' : tourPhotos,
|
bgneal@1
|
55 },
|
bgneal@1
|
56 context_instance = RequestContext(request))
|
bgneal@1
|
57
|
bgneal@1
|
58 #######################################################################
|
bgneal@1
|
59
|
bgneal@1
|
60 def bio(request):
|
bgneal@1
|
61 members = Member.objects.exclude(is_active__exact = 0)
|
bgneal@1
|
62
|
bgneal@1
|
63 return render_to_response('band/bio.html',
|
bgneal@1
|
64 { 'members' : members, },
|
bgneal@1
|
65 context_instance = RequestContext(request))
|
bgneal@1
|
66
|
bgneal@1
|
67 #######################################################################
|
bgneal@1
|
68
|
bgneal@1
|
69 def gigs(request):
|
bgneal@28
|
70 today = datetime.date.today()
|
bgneal@28
|
71 gigs = Gig.objects.select_related('venue', 'flyer', 'venue__city',
|
bgneal@28
|
72 'venue__city__state', 'venue__city__country')
|
bgneal@28
|
73 upcoming = []
|
bgneal@28
|
74 previous = []
|
bgneal@28
|
75
|
bgneal@28
|
76 # To avoid many, many database hits in the template, we get all the
|
bgneal@28
|
77 # bands out at once. We also get the many-to-many intermediate table
|
bgneal@28
|
78 # that Django generated for us so we can associate bands to gigs.
|
bgneal@28
|
79 # Since we don't know about this table we drop into raw SQL to get
|
bgneal@28
|
80 # the contents.
|
bgneal@28
|
81
|
bgneal@28
|
82 bands = dict((band.id, band) for band in Band.objects.all())
|
bgneal@28
|
83 cursor = connection.cursor()
|
bgneal@28
|
84 cursor.execute('SELECT * FROM band_gig_bands')
|
bgneal@28
|
85 gig_bands = collections.defaultdict(list)
|
bgneal@28
|
86 for row in cursor.fetchall():
|
bgneal@28
|
87 gig_bands[row[1]].append(bands[row[2]])
|
bgneal@28
|
88
|
bgneal@28
|
89 for gig in gigs:
|
bgneal@28
|
90 gig.bands_ = gig_bands[gig.id]
|
bgneal@28
|
91 if gig.date >= today:
|
bgneal@28
|
92 upcoming.append(gig)
|
bgneal@28
|
93 else:
|
bgneal@28
|
94 previous.append(gig)
|
bgneal@28
|
95
|
bgneal@28
|
96 upcoming.reverse()
|
bgneal@1
|
97
|
bgneal@1
|
98 stats = {}
|
bgneal@28
|
99 venues = set()
|
bgneal@28
|
100 cities = set()
|
bgneal@28
|
101 states = set()
|
bgneal@28
|
102 countries = set()
|
bgneal@1
|
103 for gig in previous:
|
bgneal@28
|
104 venues.add(gig.venue.id)
|
bgneal@28
|
105 cities.add(gig.venue.city.id)
|
bgneal@28
|
106 if gig.venue.city.state:
|
bgneal@1
|
107 states.add(gig.venue.city.state.id)
|
bgneal@28
|
108 if gig.venue.city.country:
|
bgneal@28
|
109 countries.add(gig.venue.city.country.id)
|
bgneal@1
|
110
|
bgneal@28
|
111 stats['count'] = len(previous)
|
bgneal@1
|
112 stats['venues'] = len(venues)
|
bgneal@1
|
113 stats['cities'] = len(cities)
|
bgneal@1
|
114 stats['states'] = len(states)
|
bgneal@5
|
115 stats['countries'] = len(countries)
|
bgneal@1
|
116 stats['bands'] = len(bands)
|
bgneal@1
|
117
|
bgneal@28
|
118 flyerGigs = Gig.objects.exclude(flyer__isnull = True).select_related(
|
bgneal@28
|
119 'venue', 'flyer').order_by('-date')
|
bgneal@1
|
120
|
bgneal@28
|
121 return render_to_response('band/gigs.html', {
|
bgneal@28
|
122 'upcoming' : upcoming,
|
bgneal@28
|
123 'previous' : previous,
|
bgneal@28
|
124 'stats' : stats,
|
bgneal@28
|
125 'flyerGigs' : flyerGigs,
|
bgneal@28
|
126 },
|
bgneal@28
|
127 context_instance = RequestContext(request))
|
bgneal@1
|
128
|
bgneal@1
|
129 #######################################################################
|
bgneal@1
|
130
|
bgneal@1
|
131 def news(request):
|
bgneal@1
|
132 news = News.objects.order_by('-date')
|
bgneal@1
|
133
|
bgneal@1
|
134 return render_to_response('band/news.html',
|
bgneal@1
|
135 {
|
bgneal@1
|
136 'news' : news
|
bgneal@1
|
137 },
|
bgneal@1
|
138 context_instance = RequestContext(request))
|
bgneal@1
|
139
|
bgneal@1
|
140 #######################################################################
|
bgneal@1
|
141
|
bgneal@1
|
142 def press_index(request):
|
bgneal@1
|
143 articles = Article.objects.order_by('-date')
|
bgneal@1
|
144
|
bgneal@1
|
145 return render_to_response('band/press.html',
|
bgneal@1
|
146 {
|
bgneal@1
|
147 'articles' : articles
|
bgneal@1
|
148 },
|
bgneal@1
|
149 context_instance = RequestContext(request))
|
bgneal@1
|
150
|
bgneal@1
|
151 #######################################################################
|
bgneal@1
|
152
|
bgneal@1
|
153 def press_detail(request, id):
|
bgneal@1
|
154 article = get_object_or_404(Article, pk = id)
|
bgneal@1
|
155
|
bgneal@1
|
156 return render_to_response('band/press_detail.html',
|
bgneal@1
|
157 { 'article' : article },
|
bgneal@1
|
158 context_instance = RequestContext(request))
|
bgneal@1
|
159
|
bgneal@1
|
160 #######################################################################
|
bgneal@1
|
161
|
bgneal@1
|
162 def songs(request):
|
bgneal@1
|
163 mp3Sets = Mp3_Set.objects.order_by('-date', '-id')
|
bgneal@1
|
164
|
bgneal@1
|
165 return render_to_response('band/songs.html',
|
bgneal@1
|
166 { 'mp3Sets' : mp3Sets },
|
bgneal@1
|
167 context_instance = RequestContext(request))
|
bgneal@1
|
168
|
bgneal@1
|
169 #######################################################################
|
bgneal@1
|
170
|
bgneal@1
|
171 def photos_index(request):
|
bgneal@1
|
172 galleries = Gallery.objects.values('title', 'id').order_by('-id')
|
bgneal@1
|
173
|
bgneal@1
|
174 photos = Photo.objects.filter(is_public__exact = 1)
|
bgneal@1
|
175 randomPhotos = random.sample(photos, 4)
|
bgneal@1
|
176
|
bgneal@1
|
177 return render_to_response('band/photos.html',
|
bgneal@1
|
178 { 'galleries' : galleries, 'randomPhotos' : randomPhotos },
|
bgneal@1
|
179 context_instance = RequestContext(request))
|
bgneal@1
|
180
|
bgneal@1
|
181 #######################################################################
|
bgneal@1
|
182
|
bgneal@1
|
183 def photo_detail(request, id):
|
bgneal@1
|
184 gallery = get_object_or_404(Gallery, pk = id)
|
bgneal@1
|
185 return render_to_response('band/photo_detail.html',
|
bgneal@1
|
186 { 'gallery' : gallery },
|
bgneal@1
|
187 context_instance = RequestContext(request))
|
bgneal@1
|
188
|
bgneal@1
|
189 #######################################################################
|
bgneal@1
|
190
|
bgneal@1
|
191 def videos_index(request):
|
bgneal@9
|
192 vidsets = Video_Set.objects.values('title', 'id').order_by('-date')
|
bgneal@1
|
193 return render_to_response('band/videos.html',
|
bgneal@1
|
194 { 'vidsets' : vidsets },
|
bgneal@1
|
195 context_instance = RequestContext(request))
|
bgneal@1
|
196
|
bgneal@1
|
197 #######################################################################
|
bgneal@1
|
198
|
bgneal@1
|
199 def video_detail(request, id):
|
bgneal@1
|
200 vidset = get_object_or_404(Video_Set, pk = id)
|
bgneal@1
|
201
|
bgneal@1
|
202 return render_to_response('band/video_detail.html',
|
bgneal@1
|
203 { 'vidset' : vidset },
|
bgneal@1
|
204 context_instance = RequestContext(request))
|
bgneal@1
|
205
|
bgneal@1
|
206 #######################################################################
|
bgneal@1
|
207
|
bgneal@1
|
208 def buy(request):
|
bgneal@1
|
209 albums = Album.objects.all().order_by('-id')
|
bgneal@1
|
210 merchandise = Merchandise.objects.all().order_by('-id')
|
bgneal@1
|
211 config = SiteConfig.objects.values('ordering_info').get(pk = 1)
|
bgneal@1
|
212 return render_to_response('band/buy.html',
|
bgneal@1
|
213 { 'albums' : albums, 'merchandise' : merchandise, 'config' : config },
|
bgneal@1
|
214 context_instance = RequestContext(request))
|
bgneal@1
|
215
|
bgneal@1
|
216 #######################################################################
|
bgneal@1
|
217
|
bgneal@1
|
218 def confirmEmail(config, to, subscribe, key):
|
bgneal@1
|
219 band = config.band_name
|
bgneal@1
|
220 fromEmail = config.contact_email
|
bgneal@1
|
221 url = config.url
|
bgneal@1
|
222 if url[-1] != '/':
|
bgneal@1
|
223 url += '/'
|
bgneal@1
|
224 url += 'mail/confirm/' + key
|
bgneal@1
|
225
|
bgneal@1
|
226 if subscribe:
|
bgneal@1
|
227 emailTemplate = 'band/email_subscribe.txt'
|
bgneal@1
|
228 else:
|
bgneal@1
|
229 emailTemplate = 'band/email_unsubscribe.txt'
|
bgneal@1
|
230
|
bgneal@1
|
231 msg = render_to_string(emailTemplate, { 'band' : band, 'url' : url, 'band_url' : config.url })
|
bgneal@1
|
232
|
bgneal@1
|
233 subject = '[' + band + '] Mailing List Confirmation'
|
bgneal@1
|
234
|
bgneal@1
|
235 send_mail(subject, msg, fromEmail, [to])
|
bgneal@1
|
236
|
bgneal@1
|
237 #######################################################################
|
bgneal@1
|
238
|
bgneal@1
|
239 def contact(request):
|
bgneal@1
|
240 config = SiteConfig.objects.get(pk = 1)
|
bgneal@1
|
241 band = Member.objects.exclude(is_active__exact = 0).order_by('order')
|
bgneal@1
|
242 return render_to_response('band/contact.html',
|
bgneal@1
|
243 { 'config' : config, 'band' : band },
|
bgneal@1
|
244 context_instance = RequestContext(request))
|
bgneal@1
|
245
|
bgneal@1
|
246 #######################################################################
|
bgneal@1
|
247
|
bgneal@1
|
248 class ContactForm(forms.Form):
|
bgneal@1
|
249 name = forms.CharField(max_length = 32, required = False,
|
bgneal@1
|
250 widget = forms.TextInput(attrs = {'class' : 'form-box'}))
|
bgneal@1
|
251 email = forms.EmailField(widget = forms.TextInput(attrs = {'class' : 'form-box'}))
|
bgneal@1
|
252 location = forms.CharField(max_length = 32, required = False,
|
bgneal@1
|
253 widget = forms.TextInput(attrs = {'class' : 'form-box'}))
|
bgneal@1
|
254 option = forms.ChoiceField(choices = (('subscribe', 'Subscribe'), ('unsubscribe', 'Unsubscribe')),
|
bgneal@1
|
255 widget = forms.Select(attrs = {'class' : 'form-box'}))
|
bgneal@1
|
256
|
bgneal@1
|
257 def mail(request):
|
bgneal@1
|
258 config = SiteConfig.objects.get(pk = 1)
|
bgneal@1
|
259 form = ContactForm()
|
bgneal@1
|
260 if request.method == 'POST':
|
bgneal@1
|
261 form = ContactForm(request.POST)
|
bgneal@1
|
262 if form.is_valid():
|
bgneal@1
|
263 if form.cleaned_data['option'] == 'unsubscribe':
|
bgneal@1
|
264 try:
|
bgneal@1
|
265 fan = Fan.objects.get(email = form.cleaned_data['email'])
|
bgneal@1
|
266 except Fan.DoesNotExist:
|
bgneal@1
|
267 return HttpResponseRedirect(reverse(mail_not_found))
|
bgneal@1
|
268
|
bgneal@1
|
269 fan.setLeaving()
|
bgneal@1
|
270 fan.save()
|
bgneal@1
|
271 confirmEmail(config, fan.email, False, fan.key)
|
bgneal@1
|
272 return HttpResponseRedirect(reverse(mail_unsubscribe))
|
bgneal@1
|
273
|
bgneal@1
|
274 elif form.cleaned_data['option'] == 'subscribe':
|
bgneal@1
|
275 try:
|
bgneal@1
|
276 fan = Fan.objects.get(email = form.cleaned_data['email'])
|
bgneal@1
|
277 except Fan.DoesNotExist:
|
bgneal@1
|
278 fan = Fan(name = form.cleaned_data['name'],
|
bgneal@1
|
279 email = form.cleaned_data['email'],
|
bgneal@1
|
280 location = form.cleaned_data['location'])
|
bgneal@1
|
281
|
bgneal@1
|
282 fan.setPending()
|
bgneal@1
|
283 fan.save()
|
bgneal@1
|
284 confirmEmail(config, fan.email, True, fan.key)
|
bgneal@1
|
285 return HttpResponseRedirect(reverse(mail_thanks))
|
bgneal@1
|
286
|
bgneal@1
|
287 return render_to_response('band/mail.html',
|
bgneal@1
|
288 { 'form' : form },
|
bgneal@1
|
289 context_instance = RequestContext(request))
|
bgneal@1
|
290
|
bgneal@1
|
291 #######################################################################
|
bgneal@1
|
292
|
bgneal@1
|
293 def mail_not_found(request):
|
bgneal@1
|
294 return render_to_response('band/mail_not_found.html',
|
bgneal@1
|
295 {},
|
bgneal@1
|
296 context_instance = RequestContext(request))
|
bgneal@1
|
297
|
bgneal@1
|
298 #######################################################################
|
bgneal@1
|
299
|
bgneal@1
|
300 def mail_thanks(request):
|
bgneal@1
|
301 return render_to_response('band/mail_thanks.html',
|
bgneal@1
|
302 {},
|
bgneal@1
|
303 context_instance = RequestContext(request))
|
bgneal@1
|
304
|
bgneal@1
|
305 #######################################################################
|
bgneal@1
|
306
|
bgneal@1
|
307 def mail_unsubscribe(request):
|
bgneal@1
|
308 return render_to_response('band/mail_unsubscribe.html',
|
bgneal@1
|
309 {},
|
bgneal@1
|
310 context_instance = RequestContext(request))
|
bgneal@1
|
311
|
bgneal@1
|
312 #######################################################################
|
bgneal@1
|
313
|
bgneal@1
|
314 def mail_confirm(request, key):
|
bgneal@1
|
315 fan = get_object_or_404(Fan, key = key)
|
bgneal@1
|
316
|
bgneal@1
|
317 email = fan.email
|
bgneal@1
|
318 action = 'subscribed'
|
bgneal@1
|
319
|
bgneal@1
|
320 if fan.isPending():
|
bgneal@1
|
321 fan.setActive()
|
bgneal@1
|
322 fan.save()
|
bgneal@1
|
323 elif fan.isLeaving():
|
bgneal@1
|
324 fan.delete()
|
bgneal@1
|
325 action = 'unsubscribed'
|
bgneal@1
|
326
|
bgneal@1
|
327 return render_to_response('band/mail_confirm.html',
|
bgneal@1
|
328 { 'email' : email, 'action' : action },
|
bgneal@1
|
329 context_instance = RequestContext(request))
|
bgneal@1
|
330
|
bgneal@1
|
331 #######################################################################
|
bgneal@1
|
332
|
bgneal@1
|
333 def flyers(request):
|
bgneal@1
|
334
|
bgneal@1
|
335 gigs = Gig.objects.exclude(flyer__isnull = True).order_by('-date')
|
bgneal@1
|
336
|
bgneal@1
|
337 return render_to_response('band/flyers.html',
|
bgneal@1
|
338 { 'gigs' : gigs },
|
bgneal@1
|
339 context_instance = RequestContext(request))
|