Changeset - 0fb224cbf6e2
[Not reviewed]
Merge
0 3 4
Sheila Miguez - 10 years ago 2014-09-28 15:45:35
codersquid@users.noreply.github.com
Merge pull request #62 from codersquid/json_endpoint

Adds a schedule_json view
7 files changed with 248 insertions and 1 deletions:
0 comments (0 inline, 0 general)
requirements-test.txt
Show inline comments
 
new file 100644
 
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
symposion/schedule/models.py
Show inline comments
 
import datetime
 

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

	
...
 
@@ -92,6 +94,29 @@ class Slot(models.Model):
 
        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"))
symposion/schedule/tests/factories.py
Show inline comments
 
new file 100644
 
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
symposion/schedule/tests/runtests.py
Show inline comments
 
new file 100755
 
#!/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")
symposion/schedule/tests/test_views.py
Show inline comments
 
new file 100644
 
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
symposion/schedule/urls.py
Show inline comments
 
# 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"),
...
 
@@ -13,4 +12,5 @@ urlpatterns = patterns("symposion.schedule.views",
 
    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"),
 
)
symposion/schedule/views.py
Show inline comments
 
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
...
 
@@ -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 (0 inline, 0 general)