Skip to content

Commit

Permalink
move generation of frab-style json schedule to separate file
Browse files Browse the repository at this point in the history
  • Loading branch information
Kunsi committed Aug 14, 2024
1 parent d375a70 commit ee12ce8
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 102 deletions.
111 changes: 9 additions & 102 deletions apps/schedule/feeds.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
import json
from datetime import timedelta
from icalendar import Calendar, Event
from flask import request, abort, current_app as app, redirect, url_for, Response
from flask_cors import cross_origin
from flask_login import current_user
from math import ceil

from main import external_url
from models import event_year, event_start, event_end
from models import event_year
from models.user import User
from models.cfp import Proposal

from ..common import feature_flag, feature_enabled, json_response
from .schedule_xml import export_frab, get_day_start_end, get_duration
from .schedule_json import export_frab_json
from .schedule_xml import export_frab
from .historic import feed_historic
from .data import (
_get_scheduled_proposals,
_get_proposal_dict,
_convert_time_to_str,
_get_upcoming,
)
from . import event_tz, schedule
from . import schedule


def _format_event_description(event):
Expand All @@ -37,9 +35,9 @@ def _format_event_description(event):
venue_str = event["venue"]
if event["map_link"]:
venue_str = f'{venue_str} ({event["map_link"]})'
footer_block.append(f'Venue: {venue_str}')
footer_block.append(f"Venue: {venue_str}")
if footer_block:
description += '\n\n' + '\n'.join(footer_block)
description += "\n\n" + "\n".join(footer_block)

return description

Expand Down Expand Up @@ -78,102 +76,10 @@ def schedule_frab_json(year):
.all()
)

duration_days = ceil((event_end() - event_end()).total_seconds / 86400)

rooms = [proposal.scheduled_venue.name for proposal in schedule]

schedule_json = {
"version": "1.0-public",
"conference": {
"acronym": "emf{}".format(event_year()),
"days": [],
"daysCount": duration_days,
"end": event_end().strftime("%Y-%m-%d"),
"rooms": [
{
"name": room,
}
for room in rooms
],
"start": event_start().strftime("%Y-%m-%d"),
"time_zone_name": event_tz,
"timeslot_duration": "00:10",
"title": "Electromagnetic Field {}".format(event_year()),
"url": external_url("main"),
},
}

for day in range(0, duration_days):
day_dt = event_start() + timedelta(days=day)
day_start, day_end = get_day_start_end(day_dt)
day_schedule = {
"date": day_dt.strftime("%Y-%m-%d"),
"day_end": day_start.isoformat(),
"day_start": day_end.isoformat(),
"index": day,
"rooms": {},
}
for room in rooms:
day_schedule["rooms"][room] = []
for proposal in schedule:
if proposal.scheduled_venue.name != room:
# TODO find a better way to do that
continue
links = {
proposal.c3voc_url,
proposal.youtube_url,
proposal.thumbnail_url,
proposal.map_link,
}
links.discard(None)
links.discard("")
day_schedule["rooms"][room].append(
{
"abstract": None, # The proposal model does not implement abstracts
"attachments": [],
"date": event_tz.localize(proposal.start_date).isoformat(),
"description": proposal.description,
"do_not_record": proposal.video_privacy != "public",
"duration": get_duration(proposal.start_date, proposal.end_date),
"guid": None,
"id": proposal.id,
# This assumes there will never be a non-english talk,
# which is probably fine for a conference in the UK.
"language": "en",
"links": sorted(links),
"persons": [
{
"name": name.strip(),
"public_name": name.strip(),
}
for name in (proposal.published_names or proposal.user.name).split(",")
],
"recording_license": "CC BY-SA 3.0",
"room": room,
"slug": "emf{}-{}-{}".format(
event_year(),
proposal.id,
proposal.slug,
),
"start": event_tz.localize(proposal.start_date).strftime("%H:%M"),
"subtitle": None,
"title": proposal.display_title,
"track": None,
"type": proposal.type,
"url": external_url(
".item",
year=event_year(),
proposal_id=proposal.id,
slug=proposal.slug,
),
}
)
schedule_json["conference"]["days"].append(day_schedule)

