Allow usage without display and SPI when setting render->False
Generated images will be available in the images folder
This commit is contained in:
		| @@ -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') | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user