diff --git a/app/models.py b/app/models.py
new file mode 100644
index 0000000..57a530e
--- /dev/null
+++ b/app/models.py
@@ -0,0 +1,99 @@
+from datetime import datetime, date, timedelta, timezone
+from caldav.objects import Event as CaldavEvent
+import dataclasses
+
+from icalendar import Event as IcEvent
+from icalendar import Calendar as Icalendar
+
+@dataclasses.dataclass
+class Event():
+ summary: str
+ dtstart: datetime
+ dtend: datetime
+ is_all_day: bool
+
+ @classmethod
+ def fromCalDavEvents(cls, caldav_events: [CaldavEvent]) -> list['Event']:
+
+ events = []
+
+ for event in caldav_events:
+ date_value = event.vobject_instance.vevent.dtstart.value
+ if isinstance(date_value, datetime):
+ dt_start = date_value
+ is_all_day = False
+ elif isinstance(date_value, date):
+ d_start = date_value
+ dt_start = datetime(d_start.year, d_start.month, d_start.day, tzinfo=datetime.now(timezone.utc).astimezone().tzinfo)
+ is_all_day = True
+ else:
+ raise Exception
+
+ date_value = event.vobject_instance.vevent.dtend.value
+ if isinstance(date_value, datetime):
+ dt_end = date_value
+ elif isinstance(date_value, date):
+ d_end = date_value
+ dt_end = datetime(d_end.year, d_end.month, d_end.day,tzinfo=datetime.now(timezone.utc).astimezone().tzinfo)
+ date_value = dt_end
+ else:
+ raise Exception
+
+ events.append(Event(
+ summary=event.vobject_instance.vevent.summary.value,
+ dtstart=dt_start,
+ dtend=dt_end,
+ is_all_day = is_all_day
+ ))
+ return events
+
+ @classmethod
+ def fromIcalendar(cls, icalendar: Icalendar) -> list['Event']:
+ events = []
+ for event in [e for e in icalendar.subcomponents if isinstance(e, IcEvent)]:
+ date_value = event['DTSTART'].dt
+ if isinstance(date_value, datetime):
+ dt_start = date_value
+ is_all_day = False
+ elif isinstance(date_value, date):
+ d_start = date_value
+ dt_start = datetime(d_start.year, d_start.month, d_start.day, tzinfo=datetime.now(timezone.utc).astimezone().tzinfo)
+ is_all_day = True
+ else:
+ raise Exception
+
+ date_value = event['DTEND'].dt if event.get('DTEND') else event['DTSTART'].dt
+ if isinstance(date_value, datetime):
+ dt_end = date_value
+ elif isinstance(date_value, date):
+ d_end = date_value
+ dt_end = datetime(d_end.year, d_end.month, d_end.day,tzinfo=datetime.now(timezone.utc).astimezone().tzinfo)
+ else:
+ raise Exception
+
+ events.append(Event(
+ summary=event['summary'],
+ dtstart=dt_start,
+ dtend=dt_end,
+ is_all_day = is_all_day
+ ))
+
+ return events
+
+ @property
+ def range_str(self) -> str:
+ start_time_str = self.dtstart.strftime('%-I')
+ end_time_str = self.dtend.strftime('%-I')
+
+ if not(self.dtstart.hour and self.dtend.hour):
+ return ""
+
+ if self.dtstart.minute: start_time_str += self.dtstart.strftime(':%M')
+ if self.dtend.minute: end_time_str += self.dtend.strftime(':%M')
+
+ if not ((self.dtstart.hour < 12 and self.dtend.hour < 12) or (self.dtstart.hour > 12 and self.dtend.hour > 12)):
+ start_time_str += self.dtstart.strftime("%p")
+
+ end_time_str += self.dtend.strftime("%p")
+
+ return f"{start_time_str}-{end_time_str}"
diff --git a/app/templates/dashboard.html b/app/templates/dashboard.html
index 0d1d556..bced635 100644
--- a/app/templates/dashboard.html
+++ b/app/templates/dashboard.html
@@ -18,19 +18,19 @@
- {% for day, event in days %}
+ {% for day, events in days %}
{{ day.strftime('%A') }}
- {% if event %}
+ {% for event in events %}
- {{ event.summary.value }}
- {% if event.dtstart.value.strftime('%H') != "00" %}
- {{ event.dtstart.value.strftime('%-I:%M %p') }}
{{ event.dtend.value.strftime('%-I:%M %p') }}
+ {{ event.summary }}
+ {% if not event.is_all_day %}
+ {{ event.range_str }}
{% endif %}
- {% endif %}
+ {% endfor %}
{% endfor %}
diff --git a/app/views.py b/app/views.py
index be5edcd..5249bd1 100644
--- a/app/views.py
+++ b/app/views.py
@@ -1,12 +1,13 @@
from app import app
-from datetime import datetime, timedelta
+from datetime import datetime, timedelta, timezone
import os
import caldav
import datetime
from icalendar import cal, Event
from flask import render_template
+from .models import Event
import requests
-url = os.getenv('caldav_url')
+caldav_url = os.getenv('caldav_url')
username = os.getenv('username')
password = os.getenv('password')
cal_id = os.getenv('cal_id')
@@ -17,42 +18,49 @@ def daterange(start_date, end_date):
yield datetime.datetime.date(start_date + timedelta(n))
@app.route('/')
-def hello_world():
- date_obj = datetime.datetime.now()
-
- start_of_week = date_obj - timedelta(days=date_obj.weekday()) # Monday
+def dashboard():
+ today = datetime.datetime.now(tz=datetime.datetime.now(timezone.utc).astimezone().tzinfo)
+ # today = datetime.datetime(2022,5,30, tzinfo=datetime.datetime.now(timezone.utc).astimezone().tzinfo)
+ start_of_week = today - timedelta(days=today.weekday()) # Monday
end_of_week = start_of_week + timedelta(days=7) # Sunday
- with caldav.DAVClient(url=url, username=username, password=password) as client:
+ events = []
+
+ for url in [
+ 'https://www.calendarlabs.com/ical-calendar/ics/76/US_Holidays.ics',
+ ]:
+ r = requests.get(url)
+ c = cal.Calendar.from_ical(r.content)
+
+ events += Event.fromIcalendar(c)
+
+ with caldav.DAVClient(url=caldav_url, username=username, password=password) as client:
my_principal = client.principal()
calendars = my_principal.calendars()
- calendar = my_principal.calendar(cal_id=cal_id)
- events_fetched = calendar.date_search(
- start=start_of_week, end=end_of_week, expand=False)
+ for id in [cal_id]:
+ calendar = my_principal.calendar(cal_id=id)
+ events += Event.fromCalDavEvents(calendar.date_search(
+ start=start_of_week, end=end_of_week, expand=False))
- events_fetched_by_date = {}
- for event in events_fetched:
- value = event.vobject_instance.vevent.dtstart.value
- if isinstance(value, datetime.datetime):
- events_fetched_by_date[datetime.datetime.date(value)] = event
- elif isinstance(value, datetime.date):
- events_fetched_by_date[value] = event
- else:
- raise Exception
+ for url in [
+ 'http://ical-cdn.teamsnap.com/team_schedule/5f1ddc9e-15b0-4912-84a2-11cc70e9e375.ics'
+ ]:
+ r = requests.get(url)
+ c = cal.Calendar.from_ical(r.content)
+
+ events += Event.fromIcalendar(c)
+
+ days = []
+ for single_date in daterange(start_of_week, end_of_week):
+ days_events = [e for e in events if (e.dtstart.date() <= single_date <= e.dtend.date())]
+ days.append((single_date, days_events))
- days = []
- for single_date in daterange(start_of_week, end_of_week):
- event = events_fetched_by_date.get(single_date)
- if event:
- days.append((single_date, event.vobject_instance.vevent))
- else:
- days.append((single_date,[]))
# breakpoint()
pass
# r = "
".join([event.vobject_instance.vevent.summary.value for event in events_fetched if event.vobject_instance.vevent.dtstart.value < datetime.now()])
- return render_template("dashboard.html", days=days, today=datetime.datetime.now())
+ return render_template("dashboard.html",
+ days=days,
+ today=today)
-if __name__ == '__main__':
- app.run(host='0.0.0.0', port=81)
\ No newline at end of file