diff --git a/Calendar/E-Paper.py b/Calendar/E-Paper.py index 5c12e50..8b77836 100644 --- a/Calendar/E-Paper.py +++ b/Calendar/E-Paper.py @@ -19,6 +19,7 @@ import random import gc import feedparser import numpy as np +from pytz import timezone from settings import * from image_data import * @@ -52,13 +53,20 @@ else: im_open = Image.open +'''Get system timezone and set timezone accordingly''' +file = open('/etc/timezone','r') +lines = file.readlines() +system_tz = lines[0].rstrip() +local_tz = timezone(system_tz) + + owm = pyowm.OWM(api_key) """Main loop starts from here""" def main(): calibration_countdown = 'initial' while True: - time = datetime.now() + time = datetime.now().replace(tzinfo=local_tz) hour = int(time.strftime("%-H")) month = int(time.now().strftime('%-m')) year = int(time.now().strftime('%Y')) @@ -179,7 +187,7 @@ def main(): """If no response was received from the openweathermap api server, add the cloud with question mark""" print('__________OWM-ERROR!__________'+'\n') - print('Reason: ',e+'\n') + print('Reason: ',e,'\n') image.paste(no_response, wiconplace) pass @@ -320,8 +328,10 @@ def main(): """Create a time span using the events_max_range value (in days) to filter events in that range""" - agenda_max_days = arrow.now().replace(days=+22) - calendar_max_days = arrow.now().replace(days=+int(events_max_range)) + + time_span_calendar = time + timedelta(days=int(events_max_range)) + time_span_agenda = time + timedelta(days=22) + if internet_available() is True: print('Internet connection test passed'+'\n') print('Fetching events from your calendar'+'\n') @@ -335,14 +345,27 @@ def main(): decode = decode[:beginAlarmIndex] + decode[endAlarmIndex+12:] ical = Calendar(decode) for events in ical.events: - if events.begin.date().year == today.year and events.begin.date().month is today.month: + if events.begin.date().year == today.year and events.begin.date().month == today.month: if int((events.begin).format('D')) not in events_this_month: events_this_month.append(int((events.begin).format('D'))) - if middle_section is 'Agenda' and events in ical.timeline.included(now, agenda_max_days): + if middle_section is 'Agenda' and time <= events.end.datetime <= time_span_agenda: upcoming.append(events) - if middle_section is 'Calendar' and events in ical.timeline.included(now, calendar_max_days): + if middle_section is 'Calendar' and time <= events.end.datetime <= time_span_calendar: upcoming.append(events) + '''Fix some known bugs from ics.py''' + for events in upcoming: + if events.all_day and events.duration.days > 1: + events.end = events.end.replace(days=-2) + for i in range(1, events.duration.days): + cc = events.clone() + cc.begin = cc.begin.replace(days=+i) + upcoming.append(cc) + + for events in upcoming: + if events.begin.format('HH:mm') == '00:00': + events.make_all_day() + def event_begins(elem): return elem.begin @@ -352,7 +375,6 @@ def main(): print("Could not fetch events from your iCalendar.") print("Either the internet connection is too weak or we're offline.") - if middle_section is 'Agenda': """For the agenda view, create a list containing dates and events of the next 22 days""" if len(upcoming) is not 0: @@ -365,9 +387,13 @@ def main(): for events in upcoming: if events.begin.date().day == date.day: if not events.all_day: - agenda_list.append({'value':events.begin.format('HH:mm')+ ' '+ str(events.name), 'type':'timed_event'}) + if hours is '24': + agenda_list.append({'value':events.begin.to(system_tz).format('HH:mm')+ ' '+ str(events.name), 'type':'timed_event'}) + if hours is '12': + agenda_list.append({'value':events.begin.to(system_tz).format('hh:mm a')+ ' '+ str(events.name), 'type':'timed_event'}) else: agenda_list.append({'value':events.name, 'type':'full_day_event'}) + if bottom_section is not "": del agenda_list[16:] image.paste(seperator2, agenda_view_lines['line17']) @@ -406,18 +432,18 @@ def main(): if len(cal) is 5: del upcoming[6:] for dates in range(len(upcoming)): - readable_date = datetime.strptime(upcoming[dates]['date'], '%Y %m %d').strftime('%-d %b') + readable_date = upcoming[dates].begin.format('D MMM', locale=language) write_text(70, 25, readable_date, date_positions['d'+str(dates+1)]) for events in range(len(upcoming)): - write_text(314, 25, (upcoming[events]['event']), event_positions['e'+str(events+1)], alignment = 'left') + write_text(314, 25, upcoming[events].name, event_positions['e'+str(events+1)], alignment = 'left') if len(cal) is 6: del upcoming[4:] for dates in range(len(upcoming)): - readable_date = datetime.strptime(upcoming[dates]['date'], '%Y %m %d').strftime('%-d %b') + readable_date = upcoming[dates].begin.format('D MMM', locale=language) write_text(70, 25, readable_date, date_positions['d'+str(dates+3)]) for events in range(len(upcoming)): - write_text(314, 25, (upcoming[events]['event']), event_positions['e'+str(events+3)], alignment = 'left') + write_text(314, 25, upcoming[events].name, event_positions['e'+str(events+3)], alignment = 'left') """ diff --git a/Changelog.md b/Changelog.md index eea1c35..2f18d4b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,48 @@ The order is from latest to oldest and structured in the following way: * Version name with date of publishing * Sections with either 'added', 'fixed', 'updated' and 'changed' +## [1.6] Mid May 2019 + +### Added +* Added new design option: **Agenda-View**, which displays events in the next few days with timings +* Added support for multi-day events +* Added support for multiple languages +* Added support for localisation options (dates will be shown in the set language now) +* Added new fonts (NotoSans Semi & Noto Sans CJK) which support many languages (without displaying tofus) +* Added dynamic space management to minimise empty space on the generated image +* Added support for RSS-feeds. It is now possible to display them in the bottom section +* Added image pre-processing operation to allow displaying the generated image correctly on the E-Paper +* Added limit (in days) when fetching events from the iCalendar +* Added option to select the display-update interval* +* Added user-friendly Web-UI (webpage) for entering personal details easily (Credit to TobyChui) +* Added support for continuing the loop even if some details are missing in the settings file (api-key, rss-feed) +* Added support for relative path and removed explicit path +* Added support for timezones. events timings will be shown correctly using the system's set timezone +* Added support for 12/24 hours format for events + + +### Changed +* Changed E-Paper layout by splitting the image into three section: top-, middle, bottom. +* Changed the way the installer checks if a required package is installed (by test-importing it in python3) +* Changed the function which displays text on the Calendar +* Merged e-paper driver files (initially epd7in5b and epd7in5) into a single one (e_paper_drivers) +* Switched from image-based translations to text-based translation +* Changed algorithm for filtering events + +### Removed +* Removed (older) fonts which were not suitable for multiple languages +* (Temporary) removed support of recurring events due to some known bugs +* (Temporary) dropped support of the installer on Raspbian Jessie Lite due to some known bugs +* Removed image-based translations for month names + +### Fixed +* Fixed problems with iCalendar triggers by removing them altogether when parsing the iCalendar +* Fixed problems with outdated events + + +(*) Updating too frequently can cause ghosting, a problem specific to E-Paper displays where parts of the previous image can be seen on the current image. Ghosting can be fixed by 'calibrating' the E-Paper (displaying a single colour on the entire display) and is done by default. As a rule of thumb, one 'calibration' should be done for every 6 display-updates to maintain a crisp image. + + ## [1.5] Early February 2019 ### Added diff --git a/Installer-with-debug.sh b/Installer-with-debug.sh index 9472260..9a5bfc3 100644 --- a/Installer-with-debug.sh +++ b/Installer-with-debug.sh @@ -197,6 +197,24 @@ if [ "$option" = 1 ] || [ "$option" = 2 ]; then sudo pip3 install feedparser fi + #pytz for user pi + echo -e "\e[1;36m"Checking if pytz is installed for user pi"\e[0m" + if python3.5 -c "import pytz" &> /dev/null; then + echo 'pytz is installed, skipping installation of this package.' + else + echo 'pytz is not installed, attempting to install now' + pip3 install pytz + fi + + #pytz for user sudo + echo -e "\e[1;36m"Checking if pytz is installed for user sudo"\e[0m" + if sudo python3.5 -c "import pytz" &> /dev/null; then + echo 'pytz is installed, skipping installation of this package.' + else + echo 'pytz is not installed, attempting to install now' + sudo pip3 install pytz + fi + echo -e "\e[1;36m"Finished installing all dependencies"\e[0m" # Clone the repository, then delete some non-required files diff --git a/README.md b/README.md index 6e9be12..5bf88d1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,3 @@ -# Attention: -## This branch is currently in a transition state (new release). Please use the Installer only if you are a new user and know what you are doing. For all other users, please wait until this warning has disappeared and the new release has been tested thoroughly. Thanks for your understanding. -