From 1e0f59739fd05667c82e05964e72ddccf36519db Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 13 Jul 2019 08:05:35 +0200 Subject: [PATCH] Formatted code --- Calendar/AgendaListDesign.py | 46 +++++----- Calendar/AgendaListPanel.py | 27 +++--- Calendar/Assets.py | 54 +++++------ Calendar/BoxDesign.py | 9 +- Calendar/CalendarEvent.py | 5 +- Calendar/CalendarInterface.py | 71 ++++++++------- Calendar/CryptoCoin.py | 4 +- Calendar/CryptoInterface.py | 1 + Calendar/CryptoListDesign.py | 15 ++-- Calendar/DataSourceInterface.py | 7 +- Calendar/DayBoxDesign.py | 4 +- Calendar/DayHeaderDesign.py | 61 +++++++------ Calendar/DayListPanel.py | 51 ++++++----- Calendar/DayRowDesign.py | 48 +++++----- Calendar/DayViewPanel.py | 52 ++++++----- Calendar/DebugConsole.py | 12 +-- Calendar/DebugInterface.py | 11 +-- Calendar/DesignEntity.py | 33 ++++--- Calendar/Dictionary.py | 74 +++++++-------- Calendar/DictionaryMapper.py | 6 +- Calendar/DisplayAdapter.py | 7 +- Calendar/E-Paper.py | 36 +++++--- Calendar/EllipseDesign.py | 12 ++- Calendar/Epd7in5Adapter.py | 15 ++-- Calendar/Epd7in5bAdapter.py | 39 ++++---- Calendar/EpdAdapter.py | 130 ++++++++++++++------------- Calendar/EventListDesign.py | 41 +++++---- Calendar/GeckoCrypto.py | 15 ++-- Calendar/HourListDesign.py | 83 +++++++++-------- Calendar/IcalEvents.py | 26 ++++-- Calendar/ImageDesign.py | 15 ++-- Calendar/ImageFileAdapter.py | 10 ++- Calendar/ImageFramePanel.py | 21 +++-- Calendar/LoopTimer.py | 26 +++--- Calendar/MonthBlockDesign.py | 53 ++++++----- Calendar/MonthOvPanel.py | 103 ++++++++++++--------- Calendar/MonthViewPanel.py | 35 ++++---- Calendar/OwmForecasts.py | 50 +++++++---- Calendar/PanelDesign.py | 19 ++-- Calendar/RssInterface.py | 6 +- Calendar/RssParserPosts.py | 5 +- Calendar/RssPost.py | 5 +- Calendar/RssPostListDesign.py | 21 +++-- Calendar/SingelDayEventListDesign.py | 9 +- Calendar/TableDesign.py | 82 +++++++++-------- Calendar/TechnicalDataDesign.py | 6 +- Calendar/TextDesign.py | 29 +++--- Calendar/TextFormatter.py | 45 ++++++---- Calendar/TextWraper.py | 10 ++- Calendar/Translator.py | 8 +- Calendar/WeatherColumnDesign.py | 64 +++++++------ Calendar/WeatherForecast.py | 5 +- Calendar/WeatherHeaderDesign.py | 60 ++++++++----- Calendar/WeatherInterface.py | 8 +- 54 files changed, 968 insertions(+), 722 deletions(-) diff --git a/Calendar/AgendaListDesign.py b/Calendar/AgendaListDesign.py index c938c6e..f89f15c 100644 --- a/Calendar/AgendaListDesign.py +++ b/Calendar/AgendaListDesign.py @@ -8,9 +8,11 @@ from settings import line_thickness separator_width = line_thickness + class AgendaListDesign (DesignEntity): '''Lists upcoming events in chronological order and groups them by days''' - def __init__ (self, size, calendar, line_spacing = 0, col_spacing = 8, text_size = defaultfontsize, start_date = date.today(), always_add_start_row = True): + + def __init__(self, size, calendar, line_spacing=0, col_spacing=8, text_size=defaultfontsize, start_date=date.today(), always_add_start_row=True): super(AgendaListDesign, self).__init__(size) self.calendar = calendar self.line_spacing = line_spacing @@ -19,19 +21,19 @@ class AgendaListDesign (DesignEntity): self.start_dt = date(start_date.year, start_date.month, start_date.day) self.always_add_start_row = always_add_start_row - def __finish_image__ (self): + def __finish_image__(self): self.__calculate_parameter__() self.__create_infos_events__() self.__draw_infos__() self.__draw_lines__() - def __calculate_parameter__ (self): + def __calculate_parameter__(self): self.__line_height__ = self.line_spacing + self.__get_text_height__() self.__event_number__ = int(int(self.size[1]) // self.__line_height__) self.__date_fontsize__ = self.text_size self.__date_linespace__ = self.line_spacing - def __create_infos_events__ (self): + def __create_infos_events__(self): self.infos = [] self.cell_props = [] fetch_day = self.start_dt @@ -39,7 +41,7 @@ class AgendaListDesign (DesignEntity): day_events = self.calendar.get_day_events(fetch_day) fetch_day_added_once = False for event in day_events: - row = [ "" ] + row = [""] if fetch_day_added_once is False: row.append(date_summary_str(fetch_day)) fetch_day_added_once = True @@ -49,46 +51,48 @@ class AgendaListDesign (DesignEntity): row.append(event_prefix_str(event, fetch_day)) row.append(event.title) self.cell_props.append(self.__get_row_props__(event)) - + self.infos.append(row) fetch_day = fetch_day + timedelta(1) - + if self.infos[0][1] != date_summary_str(self.start_dt) and self.always_add_start_row: row = ["", date_summary_str(self.start_dt), "", ""] props = self.__get_row_props__() self.infos.insert(0, row) self.cell_props.insert(0, props) - - def __draw_infos__ (self): - table = TableDesign(self.size, self.infos, fontsize = self.__date_fontsize__, line_spacing=self.__date_linespace__, col_spacing = self.col_spacing, cell_properties=self.cell_props) + + def __draw_infos__(self): + table = TableDesign(self.size, self.infos, fontsize=self.__date_fontsize__, + line_spacing=self.__date_linespace__, col_spacing=self.col_spacing, cell_properties=self.cell_props) self.draw_design(table) - def __draw_lines__ (self): + def __draw_lines__(self): for i, (_, date, _, _) in enumerate(self.infos[1:]): if date is not "": self.__draw_line__(i + 1) - def __draw_line__ (self, index): + def __draw_line__(self, index): ypos = index * self.__line_height__ - self.line_spacing / 2 pos = (0, ypos) - positions = [ pos, (self.size[0], ypos) ] + positions = [pos, (self.size[0], ypos)] - ImageDraw.Draw(self.__image__).line(positions, fill=colors["fg"], width=separator_width) + ImageDraw.Draw(self.__image__).line( + positions, fill=colors["fg"], width=separator_width) - def __get_row_props__ (self, event = None): + def __get_row_props__(self, event=None): color = colors["fg"] bg_color = colors["bg"] default_cell = { - "color" : color, - "background_color" : bg_color + "color": color, + "background_color": bg_color } if event is not None and event.highlight: color = colors["hl"] cell = { - "color" : color, - "background_color" : bg_color + "color": color, + "background_color": bg_color } - return [default_cell, default_cell, cell, cell ] + return [default_cell, default_cell, cell, cell] def __get_text_height__(self): - return ImageFont.truetype(path + defaultfont, self.text_size).font.height \ No newline at end of file + return ImageFont.truetype(path + defaultfont, self.text_size).font.height diff --git a/Calendar/AgendaListPanel.py b/Calendar/AgendaListPanel.py index b222d45..6895ab0 100644 --- a/Calendar/AgendaListPanel.py +++ b/Calendar/AgendaListPanel.py @@ -13,22 +13,25 @@ seperator_width = line_thickness infolist_size = (1, 0.24) infolist_padding = 0 + class AgendaListPanel (PanelDesign): '''Lists upcoming events in chronological order and groups them by days''' + def __init__(self, size): super(AgendaListPanel, self).__init__(size) self.weather_size = (0, 0) self.info_size = (0, 0) if general_settings["weather-info"]: - self.weather_size = (self.size[0], self.size[1] * weatherheader_height) + self.weather_size = ( + self.size[0], self.size[1] * weatherheader_height) - def add_weather (self, weather): + def add_weather(self, weather): self.weather = weather - def add_calendar (self, calendar): + def add_calendar(self, calendar): self.calendar = calendar - def add_rssfeed (self, rss): + def add_rssfeed(self, rss): if general_settings["info-area"] != "rss": return @@ -41,10 +44,10 @@ class AgendaListPanel (PanelDesign): self.__draw_seperator__(1-infolist_size[1], colors["fg"]) - def add_tasks (self, tasks): + def add_tasks(self, tasks): pass - def add_crypto (self, crypto): + def add_crypto(self, crypto): if general_settings["info-area"] != "crypto": return @@ -64,16 +67,18 @@ class AgendaListPanel (PanelDesign): if general_settings["weather-info"]: self.__draw_weather__() - def __draw_seperator__ (self, height, color): - ImageDraw.Draw(self.__image__).line([ self.__abs_pos__((0, height)), self.__abs_pos__((1, height)) ], fill=color, width=seperator_width) + def __draw_seperator__(self, height, color): + ImageDraw.Draw(self.__image__).line([self.__abs_pos__( + (0, height)), self.__abs_pos__((1, height))], fill=color, width=seperator_width) - def __abs_pos__ (self, pos, size = None): + def __abs_pos__(self, pos, size=None): if size is None: size = self.size return (int(pos[0] * size[0]), int(pos[1] * size[1])) def __draw_calendar__(self): - size = (self.size[0], self.size[1] - self.weather_size[1] - self.info_size[1] - agenda_ypadding) + size = (self.size[0], self.size[1] - self.weather_size[1] - + self.info_size[1] - agenda_ypadding) agenda = AgendaListDesign(size, self.calendar) agenda.pos = (0, agenda_ypadding + self.weather_size[1]) @@ -82,4 +87,4 @@ class AgendaListPanel (PanelDesign): def __draw_weather__(self): header = WeatherHeaderDesign(self.weather_size, self.weather) self.draw_design(header) - self.__draw_seperator__(weatherheader_height, colors["hl"]) \ No newline at end of file + self.__draw_seperator__(weatherheader_height, colors["hl"]) diff --git a/Calendar/Assets.py b/Calendar/Assets.py index 72783d1..e5c750a 100644 --- a/Calendar/Assets.py +++ b/Calendar/Assets.py @@ -9,43 +9,43 @@ path = os.path.dirname(os.path.abspath(__file__)).replace("\\", "/") if path != "" and path[-1] != "/": path += "/" -wpath = path+'weather-icons/' -opath = path+'other/' -fpath = 'fonts/' +wpath = path+'weather-icons/' +opath = path+'other/' +fpath = 'fonts/' -tempicon = im_open(opath+'temperature.jpeg') -humicon = im_open(opath+'humidity.jpeg') -no_response= im_open(opath+'cloud-no-response.jpeg') -sunriseicon = im_open(opath+'wi-sunrise.jpeg') -sunseticon = im_open(opath+'wi-sunset.jpeg') -windicon = im_open(opath+'wi-strong-wind.jpeg') +tempicon = im_open(opath+'temperature.jpeg') +humicon = im_open(opath+'humidity.jpeg') +no_response = im_open(opath+'cloud-no-response.jpeg') +sunriseicon = im_open(opath+'wi-sunrise.jpeg') +sunseticon = im_open(opath+'wi-sunset.jpeg') +windicon = im_open(opath+'wi-strong-wind.jpeg') fonts = { - "extralight" : fpath + "Assistant-ExtraLight.otf", - "light" : fpath + "Assistant-Light.otf", - "regular" : fpath + "Assistant-Regular.otf", - "semibold" : fpath + "Assistant-SemiBold.otf", - "bold" : fpath + "Assistant-Bold.otf", - "extrabold" : fpath + "Assistant-ExtraBold.otf" + "extralight": fpath + "Assistant-ExtraLight.otf", + "light": fpath + "Assistant-Light.otf", + "regular": fpath + "Assistant-Regular.otf", + "semibold": fpath + "Assistant-SemiBold.otf", + "bold": fpath + "Assistant-Bold.otf", + "extrabold": fpath + "Assistant-ExtraBold.otf" } defaultfont = fonts[font_boldness] defaultfontsize = int(font_size) weathericons = { -'01d': 'wi-day-sunny', '02d':'wi-day-cloudy', '03d': 'wi-cloudy', -'04d': 'wi-cloudy-windy', '09d': 'wi-showers', '10d':'wi-rain', -'11d':'wi-thunderstorm', '13d':'wi-snow', '50d': 'wi-fog', -'01n': 'wi-night-clear', '02n':'wi-night-cloudy', -'03n': 'wi-night-cloudy', '04n': 'wi-night-cloudy', -'09n': 'wi-night-showers', '10n':'wi-night-rain', -'11n':'wi-night-thunderstorm', '13n':'wi-night-snow', -'50n': 'wi-night-alt-cloudy-windy'} + '01d': 'wi-day-sunny', '02d': 'wi-day-cloudy', '03d': 'wi-cloudy', + '04d': 'wi-cloudy-windy', '09d': 'wi-showers', '10d': 'wi-rain', + '11d': 'wi-thunderstorm', '13d': 'wi-snow', '50d': 'wi-fog', + '01n': 'wi-night-clear', '02n': 'wi-night-cloudy', + '03n': 'wi-night-cloudy', '04n': 'wi-night-cloudy', + '09n': 'wi-night-showers', '10n': 'wi-night-rain', + '11n': 'wi-night-thunderstorm', '13n': 'wi-night-snow', + '50n': 'wi-night-alt-cloudy-windy'} colors = { - "hl" : "red", - "fg" : "black", - "bg" : "white" + "hl": "red", + "fg": "black", + "bg": "white" } supported_img_formats = [ @@ -92,4 +92,4 @@ supported_img_formats = [ "PSD", "WAL", "XPM", -] \ No newline at end of file +] diff --git a/Calendar/BoxDesign.py b/Calendar/BoxDesign.py index 2138d84..3fbf281 100644 --- a/Calendar/BoxDesign.py +++ b/Calendar/BoxDesign.py @@ -1,8 +1,10 @@ from DesignEntity import DesignEntity from PIL import ImageDraw, ImageOps + class BoxDesign (DesignEntity): """Redefinition of ImageDraw.Draw.Rectangle""" + def __init__(self, size, fill=None, outline=None, width=0): super(BoxDesign, self).__init__((size[0]+1, size[1]+1), mask=True) self.size = size @@ -12,9 +14,10 @@ class BoxDesign (DesignEntity): self.width = width def __define_corners__(self): - topleft = (0,0) + topleft = (0, 0) bottomright = self.size self.corners = [topleft, bottomright] - def __finish_image__ (self): - ImageDraw.Draw(self.__image__).rectangle(self.corners, fill=self.fill, outline=self.outline, width=self.width) \ No newline at end of file + def __finish_image__(self): + ImageDraw.Draw(self.__image__).rectangle( + self.corners, fill=self.fill, outline=self.outline, width=self.width) diff --git a/Calendar/CalendarEvent.py b/Calendar/CalendarEvent.py index 316d054..d3a058b 100644 --- a/Calendar/CalendarEvent.py +++ b/Calendar/CalendarEvent.py @@ -1,6 +1,7 @@ class CalendarEvent (object): """Defines a calendar event, independent of any implementation""" - def __init__ (self): + + def __init__(self): self.begin_datetime = None self.end_datetime = None self.duration = None @@ -19,4 +20,4 @@ class CalendarEvent (object): self.fetch_datetime = None def __repr__(self): - return self.title \ No newline at end of file + return self.title diff --git a/Calendar/CalendarInterface.py b/Calendar/CalendarInterface.py index 90dc030..740a5cc 100644 --- a/Calendar/CalendarInterface.py +++ b/Calendar/CalendarInterface.py @@ -4,31 +4,34 @@ from dateutil.rrule import rrulestr from dateutil.parser import parse import calendar + class CalendarInterface (DataSourceInterface): """Interface for fetching and processing calendar event information.""" - def __init__ (self): + + def __init__(self): self.events = [] - def reload (self): + def reload(self): if self.is_available() == False: return self.events = self.__get_events__() self.events = self.__sort_events__(self.events) - def __sort_events__ (self, events): - events.sort(key=lambda x : x.begin_datetime) + def __sort_events__(self, events): + events.sort(key=lambda x: x.begin_datetime) return events - def __sort_event_types__ (self, events): + def __sort_event_types__(self, events): multiday = [ev for ev in events if ev.multiday] allday = [ev for ev in events if ev.allday and ev.multiday == False] - timed = [ev for ev in events if ev.allday == False and ev.multiday == False] + timed = [ev for ev in events if ev.allday == + False and ev.multiday == False] return multiday + allday + timed - def __get_events__ (self): + def __get_events__(self): raise NotImplementedError("Functions needs to be implemented") - def get_upcoming_events (self, timespan = None, start_time = None): + def get_upcoming_events(self, timespan=None, start_time=None): if timespan is None: timespan = timedelta(31) if start_time == None: @@ -36,28 +39,31 @@ class CalendarInterface (DataSourceInterface): start_time = datetime.now(local_tzinfo) return self.__get_events_in_range__(start_time, timespan) - def get_today_events (self): + def get_today_events(self): return self.get_day_events(date.today()) - def get_day_events (self, day): + def get_day_events(self, day): if type(day) is not type(date.today()): - raise TypeError("get_day_events only takes date-objects as parameters, not \"%s\"" % str(type(day))) + raise TypeError( + "get_day_events only takes date-objects as parameters, not \"%s\"" % str(type(day))) local_tzinfo = datetime.now(timezone.utc).astimezone().tzinfo - day_start = datetime(day.year, day.month, day.day, 0, 0, 0, 0, local_tzinfo) + day_start = datetime(day.year, day.month, day.day, + 0, 0, 0, 0, local_tzinfo) return self.__get_events_in_range__(day_start, timedelta(1)) - def get_month_events (self, month = -1, year = -1): + def get_month_events(self, month=-1, year=-1): if month < 0: month = datetime.now().month if year < 0: year = datetime.now().year - + local_tzinfo = datetime.now(timezone.utc).astimezone().tzinfo month_start = datetime(year, month, 1, 0, 0, 0, 0, local_tzinfo) - month_days = calendar.monthrange(month_start.year, month_start.month)[1] + month_days = calendar.monthrange( + month_start.year, month_start.month)[1] return self.__get_events_in_range__(month_start, timedelta(month_days)) - def __get_events_in_range__ (self, start, duration): + def __get_events_in_range__(self, start, duration): if self.events is None: return [] @@ -66,14 +72,15 @@ class CalendarInterface (DataSourceInterface): events_in_range = [] for event in self.events: - event_occurrence = self.__get_if_event_in_range__(event, start, duration) + event_occurrence = self.__get_if_event_in_range__( + event, start, duration) if event_occurrence: events_in_range.extend(event_occurrence) events_in_range = self.__sort_events__(events_in_range) return self.__sort_event_types__(events_in_range) - def __get_if_event_in_range__ (self, event, start, duration): + def __get_if_event_in_range__(self, event, start, duration): '''Returns list or None''' if event is None: return None @@ -83,7 +90,7 @@ class CalendarInterface (DataSourceInterface): else: return self.__is_repeating_in_range__(event, start, duration) - def __is_onetime_in_range__ (self, event, start, duration): + def __is_onetime_in_range__(self, event, start, duration): if event.begin_datetime > start: first_start = start first_duration = duration @@ -94,37 +101,39 @@ class CalendarInterface (DataSourceInterface): second_start = start if (second_start - first_start) < first_duration: - return [ event ] + return [event] else: return None - def __is_repeating_in_range__ (self, event, start, duration): + def __is_repeating_in_range__(self, event, start, duration): end = start + duration occurrences = [] try: - r_string="" - r_string=self.__add_timezoneawarness__(event.rrule) - rule=rrulestr(r_string,dtstart=event.begin_datetime) + r_string = "" + r_string = self.__add_timezoneawarness__(event.rrule) + rule = rrulestr(r_string, dtstart=event.begin_datetime) for occurrence in rule: if occurrence - end > timedelta(0): return occurrences - merged_event = self.__merge_event_data__(event, start=occurrence) + merged_event = self.__merge_event_data__( + event, start=occurrence) if self.__is_onetime_in_range__(merged_event, start, duration): occurrences.append(merged_event) return occurrences except Exception as ex: - print("\"is_repeating_in_range\" failed while processing: dtstart="+str(event.begin_datetime)+" dtstart.tzinfo="+str(event.begin_datetime.tzinfo)+" rrule="+r_string) + print("\"is_repeating_in_range\" failed while processing: dtstart="+str(event.begin_datetime) + + " dtstart.tzinfo="+str(event.begin_datetime.tzinfo)+" rrule="+r_string) raise ex - def __merge_event_data__ (self, event, start = None): + def __merge_event_data__(self, event, start=None): if start is not None: event.begin_datetime = start event.end_datetime = start + event.duration - + return event - def __add_timezoneawarness__ (self, rrule): + def __add_timezoneawarness__(self, rrule): """UNTIL must be specified in UTC when DTSTART is timezone-aware (which it is)""" if "UNTIL" not in rrule: return rrule @@ -137,8 +146,8 @@ class CalendarInterface (DataSourceInterface): tz_index = until_index + len(until_template) if until_index < 0 or (tz_index < len(rrule) and rrule[tz_index] is "T"): return rrule - + if tz_index == len(rrule): return rrule + timezone_str else: - return rrule[:tz_index] + timezone_str + rrule[tz_index:] \ No newline at end of file + return rrule[:tz_index] + timezone_str + rrule[tz_index:] diff --git a/Calendar/CryptoCoin.py b/Calendar/CryptoCoin.py index 3ad4f29..8736791 100644 --- a/Calendar/CryptoCoin.py +++ b/Calendar/CryptoCoin.py @@ -1,5 +1,5 @@ class CryptoCoin(object): - def __init__ (self): + def __init__(self): self.name = None self.symbol = None self.price = None @@ -7,4 +7,4 @@ class CryptoCoin(object): self.currency = None self.datetime = None - self.fetch_datetime = None \ No newline at end of file + self.fetch_datetime = None diff --git a/Calendar/CryptoInterface.py b/Calendar/CryptoInterface.py index 5cceb75..a6cc351 100644 --- a/Calendar/CryptoInterface.py +++ b/Calendar/CryptoInterface.py @@ -1,5 +1,6 @@ from DataSourceInterface import DataSourceInterface + class CryptoInterface(DataSourceInterface): def __init__(self): self.crypto_coins = [] diff --git a/Calendar/CryptoListDesign.py b/Calendar/CryptoListDesign.py index 949e8a4..18028d6 100644 --- a/Calendar/CryptoListDesign.py +++ b/Calendar/CryptoListDesign.py @@ -6,27 +6,30 @@ from settings import crypto_coins xpadding = 5 + class CryptoListDesign (DesignEntity): - def __init__ (self, size, crypto, text_size = defaultfontsize): + def __init__(self, size, crypto, text_size=defaultfontsize): super(CryptoListDesign, self).__init__(size) self.crypto = crypto self.text_size = text_size self.matrix = self.__get_matrix__() - def __finish_image__ (self): + def __finish_image__(self): col_spacing = 10 if len(self.matrix) > 0: col_spacing = (self.size[0] / len(self.matrix[0])) * 0.5 - table_design = TableDesign(self.size, matrix=self.matrix, col_spacing=col_spacing, fontsize = self.text_size, mask=False, truncate_rows=True) - table_design.pos = (xpadding, 0) + table_design = TableDesign(self.size, matrix=self.matrix, col_spacing=col_spacing, + fontsize=self.text_size, mask=False, truncate_rows=True) + table_design.pos = (xpadding, 0) self.draw_design(table_design) - def __get_matrix__ (self): + def __get_matrix__(self): matrix = [] coins = self.crypto.get_coins() for coin in coins: - row = [ coin.symbol.upper(), coin.name, coin.currency + " " + str(coin.price), "% " + str(coin.day_change) ] + row = [coin.symbol.upper(), coin.name, coin.currency + " " + + str(coin.price), "% " + str(coin.day_change)] matrix.append(row) return matrix diff --git a/Calendar/DataSourceInterface.py b/Calendar/DataSourceInterface.py index 4c5004c..b6b541a 100644 --- a/Calendar/DataSourceInterface.py +++ b/Calendar/DataSourceInterface.py @@ -1,7 +1,8 @@ class DataSourceInterface (object): """Interface for child interfaces that fetch data.""" - def is_available (self): + + def is_available(self): raise NotImplementedError("Functions needs to be implemented") - def reload (self): - raise NotImplementedError("Functions needs to be implemented") \ No newline at end of file + def reload(self): + raise NotImplementedError("Functions needs to be implemented") diff --git a/Calendar/DayBoxDesign.py b/Calendar/DayBoxDesign.py index 839a4f1..e2fea33 100644 --- a/Calendar/DayBoxDesign.py +++ b/Calendar/DayBoxDesign.py @@ -4,8 +4,10 @@ from TextDesign import TextDesign header_height = 0.2 + class DayBoxDesign (DesignEntity): """Represents a day with its events in a box.""" + def __init__(self, size, date): super(DayBoxDesign, self).__init__(size) self.date = date @@ -28,4 +30,4 @@ class DayBoxDesign (DesignEntity): event_list = SingelDayEventListDesign(size, events) event_list.pos = pos - self.draw_design(event_list) \ No newline at end of file + self.draw_design(event_list) diff --git a/Calendar/DayHeaderDesign.py b/Calendar/DayHeaderDesign.py index 848be4e..817163c 100644 --- a/Calendar/DayHeaderDesign.py +++ b/Calendar/DayHeaderDesign.py @@ -27,62 +27,71 @@ numberbox_font_color = colors["bg"] numberbox_background_color = colors["hl"] weekday_font = fonts["bold"] + class DayHeaderDesign (DesignEntity): """Detailed and big view of a given date.""" - def __init__ (self, size, date): + + def __init__(self, size, date): super(DayHeaderDesign, self).__init__(size) self.weather_column_width = 0 self.date = date - def add_weather (self, weather): + def add_weather(self, weather): if general_settings["weather-info"] == False: return - forecast = weather.get_forecast_in_days(self.date.day - date.today().day) + forecast = weather.get_forecast_in_days( + self.date.day - date.today().day) self.weather_column_width = weathercolumn_y_size[0] * self.size[1] - size = (self.weather_column_width, weathercolumn_y_size[1] * self.size[1]) + size = (self.weather_column_width, + weathercolumn_y_size[1] * self.size[1]) pos = (self.size[0] - size[0], 0) design = WeatherColumnDesign(size, forecast) design.pos = pos self.draw_design(design) - def add_calendar (self, calendar): + def add_calendar(self, calendar): local_tzinfo = datetime.now(timezone.utc).astimezone().tzinfo now = datetime.now(local_tzinfo) - time_until_tomorrow = (datetime(now.year, now.month, now.day, 0, 0, 0, 0, local_tzinfo) + timedelta(1)) - now - self.__draw_event_list__(calendar.get_upcoming_events(time_until_tomorrow, now)) + time_until_tomorrow = (datetime( + now.year, now.month, now.day, 0, 0, 0, 0, local_tzinfo) + timedelta(1)) - now + self.__draw_event_list__( + calendar.get_upcoming_events(time_until_tomorrow, now)) - def add_events (self, events): + def add_events(self, events): self.__draw_event_list__(events) - def add_rssfeed (self, rss): + def add_rssfeed(self, rss): pass - def add_crypto (self, crypto): + def add_crypto(self, crypto): pass - def __finish_image__ (self): + def __finish_image__(self): self.__draw_number_square__() self.__draw_month__() - def __draw_event_list__ (self, events): + def __draw_event_list__(self, events): box_ypos = numberbox_ypos * self.size[1] box_xpos = numberbox_ypos * self.size[1] box_height = numberbox_height * self.size[1] xpadding = eventlist_xpadding * self.size[0] ypadding = eventlist_ypadding * self.size[1] monthbox_height = (monthbox_ypadding + month_height) * self.size[1] - pos = (box_xpos + box_height + xpadding, box_ypos + monthbox_height + ypadding) - size = (self.size[0] - pos[0] - self.weather_column_width, self.size[1] - pos[1] - box_ypos) + pos = (box_xpos + box_height + xpadding, + box_ypos + monthbox_height + ypadding) + size = (self.size[0] - pos[0] - self.weather_column_width, + self.size[1] - pos[1] - box_ypos) fontsize = eventlist_static_fontsize rel_dates = [self.date for _ in range(len(events))] - event_list = SingelDayEventListDesign(size, events, fontsize, event_prefix_rel_dates = rel_dates) + event_list = SingelDayEventListDesign( + size, events, fontsize, event_prefix_rel_dates=rel_dates) event_list.pos = pos self.draw_design(event_list) - def __draw_month__ (self): + def __draw_month__(self): font_size = int(month_height * self.size[1]) xpadding = int(monthbox_xpadding * self.size[0]) ypadding = int(monthbox_ypadding * self.size[1]) @@ -96,20 +105,20 @@ class DayHeaderDesign (DesignEntity): month.pos = box_pos self.draw_design(month) - def __draw_number_square__ (self): + def __draw_number_square__(self): box_height = numberbox_height * self.size[1] box_ypos = numberbox_ypos * self.size[1] box_pos = (box_ypos, box_ypos) box_size = (box_height, box_height) - box = BoxDesign(box_size, fill = numberbox_background_color) + box = BoxDesign(box_size, fill=numberbox_background_color) box.pos = box_pos self.draw_design(box) self.__draw_today_number__() self.__draw_weekday__() - def __draw_today_number__ (self): + def __draw_today_number__(self): font_size = number_height * self.size[1] box_height = numberbox_height * self.size[1] box_ypos = numberbox_ypos * self.size[1] @@ -118,12 +127,13 @@ class DayHeaderDesign (DesignEntity): pos = (box_ypos, box_ypos + ypadding) day_text = self.__get_day_text__() - number = TextDesign(size, text=day_text, background_color=numberbox_background_color, color=numberbox_font_color, fontsize=font_size, horizontalalignment="center", verticalalignment="center") + number = TextDesign(size, text=day_text, background_color=numberbox_background_color, + color=numberbox_font_color, fontsize=font_size, horizontalalignment="center", verticalalignment="center") number.pos = pos number.mask = False self.draw_design(number) - def __draw_weekday__ (self): + def __draw_weekday__(self): font_size = weekday_height * self.size[1] box_height = numberbox_height * self.size[1] size = (box_height, weekdaybox_height * box_height) @@ -131,13 +141,14 @@ class DayHeaderDesign (DesignEntity): pos = (box_ypos, box_ypos) week_day_name = self.date.strftime("%A") - week_day = TextDesign(size, text=week_day_name, background_color=numberbox_background_color, color=numberbox_font_color, fontsize=font_size, horizontalalignment="center", verticalalignment = "center", font=weekday_font) + week_day = TextDesign(size, text=week_day_name, background_color=numberbox_background_color, color=numberbox_font_color, + fontsize=font_size, horizontalalignment="center", verticalalignment="center", font=weekday_font) week_day.pos = pos week_day.mask = False self.draw_design(week_day) - def __abs_co__ (self, coordinates): - return (int(coordinates[0] * self.size[0]),int(coordinates[1] * self.size[1])) + def __abs_co__(self, coordinates): + return (int(coordinates[0] * self.size[0]), int(coordinates[1] * self.size[1])) - def __get_day_text__ (self): + def __get_day_text__(self): return str(self.date.day) diff --git a/Calendar/DayListPanel.py b/Calendar/DayListPanel.py index e271208..849db8a 100644 --- a/Calendar/DayListPanel.py +++ b/Calendar/DayListPanel.py @@ -12,8 +12,8 @@ from CryptoListDesign import CryptoListDesign from settings import line_thickness from math import ceil -todayheader_pos = (0,0) -todayheader_size = (1,0.25) +todayheader_pos = (0, 0) +todayheader_size = (1, 0.25) lines_thickness = line_thickness infoarea_replacedrowscount = 3 @@ -24,43 +24,46 @@ dayrow_max_format = 70 / 384 rss_y_padding = 5 crypto_y_padding = 5 + class DayListPanel (PanelDesign): """Overview that focuses on the current day and lists following days in a list below.""" - def __init__ (self, size): + + def __init__(self, size): super(DayListPanel, self).__init__(size) self.__day_rows__ = [] self.__calc_dayrow_size__() self.__first_render__() - def __first_render__ (self): + def __first_render__(self): self.__draw_today_header__() self.__draw_day_rows__() - def add_weather (self, weather): + def add_weather(self, weather): for row in self.__day_rows__: row.add_weather(weather) - def add_calendar (self, calendar): + def add_calendar(self, calendar): for row in self.__day_rows__: row.add_calendar(calendar) - def add_rssfeed (self, rss): + def add_rssfeed(self, rss): for row in self.__day_rows__: row.add_rssfeed(rss) if general_settings["info-area"] is "rss": self.__day_rows__ = self.__day_rows__[:-infoarea_replacedrowscount] self.__draw_rss_infoarea__(rss) - def add_crypto (self, crypto): + def add_crypto(self, crypto): if general_settings["info-area"] is "crypto": self.__draw_crypto_infoarea__(crypto) - def add_tasks (self, tasks): + def add_tasks(self, tasks): pass - def __draw_rss_infoarea__ (self, rss): - height = infoarea_replacedrowscount * self.dayrow_size[1] * self.size[1] - rss_y_padding + def __draw_rss_infoarea__(self, rss): + height = infoarea_replacedrowscount * \ + self.dayrow_size[1] * self.size[1] - rss_y_padding ypos = self.size[1] - height size = (self.size[0], height) pos = (0, ypos) @@ -69,8 +72,9 @@ class DayListPanel (PanelDesign): design.pos = pos self.draw_design(design) - def __draw_crypto_infoarea__ (self, crypto): - height = infoarea_replacedrowscount * self.dayrow_size[1] * self.size[1] - crypto_y_padding + def __draw_crypto_infoarea__(self, crypto): + height = infoarea_replacedrowscount * \ + self.dayrow_size[1] * self.size[1] - crypto_y_padding ypos = self.size[1] - height size = (self.size[0], height) pos = (0, ypos) @@ -79,23 +83,24 @@ class DayListPanel (PanelDesign): acutal_height = design.get_estimated_height() design.pos = (pos[0], pos[1] + (height - acutal_height)) self.draw_design(design) - - replaced_rows = ceil(acutal_height / (self.dayrow_size[1] * self.size[1])) + + replaced_rows = ceil( + acutal_height / (self.dayrow_size[1] * self.size[1])) self.__day_rows__ = self.__day_rows__[:-replaced_rows] - def __draw_day_rows__ (self): + def __draw_day_rows__(self): following_days = self.__get_following_days__() for i, date in enumerate(following_days): row = DayRowDesign(self.__abs_co__(self.dayrow_size), date) row.pos = self.__get_day_row_pos__(i) self.__day_rows__.append(row) - def __get_day_row_pos__ (self, i): + def __get_day_row_pos__(self, i): ypos = self.size[1] * dayrowsarea_ypos down_shift = i * self.dayrow_size[1] * self.size[1] return (0, int(ypos + down_shift)) - def __calc_dayrow_size__ (self): + def __calc_dayrow_size__(self): max_area_height = dayrowsarea_height * self.size[1] max_row_number = max_area_height / (dayrow_min_format * self.size[0]) min_row_number = max_area_height / (dayrow_max_format * self.size[0]) @@ -110,8 +115,9 @@ class DayListPanel (PanelDesign): following_days.append(date.today() + timedelta(days=i + 1)) return following_days - def __draw_today_header__ (self): - header = DayHeaderDesign(self.__abs_co__(todayheader_size), date.today()) + def __draw_today_header__(self): + header = DayHeaderDesign(self.__abs_co__( + todayheader_size), date.today()) header.pos = self.__abs_co__(todayheader_pos) self.__day_rows__.append(header) @@ -122,7 +128,8 @@ class DayListPanel (PanelDesign): for ypos in positions: line_start = (0, ypos) line_end = (self.size[0], ypos) - ImageDraw.Draw(self.__image__).line([line_start, line_end], fill=colors["fg"], width=lines_thickness) + ImageDraw.Draw(self.__image__).line( + [line_start, line_end], fill=colors["fg"], width=lines_thickness) def __finish_panel__(self): for design in self.__day_rows__: @@ -130,4 +137,4 @@ class DayListPanel (PanelDesign): self.__draw_lines__() def __abs_co__(self, coordinates): - return (int(coordinates[0] * self.size[0]),int(coordinates[1] * self.size[1])) + return (int(coordinates[0] * self.size[0]), int(coordinates[1] * self.size[1])) diff --git a/Calendar/DayRowDesign.py b/Calendar/DayRowDesign.py index 7f6d44d..f51e413 100644 --- a/Calendar/DayRowDesign.py +++ b/Calendar/DayRowDesign.py @@ -20,25 +20,27 @@ eventlist_y_fontsize = 0.2 font = fonts["light"] + class DayRowDesign (DesignEntity): """Detailed view of a given date.""" - def __init__ (self, size, date): + + def __init__(self, size, date): super(DayRowDesign, self).__init__(size) self.__init_image__() self.date = date - def add_weather (self, weather): + def add_weather(self, weather): if weather.is_available is False: return self.__draw_forecast__(weather) - def add_calendar (self, calendar): + def add_calendar(self, calendar): self.__draw_event_list__(calendar) - def add_rssfeed (self, rss): + def add_rssfeed(self, rss): pass - - def __draw_event_list__ (self, calendar): + + def __draw_event_list__(self, calendar): number_width = daynumber_y_size[0] * self.size[1] ypos = eventlist_ypos * self.size[1] weather_width = 0 @@ -50,12 +52,14 @@ class DayRowDesign (DesignEntity): events = calendar.get_day_events(self.date) rel_dates = [self.date for _ in range(len(events))] - event_list = SingelDayEventListDesign(size, events, fontsize, event_prefix_rel_dates = rel_dates) + event_list = SingelDayEventListDesign( + size, events, fontsize, event_prefix_rel_dates=rel_dates) event_list.pos = pos self.draw_design(event_list) - def __draw_forecast__ (self, weather): - forecast = weather.get_forecast_in_days(self.date.day - datetime.today().day) + def __draw_forecast__(self, weather): + forecast = weather.get_forecast_in_days( + self.date.day - datetime.today().day) if forecast is None: return @@ -68,44 +72,48 @@ class DayRowDesign (DesignEntity): resized_icon = icon.resize(size, resample=Image.LANCZOS) self.draw(resized_icon, pos) - def __finish_image__ (self): + def __finish_image__(self): self.__draw_weekday__() self.__draw_day_number__() - def __draw_weekday__ (self): + def __draw_weekday__(self): font_size = int(weekday_fontsize * self.size[1]) - size = (weekday_y_size[0] * self.size[1], weekday_y_size[1] * self.size[1]) + size = (weekday_y_size[0] * self.size[1], + weekday_y_size[1] * self.size[1]) ypos = weekday_ypos * self.size[1] pos = (0, ypos) color = self.__get_day_color__() week_day_name = self.date.strftime("%a") - week_day = TextDesign(size, text=week_day_name, font=font, color=color, fontsize=font_size, horizontalalignment="center", verticalalignment="top") + week_day = TextDesign(size, text=week_day_name, font=font, color=color, + fontsize=font_size, horizontalalignment="center", verticalalignment="top") week_day.pos = pos week_day.mask = False self.draw_design(week_day) - def __draw_day_number__ (self): + def __draw_day_number__(self): font_size = int(daynumber_fontsize * self.size[1]) ypadding = daynumber_ypadding * self.size[1] - size = (daynumber_y_size[0] * self.size[1], daynumber_y_size[1] * self.size[1]) + size = (daynumber_y_size[0] * self.size[1], + daynumber_y_size[1] * self.size[1]) pos = (0, ypadding) day_text = self.__get_day_text__() color = self.__get_day_color__() - number = TextDesign(size, text=day_text, font=font, color=color, fontsize=font_size, horizontalalignment="center", verticalalignment="bottom") + number = TextDesign(size, text=day_text, font=font, color=color, + fontsize=font_size, horizontalalignment="center", verticalalignment="bottom") number.pos = pos self.draw_design(number) - def __abs_co__ (self, coordinates): - return (int(coordinates[0] * self.size[0]),int(coordinates[1] * self.size[1])) + def __abs_co__(self, coordinates): + return (int(coordinates[0] * self.size[0]), int(coordinates[1] * self.size[1])) - def __get_day_text__ (self): + def __get_day_text__(self): return str(self.date.day) - def __get_day_color__ (self): + def __get_day_color__(self): """Depending on week_starts_on""" if week_starts_on == "Monday" and self.date.strftime("%w") == "0": return colors["hl"] diff --git a/Calendar/DayViewPanel.py b/Calendar/DayViewPanel.py index a35447c..3277231 100644 --- a/Calendar/DayViewPanel.py +++ b/Calendar/DayViewPanel.py @@ -18,25 +18,28 @@ infoarea_replaced_hours = 4 infoarea_borderline_width = 1 infoarea_padding = 5 + class DayViewPanel (PanelDesign): """Overview that focuses on the current day and shows a timeline split into hours.""" - def __init__ (self, size): + + def __init__(self, size): super(DayViewPanel, self).__init__(size) self.shownhours_count = default_shownhours_count if general_settings["info-area"] not in ["", "empty"]: self.shownhours_count -= infoarea_replaced_hours self.__first_render__() - def __first_render__ (self): + def __first_render__(self): self.__init_header__() self.__init_hourlist__() - def add_weather (self, weather): + def add_weather(self, weather): self.__header__.add_weather(weather) - def add_calendar (self, calendar): - allday_ev, timed_ev = self.__split_events__(calendar.get_today_events()) + def add_calendar(self, calendar): + allday_ev, timed_ev = self.__split_events__( + calendar.get_today_events()) self.__header__.add_events(allday_ev) self.__hourlist__.add_events(timed_ev) @@ -44,12 +47,12 @@ class DayViewPanel (PanelDesign): self.__draw_event_list__(calendar) self.__draw_infoarea_line__() - def add_rssfeed (self, rss): + def add_rssfeed(self, rss): if general_settings["info-area"] == "rss": self.__draw_rss_feed__(rss) self.__draw_infoarea_line__() - def add_crypto (self, crypto): + def add_crypto(self, crypto): if general_settings["info-area"] == "crypto": self.__draw_crypto_feed__(crypto) self.__draw_infoarea_line__() @@ -60,10 +63,12 @@ class DayViewPanel (PanelDesign): line_start = (0, ypos) line_end = (self.size[0], ypos) - ImageDraw.Draw(self.__image__).line([ line_start, line_end ], fill=colors["fg"], width=infoarea_borderline_width) + ImageDraw.Draw(self.__image__).line( + [line_start, line_end], fill=colors["fg"], width=infoarea_borderline_width) def __draw_rss_feed__(self, rss): - height = infoarea_replaced_hours * self.__hourlist__.row_size[1] - infoarea_padding + height = infoarea_replaced_hours * \ + self.__hourlist__.row_size[1] - infoarea_padding size = (self.size[0], height) pos = (0, self.size[1] - size[1]) @@ -72,7 +77,8 @@ class DayViewPanel (PanelDesign): self.draw_design(rss) def __draw_crypto_feed__(self, crypto): - height = infoarea_replaced_hours * self.__hourlist__.row_size[1] - infoarea_padding + height = infoarea_replaced_hours * \ + self.__hourlist__.row_size[1] - infoarea_padding size = (self.size[0], height) pos = (0, self.size[1] - size[1]) @@ -81,9 +87,9 @@ class DayViewPanel (PanelDesign): crypto.pos = (pos[0], pos[1] + (height - acutal_height)) self.draw_design(crypto) - def __draw_event_list__(self, calendar): - height = infoarea_replaced_hours * self.__hourlist__.row_size[1] - infoarea_padding + height = infoarea_replaced_hours * \ + self.__hourlist__.row_size[1] - infoarea_padding size = (self.size[0], height) pos = (0, self.size[1] - size[1]) @@ -91,21 +97,23 @@ class DayViewPanel (PanelDesign): events.pos = pos self.draw_design(events) - def add_tasks (self, tasks): + def add_tasks(self, tasks): pass - def __finish_panel__ (self): + def __finish_panel__(self): self.draw_design(self.__header__) self.draw_design(self.__hourlist__) - def __init_header__ (self): - self.__header__ = DayHeaderDesign(self.__abs_co__(header_size), date.today()) + def __init_header__(self): + self.__header__ = DayHeaderDesign( + self.__abs_co__(header_size), date.today()) self.__header__.pos = (0, 0) - def __init_hourlist__ (self): + def __init_hourlist__(self): start, end = self.__get_current_hour_range__() size = self.__abs_co__(hourlist_size) - size = (size[0], size[1] * self.shownhours_count / default_shownhours_count) + size = (size[0], size[1] * self.shownhours_count / + default_shownhours_count) self.__hourlist__ = HourListDesign(size, start, end) self.__hourlist__.pos = (0, self.__header__.size[1]) @@ -119,10 +127,10 @@ class DayViewPanel (PanelDesign): return start_hour, start_hour + additional_hours - def __abs_co__ (self, coordinates): - return (int(coordinates[0] * self.size[0]),int(coordinates[1] * self.size[1])) + def __abs_co__(self, coordinates): + return (int(coordinates[0] * self.size[0]), int(coordinates[1] * self.size[1])) - def __split_events__ (self, events): + def __split_events__(self, events): allday_ev = [] timed_ev = [] @@ -140,7 +148,7 @@ class DayViewPanel (PanelDesign): timed_ev.append(event) return allday_ev, timed_ev - def __is_today__ (self, dt): + def __is_today__(self, dt): today = date.today() return dt.day == today.day and \ dt.month == today.month and \ diff --git a/Calendar/DebugConsole.py b/Calendar/DebugConsole.py index 85d4271..885be91 100644 --- a/Calendar/DebugConsole.py +++ b/Calendar/DebugConsole.py @@ -3,9 +3,11 @@ from Assets import weathericons from datetime import datetime import traceback + class DebugConsole (DebugInterface): """Defines concrete console export of debug objects""" - def print_event (self, event): + + def print_event(self, event): print("\nCalendarEvent:") print("---------------------") print('Begin datetime: ' + str(event.begin_datetime)) @@ -22,7 +24,7 @@ class DebugConsole (DebugInterface): print('Location: ' + str(event.location)) print('Fetch datetime: ' + str(event.fetch_datetime)) - def print_forecast (self, forecast): + def print_forecast(self, forecast): print("\nWeatherForecast:") print("---------------------") print('Air temperature: ' + str(forecast.air_temperature)) @@ -45,12 +47,12 @@ class DebugConsole (DebugInterface): print('Location: ' + str(forecast.location)) print('Fetch datetime: ' + str(forecast.fetch_datetime)) - def print_line (self, content): + def print_line(self, content): if content is None: return print(str(content)) - def print_err (self, exception, msg=""): + def print_err(self, exception, msg=""): if exception is None: return @@ -60,4 +62,4 @@ class DebugConsole (DebugInterface): content += "\n" + str(msg) + "\n" traceback.print_exc() - self.print_line(str(content)) \ No newline at end of file + self.print_line(str(content)) diff --git a/Calendar/DebugInterface.py b/Calendar/DebugInterface.py index a6dcec2..cd06cbd 100644 --- a/Calendar/DebugInterface.py +++ b/Calendar/DebugInterface.py @@ -1,13 +1,14 @@ class DebugInterface (object): """Defines general interface for debugging operations""" - def print_event (self, event): + + def print_event(self, event): raise NotImplementedError("Functions needs to be implemented") - def print_forecast (self, forecast): + def print_forecast(self, forecast): raise NotImplementedError("Functions needs to be implemented") - def print_line (self, content): + def print_line(self, content): raise NotImplementedError("Functions needs to be implemented") - def print_err (self, exception, msg=""): - raise NotImplementedError("Functions needs to be implemented") \ No newline at end of file + def print_err(self, exception, msg=""): + raise NotImplementedError("Functions needs to be implemented") diff --git a/Calendar/DesignEntity.py b/Calendar/DesignEntity.py index c84f093..dc2f874 100644 --- a/Calendar/DesignEntity.py +++ b/Calendar/DesignEntity.py @@ -3,10 +3,12 @@ from Assets import colors masking_threshold = 200 + class DesignEntity (object): """General entity that can be drawn on to a panel design or other design entities.""" - def __init__ (self, size, mask=False, invert_mask=False, color_key=False): + + def __init__(self, size, mask=False, invert_mask=False, color_key=False): self.size = size self.pos = (0, 0) self.mask = mask @@ -15,36 +17,39 @@ class DesignEntity (object): self.__finished_image__ = False self.color_key = color_key - def __init_image__ (self, color = colors["bg"]): - rounded_size = (int(self.size[0]),int(self.size[1])) + def __init_image__(self, color=colors["bg"]): + rounded_size = (int(self.size[0]), int(self.size[1])) self.__image__ = Image.new('RGBA', rounded_size, color=color) - def get_image (self): + def get_image(self): if self.__finished_image__ is False: self.__finish_image__() self.__finished_image__ = True return self.__image__ - def draw (self, subimage, pos, mask=False, invert_mask=False, color_key=False): - rounded_pos = (int(pos[0]),int(pos[1])) + def draw(self, subimage, pos, mask=False, invert_mask=False, color_key=False): + rounded_pos = (int(pos[0]), int(pos[1])) img_mask = None if mask: - img_mask = self.__get_mask__(subimage, invert_mask=invert_mask, color_key=color_key) + img_mask = self.__get_mask__( + subimage, invert_mask=invert_mask, color_key=color_key) self.__image__.paste(subimage, rounded_pos, mask=img_mask) - def draw_design (self, entity): - self.draw(entity.get_image(), entity.pos, entity.mask, entity.invert_mask, entity.color_key) + def draw_design(self, entity): + self.draw(entity.get_image(), entity.pos, entity.mask, + entity.invert_mask, entity.color_key) - def draw_image (self, path, pos): + def draw_image(self, path, pos): self.draw(Image.open(path), pos) - def __finish_image__ (self): + def __finish_image__(self): pass - def __get_mask__ (self, image, invert_mask, color_key): + def __get_mask__(self, image, invert_mask, color_key): mask = image.convert('L') if color_key: - mask = mask.point(lambda p : 0 if p < masking_threshold else 255, '1').convert('L') + mask = mask.point(lambda p: 0 if p < + masking_threshold else 255, '1').convert('L') if invert_mask: mask = ImageOps.invert(mask) - return ImageOps.invert(mask) \ No newline at end of file + return ImageOps.invert(mask) diff --git a/Calendar/Dictionary.py b/Calendar/Dictionary.py index 327f563..68c1a3c 100644 --- a/Calendar/Dictionary.py +++ b/Calendar/Dictionary.py @@ -4,78 +4,78 @@ default_language = "en" '''Events''' more_events = { - 'en' : '+ *0 more', - 'de' : '+ *0 weitere' + 'en': '+ *0 more', + 'de': '+ *0 weitere' } multiday_events = { - 'en' : 'Multi-day', - 'de' : 'Mehrtägig' + 'en': 'Multi-day', + 'de': 'Mehrtägig' } allday_events = { - 'en' : 'All-day', - 'de' : 'Ganztägig' + 'en': 'All-day', + 'de': 'Ganztägig' } '''Weather''' rain_weather = { - 'en' : 'Rain', - 'de' : 'Regen' + 'en': 'Rain', + 'de': 'Regen' } clear_weather = { - 'en' : 'Clear', - 'de' : 'Klar' + 'en': 'Clear', + 'de': 'Klar' } clouds_weather = { - 'en' : 'Clouds', - 'de' : 'Wolken' + 'en': 'Clouds', + 'de': 'Wolken' } thunderstorm_weather = { - 'en' : 'Thunderstorm', - 'de' : 'Gewitter' + 'en': 'Thunderstorm', + 'de': 'Gewitter' } drizzle_weather = { - 'en' : 'Drizzle', - 'de' : 'Niesel' + 'en': 'Drizzle', + 'de': 'Niesel' } snow_weather = { - 'en' : 'Snow', - 'de' : 'Schnee' + 'en': 'Snow', + 'de': 'Schnee' } mist_weather = { - 'en' : 'Mist', - 'de' : 'Nebel' + 'en': 'Mist', + 'de': 'Nebel' } smoke_weather = { - 'en' : 'Smoke', - 'de' : 'Rauch' + 'en': 'Smoke', + 'de': 'Rauch' } haze_weather = { - 'en' : 'Haze', - 'de' : 'Nebel' + 'en': 'Haze', + 'de': 'Nebel' } dust_weather = { - 'en' : 'Dust', - 'de' : 'Staub' + 'en': 'Dust', + 'de': 'Staub' } fog_weather = { - 'en' : 'Fog', - 'de' : 'Nebel' + 'en': 'Fog', + 'de': 'Nebel' } sand_weather = { - 'en' : 'Sand', - 'de' : 'Sand' + 'en': 'Sand', + 'de': 'Sand' } ash_weather = { - 'en' : 'Ash', - 'de' : 'Asche' + 'en': 'Ash', + 'de': 'Asche' } squall_weather = { - 'en' : 'Squall', - 'de' : 'Sturm' + 'en': 'Squall', + 'de': 'Sturm' } tornado_weather = { - 'en' : 'Tornado', - 'de' : 'Tornado' + 'en': 'Tornado', + 'de': 'Tornado' } dictionary_collection = [ rain_weather, @@ -96,4 +96,4 @@ dictionary_collection = [ more_events, allday_events, multiday_events -] \ No newline at end of file +] diff --git a/Calendar/DictionaryMapper.py b/Calendar/DictionaryMapper.py index 3d7c12a..6304610 100644 --- a/Calendar/DictionaryMapper.py +++ b/Calendar/DictionaryMapper.py @@ -4,13 +4,15 @@ from settings import language '''Takes a collection of phrases and outputs the necessary text according to the language and inserts parameters.''' + def get_text(dictionary, *params): text = dictionary[default_language] if language in dictionary.keys(): text = dictionary[language] - + return __insert_params__(text, params) + def __insert_params__(text, params): index = 0 while '*%d' % index in text and index < len(params): @@ -24,4 +26,4 @@ def __insert_params__(text, params): else: text = splitted[0].rsplit(' ') index += 1 - return text \ No newline at end of file + return text diff --git a/Calendar/DisplayAdapter.py b/Calendar/DisplayAdapter.py index 613ec75..d8c3312 100644 --- a/Calendar/DisplayAdapter.py +++ b/Calendar/DisplayAdapter.py @@ -1,11 +1,12 @@ class DisplayAdapter (object): """Interface for CalendarDesign output channels.""" + def __init__(self, width, height): self.width = width self.height = height - def render (self, design): + def render(self, design): raise NotImplementedError("Functions needs to be implemented") - def calibrate (self): - raise NotImplementedError("Functions needs to be implemented") \ No newline at end of file + def calibrate(self): + raise NotImplementedError("Functions needs to be implemented") diff --git a/Calendar/E-Paper.py b/Calendar/E-Paper.py index 051fad5..8702fc0 100644 --- a/Calendar/E-Paper.py +++ b/Calendar/E-Paper.py @@ -27,8 +27,10 @@ import GeckoCrypto all_locales = locale.locale_alias if language.lower() not in all_locales.keys(): - raise Exception("The locale for \"%s\" is currently not supported! If you need support, please open an issue on github." % language) -locale.setlocale(locale.LC_ALL, "%s.%s" % (all_locales[language.lower()].split('.')[0], datetime_encoding)) + raise Exception( + "The locale for \"%s\" is currently not supported! If you need support, please open an issue on github." % language) +locale.setlocale(locale.LC_ALL, "%s.%s" % ( + all_locales[language.lower()].split('.')[0], datetime_encoding)) debug = DebugConsole() output_adapters = [] @@ -49,19 +51,22 @@ if render_to_display: output_adapters.append(epd) available_panels = { - "day-list" : DayListPanel, - "month-overview" : MonthOvPanel, - "day-view" : DayViewPanel, - "agenda-list" : AgendaListPanel, - "month-view" : MonthViewPanel, - "image-frame" : ImageFramePanel + "day-list": DayListPanel, + "month-overview": MonthOvPanel, + "day-view": DayViewPanel, + "agenda-list": AgendaListPanel, + "month-view": MonthViewPanel, + "image-frame": ImageFramePanel } loop_timer = LoopTimer(update_interval, run_on_hour=True) """Main loop starts from here""" + + def main(): - owm = OwmForecasts.OwmForecasts(location, api_key, paid_api=owm_paid_subscription) + owm = OwmForecasts.OwmForecasts( + location, api_key, paid_api=owm_paid_subscription) events_cal = IcalEvents.IcalEvents(ical_urls, highlighted_ical_urls) rss = RssParserPosts.RssParserPosts(rss_feeds) crypto = GeckoCrypto.GeckoCrypto(crypto_coins) @@ -78,7 +83,8 @@ def main(): if choosen_design in available_panels.keys(): design = available_panels[choosen_design]((epd.width, epd.height)) else: - raise ImportError("choosen_design must be valid (" + choosen_design + ")") + raise ImportError( + "choosen_design must be valid (" + choosen_design + ")") debug.print_line("Fetching weather information from open weather map") owm.reload() @@ -100,18 +106,22 @@ def main(): for i, output in enumerate(output_adapters): try: output.render(design) - debug.print_line(str(i + 1) + " of " + str(len(output_adapters)) + " rendered") + debug.print_line(str(i + 1) + " of " + + str(len(output_adapters)) + " rendered") except BaseException as ex: - debug.print_err(ex, "Failed to render output " + str(i + 1) + " of " + str(len(output_adapters))) + debug.print_err(ex, "Failed to render output " + + str(i + 1) + " of " + str(len(output_adapters))) debug.print_line("=> Finished rendering" + "\n") loop_timer.end_loop() sleep_time = loop_timer.time_until_next() - debug.print_line("This loop took " + str(loop_timer.get_last_duration()) + " to execute.") + debug.print_line("This loop took " + + str(loop_timer.get_last_duration()) + " to execute.") debug.print_line("Sleeping " + str(sleep_time) + " until next loop.") sleep(sleep_time.total_seconds()) + if __name__ == '__main__': main() diff --git a/Calendar/EllipseDesign.py b/Calendar/EllipseDesign.py index 5943df2..3d74565 100644 --- a/Calendar/EllipseDesign.py +++ b/Calendar/EllipseDesign.py @@ -1,10 +1,14 @@ from BoxDesign import BoxDesign from PIL import ImageDraw, ImageOps + class EllipseDesign (BoxDesign): """Redefinition of ImageDraw.Draw.Rectangle""" - def __init__(self, size, fill=None, outline=None, width=0): - super(EllipseDesign, self).__init__(size, fill=fill, outline=outline, width=width) - def __finish_image__ (self): - ImageDraw.Draw(self.__image__).ellipse(self.corners, fill=self.fill, outline=self.outline, width=self.width) \ No newline at end of file + def __init__(self, size, fill=None, outline=None, width=0): + super(EllipseDesign, self).__init__( + size, fill=fill, outline=outline, width=width) + + def __finish_image__(self): + ImageDraw.Draw(self.__image__).ellipse( + self.corners, fill=self.fill, outline=self.outline, width=self.width) diff --git a/Calendar/Epd7in5Adapter.py b/Calendar/Epd7in5Adapter.py index c247d79..f1393a9 100644 --- a/Calendar/Epd7in5Adapter.py +++ b/Calendar/Epd7in5Adapter.py @@ -2,11 +2,12 @@ from EpdAdapter import EpdAdapter, DISPLAY_REFRESH, DATA_START_TRANSMISSION_1 from settings import display_colours from PIL import Image, ImageDraw + class Epd7in5Adapter (EpdAdapter): - def __init__ (self): + def __init__(self): super(Epd7in5Adapter, self).__init__(384, 640) - def display_frame (self, frame_buffer): + def display_frame(self, frame_buffer): self.send_command(DATA_START_TRANSMISSION_1) for i in range(0, 30720): temp1 = frame_buffer[i] @@ -30,11 +31,11 @@ class Epd7in5Adapter (EpdAdapter): self.delay_ms(100) self.wait_until_idle() - def get_frame_buffer (self, image): + def get_frame_buffer(self, image): buf = [0x00] * int(self.height * self.width / 8) # Set buffer to value of Python Imaging Library image. # Image must be in mode 1. - image_monocolor = image.convert('L') #with ot withour dithering? + image_monocolor = image.convert('L') # with ot withour dithering? imwidth, imheight = image_monocolor.size if imwidth != self.height or imheight != self.width: raise ValueError('Image must be same dimensions as display \ @@ -44,11 +45,11 @@ class Epd7in5Adapter (EpdAdapter): for y in range(self.width): for x in range(self.height): # Set the bits for the column of pixels at the current position. - if pixels[x, y] >= 240: #White + if pixels[x, y] >= 240: # White buf[int((x + y * self.height) / 8)] |= 0x80 >> (x % 8) return buf - def calibrate (self): + def calibrate(self): for _ in range(2): self.init_render() black = Image.new('1', (self.height, self.width), 'black') @@ -61,4 +62,4 @@ class Epd7in5Adapter (EpdAdapter): print('calibrating white...') self.display_frame(self.get_frame_buffer(white)) self.sleep() - print('Calibration complete') \ No newline at end of file + print('Calibration complete') diff --git a/Calendar/Epd7in5bAdapter.py b/Calendar/Epd7in5bAdapter.py index 379fab4..726b873 100644 --- a/Calendar/Epd7in5bAdapter.py +++ b/Calendar/Epd7in5bAdapter.py @@ -4,16 +4,17 @@ from PIL import Image, ImageDraw from math import sqrt, pow import numpy as np + class Epd7in5bAdapter (EpdAdapter): - def __init__ (self): + def __init__(self): super(Epd7in5bAdapter, self).__init__(384, 640) - def display_frame (self, frame_buffer): + def display_frame(self, frame_buffer): self.send_command(DATA_START_TRANSMISSION_1) for i in range(0, int(self.height / 4 * self.width)): - #the above line had to be modified due to python2 -> python3 - #the issue lies in division, which returns integers in python2 - #but floats in python3 + # the above line had to be modified due to python2 -> python3 + # the issue lies in division, which returns integers in python2 + # but floats in python3 temp1 = frame_buffer[i] j = 0 while (j < 4): @@ -39,8 +40,8 @@ class Epd7in5bAdapter (EpdAdapter): self.delay_ms(100) self.wait_until_idle() - def get_frame_buffer (self, image): - buf = [ 0x00 ] * int(self.height * self.width / 4) + def get_frame_buffer(self, image): + buf = [0x00] * int(self.height * self.width / 4) imwidth, imheight = image.size if imwidth != self.height or imheight != self.width: raise ValueError('Image must be same dimensions as display \ @@ -51,24 +52,26 @@ class Epd7in5bAdapter (EpdAdapter): for y in range(self.height): # Set the bits for the column of pixels at the current # position. - if image_buf[x, y, 1] == 255: #White + if image_buf[x, y, 1] == 255: # White buf[int((y + x * self.height) / 4)] |= 0xC0 >> (y % 4 * 2) - elif image_buf[x, y, 0] == 0: #Black - buf[int((y + x * self.height) / 4)] &= ~(0xC0 >> (y % 4 * 2)) - else: #Red - buf[int((y + x * self.height) / 4)] &= ~(0xC0 >> (y % 4 * 2)) + elif image_buf[x, y, 0] == 0: # Black + buf[int((y + x * self.height) / 4) + ] &= ~(0xC0 >> (y % 4 * 2)) + else: # Red + buf[int((y + x * self.height) / 4) + ] &= ~(0xC0 >> (y % 4 * 2)) buf[int((y + x * self.height) / 4)] |= 0x40 >> (y % 4 * 2) return buf def __prepare_image__(self, image): buffer = np.array(image) - r,g = buffer[:,:,0], buffer[:,:,1] - buffer[np.logical_and(r > 220, g > 220)] = [255,255,255] - buffer[r > g] = [255,0,0] - buffer[r != 255] = [0,0,0] + r, g = buffer[:, :, 0], buffer[:, :, 1] + buffer[np.logical_and(r > 220, g > 220)] = [255, 255, 255] + buffer[r > g] = [255, 0, 0] + buffer[r != 255] = [0, 0, 0] return buffer - def calibrate (self): + def calibrate(self): for _ in range(2): self.init_render() black = Image.new('RGB', (self.height, self.width), 'black') @@ -86,4 +89,4 @@ class Epd7in5bAdapter (EpdAdapter): print('calibrating white...') self.display_frame(self.get_frame_buffer(white)) self.sleep() - print('Calibration complete') \ No newline at end of file + print('Calibration complete') diff --git a/Calendar/EpdAdapter.py b/Calendar/EpdAdapter.py index a1a52a8..fa933c1 100644 --- a/Calendar/EpdAdapter.py +++ b/Calendar/EpdAdapter.py @@ -4,53 +4,55 @@ import RPi.GPIO as GPIO import time from PIL import Image -RST_PIN = 17 -DC_PIN = 25 -CS_PIN = 8 +RST_PIN = 17 +DC_PIN = 25 +CS_PIN = 8 BUSY_PIN = 24 # Commands -PANEL_SETTING = 0x00 -POWER_SETTING = 0x01 -POWER_OFF = 0x02 -POWER_OFF_SEQUENCE_SETTING = 0x03 -POWER_ON = 0x04 -POWER_ON_MEASURE = 0x05 -BOOSTER_SOFT_START = 0x06 -DEEP_SLEEP = 0x07 -DATA_START_TRANSMISSION_1 = 0x10 -DATA_STOP = 0x11 -DISPLAY_REFRESH = 0x12 -IMAGE_PROCESS = 0x13 -LUT_FOR_VCOM = 0x20 -LUT_BLUE = 0x21 -LUT_WHITE = 0x22 -LUT_GRAY_1 = 0x23 -LUT_GRAY_2 = 0x24 -LUT_RED_0 = 0x25 -LUT_RED_1 = 0x26 -LUT_RED_2 = 0x27 -LUT_RED_3 = 0x28 -LUT_XON = 0x29 -PLL_CONTROL = 0x30 -TEMPERATURE_SENSOR_COMMAND = 0x40 -TEMPERATURE_CALIBRATION = 0x41 -TEMPERATURE_SENSOR_WRITE = 0x42 -TEMPERATURE_SENSOR_READ = 0x43 -VCOM_AND_DATA_INTERVAL_SETTING = 0x50 -LOW_POWER_DETECTION = 0x51 -TCON_SETTING = 0x60 -TCON_RESOLUTION = 0x61 -SPI_FLASH_CONTROL = 0x65 -REVISION = 0x70 -GET_STATUS = 0x71 -AUTO_MEASUREMENT_VCOM = 0x80 -READ_VCOM_VALUE = 0x81 -VCM_DC_SETTING = 0x82 +PANEL_SETTING = 0x00 +POWER_SETTING = 0x01 +POWER_OFF = 0x02 +POWER_OFF_SEQUENCE_SETTING = 0x03 +POWER_ON = 0x04 +POWER_ON_MEASURE = 0x05 +BOOSTER_SOFT_START = 0x06 +DEEP_SLEEP = 0x07 +DATA_START_TRANSMISSION_1 = 0x10 +DATA_STOP = 0x11 +DISPLAY_REFRESH = 0x12 +IMAGE_PROCESS = 0x13 +LUT_FOR_VCOM = 0x20 +LUT_BLUE = 0x21 +LUT_WHITE = 0x22 +LUT_GRAY_1 = 0x23 +LUT_GRAY_2 = 0x24 +LUT_RED_0 = 0x25 +LUT_RED_1 = 0x26 +LUT_RED_2 = 0x27 +LUT_RED_3 = 0x28 +LUT_XON = 0x29 +PLL_CONTROL = 0x30 +TEMPERATURE_SENSOR_COMMAND = 0x40 +TEMPERATURE_CALIBRATION = 0x41 +TEMPERATURE_SENSOR_WRITE = 0x42 +TEMPERATURE_SENSOR_READ = 0x43 +VCOM_AND_DATA_INTERVAL_SETTING = 0x50 +LOW_POWER_DETECTION = 0x51 +TCON_SETTING = 0x60 +TCON_RESOLUTION = 0x61 +SPI_FLASH_CONTROL = 0x65 +REVISION = 0x70 +GET_STATUS = 0x71 +AUTO_MEASUREMENT_VCOM = 0x80 +READ_VCOM_VALUE = 0x81 +VCM_DC_SETTING = 0x82 -class EpdAdapter (DisplayAdapter): + +class EpdAdapter (DisplayAdapter): """Generalized adapter for epd7in5 and epd7in5b""" - def __init__ (self, width, height): + + def __init__(self, width, height): super(EpdAdapter, self).__init__(width, height) self.reset_pin = RST_PIN @@ -59,16 +61,16 @@ class EpdAdapter (DisplayAdapter): self.epd_init() - def display_frame (self, frame_buffer): + def display_frame(self, frame_buffer): raise NotImplementedError("Functions needs to be implemented") - def get_frame_buffer (self, image): + def get_frame_buffer(self, image): raise NotImplementedError("Functions needs to be implemented") - def render (self, design): + def render(self, design): self.init_render() time.sleep(5) - + print('Converting image to data and sending it to the display') print('This may take a while...' + '\n') prepared_image = design.get_image().rotate(270, expand=1).convert("RGB") @@ -79,7 +81,7 @@ class EpdAdapter (DisplayAdapter): print('Data sent successfully') print('Powering off the E-Paper until the next loop' + '\n') - def init_render (self): + def init_render(self): if (self.epd_init() != 0): return -1 self.reset() @@ -113,30 +115,30 @@ class EpdAdapter (DisplayAdapter): self.send_data(0x22) self.send_command(TCON_RESOLUTION) - self.send_data(0x02) #source 640 + self.send_data(0x02) # source 640 self.send_data(0x80) - self.send_data(0x01) #gate 384 + self.send_data(0x01) # gate 384 self.send_data(0x80) self.send_command(VCM_DC_SETTING) - self.send_data(0x1E) #decide by LUT file + self.send_data(0x1E) # decide by LUT file - self.send_command(0xe5) #FLASH MODE + self.send_command(0xe5) # FLASH MODE self.send_data(0x03) - def digital_write (self, pin, value): + def digital_write(self, pin, value): GPIO.output(pin, value) - def digital_read (self, pin): + def digital_read(self, pin): return GPIO.input(pin) - def delay_ms (self, delaytime): + def delay_ms(self, delaytime): time.sleep(delaytime / 1000.0) - def spi_transfer (self, data): + def spi_transfer(self, data): self.SPI.writebytes(data) - def epd_init (self): + def epd_init(self): # SPI device, bus = 0, device = 0 self.SPI = spidev.SpiDev(0, 0) #self.SPI.no_cs = True @@ -151,13 +153,13 @@ class EpdAdapter (DisplayAdapter): self.SPI.mode = 0b00 return 0 - def sleep (self): + def sleep(self): self.send_command(POWER_OFF) self.wait_until_idle() self.send_command(DEEP_SLEEP) self.send_data(0xa5) - - def wait_until_idle (self, max_wait_seconds = 60): + + def wait_until_idle(self, max_wait_seconds=60): wait_ms = 100 count = 0 while(self.digital_read(self.busy_pin) == 0 and wait_ms * count < max_wait_seconds * 1000): # 0: busy, 1: idle @@ -166,20 +168,20 @@ class EpdAdapter (DisplayAdapter): if wait_ms * count >= max_wait_seconds * 1000: print("Skipped idle confirmation") - def reset (self): + def reset(self): self.digital_write(self.reset_pin, GPIO.LOW) # module reset self.delay_ms(200) self.digital_write(self.reset_pin, GPIO.HIGH) self.delay_ms(200) - def send_command (self, command): + def send_command(self, command): self.digital_write(self.dc_pin, GPIO.LOW) # the parameter type is list but not int # so use [command] instead of command - self.spi_transfer([ command ]) + self.spi_transfer([command]) - def send_data (self, data): + def send_data(self, data): self.digital_write(self.dc_pin, GPIO.HIGH) # the parameter type is list but not int # so use [data] instead of data - self.spi_transfer([ data ]) \ No newline at end of file + self.spi_transfer([data]) diff --git a/Calendar/EventListDesign.py b/Calendar/EventListDesign.py index 13b602c..b0c9948 100644 --- a/Calendar/EventListDesign.py +++ b/Calendar/EventListDesign.py @@ -5,10 +5,12 @@ from TextFormatter import date_str from DictionaryMapper import get_text from Dictionary import more_events + class EventListDesign (DesignEntity): """Creates a TableDesign filled with event begin date and title""" - def __init__ (self, size, events, text_size = defaultfontsize, line_spacing = 0, col_spacing = 10, event_prefix_rel_dates = [], event_prefix_func = None, font_family = None, general_color = colors["fg"], background_color = colors["bg"], highlight_color = colors["hl"], show_more_info = False): + + def __init__(self, size, events, text_size=defaultfontsize, line_spacing=0, col_spacing=10, event_prefix_rel_dates=[], event_prefix_func=None, font_family=None, general_color=colors["fg"], background_color=colors["bg"], highlight_color=colors["hl"], show_more_info=False): super(EventListDesign, self).__init__(size) self.events = events self.__event_matrix__ = [] @@ -24,22 +26,25 @@ class EventListDesign (DesignEntity): self.event_prefix_func = event_prefix_func self.event_prefix_rel_dates = event_prefix_rel_dates if self.event_prefix_func is None: - self.event_prefix_func = lambda x, y : date_str(x.begin_datetime) + self.event_prefix_func = lambda x, y: date_str(x.begin_datetime) - def __finish_image__ (self): - self.visible_event_count = int(int(self.size[1] + self.line_spacing) // (self.line_spacing + int(self.text_size))) + def __finish_image__(self): + self.visible_event_count = int(int( + self.size[1] + self.line_spacing) // (self.line_spacing + int(self.text_size))) self.__fill_event_matrix__() - - col_hori_alignment = [ 'right', 'left' ] - table_design = TableDesign(self.size, background_color = self.background_color, font=self.font_family, line_spacing=self.line_spacing, col_spacing=self.col_spacing, matrix=self.__event_matrix__, fontsize = self.text_size, column_horizontal_alignments=col_hori_alignment, mask=False, truncate_cols=False, cell_properties=self.__props_matrix__) + + col_hori_alignment = ['right', 'left'] + table_design = TableDesign(self.size, background_color=self.background_color, font=self.font_family, line_spacing=self.line_spacing, col_spacing=self.col_spacing, + matrix=self.__event_matrix__, fontsize=self.text_size, column_horizontal_alignments=col_hori_alignment, mask=False, truncate_cols=False, cell_properties=self.__props_matrix__) self.draw_design(table_design) - - def __get_formatted_event__ (self, event, index): - rel_date = None if index < 0 or index >= len(self.event_prefix_rel_dates) else self.event_prefix_rel_dates[index] + + def __get_formatted_event__(self, event, index): + rel_date = None if index < 0 or index >= len( + self.event_prefix_rel_dates) else self.event_prefix_rel_dates[index] prefix = self.event_prefix_func(event, rel_date) - return [ prefix, event.title ] - - def __fill_event_matrix__ (self): + return [prefix, event.title] + + def __fill_event_matrix__(self): visible_events = self.events if self.show_more_info and len(visible_events) > self.visible_event_count: visible_events = visible_events[:self.visible_event_count - 1] @@ -54,16 +59,16 @@ class EventListDesign (DesignEntity): additional_events_count = len(self.events) - len(visible_events) more_text = " " + get_text(more_events, additional_events_count) if additional_events_count > 0: - self.__event_matrix__.append([ "", more_text ]) + self.__event_matrix__.append(["", more_text]) self.__props_matrix__.append(self.__get_row_props__()) - def __get_row_props__ (self, event = None): + def __get_row_props__(self, event=None): color = self.general_color bg_color = self.background_color if event is not None and event.highlight: color = self.highlight_color cell = { - "color" : color, - "background_color" : bg_color + "color": color, + "background_color": bg_color } - return [ cell, cell ] \ No newline at end of file + return [cell, cell] diff --git a/Calendar/GeckoCrypto.py b/Calendar/GeckoCrypto.py index 37cb431..2505edc 100644 --- a/Calendar/GeckoCrypto.py +++ b/Calendar/GeckoCrypto.py @@ -12,6 +12,7 @@ api_price_url = api_url + "simple/price" price_currency = "usd" price_currency_sign = "$" + class GeckoCrypto(CryptoInterface): def __init__(self, coins): self.coin_ids = coins @@ -33,12 +34,13 @@ class GeckoCrypto(CryptoInterface): coins = [] for id in self.coin_ids: try: - data = urlopen(api_price_url + "?include_24hr_change=true&ids=" + self.metadata[id]['id'] + "&vs_currencies=" + price_currency).read() + data = urlopen(api_price_url + "?include_24hr_change=true&ids=" + + self.metadata[id]['id'] + "&vs_currencies=" + price_currency).read() dataJSON = json.loads(data.decode('utf-8')) raw = dataJSON[id][price_currency] price = math.ceil(raw*100) / 100 change = dataJSON[id]['usd_24h_change'] - + coins.append(self.__build_coin__(id, price, change)) except: print("Gecko-Error [" + id + "]") @@ -46,20 +48,21 @@ class GeckoCrypto(CryptoInterface): def __build_coin__(self, id, value, change): coin = CryptoCoin() - + coin.name = self.metadata[id]['name'] coin.day_change = round(change, 2) coin.price = value - + coin.datetime = datetime.now() coin.fetch_datetime = datetime.now() coin.currency = price_currency_sign coin.symbol = self.metadata[id]['symbol'] - + return coin def __prepare_metadata__(self): self.metadata = None data = urlopen(api_metadata_url).read() dataJSON = json.loads(data.decode('utf-8')) - self.metadata = { coin['id'].lower() : coin for coin in dataJSON if coin['id'].lower() in self.coin_ids } + self.metadata = {coin['id'].lower( + ): coin for coin in dataJSON if coin['id'].lower() in self.coin_ids} diff --git a/Calendar/HourListDesign.py b/Calendar/HourListDesign.py index 47283a7..f03e55c 100644 --- a/Calendar/HourListDesign.py +++ b/Calendar/HourListDesign.py @@ -1,5 +1,5 @@ from DesignEntity import DesignEntity -from settings import hours, language,line_thickness +from settings import hours, language, line_thickness from TextDesign import TextDesign from PIL import ImageDraw from Assets import colors, defaultfontsize, fonts @@ -19,54 +19,57 @@ currenttimeline_thickness = line_thickness event_title_font = fonts['bold'] + class HourListDesign (DesignEntity): """Hours of a day are listed vertically and resemble a timeline.""" - def __init__ (self, size, first_hour = 0, last_hour = 23): + + def __init__(self, size, first_hour=0, last_hour=23): super(HourListDesign, self).__init__(size) self.first_hour = first_hour self.last_hour = last_hour self.__calc_parameters__() self.events = [] - def add_events (self, events): + def add_events(self, events): self.events.extend(events) - self.events.sort(key=lambda x : x.begin_datetime) + self.events.sort(key=lambda x: x.begin_datetime) - def __finish_image__ (self): + def __finish_image__(self): self.number_columns = self.__get_max_num_simultaneous_events__() self.__draw_lines__() self.__draw_events__() self.__draw_current_time_line__() self.__draw_hour_rows__() - def __calc_parameters__ (self): + def __calc_parameters__(self): self.hour_count = self.last_hour - self.first_hour + 1 self.row_size = (self.size[0], self.size[1] / self.hour_count) - def __get_hour_text__ (self, hour): + def __get_hour_text__(self, hour): if hour <= 12 or hours is "24": return str(hour) else: short = hour - 12 return str(short) if short > 0 else "12" - def __get_ypos_for_time__ (self, hour, minute = 0): + def __get_ypos_for_time__(self, hour, minute=0): return self.__get_height_for_duration__(hour, minute) - self.__get_height_for_duration__(self.first_hour) - def __get_height_for_duration__ (self, hours, minutes = 0): + def __get_height_for_duration__(self, hours, minutes=0): row_height = self.row_size[1] return row_height * (hours + minutes / 60) - def __draw_events__ (self): + def __draw_events__(self): column_events = [] for _ in range(self.number_columns): column_events.append(None) for event in self.events: - column_events = self.__update_columns_events__(column_events, event) + column_events = self.__update_columns_events__( + column_events, event) self.__draw_event__(event, column_events.index(event)) - def __update_columns_events__ (self, column_events, new_event): + def __update_columns_events__(self, column_events, new_event): current_time = new_event.begin_datetime new_event_added = False for index in range(len(column_events)): @@ -77,11 +80,11 @@ class HourListDesign (DesignEntity): new_event_added = True return column_events - def __draw_hour_rows__ (self): + def __draw_hour_rows__(self): for hour in range(self.first_hour, self.last_hour + 1): self.__draw_row__(hour) - def __draw_row__ (self, hour): + def __draw_row__(self, hour): subtext_height = self.row_size[1] * hoursubtext_height sub_fontsize = subtext_height * hoursubtext_fontsize ypadding = hour_ypadding * self.row_size[1] @@ -91,22 +94,25 @@ class HourListDesign (DesignEntity): pos = (0, self.__get_ypos_for_time__(hour) + ypadding) fontsize = size[1] * hour_box_fontsize - txt = TextDesign(size, text=self.__get_hour_text__(hour), fontsize=fontsize, verticalalignment="bottom", horizontalalignment="center") + txt = TextDesign(size, text=self.__get_hour_text__( + hour), fontsize=fontsize, verticalalignment="bottom", horizontalalignment="center") txt.pos = pos self.draw_design(txt) - sub = TextDesign((width, subtext_height), text=self.__get_hour_sub_text__(hour), fontsize=sub_fontsize, verticalalignment="top", horizontalalignment="center") + sub = TextDesign((width, subtext_height), text=self.__get_hour_sub_text__( + hour), fontsize=sub_fontsize, verticalalignment="top", horizontalalignment="center") sub.pos = (0, height + self.__get_ypos_for_time__(hour)) self.draw_design(sub) - def __draw_lines__ (self): + def __draw_lines__(self): for i in range(self.hour_count): ypos = i * self.row_size[1] line_start = (0, ypos) line_end = (self.size[0], ypos) - ImageDraw.Draw(self.__image__).line([ line_start, line_end ], fill=colors["fg"], width=line_thickness) + ImageDraw.Draw(self.__image__).line( + [line_start, line_end], fill=colors["fg"], width=line_thickness) - def __get_hour_sub_text__ (self, hour): + def __get_hour_sub_text__(self, hour): if hours == "12": return "AM" if hour < 12 else "PM" elif language is "de": @@ -115,7 +121,7 @@ class HourListDesign (DesignEntity): return "o'c" return "" - def __draw_event__ (self, event, column = 0): + def __draw_event__(self, event, column=0): xoffset = hourbox_y_width * self.row_size[1] column_width = (self.size[0] - xoffset) / self.number_columns @@ -132,36 +138,42 @@ class HourListDesign (DesignEntity): size = (column_width, time_height + yoffset_correction) if size[1] < 0: - return #Event not in shown time range + return # Event not in shown time range self.__draw_event_block__(pos, size, event) - def __draw_event_block__ (self, pos, size, event): + def __draw_event_block__(self, pos, size, event): box_color = colors["hl"] if event.highlight else colors["fg"] - box = BoxDesign(size, fill = box_color) + box = BoxDesign(size, fill=box_color) box.mask = False box.pos = pos self.draw_design(box) text = event.title text_color = colors["bg"] - textbox_size = (size[0] - event_title_xpadding, size[1] - event_title_ypadding) - txt = TextDesign(textbox_size, text = text, font=event_title_font, fontsize=event_title_fontsize, color=text_color, background_color=box_color, wrap=True) + textbox_size = (size[0] - event_title_xpadding, + size[1] - event_title_ypadding) + txt = TextDesign(textbox_size, text=text, font=event_title_font, + fontsize=event_title_fontsize, color=text_color, background_color=box_color, wrap=True) txt.mask = False - txt.pos = (pos[0] + event_title_xpadding, pos[1] + event_title_ypadding) + txt.pos = (pos[0] + event_title_xpadding, + pos[1] + event_title_ypadding) self.draw_design(txt) half_ypadding = int(event_title_ypadding / 2) line_start = (pos[0] + event_title_xpadding, pos[1] + half_ypadding) - line_end = (pos[0] + size[0] - event_title_xpadding, pos[1] + half_ypadding) - ImageDraw.Draw(self.__image__).line([ line_start, line_end ], fill=colors["bg"], width=1) + line_end = (pos[0] + size[0] - event_title_xpadding, + pos[1] + half_ypadding) + ImageDraw.Draw(self.__image__).line( + [line_start, line_end], fill=colors["bg"], width=1) - def __get_max_num_simultaneous_events__ (self): + def __get_max_num_simultaneous_events__(self): parallelity_count = 1 for index, event in enumerate(self.events): current_parallelity = 1 - preceding = self.events[:index] #Assumption: Events are ordered chronologically + # Assumption: Events are ordered chronologically + preceding = self.events[:index] for pre_event in preceding: if self.__are_simultaneous__(pre_event, event): current_parallelity += 1 @@ -169,18 +181,19 @@ class HourListDesign (DesignEntity): parallelity_count = current_parallelity return parallelity_count - def __are_simultaneous__ (self, ev_a, ev_b): + def __are_simultaneous__(self, ev_a, ev_b): if ev_a.begin_datetime > ev_b.begin_datetime: ev_a, ev_b = ev_b, ev_a - + mes_dur = ev_b.begin_datetime - ev_a.begin_datetime return mes_dur < ev_a.duration - def __draw_current_time_line__ (self): + def __draw_current_time_line__(self): now = datetime.now() ypos = self.__get_ypos_for_time__(now.hour, now.minute) - + line_start = (0, ypos) line_end = (self.size[0], ypos) - ImageDraw.Draw(self.__image__).line([ line_start, line_end ], fill=colors["hl"], width=currenttimeline_thickness) \ No newline at end of file + ImageDraw.Draw(self.__image__).line( + [line_start, line_end], fill=colors["hl"], width=currenttimeline_thickness) diff --git a/Calendar/IcalEvents.py b/Calendar/IcalEvents.py index ae348c1..ef5068e 100644 --- a/Calendar/IcalEvents.py +++ b/Calendar/IcalEvents.py @@ -6,8 +6,10 @@ import re from settings import week_starts_on from urllib.request import urlopen + class IcalEvents(CalendarInterface): """Fetches events from ical addresses.""" + def __init__(self, urls, highlighted_urls=None): self.urls = urls self.highlighted_urls = highlighted_urls @@ -60,8 +62,10 @@ class IcalEvents(CalendarInterface): cal_event.allday = event.all_day cal_event.rrule = self.__extract_rrule__(event) - cal_event.begin_datetime = cal_event.begin_datetime.astimezone(None) - cal_event.end_datetime = cal_event.end_datetime.astimezone(None) + cal_event.begin_datetime = cal_event.begin_datetime.astimezone( + None) + cal_event.end_datetime = cal_event.end_datetime.astimezone( + None) if cal_event.allday: cal_event = self.__fix_allday__(cal_event) @@ -79,8 +83,10 @@ class IcalEvents(CalendarInterface): begin_utc = event.begin_datetime.astimezone(timezone.utc) end_utc = event.end_datetime.astimezone(timezone.utc) - event.begin_datetime = datetime(begin_utc.year, begin_utc.month, begin_utc.day, 0, 0, 0, 0, local_tzinfo) - event.end_datetime = datetime(end_utc.year, end_utc.month, end_utc.day, 0, 0, 0, 0, local_tzinfo) - timedelta(1) + event.begin_datetime = datetime( + begin_utc.year, begin_utc.month, begin_utc.day, 0, 0, 0, 0, local_tzinfo) + event.end_datetime = datetime( + end_utc.year, end_utc.month, end_utc.day, 0, 0, 0, 0, local_tzinfo) - timedelta(1) event.duration = event.end_datetime - event.begin_datetime return event @@ -95,19 +101,21 @@ class IcalEvents(CalendarInterface): beginAlarmIndex = decode.find(alarm_begin) if beginAlarmIndex >= 0: endAlarmIndex = decode.find(alarm_end, beginAlarmIndex) - decode = decode[:beginAlarmIndex] + decode[endAlarmIndex + len(alarm_end) + len(lineseparation):] + decode = decode[:beginAlarmIndex] + \ + decode[endAlarmIndex + + len(alarm_end) + len(lineseparation):] return decode def __extract_rrule__(self, event): - if re.search('RRULE',str(event)) is None: + if re.search('RRULE', str(event)) is None: return None - return re.search('RRULE:(.+?)\n',str(event)).group(1).rstrip() + return re.search('RRULE:(.+?)\n', str(event)).group(1).rstrip() - def __is_multiday__ (self, event): + def __is_multiday__(self, event): if event.allday and event.duration == timedelta(1): return False return event.begin_datetime.day != event.end_datetime.day or \ event.begin_datetime.month != event.end_datetime.month or \ - event.begin_datetime.year != event.end_datetime.year \ No newline at end of file + event.begin_datetime.year != event.end_datetime.year diff --git a/Calendar/ImageDesign.py b/Calendar/ImageDesign.py index 8323bec..2705ac5 100644 --- a/Calendar/ImageDesign.py +++ b/Calendar/ImageDesign.py @@ -2,23 +2,26 @@ from DesignEntity import DesignEntity from Assets import path as application_path from PIL import Image, ExifTags + class ImageDesign (DesignEntity): """Creates a TableDesign filled with rss post date and title""" - def __init__ (self, size, path, fill = "none", color="RGBA", dither=None): # fill: "none" : original size, "stretch" : strech to fill, "scale" : scale to fill, "border" : scale until one side touches border + + # fill: "none" : original size, "stretch" : strech to fill, "scale" : scale to fill, "border" : scale until one side touches border + def __init__(self, size, path, fill="none", color="RGBA", dither=None): super(ImageDesign, self).__init__(size) self.set_path(path) self.fill = fill self.color = color self.dither = dither - def set_path (self, path): + def set_path(self, path): path = path.replace('\\', '/') if path[0] != '/' and ':' not in path[0:3]: path = application_path + '/' + path self.path = path - def __finish_image__ (self): + def __finish_image__(self): img = Image.open(self.path) img = img.convert(self.color, dither=self.dither) @@ -70,9 +73,9 @@ class ImageDesign (DesignEntity): return img for orientation in ExifTags.TAGS.keys(): - if ExifTags.TAGS[orientation]=='Orientation': + if ExifTags.TAGS[orientation] == 'Orientation': break - exif=img.info["parsed_exif"] + exif = img.info["parsed_exif"] if exif[orientation] == 3: img = img.rotate(180, expand=True) @@ -80,4 +83,4 @@ class ImageDesign (DesignEntity): img = img.rotate(270, expand=True) elif exif[orientation] == 8: img = img.rotate(90, expand=True) - return img \ No newline at end of file + return img diff --git a/Calendar/ImageFileAdapter.py b/Calendar/ImageFileAdapter.py index f03554b..50043e0 100644 --- a/Calendar/ImageFileAdapter.py +++ b/Calendar/ImageFileAdapter.py @@ -1,16 +1,18 @@ from DisplayAdapter import DisplayAdapter from Assets import path + class ImageFileAdapter (DisplayAdapter): """Saves design to an image file, can be used for debugging""" - def __init__ (self, file_path = ""): + + def __init__(self, file_path=""): super(ImageFileAdapter, self).__init__(384, 640) self.file_path = file_path if self.file_path == "": self.file_path = path - def render (self, design): + def render(self, design): design.get_image().save(self.file_path + 'design_exported.png') - def calibrate (self): - pass \ No newline at end of file + def calibrate(self): + pass diff --git a/Calendar/ImageFramePanel.py b/Calendar/ImageFramePanel.py index ac5b267..37dd2c5 100644 --- a/Calendar/ImageFramePanel.py +++ b/Calendar/ImageFramePanel.py @@ -10,14 +10,17 @@ from random import choice class ImageFramePanel (PanelDesign): """Converts the display into a digital frame and shows a slide show of images, iterating on each update""" - def __init__ (self, size): + + def __init__(self, size): super(ImageFramePanel, self).__init__(size) - self.overlay_path = self.__complete_path__(general_settings["overlay-image"]) - self.image_folder_path = self.__complete_path__(general_settings["image-folder"]) + self.overlay_path = self.__complete_path__( + general_settings["overlay-image"]) + self.image_folder_path = self.__complete_path__( + general_settings["image-folder"]) self.images = self.__extract_valid_img_paths__() self.__first_render__() - def __extract_valid_img_paths__ (self): + def __extract_valid_img_paths__(self): images = [] for file in listdir(self.image_folder_path): file_path = join(self.image_folder_path, file).replace('\\', '/') @@ -42,17 +45,17 @@ class ImageFramePanel (PanelDesign): overlay.__finish_image__() self.__image__.alpha_composite(overlay.__image__) - def add_weather (self, weather): + def add_weather(self, weather): pass - def add_calendar (self, calendar): + def add_calendar(self, calendar): pass - def add_rssfeed (self, rss): + def add_rssfeed(self, rss): pass - def add_crypto (self, crypto): + def add_crypto(self, crypto): pass - def add_tasks (self, tasks): + def add_tasks(self, tasks): pass diff --git a/Calendar/LoopTimer.py b/Calendar/LoopTimer.py index 630dd3a..6640050 100644 --- a/Calendar/LoopTimer.py +++ b/Calendar/LoopTimer.py @@ -3,39 +3,41 @@ from datetime import datetime, timedelta min_sleep_minutes = 0 max_history_entries = 25 + class LoopTimer (object): """Manages loop times and sleeps until next loop.""" - def __init__ (self, loop_interval, run_on_hour = False): + + def __init__(self, loop_interval, run_on_hour=False): self.interval = int(str(loop_interval)) self.on_hour = run_on_hour self.loop_history = [] - def begin_loop (self): + def begin_loop(self): begin_time = datetime.now() print('\n__________Starting new loop__________') print('Datetime: ' + str(begin_time) + '\n') self.__add_beginning__(begin_time) - def __add_beginning__ (self, time): + def __add_beginning__(self, time): self.loop_history.append((time,)) if len(self.loop_history) > max_history_entries: dif = len(self.loop_history) - max_history_entries self.loop_history = self.loop_history[dif:] - def __add_ending__ (self, time): + def __add_ending__(self, time): current = self.get_current() self.loop_history[-1] = (current[0], time) - def end_loop (self): + def end_loop(self): end_time = datetime.now() self.__add_ending__(end_time) - def get_current (self): + def get_current(self): return self.loop_history[-1] - def time_until_next (self): + def time_until_next(self): interval_duration = timedelta(minutes=self.interval) loop_duration = self.get_last_duration() sleep_time = interval_duration - loop_duration @@ -48,19 +50,19 @@ class LoopTimer (object): sleep_time = timedelta(0, 0, 0, 0, min_sleep_minutes) return sleep_time - def get_last_duration (self): + def get_last_duration(self): if len(self.loop_history) == 0: return begin, end = self.loop_history[-1] return end - begin - def get_time_to_next_hour (self): + def get_time_to_next_hour(self): cur = datetime.now() rounded = datetime(cur.year, cur.month, cur.day, cur.hour) next_hour_time = rounded + timedelta(hours=1) - return next_hour_time - datetime.now() + return next_hour_time - datetime.now() - def is_new_hour_loop (self): + def is_new_hour_loop(self): if len(self.loop_history) < 2: return False previous_loop = self.loop_history[-2] @@ -69,4 +71,4 @@ class LoopTimer (object): if previous_loop[0].hour != current_loop[0].hour: return True else: - return False \ No newline at end of file + return False diff --git a/Calendar/MonthBlockDesign.py b/Calendar/MonthBlockDesign.py index d0e6beb..56677c5 100644 --- a/Calendar/MonthBlockDesign.py +++ b/Calendar/MonthBlockDesign.py @@ -11,10 +11,12 @@ dayhighlightboxsize = (0.143, 0.14) daynumbersize = daynumberboxsize[0] * 0.45 day_number_ypadding = -0.002 + class MonthBlockDesign (DesignEntity): """Creates a view containing one week of the month in one row""" - def __init__(self, size, datetime_month, highlight_today = False): + + def __init__(self, size, datetime_month, highlight_today=False): super(MonthBlockDesign, self).__init__(size, mask=True) self.month = datetime_month.month self.year = datetime_month.year @@ -24,49 +26,53 @@ class MonthBlockDesign (DesignEntity): def __finish_image__(self): self.__draw_month_overview__() - def __draw_month_overview__ (self): + def __draw_month_overview__(self): """Using the built-in calendar function, draw icons for each number of the month (1,2,3,...29,30,31)""" cal = callib.monthcalendar(self.year, self.month) for week in cal: for numbers in week: - self.__draw_day_number__(numbers, self.get_day_pos(cal.index(week), week.index(numbers))) - - if self.highlight_today: - self.__draw_highlight_box__(self.__abs_pos__(dayhighlightboxsize), self.__get_today_box_pos__(), width=3) + self.__draw_day_number__(numbers, self.get_day_pos( + cal.index(week), week.index(numbers))) - def __draw_highlight_box__ (self, size, pos, color=colors["fg"], width=1): - design = BoxDesign(size, outline=color, width = width) + if self.highlight_today: + self.__draw_highlight_box__(self.__abs_pos__( + dayhighlightboxsize), self.__get_today_box_pos__(), width=3) + + def __draw_highlight_box__(self, size, pos, color=colors["fg"], width=1): + design = BoxDesign(size, outline=color, width=width) design.pos = pos self.draw_design(design) - def __draw_day_number__ (self, number, pos): + def __draw_day_number__(self, number, pos): if number <= 0: return - txt = TextDesign(self.__abs_pos__(daynumberboxsize), fontsize=daynumbersize * self.size[0], text=str(number), verticalalignment="center", horizontalalignment="center") + txt = TextDesign(self.__abs_pos__(daynumberboxsize), fontsize=daynumbersize * + self.size[0], text=str(number), verticalalignment="center", horizontalalignment="center") txt.pos = (pos[0], pos[1] + day_number_ypadding * self.size[1]) self.draw_design(txt) - - def get_day_pos (self, week_in_month, day_of_week, rel_pos=(0,0)): + + def get_day_pos(self, week_in_month, day_of_week, rel_pos=(0, 0)): maxwidth, maxheight = self.size partialwidth = maxwidth / 7 partialheight = maxheight / 5 return (int(rel_pos[0] + day_of_week * partialwidth), int(rel_pos[1] + week_in_month * partialheight)) - - def __get_today_box_pos__ (self): - x, y = self.get_day_pos(self.__get_week_of_month__(datetime.now()), self.__get_day_of_week__(datetime.now())) + + def __get_today_box_pos__(self): + x, y = self.get_day_pos(self.__get_week_of_month__( + datetime.now()), self.__get_day_of_week__(datetime.now())) return (x, int(y + (self.__abs_pos__(daynumberboxsize)[1] - self.__abs_pos__(dayhighlightboxsize)[1]) / 2)) - - def __get_week_of_month__ (self, date): + + def __get_week_of_month__(self, date): for wof, week in enumerate(callib.monthcalendar(date.year, date.month)): if date.day in week: return wof return 0 - def __get_day_of_week__ (self, date): + def __get_day_of_week__(self, date): return self.__week_days__.index(date.strftime("%a")) - def __get_week_days_ordered__ (self): + def __get_week_days_ordered__(self): cur_weekday = datetime.now().weekday() correction = -cur_weekday if week_starts_on == "Sunday": @@ -74,17 +80,18 @@ class MonthBlockDesign (DesignEntity): weekdays = [] for i in range(7): - weekdays.append((datetime.now() + timedelta(days=(i + correction))).strftime("%a")) + weekdays.append( + (datetime.now() + timedelta(days=(i + correction))).strftime("%a")) return weekdays - def __abs_pos__ (self, pos, size = None): + def __abs_pos__(self, pos, size=None): if size is None: size = self.size return (int(pos[0] * size[0]), int(pos[1] * size[1])) - def get_real_height (self): + def get_real_height(self): weeks_in_month = callib.monthcalendar(self.year, self.month) num_size = self.__abs_pos__(daynumberboxsize) num_pos = self.get_day_pos(len(weeks_in_month) - 1, 6) - return num_size[1] + num_pos[1] \ No newline at end of file + return num_size[1] + num_pos[1] diff --git a/Calendar/MonthOvPanel.py b/Calendar/MonthOvPanel.py index b377a32..437a997 100644 --- a/Calendar/MonthOvPanel.py +++ b/Calendar/MonthOvPanel.py @@ -15,7 +15,7 @@ from settings import general_settings from CryptoListDesign import CryptoListDesign -weatherheadersize = (1,0.113) +weatherheadersize = (1, 0.113) monthboxsize = (1, 0.085) monthtextsize = monthboxsize[1] * 0.75 monthplace = (0, 0.11 - weatherheadersize[1]) @@ -29,17 +29,19 @@ weekdaytextpadding = -0.001 weekrownameboxsize = (0.143, 0.044) eventcirclehorizontalsize = 0.100 + class MonthOvPanel (PanelDesign): """Overview that focuses on the current month and some additional information in the bottom.""" - def __init__ (self, size): + + def __init__(self, size): super(MonthOvPanel, self).__init__(size) self.weather_header_height = 0 if general_settings["weather-info"]: self.weather_header_height = self.size[1] * weatherheadersize[1] self.__first_render__() - def __first_render__ (self): + def __first_render__(self): if week_starts_on == "Monday": callib.setfirstweekday(callib.MONDAY) elif week_starts_on == "Sunday": @@ -52,119 +54,135 @@ class MonthOvPanel (PanelDesign): if general_settings["weather-info"]: self.__draw_seperator__() - self.month_block = MonthBlockDesign(self.__abs_pos__(monthovsize), datetime.now(), highlight_today = True) + self.month_block = MonthBlockDesign(self.__abs_pos__( + monthovsize), datetime.now(), highlight_today=True) pos = self.__abs_pos__(monthovposition) pos = (pos[0], pos[1] + self.weather_header_height) self.month_block.pos = pos self.draw_design(self.month_block) - def add_weather (self, weather): + def add_weather(self, weather): if general_settings["weather-info"] == False: return - self.draw_design(WeatherHeaderDesign(self.__abs_pos__(weatherheadersize), weather)) + self.draw_design(WeatherHeaderDesign( + self.__abs_pos__(weatherheadersize), weather)) - def add_rssfeed (self, rss): + def add_rssfeed(self, rss): if general_settings["info-area"] is "rss": self.__draw_rss_post_list_to_bottom__(rss) - def add_crypto (self, crypto): + def add_crypto(self, crypto): if general_settings["info-area"] is "crypto": self.__draw_crypto_post_list_to_bottom__(crypto) - def add_tasks (self, tasks): + def add_tasks(self, tasks): pass - def add_calendar (self, calendar): + def add_calendar(self, calendar): if general_settings["highlight-event-days"]: - month_events = list(set([ (event.begin_datetime.day, event.begin_datetime.month, event.begin_datetime.year) for event in calendar.get_month_events()])) + month_events = list(set([(event.begin_datetime.day, event.begin_datetime.month, + event.begin_datetime.year) for event in calendar.get_month_events()])) for event in month_events: self.__draw_highlight_event_day__(event) if general_settings["info-area"] is "events": self.__draw_event_list_to_bottom__(calendar) - def __draw_rss_post_list_to_bottom__ (self, rss): + def __draw_rss_post_list_to_bottom__(self, rss): month_pos = self.__abs_pos__(monthovposition) month_height = self.month_block.get_real_height() - size = (self.size[0], self.size[1] - (month_pos[1] + month_height + self.weather_header_height)) + size = (self.size[0], self.size[1] - (month_pos[1] + + month_height + self.weather_header_height)) info_list = RssPostListDesign(size, rss) - info_list.pos = (int(month_pos[0]), month_pos[1] + month_height + self.weather_header_height) + info_list.pos = ( + int(month_pos[0]), month_pos[1] + month_height + self.weather_header_height) self.draw_design(info_list) - def __draw_crypto_post_list_to_bottom__ (self, crypto): + def __draw_crypto_post_list_to_bottom__(self, crypto): month_pos = self.__abs_pos__(monthovposition) month_height = self.month_block.get_real_height() - size = (self.size[0], self.size[1] - (month_pos[1] + month_height + self.weather_header_height)) - + size = (self.size[0], self.size[1] - (month_pos[1] + + month_height + self.weather_header_height)) + info_list = CryptoListDesign(size, crypto) list_height = info_list.get_estimated_height() - info_list.pos = (int(month_pos[0]), month_pos[1] + month_height + self.weather_header_height + (size[1] - list_height)) + info_list.pos = (int(month_pos[0]), month_pos[1] + month_height + + self.weather_header_height + (size[1] - list_height)) self.draw_design(info_list) - def __draw_event_list_to_bottom__ (self, calendar): + def __draw_event_list_to_bottom__(self, calendar): month_pos = self.__abs_pos__(monthovposition) month_height = self.month_block.get_real_height() - size = (self.size[0], self.size[1] - (month_pos[1] + month_height + self.weather_header_height)) + size = (self.size[0], self.size[1] - (month_pos[1] + + month_height + self.weather_header_height)) events = calendar.get_upcoming_events() info_list = EventListDesign(size, events) - info_list.pos = (int(month_pos[0]), int(month_pos[1] + month_height + self.weather_header_height)) + info_list.pos = (int(month_pos[0]), int( + month_pos[1] + month_height + self.weather_header_height)) self.draw_design(info_list) - def __draw_highlight_event_day__ (self, date): + def __draw_highlight_event_day__(self, date): first_month_week = datetime(date[2], date[1], 1).isocalendar()[1] cur_date = datetime(date[2], date[1], date[0]) side_length = int(eventcirclehorizontalsize * self.size[0]) - circle_size = (side_length,side_length) - pos = self.month_block.get_day_pos(cur_date.isocalendar()[1] - first_month_week, self.__get_day_of_week__(cur_date), rel_pos = self.month_block.pos) - place_size = (self.month_block.size[0] * daynumberboxsize[0], self.month_block.size[1] * daynumberboxsize[1]) - pos = (int(pos[0] + (place_size[0] - circle_size[0]) / 2), int(pos[1] + (place_size[1] - circle_size[1]) / 2)) + circle_size = (side_length, side_length) + pos = self.month_block.get_day_pos(cur_date.isocalendar( + )[1] - first_month_week, self.__get_day_of_week__(cur_date), rel_pos=self.month_block.pos) + place_size = (self.month_block.size[0] * daynumberboxsize[0], + self.month_block.size[1] * daynumberboxsize[1]) + pos = (int(pos[0] + (place_size[0] - circle_size[0]) / 2), + int(pos[1] + (place_size[1] - circle_size[1]) / 2)) self.__draw_highlight_circle__(circle_size, pos, 'red', width=2) - def __abs_pos__ (self, pos, size = None): + def __abs_pos__(self, pos, size=None): if size is None: size = self.size return (int(pos[0] * size[0]), int(pos[1] * size[1])) - def __draw_seperator__ (self): + def __draw_seperator__(self): """Draw a line seperating the weather and Calendar section""" - ImageDraw.Draw(self.__image__).line([ self.__abs_pos__(seperatorplace), self.__abs_pos__((1, seperatorplace[1])) ], fill='red', width=5) + ImageDraw.Draw(self.__image__).line([self.__abs_pos__( + seperatorplace), self.__abs_pos__((1, seperatorplace[1]))], fill='red', width=5) - def __draw_month_name__ (self): + def __draw_month_name__(self): """Draw the icon with the current month's name""" month = datetime.now().strftime("%B") - txt = TextDesign(self.__abs_pos__(monthboxsize), fontsize=monthtextsize * self.size[1], text=month, verticalalignment="center", horizontalalignment="center") + txt = TextDesign(self.__abs_pos__(monthboxsize), fontsize=monthtextsize * + self.size[1], text=month, verticalalignment="center", horizontalalignment="center") pos = self.__abs_pos__(monthplace) txt.pos = (pos[0], pos[1] + self.weather_header_height) self.draw_design(txt) - def __draw_week_row__ (self): + def __draw_week_row__(self): for day_of_week, day in enumerate(self.__week_days__): - txt = TextDesign(self.__abs_pos__(weekrownameboxsize), fontsize=weekdaytextsize * self.size[1], text=str(day), verticalalignment="center", horizontalalignment="center") + txt = TextDesign(self.__abs_pos__(weekrownameboxsize), fontsize=weekdaytextsize * + self.size[1], text=str(day), verticalalignment="center", horizontalalignment="center") pos = self.__get_week_day_pos__(day_of_week) txt.pos = (pos[0], pos[1] + weekdaytextpadding * self.size[1]) self.draw_design(txt) - self.__draw_highlight_box__(self.__abs_pos__(weekrownameboxsize), self.__get_week_day_pos__(self.__get_day_of_week__(datetime.now())), width=1) + self.__draw_highlight_box__(self.__abs_pos__(weekrownameboxsize), self.__get_week_day_pos__( + self.__get_day_of_week__(datetime.now())), width=1) - def __get_week_day_pos__ (self, day_of_week): + def __get_week_day_pos__(self, day_of_week): maxwidth, _ = self.__abs_pos__(monthovsize) partialwidth = maxwidth / 7 posx, posy = self.__abs_pos__(weekdayrowpos) return (int(posx + day_of_week * partialwidth), int(posy + self.weather_header_height)) - def __draw_highlight_box__ (self, size, pos, color = colors["fg"], width = 1): - design = BoxDesign(size, outline=color, width = width) + def __draw_highlight_box__(self, size, pos, color=colors["fg"], width=1): + design = BoxDesign(size, outline=color, width=width) design.pos = pos self.draw_design(design) - def __draw_highlight_circle__ (self, size, pos, color = colors["fg"], width = 1): - design = EllipseDesign(size, outline=color, width = width) + def __draw_highlight_circle__(self, size, pos, color=colors["fg"], width=1): + design = EllipseDesign(size, outline=color, width=width) design.pos = pos self.draw_design(design) - def __get_week_days_ordered__ (self): + def __get_week_days_ordered__(self): cur_weekday = datetime.now().weekday() correction = -cur_weekday if week_starts_on == "Sunday": @@ -172,9 +190,10 @@ class MonthOvPanel (PanelDesign): weekdays = [] for i in range(7): - weekdays.append((datetime.now() + timedelta(days=(i + correction))).strftime("%a")) + weekdays.append( + (datetime.now() + timedelta(days=(i + correction))).strftime("%a")) return weekdays - def __get_day_of_week__ (self, date): + def __get_day_of_week__(self, date): return self.__week_days__.index(date.strftime("%a")) diff --git a/Calendar/MonthViewPanel.py b/Calendar/MonthViewPanel.py index 4fbab24..26b15f0 100644 --- a/Calendar/MonthViewPanel.py +++ b/Calendar/MonthViewPanel.py @@ -15,10 +15,12 @@ info_height = 0.25 info_padding = 5 seperator_width = line_thickness + class MonthViewPanel (PanelDesign): """Displays a grid of the day of the current month with detailed event descriptions.""" - def __init__(self, size, month = None, year = None): + + def __init__(self, size, month=None, year=None): super(MonthViewPanel, self).__init__(size) self.day_table = [] self.month = month @@ -39,14 +41,14 @@ class MonthViewPanel (PanelDesign): self.weather_height = weather_height self.day_area_height = 1 - self.weather_height - self.info_height self.day_area_ypos = self.weather_height - + self.week_count = self.__get_week_count__() area_height = self.size[1] * self.day_area_height area_width = self.size[0] self.day_box_size = (area_width / 7, area_height / self.week_count) - def add_weather (self, weather): + def add_weather(self, weather): if general_settings["weather-info"] == False: return size = (self.size[0], self.size[1] * self.weather_height) @@ -55,7 +57,7 @@ class MonthViewPanel (PanelDesign): self.draw_design(header) self.__draw_seperator__(size[1], colors["hl"]) - def add_calendar (self, calendar): + def add_calendar(self, calendar): self.__add_calendar_to_days__(calendar) def __add_calendar_to_days__(self, calendar): @@ -64,7 +66,7 @@ class MonthViewPanel (PanelDesign): if day != None: day.add_calendar(calendar) - def add_rssfeed (self, rss): + def add_rssfeed(self, rss): if general_settings["info-area"] != "rss": return @@ -75,19 +77,20 @@ class MonthViewPanel (PanelDesign): rss.pos = pos self.draw_design(rss) - def add_tasks (self, tasks): + def add_tasks(self, tasks): pass - def add_crypto (self, crypto): + def add_crypto(self, crypto): if general_settings["info-area"] == "crypto": self.__draw_crypto__(crypto) def __draw_crypto__(self, crypto): size = (self.size[0], self.size[1] * self.info_height) pos = (0, self.size[1] - size[1]) - + crypto = CryptoListDesign(size, crypto) - crypto.pos = (pos[0],pos[1] + (size[1] - crypto.get_estimated_height())) + crypto.pos = (pos[0], pos[1] + (size[1] - + crypto.get_estimated_height())) self.draw_design(crypto) def __finish_panel__(self): @@ -97,12 +100,13 @@ class MonthViewPanel (PanelDesign): size = (self.size[0], self.size[1] * self.day_area_height) pos = (0, self.size[1] * self.day_area_ypos) - table = TableDesign(size, matrix = self.day_table) + table = TableDesign(size, matrix=self.day_table) table.pos = pos self.draw_design(table) - def __draw_seperator__ (self, height, color): - ImageDraw.Draw(self.__image__).line([ (0, height * self.size[1]), (self.size[0], height * self.size[1]) ], fill=color, width=seperator_width) + def __draw_seperator__(self, height, color): + ImageDraw.Draw(self.__image__).line( + [(0, height * self.size[1]), (self.size[0], height * self.size[1])], fill=color, width=seperator_width) def __init_day_boxes__(self): if week_starts_on == "Monday": @@ -120,9 +124,10 @@ class MonthViewPanel (PanelDesign): if day == None or day == 0: return None - design = DayBoxDesign(self.day_box_size, date(self.year, self.month, int(day))) + design = DayBoxDesign(self.day_box_size, date( + self.year, self.month, int(day))) return design - + def __get_week_count__(self): - return len(callib.monthcalendar(self.year, self.month)) \ No newline at end of file + return len(callib.monthcalendar(self.year, self.month)) diff --git a/Calendar/OwmForecasts.py b/Calendar/OwmForecasts.py index a6cbcac..f1be14b 100644 --- a/Calendar/OwmForecasts.py +++ b/Calendar/OwmForecasts.py @@ -5,16 +5,19 @@ from datetime import datetime from settings import units, language from Translator import translate + class OwmForecasts (WeatherInterface): """Fetches weather through the Openweathermap-api.""" - def __init__ (self, location, api_key, paid_api=False): + + def __init__(self, location, api_key, paid_api=False): self.subscription = "pro" if paid_api else None self.api_key = api_key self.units = units self.location = location - self.api = pyowm.OWM(self.api_key, subscription_type=self.subscription, language=language) + self.api = pyowm.OWM( + self.api_key, subscription_type=self.subscription, language=language) - def is_available (self): + def is_available(self): try: return self.api.is_API_online() except: @@ -23,7 +26,7 @@ class OwmForecasts (WeatherInterface): def reload(self): pass - def get_today_forecast (self, location=None): + def get_today_forecast(self, location=None): if self.is_available() is False: return None @@ -37,7 +40,7 @@ class OwmForecasts (WeatherInterface): except: return None - def get_forecast_in_days (self, offset_by_days, location=None): + def get_forecast_in_days(self, offset_by_days, location=None): if offset_by_days is 0: return self.get_today_forecast(location) @@ -50,38 +53,49 @@ class OwmForecasts (WeatherInterface): target_weather = forecast.get_forecast().get_weathers()[-1] return self.__get_forecast_from_weather__(target_weather, location=location) - except: # only allowed for paid membership + except: # only allowed for paid membership return None - def __get_forecast_from_weather__ (self, weather, location): + def __get_forecast_from_weather__(self, weather, location): forecast_object = WeatherForecast() forecast_object.units = self.units forecast_object.fetch_datetime = datetime.now() forecast_object.location = location - forecast_object.datetime = weather.get_reference_time(timeformat='date') + forecast_object.datetime = weather.get_reference_time( + timeformat='date') forecast_object.icon = weather.get_weather_icon_name() forecast_object.air_humidity = str(weather.get_humidity()) forecast_object.clouds = str(weather.get_clouds()) - forecast_object.short_description = translate(str(weather.get_status())) - forecast_object.detailed_description = str(weather.get_detailed_status()) + forecast_object.short_description = translate( + str(weather.get_status())) + forecast_object.detailed_description = str( + weather.get_detailed_status()) forecast_object.air_pressure = str(weather.get_pressure()['press']) if 'deg' in weather.get_wind().keys(): forecast_object.wind_deg = str(int(weather.get_wind()['deg'])) if forecast_object.units == "metric": - forecast_object.air_temperature = str(int(weather.get_temperature(unit='celsius')['temp'])) - forecast_object.wind_speed = str(int(weather.get_wind()['speed'])) #kmh + forecast_object.air_temperature = str( + int(weather.get_temperature(unit='celsius')['temp'])) + forecast_object.wind_speed = str( + int(weather.get_wind()['speed'])) # kmh if forecast_object.units == "aviation": - forecast_object.air_temperature = str(int(weather.get_temperature(unit='celsius')['temp'])) - forecast_object.wind_speed = str(int(weather.get_wind()['speed'] * 1.94384)) #knots + forecast_object.air_temperature = str( + int(weather.get_temperature(unit='celsius')['temp'])) + forecast_object.wind_speed = str( + int(weather.get_wind()['speed'] * 1.94384)) # knots if forecast_object.units == "imperial": - forecast_object.air_temperature = str(int(weather.get_temperature('fahrenheit')['temp'])) - forecast_object.wind_speed = str(int(weather.get_wind()['speed'] * 0.621)) #mph + forecast_object.air_temperature = str( + int(weather.get_temperature('fahrenheit')['temp'])) + forecast_object.wind_speed = str( + int(weather.get_wind()['speed'] * 0.621)) # mph - forecast_object.sunrise = datetime.fromtimestamp(int(weather.get_sunrise_time(timeformat='unix'))) - forecast_object.sunset = datetime.fromtimestamp(int(weather.get_sunset_time(timeformat='unix'))) + forecast_object.sunrise = datetime.fromtimestamp( + int(weather.get_sunrise_time(timeformat='unix'))) + forecast_object.sunset = datetime.fromtimestamp( + int(weather.get_sunset_time(timeformat='unix'))) return forecast_object diff --git a/Calendar/PanelDesign.py b/Calendar/PanelDesign.py index 361d57c..e1fc60b 100644 --- a/Calendar/PanelDesign.py +++ b/Calendar/PanelDesign.py @@ -3,25 +3,27 @@ from TechnicalDataDesign import TechnicalDataDesign from settings import print_technical_data from datetime import datetime + class PanelDesign (DesignEntity): """Defined general interface for panel designs.""" - def __init__ (self, size): + + def __init__(self, size): super(PanelDesign, self).__init__(size) self.start_timestamp = datetime.now() - def add_weather (self, weather): + def add_weather(self, weather): raise NotImplementedError("Function needs to be implemented") - def add_calendar (self, calendar): + def add_calendar(self, calendar): raise NotImplementedError("Function needs to be implemented") - def add_rssfeed (self, rss): + def add_rssfeed(self, rss): raise NotImplementedError("Function needs to be implemented") - def add_tasks (self, tasks): + def add_tasks(self, tasks): raise NotImplementedError("Function needs to be implemented") - def add_crypto (self, crypto): + def add_crypto(self, crypto): raise NotImplementedError("Function needs to be implemented") def __finish_panel__(self): @@ -31,6 +33,7 @@ class PanelDesign (DesignEntity): self.__finish_panel__() if print_technical_data: - td = TechnicalDataDesign(self.size, self.start_timestamp, datetime.now()) + td = TechnicalDataDesign( + self.size, self.start_timestamp, datetime.now()) td.mask = True - self.draw_design(td) \ No newline at end of file + self.draw_design(td) diff --git a/Calendar/RssInterface.py b/Calendar/RssInterface.py index 9fe8c14..0bb03c8 100644 --- a/Calendar/RssInterface.py +++ b/Calendar/RssInterface.py @@ -1,8 +1,10 @@ from DataSourceInterface import DataSourceInterface from datetime import datetime, timezone, timedelta + class RssInterface(DataSourceInterface): """Interface for fetching and processing rss post information.""" + def __init__(self): self.loaded_posts = [] @@ -22,7 +24,7 @@ class RssInterface(DataSourceInterface): return self.get_day_posts(datetime.now()) def get_day_posts(self, day): - return self.__get_posts_to_filter__(lambda x : x.datetime.strftime('%d-%m-%y') == day.strftime('%d-%m-%y')) + return self.__get_posts_to_filter__(lambda x: x.datetime.strftime('%d-%m-%y') == day.strftime('%d-%m-%y')) def __get_posts_to_filter__(self, post_filter): if self.loaded_posts is None: @@ -30,4 +32,4 @@ class RssInterface(DataSourceInterface): return [post for post in self.loaded_posts if post_filter(post)] def __sort_posts__(self): - self.loaded_posts.sort(key=lambda x : x.datetime, reverse=True) \ No newline at end of file + self.loaded_posts.sort(key=lambda x: x.datetime, reverse=True) diff --git a/Calendar/RssParserPosts.py b/Calendar/RssParserPosts.py index 11089fc..5c415b4 100644 --- a/Calendar/RssParserPosts.py +++ b/Calendar/RssParserPosts.py @@ -6,8 +6,10 @@ from urllib.request import urlopen max_range_days = 14 + class RssParserPosts (RssInterface): """Fetches posts from url-addresses via rss parser.""" + def __init__(self, urls): self.urls = urls super(RssParserPosts, self).__init__() @@ -52,5 +54,4 @@ class RssParserPosts (RssInterface): def __get_webpage__(self, link): start_index = link.find('://') + 3 end_index = link[start_index:].find('/') + start_index - return link[start_index : end_index] - \ No newline at end of file + return link[start_index: end_index] diff --git a/Calendar/RssPost.py b/Calendar/RssPost.py index 7851d6b..b50505b 100644 --- a/Calendar/RssPost.py +++ b/Calendar/RssPost.py @@ -1,9 +1,10 @@ class RssPost(object): """Defines a rss post, independent of any implementation""" - def __init__ (self): + + def __init__(self): self.title = None self.description = None self.source = None self.datetime = None - self.fetch_datetime = None \ No newline at end of file + self.fetch_datetime = None diff --git a/Calendar/RssPostListDesign.py b/Calendar/RssPostListDesign.py index 724c915..f4e06ea 100644 --- a/Calendar/RssPostListDesign.py +++ b/Calendar/RssPostListDesign.py @@ -2,32 +2,35 @@ from DesignEntity import DesignEntity from TableDesign import TableDesign from Assets import defaultfontsize + class RssPostListDesign (DesignEntity): """Creates a TableDesign filled with rss post date and title""" - def __init__ (self, size, rssfeed, text_size = defaultfontsize): + + def __init__(self, size, rssfeed, text_size=defaultfontsize): super(RssPostListDesign, self).__init__(size) self.rssfeed = rssfeed self.__post_matrix__ = [] self.text_size = text_size - def __finish_image__ (self): + def __finish_image__(self): self.__fill_post_matrix__() - table_design = TableDesign(self.size, line_spacing=2, col_spacing=3, matrix=self.__post_matrix__, fontsize = self.text_size, mask=False, wrap=True, truncate_rows=True) + table_design = TableDesign(self.size, line_spacing=2, col_spacing=3, matrix=self.__post_matrix__, + fontsize=self.text_size, mask=False, wrap=True, truncate_rows=True) self.draw_design(table_design) - - def __get_formatted_post__ (self, post): + + def __get_formatted_post__(self, post): date = post.datetime.strftime('%d %b') date = self.__remove_leading_zero__(date) - return [ '', '•', post.title ] + return ['', '•', post.title] def __remove_leading_zero__(self, text): while text[0] is '0': text = text[1:] return text - - def __fill_post_matrix__ (self): + + def __fill_post_matrix__(self): for post in self.rssfeed.get_latest_posts(): row = self.__get_formatted_post__(post) - self.__post_matrix__.append(row) \ No newline at end of file + self.__post_matrix__.append(row) diff --git a/Calendar/SingelDayEventListDesign.py b/Calendar/SingelDayEventListDesign.py index 90f3547..f3d7942 100644 --- a/Calendar/SingelDayEventListDesign.py +++ b/Calendar/SingelDayEventListDesign.py @@ -5,8 +5,11 @@ from TextFormatter import event_prefix_str_sum font = fonts["regular"] + class SingelDayEventListDesign (EventListDesign): """Specialized event list for day list design.""" - def __init__ (self, size, events, font_size = defaultfontsize, line_spacing=0, event_prefix_rel_dates = [], col_spacing=5, general_color=colors["fg"], background_color=colors["bg"], highlight_color=colors["hl"]): - prefix_func = lambda x, rel_date : event_prefix_str_sum(x, rel_date) - super().__init__(size, events, text_size=font_size, line_spacing=line_spacing, col_spacing=col_spacing, event_prefix_rel_dates = event_prefix_rel_dates, event_prefix_func=prefix_func, font_family=font, show_more_info=True, general_color=general_color, background_color=background_color, highlight_color = highlight_color) \ No newline at end of file + + def __init__(self, size, events, font_size=defaultfontsize, line_spacing=0, event_prefix_rel_dates=[], col_spacing=5, general_color=colors["fg"], background_color=colors["bg"], highlight_color=colors["hl"]): + def prefix_func(x, rel_date): return event_prefix_str_sum(x, rel_date) + super().__init__(size, events, text_size=font_size, line_spacing=line_spacing, col_spacing=col_spacing, event_prefix_rel_dates=event_prefix_rel_dates, + event_prefix_func=prefix_func, font_family=font, show_more_info=True, general_color=general_color, background_color=background_color, highlight_color=highlight_color) diff --git a/Calendar/TableDesign.py b/Calendar/TableDesign.py index c08beb0..b654f2d 100644 --- a/Calendar/TableDesign.py +++ b/Calendar/TableDesign.py @@ -5,16 +5,19 @@ from DesignEntity import DesignEntity default_props = { - "color" : colors["fg"], - "background_color" : colors["bg"], - "font-size" : defaultfontsize + "color": colors["fg"], + "background_color": colors["bg"], + "font-size": defaultfontsize } + class TableDesign (TextDesign): """Gets a matrix with text or designs that is than displayed in a table without borders.""" - def __init__ (self, size, matrix, max_col_size = None, max_row_size = None, font = None, fontsize = defaultfontsize, column_horizontal_alignments = [], mask = True, line_spacing = 0, col_spacing = 0, truncate_rows = True, truncate_cols = True, wrap = False, truncate_text=True, truncate_suffix="...", cell_properties=None, background_color = colors["bg"]): - super(TableDesign, self).__init__(size, font=font, fontsize=fontsize, mask=mask) + + def __init__(self, size, matrix, max_col_size=None, max_row_size=None, font=None, fontsize=defaultfontsize, column_horizontal_alignments=[], mask=True, line_spacing=0, col_spacing=0, truncate_rows=True, truncate_cols=True, wrap=False, truncate_text=True, truncate_suffix="...", cell_properties=None, background_color=colors["bg"]): + super(TableDesign, self).__init__( + size, font=font, fontsize=fontsize, mask=mask) self.__init_image__(background_color) self.matrix = matrix self.max_col_size = max_col_size @@ -32,7 +35,7 @@ class TableDesign (TextDesign): self.cell_properties = cell_properties default_props["font-size"] = fontsize - def __finish_image__ (self): + def __finish_image__(self): if len(self.matrix) is 0: return self.__reform_col_size__() @@ -41,19 +44,19 @@ class TableDesign (TextDesign): self.max_col, self.max_row = self.__get_truncated_counts__() self.__print_table__(self.matrix) - def __reform_col_size__ (self): + def __reform_col_size__(self): if self.max_col_size is not None: return - + col_sizes = [] - for c in range(len(self.matrix[0])): #amout of columns + for c in range(len(self.matrix[0])): # amout of columns for r in range(len(self.matrix)): - row_col_size = self.__get_cell_size__(r,c)[0] + row_col_size = self.__get_cell_size__(r, c)[0] if len(col_sizes) - 1 < c: col_sizes.append(row_col_size) elif row_col_size > col_sizes[c]: col_sizes[c] = row_col_size - + for index, size in enumerate(col_sizes): preceding_size = sum(col_sizes[:index]) + index * self.col_spacing if preceding_size + size > self.size[0]: @@ -62,19 +65,19 @@ class TableDesign (TextDesign): self.max_col_size = col_sizes - def __reform_row_size__ (self): + def __reform_row_size__(self): if self.max_row_size is not None: return - + row_sizes = [] for r in range(len(self.matrix)): - for c in range(len(self.matrix[0])): #amout of columns - col_row_size = self.__get_cell_size__(r,c)[1] + for c in range(len(self.matrix[0])): # amout of columns + col_row_size = self.__get_cell_size__(r, c)[1] if len(row_sizes) - 1 < r: row_sizes.append(col_row_size) elif col_row_size > row_sizes[r]: row_sizes[r] = col_row_size - + self.max_row_size = row_sizes def __get_cell_size__(self, r, c): @@ -85,18 +88,20 @@ class TableDesign (TextDesign): return size elif type(content) == str: font = self.__get_font__() - width = font.getsize(self.matrix[r][c])[0] #get width of text in that row/col + # get width of text in that row/col + width = font.getsize(self.matrix[r][c])[0] if self.wrap and self.max_col_size != None: - content = wrap_text_with_font(content, self.max_col_size[c], font) + content = wrap_text_with_font( + content, self.max_col_size[c], font) line_count = content.count('\n') + 1 - height = font.font.height * line_count #get height of text in that col/row + height = font.font.height * line_count # get height of text in that col/row size = (width, height) - else: #DesignEntity + else: # DesignEntity size = content.size return size - def __get_truncated_counts__ (self): + def __get_truncated_counts__(self): max_col = 0 if self.truncate_cols: while max_col < len(self.matrix[0]) and self.__get_cell_pos__(0, max_col + 1)[0] - self.col_spacing <= self.size[0]: @@ -106,44 +111,45 @@ class TableDesign (TextDesign): max_row = 0 if self.truncate_rows: - while max_row < len(self.matrix) and self.__get_cell_pos__(max_row + 1,0)[1] - self.line_spacing <= self.size[1]: + while max_row < len(self.matrix) and self.__get_cell_pos__(max_row + 1, 0)[1] - self.line_spacing <= self.size[1]: max_row += 1 else: max_row = len(self.matrix) return (max_col, max_row) - def __print_table__ (self, matrix): + def __print_table__(self, matrix): for r in range(self.max_row): for c in range(self.max_col): - self.__draw_cell__(r,c) - - def __draw_text__ (self, pos, size, row, col): + self.__draw_cell__(r, c) + + def __draw_text__(self, pos, size, row, col): color = self.__get_cell_prop__(row, col, "color") bg_color = self.__get_cell_prop__(row, col, "background_color") fontsize = self.__get_cell_prop__(row, col, "font-size") - design = TextDesign(size, text=self.matrix[row][col], font=self.font_family, color=color, background_color=bg_color, fontsize=fontsize, horizontalalignment=self.__get_col_hori_alignment__(col), wrap=self.wrap, truncate=self.truncate_text, truncate_suffix=self.truncate_suffix) + design = TextDesign(size, text=self.matrix[row][col], font=self.font_family, color=color, background_color=bg_color, fontsize=fontsize, + horizontalalignment=self.__get_col_hori_alignment__(col), wrap=self.wrap, truncate=self.truncate_text, truncate_suffix=self.truncate_suffix) design.pos = pos design.mask = False self.draw_design(design) - - def __draw_design__ (self, pos, size, row, col): + + def __draw_design__(self, pos, size, row, col): bg_color = self.__get_cell_prop__(row, col, "background_color") source_design = self.matrix[row][col] source_design.mask = False - framed_design = DesignEntity(size, mask = False) + framed_design = DesignEntity(size, mask=False) framed_design.__init_image__(color=bg_color) framed_design.draw_design(source_design) framed_design.pos = pos self.draw_design(framed_design) - def __draw_cell__ (self, row, col): + def __draw_cell__(self, row, col): size = self.cell_sizes[row][col] - pos = self.__get_cell_pos__(row,col) + pos = self.__get_cell_pos__(row, col) if self.matrix[row][col] == None: return @@ -151,8 +157,8 @@ class TableDesign (TextDesign): self.__draw_text__(pos, size, row, col) else: self.__draw_design__(pos, size, row, col) - - def __get_cell_pos__ (self, row, col): + + def __get_cell_pos__(self, row, col): xpos, ypos = (0, 0) for c in range(col): xpos += self.cell_sizes[row][c][0] @@ -162,7 +168,7 @@ class TableDesign (TextDesign): ypos += self.line_spacing return (xpos, ypos) - def __get_cell_sizes__ (self): + def __get_cell_sizes__(self): size_matrix = [] for r in range(len(self.matrix)): size_matrix.append([]) @@ -171,7 +177,7 @@ class TableDesign (TextDesign): size_matrix[r].append(size) return size_matrix - def __get_col_hori_alignment__ (self, c): + def __get_col_hori_alignment__(self, c): if len(self.column_horizontal_alignments) <= c: return "left" return self.column_horizontal_alignments[c] @@ -179,8 +185,8 @@ class TableDesign (TextDesign): def __get_cell_prop__(self, r, c, prop): if self.cell_properties is None: return default_props[prop] - + if r < len(self.cell_properties) and c < len(self.cell_properties[r]) and prop in self.cell_properties[r][c].keys(): return self.cell_properties[r][c][prop] else: - return default_props[prop] \ No newline at end of file + return default_props[prop] diff --git a/Calendar/TechnicalDataDesign.py b/Calendar/TechnicalDataDesign.py index f66f59a..4445fa7 100644 --- a/Calendar/TechnicalDataDesign.py +++ b/Calendar/TechnicalDataDesign.py @@ -4,10 +4,12 @@ from Assets import colors font_size = 20 + class TechnicalDataDesign(DesignEntity): '''Prints data about the current loop ontop of the panel''' + def __init__(self, size, start, stop): - super(TechnicalDataDesign, self).__init__(size, mask = True) + super(TechnicalDataDesign, self).__init__(size, mask=True) self.start = start self.stop = stop @@ -37,4 +39,4 @@ class TechnicalDataDesign(DesignEntity): data += str(dur) data += "\nSTOP: " data += str(self.stop) - return data \ No newline at end of file + return data diff --git a/Calendar/TextDesign.py b/Calendar/TextDesign.py index 9c44e70..beac47a 100644 --- a/Calendar/TextDesign.py +++ b/Calendar/TextDesign.py @@ -5,11 +5,13 @@ from TextWraper import wrap_text_with_font truncateerror_fontsize = 0.5 + class TextDesign (DesignEntity): """Object that manages all information relevant to text and prints it to an image""" - def __init__ (self, size, color=colors["fg"], background_color=colors["bg"], font = None, fontsize = defaultfontsize, text = "", horizontalalignment = "left", verticalalignment = "top", mask=True, truncate=False, truncate_suffix = '...', wrap=False): - super(TextDesign, self).__init__(size, mask = mask) + + def __init__(self, size, color=colors["fg"], background_color=colors["bg"], font=None, fontsize=defaultfontsize, text="", horizontalalignment="left", verticalalignment="top", mask=True, truncate=False, truncate_suffix='...', wrap=False): + super(TextDesign, self).__init__(size, mask=mask) if font is None: font = defaultfont self.font_family = font @@ -23,7 +25,7 @@ class TextDesign (DesignEntity): self.color = color self.background_color = background_color - def __finish_image__ (self): + def __finish_image__(self): if self.color is "white": self.invert_mask = True if self.background_color not in ["white", "black"] or self.color in ["red"]: @@ -36,21 +38,24 @@ class TextDesign (DesignEntity): if self.wrap: self.__wrap_text__() pos = self.__pos_from_alignment__() - ImageDraw.Draw(self.__image__).text(pos, self.text, fill=self.color, font=self.__font__) - - def __truncate_text__ (self): - if self.__font__.getsize_multiline(self.text)[0] <= self.size[0]: #does not need truncating + ImageDraw.Draw(self.__image__).text( + pos, self.text, fill=self.color, font=self.__font__) + + def __truncate_text__(self): + # does not need truncating + if self.__font__.getsize_multiline(self.text)[0] <= self.size[0]: return - suffix_length = self.__font__.getsize_multiline(self.truncate_suffix)[0] + suffix_length = self.__font__.getsize_multiline( + self.truncate_suffix)[0] while len(self.text) > 1 and self.__font__.getsize_multiline(self.text)[0] + suffix_length >= self.size[0]: self.text = self.text[0:-1] self.text = self.text.rstrip(' ') self.text += self.truncate_suffix - def __pos_from_alignment__ (self): + def __pos_from_alignment__(self): width, height = self.__get_text_size__() x, y = 0, 0 - + if self.vertical_alignment == "center": y = int((self.size[1] / 2) - (height / 2)) elif self.vertical_alignment == "bottom": @@ -68,8 +73,8 @@ class TextDesign (DesignEntity): height = (self.text.count('\n') + 1) * self.__font__.font.height return widht, height - def __wrap_text__ (self): + def __wrap_text__(self): self.text = wrap_text_with_font(self.text, self.size[0], self.__font__) def __get_font__(self): - return ImageFont.truetype(path + self.font_family, int(self.font_size)) \ No newline at end of file + return ImageFont.truetype(path + self.font_family, int(self.font_size)) diff --git a/Calendar/TextFormatter.py b/Calendar/TextFormatter.py index 94e5b59..e0e7f01 100644 --- a/Calendar/TextFormatter.py +++ b/Calendar/TextFormatter.py @@ -12,7 +12,8 @@ until_character = ' - ' allday_character = "•" multiday_character = allday_character + allday_character -def time_str (dt): + +def time_str(dt): if hours is "12": return dt.strftime("%I:%M%p") elif hours is "24": @@ -20,29 +21,31 @@ def time_str (dt): else: return str(dt) -def event_prefix_str_md_dif (event, relative_date=None): + +def event_prefix_str_md_dif(event, relative_date=None): if relative_date is None: relative_date = event.begin_datetime.date() if event.multiday is False: return event_time_summary(event) - - #Relative to - #First day + + # Relative to + # First day elif __equal__(event.begin_datetime, relative_date): return event_time_summary(event) + multiday_begin_character - #Last day + # Last day elif __equal__(event.end_datetime, relative_date) or \ - (__day_duration__(event.end_datetime) == timedelta(0) and __equal__(relative_date + timedelta(1), event.end_datetime)): + (__day_duration__(event.end_datetime) == timedelta(0) and __equal__(relative_date + timedelta(1), event.end_datetime)): return multiday_end_character + event_time_summary(event) - #Some day + # Some day else: event.allday = True return multiday_end_character + event_time_summary(event) + multiday_begin_character -def event_prefix_str (event, relative_date=None): + +def event_prefix_str(event, relative_date=None): if relative_date is None: relative_date = event.begin_datetime.date() @@ -51,7 +54,8 @@ def event_prefix_str (event, relative_date=None): else: return event_time_detailed(event) -def event_prefix_str_sum (event, relative_date=None): + +def event_prefix_str_sum(event, relative_date=None): if relative_date is None: relative_date = event.begin_datetime.date() @@ -60,25 +64,30 @@ def event_prefix_str_sum (event, relative_date=None): else: return event_time_summary(event) -def event_time_summary (event): + +def event_time_summary(event): if event.allday: return allday_character else: return time_str(event.begin_datetime) -def event_time_detailed (event): + +def event_time_detailed(event): if event.allday: return get_text(allday_events) else: return time_str(event.begin_datetime) + until_character + time_str(event.end_datetime) + def date_str(dt): return remove_leading_zero(dt.strftime('%d. %b')) -def remove_leading_zero (text): - while text[0] is '0': - text = text[1:] - return text + +def remove_leading_zero(text): + while text[0] is '0': + text = text[1:] + return text + def date_summary_str(dt): day = remove_leading_zero(dt.strftime("%d")) @@ -89,11 +98,13 @@ def date_summary_str(dt): else: return dt.strftime('%a ' + day + '. %b') + def __equal__(dt1, dt2): return dt1.day == dt2.day and \ dt1.month == dt2.month and \ dt1.year == dt2.year + def __day_duration__(dt): day_begin = datetime(dt.year, dt.month, dt.day, 0, 0, 0, 0, timezone.utc) - return dt - day_begin \ No newline at end of file + return dt - day_begin diff --git a/Calendar/TextWraper.py b/Calendar/TextWraper.py index b480a36..dcb2970 100644 --- a/Calendar/TextWraper.py +++ b/Calendar/TextWraper.py @@ -1,10 +1,11 @@ from Assets import path, defaultfont from PIL import ImageFont -def wrap_text_with_font (text, width, font): + +def wrap_text_with_font(text, width, font): words = text.split(' ') result = "" - for index, word in enumerate(words): + for word in words: until_current = (result + " " + word).strip() txt_width, _ = font.getsize_multiline(until_current) if txt_width > width: @@ -14,5 +15,6 @@ def wrap_text_with_font (text, width, font): result += word return result.strip() -def wrap_text (text, width, font_size, font_family = defaultfont): - return wrap_text_with_font(text, width, ImageFont.truetype(path + font_family, int(font_size))) \ No newline at end of file + +def wrap_text(text, width, font_size, font_family=defaultfont): + return wrap_text_with_font(text, width, ImageFont.truetype(path + font_family, int(font_size))) diff --git a/Calendar/Translator.py b/Calendar/Translator.py index 0a523de..2eb4297 100644 --- a/Calendar/Translator.py +++ b/Calendar/Translator.py @@ -4,7 +4,8 @@ from settings import language '''Looks up a phrase in a given dictionary-collection and returns the translated phrase''' -def translate(phrase, target_lang = language, dictionary_collection = dictionary_collection) : + +def translate(phrase, target_lang=language, dictionary_collection=dictionary_collection): dictionary = find_dictionary(phrase, dictionary_collection) if dictionary == None: @@ -17,8 +18,9 @@ def translate(phrase, target_lang = language, dictionary_collection = dictionary else: return dictionary[default_language] -def find_dictionary(phrase, dictionary_collection = dictionary_collection): + +def find_dictionary(phrase, dictionary_collection=dictionary_collection): for dictionary in dictionary_collection: if phrase in dictionary.values(): return dictionary - return None \ No newline at end of file + return None diff --git a/Calendar/WeatherColumnDesign.py b/Calendar/WeatherColumnDesign.py index 77f6ec7..5de1232 100644 --- a/Calendar/WeatherColumnDesign.py +++ b/Calendar/WeatherColumnDesign.py @@ -13,13 +13,15 @@ info_yresize = -0.05 fontsize_static = defaultfontsize max_symbol_y_width = 0.15 + class WeatherColumnDesign (DesignEntity): """Displays weather information in a column""" - def __init__ (self, size, forecast): + + def __init__(self, size, forecast): super().__init__(size) self.forecast = forecast - def __finish_image__ (self): + def __finish_image__(self): if self.forecast is None: self.__draw_no_response__() return @@ -27,47 +29,56 @@ class WeatherColumnDesign (DesignEntity): self.__draw_icon__(self.forecast.icon) self.__draw_infos__(self.forecast) - def __draw_infos__ (self, forecast): - temperature = forecast.air_temperature + " " + self.__get_unit__(("°C", "°F")) + def __draw_infos__(self, forecast): + temperature = forecast.air_temperature + \ + " " + self.__get_unit__(("°C", "°F")) humidity = forecast.air_humidity + "%" - if forecast.units== "aviation": + if forecast.units == "aviation": if forecast.wind_deg == None: forecast.wind_deg = "" - elif len(forecast.wind_deg)==1: + elif len(forecast.wind_deg) == 1: forecast.wind_deg = "00" + forecast.wind_deg - elif len(forecast.wind_deg)==2: + elif len(forecast.wind_deg) == 2: forecast.wind_deg = "0" + forecast.wind_deg - if int(forecast.wind_speed)<10: - windspeed = forecast.wind_deg + "@" + "0" + forecast.wind_speed + self.__get_unit__(("", "")) #added degrees, if wind<10 add a 0 to make two digit + if int(forecast.wind_speed) < 10: + windspeed = forecast.wind_deg + "@" + "0" + forecast.wind_speed + \ + self.__get_unit__( + ("", "")) # added degrees, if wind<10 add a 0 to make two digit else: - windspeed = forecast.wind_deg + "@" + forecast.wind_speed + self.__get_unit__(("", "")) #added degrees + windspeed = forecast.wind_deg + "@" + forecast.wind_speed + \ + self.__get_unit__(("", "")) # added degrees else: - windspeed = forecast.wind_speed + " " + self.__get_unit__(("km/h", "mph")) + windspeed = forecast.wind_speed + " " + \ + self.__get_unit__(("km/h", "mph")) - numbers_list = [ [ forecast.short_description ], - [ temperature ], - [ humidity ], - [ windspeed ] ] + numbers_list = [[forecast.short_description], + [temperature], + [humidity], + [windspeed]] ypos = info_x_ypos * self.size[0] pos = (0, ypos) - size = (self.size[0], self.size[1] + info_yresize * self.size[1] - pos[1]) - line_spacing = (size[1] - len(numbers_list) * fontsize_static) / (len(numbers_list) + 1) + size = (self.size[0], self.size[1] + + info_yresize * self.size[1] - pos[1]) + line_spacing = (size[1] - len(numbers_list) * + fontsize_static) / (len(numbers_list) + 1) - table = TableDesign(size, numbers_list, fontsize=fontsize_static, line_spacing=line_spacing, column_horizontal_alignments=[ "center" ], max_col_size=[ size[0] ], truncate_text=False, truncate_rows=False) + table = TableDesign(size, numbers_list, fontsize=fontsize_static, line_spacing=line_spacing, column_horizontal_alignments=[ + "center"], max_col_size=[size[0]], truncate_text=False, truncate_rows=False) table.pos = pos self.draw_design(table) - def __draw_icon__ (self, icon_id): + def __draw_icon__(self, icon_id): width = int(icon_width * self.size[0]) size = (width, width) xpos = icon_xpos * self.size[0] ypos = icon_x_ypos * self.size[0] pos = (xpos, ypos) - self.__draw_resized_path_at__(wpath + weathericons[icon_id] + ".jpeg", pos, size) + self.__draw_resized_path_at__( + wpath + weathericons[icon_id] + ".jpeg", pos, size) - def __draw_no_response__ (self): + def __draw_no_response__(self): width = int(icon_width * self.size[0]) size = (width, width) xpos = icon_xpos * self.size[0] @@ -76,26 +87,25 @@ class WeatherColumnDesign (DesignEntity): self.__draw_resized_image_at__(no_response, pos, size) - def __draw_resized_path_at__ (self, path, pos, size): + def __draw_resized_path_at__(self, path, pos, size): img = Image.open(path) self.__draw_resized_image_at__(img, pos, size) - def __draw_resized_image_at__ (self, img, pos, size): + def __draw_resized_image_at__(self, img, pos, size): size = (int(size[0]), int(size[1])) resized_img = img.resize(size, resample=Image.LANCZOS) self.draw(resized_img, pos) - - def __get_unit__ (self, tuple): + def __get_unit__(self, tuple): if self.forecast.units == "metric" or self.forecast.units == "aviation": return tuple[0] else: return tuple[1] - def __abs_co__ (self, coordinates): + def __abs_co__(self, coordinates): return (coordinates[0] * self.size[0], coordinates[1] * self.size[1]) - def __get_time__ (self, time): + def __get_time__(self, time): if hours == "24": return time.strftime('%H:%M') else: diff --git a/Calendar/WeatherForecast.py b/Calendar/WeatherForecast.py index 8c717ec..a2a192a 100644 --- a/Calendar/WeatherForecast.py +++ b/Calendar/WeatherForecast.py @@ -1,6 +1,7 @@ class WeatherForecast (object): """Defines a weather forecast, independent of any implementation""" - def __init__ (self): + + def __init__(self): self.air_temperature = None self.air_pressure = None self.air_humidity = None @@ -21,4 +22,4 @@ class WeatherForecast (object): self.units = None self.datetime = None self.location = None - self.fetch_datetime = None \ No newline at end of file + self.fetch_datetime = None diff --git a/Calendar/WeatherHeaderDesign.py b/Calendar/WeatherHeaderDesign.py index 2e7562b..f8d5940 100644 --- a/Calendar/WeatherHeaderDesign.py +++ b/Calendar/WeatherHeaderDesign.py @@ -10,14 +10,16 @@ windiconspace = (0.206, 0) sunriseplace = (0.55, 0) sunsetplace = (0.55, 0.486) + class WeatherHeaderDesign (DesignEntity): """Defines a top area that displays basic weather information""" - def __init__ (self, size, weather): + + def __init__(self, size, weather): super(WeatherHeaderDesign, self).__init__(size) self.__weather__ = weather self.__first_render__() - def __first_render__ (self): + def __first_render__(self): if self.__weather__.is_available() is False: self.__render_missing_connection__() return @@ -28,53 +30,65 @@ class WeatherHeaderDesign (DesignEntity): self.__render_missing_connection__() return - temperature = cur_weather.air_temperature + " " + self.__get_unit__(("°C", "°F")) - if units== "aviation": #pick up aviation + temperature = cur_weather.air_temperature + \ + " " + self.__get_unit__(("°C", "°F")) + if units == "aviation": # pick up aviation if cur_weather.wind_deg == None: cur_weather.wind_deg = "" - elif len(cur_weather.wind_deg)==1: #if deg is 2, add two zeros for format + elif len(cur_weather.wind_deg) == 1: # if deg is 2, add two zeros for format cur_weather.wind_deg = "00" + cur_weather.wind_deg - elif len(cur_weather.wind_deg)==2: + elif len(cur_weather.wind_deg) == 2: cur_weather.wind_deg = "0" + cur_weather.wind_deg - if int(cur_weather.wind_speed)<10: - windspeed = cur_weather.wind_deg + "@" + "0" + cur_weather.wind_speed + self.__get_unit__(("", "")) #added degrees, if wind<10 add a 0 to make two digit + if int(cur_weather.wind_speed) < 10: + windspeed = cur_weather.wind_deg + "@" + "0" + cur_weather.wind_speed + \ + self.__get_unit__( + ("", "")) # added degrees, if wind<10 add a 0 to make two digit else: - windspeed = cur_weather.wind_deg + "@" + cur_weather.wind_speed + self.__get_unit__(("", "")) #added degrees + windspeed = cur_weather.wind_deg + "@" + cur_weather.wind_speed + \ + self.__get_unit__(("", "")) # added degrees else: - windspeed = cur_weather.wind_speed + " " + self.__get_unit__(("km/h", "mph")) + windspeed = cur_weather.wind_speed + " " + \ + self.__get_unit__(("km/h", "mph")) - self.__draw_text__(temperature, self.__abs_pos__((0.87, 0)), (50,35)) - self.__draw_text__(windspeed, self.__abs_pos__((0.297, 0.05)), (100,35)) - self.__draw_text__(self.__get_time__(cur_weather.sunrise), self.__abs_pos__((0.64,0)), (50,35)) - self.__draw_text__(self.__get_time__(cur_weather.sunset), self.__abs_pos__((0.64,0.486)), (50,35)) - self.__draw_text__(cur_weather.air_humidity + " %", self.__abs_pos__((0.87,0.486)), (50,35)) - self.__draw_text__(cur_weather.short_description, self.__abs_pos__((0.182,0.486)), (144,35)) + self.__draw_text__(temperature, self.__abs_pos__((0.87, 0)), (50, 35)) + self.__draw_text__(windspeed, self.__abs_pos__( + (0.297, 0.05)), (100, 35)) + self.__draw_text__(self.__get_time__(cur_weather.sunrise), + self.__abs_pos__((0.64, 0)), (50, 35)) + self.__draw_text__(self.__get_time__(cur_weather.sunset), + self.__abs_pos__((0.64, 0.486)), (50, 35)) + self.__draw_text__(cur_weather.air_humidity + " %", + self.__abs_pos__((0.87, 0.486)), (50, 35)) + self.__draw_text__(cur_weather.short_description, + self.__abs_pos__((0.182, 0.486)), (144, 35)) self.draw(windicon, self.__abs_pos__(windiconspace)) self.draw(sunseticon, self.__abs_pos__(sunsetplace)) self.draw(sunriseicon, self.__abs_pos__(sunriseplace)) self.draw(humicon, self.__abs_pos__(humplace)) self.draw(tempicon, self.__abs_pos__(tempplace)) - self.draw_image(wpath + weathericons[cur_weather.icon] + '.jpeg', self.__abs_pos__(wiconplace)) + self.draw_image( + wpath + weathericons[cur_weather.icon] + '.jpeg', self.__abs_pos__(wiconplace)) - def __render_missing_connection__ (self): + def __render_missing_connection__(self): self.draw(no_response, self.__abs_pos__(wiconplace)) - def __abs_pos__ (self, pos): + def __abs_pos__(self, pos): return (int(pos[0] * self.size[0]), int(pos[1] * self.size[1])) - def __draw_text__ (self, text, pos, size): - txt = TextDesign(size, fontsize=18, text=text, verticalalignment="center", horizontalalignment="center") + def __draw_text__(self, text, pos, size): + txt = TextDesign(size, fontsize=18, text=text, + verticalalignment="center", horizontalalignment="center") txt.pos = pos self.draw_design(txt) - def __get_unit__ (self, tuple): + def __get_unit__(self, tuple): if units == "metric" or units == "aviation": return tuple[0] else: return tuple[1] - def __get_time__ (self, time): + def __get_time__(self, time): if hours == "24": return time.strftime('%H:%M') else: diff --git a/Calendar/WeatherInterface.py b/Calendar/WeatherInterface.py index bd3fc6e..cb02fc9 100644 --- a/Calendar/WeatherInterface.py +++ b/Calendar/WeatherInterface.py @@ -1,9 +1,11 @@ from DataSourceInterface import DataSourceInterface + class WeatherInterface (DataSourceInterface): """Interface for fetching and processing weather forecast information.""" - def get_forecast_in_days (self, offset_by_days, location=None): + + def get_forecast_in_days(self, offset_by_days, location=None): raise NotImplementedError("Functions needs to be implemented") - def get_today_forecast (self, location=None): - raise NotImplementedError("Functions needs to be implemented") \ No newline at end of file + def get_today_forecast(self, location=None): + raise NotImplementedError("Functions needs to be implemented")