symposion_app/pinaxcon/registrasion/management/commands/update_schedule.py

127 lines
4.1 KiB
Python

from django.core.management.base import BaseCommand
from symposion.conference.models import Section, current_conference, Conference
from symposion.schedule.models import Day, Schedule, Session
from symposion.schedule.models import (Day, Presentation, Room, SlotKind, Slot,
SlotRoom, ProposalBase)
from dateutil.parser import parse
from collections import Counter
from pathlib import Path
import csv
class Command(BaseCommand):
known_headers = ["date", "start time", "end time", "kind", "rooms"]
SLOTS = 'slots'
TALKS = 'talks'
help = "Updates the schedule based on two csv files, "\
"one that gives all the talk slots, the other the talks."
def find_or_create_slot(self, date, start_time, end_time, room):
print(date, start_time, end_time, room)
return (date, start_time, end_time, room)
def add_arguments(self, parser):
parser.add_argument(self.SLOTS, type=Path)
parser.add_argument(self.TALKS, type=Path)
def handle(self, *args, **options):
date_strs = set()
slotkind_names = set()
room_names = set()
slot = {}
slot_type_count = Counter()
conf = current_conference()
section = Section.objects.filter(conference=conf, slug="main").all().first()
schedule, _created = Schedule.objects.get_or_create(section=section)
print('conf', conf)
print('section', section)
print('schedule', schedule)
with open(options[self.SLOTS]) as csv_file:
csv_reader = csv.reader(csv_file)
headers = next(csv_reader)
assert headers == self.known_headers
for row in csv_reader:
assert len(row) == len(self.known_headers)
rowdate, start_time, end_time, kind, rooms = row
slotkind_names.add(kind)
if rowdate:
date = rowdate
date_strs.add(date)
assert kind, "kind cannot be blank"
slot_type_count[(date, kind)] += 1
slot_name = f"{kind} {slot_type_count[(date, kind)]}"
for room in rooms.split(';'):
room = room.strip()
room_names.add(room)
slot[(date, slot_name, room)] = self.find_or_create_slot(
date, start_time, end_time, room)
with open(options[self.TALKS]) as csv_file:
csv_reader = csv.reader(csv_file)
used_rooms = next(csv_reader)
assert used_rooms[0] == '', "Cell (1, 1) must be empty"
for room in used_rooms[1:]:
assert room in room_names, f"Unknown room: {room}"
for row in csv_reader:
cell = row[0]
if cell.rsplit(' ', 1)[0] in slotkind_names:
kind = cell
for i, room in enumerate(used_rooms[1:], 1):
talk_id = row[i]
if not talk_id:
continue
assert (date, kind, room) in slot, f"Slot ({date}, '{kind}', '{room}') not found"
# TODO set the talk slot to the associated talk
# place_talk(slot[(date, slot_name)].talk = int(talk_id)
else:
assert parse(row[0]), "Not a date: {row[0]}"
date = row[0]
for col in row[1:]:
assert col == '', f"All other columns must be empty: {date}"
days = {}
for date in date_strs:
print('schedule', type(schedule))
day, _created = Day.objects.get_or_create(
schedule=schedule, date=date)
days['date'] = day
rooms = {}
for room_name in room_names:
room, _created = Room.objects.get_or_create(
schedule=schedule, name=room_name, order=used_rooms.index(room_name))
slotkind = {}
for slotkind_name in slotkind_names:
slotkind, _created = SlotKind.objects.get_or_create(schedule=schedule, label=slotkind_name)