aonestar
.public
Tables
(current)
Columns
Constraints
Relationships
Orphan Tables
Anomalies
Routines
fn_parse_ics
Parameters
Name
Type
Mode
p_ics
text
IN
Definition
import json, datetime text = p_ics or '' text = text.replace('\r\n', '\n').replace('\r', '\n') # RFC5545 line unfolding: a leading space/tab continues the previous line. lines = [] for line in text.split('\n'): if line[:1] in (' ', '\t'): if lines: lines[-1] += line[1:] else: lines.append(line) def unescape(s): return (s.replace('\\n', ' ').replace('\\N', ' ') .replace('\\,', ',').replace('\\;', ';').replace('\\\\', '\\')).strip() def parse_dt(value): # returns (date_str 'YYYY-MM-DD', time_str 'HH:MM:SS' or None, all_day bool) v = value.strip() if 'T' in v: d, t = v.split('T', 1) t = t.rstrip('Z') date_s = '%s-%s-%s' % (d[0:4], d[4:6], d[6:8]) hh = t[0:2] if len(t) >= 2 else '00' mm = t[2:4] if len(t) >= 4 else '00' ss = t[4:6] if len(t) >= 6 else '00' return date_s, '%s:%s:%s' % (hh, mm, ss), False else: date_s = '%s-%s-%s' % (v[0:4], v[4:6], v[6:8]) return date_s, None, True events, cur = [], None for ln in lines: up = ln.upper() if up.startswith('BEGIN:VEVENT'): cur = {} elif up.startswith('END:VEVENT'): if cur is not None: events.append(cur) cur = None elif cur is not None and ':' in ln: name_part, value = ln.split(':', 1) key = name_part.split(';', 1)[0].upper() if key == 'UID': cur['external_uid'] = value.strip() elif key == 'SUMMARY': cur['name'] = unescape(value) elif key == 'DTSTART': ds, ts, allday = parse_dt(value) cur['start_date'], cur['start_time'], cur['all_day'] = ds, ts, allday elif key == 'DTEND': ds, ts, _ = parse_dt(value) cur['_end_raw'], cur['end_time'] = ds, ts out = [] for e in events: if not e.get('start_date'): continue all_day = e.get('all_day', True) end_date = e.get('_end_raw') if end_date and all_day: try: y, m, d = map(int, end_date.split('-')) end_date = (datetime.date(y, m, d) - datetime.timedelta(days=1)).isoformat() except Exception: pass if end_date == e.get('start_date'): end_date = None out.append({ 'external_uid': e.get('external_uid'), 'name': e.get('name') or '(no title)', 'start_date': e.get('start_date'), 'end_date': end_date, 'all_day': all_day, 'start_time': None if all_day else e.get('start_time'), 'end_time': None if all_day else e.get('end_time'), }) return json.dumps(out)