Skip to content

Commit

Permalink
Merge pull request #62 from codersquid/json_endpoint
Browse files Browse the repository at this point in the history
Adds a schedule_json view
  • Loading branch information
codersquid committed Sep 28, 2014
2 parents a4c4e69 + 40a55c2 commit 0fb224c
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 1 deletion.
11 changes: 11 additions & 0 deletions requirements-test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Django==1.4.15
Pillow==2.5.3
django-discover-runner==1.0
django-markitup==2.2.2
django-model-utils==1.5.0
django-nose==1.2
django-reversion==1.8.0
django-timezones==0.2
factory-boy==2.4.1
nose==1.3.4
pytz==2014.7
25 changes: 25 additions & 0 deletions symposion/schedule/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import datetime

from django.core.exceptions import ObjectDoesNotExist
from django.db import models

Expand Down Expand Up @@ -92,6 +94,29 @@ def content(self):
except ObjectDoesNotExist:
return None

@property
def start_datetime(self):
return datetime.datetime(
self.day.date.year,
self.day.date.month,
self.day.date.day,
self.start.hour,
self.start.minute)

@property
def end_datetime(self):
return datetime.datetime(
self.day.date.year,
self.day.date.month,
self.day.date.day,
self.end.hour,
self.end.minute)

@property
def length_in_minutes(self):
return int(
(self.end_datetime - self.start_datetime).total_seconds() / 60)

@property
def rooms(self):
return Room.objects.filter(pk__in=self.slotroom_set.values("room"))
Expand Down
63 changes: 63 additions & 0 deletions symposion/schedule/tests/factories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import datetime
import random

import factory
from factory import fuzzy

from symposion.schedule.models import Schedule, Day, Slot, SlotKind
from symposion.conference.models import Section, Conference


class ConferenceFactory(factory.DjangoModelFactory):
title = fuzzy.FuzzyText()
start_date = fuzzy.FuzzyDate(datetime.date(2014, 1, 1))
end_date = fuzzy.FuzzyDate(datetime.date(2014, 1, 1)
+ datetime.timedelta(days=random.randint(1, 10)))
# timezone = TimeZoneField("UTC")

class Meta:
model = Conference


class SectionFactory(factory.DjangoModelFactory):
conference = factory.SubFactory(ConferenceFactory)
name = fuzzy.FuzzyText()
slug = fuzzy.FuzzyText()

class Meta:
model = Section


class ScheduleFactory(factory.DjangoModelFactory):
section = factory.SubFactory(SectionFactory)
published = True
hidden = False

class Meta:
model = Schedule


class SlotKindFactory(factory.DjangoModelFactory):
schedule = factory.SubFactory(ScheduleFactory)
label = fuzzy.FuzzyText()

class Meta:
model = SlotKind


class DayFactory(factory.DjangoModelFactory):
schedule = factory.SubFactory(ScheduleFactory)
date = fuzzy.FuzzyDate(datetime.date(2014, 1, 1))

class Meta:
model = Day


class SlotFactory(factory.DjangoModelFactory):
day = factory.SubFactory(DayFactory)
kind = factory.SubFactory(SlotKindFactory)
start = datetime.time(random.randint(0, 23), random.randint(0, 59))
end = datetime.time(random.randint(0, 23), random.randint(0, 59))

class Meta:
model = Slot
68 changes: 68 additions & 0 deletions symposion/schedule/tests/runtests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# see runtests.py in https://github.com/pydanny/cookiecutter-djangopackage

import sys

try:
from django.conf import settings

settings.configure(
DEBUG=True,
USE_TZ=True,
DATABASES={
"default": {
"ENGINE": "django.db.backends.sqlite3",
}
},
ROOT_URLCONF="symposion.schedule.urls",
INSTALLED_APPS=[
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sites",

"markitup",
"reversion",

"symposion",
"symposion.conference",
"symposion.speakers",
"symposion.schedule",
"symposion.proposals",

],
SITE_ID=1,
NOSE_ARGS=['-s'],

MARKITUP_FILTER=('django.contrib.markup.templatetags.markup.textile', {}),
)

