add speakers app from pycon

This commit is contained in:
Luke Hatcher 2012-07-12 00:38:24 -04:00
parent 76c4a7b79c
commit 2b7f5546a0
10 changed files with 307 additions and 0 deletions

View file

View file

@ -0,0 +1,9 @@
from django.contrib import admin
from symposion.speakers.models import Speaker
admin.site.register(Speaker,
list_display = ["name", "email", "twitter_username", "sessions_preference", "created"],
search_fields = ["name"],
)

View file

@ -0,0 +1,31 @@
from django.contrib.auth.models import User
from fixture_generator import fixture_generator
from symposion.speakers.models import Speaker
@fixture_generator(Speaker, User)
def speakers():
guido = User.objects.create_user("guido", "guido@python.org", "pythonisawesome")
matz = User.objects.create_user("matz", "matz@ruby.org", "pythonsucks")
larry = User.objects.create_user("larryw", "larry@perl.org", "linenoisehere")
Speaker.objects.create(
user=guido,
name="Guido van Rossum",
biography="I wrote Python, and named it after Monty Python",
twitter_username="gvanrossum",
)
Speaker.objects.create(
user=matz,
name="Yukihiro Matsumoto",
biography="I wrote Ruby, and named it after the rare gem Ruby, a pun "
"on Perl/pearl.",
twitter_username="yukihiro_matz"
)
Speaker.objects.create(
user=larry,
name="Larry Wall",
biography="I wrote Perl, and named it after the Parable of the Pearl",
)

View file

@ -0,0 +1,63 @@
from django import forms
from django.contrib import messages
from markitup.widgets import MarkItUpWidget
from symposion.speakers.models import Speaker
class SpeakerForm(forms.ModelForm):
sessions_preference = forms.ChoiceField(
widget=forms.RadioSelect(),
choices=Speaker.SESSION_COUNT_CHOICES,
required=False,
help_text="If you've submitted multiple proposals, please let us know if you only want to give one or if you'd like to give two talks."
)
class Meta:
model = Speaker
fields = [
"name",
"biography",
"photo",
"twitter_username",
"sessions_preference"
]
widgets = {
"biography": MarkItUpWidget(),
}
def clean_twitter_username(self):
value = self.cleaned_data["twitter_username"]
if value.startswith("@"):
value = value[1:]
return value
def clean_sessions_preference(self):
value = self.cleaned_data["sessions_preference"]
if not value:
return None
return int(value)
# class SignupForm(PinaxSignupForm):
# def save(self, speaker, request=None):
# # don't assume a username is available. it is a common removal if
# # site developer wants to use email authentication.
# username = self.cleaned_data.get("username")
# email = self.cleaned_data["email"]
# new_user = self.create_user(username)
# if speaker.invite_email == new_user.email:
# # already verified so can just create
# EmailAddress(user=new_user, email=email, verified=True, primary=True).save()
# else:
# if request:
# messages.info(request, u"Confirmation email sent to %(email)s" % {"email": email})
# EmailAddress.objects.add_email(new_user, email)
# new_user.is_active = False
# new_user.save()
# self.after_signup(new_user)
# return new_user

View file

@ -0,0 +1,19 @@
import csv
import os
from django.core.management.base import BaseCommand, CommandError
from symposion.speakers.models import Speaker
class Command(BaseCommand):
def handle(self, *args, **options):
csv_file = csv.writer(open(os.path.join(os.getcwd(), "speakers.csv"), "wb"))
csv_file.writerow(["Name", "Bio"])
for speaker in Speaker.objects.all():
csv_file.writerow([
speaker.name.encode("utf-8"),
speaker.biography.encode("utf-8"),
])

View file

