bgneal@1: ####################################################################### bgneal@1: # bgneal@28: # PyBand Copyright (C) 2008 - 2011 by Brian Neal bgneal@1: # bgneal@1: ####################################################################### bgneal@28: import collections bgneal@28: import datetime bgneal@28: import random bgneal@28: bgneal@1: from django import forms bgneal@1: from django.core.urlresolvers import reverse bgneal@1: from django.http import HttpResponse bgneal@1: from django.http import HttpResponseRedirect bgneal@1: from django.shortcuts import render_to_response bgneal@1: from django.shortcuts import get_object_or_404 bgneal@1: from django.template import RequestContext bgneal@1: from django.template.loader import render_to_string bgneal@1: from django.core.mail import send_mail bgneal@28: from django.db import connection bgneal@28: bgneal@40: from band.models import Article bgneal@40: from band.models import Album bgneal@40: from band.models import Band bgneal@40: from band.models import Fan bgneal@40: from band.models import Gear bgneal@40: from band.models import Gig bgneal@40: from band.models import Member bgneal@40: from band.models import Merchandise bgneal@40: from band.models import Mp3 bgneal@40: from band.models import Mp3_Set bgneal@40: from band.models import News bgneal@40: from band.models import SiteConfig bgneal@40: from band.models import Video_Set bgneal@40: from photologue.models import Gallery bgneal@40: from photologue.models import Photo bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def index(request): bgneal@1: config = SiteConfig.objects.get(pk = 1) bgneal@1: carpe = Photo.objects.get(title_slug = 'carpe-noctem') bgneal@1: sandstorm = Photo.objects.get(title_slug = 'sandstorm-cover') bgneal@1: ruins = Photo.objects.get(title_slug = 'ruins-cover') bgneal@1: bgneal@1: upcomingDates = Gig.objects.filter(date__gte = datetime.date.today).order_by('date')[:5] bgneal@1: bgneal@1: return render_to_response('band/index.html', bgneal@1: { bgneal@1: 'config' : config, bgneal@1: 'carpe' : carpe, bgneal@1: 'sandstorm' : sandstorm, bgneal@1: 'ruins' : ruins, bgneal@1: 'upcomingDates' : upcomingDates, bgneal@1: # 'tourPhotos' : tourPhotos, bgneal@1: }, bgneal@1: context_instance = RequestContext(request)) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def bio(request): bgneal@1: members = Member.objects.exclude(is_active__exact = 0) bgneal@1: bgneal@1: return render_to_response('band/bio.html', bgneal@1: { 'members' : members, }, bgneal@1: context_instance = RequestContext(request)) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def gigs(request): bgneal@28: today = datetime.date.today() bgneal@28: gigs = Gig.objects.select_related('venue', 'flyer', 'venue__city', bgneal@28: 'venue__city__state', 'venue__city__country') bgneal@28: upcoming = [] bgneal@28: previous = [] bgneal@28: bgneal@28: # To avoid many, many database hits in the template, we get all the bgneal@28: # bands out at once. We also get the many-to-many intermediate table bgneal@28: # that Django generated for us so we can associate bands to gigs. bgneal@28: # Since we don't know about this table we drop into raw SQL to get bgneal@28: # the contents. bgneal@28: bgneal@28: bands = dict((band.id, band) for band in Band.objects.all()) bgneal@28: cursor = connection.cursor() bgneal@28: cursor.execute('SELECT * FROM band_gig_bands') bgneal@28: gig_bands = collections.defaultdict(list) bgneal@28: for row in cursor.fetchall(): bgneal@28: gig_bands[row[1]].append(bands[row[2]]) bgneal@28: bgneal@28: for gig in gigs: bgneal@28: gig.bands_ = gig_bands[gig.id] bgneal@28: if gig.date >= today: bgneal@28: upcoming.append(gig) bgneal@28: else: bgneal@28: previous.append(gig) bgneal@28: bgneal@28: upcoming.reverse() bgneal@1: bgneal@1: stats = {} bgneal@28: venues = set() bgneal@28: cities = set() bgneal@28: states = set() bgneal@28: countries = set() bgneal@1: for gig in previous: bgneal@28: venues.add(gig.venue.id) bgneal@28: cities.add(gig.venue.city.id) bgneal@28: if gig.venue.city.state: bgneal@1: states.add(gig.venue.city.state.id) bgneal@28: if gig.venue.city.country: bgneal@28: countries.add(gig.venue.city.country.id) bgneal@1: bgneal@28: stats['count'] = len(previous) bgneal@1: stats['venues'] = len(venues) bgneal@1: stats['cities'] = len(cities) bgneal@1: stats['states'] = len(states) bgneal@5: stats['countries'] = len(countries) bgneal@1: stats['bands'] = len(bands) bgneal@1: bgneal@28: flyerGigs = Gig.objects.exclude(flyer__isnull = True).select_related( bgneal@28: 'venue', 'flyer').order_by('-date') bgneal@1: bgneal@28: return render_to_response('band/gigs.html', { bgneal@28: 'upcoming' : upcoming, bgneal@28: 'previous' : previous, bgneal@28: 'stats' : stats, bgneal@28: 'flyerGigs' : flyerGigs, bgneal@28: }, bgneal@28: context_instance = RequestContext(request)) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def news(request): bgneal@1: news = News.objects.order_by('-date') bgneal@1: bgneal@1: return render_to_response('band/news.html', bgneal@1: { bgneal@1: 'news' : news bgneal@1: }, bgneal@1: context_instance = RequestContext(request)) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def press_index(request): bgneal@1: articles = Article.objects.order_by('-date') bgneal@1: bgneal@1: return render_to_response('band/press.html', bgneal@1: { bgneal@1: 'articles' : articles bgneal@1: }, bgneal@1: context_instance = RequestContext(request)) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def press_detail(request, id): bgneal@1: article = get_object_or_404(Article, pk = id) bgneal@1: bgneal@1: return render_to_response('band/press_detail.html', bgneal@1: { 'article' : article }, bgneal@1: context_instance = RequestContext(request)) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def songs(request): bgneal@1: mp3Sets = Mp3_Set.objects.order_by('-date', '-id') bgneal@1: bgneal@1: return render_to_response('band/songs.html', bgneal@1: { 'mp3Sets' : mp3Sets }, bgneal@1: context_instance = RequestContext(request)) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def photos_index(request): bgneal@1: galleries = Gallery.objects.values('title', 'id').order_by('-id') bgneal@1: bgneal@1: photos = Photo.objects.filter(is_public__exact = 1) bgneal@1: randomPhotos = random.sample(photos, 4) bgneal@1: bgneal@1: return render_to_response('band/photos.html', bgneal@1: { 'galleries' : galleries, 'randomPhotos' : randomPhotos }, bgneal@1: context_instance = RequestContext(request)) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def photo_detail(request, id): bgneal@1: gallery = get_object_or_404(Gallery, pk = id) bgneal@29: photos = gallery.photos.order_by('id') bgneal@1: return render_to_response('band/photo_detail.html', bgneal@29: {'gallery' : gallery, 'photos': photos }, bgneal@29: context_instance = RequestContext(request)) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def videos_index(request): bgneal@9: vidsets = Video_Set.objects.values('title', 'id').order_by('-date') bgneal@1: return render_to_response('band/videos.html', bgneal@1: { 'vidsets' : vidsets }, bgneal@1: context_instance = RequestContext(request)) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def video_detail(request, id): bgneal@1: vidset = get_object_or_404(Video_Set, pk = id) bgneal@1: bgneal@1: return render_to_response('band/video_detail.html', bgneal@1: { 'vidset' : vidset }, bgneal@1: context_instance = RequestContext(request)) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def buy(request): bgneal@1: albums = Album.objects.all().order_by('-id') bgneal@1: merchandise = Merchandise.objects.all().order_by('-id') bgneal@1: config = SiteConfig.objects.values('ordering_info').get(pk = 1) bgneal@1: return render_to_response('band/buy.html', bgneal@1: { 'albums' : albums, 'merchandise' : merchandise, 'config' : config }, bgneal@1: context_instance = RequestContext(request)) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def confirmEmail(config, to, subscribe, key): bgneal@1: band = config.band_name bgneal@1: fromEmail = config.contact_email bgneal@1: url = config.url bgneal@1: if url[-1] != '/': bgneal@1: url += '/' bgneal@1: url += 'mail/confirm/' + key bgneal@1: bgneal@1: if subscribe: bgneal@1: emailTemplate = 'band/email_subscribe.txt' bgneal@1: else: bgneal@1: emailTemplate = 'band/email_unsubscribe.txt' bgneal@1: bgneal@1: msg = render_to_string(emailTemplate, { 'band' : band, 'url' : url, 'band_url' : config.url }) bgneal@1: bgneal@1: subject = '[' + band + '] Mailing List Confirmation' bgneal@1: bgneal@1: send_mail(subject, msg, fromEmail, [to]) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def contact(request): bgneal@1: config = SiteConfig.objects.get(pk = 1) bgneal@1: band = Member.objects.exclude(is_active__exact = 0).order_by('order') bgneal@1: return render_to_response('band/contact.html', bgneal@1: { 'config' : config, 'band' : band }, bgneal@1: context_instance = RequestContext(request)) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: class ContactForm(forms.Form): bgneal@1: name = forms.CharField(max_length = 32, required = False, bgneal@1: widget = forms.TextInput(attrs = {'class' : 'form-box'})) bgneal@1: email = forms.EmailField(widget = forms.TextInput(attrs = {'class' : 'form-box'})) bgneal@1: location = forms.CharField(max_length = 32, required = False, bgneal@1: widget = forms.TextInput(attrs = {'class' : 'form-box'})) bgneal@1: option = forms.ChoiceField(choices = (('subscribe', 'Subscribe'), ('unsubscribe', 'Unsubscribe')), bgneal@1: widget = forms.Select(attrs = {'class' : 'form-box'})) bgneal@1: bgneal@1: def mail(request): bgneal@1: config = SiteConfig.objects.get(pk = 1) bgneal@1: form = ContactForm() bgneal@1: if request.method == 'POST': bgneal@1: form = ContactForm(request.POST) bgneal@1: if form.is_valid(): bgneal@1: if form.cleaned_data['option'] == 'unsubscribe': bgneal@1: try: bgneal@1: fan = Fan.objects.get(email = form.cleaned_data['email']) bgneal@1: except Fan.DoesNotExist: bgneal@1: return HttpResponseRedirect(reverse(mail_not_found)) bgneal@1: bgneal@1: fan.setLeaving() bgneal@1: fan.save() bgneal@1: confirmEmail(config, fan.email, False, fan.key) bgneal@1: return HttpResponseRedirect(reverse(mail_unsubscribe)) bgneal@1: bgneal@1: elif form.cleaned_data['option'] == 'subscribe': bgneal@1: try: bgneal@1: fan = Fan.objects.get(email = form.cleaned_data['email']) bgneal@1: except Fan.DoesNotExist: bgneal@1: fan = Fan(name = form.cleaned_data['name'], bgneal@1: email = form.cleaned_data['email'], bgneal@1: location = form.cleaned_data['location']) bgneal@1: bgneal@1: fan.setPending() bgneal@1: fan.save() bgneal@1: confirmEmail(config, fan.email, True, fan.key) bgneal@1: return HttpResponseRedirect(reverse(mail_thanks)) bgneal@1: bgneal@1: return render_to_response('band/mail.html', bgneal@1: { 'form' : form }, bgneal@1: context_instance = RequestContext(request)) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def mail_not_found(request): bgneal@1: return render_to_response('band/mail_not_found.html', bgneal@1: {}, bgneal@1: context_instance = RequestContext(request)) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def mail_thanks(request): bgneal@1: return render_to_response('band/mail_thanks.html', bgneal@1: {}, bgneal@1: context_instance = RequestContext(request)) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def mail_unsubscribe(request): bgneal@1: return render_to_response('band/mail_unsubscribe.html', bgneal@1: {}, bgneal@1: context_instance = RequestContext(request)) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def mail_confirm(request, key): bgneal@1: fan = get_object_or_404(Fan, key = key) bgneal@1: bgneal@1: email = fan.email bgneal@1: action = 'subscribed' bgneal@1: bgneal@1: if fan.isPending(): bgneal@1: fan.setActive() bgneal@1: fan.save() bgneal@1: elif fan.isLeaving(): bgneal@1: fan.delete() bgneal@1: action = 'unsubscribed' bgneal@1: bgneal@1: return render_to_response('band/mail_confirm.html', bgneal@1: { 'email' : email, 'action' : action }, bgneal@1: context_instance = RequestContext(request)) bgneal@1: bgneal@1: ####################################################################### bgneal@1: bgneal@1: def flyers(request): bgneal@1: bgneal@1: gigs = Gig.objects.exclude(flyer__isnull = True).order_by('-date') bgneal@1: bgneal@1: return render_to_response('band/flyers.html', bgneal@1: { 'gigs' : gigs }, bgneal@1: context_instance = RequestContext(request))