return Response(
json.dumps(
{
"schedule": schedule_json,
"schedule": export_frab_json(schedule),
"$schema": "https://c3voc.de/schedule/schema.json",
"generator": {
"name": "emfcamp-website",
Expand All @@ -187,7 +93,8 @@ def schedule_frab_json(year):

@schedule.route("/schedule/<int:year>.frab")
def schedule_frab(year):
return redirect(url_for('schedule_frab_xml', year=year), code=301)
return redirect(url_for("schedule_frab_xml", year=year), code=301)


@schedule.route("/schedule/frab-<int:year>.xml")
def schedule_frab_xml(year):
Expand Down
128 changes: 128 additions & 0 deletions apps/schedule/schedule_json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
from datetime import timedelta
from math import ceil

from main import external_url
from models import event_end, event_start, event_year

from . import event_tz
from .schedule_xml import get_day_start_end, get_duration


def events_per_day_and_room(schedule):
days = {
current_date.date(): {
"index": index + 1,
"start": get_day_start_end(event_start() + timedelta(days=index))[0],
"end": get_day_start_end(event_start() + timedelta(days=index))[1],
"rooms": {},
}
for index, current_date in enumerate(
event_start() + timedelta(days=i) for i in range((event_end() - event_start()).days + 1)
)
}

for proposal in schedule:
talk_date = proposal.start_date.date()
if talk.start_date.hour < 4 and talk_date != event_start().date():
talk_date -= timedelta(days=1)
if talk_date not in days:
# Event is outside the scheduled event duration.
continue
if proposal.scheduled_venue.name not in days[talk_date]:
days[talk_date][proposal.scheduled_venue.name] = [proposal]
else:
days[talk_date][proposal.scheduled_venue.name].append(proposal)

return days.values()


def export_frab_json(schedule):
duration_days = ceil((event_end() - event_end()).total_seconds / 86400)

rooms = set([proposal.scheduled_venue.name for proposal in schedule])

schedule_json = {
"version": "1.0-public",
"conference": {
"acronym": "emf{}".format(event_year()),
"days": [],
"daysCount": duration_days,
"end": event_end().strftime("%Y-%m-%d"),
"rooms": [
{
"name": room,
}
for room in sorted(rooms)
],
"start": event_start().strftime("%Y-%m-%d"),
"time_zone_name": event_tz,
"timeslot_duration": "00:10",
"title": "Electromagnetic Field {}".format(event_year()),
"url": external_url("main"),
},
}

for day in events_per_day_and_room:
day_schedule = {
"date": day["start"].strftime("%Y-%m-%d"),
"day_end": day["start"].isoformat(),
"day_start": day["end"].isoformat(),
"index": day["index"],
"rooms": {},
}
for room, events in sorted(day["rooms"].items()):
day_schedule["rooms"][room] = []
for proposal in events:
links = {
proposal.c3voc_url,
proposal.youtube_url,
proposal.thumbnail_url,
proposal.map_link,
}
links.discard(None)
links.discard("")
day_schedule["rooms"][room].append(
{
"abstract": None, # The proposal model does not implement abstracts
"attachments": [],
"date": event_tz.localize(proposal.start_date).isoformat(),
"description": proposal.description,
"do_not_record": proposal.video_privacy != "public",
"duration": get_duration(proposal.start_date, proposal.end_date),
"guid": None,
"id": proposal.id,
# This assumes there will never be a non-english talk,
# which is probably fine for a conference in the UK.
"language": "en",
"links": sorted(links),
"persons": [
{
"name": name.strip(),
"public_name": name.strip(),
}
for name in (proposal.published_names or proposal.user.name).split(",")
],
"recording_license": "CC BY-SA 3.0",
"room": room,
"slug": "emf{}-{}-{}".format(
event_year(),
proposal.id,
proposal.slug,
),
"start": event_tz.localize(proposal.start_date).strftime("%H:%M"),
"subtitle": None,
"title": proposal.display_title,
# Contrary to the infobeamer frab module, the json module does not allow users to set colours
# for tracks themselves. It instead relies on the schedule itself to provide those colours.
"track": None,
"type": proposal.type,
"url": external_url(
".item",
year=event_year(),
proposal_id=proposal.id,
slug=proposal.slug,
),
}
)
schedule_json["conference"]["days"].append(day_schedule)
return schedule_json

0 comments on commit ee12ce8

Please sign in to comment.