From 41e3ff190c1bddc02019933806973cef71993941 Mon Sep 17 00:00:00 2001 From: Xenror Date: Sat, 11 Sep 2021 18:22:33 +0200 Subject: [PATCH 01/10] Reading config from config-file now --- config | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 config diff --git a/config b/config new file mode 100644 index 0000000..b49e71d --- /dev/null +++ b/config @@ -0,0 +1,6 @@ +server:https://www.kuhl-mann.de/nextcloud/remote.php/dav +user:Justus +password:Alphabeth1forB2; +datafile: +birthdays:Geburtstage von Kontakten +calendars: \ No newline at end of file From 895036ae0c505199ce3c5ef1fc2c8959bf7df5bd Mon Sep 17 00:00:00 2001 From: Xenror Date: Sat, 11 Sep 2021 19:00:50 +0200 Subject: [PATCH 02/10] Selection of calendars to download now possible --- README.md | 3 ++ TODO.md | 9 ++++ calDAVconnector.py | 111 ++++++++++++++++++++++++++------------------- config | 2 +- 4 files changed, 78 insertions(+), 47 deletions(-) create mode 100644 TODO.md diff --git a/README.md b/README.md index e2789f9..d5cf749 100644 --- a/README.md +++ b/README.md @@ -1 +1,4 @@ # e-inkCal + +this small script is supposed to be run on a raspberry pi with an SPI e-ink display attached to it. +it will then display a weekcalendar on the e-ink display, which is fetched from a calDAV resource. diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..4fa1c23 --- /dev/null +++ b/TODO.md @@ -0,0 +1,9 @@ +ToDo: + +1. catching exceptions for caldav unauthorized +2. options: + -w show week calendar + -m show month calendar + +3. include birthdays from another calendar +4. make other views, e.g. month, day, year... diff --git a/calDAVconnector.py b/calDAVconnector.py index 070a7f3..1349dec 100644 --- a/calDAVconnector.py +++ b/calDAVconnector.py @@ -11,40 +11,44 @@ sys.path.insert(0, './caldav') import caldav from caldav.lib.error import AuthorizationError -#look for commandline args - -import getopt - - -inputfile = '' -outputfile = '' -try: - opts, args = getopt.getopt(sys.argv[1:],"h:i:o",["ifile=","ofile="]) -except getopt.GetoptError: - print('test.py -i -o ') - sys.exit(2) -for opt, arg in opts: - if opt == '-h': - print ('test.py -i -o ') - sys.exit() - elif opt in ("-i", "--ifile"): - inputfile = arg - elif opt in ("-o", "--ofile"): - outputfile = arg -print ('Input file is "', inputfile) -print ('Output file is "', outputfile) - +caldav_url = '' +username = '' +password = '' +datafile = '' +selected_cals = [] +#open config file, load configs +configfile = open("./config", "r") +conf = configfile.readlines() +print(conf) +for l in conf: + l = l.strip() + if(l.startswith("server")): + caldav_url = l[7:] + elif(l.startswith("user")): + username = l[5:] + elif(l.startswith("password")): + password = l[9:] + elif(l.startswith("birthdays")): + birthdaycal = l[10:] + elif(l.startswith("datafile")): + datafile = l[9:] + elif(l.startswith("calendars")): + selected_cals = l[10:].split(";") +print(selected_cals) +if(len(caldav_url) == 0): + print("Please provide a calDAV link") +if(len(username) == 0): + print("Please provide a username") #calDAV setup -caldav_url = 'https://www.kuhl-mann.de/nextcloud/remote.php/dav' -username = 'Justus' -password = 'Alphabeth1forB2;' + timezone = [2,0] timeout = 5 -f = open("./calendarlib.p") +if not (len(datafile) == 0): + f = open(datafile) server_reached = True client_established = True @@ -58,7 +62,6 @@ except (requests.ConnectionError, requests.Timeout) as exception: else: print("found server") - try: client = caldav.DAVClient(url=caldav_url, username=username, password=password) except (Exception) as ex: @@ -67,8 +70,19 @@ except (Exception) as ex: if(server_reached and client_established): print("Successfully connected to server, starting to download calendars...") my_principal = client.principal() - calendars = my_principal.calendars() - + calendars_fetched = my_principal.calendars() + calendars = [] + if not (len(selected_cals) == 0 or len(selected_cals[0]) == 0): + for c in calendars_fetched: + if c.name in selected_cals: + calendars.append(c) + else: + calendars = calendars_fetched + print("selected calendars:") + for c in calendars: + print(c.name) + + time_events = [] day_events = [] birthdays = [] @@ -105,24 +119,29 @@ if(server_reached and client_established): "SUMMARY":str(event.vobject_instance.vevent.summary.value), "CALENDAR":c.name }) - for event in day_events: - if event["CALENDAR"] == "Geburtstage von Kontakten": - pieces = event["SUMMARY"].split(" ") - age = date.today().year - int(pieces[2][2:-1]) - event["SUMMARY"] = pieces[1]+" "+pieces[0][:-1]+" ("+str(age)+")" - birthdays.append(event) - day_events.remove(event) + if(not (len(birthdaycal) == 0)): + for event in day_events: + if event["CALENDAR"] == birthdaycal: + pieces = event["SUMMARY"].split(" ") + age = date.today().year - int(pieces[2][2:-1]) + event["SUMMARY"] = pieces[1]+" "+pieces[0][:-1]+" ("+str(age)+")" + birthdays.append(event) + day_events.remove(event) print("Download complete") - calendarlib = {"DAY_EVENTS":day_events,"TIME_EVENTS":time_events,"BIRTHDAYS":birthdays} - #f = open("./calendarlib.p") - p.dump( calendarlib, open( "calendarlib.p", "wb" )) - f.close() + if(len(datafile)!= 0): + calendarlib = {"DAY_EVENTS":day_events,"TIME_EVENTS":time_events,"BIRTHDAYS":birthdays} + p.dump( calendarlib, open( "calendarlib.p", "wb" )) + f.close() else: - print("Loading caldata from last time...") - calendarlib = p.load(open("calendarlib.p","rb")) - time_events = calendarlib["TIME_EVENTS"] - day_events = calendarlib["DAY_EVENTS"] - birthdays = calendarlib["BIRTHDAYS"] + if(len(datafile)!= 0): + print("Loading caldata from last time...") + calendarlib = p.load(open("calendarlib.p","rb")) + time_events = calendarlib["TIME_EVENTS"] + day_events = calendarlib["DAY_EVENTS"] + birthdays = calendarlib["BIRTHDAYS"] + else: + print("No data available!") + exit() #get principal file diff --git a/config b/config index b49e71d..44f122d 100644 --- a/config +++ b/config @@ -1,6 +1,6 @@ server:https://www.kuhl-mann.de/nextcloud/remote.php/dav user:Justus password:Alphabeth1forB2; -datafile: +datafile:calendarlib.p birthdays:Geburtstage von Kontakten calendars: \ No newline at end of file From 236cfd35c4d5aae1825fdb2c59ab4801c26e82f0 Mon Sep 17 00:00:00 2001 From: Xenror Date: Sun, 12 Sep 2021 14:38:31 +0200 Subject: [PATCH 03/10] added more options to be read from config --- calDAVconnector.py | 2 +- calendarlib.p | Bin 0 -> 271 bytes canvas.bmp | Bin 0 -> 48062 bytes 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 calendarlib.p create mode 100644 canvas.bmp diff --git a/calDAVconnector.py b/calDAVconnector.py index 1349dec..46e5c5a 100644 --- a/calDAVconnector.py +++ b/calDAVconnector.py @@ -135,7 +135,7 @@ if(server_reached and client_established): else: if(len(datafile)!= 0): print("Loading caldata from last time...") - calendarlib = p.load(open("calendarlib.p","rb")) + calendarlib = p.load(open(datafile,"rb")) time_events = calendarlib["TIME_EVENTS"] day_events = calendarlib["DAY_EVENTS"] birthdays = calendarlib["BIRTHDAYS"] diff --git a/calendarlib.p b/calendarlib.p new file mode 100644 index 0000000000000000000000000000000000000000..f1b87f7225db0fa469c34f02f3bafa75970a6dda GIT binary patch literal 271 zcmZo*naaY*00y;FGERCX^mRq>H9$&OgF_sHLZ$($aDpab5u^wXN#9+v<12JHD6wC7C z3jI;+1E`}v02}tM6jT@@as?(bc8kZ@FTsvmtHs-~M*>%A30$Rv;<=Jx2f;N<;7A;|H0;C{Uc<&6tfr*$OfRM*GKhm>-8AOa7=^6&^NV9zvT7vl=!3Pe$@W$-yAF08w+eixMyfC19u$ zFl2C*lwgMq0`CnV9VK~=YnFhXGW``el8QKf06t3M3e+K27*{wKwI@W8hJ6Vj1p5+P z-v!~oM9dFB2<8Xo2M7nu4}5lz;QXp6BkU@UAAk=WKOSQI2m&HS%}Zpg!v!SR(J28# z#@Z{cSprASfVB)xS9d|F8Tv7fd0UHP7n^I;$u7x z4#VgE=Gxx9Q?=hHo|S-MyUDpA#ty`=Lcd&}h+H9876a8AKQOK=Rxt-LuB>R_(x8O= z2uQ#PO2F7H0YiozM1mcN0TQiDzngc!H&FK3=Au=5pC$U-a!46}VC-5{mHqx4_VqaoK5B4S4msrt&eF^p@GzRc{9FP*F&zC$Q z_mSBerf8d%7$m|&~_rW#GndJ}65A+9M0PhVT8BCTi4k891eFltC z=nwPGCE!VGpD9DavT)*6$ zJ9^1IkUI80`Zq=Nv zi){PJFA(E{bl>^9u+Jv}qfsOV=PKMQ(vIu(>BW7W;gcdU?n&@R){&-hHPrP@h5oox zJLP+vec873-C$?s`Eh6J&p__WE=z9>bP`@F$-#>3;9OOXF}!-}Tp6ubj!_9$)5S>45tb-B4xb`Tt>3jrMcQ#Dthl@{9~Fw>3HzHDc$V-RR#9A?d+tyj4PK#kFh9t^ zU^uLZ;>u{<*b2pPlB`HO?*35gaJFAMFA^gatF3ps<8kpAw}oQpj4SuQLNQXq!8uO% zO|cjf{E;4}Ty1#gZE-%=0wfk}a0<|+!#{-0M#Suhd$e6=Xu0RpP zRq`xc!kb$M0IN4|mw^E<{4sv-AimEMII`Tm0XP)jHEAQG^tS-E>c{wfWN3%Q0Om*a z#wd$bDq(&AIt+%jD!RX`b`ulVz_!j{|z3%Tk!*WDy*yU8A!OkD?oPAUk(Up*48A& zu$Kode5mlyinxL&(t8}6YVT(r5+he=nq$!4Ul_&2h#H#8Kg^uvc9<1~OUoF?8P9V1 zO=a?9vQ@(l#jG$f%w|=-*UVXtG1*5LrxmW0pB6RSus&LdpDV_}-b9pZCPs?zD^&Tu z%r4#($4JpV3fpU(mX8{(@Y6=w&ru2`+5P>OFSPCrab1sfEe_1{#YefOEkE$ehGpvp z+roaTA6oL->iLUC{LN9S& zp&g<83WX{RW5i1_UZe`qGfl2Y*iDR9v{9dHuw^3eWL3OmJQrIUmEDG66vO8|=pW|{ z5Y4ytlR Date: Sun, 12 Sep 2021 20:43:53 +0200 Subject: [PATCH 04/10] time events longer than a day now displayed, some more controll in config --- calDAVconnector.py | 83 ++++++++++++++++++++++++++++----------------- calendarlib.p | Bin 271 -> 0 bytes canvas.bmp | Bin 48062 -> 0 bytes config | 5 ++- 4 files changed, 55 insertions(+), 33 deletions(-) delete mode 100644 calendarlib.p delete mode 100644 canvas.bmp diff --git a/calDAVconnector.py b/calDAVconnector.py index 46e5c5a..48c1f57 100644 --- a/calDAVconnector.py +++ b/calDAVconnector.py @@ -1,22 +1,21 @@ -from datetime import datetime -from datetime import date -from datetime import timedelta +from datetime import datetime, date, time, timezone, timedelta from PIL import Image,ImageDraw,ImageFont import pickle as p import requests import sys -import getopt sys.path.insert(0, './caldav') import caldav from caldav.lib.error import AuthorizationError - caldav_url = '' username = '' password = '' datafile = '' selected_cals = [] +language="EN" +weekday_l_key = "FULL" +draw_date = False #open config file, load configs configfile = open("./config", "r") conf = configfile.readlines() @@ -35,7 +34,17 @@ for l in conf: datafile = l[9:] elif(l.startswith("calendars")): selected_cals = l[10:].split(";") -print(selected_cals) + elif(l.startswith("language")): + language = l[9:] + elif(l.startswith("weekday_format")): + weekday_l_key = l[15:] + elif(l.startswith("draw_date")): + k = l[10:] + trueish = ["true","TRUE","1","True","T"] + draw_date = (k in trueish) + +#print(selected_cals) +#look if server and user are set if(len(caldav_url) == 0): print("Please provide a calDAV link") if(len(username) == 0): @@ -43,8 +52,6 @@ if(len(username) == 0): #calDAV setup -timezone = [2,0] - timeout = 5 if not (len(datafile) == 0): @@ -67,7 +74,11 @@ try: except (Exception) as ex: client_established = False +#check in which time zone we are +tz = timedelta(minutes = round((datetime.now()-datetime.utcnow()).seconds/60)) + if(server_reached and client_established): + #if server is available, download new information from server print("Successfully connected to server, starting to download calendars...") my_principal = client.principal() calendars_fetched = my_principal.calendars() @@ -82,43 +93,47 @@ if(server_reached and client_established): for c in calendars: print(c.name) - + time_events = [] day_events = [] birthdays = [] + #go through all calendars to look for events for c in calendars: current_calendar = my_principal.calendar(name=c.name) events_fetched = current_calendar.date_search( start=datetime.today()-timedelta(days = datetime.today().weekday()), end=datetime.today()+timedelta(days = 6-datetime.today().weekday()), expand=True) - if len(events_fetched)> 0: for event in events_fetched: event_start_str = str(event.vobject_instance.vevent.dtstart)[10:-1] event_end_str = str(event.vobject_instance.vevent.dtend)[8:-1] + print(event.vobject_instance.vevent) if(event_start_str.startswith("VALUE")): + #if it is an event over a whole day, sort it into the day events day_events.append({ "DATE":date(int(event_start_str.split("}")[1].split("-")[0]),int(event_start_str.split("}")[1].split("-")[1]),int(event_start_str.split("}")[1].split("-")[2])), "SUMMARY":str(event.vobject_instance.vevent.summary.value), "CALENDAR":c.name }) else: + #otherwise it has to be a time event sd = event_start_str.split(" ")[0] st = event_start_str.split(" ")[1] - sh = int(st.split(":")[0])+timezone[0]+int(st.split(":")[2][2:4]) - sm = int(st.split(":")[1])+timezone[1]+int(st.split(":")[3]) + sh = int(st.split(":")[0])+int(st.split(":")[2][2:4]) + sm = int(st.split(":")[1])+int(st.split(":")[3]) ss = int(st.split(":")[2][0:1]) ed = event_end_str.split(" ")[0] et = event_end_str.split(" ")[1] - eh = int(et.split(":")[0])+timezone[0]+int(st.split(":")[2][2:4]) - em = int(et.split(":")[1])+timezone[1]+int(et.split(":")[3]) + eh = int(et.split(":")[0])+int(st.split(":")[2][2:4]) + em = int(et.split(":")[1])+int(et.split(":")[3]) es = int(et.split(":")[2][0:1]) time_events.append({ - "START":datetime(int(sd.split("-")[0]),int(sd.split("-")[1]),int(sd.split("-")[2]), hour = sh, minute = sm, second = ss), - "END":datetime(int(ed.split("-")[0]),int(ed.split("-")[1]),int(ed.split("-")[2]), hour = eh, minute = em, second = es), + "START":datetime(int(sd.split("-")[0]),int(sd.split("-")[1]),int(sd.split("-")[2]), hour = sh, minute = sm, second = ss)+tz, + "END":datetime(int(ed.split("-")[0]),int(ed.split("-")[1]),int(ed.split("-")[2]), hour = eh, minute = em, second = es)+tz, "SUMMARY":str(event.vobject_instance.vevent.summary.value), "CALENDAR":c.name }) + #if the user wants one calendar to be treated as a birthday calendar, these are sorted into an extra library if(not (len(birthdaycal) == 0)): for event in day_events: if event["CALENDAR"] == birthdaycal: @@ -128,11 +143,13 @@ if(server_reached and client_established): birthdays.append(event) day_events.remove(event) print("Download complete") + #back up the data received to a local copy so that it can be displayed if needed if(len(datafile)!= 0): calendarlib = {"DAY_EVENTS":day_events,"TIME_EVENTS":time_events,"BIRTHDAYS":birthdays} p.dump( calendarlib, open( "calendarlib.p", "wb" )) f.close() else: + #if the server is not available, instead load information from datafile if(len(datafile)!= 0): print("Loading caldata from last time...") calendarlib = p.load(open(datafile,"rb")) @@ -143,9 +160,6 @@ else: print("No data available!") exit() - -#get principal file - print(birthdays) print(day_events) print(time_events) @@ -184,9 +198,7 @@ Himage = Image.new('1', (800,480), 255) # 255: clear the frame draw = ImageDraw.Draw(Himage) #define language, and if abbreviations for weekdays should be used -language = "EN" -weekday_l_key = "FULL" -draw_date = True + #define grid coordinates upper_border_grid = 0 lower_border_grid = 465 @@ -282,22 +294,29 @@ for event in time_events: right_border_event = row_start+width_day-6-((events_on_weekday[event["START"].weekday()])>0)*3 upper_border_event = round(upper_border_grid+weekday_height+5+((lower_border_grid-(upper_border_grid+weekday_height+5))/hours_in_day)*(event["START"].hour-first_hour+(event["START"].minute/60))) lower_border_event = round(upper_border_grid+weekday_height+5+((lower_border_grid-(upper_border_grid+weekday_height+5))/hours_in_day)*(event["END"].hour-first_hour+(event["END"].minute/60))) - #blank out everything + if (row_start == row_end): draw.rectangle((left_border_event,upper_border_event,right_border_event,lower_border_event),fill = 255) + if(lower_border_eventERCX^mRq>H9$&OgF_sHLZ$($aDpab5u^wXN#9+v<12JHD6wC7C z3jI;+1E`}v02}tM6jT@@as?(bc8kZ@FTsvmtHs-~M*>%A30$Rv;<=Jx2f;N<;7A;|H0;C{Uc<&6tfr*$OfRM*GKhm>-8AOa7=^6&^NV9zvT7vl=!3Pe$@W$-yAF08w+eixMyfC19u$ zFl2C*lwgMq0`CnV9VK~=YnFhXGW``el8QKf06t3M3e+K27*{wKwI@W8hJ6Vj1p5+P z-v!~oM9dFB2<8Xo2M7nu4}5lz;QXp6BkU@UAAk=WKOSQI2m&HS%}Zpg!v!SR(J28# z#@Z{cSprASfVB)xS9d|F8Tv7fd0UHP7n^I;$u7x z4#VgE=Gxx9Q?=hHo|S-MyUDpA#ty`=Lcd&}h+H9876a8AKQOK=Rxt-LuB>R_(x8O= z2uQ#PO2F7H0YiozM1mcN0TQiDzngc!H&FK3=Au=5pC$U-a!46}VC-5{mHqx4_VqaoK5B4S4msrt&eF^p@GzRc{9FP*F&zC$Q z_mSBerf8d%7$m|&~_rW#GndJ}65A+9M0PhVT8BCTi4k891eFltC z=nwPGCE!VGpD9DavT)*6$ zJ9^1IkUI80`Zq=Nv zi){PJFA(E{bl>^9u+Jv}qfsOV=PKMQ(vIu(>BW7W;gcdU?n&@R){&-hHPrP@h5oox zJLP+vec873-C$?s`Eh6J&p__WE=z9>bP`@F$-#>3;9OOXF}!-}Tp6ubj!_9$)5S>45tb-B4xb`Tt>3jrMcQ#Dthl@{9~Fw>3HzHDc$V-RR#9A?d+tyj4PK#kFh9t^ zU^uLZ;>u{<*b2pPlB`HO?*35gaJFAMFA^gatF3ps<8kpAw}oQpj4SuQLNQXq!8uO% zO|cjf{E;4}Ty1#gZE-%=0wfk}a0<|+!#{-0M#Suhd$e6=Xu0RpP zRq`xc!kb$M0IN4|mw^E<{4sv-AimEMII`Tm0XP)jHEAQG^tS-E>c{wfWN3%Q0Om*a z#wd$bDq(&AIt+%jD!RX`b`ulVz_!j{|z3%Tk!*WDy*yU8A!OkD?oPAUk(Up*48A& zu$Kode5mlyinxL&(t8}6YVT(r5+he=nq$!4Ul_&2h#H#8Kg^uvc9<1~OUoF?8P9V1 zO=a?9vQ@(l#jG$f%w|=-*UVXtG1*5LrxmW0pB6RSus&LdpDV_}-b9pZCPs?zD^&Tu z%r4#($4JpV3fpU(mX8{(@Y6=w&ru2`+5P>OFSPCrab1sfEe_1{#YefOEkE$ehGpvp z+roaTA6oL->iLUC{LN9S& zp&g<83WX{RW5i1_UZe`qGfl2Y*iDR9v{9dHuw^3eWL3OmJQrIUmEDG66vO8|=pW|{ z5Y4ytlR Date: Sun, 19 Sep 2021 21:24:25 +0200 Subject: [PATCH 05/10] debugged situation where ends before first hour are displayed --- calDAVconnector.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/calDAVconnector.py b/calDAVconnector.py index 48c1f57..f937b5b 100644 --- a/calDAVconnector.py +++ b/calDAVconnector.py @@ -311,9 +311,10 @@ for event in time_events: draw.rectangle((left_border_event+(d*width_day),upper_border_grid+weekday_height+5,right_border_event+(d*width_day),lower_border_grid),fill = 255) draw.line([(left_border_event+(d*width_day),upper_border_grid+weekday_height+5),(left_border_event+(d*width_day),lower_border_grid-1)], width = 4, fill = 0) draw.line([(right_border_event-1+(d*width_day),upper_border_grid+weekday_height+5),(right_border_event-1+(d*width_day),lower_border_grid-2)], width = 2, fill = 0) - draw.rectangle((left_border_event+((event["END"].weekday()-event["START"].weekday())*width_day),upper_border_grid+weekday_height+5,right_border_event+((event["END"].weekday()-event["START"].weekday())*width_day),lower_border_event),fill = 255) - draw.line([(left_border_event+((event["END"].weekday()-event["START"].weekday())*width_day),upper_border_grid+weekday_height+5),(left_border_event+((event["END"].weekday()-event["START"].weekday())*width_day),lower_border_event)], width = 4, fill = 0) - draw.line([(right_border_event-1+((event["END"].weekday()-event["START"].weekday())*width_day),upper_border_grid+weekday_height+5),(right_border_event-1+((event["END"].weekday()-event["START"].weekday())*width_day),lower_border_event)], width = 2, fill = 0) + if(event["END"].hour> first_hour): + draw.rectangle((left_border_event+((event["END"].weekday()-event["START"].weekday())*width_day),upper_border_grid+weekday_height+5,right_border_event+((event["END"].weekday()-event["START"].weekday())*width_day),lower_border_event),fill = 255) + draw.line([(left_border_event+((event["END"].weekday()-event["START"].weekday())*width_day),upper_border_grid+weekday_height+5),(left_border_event+((event["END"].weekday()-event["START"].weekday())*width_day),lower_border_event)], width = 4, fill = 0) + draw.line([(right_border_event-1+((event["END"].weekday()-event["START"].weekday())*width_day),upper_border_grid+weekday_height+5),(right_border_event-1+((event["END"].weekday()-event["START"].weekday())*width_day),lower_border_event)], width = 2, fill = 0) if(lower_border_event right_border_event-left_border_event-4): cropped_ev_str = cropped_ev_str[:-1] draw.text((left_border_event+6, lower_border_event+4),cropped_ev_str, font = eventfont, fill = 0) - elif(lower_border_event-upper_border_event-2 < hi*2): + elif(event["START"].day == event["END"].day and lower_border_event-upper_border_event-2 < hi*2) or lower_border_grid-upper_border_event-2 < hi*2: cropped_ev_str = ('{:2d}'.format(event["START"].hour)+":"+'{:02d}'.format(event["START"].minute)+ " " +event["SUMMARY"]) while (eventfont.getsize(cropped_ev_str)[0] > right_border_event-left_border_event-4): cropped_ev_str = cropped_ev_str[:-1] draw.text((left_border_event+6, upper_border_event+4),cropped_ev_str, font = eventfont, fill = 0) - + else: cropped_ev_str = (event["SUMMARY"]) while (eventfont.getsize(cropped_ev_str)[0] > right_border_event-left_border_event-4): From dfe340c3a19811d63c429d65e08449a573b07f9a Mon Sep 17 00:00:00 2001 From: Justus Kuhlmann Date: Wed, 22 Sep 2021 17:26:05 +0200 Subject: [PATCH 06/10] day events can now stretch over multi. days, collisions for appointments at same time handled better --- calDAVconnector.py | 109 ++++++++++++++++++++++++--------------------- 1 file changed, 59 insertions(+), 50 deletions(-) diff --git a/calDAVconnector.py b/calDAVconnector.py index f937b5b..4e509e2 100644 --- a/calDAVconnector.py +++ b/calDAVconnector.py @@ -2,8 +2,9 @@ from datetime import datetime, date, time, timezone, timedelta from PIL import Image,ImageDraw,ImageFont import pickle as p +import numpy as np import requests -import sys +import sys, os sys.path.insert(0, './caldav') import caldav from caldav.lib.error import AuthorizationError @@ -16,32 +17,38 @@ selected_cals = [] language="EN" weekday_l_key = "FULL" draw_date = False +has_color = False #open config file, load configs -configfile = open("./config", "r") -conf = configfile.readlines() -print(conf) -for l in conf: - l = l.strip() - if(l.startswith("server")): - caldav_url = l[7:] - elif(l.startswith("user")): - username = l[5:] - elif(l.startswith("password")): - password = l[9:] - elif(l.startswith("birthdays")): - birthdaycal = l[10:] - elif(l.startswith("datafile")): - datafile = l[9:] - elif(l.startswith("calendars")): - selected_cals = l[10:].split(";") - elif(l.startswith("language")): - language = l[9:] - elif(l.startswith("weekday_format")): - weekday_l_key = l[15:] - elif(l.startswith("draw_date")): - k = l[10:] - trueish = ["true","TRUE","1","True","T"] - draw_date = (k in trueish) + +if (os.path.isfile("./config")): + configfile = open("./config", "r") + conf = configfile.readlines() + print(conf) + for l in conf: + l = l.strip() + if(l.startswith("server")): + caldav_url = l[7:] + elif(l.startswith("user")): + username = l[5:] + elif(l.startswith("password")): + password = l[9:] + elif(l.startswith("birthdays")): + birthdaycal = l[10:] + elif(l.startswith("datafile")): + datafile = l[9:] + elif(l.startswith("calendars")): + selected_cals = l[10:].split(";") + elif(l.startswith("language")): + language = l[9:] + elif(l.startswith("weekday_format")): + weekday_l_key = l[15:] + elif(l.startswith("draw_date")): + k = l[10:] + trueish = ["true","TRUE","1","True","T"] + draw_date = (k in trueish) + elif(l.startswith("colormode")): + if l[10:] == "2color": + has_color = True #print(selected_cals) #look if server and user are set @@ -111,7 +118,8 @@ if(server_reached and client_established): if(event_start_str.startswith("VALUE")): #if it is an event over a whole day, sort it into the day events day_events.append({ - "DATE":date(int(event_start_str.split("}")[1].split("-")[0]),int(event_start_str.split("}")[1].split("-")[1]),int(event_start_str.split("}")[1].split("-")[2])), + "START":date(int(event_start_str.split("}")[1].split("-")[0]),int(event_start_str.split("}")[1].split("-")[1]),int(event_start_str.split("}")[1].split("-")[2])), + "END":date(int(event_end_str.split("}")[1].split("-")[0]),int(event_end_str.split("}")[1].split("-")[1]),int(event_end_str.split("}")[1].split("-")[2])), "SUMMARY":str(event.vobject_instance.vevent.summary.value), "CALENDAR":c.name }) @@ -252,7 +260,7 @@ for y in range(width_day,width_grid,width_day): for y in range(upper_border_grid+weekday_height+2,lower_border_grid,two_hour_space): for x in range(left_border_grid, right_border_grid, 6): - draw.line([(x, y), (x+2, y)], fill = 0, width = 1) + draw.line([(x, y), (x+2, y)], fill = 0, width = 1) #draw times for orientation i = 0 @@ -260,29 +268,30 @@ for y in range(upper_border_grid+weekday_height+4,lower_border_grid,two_hour_spa draw.text((left_border_grid-timefont.getsize(str(i*2+first_hour))[0], y), str(i*2+first_hour), font = timefont, fill = 0) i +=1 -events_on_weekday = [0,0,0,0,0,0,0] +already_an_event = np.zeros((7,lower_border_grid - upper_border_grid)) known_calendars = {"DLRG Kalendar" : "DLRG", "Uni Kalendar" : "UNI", "Persönlich" : "PER"} for event in day_events: - row = width_day*event["DATE"].weekday()+left_border_grid+4 - if event["CALENDAR"] in known_calendars: - cal = known_calendars[event["CALENDAR"]] - else: - cal = event["CALENDAR"] - if(events_on_weekday[event["DATE"].weekday()]== 0): - draw.rectangle((row,upper_border_grid+weekday_height+5,row+width_day-6,lower_border_grid-1),fill = 255) - draw.line([(row,upper_border_grid+weekday_height+5),(row,lower_border_grid-1)], width = 4, fill = 0) - draw.line([(row,lower_border_grid-2),(row+width_day-6,lower_border_grid-2)], width = 2, fill = 0) - draw.line([(row,upper_border_grid+weekday_height+5),(row+width_day-6,upper_border_grid+weekday_height+5)], width = 2, fill = 0) - draw.line([(row+width_day-7,upper_border_grid+weekday_height+5),(row+width_day-7,lower_border_grid-1)], width = 2, fill = 0) - wi, hi = eventfont.getsize (event["SUMMARY"]) - draw_text_90_into("["+cal+"] "+event["SUMMARY"], Himage, (row+4,height_grid-(weekday_height+5)-round(wi/2))) - else: - wi, hi = eventfont.getsize(event["SUMMARY"]) - draw.line([(row+6+hi,upper_border_grid+weekday_height+9),(row+6+hi,lower_border_grid-4)], width = 2, fill = 0) - draw_text_90_into("["+cal+"] "+event["SUMMARY"], Himage, (row+10+hi,-round(wi/2))) - events_on_weekday[event["DATE"].weekday()] += 1 + for d in range(event["START"].weekday(),event["END"].weekday()): + row = width_day*d+left_border_grid+4 + if event["CALENDAR"] in known_calendars: + cal = known_calendars[event["CALENDAR"]] + else: + cal = event["CALENDAR"] + if(np.amax(already_an_event[d,:])== 0): + draw.rectangle((row,upper_border_grid+weekday_height+5,row+width_day-6,lower_border_grid-1),fill = 255) + draw.line([(row,upper_border_grid+weekday_height+5),(row,lower_border_grid-1)], width = 4, fill = 0) + draw.line([(row,lower_border_grid-2),(row+width_day-6,lower_border_grid-2)], width = 2, fill = 0) + draw.line([(row,upper_border_grid+weekday_height+5),(row+width_day-6,upper_border_grid+weekday_height+5)], width = 2, fill = 0) + draw.line([(row+width_day-7,upper_border_grid+weekday_height+5),(row+width_day-7,lower_border_grid-1)], width = 2, fill = 0) + wi, hi = eventfont.getsize (event["SUMMARY"]) + draw_text_90_into("["+cal+"] "+event["SUMMARY"], Himage, (row+4,round(height_grid/2-(weekday_height+5)-wi/2))) + else: + wi, hi = eventfont.getsize(event["SUMMARY"]) + draw.line([(row+6+hi,upper_border_grid+weekday_height+9),(row+6+hi,lower_border_grid-4)], width = 2, fill = 0) + draw_text_90_into("["+cal+"] "+event["SUMMARY"], Himage, (row+10+hi,round(height_grid/2-(weekday_height+5)-wi/2))) + already_an_event[d,:] += 1 for event in time_events: #draw rectangle @@ -290,11 +299,11 @@ for event in time_events: row_start = width_day*event["START"].weekday()+left_border_grid+4 row_end = width_day*event["END"].weekday()+left_border_grid+4 - left_border_event = row_start+(events_on_weekday[event["START"].weekday()]*(6+(eventfont.getsize(event["SUMMARY"])[1]))) - right_border_event = row_start+width_day-6-((events_on_weekday[event["START"].weekday()])>0)*3 + right_border_event = row_start+width_day-6 upper_border_event = round(upper_border_grid+weekday_height+5+((lower_border_grid-(upper_border_grid+weekday_height+5))/hours_in_day)*(event["START"].hour-first_hour+(event["START"].minute/60))) lower_border_event = round(upper_border_grid+weekday_height+5+((lower_border_grid-(upper_border_grid+weekday_height+5))/hours_in_day)*(event["END"].hour-first_hour+(event["END"].minute/60))) - + left_border_event = row_start+((np.amax(already_an_event[event["START"].weekday(),upper_border_event:lower_border_event]))*6) + already_an_event[event["START"].weekday(),upper_border_event:lower_border_event] +=1 if (row_start == row_end): draw.rectangle((left_border_event,upper_border_event,right_border_event,lower_border_event),fill = 255) if(lower_border_event Date: Sun, 26 Sep 2021 10:54:17 +0200 Subject: [PATCH 07/10] small changes to grafic collisions --- calDAVconnector.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/calDAVconnector.py b/calDAVconnector.py index 4e509e2..2fab03f 100644 --- a/calDAVconnector.py +++ b/calDAVconnector.py @@ -38,6 +38,7 @@ if (os.path.isfile("./config")): datafile = l[9:] elif(l.startswith("calendars")): selected_cals = l[10:].split(";") +#here the configs for drawing the calendar start elif(l.startswith("language")): language = l[9:] elif(l.startswith("weekday_format")): @@ -69,7 +70,7 @@ client_established = True print("Looking for server...") try: - request = requests.get(caldav_url, timeout=timeout) + request = requests.get(caldav_url, timeout=timeout) except (requests.ConnectionError, requests.Timeout) as exception: print("didn't find server, showing data from last successful connection") server_reached = False @@ -99,8 +100,7 @@ if(server_reached and client_established): print("selected calendars:") for c in calendars: print(c.name) - - + time_events = [] day_events = [] birthdays = [] @@ -151,6 +151,7 @@ if(server_reached and client_established): birthdays.append(event) day_events.remove(event) print("Download complete") + #back up the data received to a local copy so that it can be displayed if needed if(len(datafile)!= 0): calendarlib = {"DAY_EVENTS":day_events,"TIME_EVENTS":time_events,"BIRTHDAYS":birthdays} @@ -171,6 +172,7 @@ else: print(birthdays) print(day_events) print(time_events) + #with this information now the week calendar can be painted on a b/w 800x480 bitmap. From ec1f6d1cc1efa64bbbeb5078b4b361929104cc37 Mon Sep 17 00:00:00 2001 From: Justus Date: Sat, 9 Oct 2021 21:57:41 +0200 Subject: [PATCH 08/10] Added support for color, added marks for (single-)birthdays --- calDAVconnector.py | 120 ++++++++++++++++++++++++++++++--------------- 1 file changed, 81 insertions(+), 39 deletions(-) diff --git a/calDAVconnector.py b/calDAVconnector.py index 2fab03f..cc27807 100644 --- a/calDAVconnector.py +++ b/calDAVconnector.py @@ -14,6 +14,7 @@ username = '' password = '' datafile = '' selected_cals = [] +birthdaycal = '' language="EN" weekday_l_key = "FULL" draw_date = False @@ -113,16 +114,28 @@ if(server_reached and client_established): for event in events_fetched: event_start_str = str(event.vobject_instance.vevent.dtstart)[10:-1] event_end_str = str(event.vobject_instance.vevent.dtend)[8:-1] - print(event.vobject_instance.vevent) + #print(event.vobject_instance.vevent) if(event_start_str.startswith("VALUE")): #if it is an event over a whole day, sort it into the day events - day_events.append({ - "START":date(int(event_start_str.split("}")[1].split("-")[0]),int(event_start_str.split("}")[1].split("-")[1]),int(event_start_str.split("}")[1].split("-")[2])), - "END":date(int(event_end_str.split("}")[1].split("-")[0]),int(event_end_str.split("}")[1].split("-")[1]),int(event_end_str.split("}")[1].split("-")[2])), - "SUMMARY":str(event.vobject_instance.vevent.summary.value), - "CALENDAR":c.name - }) + if(not birthdaycal == ''): + if(c.name == birthdaycal): + summary = str(event.vobject_instance.vevent.summary.value) + pieces = summary.split(" ") + age = date.today().year - int(pieces[2][2:-1]) + birthdays.append({ + "START":date(int(event_start_str.split("}")[1].split("-")[0]),int(event_start_str.split("}")[1].split("-")[1]),int(event_start_str.split("}")[1].split("-")[2])), + "END":date(int(event_end_str.split("}")[1].split("-")[0]),int(event_end_str.split("}")[1].split("-")[1]),int(event_end_str.split("}")[1].split("-")[2])), + "SUMMARY":pieces[1]+" "+pieces[0][:-1]+" ("+str(age)+")", + "CALENDAR":c.name + }) + else: + day_events.append({ + "START":date(int(event_start_str.split("}")[1].split("-")[0]),int(event_start_str.split("}")[1].split("-")[1]),int(event_start_str.split("}")[1].split("-")[2])), + "END":date(int(event_end_str.split("}")[1].split("-")[0]),int(event_end_str.split("}")[1].split("-")[1]),int(event_end_str.split("}")[1].split("-")[2])), + "SUMMARY":str(event.vobject_instance.vevent.summary.value), + "CALENDAR":c.name + }) else: #otherwise it has to be a time event sd = event_start_str.split(" ")[0] @@ -142,14 +155,6 @@ if(server_reached and client_established): "CALENDAR":c.name }) #if the user wants one calendar to be treated as a birthday calendar, these are sorted into an extra library - if(not (len(birthdaycal) == 0)): - for event in day_events: - if event["CALENDAR"] == birthdaycal: - pieces = event["SUMMARY"].split(" ") - age = date.today().year - int(pieces[2][2:-1]) - event["SUMMARY"] = pieces[1]+" "+pieces[0][:-1]+" ("+str(age)+")" - birthdays.append(event) - day_events.remove(event) print("Download complete") #back up the data received to a local copy so that it can be displayed if needed @@ -198,14 +203,20 @@ def draw_text_90_into (text: str, into, at): # Note that we don't need a mask into.paste (img, at) +#only for testing purposes +has_color = True + #define fonts to be used eventfont = ImageFont.truetype("./resource/bf_mnemonika_regular.ttf", 16) weekdayfont = ImageFont.truetype("./resource/bf_mnemonika_regular.ttf", 16) timefont = ImageFont.truetype("./resource/bf_mnemonika_regular.ttf", 12) - +birthdayfont = weekdayfont #create image buffer Himage = Image.new('1', (800,480), 255) # 255: clear the frame draw = ImageDraw.Draw(Himage) +if(has_color): + HRimage = Image.new('1', (800,480), 255) # 255: clear the frame + draw_r = ImageDraw.Draw(HRimage) #define language, and if abbreviations for weekdays should be used @@ -223,6 +234,11 @@ width_grid = right_border_grid-left_border_grid width_day = round(width_grid/7) height_grid = lower_border_grid-upper_border_grid weekday_height = weekdayfont.getsize("Monday")[1] +if(birthdaycal == ''): + upper_border_writable = upper_border_grid+weekday_height +else: + birthday_height = birthdayfont.getsize("ABCDEFGHIJKLMNOPQRSTUVWXYZÄÜÖabcdefghijklmnpqrstuvwxyzäüö")[1] + upper_border_writable = upper_border_grid+weekday_height+birthday_height+3 two_hour_space = round(2*(lower_border_grid-(upper_border_grid+weekday_height+2))/hours_in_day) last_hour_line = round((hours_in_day-(hours_in_day%2))*two_hour_space/2+upper_border_grid+weekday_height+2) #write down weekdays, makes next step easier @@ -243,30 +259,52 @@ weekdays = { #draw the weekdays monday = datetime.today()-timedelta(days = datetime.today().weekday()) +free_days = [5,6] for j in range(len(weekdays[language][weekday_l_key])): if draw_date: if(max([(weekdayfont.getsize(i+", "+str((monday+timedelta(days=j)).day)+"."+str((monday+timedelta(days=j)).month)+".")[0]>width_day-7) for i in weekdays[language]["FULL"]])): weekday_l_key = "SHORT" - draw.text((left_border_grid+j*width_day+5, upper_border_grid), (weekdays[language][weekday_l_key][j]+", "+str((monday+timedelta(days=j)).day)+"."+str((monday+timedelta(days=j)).month)+"."), font = weekdayfont, fill = 0) + w_str = (weekdays[language][weekday_l_key][j]+", "+str((monday+timedelta(days=j)).day)+"."+str((monday+timedelta(days=j)).month)+".") else: if(max([(weekdayfont.getsize(i)[0]>width_day-7) for i in weekdays[language]["FULL"]])): weekday_l_key = "SHORT" - draw.text((left_border_grid+j*width_day+5, upper_border_grid), weekdays[language][weekday_l_key][j], font = weekdayfont, fill = 0) + w_str = (weekdays[language][weekday_l_key][j]) + if has_color and j in free_days: + draw_r.text((left_border_grid+j*width_day+5, upper_border_grid),w_str, font = weekdayfont, fill = 0) + else: + draw.text((left_border_grid+j*width_day+5, upper_border_grid),w_str, font = weekdayfont, fill = 0) +# draw birthdays +for event in birthdays: + cropped_ev_str = (event["SUMMARY"]) + if (birthdayfont.getsize(cropped_ev_str)[0] > width_day-4): + p_list = cropped_ev_str.split(" ") + p_list[-2] = p_list[-2][0]+"." + cropped_ev_str = "" + for l in p_list: + cropped_ev_str += l+" " + print(cropped_ev_str) + while (birthdayfont.getsize(cropped_ev_str)[0] > width_day-4): + cropped_ev_str = cropped_ev_str.split("(")[0][:-1]+"("+cropped_ev_str.split("(")[1] + d = event["START"].weekday() + if has_color: + draw_r.text((left_border_grid+d*width_day+5, upper_border_grid+weekday_height+2),cropped_ev_str, font = weekdayfont, fill = 0) + else: + draw.text((left_border_grid+d*width_day+5, upper_border_grid+weekday_height+2),cropped_ev_str, font = weekdayfont, fill = 0) #draw a grid -draw.line([(left_border_grid, upper_border_grid+weekday_height+2),(right_border_grid, upper_border_grid+weekday_height+2)], fill=0, width=2) +draw.line([(left_border_grid, upper_border_writable+2),(right_border_grid, upper_border_writable+2)], fill=0, width=2) for y in range(width_day,width_grid,width_day): draw.line([(y+left_border_grid, upper_border_grid),(y+left_border_grid, lower_border_grid)], fill=0, width=2) -for y in range(upper_border_grid+weekday_height+2,lower_border_grid,two_hour_space): +for y in range(upper_border_writable+2,lower_border_grid,two_hour_space): for x in range(left_border_grid, right_border_grid, 6): draw.line([(x, y), (x+2, y)], fill = 0, width = 1) #draw times for orientation i = 0 -for y in range(upper_border_grid+weekday_height+4,lower_border_grid,two_hour_space): +for y in range(upper_border_writable+4,lower_border_grid,two_hour_space): draw.text((left_border_grid-timefont.getsize(str(i*2+first_hour))[0], y), str(i*2+first_hour), font = timefont, fill = 0) i +=1 @@ -282,16 +320,16 @@ for event in day_events: else: cal = event["CALENDAR"] if(np.amax(already_an_event[d,:])== 0): - draw.rectangle((row,upper_border_grid+weekday_height+5,row+width_day-6,lower_border_grid-1),fill = 255) - draw.line([(row,upper_border_grid+weekday_height+5),(row,lower_border_grid-1)], width = 4, fill = 0) + draw.rectangle((row,upper_border_writable+5,row+width_day-6,lower_border_grid-1),fill = 255) + draw.line([(row,upper_border_writable+5),(row,lower_border_grid-1)], width = 4, fill = 0) draw.line([(row,lower_border_grid-2),(row+width_day-6,lower_border_grid-2)], width = 2, fill = 0) - draw.line([(row,upper_border_grid+weekday_height+5),(row+width_day-6,upper_border_grid+weekday_height+5)], width = 2, fill = 0) - draw.line([(row+width_day-7,upper_border_grid+weekday_height+5),(row+width_day-7,lower_border_grid-1)], width = 2, fill = 0) + draw.line([(row,upper_border_writable+5),(row+width_day-6,upper_border_writable+5)], width = 2, fill = 0) + draw.line([(row+width_day-7,upper_border_writable+5),(row+width_day-7,lower_border_grid-1)], width = 2, fill = 0) wi, hi = eventfont.getsize (event["SUMMARY"]) draw_text_90_into("["+cal+"] "+event["SUMMARY"], Himage, (row+4,round(height_grid/2-(weekday_height+5)-wi/2))) else: wi, hi = eventfont.getsize(event["SUMMARY"]) - draw.line([(row+6+hi,upper_border_grid+weekday_height+9),(row+6+hi,lower_border_grid-4)], width = 2, fill = 0) + draw.line([(row+6+hi,upper_border_writable+9),(row+6+hi,lower_border_grid-4)], width = 2, fill = 0) draw_text_90_into("["+cal+"] "+event["SUMMARY"], Himage, (row+10+hi,round(height_grid/2-(weekday_height+5)-wi/2))) already_an_event[d,:] += 1 @@ -302,8 +340,8 @@ for event in time_events: row_start = width_day*event["START"].weekday()+left_border_grid+4 row_end = width_day*event["END"].weekday()+left_border_grid+4 right_border_event = row_start+width_day-6 - upper_border_event = round(upper_border_grid+weekday_height+5+((lower_border_grid-(upper_border_grid+weekday_height+5))/hours_in_day)*(event["START"].hour-first_hour+(event["START"].minute/60))) - lower_border_event = round(upper_border_grid+weekday_height+5+((lower_border_grid-(upper_border_grid+weekday_height+5))/hours_in_day)*(event["END"].hour-first_hour+(event["END"].minute/60))) + upper_border_event = round(upper_border_writable+5+((lower_border_grid-(upper_border_writable+5))/hours_in_day)*(event["START"].hour-first_hour+(event["START"].minute/60))) + lower_border_event = round(upper_border_writable+5+((lower_border_grid-(upper_border_writable+5))/hours_in_day)*(event["END"].hour-first_hour+(event["END"].minute/60))) left_border_event = row_start+((np.amax(already_an_event[event["START"].weekday(),upper_border_event:lower_border_event]))*6) already_an_event[event["START"].weekday(),upper_border_event:lower_border_event] +=1 if (row_start == row_end): @@ -319,13 +357,13 @@ for event in time_events: draw.line([(right_border_event-1,upper_border_event),(right_border_event-1,lower_border_grid-2)], width = 2, fill = 0) draw.line([(left_border_event,upper_border_event),(right_border_event,upper_border_event)], width = 2, fill = 0) for d in range(event["START"].weekday()+1,event["END"].weekday()): - draw.rectangle((left_border_event+(d*width_day),upper_border_grid+weekday_height+5,right_border_event+(d*width_day),lower_border_grid),fill = 255) - draw.line([(left_border_event+(d*width_day),upper_border_grid+weekday_height+5),(left_border_event+(d*width_day),lower_border_grid-1)], width = 4, fill = 0) - draw.line([(right_border_event-1+(d*width_day),upper_border_grid+weekday_height+5),(right_border_event-1+(d*width_day),lower_border_grid-2)], width = 2, fill = 0) + draw.rectangle((left_border_event+(d*width_day),upper_border_writable+5,right_border_event+(d*width_day),lower_border_grid),fill = 255) + draw.line([(left_border_event+(d*width_day),upper_border_writable+5),(left_border_event+(d*width_day),lower_border_grid-1)], width = 4, fill = 0) + draw.line([(right_border_event-1+(d*width_day),upper_border_writable+5),(right_border_event-1+(d*width_day),lower_border_grid-2)], width = 2, fill = 0) if(event["END"].hour> first_hour): - draw.rectangle((left_border_event+((event["END"].weekday()-event["START"].weekday())*width_day),upper_border_grid+weekday_height+5,right_border_event+((event["END"].weekday()-event["START"].weekday())*width_day),lower_border_event),fill = 255) - draw.line([(left_border_event+((event["END"].weekday()-event["START"].weekday())*width_day),upper_border_grid+weekday_height+5),(left_border_event+((event["END"].weekday()-event["START"].weekday())*width_day),lower_border_event)], width = 4, fill = 0) - draw.line([(right_border_event-1+((event["END"].weekday()-event["START"].weekday())*width_day),upper_border_grid+weekday_height+5),(right_border_event-1+((event["END"].weekday()-event["START"].weekday())*width_day),lower_border_event)], width = 2, fill = 0) + draw.rectangle((left_border_event+((event["END"].weekday()-event["START"].weekday())*width_day),upper_border_writable+5,right_border_event+((event["END"].weekday()-event["START"].weekday())*width_day),lower_border_event),fill = 255) + draw.line([(left_border_event+((event["END"].weekday()-event["START"].weekday())*width_day),upper_border_writable+5),(left_border_event+((event["END"].weekday()-event["START"].weekday())*width_day),lower_border_event)], width = 4, fill = 0) + draw.line([(right_border_event-1+((event["END"].weekday()-event["START"].weekday())*width_day),upper_border_writable+5),(right_border_event-1+((event["END"].weekday()-event["START"].weekday())*width_day),lower_border_event)], width = 2, fill = 0) if(lower_border_event upper_border_grid+weekday_height+2): - draw.line([(now_row,now_time),(now_row+width_day-2,now_time)], width = 2, fill = 0) - draw.ellipse((now_row, now_time, now_row+10, now_time+4), fill = 0) +now_time = round(upper_border_writable+5+(((last_hour_line-(upper_border_writable+5))/(hours_in_day-(hours_in_day%2)))*(datetime.now().hour-first_hour+(datetime.now().minute/60)))) +if(now_time < lower_border_grid and now_time > upper_border_writable+2): + if has_color: + draw_r.line([(now_row,now_time),(now_row+width_day-2,now_time)], width = 2, fill = 0) + draw_r.ellipse((now_row, now_time, now_row+10, now_time+4), fill = 0) + else: + draw.line([(now_row,now_time),(now_row+width_day-2,now_time)], width = 2, fill = 0) + draw.ellipse((now_row, now_time, now_row+10, now_time+4), fill = 0) #draw warnings, if something went wrong with the connection if(not server_reached): @@ -372,4 +414,4 @@ if(not server_reached): if(not client_established): Himage.paste(Image.open("./resource/unauthorized.png"), (right_border_grid-40,lower_border_grid-40)) Himage.save("./canvas.bmp") - +HRimage.save("./r_canvas.bmp") From 1e55649e1954718bc76826283616e67e5c7646a8 Mon Sep 17 00:00:00 2001 From: Justus Kuhlmann <56114108+Xenror@users.noreply.github.com> Date: Sun, 24 Oct 2021 19:50:24 +0200 Subject: [PATCH 09/10] Deleted config file --- config | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 config diff --git a/config b/config deleted file mode 100644 index 210a1a3..0000000 --- a/config +++ /dev/null @@ -1,9 +0,0 @@ -server:https://www.kuhl-mann.de/nextcloud/remote.php/dav -user:Justus -password:Alphabeth1forB2; -datafile:calendarlib.p -birthdays:Geburtstage von Kontakten -calendars: -language:EN -weekday_format:FULL -draw_date:True \ No newline at end of file From 80c72914087bb2396b338a09ea147afbe49f6654 Mon Sep 17 00:00:00 2001 From: Justus Kuhlmann Date: Sun, 24 Oct 2021 21:36:08 +0200 Subject: [PATCH 10/10] Added first e-paper support --- calDAVconnector.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/calDAVconnector.py b/calDAVconnector.py index cc27807..9fc7841 100644 --- a/calDAVconnector.py +++ b/calDAVconnector.py @@ -6,9 +6,11 @@ import numpy as np import requests import sys, os sys.path.insert(0, './caldav') +sys.path.insert(0, './e-Paper/RaspberryPi_JetsonNano/python/lib') import caldav from caldav.lib.error import AuthorizationError + caldav_url = '' username = '' password = '' @@ -52,6 +54,10 @@ if (os.path.isfile("./config")): if l[10:] == "2color": has_color = True +on_e_paper = False +if(on_e_paper): + from waveshare_epd import epd7in5b_V2 + #print(selected_cals) #look if server and user are set if(len(caldav_url) == 0): @@ -211,6 +217,12 @@ eventfont = ImageFont.truetype("./resource/bf_mnemonika_regular.ttf", 16) weekdayfont = ImageFont.truetype("./resource/bf_mnemonika_regular.ttf", 16) timefont = ImageFont.truetype("./resource/bf_mnemonika_regular.ttf", 12) birthdayfont = weekdayfont + +if(on_e_paper): + #initialise epd for the e-ink display + epd = epd7in5b_V2.EPD() + epd.init() + epd.Clear() #create image buffer Himage = Image.new('1', (800,480), 255) # 255: clear the frame draw = ImageDraw.Draw(Himage) @@ -415,3 +427,6 @@ if(not client_established): Himage.paste(Image.open("./resource/unauthorized.png"), (right_border_grid-40,lower_border_grid-40)) Himage.save("./canvas.bmp") HRimage.save("./r_canvas.bmp") + +if(on_e_paper): + epd.display(epd.getbuffer(Himage), epd.getbuffer(HRimage)) \ No newline at end of file