try:
import django
setup = django.setup
except AttributeError:
pass
else:
setup()

from django_nose import NoseTestSuiteRunner
except ImportError:
raise ImportError("To fix this error, run: pip install -r requirements-test.txt")


def run_tests(*test_args):
if not test_args:
test_args = ['tests']

# Run tests
test_runner = NoseTestSuiteRunner(verbosity=1)

failures = test_runner.run_tests(test_args)

if failures:
sys.exit(failures)


if __name__ == '__main__':
run_tests("symposion.schedule.tests.test_views")
30 changes: 30 additions & 0 deletions symposion/schedule/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import json

from django.test.client import Client
from django.test import TestCase

from . import factories


class ScheduleViewTests(TestCase):

def test_empty_json(self):
c = Client()
r = c.get('/conference.json')
assert r.status_code == 200

conference = json.loads(r.content)
assert 'schedule' in conference
assert len(conference['schedule']) == 0

def test_populated_empty_presentations(self):

factories.SlotFactory.create_batch(size=5)

c = Client()
r = c.get('/conference.json')
assert r.status_code == 200

conference = json.loads(r.content)
assert 'schedule' in conference
assert len(conference['schedule']) == 5
2 changes: 1 addition & 1 deletion symposion/schedule/urls.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# flake8: noqa
from django.conf.urls.defaults import url, patterns


urlpatterns = patterns("symposion.schedule.views",
url(r"^$", "schedule_conference", name="schedule_conference"),
url(r"^edit/$", "schedule_edit", name="schedule_edit"),
Expand All @@ -13,4 +12,5 @@
url(r"^([\w\-]+)/list/$", "schedule_list", name="schedule_list"),
url(r"^([\w\-]+)/presentations.csv$", "schedule_list_csv", name="schedule_list_csv"),
url(r"^([\w\-]+)/edit/slot/(\d+)/", "schedule_slot_edit", name="schedule_slot_edit"),
url(r"^conference.json", "schedule_json", name="schedule_json"),
)
50 changes: 50 additions & 0 deletions symposion/schedule/views.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import json

from django.core.urlresolvers import reverse
from django.http import Http404, HttpResponse
from django.shortcuts import render, get_object_or_404, redirect
from django.template import loader, Context

from django.contrib.auth.decorators import login_required
from django.contrib.sites.models import Site

from symposion.schedule.forms import SlotEditForm
from symposion.schedule.models import Schedule, Day, Slot, Presentation
Expand Down Expand Up @@ -156,3 +160,49 @@ def schedule_presentation_detail(request, pk):
"schedule": schedule,
}
return render(request, "schedule/presentation_detail.html", ctx)


def schedule_json(request):
slots = Slot.objects.filter(
day__schedule__published=True,
day__schedule__hidden=False
).order_by("start")

protocol = request.META.get('HTTP_X_FORWARDED_PROTO', 'http')
data = []
for slot in slots:
slot_data = {
"room": ", ".join(room["name"] for room in slot.rooms.values()),
"rooms": [room["name"] for room in slot.rooms.values()],
"start": slot.start_datetime.isoformat(),
"end": slot.end_datetime.isoformat(),
"duration": slot.length_in_minutes,
"kind": slot.kind.label,
"section": slot.day.schedule.section.slug,
}
if hasattr(slot.content, "proposal"):
slot_data.update({
"name": slot.content.title,
"authors": [s.name for s in slot.content.speakers()],
"contact": [
s.email for s in slot.content.speakers()
] if request.user.is_staff else ["redacted"],
"abstract": slot.content.abstract.raw,
"description": slot.content.description.raw,
"content_href": "%s://%s%s" % (
protocol,
Site.objects.get_current().domain,
reverse("schedule_presentation_detail", args=[slot.content.pk])
),
"cancelled": slot.content.cancelled,
})
else:
slot_data.update({
"name": slot.content_override.raw if slot.content_override else "Slot",
})
data.append(slot_data)

return HttpResponse(
json.dumps({'schedule': data}),
content_type="application/json"
)

0 comments on commit 0fb224c

Please sign in to comment.