add speakers app from pycon
This commit is contained in:
parent
76c4a7b79c
commit
2b7f5546a0
10 changed files with 307 additions and 0 deletions
0
symposion/speakers/__init__.py
Normal file
0
symposion/speakers/__init__.py
Normal file
9
symposion/speakers/admin.py
Normal file
9
symposion/speakers/admin.py
Normal 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"],
|
||||
)
|
31
symposion/speakers/fixture_gen.py
Normal file
31
symposion/speakers/fixture_gen.py
Normal 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",
|
||||
)
|
63
symposion/speakers/forms.py
Normal file
63
symposion/speakers/forms.py
Normal 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
|
0
symposion/speakers/management/__init__.py
Normal file
0
symposion/speakers/management/__init__.py
Normal file
0
symposion/speakers/management/commands/__init__.py
Normal file
0
symposion/speakers/management/commands/__init__.py
Normal 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"),
|
||||
])
|
55
symposion/speakers/models.py
Normal file
55
symposion/speakers/models.py
Normal 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
|
9
symposion/speakers/urls.py
Normal file
9
symposion/speakers/urls.py
Normal 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
121
symposion/speakers/views.py
Normal 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))
|
Loading…
Reference in a new issue