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