summaryrefslogtreecommitdiff
path: root/src/program_parser.py
blob: 7233c490dca9397efac6c9daeb4ee60401d6a89d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import os
import json
import datetime
import dataclasses
import logging


logger = logging.getLogger(__name__) # Set the logger name, to the name of the module

@dataclasses.dataclass
class Event:
    title:      str = None
    room:       str = None
    day:        str = None
    start_date: datetime.datetime = None
    end_date:   datetime.datetime = None
    icon:       str = '?'
    time:       str = None
    duration:   datetime.timedelta = None
    pretty:     str = None
    progress:   int = None


class ProgramParser:
    '''
    Parse the JSON program into dataformat for easy processing
    '''
    def __init__(self, program_path:os.PathLike=None, title_max_length:int=34, override_date:datetime.datetime|None=None):
        self.program_path = program_path
        self.title_max_length = title_max_length
        self.override_date = override_date
        self.icons = {
                'Startent at Info Desk' :         "⭐",
                'Speakers Tent':                  "🏕",
                'Workshop Room':                  "🛠️",
                'Bar Meetup Area':                "🍺",
                'Bar Area':                       "🍺",
                'External':                       "🚗",
                'Pyjam.as Village in Party Area': "🐍",
                'Workshop Room (possibly outside of it)': "🛠️(🏞️)",
                'Workshop Room (sofa area)':      "🛠️(🛋️)",
                'NWWC Village in Party Area':     "🔊",
                'Wellness area':                  "🛀",
                'Online':                         "🌐",
        }


    def get_program(self) -> list[Event]:
        program: list[Event] = []
        # Parse program into data format (interpret datetime, and such)
        with open(self.program_path, "r") as json_file:
            program_raw = json.load(json_file)
            for event_raw in program_raw:
                event = Event()
                #print(event_raw["title"])
                for d in ["title", "room"]: # 1 to 1 mapping
                    setattr(event, d, event_raw[d])
                event.start_date = datetime.datetime.strptime(event_raw["date"], "%Y-%m-%dT%H:%M:%S+00:00")
                event.start_date += datetime.timedelta(hours=2)  # Hvad er vinter tid?
                end_bogus = datetime.datetime.strptime(event_raw["duration"],"%H:%M:%S")
                event.duration = datetime.timedelta(
                        hours=end_bogus.hour, minutes=end_bogus.minute, seconds=end_bogus.second)
                event.end_date = event.start_date + event.duration
                #print('Start date: ', event["start_date"])
                #print("End date:   ", event["end_date"])
                #print()
                program.append(event)

        program = sorted(program, key=lambda x: x.start_date)
        return program

    def get_events_to_show(self, program: list[Event], lines=4) -> list[Event]:
        current_datetime = datetime.datetime.now() if not self.override_date else self.override_date
        #current_datetime = datetime.datetime(year=2025, month=7, day=18, hour=15, minute=30)  # DEBUG
        # Get events to show
        events_to_show = []
        for event in program:
            if len(events_to_show) >= lines:
                break
            if event.end_date > current_datetime:
                events_to_show.append(event)

        def format_program(event: Event, cli=False) -> str:
            if len(event.title) > self.title_max_length:
                # Truncate title by deleting was 1-3 chars and putting ...
                event.title = f'{event.title[:self.title_max_length - 3]}...'
            else:
                event.title += " " * (self.title_max_length - len(event.title)) # Pad title
            event.day = event.start_date.strftime('%a')
            start_time = event.start_date.strftime('%H:%M')
            end_time = event.end_date.strftime('%H:%M')
            event.icon = self.icons.get(event.room)
            if event.icon == None:
                event.icon = '?'
                logger.warning(f"NEW ICON NEEDED!!! for {event.room}")
            event.time = f"{start_time}-{end_time}"
            return f"{event.title}  {event.day}  {start_time}-{end_time} {event.icon}"

        for event_to_show in events_to_show:
            event_to_show.pretty = format_program(event_to_show)
            duration_sec = (event_to_show.end_date - event_to_show.start_date).total_seconds()
            progress_sec = (current_datetime - event_to_show.end_date).total_seconds()
            event_to_show.progress = 100 + (progress_sec / duration_sec) * 100

        return events_to_show

def program_parser_factory():
    program_path = os.environ["PROGRAM_PATH"] if "PROGRAM_PATH" in os.environ else os.path.join(os.getcwd(),'programs', 'current.json')
    override_date = datetime.datetime.fromisoformat(os.environ["OVERRIDE_DATE"]) if "OVERRIDE_DATE" in os.environ else None
    return ProgramParser(program_path=program_path, override_date=override_date)