Merge pull request #80 from miurahr/sessionrole
schedule: add session and session role
This commit is contained in:
commit
7dc043b9ab
5 changed files with 206 additions and 2 deletions
|
@ -1,6 +1,6 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from symposion.schedule.models import Schedule, Day, Room, SlotKind, Slot, SlotRoom, Presentation
|
from symposion.schedule.models import Schedule, Day, Room, SlotKind, Slot, SlotRoom, Presentation, Session, SessionRole
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Schedule)
|
admin.site.register(Schedule)
|
||||||
|
@ -15,4 +15,6 @@ admin.site.register(
|
||||||
SlotRoom,
|
SlotRoom,
|
||||||
list_display=("slot", "room")
|
list_display=("slot", "room")
|
||||||
)
|
)
|
||||||
|
admin.site.register(Session)
|
||||||
|
admin.site.register(SessionRole)
|
||||||
admin.site.register(Presentation)
|
admin.site.register(Presentation)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
|
from django.contrib.auth.models import User
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
from markitup.fields import MarkupField
|
from markitup.fields import MarkupField
|
||||||
|
@ -180,3 +181,62 @@ class Presentation(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ["slot"]
|
ordering = ["slot"]
|
||||||
|
|
||||||
|
|
||||||
|
class Session(models.Model):
|
||||||
|
|
||||||
|
day = models.ForeignKey(Day, related_name="sessions")
|
||||||
|
slots = models.ManyToManyField(Slot, related_name="sessions")
|
||||||
|
|
||||||
|
def sorted_slots(self):
|
||||||
|
return self.slots.order_by("start")
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
slots = self.sorted_slots()
|
||||||
|
if slots:
|
||||||
|
return list(slots)[0].start
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def end(self):
|
||||||
|
slots = self.sorted_slots()
|
||||||
|
if slots:
|
||||||
|
return list(slots)[-1].end
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
start = self.start()
|
||||||
|
end = self.end()
|
||||||
|
if start and end:
|
||||||
|
return u"%s: %s - %s" % (
|
||||||
|
self.day.date.strftime("%a"),
|
||||||
|
start.strftime("%X"),
|
||||||
|
end.strftime("%X")
|
||||||
|
)
|
||||||
|
return u""
|
||||||
|
|
||||||
|
|
||||||
|
class SessionRole(models.Model):
|
||||||
|
|
||||||
|
SESSION_ROLE_CHAIR = 1
|
||||||
|
SESSION_ROLE_RUNNER = 2
|
||||||
|
|
||||||
|
SESSION_ROLE_TYPES = [
|
||||||
|
(SESSION_ROLE_CHAIR, "Session Chair"),
|
||||||
|
(SESSION_ROLE_RUNNER, "Session Runner"),
|
||||||
|
]
|
||||||
|
|
||||||
|
session = models.ForeignKey(Session)
|
||||||
|
user = models.ForeignKey(User)
|
||||||
|
role = models.IntegerField(choices=SESSION_ROLE_TYPES)
|
||||||
|
status = models.NullBooleanField()
|
||||||
|
|
||||||
|
submitted = models.DateTimeField(default=datetime.datetime.now)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = [("session", "user", "role")]
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return u"%s %s: %s" % (self.user, self.session,
|
||||||
|
self.SESSION_ROLE_TYPES[self.role - 1][1])
|
||||||
|
|
58
symposion/schedule/tests/test_views_session.py
Normal file
58
symposion/schedule/tests/test_views_session.py
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
from datetime import date
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from symposion.conference.models import Section, current_conference, Conference
|
||||||
|
from symposion.schedule.models import Day, Schedule, Session
|
||||||
|
|
||||||
|
|
||||||
|
class TestScheduleViews(TestCase):
|
||||||
|
username = "user@example.com"
|
||||||
|
first_name = "Sam"
|
||||||
|
last_name = "McGillicuddy"
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.user = User.objects.create_user(self.username,
|
||||||
|
password="pass",
|
||||||
|
email=self.username)
|
||||||
|
self.user.first_name = self.first_name
|
||||||
|
self.user.last_name = self.last_name
|
||||||
|
self.user.save()
|
||||||
|
|
||||||
|
def test_session_list(self):
|
||||||
|
# Really minimal test for session list
|
||||||
|
rsp = self.client.get(reverse("schedule_session_list"))
|
||||||
|
self.assertEqual(200, rsp.status_code)
|
||||||
|
|
||||||
|
def test_session_staff_email(self):
|
||||||
|
# login and staff required
|
||||||
|
self.user.is_staff = True
|
||||||
|
self.user.save()
|
||||||
|
assert self.client.login(username=self.username, password="pass")
|
||||||
|
|
||||||
|
url = reverse("schedule_session_staff_email")
|
||||||
|
rsp = self.client.get(url)
|
||||||
|
self.assertEqual(200, rsp.status_code)
|
||||||
|
|
||||||
|
def test_session_detail(self):
|
||||||
|
# really minimal test
|
||||||
|
Conference.objects.get_or_create(id=settings.CONFERENCE_ID)
|
||||||
|
section = Section.objects.create(
|
||||||
|
conference=current_conference(),
|
||||||
|
)
|
||||||
|
schedule = Schedule.objects.create(
|
||||||
|
section=section,
|
||||||
|
)
|
||||||
|
day = Day.objects.create(
|
||||||
|
schedule=schedule,
|
||||||
|
date=date.today(),
|
||||||
|
)
|
||||||
|
session = Session.objects.create(
|
||||||
|
day=day,
|
||||||
|
)
|
||||||
|
url = reverse("schedule_session_detail", args=(session.pk,))
|
||||||
|
rsp = self.client.get(url)
|
||||||
|
self.assertEqual(200, rsp.status_code)
|
|
@ -17,4 +17,7 @@ urlpatterns = patterns(
|
||||||
url(r"^([\w\-]+)/edit/slot/(\d+)/", "schedule_slot_edit",
|
url(r"^([\w\-]+)/edit/slot/(\d+)/", "schedule_slot_edit",
|
||||||
name="schedule_slot_edit"),
|
name="schedule_slot_edit"),
|
||||||
url(r"^conference.json", "schedule_json", name="schedule_json"),
|
url(r"^conference.json", "schedule_json", name="schedule_json"),
|
||||||
|
url(r"^sessions/staff.txt$", "session_staff_email", name="schedule_session_staff_email"),
|
||||||
|
url(r"^sessions/$", "session_list", name="schedule_session_list"),
|
||||||
|
url(r"^session/(\d+)/$", "session_detail", name="schedule_session_detail"),
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,11 +6,12 @@ from django.shortcuts import render, get_object_or_404, redirect
|
||||||
from django.template import loader, Context
|
from django.template import loader, Context
|
||||||
|
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.contrib.auth.models import User
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
|
|
||||||
from symposion.schedule.forms import SlotEditForm, ScheduleSectionForm
|
from symposion.schedule.forms import SlotEditForm, ScheduleSectionForm
|
||||||
from symposion.schedule.models import Schedule, Day, Slot, Presentation
|
from symposion.schedule.models import Schedule, Day, Slot, Presentation, Session, SessionRole
|
||||||
from symposion.schedule.timetable import TimeTable
|
from symposion.schedule.timetable import TimeTable
|
||||||
|
|
||||||
|
|
||||||
|
@ -231,3 +232,83 @@ def schedule_json(request):
|
||||||
json.dumps({'schedule': data}),
|
json.dumps({'schedule': data}),
|
||||||
content_type="application/json"
|
content_type="application/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def session_list(request):
|
||||||
|
sessions = Session.objects.all().order_by('pk')
|
||||||
|
|
||||||
|
return render(request, "schedule/session_list.html", {
|
||||||
|
"sessions": sessions,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def session_staff_email(request):
|
||||||
|
|
||||||
|
if not request.user.is_staff:
|
||||||
|
return redirect("schedule_session_list")
|
||||||
|
|
||||||
|
data = "\n".join(user.email for user in User.objects.filter(sessionrole__isnull=False).distinct())
|
||||||
|
|
||||||
|
return HttpResponse(data, content_type="text/plain;charset=UTF-8")
|
||||||
|
|
||||||
|
|
||||||
|
def session_detail(request, session_id):
|
||||||
|
|
||||||
|
session = get_object_or_404(Session, id=session_id)
|
||||||
|
|
||||||
|
chair = None
|
||||||
|
chair_denied = False
|
||||||
|
chairs = SessionRole.objects.filter(session=session, role=SessionRole.SESSION_ROLE_CHAIR).exclude(status=False)
|
||||||
|
if chairs:
|
||||||
|
chair = chairs[0].user
|
||||||
|
else:
|
||||||
|
if request.user.is_authenticated():
|
||||||
|
# did the current user previously try to apply and got rejected?
|
||||||
|
if SessionRole.objects.filter(session=session, user=request.user, role=SessionRole.SESSION_ROLE_CHAIR, status=False):
|
||||||
|
chair_denied = True
|
||||||
|
|
||||||
|
runner = None
|
||||||
|
runner_denied = False
|
||||||
|
runners = SessionRole.objects.filter(session=session, role=SessionRole.SESSION_ROLE_RUNNER).exclude(status=False)
|
||||||
|
if runners:
|
||||||
|
runner = runners[0].user
|
||||||
|
else:
|
||||||
|
if request.user.is_authenticated():
|
||||||
|
# did the current user previously try to apply and got rejected?
|
||||||
|
if SessionRole.objects.filter(session=session, user=request.user, role=SessionRole.SESSION_ROLE_RUNNER, status=False):
|
||||||
|
runner_denied = True
|
||||||
|
|
||||||
|
if request.method == "POST" and request.user.is_authenticated():
|
||||||
|
if not hasattr(request.user, "profile") or not request.user.profile.is_complete:
|
||||||
|
response = redirect("profile_edit")
|
||||||
|
response["Location"] += "?next=%s" % request.path
|
||||||
|
return response
|
||||||
|
|
||||||
|
role = request.POST.get("role")
|
||||||
|
if role == "chair":
|
||||||
|
if chair is None and not chair_denied:
|
||||||
|
SessionRole(session=session, role=SessionRole.SESSION_ROLE_CHAIR, user=request.user).save()
|
||||||
|
elif role == "runner":
|
||||||
|
if runner is None and not runner_denied:
|
||||||
|
SessionRole(session=session, role=SessionRole.SESSION_ROLE_RUNNER, user=request.user).save()
|
||||||
|
elif role == "un-chair":
|
||||||
|
if chair == request.user:
|
||||||
|
session_role = SessionRole.objects.filter(session=session, role=SessionRole.SESSION_ROLE_CHAIR, user=request.user)
|
||||||
|
if session_role:
|
||||||
|
session_role[0].delete()
|
||||||
|
elif role == "un-runner":
|
||||||
|
if runner == request.user:
|
||||||
|
session_role = SessionRole.objects.filter(session=session, role=SessionRole.SESSION_ROLE_RUNNER, user=request.user)
|
||||||
|
if session_role:
|
||||||
|
session_role[0].delete()
|
||||||
|
|
||||||
|
return redirect("schedule_session_detail", session_id)
|
||||||
|
|
||||||
|
return render(request, "schedule/session_detail.html", {
|
||||||
|
"session": session,
|
||||||
|
"chair": chair,
|
||||||
|
"chair_denied": chair_denied,
|
||||||
|
"runner": runner,
|
||||||
|
"runner_denied": runner_denied,
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in a new issue