diff --git a/fonts/MaterialIcons/MaterialIcons.ttf b/fonts/MaterialIcons/MaterialIcons.ttf new file mode 100644 index 0000000..9d09b0f Binary files /dev/null and b/fonts/MaterialIcons/MaterialIcons.ttf differ diff --git a/inkycal/custom/openweathermap_wrapper.py b/inkycal/custom/openweathermap_wrapper.py index 6cd4405..779c5bf 100644 --- a/inkycal/custom/openweathermap_wrapper.py +++ b/inkycal/custom/openweathermap_wrapper.py @@ -41,18 +41,9 @@ def get_json_from_url(request_url): class OpenWeatherMap: - def __init__( - self, - api_key: str, - city_id: int = None, - lat: float = None, - lon: float = None, - api_version: API_VERSIONS = "2.5", - temp_unit: TEMP_UNITS = "celsius", - wind_unit: WIND_UNITS = "meters_sec", - language: str = "en", - tz_name: str = "UTC", - ) -> None: + def __init__(self, api_key: str, city_id: int = None, lat: float = None, lon: float = None, + api_version: API_VERSIONS = "2.5", temp_unit: TEMP_UNITS = "celsius", + wind_unit: WIND_UNITS = "meters_sec", language: str = "en", tz_name: str = "UTC") -> None: self.api_key = api_key self.temp_unit = temp_unit self.wind_unit = wind_unit @@ -106,7 +97,7 @@ class OpenWeatherMap: current_weather["temp_feels_like"] = self.get_converted_temperature(current_data["main"]["feels_like"]) current_weather["min_temp"] = self.get_converted_temperature(current_data["main"]["temp_min"]) current_weather["max_temp"] = self.get_converted_temperature(current_data["main"]["temp_max"]) - current_weather["humidity"] = current_data["main"]["humidity"] # OWM Unit: % rH + current_weather["humidity"] = current_data["main"]["humidity"] # OWM Unit: % rH current_weather["wind"] = self.get_converted_windspeed( current_data["wind"]["speed"] ) # OWM Unit Default: meter/sec, Metric: meter/sec @@ -161,10 +152,10 @@ class OpenWeatherMap: forecast["wind"]["speed"] ), # OWM Unit Default: meter/sec, Metric: meter/sec, Imperial: miles/hour "wind_gust": self.get_converted_windspeed(forecast["wind"]["gust"]), - "pressure": forecast["main"]["pressure"], # OWM Unit: hPa - "humidity": forecast["main"]["humidity"], # OWM Unit: % rH + "pressure": forecast["main"]["pressure"], # OWM Unit: hPa + "humidity": forecast["main"]["humidity"], # OWM Unit: % rH "precip_probability": forecast["pop"] - * 100.0, # OWM value is unitless, directly converting to % scale + * 100.0, # OWM value is unitless, directly converting to % scale "icon": forecast["weather"][0]["icon"], "datetime": datetime.fromtimestamp(forecast["dt"], tz=self.tz_zone), } @@ -187,7 +178,7 @@ class OpenWeatherMap: :return: Forecast dictionary """ - # Make sure hourly forecasts are up to date + # Make sure hourly forecasts are up-to-date _ = self.get_weather_forecast() # Calculate the start and end times for the specified number of days from now @@ -207,7 +198,7 @@ class OpenWeatherMap: ] # In case the next available forecast is already for the next day, use that one for the less than 3 remaining hours of today - if forecasts == []: + if not forecasts: forecasts.append(self.hourly_forecasts[0]) # Get rain and temperatures for that day diff --git a/inkycal/modules/inkycal_agenda.py b/inkycal/modules/inkycal_agenda.py index 5b7f5d0..f695440 100755 --- a/inkycal/modules/inkycal_agenda.py +++ b/inkycal/modules/inkycal_agenda.py @@ -77,6 +77,8 @@ class Agenda(inkycal_module): # Additional config self.timezone = get_system_tz() + self.icon_font = ImageFont.truetype(fonts['MaterialIcons'], size=self.fontsize) + # give an OK message print(f'{__name__} loaded') @@ -203,10 +205,10 @@ class Agenda(inkycal_module): write(im_black, (x_time, line_pos[cursor][1]), (time_width, line_height), time, font=self.font, alignment='right') - if parser.all_day(_): + else: write(im_black, (x_time, line_pos[cursor][1]), - (time_width, line_height), "all day", - font=self.font, alignment='right') + (time_width, line_height), "\ue878", + font=self.icon_font, alignment='right') write(im_black, (x_event, line_pos[cursor][1]), (event_width, line_height), diff --git a/inkycal/modules/inkycal_weather.py b/inkycal/modules/inkycal_weather.py index 7aeb845..6bd61c1 100644 --- a/inkycal/modules/inkycal_weather.py +++ b/inkycal/modules/inkycal_weather.py @@ -2,12 +2,12 @@ Inkycal weather module Copyright by aceinnolab """ - -import arrow import decimal import logging import math +from typing import Tuple +import arrow from PIL import Image from PIL import ImageDraw from PIL import ImageFont @@ -51,7 +51,7 @@ class Weather(inkycal_module): "options": [True, False], }, - "round_windspeed": { + "round_wind_speed": { "label": "Round windspeed?", "options": [True, False], }, @@ -89,7 +89,7 @@ class Weather(inkycal_module): # Check if all required parameters are present for param in self.requires: - if not param in config: + if param not in config: raise Exception(f'config is missing {param}') # required parameters @@ -98,15 +98,15 @@ class Weather(inkycal_module): # optional parameters self.round_temperature = config['round_temperature'] - self.round_windspeed = config['round_windspeed'] + self.round_wind_speed = config['round_windspeed'] self.forecast_interval = config['forecast_interval'] self.hour_format = int(config['hour_format']) if config['units'] == "imperial": self.temp_unit = "fahrenheit" else: self.temp_unit = "celsius" - - if config['use_beaufort'] == True: + + if config['use_beaufort']: self.wind_unit = "beaufort" elif config['units'] == "imperial": self.wind_unit = "miles_hour" @@ -116,17 +116,17 @@ class Weather(inkycal_module): # additional configuration self.owm = OpenWeatherMap( - api_key=self.api_key, - city_id=self.location, - wind_unit=self.wind_unit, + api_key=self.api_key, + city_id=self.location, + wind_unit=self.wind_unit, temp_unit=self.temp_unit, - language=self.locale, + language=self.locale, tz_name=self.timezone - ) - + ) + self.weatherfont = ImageFont.truetype( fonts['weathericons-regular-webfont'], size=self.fontsize) - + if self.wind_unit == "beaufort": self.windDispUnit = "bft" elif self.wind_unit == "knots": @@ -145,8 +145,6 @@ class Weather(inkycal_module): # give an OK message print(f"{__name__} loaded") - - def generate_image(self): """Generate image for this module""" @@ -190,7 +188,7 @@ class Weather(inkycal_module): 7: '\uf0ae' }[int(index) & 7] - def is_negative(temp:str): + def is_negative(temp: str): """Check if temp is below freezing point of water (0°C/32°F) returns True if temp below freezing point, else False""" answer = False @@ -223,12 +221,19 @@ class Weather(inkycal_module): '50n': '\uf023' } - def draw_icon(image, xy, box_size, icon, rotation=None): - """Custom function to add icons of weather font on image - image = on which image should the text be added? - xy = xy-coordinates as tuple -> (x,y) - box_size = size of text-box -> (width,height) - icon = icon-unicode, looks this up in weathericons dictionary + def draw_icon(image: Image, xy: Tuple[int, int], box_size: Tuple[int, int], icon: str, rotation=None): + """Custom function to add icons of weather font on the image. + + Args: + - image: + the image on which image should the text be added + - xy: + coordinates as tuple -> (x,y) + - box_size: + size of text-box -> (width,height) + - icon: + icon-unicode, looks this up in weather-icons dictionary + """ icon_size_correction = { @@ -263,7 +268,6 @@ class Weather(inkycal_module): '\uf0a0': 0, '\uf0a3': 0, '\uf0a7': 0, - '\uf0aa': 0, '\uf0ae': 0 } @@ -277,8 +281,7 @@ class Weather(inkycal_module): font = ImageFont.truetype(font.path, size) text_width, text_height = font.getbbox(text)[2:] - while (text_width < int(box_width * 0.9) and - text_height < int(box_height * 0.9)): + while text_width < int(box_width * 0.9) and text_height < int(box_height * 0.9): size += 1 font = ImageFont.truetype(font.path, size) text_width, text_height = font.getbbox(text)[2:] @@ -289,8 +292,6 @@ class Weather(inkycal_module): x = int((box_width / 2) - (text_width / 2)) y = int((box_height / 2) - (text_height / 2)) - # Draw the text in the text-box - draw = ImageDraw.Draw(image) space = Image.new('RGBA', (box_width, box_height)) ImageDraw.Draw(space).text((x, y), text, fill='black', font=font) @@ -349,17 +350,17 @@ class Weather(inkycal_module): row3 = row2 + line_gap + row_height # Draw lines on each row and border - ############################################################################ - ## draw = ImageDraw.Draw(im_black) - ## draw.line((0, 0, im_width, 0), fill='red') - ## draw.line((0, im_height-1, im_width, im_height-1), fill='red') - ## draw.line((0, row1, im_width, row1), fill='black') - ## draw.line((0, row1+row_height, im_width, row1+row_height), fill='black') - ## draw.line((0, row2, im_width, row2), fill='black') - ## draw.line((0, row2+row_height, im_width, row2+row_height), fill='black') - ## draw.line((0, row3, im_width, row3), fill='black') - ## draw.line((0, row3+row_height, im_width, row3+row_height), fill='black') - ############################################################################ + ########################################################################### + # draw = ImageDraw.Draw(im_black) + # draw.line((0, 0, im_width, 0), fill='red') + # draw.line((0, im_height-1, im_width, im_height-1), fill='red') + # draw.line((0, row1, im_width, row1), fill='black') + # draw.line((0, row1+row_height, im_width, row1+row_height), fill='black') + # draw.line((0, row2, im_width, row2), fill='black') + # draw.line((0, row2+row_height, im_width, row2+row_height), fill='black') + # draw.line((0, row3, im_width, row3), fill='black') + # draw.line((0, row3+row_height, im_width, row3+row_height), fill='black') + ########################################################################### # Positions for current weather details weather_icon_pos = (col1, 0) @@ -378,24 +379,24 @@ class Weather(inkycal_module): sunset_time_pos = (col3 + icon_small, row3) # Positions for forecast 1 - stamp_fc1 = (col4, row1) - icon_fc1 = (col4, row1 + row_height) - temp_fc1 = (col4, row3) + stamp_fc1 = (col4, row1) # noqa + icon_fc1 = (col4, row1 + row_height) # noqa + temp_fc1 = (col4, row3) # noqa # Positions for forecast 2 - stamp_fc2 = (col5, row1) - icon_fc2 = (col5, row1 + row_height) - temp_fc2 = (col5, row3) + stamp_fc2 = (col5, row1) # noqa + icon_fc2 = (col5, row1 + row_height) # noqa + temp_fc2 = (col5, row3) # noqa # Positions for forecast 3 - stamp_fc3 = (col6, row1) - icon_fc3 = (col6, row1 + row_height) - temp_fc3 = (col6, row3) + stamp_fc3 = (col6, row1) # noqa + icon_fc3 = (col6, row1 + row_height) # noqa + temp_fc3 = (col6, row3) # noqa # Positions for forecast 4 - stamp_fc4 = (col7, row1) - icon_fc4 = (col7, row1 + row_height) - temp_fc4 = (col7, row3) + stamp_fc4 = (col7, row1) # noqa + icon_fc4 = (col7, row1 + row_height) # noqa + temp_fc4 = (col7, row3) # noqa # Create current-weather and weather-forecast objects logging.debug('looking up location by ID') @@ -404,7 +405,7 @@ class Weather(inkycal_module): # Set decimals dec_temp = 0 if self.round_temperature == True else 1 - dec_wind = 0 if self.round_windspeed == True else 1 + dec_wind = 0 if self.round_wind_speed == True else 1 logging.debug(f'temperature unit: {self.temp_unit}') logging.debug(f'decimals temperature: {dec_temp} | decimals wind: {dec_wind}') @@ -424,7 +425,8 @@ class Weather(inkycal_module): fc_data['fc' + str(index + 1)] = { 'temp': f"{forecast['temp']:.{dec_temp}f}{self.tempDispUnit}", 'icon': forecast["icon"], - 'stamp': forecast["datetime"].strftime("%I %p" if self.hour_format == 12 else "%H:%M")} + 'stamp': forecast["datetime"].strftime("%I %p" if self.hour_format == 12 else "%H:%M") + } elif self.forecast_interval == 'daily': @@ -433,7 +435,7 @@ class Weather(inkycal_module): daily_forecasts = [self.owm.get_forecast_for_day(days) for days in range(1, 5)] for index, forecast in enumerate(daily_forecasts): - fc_data['fc' + str(index +1)] = { + fc_data['fc' + str(index + 1)] = { 'temp': f'{forecast["temp_min"]:.{dec_temp}f}{self.tempDispUnit}/{forecast["temp_max"]:.{dec_temp}f}{self.tempDispUnit}', 'icon': forecast['icon'], 'stamp': forecast['datetime'].strftime("%A") @@ -513,6 +515,9 @@ class Weather(inkycal_module): # Add the forecast data to the correct places for pos in range(1, len(fc_data) + 1): stamp = fc_data[f'fc{pos}']['stamp'] + # check if we're using daily forecasts + if "day" in stamp: + stamp = arrow.get(fc_data[f'fc{pos}']['stamp'], "dddd").format("dddd", locale="de") icon = weather_icons[fc_data[f'fc{pos}']['icon']] temp = fc_data[f'fc{pos}']['temp'] diff --git a/tests/test_inkycal_agenda.py b/tests/test_inkycal_agenda.py index af002ec..cc4903a 100755 --- a/tests/test_inkycal_agenda.py +++ b/tests/test_inkycal_agenda.py @@ -37,7 +37,7 @@ tests = [ "size": [500, 800], "ical_urls": sample_url, "ical_files": None, - "date_format": "ddd D MMM", + "date_format": "DD.MMMM YYYY", "time_format": "HH:mm", "padding_x": 10, "padding_y": 10, diff --git a/tests/test_inkycal_weather.py b/tests/test_inkycal_weather.py index bcc50ce..2325616 100755 --- a/tests/test_inkycal_weather.py +++ b/tests/test_inkycal_weather.py @@ -34,7 +34,7 @@ tests = [ "padding_x": 10, "padding_y": 10, "fontsize": 12, - "language": "en" + "language": "de" } }, {