| 
									
										
										
										
											2022-10-03 02:58:07 +02:00
										 |  |  | """
 | 
					
						
							|  |  |  | Textfile module for InkyCal Project | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Reads data from a plain .txt file and renders it on the display. | 
					
						
							|  |  |  | If the content is too long, it will be truncated from the back until it fits | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-03 16:16:07 +02:00
										 |  |  | Copyright by aceinnolab | 
					
						
							| 
									
										
										
										
											2022-10-03 02:58:07 +02:00
										 |  |  | """
 | 
					
						
							|  |  |  | from urllib.request import urlopen | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-07 23:13:30 +01:00
										 |  |  | from inkycal.custom import * | 
					
						
							|  |  |  | from inkycal.modules.template import inkycal_module | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-03 02:58:07 +02:00
										 |  |  | logger = logging.getLogger(__name__) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TextToDisplay(inkycal_module): | 
					
						
							| 
									
										
										
										
											2023-11-24 02:37:27 +01:00
										 |  |  |     """TextToDisplay module - Display text from a local file on the display
 | 
					
						
							| 
									
										
										
										
											2022-10-03 02:58:07 +02:00
										 |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, config): | 
					
						
							|  |  |  |         """Initialize inkycal_textfile_to_display module""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         super().__init__(config) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         config = config['config'] | 
					
						
							|  |  |  |         # required parameters | 
					
						
							|  |  |  |         self.filepath = config["filepath"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.make_request = True if self.filepath.startswith("https://") else False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # give an OK message | 
					
						
							|  |  |  |         print(f'{__name__} loaded') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _validate(self): | 
					
						
							|  |  |  |         """Validate module-specific parameters""" | 
					
						
							|  |  |  |         # ensure we only use a single file | 
					
						
							|  |  |  |         assert (self.filepath and len(self.filepath) == 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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_left)) | 
					
						
							|  |  |  |         im_height = int(self.height - (2 * self.padding_top)) | 
					
						
							|  |  |  |         im_size = im_width, im_height | 
					
						
							|  |  |  |         logger.info(f'Image size: {im_size}') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Create an image for black pixels and one for coloured pixels | 
					
						
							|  |  |  |         im_black = Image.new('RGB', size=im_size, color='white') | 
					
						
							|  |  |  |         im_colour = Image.new('RGB', size=im_size, color='white') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Set some parameters for formatting feeds | 
					
						
							| 
									
										
										
										
											2023-11-07 22:49:48 +01:00
										 |  |  |         line_spacing = 4 | 
					
						
							|  |  |  |         text_bbox_height = self.font.getbbox("hg") | 
					
						
							| 
									
										
										
										
											2023-11-21 16:03:09 +01:00
										 |  |  |         line_height = text_bbox_height[3] + line_spacing | 
					
						
							| 
									
										
										
										
											2022-10-03 02:58:07 +02:00
										 |  |  |         line_width = im_width | 
					
						
							| 
									
										
										
										
											2023-11-07 22:49:48 +01:00
										 |  |  |         max_lines = im_height // line_height | 
					
						
							| 
									
										
										
										
											2022-10-03 02:58:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Calculate padding from top so the lines look centralised | 
					
						
							|  |  |  |         spacing_top = int(im_height % line_height / 2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Calculate line_positions | 
					
						
							|  |  |  |         line_positions = [ | 
					
						
							|  |  |  |             (0, spacing_top + _ * line_height) for _ in range(max_lines)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if self.make_request: | 
					
						
							|  |  |  |             logger.info("Detected http path, making request") | 
					
						
							| 
									
										
										
										
											2023-11-08 20:22:50 +01:00
										 |  |  |             # Check if internet is available | 
					
						
							|  |  |  |             if internet_available(): | 
					
						
							|  |  |  |                 logger.info('Connection test passed') | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 raise NetworkNotReachableError | 
					
						
							| 
									
										
										
										
											2022-10-03 02:58:07 +02:00
										 |  |  |             file_content = urlopen(self.filepath).read().decode('utf-8') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             # Create list containing all lines | 
					
						
							|  |  |  |             with open(self.filepath, 'r') as file: | 
					
						
							|  |  |  |                 file_content = file.read() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         fitted_content = text_wrap(file_content, font=self.font, max_width=im_width) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Trim down the list to the max number of lines | 
					
						
							|  |  |  |         del fitted_content[max_lines:] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Write feeds on image | 
					
						
							|  |  |  |         for index, line in enumerate(fitted_content): | 
					
						
							|  |  |  |             write( | 
					
						
							|  |  |  |                 im_black, | 
					
						
							|  |  |  |                 line_positions[index], | 
					
						
							|  |  |  |                 (line_width, line_height), | 
					
						
							|  |  |  |                 line, | 
					
						
							|  |  |  |                 font=self.font, | 
					
						
							|  |  |  |                 alignment='left' | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # return images | 
					
						
							|  |  |  |         return im_black, im_colour |