2022-08-14 17:51:51 +00:00
|
|
|
from datetime import datetime, timedelta, timezone
|
|
|
|
import urllib.request
|
|
|
|
|
|
|
|
from icalendar import Calendar, Event, vCalAddress, vText
|
|
|
|
from PIL import Image, ImageDraw, ImageFont
|
|
|
|
import pytz
|
|
|
|
|
|
|
|
class IcalModule:
|
|
|
|
|
2022-08-14 17:55:12 +00:00
|
|
|
def __init__(self, config):
|
|
|
|
self.cals = config.cals
|
2022-08-14 17:51:51 +00:00
|
|
|
|
|
|
|
def draw_module(self, config, width, height, line_height=19):
|
|
|
|
now = datetime.now(tz=pytz.timezone('Europe/Paris'))
|
|
|
|
toofar = now + timedelta(weeks=1)
|
|
|
|
|
|
|
|
events = []
|
|
|
|
for cal in self.cals:
|
|
|
|
with urllib.request.urlopen(cal) as c:
|
|
|
|
ecal = Calendar.from_ical(c.read())
|
|
|
|
for component in ecal.walk():
|
|
|
|
if component.name == "VEVENT":
|
|
|
|
if component.decoded("DTEND") < now:
|
|
|
|
continue
|
|
|
|
if component.decoded("DTSTART") > toofar:
|
|
|
|
continue
|
|
|
|
|
|
|
|
events.append({
|
|
|
|
"summary": component.get("SUMMARY"),
|
|
|
|
"start": component.decoded("DTSTART"),
|
|
|
|
"end": component.decoded("DTEND"),
|
|
|
|
})
|
|
|
|
|
|
|
|
# Sort events
|
|
|
|
events.sort(key=lambda e: e["start"])
|
|
|
|
|
|
|
|
image = Image.new('RGB', (width, height), '#fff')
|
|
|
|
draw = ImageDraw.Draw(image)
|
|
|
|
|
|
|
|
fnt_R = ImageFont.truetype(config.fnt_R_path, int(line_height*0.7))
|
|
|
|
fnt_B = ImageFont.truetype(config.fnt_RB_path, int(line_height*0.7))
|
|
|
|
|
|
|
|
last_evt = None
|
|
|
|
align = 0
|
|
|
|
for evt in events:
|
|
|
|
if last_evt is None or last_evt["start"].astimezone(pytz.timezone('Europe/Paris')).day != evt["start"].astimezone(pytz.timezone('Europe/Paris')).day:
|
|
|
|
draw.text(
|
|
|
|
(width / 2, align),
|
|
|
|
evt["start"].astimezone(pytz.timezone('Europe/Paris')).strftime("%a %d %B"),
|
|
|
|
fill="black", anchor="mt", font=fnt_B
|
|
|
|
)
|
|
|
|
align += line_height
|
|
|
|
draw.rectangle((0, align-4, width, align-4), fill="black")
|
|
|
|
|
|
|
|
draw.text(
|
|
|
|
(2, align),
|
|
|
|
evt["start"].astimezone(pytz.timezone('Europe/Paris')).strftime("%H:%M") + " " + evt["summary"],
|
|
|
|
fill="black", anchor="lt", font=fnt_R
|
|
|
|
)
|
|
|
|
|
|
|
|
align += line_height
|
|
|
|
last_evt = evt
|
|
|
|
|
|
|
|
return image
|