Adapting modules for new web-ui (do not use yet)

This commit is contained in:
Ace 2020-11-10 11:53:48 +01:00
parent 29788f0313
commit 035ce65f06
14 changed files with 155 additions and 415 deletions

View File

@ -7,8 +7,8 @@ from inkycal.display import Display
import inkycal.modules.inkycal_agenda
import inkycal.modules.inkycal_calendar
import inkycal.modules.inkycal_weather
import inkycal.modules.inkycal_rss
#import inkycal.modules.inkycal_image
import inkycal.modules.inkycal_feeds
# import inkycal.modules.inkycal_image
# import inkycal.modules.inkycal_server
# Main file

View File

@ -1,2 +1 @@
from .settings_parser import Settings
from .layout import Layout

View File

@ -124,5 +124,4 @@ class Layout:
if __name__ == '__main__':
print('running {0} in standalone/debug mode'.format(
os.path.basename(__file__).split('.py')[0]))
os.path.basename(__file__).split('.py')[0]))

View File

@ -1,207 +0,0 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
Json settings parser for inkycal project
Copyright by aceisace
"""
from inkycal.config.layout import Layout
import json
import os
import logging
from jsmin import jsmin
logger = logging.getLogger('settings')
logger.setLevel(level=logging.DEBUG)
class Settings:
"""Load and validate settings from the settings file"""
_supported_languages = ['en', 'de', 'ru', 'it', 'es', 'fr', 'el', 'sv', 'nl',
'pl', 'ua', 'nb', 'vi', 'zh_tw', 'zh-cn', 'ja', 'ko']
_supported_units = ['metric', 'imperial']
_supported_hours = [12, 24]
_supported_update_interval = [10, 15, 20, 30, 60]
_supported_display_orientation = ['normal', 'upside_down']
_supported_models = [
'epd_7_in_5_v2_colour', 'epd_7_in_5_v2',
'epd_7_in_5_colour', 'epd_7_in_5',
'epd_5_in_83_colour','epd_5_in_83',
'epd_4_in_2_colour', 'epd_4_in_2',
'9_in_7'
]
def __init__(self, settings_file_path):
"""Load settings from path (folder or settings.json file)
Set show_info_section to False to hide the info section"""
try:
if settings_file_path.endswith('settings.json'):
folder = settings_file_path.split('/settings.json')[0]
else:
folder = settings_file_path
os.chdir(folder)
if os.path.exists('settings.jsonc'):
with open("settings.jsonc") as jsonc_file:
# minify in order to remove comments
minified = jsmin(jsonc_file.read())
# remove known invalid json (comma followed by closing accolades)
minified = minified.replace(",}","}")
settings = json.loads(minified)
self._settings = settings
else:
with open("settings.json") as file:
settings = json.load(file)
self._settings = settings
except FileNotFoundError:
print('No settings file found in specified location')
# Validate the settings
self._validate()
# Get the height-percentages of the modules
if self.info_section == True:
self.Layout = Layout(model=self.model, use_info_section = True)
else:
self.Layout = Layout(model=self.model, use_info_section = False)
all_heights = [_['height'] for _ in self._settings['panels']]
num_modules = len(self.active_modules())
# check if height have (or have not) been provided for all modules
if len(all_heights) == num_modules:
# If no height is provided, use default values
if list(set(all_heights)) == [None]:
self.Layout.create_sections()
# if all heights are specified, use given values
else:
logger.info('Setting section height according to settings file')
to_decimal = lambda percentage: percentage/100
top_height = [to_decimal(_['height']) for _ in
self._settings['panels'] if _['location'] == 'top']
middle_height = [to_decimal(_['height']) for _ in
self._settings['panels'] if _['location'] == 'middle']
bottom_height = [to_decimal(_['height']) for _ in
self._settings['panels'] if _['location'] == 'bottom']
self.Layout.create_sections(
top_section = top_height[0] if top_height else 0,
middle_section = middle_height[0] if middle_height else 0,
bottom_section = bottom_height[0] if bottom_height else 0)
# If only some heights were defined, raise an error
else:
print("Section height is not defined for all sections.")
print("Please leave height empty for all modules")
print("OR specify the height for all sections")
raise Exception('Module height is not specified in all modules!')
def _validate(self):
"""Validate the basic config"""
settings = self._settings
required = ['language', 'units', 'hours', 'model', 'calibration_hours',
'display_orientation', 'info_section']
# Check if all required settings exist
for param in required:
if not param in settings:
raise Exception (
'required parameter: `{0}` not found in settings file!'.format(param))
# Attempt to parse the parameters
self.language = settings['language']
self.units = settings['units']
self.hours = settings['hours']
self.model = settings['model']
self.update_interval = settings['update_interval']
self.calibration_hours = settings['calibration_hours']
self.display_orientation = settings['display_orientation']
self.info_section = settings['info_section']
# Validate the parameters
if (not isinstance(self.language, str) or self.language not in
self._supported_languages):
print('Language not supported, switching to fallback, en')
self.language = 'en'
if (not isinstance(self.units, str) or self.units not in
self._supported_units):
print('units not supported, switching to fallback, metric')
self.units = 'metric'
if (not isinstance(self.hours, int) or self.hours not in
self._supported_hours):
print('hour-format not supported, switching to fallback, 24')
self.hours = 24
if (not isinstance(self.model, str) or self.model not in
self._supported_models):
print('model not supported, switching to fallback, epd_7_in_5')
self.model = 'epd_7_in_5'
if (not isinstance(self.update_interval, int) or self.update_interval
not in self._supported_update_interval):
print('update-interval not supported, switching to fallback, 60')
self.update_interval = 60
if (not isinstance(self.calibration_hours, list)):
print('calibration_hours not supported, switching to fallback, [0,12,18]')
self.calibration_hours = [0,12,18]
if (not isinstance(self.display_orientation, str) or self.display_orientation not in
self._supported_display_orientation):
print('display orientation not supported, switching to fallback, normal')
self.display_orientation = 'normal'
if (not isinstance(self.info_section, bool)):
print('info_section must be True/False. Switching to fallback: False')
self.info_section = False
print('Settings file OK!')
def active_modules(self):
modules = [section['type'] for section in self._settings['panels']]
return modules
def common_config(self):
common_config = {
'language' : self.language, 'units' : self.units, 'hours' : self.hours
}
return common_config
def get_config(self, module_name):
"""Ge the config of this module (size, config)"""
if module_name not in self.active_modules():
print('No config is available for this module')
else:
for section in self._settings['panels']:
if section['type'] == module_name:
config = section['config']
size = self.Layout.get_size(self.get_position(module_name))
return {'size':size, 'config': {**config, **self.common_config()}}
def get_position(self, module_name):
"""Get the position of this module's image on the display"""
if module_name not in self.active_modules():
print('No position is available for this module')
else:
for section in self._settings['panels']:
if section['type'] == module_name:
position = section['location']
return position
if __name__ == '__main__':
print('running {0} in standalone/debug mode'.format(
os.path.basename(__file__).split('.py')[0]))

