| 
									
										
										
										
											2020-05-12 19:35:08 +02:00
										 |  |  | """
 | 
					
						
							| 
									
										
										
										
											2022-10-02 00:49:27 +02:00
										 |  |  | Inkycal custom-functions for ease-of-use | 
					
						
							| 
									
										
										
										
											2020-05-12 19:35:08 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-03 16:16:07 +02:00
										 |  |  | Copyright by aceinnolab | 
					
						
							| 
									
										
										
										
											2020-05-12 19:35:08 +02:00
										 |  |  | """
 | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  | import json | 
					
						
							| 
									
										
										
										
											2020-05-12 19:35:08 +02:00
										 |  |  | import logging | 
					
						
							| 
									
										
										
										
											2023-11-08 20:22:50 +01:00
										 |  |  | import os | 
					
						
							|  |  |  | import time | 
					
						
							| 
									
										
										
										
											2023-11-07 22:49:48 +01:00
										 |  |  | import traceback | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  | import arrow | 
					
						
							| 
									
										
										
										
											2023-12-14 01:51:10 +01:00
										 |  |  | import PIL | 
					
						
							| 
									
										
										
										
											2023-11-07 22:49:48 +01:00
										 |  |  | import requests | 
					
						
							| 
									
										
										
										
											2024-01-17 21:27:40 +00:00
										 |  |  | import tzlocal | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  | from PIL import Image | 
					
						
							|  |  |  | from PIL import ImageDraw | 
					
						
							|  |  |  | from PIL import ImageFont | 
					
						
							| 
									
										
										
										
											2020-05-12 19:35:08 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-03 02:56:04 +02:00
										 |  |  | logs = logging.getLogger(__name__) | 
					
						
							| 
									
										
										
										
											2020-11-21 16:25:08 +01:00
										 |  |  | logs.setLevel(level=logging.INFO) | 
					
						
							| 
									
										
										
										
											2020-05-12 19:35:08 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-30 00:46:52 +02:00
										 |  |  | # Get the path to the Inkycal folder | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  | top_level = os.path.dirname(os.path.abspath(os.path.dirname(__file__))).split("/inkycal")[0] | 
					
						
							| 
									
										
										
										
											2020-05-12 19:35:08 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-30 00:46:52 +02:00
										 |  |  | # Get path of 'fonts' and 'images' folders within Inkycal folder | 
					
						
							| 
									
										
										
										
											2024-01-20 15:19:38 +01:00
										 |  |  | fonts_location = os.path.join(top_level, "fonts/") | 
					
						
							|  |  |  | image_folder = os.path.join(top_level, "image_folder/") | 
					
						
							| 
									
										
										
										
											2020-05-12 19:35:08 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Get available fonts within fonts folder | 
					
						
							|  |  |  | fonts = {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  | for path, dirs, files in os.walk(fonts_location): | 
					
						
							| 
									
										
										
										
											2022-10-03 02:56:04 +02:00
										 |  |  |     for _ in files: | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  |         if _.endswith(".otf"): | 
					
						
							|  |  |  |             name = _.split(".otf")[0] | 
					
						
							| 
									
										
										
										
											2022-10-03 02:56:04 +02:00
										 |  |  |             fonts[name] = os.path.join(path, _) | 
					
						
							| 
									
										
										
										
											2020-05-12 19:35:08 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  |         if _.endswith(".ttf"): | 
					
						
							|  |  |  |             name = _.split(".ttf")[0] | 
					
						
							| 
									
										
										
										
											2022-10-03 02:56:04 +02:00
										 |  |  |             fonts[name] = os.path.join(path, _) | 
					
						
							| 
									
										
										
										
											2024-01-15 19:08:46 +01:00
										 |  |  | logs.debug(f"Found fonts: {json.dumps(fonts, indent=4, sort_keys=True)}") | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  | available_fonts = [key for key, values in fonts.items()] | 
					
						
							| 
									
										
										
										
											2020-05-12 19:35:08 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def get_fonts(): | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     """Print all available fonts by name.
 | 
					
						
							| 
									
										
										
										
											2020-11-24 00:40:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     Searches the /font folder in Inkycal and displays all fonts found in | 
					
						
							|  |  |  |     there. | 
					
						
							| 
									
										
										
										
											2020-11-24 00:40:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     Returns: | 
					
						
							|  |  |  |       printed output of all available fonts. To access a fontfile, use the | 
					
						
							|  |  |  |       fonts dictionary to access it. | 
					
						
							| 
									
										
										
										
											2020-12-05 00:18:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |       >>> fonts['fontname'] | 
					
						
							| 
									
										
										
										
											2020-11-24 00:40:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     To use a font, use the following sytax, where fontname is one of the | 
					
						
							|  |  |  |     printed fonts of this function: | 
					
						
							| 
									
										
										
										
											2020-12-05 00:18:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     >>> ImageFont.truetype(fonts['fontname'], size = 10) | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     for fonts in available_fonts: | 
					
						
							|  |  |  |         print(fonts) | 
					
						
							| 
									
										
										
										
											2020-05-12 19:35:08 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  | def get_system_tz() -> str: | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     """Gets the system-timezone
 | 
					
						
							| 
									
										
										
										
											2020-11-24 00:40:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     Gets the timezone set by the system. | 
					
						
							| 
									
										
										
										
											2020-11-24 00:40:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     Returns: | 
					
						
							|  |  |  |       - A timezone if a system timezone was found. | 
					
						
							| 
									
										
										
										
											2024-01-17 21:27:40 +00:00
										 |  |  |       - UTC if no timezone was found. | 
					
						
							| 
									
										
										
										
											2020-11-24 00:40:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     The extracted timezone can be used to show the local time instead of UTC. e.g. | 
					
						
							| 
									
										
										
										
											2020-11-24 00:40:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |       >>> import arrow | 
					
						
							|  |  |  |       >>> print(arrow.now()) # returns non-timezone-aware time | 
					
						
							|  |  |  |       >>> print(arrow.now(tz=get_system_tz()) # prints timezone aware time. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2024-01-17 21:27:40 +00:00
										 |  |  |         local_tz = tzlocal.get_localzone().key | 
					
						
							|  |  |  |         logs.debug(f"Local system timezone is {local_tz}.") | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     except: | 
					
						
							| 
									
										
										
										
											2024-01-17 21:27:40 +00:00
										 |  |  |         logs.error("System timezone could not be parsed!") | 
					
						
							|  |  |  |         logs.error("Please set timezone manually!. Falling back to UTC...") | 
					
						
							|  |  |  |         local_tz = "UTC" | 
					
						
							|  |  |  |     logs.debug(f"The time is {arrow.now(tz=local_tz).format('YYYY-MM-DD HH:mm:ss ZZ')}.") | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     return local_tz | 
					
						
							| 
									
										
										
										
											2020-05-12 19:35:08 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def auto_fontsize(font, max_height): | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     """Scales a given font to 80% of max_height.
 | 
					
						
							| 
									
										
										
										
											2020-11-24 00:40:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  |     Gets the height of a font and scales it until 80% of the max_height | 
					
						
							|  |  |  |     is filled. | 
					
						
							| 
									
										
										
										
											2020-11-24 00:40:49 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  |     Args: | 
					
						
							|  |  |  |         - font: A PIL Font object. | 
					
						
							|  |  |  |         - max_height: An integer representing the height to adjust the font to | 
					
						
							|  |  |  |           which the given font should be scaled to. | 
					
						
							| 
									
										
										
										
											2020-11-24 00:40:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  |     Returns: | 
					
						
							|  |  |  |         A PIL font object with modified height. | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-11-07 22:49:48 +01:00
										 |  |  |     text_bbox = font.getbbox("hg") | 
					
						
							| 
									
										
										
										
											2023-11-21 16:03:09 +01:00
										 |  |  |     text_height = text_bbox[3] | 
					
						
							| 
									
										
										
										
											2023-11-07 22:49:48 +01:00
										 |  |  |     fontsize = text_height | 
					
						
							|  |  |  |     while text_height <= (max_height * 0.80): | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |         fontsize += 1 | 
					
						
							|  |  |  |         font = ImageFont.truetype(font.path, fontsize) | 
					
						
							| 
									
										
										
										
											2023-11-21 16:03:09 +01:00
										 |  |  |         text_height = text_bbox[3] | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     return font | 
					
						
							| 
									
										
										
										
											2020-05-12 19:35:08 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def write(image, xy, box_size, text, font=None, **kwargs): | 
					
						
							| 
									
										
										
										
											2024-02-08 12:51:06 +01:00
										 |  |  |     """Writes text on an image.
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Writes given text at given position on the specified image. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Args: | 
					
						
							|  |  |  |       - image: The image to draw this text on, usually im_black or im_colour. | 
					
						
							|  |  |  |       - xy: tuple-> (x,y) representing the x and y co-ordinate. | 
					
						
							|  |  |  |       - box_size: tuple -> (width, height) representing the size of the text box. | 
					
						
							|  |  |  |       - text: string, the actual text to add on the image. | 
					
						
							|  |  |  |       - font: A PIL Font object e.g. | 
					
						
							|  |  |  |         ImageFont.truetype(fonts['fontname'], size = 10). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Args: (optional) | 
					
						
							|  |  |  |       - alignment: alignment of the text, use 'center', 'left', 'right'. | 
					
						
							|  |  |  |       - autofit: bool (True/False). Automatically increases fontsize to fill in | 
					
						
							|  |  |  |         as much of the box-height as possible. | 
					
						
							|  |  |  |       - colour: black by default, do not change as it causes issues with rendering | 
					
						
							|  |  |  |         on e-Paper. | 
					
						
							|  |  |  |       - rotation: Rotate the text with the text-box by a given angle anti-clockwise. | 
					
						
							| 
									
										
										
										
											2024-02-08 12:51:06 +01:00
										 |  |  |       - fill_width: Decimal representing a percentage e.g. 0.9 # 90%. Fill | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |         maximum of 90% of the size of the full width of text-box. | 
					
						
							| 
									
										
										
										
											2024-02-08 12:51:06 +01:00
										 |  |  |       - fill_height: Decimal representing a percentage e.g. 0.9 # 90%. Fill | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |         maximum of 90% of the size of the full height of the text-box. | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  |     allowed_kwargs = ["alignment", "autofit", "colour", "rotation", "fill_width", "fill_height"] | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Validate kwargs | 
					
						
							|  |  |  |     for key, value in kwargs.items(): | 
					
						
							|  |  |  |         if key not in allowed_kwargs: | 
					
						
							| 
									
										
										
										
											2024-02-08 12:51:06 +01:00
										 |  |  |             print(f'{key} does not exist') | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Set kwargs if given, it not, use defaults | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  |     alignment = kwargs["alignment"] if "alignment" in kwargs else "center" | 
					
						
							|  |  |  |     autofit = kwargs["autofit"] if "autofit" in kwargs else False | 
					
						
							|  |  |  |     fill_width = kwargs["fill_width"] if "fill_width" in kwargs else 1.0 | 
					
						
							|  |  |  |     fill_height = kwargs["fill_height"] if "fill_height" in kwargs else 0.8 | 
					
						
							|  |  |  |     colour = kwargs["colour"] if "colour" in kwargs else "black" | 
					
						
							|  |  |  |     rotation = kwargs["rotation"] if "rotation" in kwargs else None | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     x, y = xy | 
					
						
							|  |  |  |     box_width, box_height = box_size | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Increase fontsize to fit specified height and width of text box | 
					
						
							| 
									
										
										
										
											2023-01-10 22:58:01 +01:00
										 |  |  |     if autofit or (fill_width != 1.0) or (fill_height != 0.8): | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |         size = 8 | 
					
						
							|  |  |  |         font = ImageFont.truetype(font.path, size) | 
					
						
							| 
									
										
										
										
											2023-11-07 22:49:48 +01:00
										 |  |  |         text_bbox = font.getbbox(text) | 
					
						
							|  |  |  |         text_width = text_bbox[2] - text_bbox[0] | 
					
						
							|  |  |  |         text_bbox_height = font.getbbox("hg") | 
					
						
							|  |  |  |         text_height = text_bbox_height[3] - text_bbox_height[1] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  |         while text_width < int(box_width * fill_width) and text_height < int(box_height * fill_height): | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |             size += 1 | 
					
						
							|  |  |  |             font = ImageFont.truetype(font.path, size) | 
					
						
							| 
									
										
										
										
											2023-11-07 22:49:48 +01:00
										 |  |  |             text_bbox = font.getbbox(text) | 
					
						
							|  |  |  |             text_width = text_bbox[2] - text_bbox[0] | 
					
						
							|  |  |  |             text_bbox_height = font.getbbox("hg") | 
					
						
							|  |  |  |             text_height = text_bbox_height[3] - text_bbox_height[1] | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-07 22:49:48 +01:00
										 |  |  |     text_bbox = font.getbbox(text) | 
					
						
							|  |  |  |     text_width = text_bbox[2] - text_bbox[0] | 
					
						
							|  |  |  |     text_bbox_height = font.getbbox("hg") | 
					
						
							|  |  |  |     text_height = text_bbox_height[3] - text_bbox_height[1] | 
					
						
							| 
									
										
										
										
											2020-05-12 19:35:08 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-08 12:51:06 +01:00
										 |  |  |     # Truncate text if text is too long, so it can fit inside the box | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     if (text_width, text_height) > (box_width, box_height): | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  |         logs.debug(("truncating {}".format(text))) | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |         while (text_width, text_height) > (box_width, box_height): | 
					
						
							|  |  |  |             text = text[0:-1] | 
					
						
							| 
									
										
										
										
											2023-11-07 22:49:48 +01:00
										 |  |  |             text_bbox = font.getbbox(text) | 
					
						
							|  |  |  |             text_width = text_bbox[2] - text_bbox[0] | 
					
						
							|  |  |  |             text_bbox_height = font.getbbox("hg") | 
					
						
							|  |  |  |             text_height = text_bbox_height[3] - text_bbox_height[1] | 
					
						
							| 
									
										
										
										
											2023-01-10 22:58:01 +01:00
										 |  |  |         logs.debug(text) | 
					
						
							| 
									
										
										
										
											2020-05-12 19:35:08 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     # Align text to desired position | 
					
						
							|  |  |  |     if alignment == "center" or None: | 
					
						
							|  |  |  |         x = int((box_width / 2) - (text_width / 2)) | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  |     elif alignment == "left": | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |         x = 0 | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  |     elif alignment == "right": | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |         x = int(box_width - text_width) | 
					
						
							| 
									
										
										
										
											2020-11-24 00:40:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     # Draw the text in the text-box | 
					
						
							|  |  |  |     draw = ImageDraw.Draw(image) | 
					
						
							|  |  |  |     space = Image.new('RGBA', (box_width, box_height)) | 
					
						
							| 
									
										
										
										
											2024-02-08 12:51:06 +01:00
										 |  |  |     ImageDraw.Draw(space).text((x, 0), text, fill=colour, font=font) | 
					
						
							| 
									
										
										
										
											2020-11-24 00:40:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     # Uncomment following two lines, comment out above two lines to show | 
					
						
							|  |  |  |     # red text-box with white text (debugging purposes) | 
					
						
							| 
									
										
										
										
											2020-11-24 00:40:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     # space = Image.new('RGBA', (box_width, box_height), color= 'red') | 
					
						
							| 
									
										
										
										
											2024-02-08 12:51:06 +01:00
										 |  |  |     # ImageDraw.Draw(space).text((x, 0), text, fill='white', font=font, anchor="la") | 
					
						
							| 
									
										
										
										
											2020-05-12 19:35:08 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-10 22:58:01 +01:00
										 |  |  |     if rotation: | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |         space.rotate(rotation, expand=True) | 
					
						
							| 
									
										
										
										
											2020-05-12 19:35:08 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     # Update only region with text (add text with transparent background) | 
					
						
							|  |  |  |     image.paste(space, xy, space) | 
					
						
							| 
									
										
										
										
											2020-05-12 19:35:08 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 00:40:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  | def text_wrap(text, font=None, max_width=None): | 
					
						
							|  |  |  |     """Splits a very long text into smaller parts
 | 
					
						
							| 
									
										
										
										
											2020-12-05 00:18:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     Splits a long text to smaller lines which can fit in a line with max_width. | 
					
						
							|  |  |  |     Uses a Font object for more accurate calculations. | 
					
						
							| 
									
										
										
										
											2020-11-24 00:40:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     Args: | 
					
						
							| 
									
										
										
										
											2022-10-03 02:56:04 +02:00
										 |  |  |       - text -> Text as a string | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |       - font: A PIL font object which is used to calculate the size. | 
					
						
							|  |  |  |       - max_width: int-> a width in pixels defining the maximum width before | 
					
						
							|  |  |  |         splitting the text into the next chunk. | 
					
						
							| 
									
										
										
										
											2020-11-24 00:40:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     Returns: | 
					
						
							|  |  |  |       A list containing chunked strings of the full text. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     lines = [] | 
					
						
							| 
									
										
										
										
											2023-11-07 22:49:48 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     text_width = font.getlength(text) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if text_width < max_width: | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |         lines.append(text) | 
					
						
							|  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  |         words = text.split(" ") | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |         i = 0 | 
					
						
							|  |  |  |         while i < len(words): | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  |             line = "" | 
					
						
							| 
									
										
										
										
											2023-11-07 22:49:48 +01:00
										 |  |  |             while i < len(words) and font.getlength(line + words[i]) <= max_width: | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |                 line = line + words[i] + " " | 
					
						
							|  |  |  |                 i += 1 | 
					
						
							|  |  |  |             if not line: | 
					
						
							|  |  |  |                 line = words[i] | 
					
						
							|  |  |  |                 i += 1 | 
					
						
							|  |  |  |             lines.append(line) | 
					
						
							|  |  |  |     return lines | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def internet_available(): | 
					
						
							|  |  |  |     """checks if the internet is available.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Attempts to connect to google.com with a timeout of 5 seconds to check | 
					
						
							|  |  |  |     if the network can be reached. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Returns: | 
					
						
							|  |  |  |       - True if connection could be established. | 
					
						
							|  |  |  |       - False if the internet could not be reached. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Returned output can be used to add a check for internet availability: | 
					
						
							| 
									
										
										
										
											2020-11-24 00:40:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-10 06:35:08 +02:00
										 |  |  |     >>> if internet_available(): | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     >>> #...do something that requires internet connectivity | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-11-08 20:22:50 +01:00
										 |  |  |     for attempt in range(3): | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  |             requests.get("https://google.com", timeout=5) | 
					
						
							| 
									
										
										
										
											2023-11-08 20:22:50 +01:00
										 |  |  |             return True | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             print(f"Network could not be reached: {traceback.print_exc()}") | 
					
						
							|  |  |  |             time.sleep(5) | 
					
						
							|  |  |  |     return False | 
					
						
							| 
									
										
										
										
											2020-05-30 00:46:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-23 22:08:33 +01:00
										 |  |  | def draw_border(image, xy, size, radius=5, thickness=1, shrinkage=(0.1, 0.1)): | 
					
						
							|  |  |  |     """Draws a border at given coordinates.
 | 
					
						
							| 
									
										
										
										
											2020-05-23 01:45:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     Args: | 
					
						
							| 
									
										
										
										
											2023-11-23 22:08:33 +01:00
										 |  |  |       - image: The image on which the border should be drawn (usually im_black or | 
					
						
							|  |  |  |         im_colour. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       - xy: Tuple representing the top-left corner of the border e.g. (32, 100) | 
					
						
							|  |  |  |         where 32 is the x co-ordinate and 100 is the y-coordinate. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       - size: Size of the border as a tuple -> (width, height). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       - radius: Radius of the corners, where 0 = plain rectangle, 5 = round corners. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       - thickness: Thickness of the border in pixels. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       - shrinkage: A tuple containing decimals presenting a percentage of shrinking | 
					
						
							|  |  |  |         -> (width_shrink_percentage, height_shrink_percentage). | 
					
						
							|  |  |  |         e.g. (0.1, 0.2) ~ shrinks the width of border by 10%, shrinks height of | 
					
						
							|  |  |  |         border by 20% | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-05-23 01:45:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-20 15:10:05 +01:00
										 |  |  |     colour = "black" | 
					
						
							| 
									
										
										
										
											2023-11-23 22:08:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-24 02:37:27 +01:00
										 |  |  |     # size from function parameter | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     width, height = int(size[0] * (1 - shrinkage[0])), int(size[1] * (1 - shrinkage[1])) | 
					
						
							| 
									
										
										
										
											2023-11-23 22:08:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # shift cursor to move rectangle to center | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     offset_x, offset_y = int((size[0] - width) / 2), int((size[1] - height) / 2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     x, y, diameter = xy[0] + offset_x, xy[1] + offset_y, radius * 2 | 
					
						
							| 
									
										
										
										
											2023-11-24 02:37:27 +01:00
										 |  |  |     # length of rectangle size | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     a, b = (width - diameter), (height - diameter) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-24 02:37:27 +01:00
										 |  |  |     # Set coordinates for straight lines | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |     p1, p2 = (x + radius, y), (x + radius + a, y) | 
					
						
							|  |  |  |     p3, p4 = (x + width, y + radius), (x + width, y + radius + b) | 
					
						
							|  |  |  |     p5, p6 = (p2[0], y + height), (p1[0], y + height) | 
					
						
							|  |  |  |     p7, p8 = (x, p4[1]), (x, p3[1]) | 
					
						
							|  |  |  |     if radius != 0: | 
					
						
							| 
									
										
										
										
											2023-11-23 22:08:33 +01:00
										 |  |  |         # Set coordinates for arcs | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |         c1, c2 = (x, y), (x + diameter, y + diameter) | 
					
						
							|  |  |  |         c3, c4 = ((x + width) - diameter, y), (x + width, y + diameter) | 
					
						
							|  |  |  |         c5, c6 = ((x + width) - diameter, (y + height) - diameter), (x + width, y + height) | 
					
						
							|  |  |  |         c7, c8 = (x, (y + height) - diameter), (x + diameter, y + height) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-23 22:08:33 +01:00
										 |  |  |     # Draw lines and arcs, creating a square with round corners | 
					
						
							|  |  |  |     draw = ImageDraw.Draw(image) | 
					
						
							|  |  |  |     draw.line((p1, p2), fill=colour, width=thickness) | 
					
						
							|  |  |  |     draw.line((p3, p4), fill=colour, width=thickness) | 
					
						
							|  |  |  |     draw.line((p5, p6), fill=colour, width=thickness) | 
					
						
							|  |  |  |     draw.line((p7, p8), fill=colour, width=thickness) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if radius != 0: | 
					
						
							| 
									
										
										
										
											2022-04-02 01:30:17 +02:00
										 |  |  |         draw.arc((c1, c2), 180, 270, fill=colour, width=thickness) | 
					
						
							|  |  |  |         draw.arc((c3, c4), 270, 360, fill=colour, width=thickness) | 
					
						
							|  |  |  |         draw.arc((c5, c6), 0, 90, fill=colour, width=thickness) | 
					
						
							|  |  |  |         draw.arc((c7, c8), 90, 180, fill=colour, width=thickness) | 
					
						
							| 
									
										
										
										
											2023-11-24 02:37:27 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-14 01:51:10 +01:00
										 |  |  | def draw_border_2(im: PIL.Image, xy: tuple, size: tuple, radius: int): | 
					
						
							| 
									
										
										
										
											2023-11-24 02:37:27 +01:00
										 |  |  |     draw = ImageDraw.Draw(im) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     x, y = xy | 
					
						
							|  |  |  |     w, h = size | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-14 01:51:10 +01:00
										 |  |  |     draw.rounded_rectangle(xy=(x, y, x + w, y + h), outline="black", radius=radius) |