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_details = {} 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 kindslot = f"{kind} {slot_type_count[(date, kind)]}" for room in rooms.split(';'): room = room.strip() room_names.add(room) slot_details[(date, kindslot, room)] = (start_time, end_time) with open(options[self.TALKS]) as csv_file: csv_reader = csv.reader(csv_file) used_rooms = next(csv_reader) talk = {} 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: kindslot = cell for i, room in enumerate(used_rooms[1:], 1): talk_id = row[i] if not talk_id: continue assert (date, kindslot, room) in slot_details, f"Slot ({date}, '{kindslot}', '{room}') not found" talk[(date, kindslot, room)] = 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 print('days', days) 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)) slotkinds = {} for slotkind_name in slotkind_names: slotkind, _created = SlotKind.objects.get_or_create(schedule=schedule, label=slotkind_name) slotkinds[slotkind_name] = slotkind for details in slot_details: date, kindslot, room = details start_time, end_time = slot_details[details] kind_name = kindslot.rsplit(' ', 1)[0] # TODO this should not be hard coded exclusive = kind_name in ["plenary", "morning tea", "afternoon tea"] slot, _created = Slot.objects.get_or_create( day=days[date], kind=slotkinds[kind_name], start=start_time, end=end_time, exclusive=exclusive)