TouchPortalAPI v1.7.8
TouchPortalAPI.tools
1__copyright__ = """ 2 This file is part of the TouchPortal-API project. 3 Copyright (c) TouchPortal-API Developers/Contributors 4 Copyright (C) 2021 DamienS 5 All rights reserved. 6 7 This program is free software: you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation, either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <https://www.gnu.org/licenses/>. 19""" 20 21import os 22import base64 23import requests 24from types import SimpleNamespace 25 26class Tools(): 27 """ 28 A collection of utilities which may be useful for Touch Portal plugins at runtime. 29 """ 30 31 @staticmethod 32 def convertImage_to_base64(image, type="Auto", image_formats=["image/png", "image/jpeg", "image/jpg"]): 33 """ 34 Returns a Base64-encoded representation of an image. 35 36 Args: 37 `image` can be a URL or file path. 38 `type` can be "Auto", "Web" (for URL), or "Local" (for file path). 39 `image_formats` is a list of one or more MIME types to accept, used only with URLs to confirm the response is valid. 40 41 Raises: 42 `TypeError`: If URL request returns an invalid MIME type. 43 `ValueError`: In other cases such as invalid URL or file path. 44 """ 45 data = None 46 if type == "Auto" or type == "Web": 47 try: 48 r = requests.head(image) 49 if r.headers.get('content-type', 'image/png' if type == "Web" else '') in image_formats: 50 data = requests.get(image).content 51 else: 52 raise TypeError(f"Returned image content type ({r.headers['content-type']}) is not one of: {image_formats}") 53 except ValueError: # raised by requests module for invalid URLs, less generic than requests.RequestException 54 if type == "Auto": 55 pass 56 else: 57 raise 58 if not data and (type == "Auto" or type == "Local") and os.path.isfile(image): 59 with open(image, "rb") as img_file: 60 data = img_file.read() 61 if data: 62 return base64.b64encode(data).decode('ascii') 63 raise ValueError(f"'{image}' is neither a valid URL nor an existing file.") 64 65 @staticmethod 66 def updateCheck(name, repository): 67 """ 68 Returns the newest tag name from a GitHub repository. 69 70 Args: 71 `name`: the GitHub user name for the URL path. 72 `repository`: the GitHub repository name for the URL path. 73 74 Raises: 75 `ValueError`: If the repository URL can't be reached, doesn't exist, or doesn't have any tags. 76 """ 77 baselink = f'https://api.github.com/repos/{name}/{repository}/tags' 78 if (r := requests.get(baselink)) and r.ok: 79 if (js := r.json()): 80 return js[0].get('name', "") 81 raise ValueError(f'No tags found in repository: {baselink}') 82 else: 83 raise ValueError(f'Invalid repository URL or response: {baselink}') 84 85 @staticmethod 86 def nested_conversion(value): 87 """ 88 Convert dictionary to object for easier access data. 89 Examples 90 `data = {"car": {"year": 2008, "name": "Tesla"}}` # try get name 91 92 instead of this `data['car']['name']` you can get name this way 93 94 data = Tools.nested_conversion(data) 95 96 `data.car.name` 97 98 Args: 99 `value`: any dictionary 100 """ 101 if not isinstance(value, dict): 102 return value 103 104 return SimpleNamespace(**{key: Tools.nested_conversion(value) for key, value in value.items()})
class
Tools:
27class Tools(): 28 """ 29 A collection of utilities which may be useful for Touch Portal plugins at runtime. 30 """ 31 32 @staticmethod 33 def convertImage_to_base64(image, type="Auto", image_formats=["image/png", "image/jpeg", "image/jpg"]): 34 """ 35 Returns a Base64-encoded representation of an image. 36 37 Args: 38 `image` can be a URL or file path. 39 `type` can be "Auto", "Web" (for URL), or "Local" (for file path). 40 `image_formats` is a list of one or more MIME types to accept, used only with URLs to confirm the response is valid. 41 42 Raises: 43 `TypeError`: If URL request returns an invalid MIME type. 44 `ValueError`: In other cases such as invalid URL or file path. 45 """ 46 data = None 47 if type == "Auto" or type == "Web": 48 try: 49 r = requests.head(image) 50 if r.headers.get('content-type', 'image/png' if type == "Web" else '') in image_formats: 51 data = requests.get(image).content 52 else: 53 raise TypeError(f"Returned image content type ({r.headers['content-type']}) is not one of: {image_formats}") 54 except ValueError: # raised by requests module for invalid URLs, less generic than requests.RequestException 55 if type == "Auto": 56 pass 57 else: 58 raise 59 if not data and (type == "Auto" or type == "Local") and os.path.isfile(image): 60 with open(image, "rb") as img_file: 61 data = img_file.read() 62 if data: 63 return base64.b64encode(data).decode('ascii') 64 raise ValueError(f"'{image}' is neither a valid URL nor an existing file.") 65 66 @staticmethod 67 def updateCheck(name, repository): 68 """ 69 Returns the newest tag name from a GitHub repository. 70 71 Args: 72 `name`: the GitHub user name for the URL path. 73 `repository`: the GitHub repository name for the URL path. 74 75 Raises: 76 `ValueError`: If the repository URL can't be reached, doesn't exist, or doesn't have any tags. 77 """ 78 baselink = f'https://api.github.com/repos/{name}/{repository}/tags' 79 if (r := requests.get(baselink)) and r.ok: 80 if (js := r.json()): 81 return js[0].get('name', "") 82 raise ValueError(f'No tags found in repository: {baselink}') 83 else: 84 raise ValueError(f'Invalid repository URL or response: {baselink}') 85 86 @staticmethod 87 def nested_conversion(value): 88 """ 89 Convert dictionary to object for easier access data. 90 Examples 91 `data = {"car": {"year": 2008, "name": "Tesla"}}` # try get name 92 93 instead of this `data['car']['name']` you can get name this way 94 95 data = Tools.nested_conversion(data) 96 97 `data.car.name` 98 99 Args: 100 `value`: any dictionary 101 """ 102 if not isinstance(value, dict): 103 return value 104 105 return SimpleNamespace(**{key: Tools.nested_conversion(value) for key, value in value.items()})
A collection of utilities which may be useful for Touch Portal plugins at runtime.
@staticmethod
def
convertImage_to_base64( image, type='Auto', image_formats=['image/png', 'image/jpeg', 'image/jpg'])
32 @staticmethod 33 def convertImage_to_base64(image, type="Auto", image_formats=["image/png", "image/jpeg", "image/jpg"]): 34 """ 35 Returns a Base64-encoded representation of an image. 36 37 Args: 38 `image` can be a URL or file path. 39 `type` can be "Auto", "Web" (for URL), or "Local" (for file path). 40 `image_formats` is a list of one or more MIME types to accept, used only with URLs to confirm the response is valid. 41 42 Raises: 43 `TypeError`: If URL request returns an invalid MIME type. 44 `ValueError`: In other cases such as invalid URL or file path. 45 """ 46 data = None 47 if type == "Auto" or type == "Web": 48 try: 49 r = requests.head(image) 50 if r.headers.get('content-type', 'image/png' if type == "Web" else '') in image_formats: 51 data = requests.get(image).content 52 else: 53 raise TypeError(f"Returned image content type ({r.headers['content-type']}) is not one of: {image_formats}") 54 except ValueError: # raised by requests module for invalid URLs, less generic than requests.RequestException 55 if type == "Auto": 56 pass 57 else: 58 raise 59 if not data and (type == "Auto" or type == "Local") and os.path.isfile(image): 60 with open(image, "rb") as img_file: 61 data = img_file.read() 62 if data: 63 return base64.b64encode(data).decode('ascii') 64 raise ValueError(f"'{image}' is neither a valid URL nor an existing file.")
Returns a Base64-encoded representation of an image.
Args
image
can be a URL or file path.type
can be "Auto", "Web" (for URL), or "Local" (for file path).image_formats
is a list of one or more MIME types to accept, used only with URLs to confirm the response is valid.
Raises
TypeError
: If URL request returns an invalid MIME type.ValueError
: In other cases such as invalid URL or file path.
@staticmethod
def
updateCheck(name, repository)
66 @staticmethod 67 def updateCheck(name, repository): 68 """ 69 Returns the newest tag name from a GitHub repository. 70 71 Args: 72 `name`: the GitHub user name for the URL path. 73 `repository`: the GitHub repository name for the URL path. 74 75 Raises: 76 `ValueError`: If the repository URL can't be reached, doesn't exist, or doesn't have any tags. 77 """ 78 baselink = f'https://api.github.com/repos/{name}/{repository}/tags' 79 if (r := requests.get(baselink)) and r.ok: 80 if (js := r.json()): 81 return js[0].get('name', "") 82 raise ValueError(f'No tags found in repository: {baselink}') 83 else: 84 raise ValueError(f'Invalid repository URL or response: {baselink}')
Returns the newest tag name from a GitHub repository.
Args
name
: the GitHub user name for the URL path.repository
: the GitHub repository name for the URL path.
Raises
ValueError
: If the repository URL can't be reached, doesn't exist, or doesn't have any tags.
@staticmethod
def
nested_conversion(value)
86 @staticmethod 87 def nested_conversion(value): 88 """ 89 Convert dictionary to object for easier access data. 90 Examples 91 `data = {"car": {"year": 2008, "name": "Tesla"}}` # try get name 92 93 instead of this `data['car']['name']` you can get name this way 94 95 data = Tools.nested_conversion(data) 96 97 `data.car.name` 98 99 Args: 100 `value`: any dictionary 101 """ 102 if not isinstance(value, dict): 103 return value 104 105 return SimpleNamespace(**{key: Tools.nested_conversion(value) for key, value in value.items()})
Convert dictionary to object for easier access data.
Examples
data = {"car": {"year": 2008, "name": "Tesla"}}
# try get name
instead of this `data['car']['name']` you can get name this way
data = Tools.nested_conversion(data)
`data.car.name`
Args
value
: any dictionary