From 8b9ce75959878388f2e54aaf06fd87defd2c0bf1 Mon Sep 17 00:00:00 2001 From: "Edgar P. Burkhart" Date: Thu, 27 Jan 2022 17:43:06 +0100 Subject: [PATCH] Updated design and backend --- saturn/__main__.py | 7 ++- saturn/calendar/__init__.py | 25 +++++---- saturn/calendar/event.py | 47 ++++++++++++++++ saturn/server/__init__.py | 7 +-- saturn/server/static/css/index.css | 50 +++++++++-------- saturn/server/static/css/main.css | 2 + saturn/server/templates/index.html | 87 +++++++++++++++++++----------- 7 files changed, 158 insertions(+), 67 deletions(-) create mode 100644 saturn/calendar/event.py diff --git a/saturn/__main__.py b/saturn/__main__.py index c2da513..9599342 100644 --- a/saturn/__main__.py +++ b/saturn/__main__.py @@ -1,6 +1,7 @@ import argparse import configparser import logging +import locale ## dev imports from pprint import pp import sys @@ -23,6 +24,8 @@ args = parser.parse_args() config = configparser.ConfigParser() config.read(args.config) +locale.setlocale(locale.LC_ALL, config.get('locale', 'locale', fallback=None)) + logging.basicConfig(level=config.get('logging', 'level', fallback='WARN')) log = logging.getLogger('saturn') @@ -30,7 +33,9 @@ log.info('Starting saturn') davclient = get_davclient(config['caldav']) -app = create_app(davclient) +app = create_app( + davclient, +) if __name__ == '__main__': app.run( diff --git a/saturn/calendar/__init__.py b/saturn/calendar/__init__.py index c2d4a1a..77e0cfd 100644 --- a/saturn/calendar/__init__.py +++ b/saturn/calendar/__init__.py @@ -1,6 +1,9 @@ +import re +from datetime import date, datetime, time + import caldav -from datetime import date, datetime +from .event import Event def get_davclient(config): @@ -10,6 +13,15 @@ def get_davclient(config): password=config.get('password', fallback=None), ) +def get_comparable_dt(event): + if type(event.dtstart.value) == date: + return datetime.combine( + event.dtstart.value, + time.min, + ).timestamp() + else: + return event.dtstart.value.timestamp() + def get_events(davclient): pri = davclient.principal() @@ -18,12 +30,7 @@ def get_events(davclient): for cal in pri.calendars(): events += [event.instance.vevent - for event in cal.date_search(start=date.today()) - if type(event.instance.vevent.dtstart.value) == datetime] - events_day += [event.instance.vevent - for event in cal.date_search(start=date.today()) - if type(event.instance.vevent.dtstart.value) != datetime] - events.sort(key=lambda event:event.dtstart.value) - events_day.sort(key=lambda event:event.dtstart.value) + for event in cal.date_search(start=date.today())] + events.sort(key=get_comparable_dt) - return events, events_day + return [Event(event) for event in events] diff --git a/saturn/calendar/event.py b/saturn/calendar/event.py new file mode 100644 index 0000000..036ae29 --- /dev/null +++ b/saturn/calendar/event.py @@ -0,0 +1,47 @@ +import re + + +class Event: + def __init__( + self, + vobject, + ): + for attr in [ + 'dtstart', + 'dtend', + 'summary', + 'description', + 'location', + 'rrule', + ]: + setattr(self, f'_{attr}', + getattr(getattr(vobject, attr, None), 'value', None)) + + @property + def dtstart(self): + return self._dtstart + + @property + def dtend(self): + return self._dtend + + @property + def summary(self): + return self._summary + + @property + def description(self): + return self._description + + @property + def location(self): + return self._location + + @property + def freq(self): + if self._rrule is None: return None + return re.search( + r'FREQ=([A-Z]+?);', + self._rrule, + ).group(1) + diff --git a/saturn/server/__init__.py b/saturn/server/__init__.py index 7c3e716..da8d493 100644 --- a/saturn/server/__init__.py +++ b/saturn/server/__init__.py @@ -4,17 +4,18 @@ from datetime import date, datetime from ..calendar import get_events -def create_app(davclient): +def create_app( + davclient, + ): app = flask.Flask(__name__) @app.route('/') def home(): - events, events_day = get_events(davclient) + events = get_events(davclient) return flask.render_template( 'index.html', events = events, - events_day = events_day, ) return app diff --git a/saturn/server/static/css/index.css b/saturn/server/static/css/index.css index 19bd8f8..2b49849 100644 --- a/saturn/server/static/css/index.css +++ b/saturn/server/static/css/index.css @@ -1,7 +1,6 @@ body { display: grid; grid-template-columns: - 1fr 1fr; grid-template-rows: auto @@ -22,13 +21,10 @@ body > * { margin: 1rem; display: grid; grid-template-columns: - 1fr + 6rem 1fr; - grid-template-rows: - auto - auto - auto; - gap: .5rem; + row-gap: .5rem; + column-gap: 1rem; background: var(--ui-01); padding: 1rem; } @@ -39,23 +35,33 @@ body > * { grid-column: 1 / span 2; } .event > .date { - grid-row: 2; + grid-column: 1; font-size: 1.1rem; + display: grid; + grid-template-columns: auto; + gap: 1rem; + text-align: center; } -.event > .start-date { - grid-column: 1; - text-align: right; +.event > .date > div { + display: grid; + grid-template-columns: auto; } -.event > .end-date { +.date .day { + font-size: 3em; +} +.date .time { + font-size: 1.5em; +} +.event .end-date, +.event .other { + color: var(--text-02); +} +.event > .info { grid-column: 2; -} -.event > .description { - grid-column: 1; -} -.event > .other { - grid-column: 2; -} -.event > .description, -.event > .other > * { - padding-top: 1rem; + display: grid; + grid-template-columns: 1fr; + grid-template-rows: + 1fr + auto; + gap: 1rem; } diff --git a/saturn/server/static/css/main.css b/saturn/server/static/css/main.css index a6d63cf..713e80a 100644 --- a/saturn/server/static/css/main.css +++ b/saturn/server/static/css/main.css @@ -2,8 +2,10 @@ --ui-background: white; --ui-01: var(--gray-10); --text-01: var(--gray-100); + --text-02: var(--gray-70); --gray-10: #f4f4f4; + --gray-70: #525252; --gray-100: #161616; } diff --git a/saturn/server/templates/index.html b/saturn/server/templates/index.html index 38362a6..ac5d43f 100644 --- a/saturn/server/templates/index.html +++ b/saturn/server/templates/index.html @@ -3,6 +3,7 @@ {% block style %} {{ super() }} + {% endblock %} {% block body %} @@ -11,39 +12,61 @@
{% for event in events %}
-
{{ event.summary.value }}
-
{{ event.dtstart.value.isoformat() }}
-
{{ event.dtend.value.isoformat() }}
- {% if event.description %} -
{{ event.description.value }}
- {% endif %} -
- {% if event.location %} -
{{ event.location.value }}
- {% endif %} - {% if event.rrule %} -
{{ event.rrule.value }}
- {% endif %} +
{{ event.summary }}
+
+
+ + {{ event.dtstart.strftime('%A').capitalize() }} + + + {{ event.dtstart.strftime('%d') }} + + + {{ event.dtstart.strftime('%B').capitalize() }} + + + {{ event.dtstart.strftime('%H:%M') }} + +
+
+ {% if not event.dtend.date or event.dtend.date() != event.dtstart.date() %} + + {{ event.dtend.strftime('%A').capitalize() }} + + + {{ event.dtend.strftime('%d') }} + + {% endif %} + {% if event.dtend.month != event.dtstart.month %} + + {{ event.dtend.strftime('%B').capitalize() }} + + {% endif %} + + {{ event.dtend.strftime('%H:%M') }} + +
-
- {% endfor %} -
-
- {% for event in events_day %} -
-
{{ event.summary.value }}
-
{{ event.dtstart.value }}
-
{{ event.dtend.value }}
- {% if event.description %} -
{{ event.description.value }}
- {% endif %} -
- {% if event.location %} -
{{ event.location.value }}
- {% endif %} - {% if event.rrule %} -
{{ event.rrule.value }}
- {% endif %} +
+
+ {% if event.description %} + {{ event.description }} + {% endif %} +
+
+ {% if event.location %} +
+ + {{ event.location }} +
+ {% endif %} + {% if event.freq %} +
+ + {{ event.freq}} +
+ {% endif %} +
{% endfor %}