-
Notifications
You must be signed in to change notification settings - Fork 0
/
indico.py
145 lines (130 loc) · 4.46 KB
/
indico.py
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#
# The quick-n-dirty LPC BBB frontend system
# Copyright 2020 Jonathan Corbet <[email protected]>
# Copyright 2020 Guy Lunardi <[email protected]>
# Redistributable under the terms of the GNU General Public License,
# version 2 or greater
#
#
# Interface to Indico (to get the schedule mainly)
#
import requests, datetime, copy
import config
#
# Save the time of the final session
#
final_time = None
Tracks = { }
NewTracks = { }
def load_timetable():
global Tracks, NewTracks
url = '%s/export/timetable/%d.json?ak=%s&pretty=yes' % (config.INDICO_SERVER,
config.EVENT_ID,
config.INDICO_API_KEY)
r = requests.get(url)
if r.status_code != 200:
print('Bad status %d getting timetable' % (r.status_code))
return
#
# The timetable is loaded into NewTracks, then assigned over at the end,
# just in case some other thread is trying to access it.
#
NewTracks = { }
decrypt_indico_json(r.json())
Tracks = NewTracks
#
# Try to turn the massive blob of json we get back from Indico into some
# sort of rational data structure.
#
def decrypt_indico_json(j):
days = j['results'][str(config.EVENT_ID)]
for day in days.values():
for item in day.values():
if item['entryType'] == 'Session':
decrypt_session(item)
elif item['entryType'] == 'Contribution':
# A talk outside of any session
add_talk('none', item)
else:
print('Unknown entry', item['id'], item['entryType'])
def add_talk(session, talk):
global final_time
item = sched_item(talk, session)
try:
NewTracks[session].append(item)
except KeyError:
NewTracks[session] = [item]
if (final_time is None) or (item.end > final_time):
final_time = item.end
def decrypt_session(session):
title = session['title']
for entry in session['entries'].values():
if entry['entryType'] not in ['Break', 'Contribution']:
print('Funky session entry', title, entry['title'], entry['entryType'])
else:
add_talk(title, entry)
#
# Let's try to simplify the representation of a schedule item
#
def fixtime(indico_time):
ts = indico_time['date'] + ' ' + indico_time['time'] + ' ' + config.INDICO_TZOFFSET
return datetime.datetime.strptime(ts, '%Y-%m-%d %H:%M:%S %z')
class sched_item:
def __init__(self, item, track):
self.is_break = item['entryType'] == 'Break'
self.title = item['title']
self.begin = fixtime(item['startDate'])
self.end = fixtime(item['endDate'])
self.room = item['room']
self.desc = item['description'].replace('\n', ' ')
self.track = track
try:
self.url = config.INDICO_SERVER + item['url']
except KeyError:
self.url = None
self.presenters = [ ]
if 'presenters' in item:
for pres in item['presenters']:
self.presenters.append(pres['name'])
#
# Get a piece of the timetable.
#
def get_timetable(begin, minutes, in_progress = 10):
end = begin + datetime.timedelta(minutes = minutes)
ip_end = begin + datetime.timedelta(minutes = in_progress)
ret = { }
for track in Tracks.keys():
items = [ ]
for item in Tracks[track]:
if (begin <= item.begin < end) or (ip_end < item.end < end) or \
(item.begin < begin and item.end > end):
items.append(copy.copy(item))
if items:
ret[track] = items
return ret
#
# Find out when the next session begins after the present time. This is
# inefficient, we could do this in the get_timetable() pass, but nobody
# will care...
#
def find_restart_time(begin):
if begin > final_time:
return None
earliest = final_time
for track in Tracks.keys():
for talk in Tracks[track]:
if (talk.begin > begin) and (talk.begin < earliest):
earliest = talk.begin
return earliest
#
# Which track is in the given room now (or soon)?
#
def track_in_room(room, time, lead = 60):
end = time + datetime.timedelta(minutes = lead)
for track in Tracks:
for item in Tracks[track]:
if (item.room == room) and \
((time <= item.begin < end) or (time < item.end < end) or \
(item.begin < time and item.end > end)):
return track
return None