summaryrefslogtreecommitdiff
path: root/src/program_parser.py
blob: 1fae5280a4234cbf496ecb8a3af8989282ea45ec (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
112
113
114
115
116
117
118
119
120
121
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
    short:      str = None
    spacer:     str = ''
    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:   float = 0


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':                         "🌐",
                'Cabin fireplace':                "🔥(🏚️)",
                'Cabin Fireplace':                "🔥(🏚️)",
                'Main camping fireplace':         "🔥(🏞️)",
        }


    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=1000) -> 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) -> str:
            if len(event.title) > self.title_max_length:
                # Truncate title by deleting was 1-3 chars and putting ...
                event.short = f'{event.title[:self.title_max_length - 3]}...'
            else:
                event.short = event.title
                event.spacer = "." * (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.short}{event.spacer}  {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)

            # Get progress
            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()
            progress = 100 + (progress_sec / duration_sec) * 100
            if progress > 0:
                event_to_show.progress = progress

        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)