@ -0,0 +1,55 @@
import datetime
from django.db import models
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from markitup.fields import MarkupField
class Speaker(models.Model):
SESSION_COUNT_CHOICES = [
(1, "One"),
(2, "Two")
]
user = models.OneToOneField(User, null=True, related_name="speaker_profile")
name = models.CharField(max_length=100, help_text="As you would like it to appear in the conference program.")
biography = MarkupField(help_text="A little bit about you. Edit using <a href='http://warpedvisions.org/projects/markdown-cheat-sheet/' target='_blank'>Markdown</a>.")
photo = models.ImageField(upload_to="speaker_photos", blank=True)
twitter_username = models.CharField(
max_length = 15,
blank = True,
help_text = "Your Twitter account"
)
annotation = models.TextField() # staff only
invite_email = models.CharField(max_length=200, unique=True, null=True, db_index=True)
invite_token = models.CharField(max_length=40, db_index=True)
created = models.DateTimeField(
default = datetime.datetime.now,
editable = False
)
sessions_preference = models.IntegerField(
choices=SESSION_COUNT_CHOICES,
null=True,
blank=True,
help_text="If you've submitted multiple proposals, please let us know if you only want to give one or if you'd like to give two talks. You may submit more than two proposals."
)
def __unicode__(self):
if self.user:
return self.name
else:
return "?"
def get_absolute_url(self):
return reverse("speaker_edit")
@property
def email(self):
if self.user is not None:
return self.user.email
else:
return self.invite_email

View file

@ -0,0 +1,9 @@
from django.conf.urls.defaults import *
urlpatterns = patterns("symposion.speakers.views",
url(r"^create/$", "speaker_create", name="speaker_create"),
url(r"^create/(\w+)/$", "speaker_create_token", name="speaker_create_token"),
url(r"^edit/(?:(?P<pk>\d+)/)?$", "speaker_edit", name="speaker_edit"),
url(r"^profile/(?P<pk>\d+)/$", "speaker_profile", name="speaker_profile"),
)

121
symposion/speakers/views.py Normal file
View file

@ -0,0 +1,121 @@
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q
from django.http import Http404, HttpResponse
from django.shortcuts import render, redirect, get_object_or_404
from django.template import RequestContext
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from symposion.proposals.models import ProposalBase
from symposion.speakers.forms import SpeakerForm #, SignupForm
from symposion.speakers.models import Speaker
@login_required
def speaker_create(request):
try:
return redirect(request.user.speaker_profile)
except ObjectDoesNotExist:
pass
if request.method == "POST":
try:
speaker = Speaker.objects.get(invite_email=request.user.email)
found = True
except Speaker.DoesNotExist:
speaker = None
found = False
form = SpeakerForm(request.POST, request.FILES, instance=speaker)
if form.is_valid():
speaker = form.save(commit=False)
speaker.user = request.user
if not found:
speaker.invite_email = None
speaker.save()
messages.success(request, "Speaker profile created.")
return redirect("dashboard")
else:
form = SpeakerForm(initial = {"name": request.user.get_full_name()})
return render(request, "speakers/speaker_create.html", {
"form": form,
})
def speaker_create_token(request, token):
speaker = get_object_or_404(Speaker, invite_token=token)
request.session["pending-token"] = token
if request.user.is_authenticated():
# check for speaker profile
try:
existing_speaker = request.user.speaker_profile
except ObjectDoesNotExist:
pass
else:
del request.session["pending-token"]
additional_speakers = ProposalBase.additional_speakers.through
additional_speakers._default_manager.filter(
speaker = speaker
).update(
speaker = existing_speaker
)
messages.info(request, "You have been associated with all pending "
"talk proposals")
return redirect("dashboard")
else:
if not request.user.is_authenticated():
return redirect("account_login")
return redirect("speaker_create")
@login_required
def speaker_edit(request, pk=None):
if pk is None:
try:
speaker = request.user.speaker_profile
except Speaker.DoesNotExist:
return redirect("speaker_create")
else:
if request.user.groups.filter(name="organizer").exists(): # @@@
speaker = get_object_or_404(Speaker, pk=pk)
else:
raise Http404()
if request.method == "POST":
form = SpeakerForm(request.POST, request.FILES, instance=speaker)
if form.is_valid():
form.save()
messages.success(request, "Speaker profile updated.")
return redirect("dashboard")
else:
form = SpeakerForm(instance=speaker)
return render(request, "speakers/speaker_edit.html", {
"form": form,
})
def speaker_profile(request, pk, template_name="speakers/speaker_profile.html", extra_context=None):
if extra_context is None:
extra_context = {}
speaker = get_object_or_404(Speaker, pk=pk)
# schedule may not be installed so we need to check for sessions
if hasattr(speaker, "sessions"):
sessions = speaker.sessions.exclude(slot=None).order_by("slot__start")
else:
sessions = []
if not sessions:
raise Http404()
return render_to_response(template_name, dict({
"speaker": speaker,
"sessions": sessions,
"timezone": settings.SCHEDULE_TIMEZONE,
}, **extra_context), context_instance=RequestContext(request))