Allow usage without display and SPI when setting render->False
Generated images will be available in the images folder
This commit is contained in:
parent
cd02d2fbab
commit
f10fe8a988
@ -10,6 +10,7 @@ from PIL import Image
|
|||||||
from inkycal.custom import top_level
|
from inkycal.custom import top_level
|
||||||
import glob
|
import glob
|
||||||
|
|
||||||
|
|
||||||
class Display:
|
class Display:
|
||||||
"""Display class for inkycal
|
"""Display class for inkycal
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ class Display:
|
|||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
raise Exception('SPI could not be found. Please check if SPI is enabled')
|
raise Exception('SPI could not be found. Please check if SPI is enabled')
|
||||||
|
|
||||||
def render(self, im_black, im_colour = None):
|
def render(self, im_black, im_colour=None):
|
||||||
"""Renders an image on the selected E-Paper display.
|
"""Renders an image on the selected E-Paper display.
|
||||||
|
|
||||||
Initlializes the E-Paper display, sends image data and executes command
|
Initlializes the E-Paper display, sends image data and executes command
|
||||||
@ -81,23 +82,23 @@ class Display:
|
|||||||
|
|
||||||
epaper = self._epaper
|
epaper = self._epaper
|
||||||
|
|
||||||
if self.supports_colour == False:
|
if not self.supports_colour:
|
||||||
print('Initialising..', end = '')
|
print('Initialising..', end='')
|
||||||
epaper.init()
|
epaper.init()
|
||||||
print('Updating display......', end = '')
|
print('Updating display......', end='')
|
||||||
epaper.display(epaper.getbuffer(im_black))
|
epaper.display(epaper.getbuffer(im_black))
|
||||||
print('Done')
|
print('Done')
|
||||||
|
|
||||||
elif self.supports_colour == True:
|
elif self.supports_colour:
|
||||||
if not im_colour:
|
if not im_colour:
|
||||||
raise Exception('im_colour is required for coloured epaper displays')
|
raise Exception('im_colour is required for coloured epaper displays')
|
||||||
print('Initialising..', end = '')
|
print('Initialising..', end='')
|
||||||
epaper.init()
|
epaper.init()
|
||||||
print('Updating display......', end = '')
|
print('Updating display......', end='')
|
||||||
epaper.display(epaper.getbuffer(im_black), epaper.getbuffer(im_colour))
|
epaper.display(epaper.getbuffer(im_black), epaper.getbuffer(im_colour))
|
||||||
print('Done')
|
print('Done')
|
||||||
|
|
||||||
print('Sending E-Paper to deep sleep...', end = '')
|
print('Sending E-Paper to deep sleep...', end='')
|
||||||
epaper.sleep()
|
epaper.sleep()
|
||||||
print('Done')
|
print('Done')
|
||||||
|
|
||||||
@ -116,7 +117,7 @@ class Display:
|
|||||||
critical, but not calibrating regularly results in grey-ish text.
|
critical, but not calibrating regularly results in grey-ish text.
|
||||||
|
|
||||||
Please note that calibration takes a while to complete. 3 cycles may
|
Please note that calibration takes a while to complete. 3 cycles may
|
||||||
take 10 mins on black-white E-Papers while it takes 20 minutes on coloured
|
take 10 minutes on black-white E-Papers while it takes 20 minutes on coloured
|
||||||
E-Paper displays.
|
E-Paper displays.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -129,35 +130,34 @@ class Display:
|
|||||||
black = Image.new('1', display_size, 'black')
|
black = Image.new('1', display_size, 'black')
|
||||||
|
|
||||||
print('----------Started calibration of ePaper display----------')
|
print('----------Started calibration of ePaper display----------')
|
||||||
if self.supports_colour == True:
|
if self.supports_colour:
|
||||||
for _ in range(cycles):
|
for _ in range(cycles):
|
||||||
print('Calibrating...', end= ' ')
|
print('Calibrating...', end=' ')
|
||||||
print('black...', end= ' ')
|
print('black...', end=' ')
|
||||||
epaper.display(epaper.getbuffer(black), epaper.getbuffer(white))
|
epaper.display(epaper.getbuffer(black), epaper.getbuffer(white))
|
||||||
print('colour...', end = ' ')
|
print('colour...', end=' ')
|
||||||
epaper.display(epaper.getbuffer(white), epaper.getbuffer(black))
|
epaper.display(epaper.getbuffer(white), epaper.getbuffer(black))
|
||||||
print('white...')
|
print('white...')
|
||||||
epaper.display(epaper.getbuffer(white), epaper.getbuffer(white))
|
epaper.display(epaper.getbuffer(white), epaper.getbuffer(white))
|
||||||
print(f'Cycle {_+1} of {cycles} complete')
|
print(f'Cycle {_ + 1} of {cycles} complete')
|
||||||
|
|
||||||
if self.supports_colour == False:
|
if not self.supports_colour:
|
||||||
for _ in range(cycles):
|
for _ in range(cycles):
|
||||||
print('Calibrating...', end= ' ')
|
print('Calibrating...', end=' ')
|
||||||
print('black...', end = ' ')
|
print('black...', end=' ')
|
||||||
epaper.display(epaper.getbuffer(black))
|
epaper.display(epaper.getbuffer(black))
|
||||||
print('white...')
|
print('white...')
|
||||||
epaper.display(epaper.getbuffer(white)),
|
epaper.display(epaper.getbuffer(white)),
|
||||||
print(f'Cycle {_+1} of {cycles} complete')
|
print(f'Cycle {_ + 1} of {cycles} complete')
|
||||||
|
|
||||||
print('-----------Calibration complete----------')
|
print('-----------Calibration complete----------')
|
||||||
epaper.sleep()
|
epaper.sleep()
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_display_size(cls, model_name):
|
def get_display_size(cls, model_name):
|
||||||
"""Returns the size of the display as a tuple -> (width, height)
|
"""Returns the size of the display as a tuple -> (width, height)
|
||||||
|
|
||||||
Looks inside drivers folder for the given model name, then returns it's
|
Looks inside "drivers" folder for the given model name, then returns it's
|
||||||
size.
|
size.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -174,7 +174,7 @@ class Display:
|
|||||||
print('model_name should be a string')
|
print('model_name should be a string')
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
driver_files = top_level+'/inkycal/display/drivers/*.py'
|
driver_files = top_level + '/inkycal/display/drivers/*.py'
|
||||||
drivers = glob.glob(driver_files)
|
drivers = glob.glob(driver_files)
|
||||||
drivers = [i.split('/')[-1].split('.')[0] for i in drivers]
|
drivers = [i.split('/')[-1].split('.')[0] for i in drivers]
|
||||||
drivers.remove('__init__')
|
drivers.remove('__init__')
|
||||||
@ -183,7 +183,7 @@ class Display:
|
|||||||
print('This model name was not found. Please double check your spellings')
|
print('This model name was not found. Please double check your spellings')
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
with open(top_level+'/inkycal/display/drivers/'+model_name+'.py') as file:
|
with open(top_level + '/inkycal/display/drivers/' + model_name + '.py') as file:
|
||||||
for line in file:
|
for line in file:
|
||||||
if 'EPD_WIDTH=' in line.replace(" ", ""):
|
if 'EPD_WIDTH=' in line.replace(" ", ""):
|
||||||
width = int(line.rstrip().replace(" ", "").split('=')[-1])
|
width = int(line.rstrip().replace(" ", "").split('=')[-1])
|
||||||
@ -207,13 +207,13 @@ class Display:
|
|||||||
|
|
||||||
>>> Display.get_display_names()
|
>>> Display.get_display_names()
|
||||||
"""
|
"""
|
||||||
driver_files = top_level+'/inkycal/display/drivers/*.py'
|
driver_files = top_level + '/inkycal/display/drivers/*.py'
|
||||||
drivers = glob.glob(driver_files)
|
drivers = glob.glob(driver_files)
|
||||||
drivers = [i.split('/')[-1].split('.')[0] for i in drivers]
|
drivers = [i.split('/')[-1].split('.')[0] for i in drivers]
|
||||||
drivers.remove('__init__')
|
drivers.remove('__init__')
|
||||||
drivers.remove('epdconfig')
|
drivers.remove('epdconfig')
|
||||||
print(*drivers, sep='\n')
|
print(*drivers, sep='\n')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print("Running Display class in standalone mode")
|
print("Running Display class in standalone mode")
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/python3
|
#!python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -44,7 +44,7 @@ stream_handler.setLevel(logging.ERROR)
|
|||||||
on_rtd = os.environ.get('READTHEDOCS') == 'True'
|
on_rtd = os.environ.get('READTHEDOCS') == 'True'
|
||||||
if on_rtd:
|
if on_rtd:
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
level = logging.INFO,
|
level=logging.INFO,
|
||||||
format='%(asctime)s | %(name)s | %(levelname)s: %(message)s',
|
format='%(asctime)s | %(name)s | %(levelname)s: %(message)s',
|
||||||
datefmt='%d-%m-%Y %H:%M:%S',
|
datefmt='%d-%m-%Y %H:%M:%S',
|
||||||
handlers=[stream_handler])
|
handlers=[stream_handler])
|
||||||
@ -52,7 +52,7 @@ if on_rtd:
|
|||||||
else:
|
else:
|
||||||
# Save all logs to a file, which contains more detailed output
|
# Save all logs to a file, which contains more detailed output
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
level = logging.INFO,
|
level=logging.INFO,
|
||||||
format='%(asctime)s | %(name)s | %(levelname)s: %(message)s',
|
format='%(asctime)s | %(name)s | %(levelname)s: %(message)s',
|
||||||
datefmt='%d-%m-%Y %H:%M:%S',
|
datefmt='%d-%m-%Y %H:%M:%S',
|
||||||
handlers=[
|
handlers=[
|
||||||
@ -73,6 +73,7 @@ logging.getLogger("PIL").setLevel(logging.WARNING)
|
|||||||
filename = os.path.basename(__file__).split('.py')[0]
|
filename = os.path.basename(__file__).split('.py')[0]
|
||||||
logger = logging.getLogger(filename)
|
logger = logging.getLogger(filename)
|
||||||
|
|
||||||
|
|
||||||
# TODO: autostart -> supervisor?
|
# TODO: autostart -> supervisor?
|
||||||
|
|
||||||
class Inkycal:
|
class Inkycal:
|
||||||
@ -122,15 +123,13 @@ class Inkycal:
|
|||||||
print('No settings file found in /boot')
|
print('No settings file found in /boot')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
# Option to use epaper image optimisation, reduces colours
|
# Option to use epaper image optimisation, reduces colours
|
||||||
self.optimize = True
|
self.optimize = True
|
||||||
|
|
||||||
# Load drivers if image should be rendered
|
# Load drivers if image should be rendered
|
||||||
if self.render == True:
|
if self.render == True:
|
||||||
|
|
||||||
# Init Display class with model in settings file
|
# Init Display class with model in settings file
|
||||||
from inkycal.display import Display
|
# from inkycal.display import Display
|
||||||
self.Display = Display(settings["model"])
|
self.Display = Display(settings["model"])
|
||||||
|
|
||||||
# check if colours can be rendered
|
# check if colours can be rendered
|
||||||
@ -154,9 +153,9 @@ class Inkycal:
|
|||||||
# print(setup)
|
# print(setup)
|
||||||
exec(setup)
|
exec(setup)
|
||||||
logger.info(('name : {name} size : {width}x{height} px'.format(
|
logger.info(('name : {name} size : {width}x{height} px'.format(
|
||||||
name = module_name,
|
name=module_name,
|
||||||
width = module['config']['size'][0],
|
width=module['config']['size'][0],
|
||||||
height = module['config']['size'][1])))
|
height=module['config']['size'][1])))
|
||||||
|
|
||||||
self._module_number += 1
|
self._module_number += 1
|
||||||
|
|
||||||
@ -169,7 +168,7 @@ class Inkycal:
|
|||||||
print(str(e))
|
print(str(e))
|
||||||
|
|
||||||
# Path to store images
|
# Path to store images
|
||||||
self.image_folder = top_level+'/images'
|
self.image_folder = top_level + '/images'
|
||||||
|
|
||||||
# Give an OK message
|
# Give an OK message
|
||||||
print('loaded inkycal')
|
print('loaded inkycal')
|
||||||
@ -183,22 +182,21 @@ class Inkycal:
|
|||||||
|
|
||||||
# Find out at which minutes the update should happen
|
# Find out at which minutes the update should happen
|
||||||
now = arrow.now()
|
now = arrow.now()
|
||||||
update_timings = [(60 - int(interval_mins)*updates) for updates in
|
update_timings = [(60 - int(interval_mins) * updates) for updates in
|
||||||
range(60//int(interval_mins))][::-1]
|
range(60 // int(interval_mins))][::-1]
|
||||||
|
|
||||||
# Calculate time in mins until next update
|
# Calculate time in mins until next update
|
||||||
minutes = [_ for _ in update_timings if _>= now.minute][0] - now.minute
|
minutes = [_ for _ in update_timings if _ >= now.minute][0] - now.minute
|
||||||
|
|
||||||
# Print the remaining time in mins until next update
|
# Print the remaining time in mins until next update
|
||||||
print(f'{minutes} minutes left until next refresh')
|
print(f'{minutes} minutes left until next refresh')
|
||||||
|
|
||||||
# Calculate time in seconds until next update
|
# Calculate time in seconds until next update
|
||||||
remaining_time = minutes*60 + (60 - now.second)
|
remaining_time = minutes * 60 + (60 - now.second)
|
||||||
|
|
||||||
# Return seconds until next update
|
# Return seconds until next update
|
||||||
return remaining_time
|
return remaining_time
|
||||||
|
|
||||||
|
|
||||||
def test(self):
|
def test(self):
|
||||||
"""Tests if Inkycal can run without issues.
|
"""Tests if Inkycal can run without issues.
|
||||||
|
|
||||||
@ -223,7 +221,7 @@ class Inkycal:
|
|||||||
module = eval(f'self.module_{number}')
|
module = eval(f'self.module_{number}')
|
||||||
print(f'generating image(s) for {name}...', end="")
|
print(f'generating image(s) for {name}...', end="")
|
||||||
try:
|
try:
|
||||||
black,colour=module.generate_image()
|
black, colour = module.generate_image()
|
||||||
black.save(f"{self.image_folder}/module{number}_black.png", "PNG")
|
black.save(f"{self.image_folder}/module{number}_black.png", "PNG")
|
||||||
colour.save(f"{self.image_folder}/module{number}_colour.png", "PNG")
|
colour.save(f"{self.image_folder}/module{number}_colour.png", "PNG")
|
||||||
print('OK!')
|
print('OK!')
|
||||||
@ -234,7 +232,7 @@ class Inkycal:
|
|||||||
print(traceback.format_exc())
|
print(traceback.format_exc())
|
||||||
|
|
||||||
if errors:
|
if errors:
|
||||||
print('Error/s in modules:',*errors)
|
print('Error/s in modules:', *errors)
|
||||||
del errors
|
del errors
|
||||||
|
|
||||||
self._assemble()
|
self._assemble()
|
||||||
@ -276,7 +274,7 @@ class Inkycal:
|
|||||||
module = eval(f'self.module_{number}')
|
module = eval(f'self.module_{number}')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
black,colour=module.generate_image()
|
black, colour = module.generate_image()
|
||||||
black.save(f"{self.image_folder}/module{number}_black.png", "PNG")
|
black.save(f"{self.image_folder}/module{number}_black.png", "PNG")
|
||||||
colour.save(f"{self.image_folder}/module{number}_colour.png", "PNG")
|
colour.save(f"{self.image_folder}/module{number}_colour.png", "PNG")
|
||||||
self.info += f"module {number}: OK "
|
self.info += f"module {number}: OK "
|
||||||
@ -288,7 +286,7 @@ class Inkycal:
|
|||||||
logger.exception(f'Exception in module {number}')
|
logger.exception(f'Exception in module {number}')
|
||||||
|
|
||||||
if errors:
|
if errors:
|
||||||
print('error/s in modules:',*errors)
|
print('error/s in modules:', *errors)
|
||||||
counter = 0
|
counter = 0
|
||||||
else:
|
else:
|
||||||
counter += 1
|
counter += 1
|
||||||
@ -340,7 +338,7 @@ class Inkycal:
|
|||||||
|
|
||||||
im_path = images
|
im_path = images
|
||||||
|
|
||||||
im1_path, im2_path = images+'canvas.png', images+'canvas_colour.png'
|
im1_path, im2_path = images + 'canvas.png', images + 'canvas_colour.png'
|
||||||
|
|
||||||
# If there is an image for black and colour, merge them
|
# If there is an image for black and colour, merge them
|
||||||
if os.path.exists(im1_path) and os.path.exists(im2_path):
|
if os.path.exists(im1_path) and os.path.exists(im2_path):
|
||||||
@ -356,7 +354,6 @@ class Inkycal:
|
|||||||
|
|
||||||
return im1
|
return im1
|
||||||
|
|
||||||
|
|
||||||
def _assemble(self):
|
def _assemble(self):
|
||||||
"""Assembles all sub-images to a single image"""
|
"""Assembles all sub-images to a single image"""
|
||||||
|
|
||||||
@ -366,8 +363,8 @@ class Inkycal:
|
|||||||
# Since Inkycal runs in vertical mode, switch the height and width
|
# Since Inkycal runs in vertical mode, switch the height and width
|
||||||
width, height = height, width
|
width, height = height, width
|
||||||
|
|
||||||
im_black = Image.new('RGB', (width, height), color = 'white')
|
im_black = Image.new('RGB', (width, height), color='white')
|
||||||
im_colour = Image.new('RGB', (width ,height), color = 'white')
|
im_colour = Image.new('RGB', (width, height), color='white')
|
||||||
|
|
||||||
# Set cursor for y-axis
|
# Set cursor for y-axis
|
||||||
im1_cursor = 0
|
im1_cursor = 0
|
||||||
@ -391,16 +388,16 @@ class Inkycal:
|
|||||||
i['position'] == number][0]['config']['size']
|
i['position'] == number][0]['config']['size']
|
||||||
|
|
||||||
# Calculate coordinates to center the image
|
# Calculate coordinates to center the image
|
||||||
x = int( (section_size[0] - im1_size[0]) /2)
|
x = int((section_size[0] - im1_size[0]) / 2)
|
||||||
|
|
||||||
# If this is the first module, use the y-offset
|
# If this is the first module, use the y-offset
|
||||||
if im1_cursor == 0:
|
if im1_cursor == 0:
|
||||||
y = int( (section_size[1]-im1_size[1]) /2)
|
y = int((section_size[1] - im1_size[1]) / 2)
|
||||||
else:
|
else:
|
||||||
y = im1_cursor + int( (section_size[1]-im1_size[1]) /2)
|
y = im1_cursor + int((section_size[1] - im1_size[1]) / 2)
|
||||||
|
|
||||||
# center the image in the section space
|
# center the image in the section space
|
||||||
im_black.paste(im1, (x,y), im1)
|
im_black.paste(im1, (x, y), im1)
|
||||||
|
|
||||||
# Shift the y-axis cursor at the beginning of next section
|
# Shift the y-axis cursor at the beginning of next section
|
||||||
im1_cursor += section_size[1]
|
im1_cursor += section_size[1]
|
||||||
@ -417,21 +414,20 @@ class Inkycal:
|
|||||||
i['position'] == number][0]['config']['size']
|
i['position'] == number][0]['config']['size']
|
||||||
|
|
||||||
# Calculate coordinates to center the image
|
# Calculate coordinates to center the image
|
||||||
x = int( (section_size[0]-im2_size[0]) /2)
|
x = int((section_size[0] - im2_size[0]) / 2)
|
||||||
|
|
||||||
# If this is the first module, use the y-offset
|
# If this is the first module, use the y-offset
|
||||||
if im2_cursor == 0:
|
if im2_cursor == 0:
|
||||||
y = int( (section_size[1]-im2_size[1]) /2)
|
y = int((section_size[1] - im2_size[1]) / 2)
|
||||||
else:
|
else:
|
||||||
y = im2_cursor + int( (section_size[1]-im2_size[1]) /2)
|
y = im2_cursor + int((section_size[1] - im2_size[1]) / 2)
|
||||||
|
|
||||||
# center the image in the section space
|
# center the image in the section space
|
||||||
im_colour.paste(im2, (x,y), im2)
|
im_colour.paste(im2, (x, y), im2)
|
||||||
|
|
||||||
# Shift the y-axis cursor at the beginning of next section
|
# Shift the y-axis cursor at the beginning of next section
|
||||||
im2_cursor += section_size[1]
|
im2_cursor += section_size[1]
|
||||||
|
|
||||||
|
|
||||||
# Add info-section if specified --
|
# Add info-section if specified --
|
||||||
|
|
||||||
# Calculate the max. fontsize for info-section
|
# Calculate the max. fontsize for info-section
|
||||||
@ -439,19 +435,19 @@ class Inkycal:
|
|||||||
info_height = self.settings["info_section_height"]
|
info_height = self.settings["info_section_height"]
|
||||||
info_width = width
|
info_width = width
|
||||||
font = self.font = ImageFont.truetype(
|
font = self.font = ImageFont.truetype(
|
||||||
fonts['NotoSansUI-Regular'], size = 14)
|
fonts['NotoSansUI-Regular'], size=14)
|
||||||
|
|
||||||
info_x = im_black.size[1] - info_height
|
info_x = im_black.size[1] - info_height
|
||||||
write(im_black, (0, info_x), (info_width, info_height),
|
write(im_black, (0, info_x), (info_width, info_height),
|
||||||
self.info, font = font)
|
self.info, font=font)
|
||||||
|
|
||||||
# optimize the image by mapping colours to pure black and white
|
# optimize the image by mapping colours to pure black and white
|
||||||
if self.optimize == True:
|
if self.optimize == True:
|
||||||
im_black = self._optimize_im(im_black)
|
im_black = self._optimize_im(im_black)
|
||||||
im_colour = self._optimize_im(im_colour)
|
im_colour = self._optimize_im(im_colour)
|
||||||
|
|
||||||
im_black.save(self.image_folder+'/canvas.png', 'PNG')
|
im_black.save(self.image_folder + '/canvas.png', 'PNG')
|
||||||
im_colour.save(self.image_folder+'/canvas_colour.png', 'PNG')
|
im_colour.save(self.image_folder + '/canvas_colour.png', 'PNG')
|
||||||
|
|
||||||
def _optimize_im(self, image, threshold=220):
|
def _optimize_im(self, image, threshold=220):
|
||||||
"""Optimize the image for rendering on ePaper displays"""
|
"""Optimize the image for rendering on ePaper displays"""
|
||||||
@ -460,7 +456,7 @@ class Inkycal:
|
|||||||
red, green = buffer[:, :, 0], buffer[:, :, 1]
|
red, green = buffer[:, :, 0], buffer[:, :, 1]
|
||||||
|
|
||||||
# grey->black
|
# grey->black
|
||||||
buffer[numpy.logical_and(red <= threshold, green <= threshold)] = [0,0,0]
|
buffer[numpy.logical_and(red <= threshold, green <= threshold)] = [0, 0, 0]
|
||||||
image = Image.fromarray(buffer)
|
image = Image.fromarray(buffer)
|
||||||
return image
|
return image
|
||||||
|
|
||||||
@ -485,7 +481,6 @@ class Inkycal:
|
|||||||
else:
|
else:
|
||||||
self._calibration_state = False
|
self._calibration_state = False
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_module(cls, filepath):
|
def add_module(cls, filepath):
|
||||||
"""registers a third party module for inkycal.
|
"""registers a third party module for inkycal.
|
||||||
@ -515,7 +510,7 @@ class Inkycal:
|
|||||||
>>> Inkycal.add_module('/full/path/to/the/module/in/inkycal/modules.py')
|
>>> Inkycal.add_module('/full/path/to/the/module/in/inkycal/modules.py')
|
||||||
"""
|
"""
|
||||||
|
|
||||||
module_folder = top_level+'/inkycal/modules'
|
module_folder = top_level + '/inkycal/modules'
|
||||||
|
|
||||||
# Check if module is inside the modules folder
|
# Check if module is inside the modules folder
|
||||||
if not module_folder in filepath:
|
if not module_folder in filepath:
|
||||||
@ -538,9 +533,8 @@ class Inkycal:
|
|||||||
raise TypeError("your module doesn't seem to be a correct inkycal module.."
|
raise TypeError("your module doesn't seem to be a correct inkycal module.."
|
||||||
"Please check your module again.")
|
"Please check your module again.")
|
||||||
|
|
||||||
|
|
||||||
# Check if filename or classname exists in init of module folder
|
# Check if filename or classname exists in init of module folder
|
||||||
with open(module_folder+'/__init__.py', mode ='r') as file:
|
with open(module_folder + '/__init__.py', mode='r') as file:
|
||||||
module_init = file.read().splitlines()
|
module_init = file.read().splitlines()
|
||||||
|
|
||||||
print('checking module init file..')
|
print('checking module init file..')
|
||||||
@ -558,7 +552,7 @@ class Inkycal:
|
|||||||
print('OK!')
|
print('OK!')
|
||||||
|
|
||||||
# Check if filename or classname exists in init of inkycal folder
|
# Check if filename or classname exists in init of inkycal folder
|
||||||
with open(top_level+'/inkycal/__init__.py', mode ='r') as file:
|
with open(top_level + '/inkycal/__init__.py', mode='r') as file:
|
||||||
inkycal_init = file.read().splitlines()
|
inkycal_init = file.read().splitlines()
|
||||||
|
|
||||||
print('checking inkycal init file..')
|
print('checking inkycal init file..')
|
||||||
@ -576,17 +570,16 @@ class Inkycal:
|
|||||||
print('OK')
|
print('OK')
|
||||||
|
|
||||||
# If all checks have passed, add the module in the module init file
|
# If all checks have passed, add the module in the module init file
|
||||||
with open(module_folder+'/__init__.py', mode='a') as file:
|
with open(module_folder + '/__init__.py', mode='a') as file:
|
||||||
file.write(f'from .{filename} import {classname} # Added by module adder')
|
file.write(f'from .{filename} import {classname} # Added by module adder')
|
||||||
|
|
||||||
# If all checks have passed, add the module in the inkycal init file
|
# If all checks have passed, add the module in the inkycal init file
|
||||||
with open(top_level+'/inkycal/__init__.py', mode ='a') as file:
|
with open(top_level + '/inkycal/__init__.py', mode='a') as file:
|
||||||
file.write(f'import inkycal.modules.{filename} # Added by module adder')
|
file.write(f'import inkycal.modules.{filename} # Added by module adder')
|
||||||
|
|
||||||
print(f"Your module '{filename}' with class '{classname}' has been added "
|
print(f"Your module '{filename}' with class '{classname}' has been added "
|
||||||
"successfully! Hooray!")
|
"successfully! Hooray!")
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def remove_module(cls, filename, remove_file=True):
|
def remove_module(cls, filename, remove_file=True):
|
||||||
"""unregisters a inkycal module.
|
"""unregisters a inkycal module.
|
||||||
@ -611,7 +604,7 @@ class Inkycal:
|
|||||||
>>> Inkycal.remove_module('mymodule.py')
|
>>> Inkycal.remove_module('mymodule.py')
|
||||||
"""
|
"""
|
||||||
|
|
||||||
module_folder = top_level+'/inkycal/modules'
|
module_folder = top_level + '/inkycal/modules'
|
||||||
|
|
||||||
# Check if module is inside the modules folder and extract classname
|
# Check if module is inside the modules folder and extract classname
|
||||||
try:
|
try:
|
||||||
@ -636,28 +629,28 @@ class Inkycal:
|
|||||||
filename = filename.split('.py')[0]
|
filename = filename.split('.py')[0]
|
||||||
|
|
||||||
# Create a memory backup of /modules init file
|
# Create a memory backup of /modules init file
|
||||||
with open(module_folder+'/__init__.py', mode ='r') as file:
|
with open(module_folder + '/__init__.py', mode='r') as file:
|
||||||
module_init = file.read().splitlines()
|
module_init = file.read().splitlines()
|
||||||
|
|
||||||
print('removing line from module_init')
|
print('removing line from module_init')
|
||||||
# Remove lines that contain classname
|
# Remove lines that contain classname
|
||||||
with open(module_folder+'/__init__.py', mode ='w') as file:
|
with open(module_folder + '/__init__.py', mode='w') as file:
|
||||||
for line in module_init:
|
for line in module_init:
|
||||||
if not classname in line:
|
if not classname in line:
|
||||||
file.write(line+'\n')
|
file.write(line + '\n')
|
||||||
else:
|
else:
|
||||||
print('found, removing')
|
print('found, removing')
|
||||||
|
|
||||||
# Create a memory backup of inkycal init file
|
# Create a memory backup of inkycal init file
|
||||||
with open(f"{top_level}/inkycal/__init__.py", mode ='r') as file:
|
with open(f"{top_level}/inkycal/__init__.py", mode='r') as file:
|
||||||
inkycal_init = file.read().splitlines()
|
inkycal_init = file.read().splitlines()
|
||||||
|
|
||||||
print('removing line from inkycal init')
|
print('removing line from inkycal init')
|
||||||
# Remove lines that contain classname
|
# Remove lines that contain classname
|
||||||
with open(f"{top_level}/inkycal/__init__.py", mode ='w') as file:
|
with open(f"{top_level}/inkycal/__init__.py", mode='w') as file:
|
||||||
for line in inkycal_init:
|
for line in inkycal_init:
|
||||||
if not filename in line:
|
if not filename in line:
|
||||||
file.write(line+'\n')
|
file.write(line + '\n')
|
||||||
else:
|
else:
|
||||||
print('found, removing')
|
print('found, removing')
|
||||||
|
|
||||||
@ -669,5 +662,6 @@ class Inkycal:
|
|||||||
|
|
||||||
print(f"Your module '{filename}' with class '{classname}' was removed.")
|
print(f"Your module '{filename}' with class '{classname}' was removed.")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print(f'running inkycal main in standalone/debug mode')
|
print(f'running inkycal main in standalone/debug mode')
|
||||||
|
Loading…
Reference in New Issue
Block a user