View File

@ -11,6 +11,8 @@ from urllib.request import urlopen
import os
import time
logger = logging.getLogger('inkycal_custom')
logger.setLevel(level=logging.INFO)
# Get the path to the Inkycal folder
top_level = os.path.dirname(
@ -107,11 +109,11 @@ def write(image, xy, box_size, text, font=None, **kwargs):
# Truncate text if text is too long so it can fit inside the box
if (text_width, text_height) > (box_width, box_height):
logging.debug(('truncating {}'.format(text)))
logger.debug(('truncating {}'.format(text)))
while (text_width, text_height) > (box_width, box_height):
text=text[0:-1]
text_width, text_height = font.getsize(text)[0], font.getsize('hg')[1]
logging.debug((text))
logger.debug((text))
# Align text to desired position
if alignment == "center" or None:

View File

@ -1,99 +0,0 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
Inky-Calendar epaper functions
Copyright by aceisace
"""
from importlib import import_module
from PIL import Image
class Display:
"""Display class for inkycal
Handles rendering on display"""
def __init__(self, epaper_model):
"""Load the drivers for this epaper model"""
if 'colour' in epaper_model:
self.supports_colour = True
else:
self.supports_colour = False
try:
driver_path = 'inkycal.display.drivers.{}'.format(epaper_model)
driver = import_module(driver_path)
self._epaper = driver.EPD()
self.model_name = epaper_model
except ImportError:
raise Exception('This module is not supported. Check your spellings?')
except FileNotFoundError:
raise Exception('SPI could not be found. Please check if SPI is enabled')
def render(self, im_black, im_colour = None):
"""Render an image on the epaper
im_colour is required for three-colour epapers"""
epaper = self._epaper
if self.supports_colour == False:
print('Initialising..', end = '')
epaper.init()
# For the 9.7" ePaper, the image needs to be flipped by 90 deg first
# The other displays flip the image automatically
if self.model_name == "9_in_7":
im_black.rotate(90, expand=True)
print('Updating display......', end = '')
epaper.display(epaper.getbuffer(im_black))
print('Done')
elif self.supports_colour == True:
if not im_colour:
raise Exception('im_colour is required for coloured epaper displays')
print('Initialising..', end = '')
epaper.init()
print('Updating display......', end = '')
epaper.display(epaper.getbuffer(im_black), epaper.getbuffer(im_colour))
print('Done')
print('Sending E-Paper to deep sleep...', end = '')
epaper.sleep()
print('Done')
def calibrate(self, cycles=3):
"""Flush display with single colour to prevent burn-ins (ghosting)
cycles -> int. How many times should each colour be flushed?
recommended cycles = 3"""
epaper = self._epaper
epaper.init()
white = Image.new('1', (epaper.width, epaper.height), 'white')
black = Image.new('1', (epaper.width, epaper.height), 'black')
print('----------Started calibration of ePaper display----------')
if self.supports_colour == True:
for _ in range(cycles):
print('Calibrating...', end= ' ')
print('black...', end= ' ')
epaper.display(epaper.getbuffer(black), epaper.getbuffer(white))
print('colour...', end = ' ')
epaper.display(epaper.getbuffer(white), epaper.getbuffer(black))
print('white...')
epaper.display(epaper.getbuffer(white), epaper.getbuffer(white))
print('Cycle {0} of {1} complete'.format(_+1, cycles))
if self.supports_colour == False:
for _ in range(cycles):
print('Calibrating...', end= ' ')
print('black...', end = ' ')
epaper.display(epaper.getbuffer(black))
print('white...')
epaper.display(epaper.getbuffer(white)),
print('Cycle {0} of {1} complete'.format(_+1, cycles))
print('-----------Calibration complete----------')
epaper.sleep()

View File

@ -1,5 +1,5 @@
from .inkycal_agenda import Agenda
from .inkycal_calendar import Calendar
from .inkycal_weather import Weather
from .inkycal_rss import RSS
from .inkycal_feeds import RSS
#from .inkycal_image import Image

View File

@ -14,7 +14,7 @@ import arrow
filename = os.path.basename(__file__).split('.py')[0]
logger = logging.getLogger(filename)
logger.setLevel(level=logging.ERROR)
logger.setLevel(level=logging.INFO)
class Agenda(inkycal_module):
"""Agenda class
@ -33,7 +33,6 @@ class Agenda(inkycal_module):
optional = {
"ical_files" : {
"label":"iCalendar filepaths, separated with a comma",
"default":[]
},
"date_format":{
@ -45,27 +44,37 @@ class Agenda(inkycal_module):
"time_format":{
"label":"Use an arrow-supported token for custom time formatting "+
"see https://arrow.readthedocs.io/en/stable/#supported-tokens, e.g. HH:mm",
"default":"HH:mm",
},
}
def __init__(self, section_size, section_config):
def __init__(self, config):
"""Initialize inkycal_agenda module"""
super().__init__(section_size, section_config)
super().__init__(config)
for param in self.equires:
if not param in section_config:
config = config['config']
# Check if all required parameters are present
for param in self.requires:
if not param in config:
raise Exception('config is missing {}'.format(param))
# module specific parameters
self.date_format = self.config['date_format']
self.time_format = self.config['time_format']
self.language = self.config['language']
self.ical_urls = self.config['ical_urls']
self.ical_files = self.config['ical_files']
self.date_format = config['date_format']
self.time_format = config['time_format']
self.language = config['language']
self.ical_urls = config['ical_urls'].split(',')
# Check if ical_files is an empty string
if config['ical_files'] != "":
self.ical_files = config['ical_files'].split(',')
else:
self.ical_files = []
# Additional config
self.timezone = get_system_tz()
# give an OK message
@ -83,9 +92,6 @@ class Agenda(inkycal_module):
if not isinstance(self.language, str):
print('language has to be a string: "en" ')
if not isinstance(self.timezone, str):
print('The timezone has bo be a string.')
if not isinstance(self.ical_urls, list):
print('ical_urls has to be a list ["url1", "url2"] ')
@ -96,8 +102,8 @@ class Agenda(inkycal_module):
"""Generate image for this module"""
# Define new image size with respect to padding
im_width = int(self.width - (self.width * 2 * self.margin_x))
im_height = int(self.height - (self.height * 2 * self.margin_y))
im_width = int(self.width - (2 * self.padding_left))
im_height = int(self.height - (2 * self.padding_top))
im_size = im_width, im_height
logger.info('Image size: {0}'.format(im_size))
@ -130,6 +136,7 @@ class Agenda(inkycal_module):
if self.ical_urls:
parser.load_url(self.ical_urls)
if self.ical_files:
parser.load_from_file(self.ical_files)
@ -139,7 +146,7 @@ class Agenda(inkycal_module):
# Sort events by beginning time
parser.sort()
# parser.show_events()
#parser.show_events()
# Set the width for date, time and event titles
date_width = int(max([self.font.getsize(
@ -147,8 +154,13 @@ class Agenda(inkycal_module):
for dates in agenda_events]) * 1.2)
logger.debug(('date_width:', date_width))
# Calculate positions for each line
line_pos = [(0, int(line * line_height)) for line in range(max_lines)]
logger.debug(('line_pos:', line_pos))
# Check if any events were filtered
if upcoming_events:
logger.info('Managed to parse events from urls')
# Find out how much space the event times take
time_width = int(max([self.font.getsize(
@ -168,10 +180,6 @@ class Agenda(inkycal_module):
x_event = date_width + time_width
logger.debug(('x-event:', x_event))
# Calculate positions for each line
line_pos = [(0, int(line * line_height)) for line in range(max_lines)]
logger.debug(('line_pos:', line_pos))
# Merge list of dates and list of events
agenda_events += upcoming_events
@ -216,6 +224,8 @@ class Agenda(inkycal_module):
# If no events were found, write only dates and lines
else:
logger.info('no events found')
cursor = 0
for _ in agenda_events:
title = _['title']
@ -228,10 +238,9 @@ class Agenda(inkycal_module):
cursor += 1
logger.info('no events found')
# return the images ready for the display
return im_black, im_colour
if __name__ == '__main__':
print('running {0} in standalone mode'.format(filename))
print('running {0} in standalone mode'.format(filename))

View File

@ -12,7 +12,7 @@ import arrow
filename = os.path.basename(__file__).split('.py')[0]
logger = logging.getLogger(filename)
logger.setLevel(level=logging.ERROR)
logger.setLevel(level=logging.DEBUG)
class Calendar(inkycal_module):
"""Calendar class
@ -37,12 +37,10 @@ class Calendar(inkycal_module):
"ical_urls" : {
"label":"iCalendar URL/s, separate multiple ones with a comma",
"default":[]
},
"ical_files" : {
"label":"iCalendar filepaths, separated with a comma",
"default":[]
},
"date_format":{
@ -59,24 +57,33 @@ class Calendar(inkycal_module):
}
def __init__(self, section_size, section_config):
def __init__(self, config):
"""Initialize inkycal_calendar module"""
super().__init__(section_size, section_config)
super().__init__(config)
config = config['config']
# optional parameters
self.weekstart = config['week_starts_on']
self.show_events = bool(config['show_events'])
self.date_format = config["date_format"]
self.time_format = config['time_format']
self.language = config['language']
# module specific parameters
if config['ical_urls'] != "":
self.ical_urls = config['ical_urls'].split(',')
else:
self.ical_urls = []
if config['ical_files'] != "":
self.ical_files = config['ical_files'].split(',')
else:
self.ical_files = []
# additional configuration
self.timezone = get_system_tz()
self.num_font = ImageFont.truetype(
fonts['NotoSans-SemiCondensed'], size = self.fontsize)
self.weekstart = self.config['week_starts_on']
self.show_events = self.config['show_events']
self.date_format = self.config["date_format"]
self.time_format = self.config['time_format']
self.language = self.config['language']
self.timezone = get_system_tz()
self.ical_urls = self.config['ical_urls']
self.ical_files = self.config['ical_files']
# give an OK message
print('{0} loaded'.format(filename))
@ -85,8 +92,8 @@ class Calendar(inkycal_module):
"""Generate image for this module"""
# Define new image size with respect to padding
im_width = int(self.width - (2 * self.padding_x))
im_height = int(self.height - (2 * self.padding_y))
im_width = int(self.width - (2 * self.padding_left))
im_height = int(self.height - (2 * self.padding_top))
im_size = im_width, im_height
logger.info('Image size: {0}'.format(im_size))
@ -313,4 +320,4 @@ class Calendar(inkycal_module):
return im_black, im_colour
if __name__ == '__main__':
print('running {0} in standalone mode'.format(filename))
print('running {0} in standalone mode'.format(filename))

View File

@ -18,7 +18,7 @@ except ImportError:
filename = os.path.basename(__file__).split('.py')[0]
logger = logging.getLogger(filename)
logger.setLevel(level=logging.ERROR)
logger.setLevel(level=logging.INFO)
class RSS(inkycal_module):
"""RSS class
@ -28,7 +28,7 @@ class RSS(inkycal_module):
name = "Inkycal RSS / Atom"
requires = {
"rss_urls" : {
"feed_urls" : {
"label":"Please enter ATOM or RSS feed URL/s, separated by a comma",
},
@ -44,23 +44,24 @@ class RSS(inkycal_module):
}
def __init__(self, section_size, section_config):
"""Initialize inkycal_rss module"""
def __init__(self, config):
"""Initialize inkycal_feeds module"""
super().__init__(section_size, section_config)
super().__init__(config)
# Check if required parameters are available in config
config = config['config']
# Check if all required parameters are present
for param in self.requires:
if not param in section_config:
if not param in config:
raise Exception('config is missing {}'.format(param))
# parse required config
self.rss_urls = self.config["rss_urls"].split(",")
# required parameters
self.feed_urls = self.config["feed_urls"].split(",")
# parse optional config
self.shuffle_feeds = self.config["shuffle_feeds"]
# optional parameters
self.shuffle_feeds = bool(self.config["shuffle_feeds"])
# give an OK message
print('{0} loaded'.format(filename))
@ -75,8 +76,8 @@ class RSS(inkycal_module):
"""Generate image for this module"""
# Define new image size with respect to padding
im_width = int(self.width - ( 2 * self.padding_x))
im_height = int(self.height - (2 * self.padding_y))
im_width = int(self.width - (2 * self.padding_left))
im_height = int(self.height - (2 * self.padding_top))
im_size = im_width, im_height
logger.info('image size: {} x {} px'.format(im_width, im_height))
@ -90,7 +91,7 @@ class RSS(inkycal_module):
else:
raise Exception('Network could not be reached :/')
# Set some parameters for formatting rss feeds
# Set some parameters for formatting feeds
line_spacing = 1
line_height = self.font.getsize('hg')[1] + line_spacing
line_width = im_width
@ -103,9 +104,9 @@ class RSS(inkycal_module):
line_positions = [
(0, spacing_top + _ * line_height ) for _ in range(max_lines)]
# Create list containing all rss-feeds from all rss-feed urls
# Create list containing all feeds from all urls
parsed_feeds = []
for feeds in self.rss_urls:
for feeds in self.feed_urls:
text = feedparser.parse(feeds)
for posts in text.entries:
parsed_feeds.append('{0}: {1}'.format(posts.title, posts.summary))
@ -131,23 +132,21 @@ class RSS(inkycal_module):
filtered_feeds = flatten(filtered_feeds)
self._filtered_feeds = filtered_feeds
logger.debug(f'filtered feeds -> {filtered_feeds}')
# Check if feeds could be parsed and can be displayed
if len(filtered_feeds) == 0 and len(parsed_feeds) > 0:
print('Feeds could be parsed, but the text is too long to be displayed:/')
elif len(filtered_feeds) == 0 and len(parsed_feeds) == 0:
print('No feeds could be parsed :/')
else:
# Write rss-feeds on image
# Write feeds on image
for _ in range(len(filtered_feeds)):
write(im_black, line_positions[_], (line_width, line_height),
filtered_feeds[_], font = self.font, alignment= 'left')
# Cleanup
del filtered_feeds, parsed_feeds, wrapped, counter, text
# Save image of black and colour channel in image-folder
return im_black, im_colour
if __name__ == '__main__':
print('running {0} in standalone/debug mode'.format(filename))
print(RSS.get_config())
print('running {0} in standalone/debug mode'.format(filename))

View File

@ -169,8 +169,4 @@ class Todoist(inkycal_module):
return im_black, im_colour
if __name__ == '__main__':
print('running {0} in standalone/debug mode'.format(filename))
config = {'api_key':'4e166367dcafdd60e6a9f4cbed598d578bf2c359'}
size = (480, 100)
a = Todoist(size, config)
b,c = a.generate_image()
print('running {0} in standalone/debug mode'.format(filename))

View File

@ -81,42 +81,74 @@ class Weather(inkycal_module):
}
def __init__(self, section_size, section_config):
def __init__(self, config):
"""Initialize inkycal_weather module"""
super().__init__(section_size, section_config)
super().__init__(config)
# Module specific parameters
config = config['config']
# Check if all required parameters are present
for param in self.requires:
if not param in section_config:
if not param in config:
raise Exception('config is missing {}'.format(param))
# required parameters
self.location = self.config['location']
self.api_key = self.config['api_key']
self.location = config['location']
self.api_key = config['api_key']
# optional parameters
self.round_temperature = self.config['round_temperature']
self.round_windspeed = self.config['round_windspeed']
self.forecast_interval = self.config['forecast_interval']
self.units = self.config['units']
self.hour_format = self.config['hour_format']
self.use_beaufort = self.config['use_beaufort']
self.round_temperature = bool(config['round_temperature'])
self.round_windspeed = bool(config['round_windspeed'])
self.forecast_interval = config['forecast_interval']
self.units = config['units']
self.hour_format = int(config['hour_format'])
self.use_beaufort = bool(config['use_beaufort'])
# additional configuration
self.owm = pyowm.OWM(self.api_key)
self.timezone = get_system_tz()
self.locale = sys_locale()[0]
self.weatherfont = ImageFont.truetype(fonts['weathericons-regular-webfont'],
size = self.fontsize)
self.weatherfont = ImageFont.truetype(
fonts['weathericons-regular-webfont'], size = self.fontsize)
#self.owm = pyowm.OWM(self.config['api_key'])
# give an OK message
print('{0} loaded'.format(filename))
def _validate(self):
if not isinstance(self.location, str):
print(f'location should be -> Manchester, USA, not {self.location}')
if not isinstance(self.api_key, str):
print(f'api_key should be a string, not {self.api_key}')
if not isinstance(self.round_temperature, bool):
print(f'round_temperature should be a boolean, not {self.round_temperature}')
if not isinstance(self.round_windspeed, bool):
print(f'round_windspeed should be a boolean, not {self.round_windspeed}')
if not isinstance(self.forecast_interval, int):
print(f'forecast_interval should be a boolean, not {self.forecast_interval}')
if not isinstance(self.units, str):
print(f'units should be a boolean, not {self.units}')
if not isinstance(self.hour_format, int):
print(f'hour_format should be a int, not {self.hour_format}')
if not isinstance(self.use_beaufort, bool):
print(f'use_beaufort should be a int, not {self.use_beaufort}')
def generate_image(self):
"""Generate image for this module"""
# Define new image size with respect to padding
im_width = int(self.width - (2 * self.padding_x))
im_height = int(self.height - (2 * self.padding_y))
im_width = int(self.width - (2 * self.padding_left))
im_height = int(self.height - (2 * self.padding_top))
im_size = im_width, im_height
logger.info('image size: {} x {} px'.format(im_width, im_height))
@ -338,6 +370,10 @@ class Weather(inkycal_module):
elif self.forecast_interval == 'daily':
###
logger.debug("daily")
def calculate_forecast(days_from_today):
"""Get temperature range and most frequent icon code for forecast
days_from_today should be int from 1-4: e.g. 2 -> 2 days from today
@ -352,7 +388,6 @@ class Weather(inkycal_module):
# Get forecasts for each time-object
forecasts = [forecast.get_weather_at(_.datetime) for _ in time_range]
# Get all temperatures for this day
daily_temp = [round(_.get_temperature(unit=temp_unit)['temp'],
ndigits=dec_temp) for _ in forecasts]
@ -418,7 +453,6 @@ class Weather(inkycal_module):
moonphase = get_moon_phase()
# Fill weather details in col 1 (current weather icon)
# write(im_black, (col_width, row_height), now_str, text_now_pos, font = font)
draw_icon(im_colour, weather_icon_pos, (icon_large, icon_large),
weathericons[weather_icon])
@ -481,4 +515,4 @@ class Weather(inkycal_module):
return im_black, im_colour
if __name__ == '__main__':
print('running {0} in standalone mode'.format(filename))
print('running {0} in standalone mode'.format(filename))

View File

@ -1,6 +1,10 @@
import abc
from inkycal.custom import *
# Set the root logger to level DEBUG to allow any inkycal module to use the
# logger for any level
logging.basicConfig(level = logging.DEBUG)
class inkycal_module(metaclass=abc.ABCMeta):
"""Generic base class for inykcal modules"""
@ -10,16 +14,18 @@ class inkycal_module(metaclass=abc.ABCMeta):
callable(subclass.generate_image) or
NotImplemented)
def __init__(self, section_config):
def __init__(self, config):
"""Initialize module with given config"""
# Initializes base module
# sets properties shared amongst all sections
self.config = section_config
self.width, self.height = section_config['size']
self.config = conf = config['config']
self.width, self.height = conf['size']
self.padding_left = self.padding_right = self.config["padding_x"]
self.padding_top = self.padding_bottom = self.config["padding_y"]
self.padding_left = self.padding_right = conf["padding_x"]
self.padding_top = self.padding_bottom = conf['padding_y']
self.fontsize = self.config["fontsize"]
self.fontsize = conf["fontsize"]
self.font = ImageFont.truetype(
fonts['NotoSans-SemiCondensed'], size = self.fontsize)

View File

@ -1,9 +1,7 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
Module template for Inky-Calendar Project
Create your own module with this template
Developer module template for Inkycal Project
Copyright by aceisace
"""
@ -79,9 +77,6 @@ class Simple(inkycal_module):
# Initialise this module via the inkycal_module template (required)
super().__init__(section_size, section_config)
# module name (required)
self.name = self.__class__.__name__
# module specific parameters (optional)
self.do_something = True