Changeset - 20469223cb05
[Not reviewed]
0 1 0
Clinton Roy - 5 years ago 2019-10-19 01:38:29
clintonr@ansto.gov.au
go from proposal, to presentation, to slot, to slotroom.
1 file changed with 17 insertions and 26 deletions:
0 comments (0 inline, 0 general)
pinaxcon/registrasion/management/commands/update_schedule.py
Show inline comments
 
from django.core.management.base import BaseCommand
 

	
 
from symposion.conference.models import Section, current_conference
 

	
 
from symposion.schedule.models import (Day, Presentation, Room, SlotKind, Schedule, Slot, SlotRoom)
 

	
 
from symposion.proposals.models import 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 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)
 

	
 
        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)
 
            talks = {}
 

	
 
            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"
 

	
 
                        talks[(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:
 
            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))
 
            rooms[room_name] = room
 

	
 
        slotkinds = {}
 
        for slotkind_name in slotkind_names:
 
            slotkind, _created = SlotKind.objects.get_or_create(schedule=schedule, label=slotkind_name)
 
            slotkinds[slotkind_name] = slotkind
 

	
 
        slots = {}
 
        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)
 

	
 
            slots[(date, kind_name, start_time, end_time)] = slot
 

	
 
        for details, talk_id in talks.items():
 
            date, kindslot, room = details
 
            date, kindslot, room_name = details
 
            kind_name = kindslot.rsplit(' ', 1)[0]
 

	
 
            (start_time, end_time) = slot_details[(date, kindslot, room)]
 

	
 
            slot = slots[(date, kind_name, start_time, end_time)]
 

	
 
            slotroom = SlotRoom.objects.get_or_create(slot=slot, room=rooms[room])
 
            (start_time, end_time) = slot_details[(date, kindslot, room_name)]
 

	
 
            proposal = ProposalBase.objects.filter(pk=talk_id).first()
 

	
 
            assert proposal, f"Could not find proposal {talk_id}"
 

	
 
            preso = Presentation.objects.filter(proposal_base=proposal).first()
 

	
 
            print(f'would like to set {preso} to slot {slot}')
 
            assert preso, f"Could not find Presentation for talk {talk_id}"
 

	
 
            if not preso.slot:
 

	
 
                # TODO the exclusive list should not be hard coded, another csv file maybe.
 
                exclusive = kind_name in ["plenary", "morning tea", "lunch", "afternoon tea"]
 

	
 
                preso.slot, _created = Slot.objects.get_or_create(
 
                    day=days[date],
 
                    kind=slotkinds[kind_name],
 
                    start=start_time,
 
                    end=end_time,
 
                    exclusive=exclusive)
 

	
 
            #preso.slot = slot
 
            preso.save()
 

	
 
            slotroom, _create = SlotRoom.objects.get_or_create(slot=preso.slot, room=rooms[room_name])
0 comments (0 inline, 0 general)