First attempt
This commit is contained in:
commit
89677fbeee
22 changed files with 3461 additions and 0 deletions
119
voc/webcal2.py
Normal file
119
voc/webcal2.py
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
import re
|
||||
import icalendar
|
||||
import requests
|
||||
|
||||
from voc import GenericConference
|
||||
from voc.event import Event, EventSourceInterface
|
||||
from voc.schedule import Schedule, ScheduleException
|
||||
from voc.tools import format_duration, gen_person_uuid, gen_uuid
|
||||
|
||||
|
||||
class WebcalConference2(GenericConference, EventSourceInterface):
|
||||
def __init__(self, **args):
|
||||
GenericConference.__init__(self, **args)
|
||||
|
||||
def schedule(self, template: Schedule):
|
||||
if not self.schedule_url or self.schedule_url == 'TBD':
|
||||
raise ScheduleException(' has no schedule url yet – ignoring')
|
||||
|
||||
url = re.sub(r'^webcal', 'http', self.schedule_url)
|
||||
r = requests.get(url, timeout=10)
|
||||
if r.status_code != 200:
|
||||
raise ScheduleException(f' Failed to retrieve iCal feed: Error ({r.status_code})')
|
||||
cal = icalendar.Calendar.from_ical(r.text)
|
||||
|
||||
schedule = template.copy(self['name']) or Schedule(conference=self)
|
||||
|
||||
for e in cal.walk('vevent'):
|
||||
try:
|
||||
event = Event(convert_to_dict(e, self), origin=self)
|
||||
schedule.add_event(event)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
return schedule
|
||||
|
||||
|
||||
def convert_to_dict(e: icalendar.Event, context: WebcalConference2) -> dict:
|
||||
# title, subtitle, event_type = re.match(r"^(.+?)(?:( ?[:–] .+?))?(?: \((.+?)\))?$", e.name).groups()
|
||||
track, = [ str(c) for c in e.get('categories').cats] or [None]
|
||||
begin = e['dtstart'].dt
|
||||
end = e['dtend'].dt
|
||||
duration = end - begin
|
||||
|
||||
return { k: (v if isinstance(v, list) or v is None else str(v)) for k, v in {
|
||||
"guid": gen_uuid(e['uid']),
|
||||
"id": e['event-id'],
|
||||
"title": e.get('summary'),
|
||||
"subtitle": '',
|
||||
"abstract": e['description'],
|
||||
"description": '', # empty description for pretalx importer (temporary workaround)
|
||||
"date": begin.isoformat(),
|
||||
"start": begin.strftime("%H:%M"),
|
||||
"duration": format_duration(duration),
|
||||
"room": track, #context['name'],
|
||||
"persons": [{
|
||||
**p,
|
||||
"id": 0
|
||||
} for p in extract_persons(e)],
|
||||
"track": track,
|
||||
"language": 'de',
|
||||
"type": 'Session' or 'Other',
|
||||
"url": e.get('url', None),
|
||||
}.items() }
|
||||
|
||||
def extract_persons(e: icalendar.Event) -> list:
|
||||
person_str = str(e.get('location', '')).replace(' und ', '; ').strip()
|
||||
print(person_str)
|
||||
# persons = re.split(r'\s*[,;/]\s*', person_str)
|
||||
persons = re.split(r'[,;/](?![^()]*\))', person_str)
|
||||
|
||||
if len(persons) == 0:
|
||||
return []
|
||||
pattern = r'([^()]+)(?:\((\w{2,3}\s+)?([^)]*)\))'
|
||||
|
||||
result = []
|
||||
for p in persons:
|
||||
# p is either "name (org)" or or "name (org role)" or "name (name@org.tld)"
|
||||
match = re.match(pattern, p)
|
||||
if match:
|
||||
name, org, role = match.groups()
|
||||
if role and '@' in role:
|
||||
match = re.search(r'@(.+)(\.de)?$', role)
|
||||
org = match.group(1)
|
||||
result.append({
|
||||
"name": name.strip(),
|
||||
"org": org.strip(),
|
||||
"email": role.strip(),
|
||||
"guid": gen_person_uuid(role)
|
||||
})
|
||||
else:
|
||||
if not org:
|
||||
if len(role) <= 3:
|
||||
org = role
|
||||
role = None
|
||||
else:
|
||||
# try catch `Distribution Cordinator, ZER` and split org
|
||||
m = re.match(r'^(.+?), (\w{2,3})$', role)
|
||||
if m:
|
||||
org = m.group(2)
|
||||
role = m.group(1)
|
||||
|
||||
if name:
|
||||
result.append({
|
||||
"name": name.strip(),
|
||||
"org": org.strip() if org else None,
|
||||
"role": role.strip() if role else None,
|
||||
})
|
||||
elif p:
|
||||
result.append({
|
||||
"name": p.strip(),
|
||||
})
|
||||
|
||||
print(result)
|
||||
print()
|
||||
return result
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
WebcalConference()
|
||||
Loading…
Add table
Add a link
Reference in a new issue