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.

Tools()
@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