~fabrixxm/confy

ref: 3711232f069768031fd703392d6fc7635fa708da confy/src/remotes/ics.py -rw-r--r-- 4.5 KiB
3711232ffabrixxm Fix typo 4 months ago
                                                                                
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
# ics.py
#
# Copyright 2020 Fabio
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import time
import html
from datetime import datetime, timedelta, timezone
from icalendar import Calendar, Event

from .exceptions import InvalidFormatException
from .. import local
from ..models import Meta

def utc_to_local(utc_dt):
    """remove timezone info from date object

    Calendar items comes with timezone info. We could keep this info and allow
    users to select wich timezone they want to see. Atm, all code works without
    timezones (and sqlite3 driver spit errors if we try to save a timezone-aware datetime).
    We assume that this thing will be used "on premise", so every date/time will
    be in conference location tz.
    You have to live with this until a better option come up.
    I hate timezones and datetime handling.
    """
    return utc_dt.replace(tzinfo=None)


def import_ics(content:str, url:str):
    cal = Calendar.from_ical(content)

    _db = local.getDb()

    meta_title = None
    meta_end = datetime(1970,1,1,0,0,0)
    meta_start = datetime(3100,12,12,23,59,59)

    for c in cal.walk():
        if c.name == "VCALENDAR":
            meta_title = c.get('X-WR-CALNAME')

        if c.name == "VEVENT":
            fulltextsearch = []
            eventid = c['UID']
            if c.get('DTSTART'):
                start = utc_to_local(c['DTSTART'].dt)
            else:
                start = utc_to_local(c['DTSTAMP'].dt)
            if c.get('DURATION'):
                end = start + c['DURATION'].dt
            elif c.get('DTEND'):
                end = utc_to_local(c['DTEND'].dt)
            else:
                end = start + timedelta(hours=1)
            evtdate = start.date()
            room = c.get('LOCATION')
            slug = None
            title = c.get('SUMMARY', "")
            subtitle = None
            track = None
            evtype = None
            abstract = None
            description = c.get('DESCRIPTION', "")

            if title == "" and description == "":
                title = "Untitled event"
            if title == "" and description != "":
                title = description[:20]
                if len(description) > 20:
                    title = title + "…"

            if room:
                room = html.unescape(room)
            if room == "":
                room = None

            if start < meta_start:
                meta_start = start
            if end > meta_end:
                meta_end = end

            fulltextsearch += [ s for s in [title, subtitle, abstract, description, room, track] if s is not None ]

            links = []
            _url = c.get('URL')
            if _url:
                links.append((eventid, _url, _url))

            _db.execute("""INSERT OR REPLACE INTO events
                                (id, date, start, end, room, slug, title, subtitle, track, type, abstract, description, starred)
                                VALUES (?,?,?,?,?,?,?,?,?,?,?,?, (SELECT starred FROM events WHERE id=?))""",
                                (eventid, evtdate, start, end, room, slug, title, subtitle, track, evtype, abstract, description, eventid))
            #_db.executemany("INSERT OR REPLACE INTO persons (id, name) VALUES (?, ?)", persons)
            #_db.executemany("""INSERT OR REPLACE INTO event_person (event_id, person_id)
            #                    VALUES (?, ?) ON CONFLICT DO NOTHING""",
            #                    [ (eventid, p[0]) for p in persons ])
            _db.executemany("""INSERT OR REPLACE INTO links
                                (event_id, href, name) VALUES (?,?,?)""", links)
            fulltextsearchstr = ' '.join(fulltextsearch)
            _db.execute("""INSERT OR REPLACE INTO fts_event (event_id, text) VALUES (?, ?)""", (eventid, fulltextsearchstr))
    _db.commit()

    with Meta() as m:
        m.url = url
        m.title = meta_title
        m.last_update = time.time() # timestamp
        m.start = meta_start.date()
        m.end = meta_end.date()