From e52727b95028fda7092d69ef8c65b268736f4673 Mon Sep 17 00:00:00 2001 From: RaiBnod Date: Wed, 27 Nov 2024 13:08:00 +0545 Subject: [PATCH 1/5] Turn ON debug mode --- run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run.py b/run.py index 9253cae..41a96b2 100644 --- a/run.py +++ b/run.py @@ -178,7 +178,7 @@ def read_ai_all(): if __name__ == '__main__': - app.run(host='0.0.0.0', port = api_port) + app.run(host='0.0.0.0', port = api_port, debug=True) # # # READ ALL DOs From 0c7104ca03698deae502e3a871a83f739c272ab7 Mon Sep 17 00:00:00 2001 From: RaiBnod Date: Wed, 27 Nov 2024 13:08:46 +0545 Subject: [PATCH 2/5] Release v0.0.3-rc.1 --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bebb748..1dc9f7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,7 @@ # CHANGELOG +## [v0.0.3-rc.1](https://github.com/NubeIO/bbb-py-rest/tree/v0.0.3-rc.1) (2024-11-27) +- Turn ON debug mode + ## [v0.0.2](https://github.com/NubeIO/bbb-py-rest/tree/v0.0.2) (2022-04-07) - Fix: io-calibration.json copy From 4422308d8147994df7617259bcb0d11ed8c8a1ee Mon Sep 17 00:00:00 2001 From: RaiBnod Date: Wed, 27 Nov 2024 13:13:11 +0545 Subject: [PATCH 3/5] Fix poetry installation --- docker/Dockerfile | 6 +- docker/get-poetry.py | 1164 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1168 insertions(+), 2 deletions(-) create mode 100644 docker/get-poetry.py diff --git a/docker/Dockerfile b/docker/Dockerfile index e07758b..4f69200 100755 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -2,8 +2,10 @@ ARG BASE_IMAGE_VERSION FROM python:$BASE_IMAGE_VERSION-slim-buster as build RUN apt update -qq \ - && apt install git curl gcc g++ make file musl-dev libffi6 libffi-dev zlib1g zlib1g-dev -y \ - && curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python + && apt install git curl gcc g++ make file musl-dev libffi-dev zlib1g zlib1g-dev libpq-dev -y + +COPY docker/get-poetry.py get-poetry.py +RUN POETRY_VERSION=1.1.13 python3 get-poetry.py WORKDIR /usr/src/app/ ADD poetry.lock pyproject.toml ./ diff --git a/docker/get-poetry.py b/docker/get-poetry.py new file mode 100644 index 0000000..e3ec494 --- /dev/null +++ b/docker/get-poetry.py @@ -0,0 +1,1164 @@ +""" +This script will install Poetry and its dependencies +in isolation from the rest of the system. + +It does, in order: + + - Downloads the latest stable (or pre-release) version of poetry. + - Downloads all its dependencies in the poetry/_vendor directory. + - Copies it and all extra files in $POETRY_HOME. + - Updates the PATH in a system-specific way. + +There will be a `poetry` script that will be installed in $POETRY_HOME/bin +which will act as the poetry command but is slightly different in the sense +that it will use the current Python installation. + +What this means is that one Poetry installation can serve for multiple +Python versions. +""" +import argparse +import hashlib +import json +import os +import platform +import re +import shutil +import stat +import subprocess +import sys +import tarfile +import tempfile + +from contextlib import closing +from contextlib import contextmanager +from functools import cmp_to_key +from gzip import GzipFile +from io import UnsupportedOperation +from io import open + +try: + from urllib.error import HTTPError + from urllib.request import Request + from urllib.request import urlopen +except ImportError: + from urllib2 import HTTPError + from urllib2 import Request + from urllib2 import urlopen + +try: + input = raw_input +except NameError: + pass + +try: + try: + import winreg + except ImportError: + import _winreg as winreg +except ImportError: + winreg = None + +try: + u = unicode +except NameError: + u = str + +SHELL = os.getenv("SHELL", "") +WINDOWS = sys.platform.startswith("win") or (sys.platform == "cli" and os.name == "nt") + +FOREGROUND_COLORS = { + "black": 30, + "red": 31, + "green": 32, + "yellow": 33, + "blue": 34, + "magenta": 35, + "cyan": 36, + "white": 37, +} + +BACKGROUND_COLORS = { + "black": 40, + "red": 41, + "green": 42, + "yellow": 43, + "blue": 44, + "magenta": 45, + "cyan": 46, + "white": 47, +} + +OPTIONS = {"bold": 1, "underscore": 4, "blink": 5, "reverse": 7, "conceal": 8} + + +def style(fg, bg, options): + codes = [] + + if fg: + codes.append(FOREGROUND_COLORS[fg]) + + if bg: + codes.append(BACKGROUND_COLORS[bg]) + + if options: + if not isinstance(options, (list, tuple)): + options = [options] + + for option in options: + codes.append(OPTIONS[option]) + + return "\033[{}m".format(";".join(map(str, codes))) + + +STYLES = { + "info": style("green", None, None), + "comment": style("yellow", None, None), + "error": style("red", None, None), + "warning": style("yellow", None, None), + "deprecation": style("magenta", None, None), +} + + +def is_decorated(): + if platform.system().lower() == "windows": + return ( + os.getenv("ANSICON") is not None + or os.getenv("ConEmuANSI") == "ON" + or os.getenv("Term") == "xterm" + ) + + if not hasattr(sys.stdout, "fileno"): + return False + + try: + return os.isatty(sys.stdout.fileno()) + except UnsupportedOperation: + return False + + +def is_interactive(): + if not hasattr(sys.stdin, "fileno"): + return False + + try: + return os.isatty(sys.stdin.fileno()) + except UnsupportedOperation: + return False + + +def colorize(style, text): + if not is_decorated(): + return text + + return "{}{}\033[0m".format(STYLES[style], text) + + +@contextmanager +def temporary_directory(*args, **kwargs): + try: + from tempfile import TemporaryDirectory + except ImportError: + name = tempfile.mkdtemp(*args, **kwargs) + + yield name + + shutil.rmtree(name) + else: + with TemporaryDirectory(*args, **kwargs) as name: + yield name + + +def string_to_bool(value): + value = value.lower() + + return value in {"true", "1", "y", "yes"} + + +def expanduser(path): + """ + Expand ~ and ~user constructions. + + Includes a workaround for http://bugs.python.org/issue14768 + """ + expanded = os.path.expanduser(path) + if path.startswith("~/") and expanded.startswith("//"): + expanded = expanded[1:] + + return expanded + + +HOME = expanduser("~") +POETRY_HOME = os.environ.get("POETRY_HOME") or os.path.join(HOME, ".poetry") +POETRY_BIN = os.path.join(POETRY_HOME, "bin") +POETRY_ENV = os.path.join(POETRY_HOME, "env") +POETRY_LIB = os.path.join(POETRY_HOME, "lib") +POETRY_LIB_BACKUP = os.path.join(POETRY_HOME, "lib-backup") + +BIN = """# -*- coding: utf-8 -*- +import glob +import sys +import os + +lib = os.path.normpath(os.path.join(os.path.realpath(__file__), "../..", "lib")) +vendors = os.path.join(lib, "poetry", "_vendor") +current_vendors = os.path.join( + vendors, "py{}".format(".".join(str(v) for v in sys.version_info[:2])) +) + +sys.path.insert(0, lib) +sys.path.insert(0, current_vendors) + +if __name__ == "__main__": + from poetry.console import main + + main() +""" + +BAT = u('@echo off\r\n{python_executable} "{poetry_bin}" %*\r\n') + +PRE_MESSAGE = """# Welcome to {poetry}! + +This will download and install the latest version of {poetry}, +a dependency and package manager for Python. + +It will add the `poetry` command to {poetry}'s bin directory, located at: + +{poetry_home_bin} + +{platform_msg} + +You can uninstall at any time by executing this script with the --uninstall option, +and these changes will be reverted. +""" + +PRE_UNINSTALL_MESSAGE = """# We are sorry to see you go! + +This will uninstall {poetry}. + +It will remove the `poetry` command from {poetry}'s bin directory, located at: + +{poetry_home_bin} + +This will also remove {poetry} from your system's PATH. +""" + +PRE_MESSAGE_UNIX = """This path will then be added to your `PATH` environment variable by +modifying the profile file{plural} located at: + +{rcfiles}""" + +PRE_MESSAGE_FISH = """This path will then be added to your `PATH` environment variable by +modifying the `fish_user_paths` universal variable.""" + +PRE_MESSAGE_WINDOWS = """This path will then be added to your `PATH` environment variable by +modifying the `HKEY_CURRENT_USER/Environment/PATH` registry key.""" + +PRE_MESSAGE_NO_MODIFY_PATH = """This path needs to be in your `PATH` environment variable, +but will not be added automatically.""" + +POST_MESSAGE_UNIX = """{poetry} ({version}) is installed now. Great! + +To get started you need {poetry}'s bin directory ({poetry_home_bin}) in your `PATH` +environment variable. Next time you log in this will be done +automatically. + +To configure your current shell run `source {poetry_home_env}` +""" + +POST_MESSAGE_FISH = """{poetry} ({version}) is installed now. Great! + +{poetry}'s bin directory ({poetry_home_bin}) has been added to your `PATH` +environment variable by modifying the `fish_user_paths` universal variable. +""" + +POST_MESSAGE_WINDOWS = """{poetry} ({version}) is installed now. Great! + +To get started you need Poetry's bin directory ({poetry_home_bin}) in your `PATH` +environment variable. Future applications will automatically have the +correct environment, but you may need to restart your current shell. +""" + +POST_MESSAGE_UNIX_NO_MODIFY_PATH = """{poetry} ({version}) is installed now. Great! + +To get started you need {poetry}'s bin directory ({poetry_home_bin}) in your `PATH` +environment variable. + +To configure your current shell run `source {poetry_home_env}` +""" + +POST_MESSAGE_FISH_NO_MODIFY_PATH = """{poetry} ({version}) is installed now. Great! + +To get started you need {poetry}'s bin directory ({poetry_home_bin}) +in your `PATH` environment variable, which you can add by running +the following command: + + set -U fish_user_paths {poetry_home_bin} $fish_user_paths +""" + +POST_MESSAGE_WINDOWS_NO_MODIFY_PATH = """{poetry} ({version}) is installed now. Great! + +To get started you need Poetry's bin directory ({poetry_home_bin}) in your `PATH` +environment variable. This has not been done automatically. +""" + + +class Installer: + CURRENT_PYTHON = sys.executable + CURRENT_PYTHON_VERSION = sys.version_info[:2] + METADATA_URL = "https://pypi.org/pypi/poetry/json" + VERSION_REGEX = re.compile( + r"v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+))?" + "(" + "[._-]?" + r"(?:(stable|beta|b|rc|RC|alpha|a|patch|pl|p)((?:[.-]?\d+)*)?)?" + "([.-]?dev)?" + ")?" + r"(?:\+[^\s]+)?" + ) + + REPOSITORY_URL = "https://github.com/python-poetry/poetry" + BASE_URL = REPOSITORY_URL + "/releases/download/" + FALLBACK_BASE_URL = "https://github.com/sdispater/poetry/releases/download/" + + def __init__( + self, + version=None, + preview=False, + force=False, + modify_path=True, + accept_all=False, + file=None, + base_url=BASE_URL, + ): + self._version = version + self._preview = preview + self._force = force + self._modify_path = modify_path + self._accept_all = accept_all + self._offline_file = file + self._base_url = base_url + + def allows_prereleases(self): + return self._preview + + def run(self): + version, current_version = self.get_version() + + if version is None: + return 1 + + self.customize_install() + self.display_pre_message() + self.ensure_home() + + try: + self.install( + version, upgrade=current_version is not None, file=self._offline_file + ) + except subprocess.CalledProcessError as e: + print(colorize("error", "An error has occurred: {}".format(str(e)))) + print(e.output.decode()) + + return e.returncode + + self.display_post_message(version) + + return 0 + + def uninstall(self): + self.display_pre_uninstall_message() + + if not self.customize_uninstall(): + return + + self.remove_home() + self.remove_from_path() + + def get_version(self): + current_version = None + if os.path.exists(POETRY_LIB): + with open( + os.path.join(POETRY_LIB, "poetry", "__version__.py"), encoding="utf-8" + ) as f: + version_content = f.read() + + current_version_re = re.match( + '(?ms).*__version__ = "(.+)".*', version_content + ) + if not current_version_re: + print( + colorize( + "warning", + "Unable to get the current Poetry version. Assuming None", + ) + ) + else: + current_version = current_version_re.group(1) + + # Skip retrieving online release versions if install file is specified + if self._offline_file is not None: + if current_version is not None and not self._force: + print("There is a version of Poetry already installed.") + return None, current_version + + return "from an offline file", current_version + + print(colorize("info", "Retrieving Poetry metadata")) + + metadata = json.loads(self._get(self.METADATA_URL).decode()) + + def _compare_versions(x, y): + mx = self.VERSION_REGEX.match(x) + my = self.VERSION_REGEX.match(y) + + vx = tuple(int(p) for p in mx.groups()[:3]) + (mx.group(5),) + vy = tuple(int(p) for p in my.groups()[:3]) + (my.group(5),) + + if vx < vy: + return -1 + elif vx > vy: + return 1 + + return 0 + + print("") + releases = sorted( + metadata["releases"].keys(), key=cmp_to_key(_compare_versions) + ) + + if self._version and self._version not in releases: + print(colorize("error", "Version {} does not exist.".format(self._version))) + + return None, None + + def _is_supported(x): + mx = self.VERSION_REGEX.match(x) + vx = tuple(int(p) for p in mx.groups()[:3]) + (mx.group(5),) + return vx < (1, 2, 0) + + print( + colorize( + "deprecation", + ( + "This installer is deprecated, and scheduled for removal from the" + " Poetry repository on or after January 1, 2023.\nSee" + " https://github.com/python-poetry/poetry/issues/6377 for" + " details.\n\nYou should migrate to" + " https://install.python-poetry.org instead, which supports all" + " versions of Poetry, and allows for `self update` of versions" + " 1.1.7 or newer.\nInstructions are available at" + " https://python-poetry.org/docs/#installation.\n" + ), + ) + ) + + if not os.environ.get("GET_POETRY_IGNORE_DEPRECATION") and not self._version: + print( + colorize( + "deprecation", + ( + "Without an explicit version, this installer will attempt to" + " install the latest version of Poetry.\nThis installer cannot" + " install Poetry 1.2.0a1 or newer (and installs will be unable" + " to `self update` to 1.2.0a1 or newer).\n\nTo continue to use" + " this deprecated installer, you must specify an explicit" + " version with --version or" + " POETRY_VERSION=.\nAlternatively, if you wish to" + " force this deprecated installer to use the latest installable" + " release, set GET_POETRY_IGNORE_DEPRECATION=1.\n" + ), + ) + ) + + version = self._version + if not version: + for release in reversed(releases): + m = self.VERSION_REGEX.match(release) + if m.group(5) and not self.allows_prereleases(): + continue + + if not os.environ.get("GET_POETRY_IGNORE_DEPRECATION"): + version = release + break + else: + if _is_supported(release): + print( + colorize( + "warning", + "Version {release} will be installed as it is the" + " latest version supported by this installer.\n\nThis" + " is not the latest version of Poetry! If you wish to" + " install the latest version, you must move to the new" + " installer as described above!\n".format( + release=release + ), + ) + ) + version = release + break + else: + print( + colorize( + "warning", + "Version {release} is available but is not supported by" + " this installer!".format(release=release), + ) + ) + + if not _is_supported(version): + print( + colorize( + "error", + "Version {version} is not supported by this installer! Please" + " specify a version prior to 1.2.0a1 to continue!".format( + version=version + ), + ) + ) + + return None, None + + current_version = None + if os.path.exists(POETRY_LIB): + with open( + os.path.join(POETRY_LIB, "poetry", "__version__.py"), encoding="utf-8" + ) as f: + version_content = f.read() + + current_version_re = re.match( + '(?ms).*__version__ = "(.+)".*', version_content + ) + if not current_version_re: + print( + colorize( + "warning", + "Unable to get the current Poetry version. Assuming None", + ) + ) + else: + current_version = current_version_re.group(1) + + if current_version == version and not self._force: + print("Latest version already installed.") + return None, current_version + + return version, current_version + + def customize_install(self): + if not self._accept_all: + print("Before we start, please answer the following questions.") + print("You may simply press the Enter key to leave unchanged.") + + modify_path = input("Modify PATH variable? ([y]/n) ") or "y" + if modify_path.lower() in {"n", "no"}: + self._modify_path = False + + print("") + + def customize_uninstall(self): + if not self._accept_all: + print() + + uninstall = ( + input("Are you sure you want to uninstall Poetry? (y/[n]) ") or "n" + ) + if uninstall.lower() not in {"y", "yes"}: + return False + + print("") + + return True + + def ensure_home(self): + """ + Ensures that $POETRY_HOME exists or create it. + """ + if not os.path.exists(POETRY_HOME): + os.mkdir(POETRY_HOME, 0o755) + + def remove_home(self): + """ + Removes $POETRY_HOME. + """ + if not os.path.exists(POETRY_HOME): + return + + shutil.rmtree(POETRY_HOME) + + def install(self, version, upgrade=False, file=None): + """ + Installs Poetry in $POETRY_HOME. + """ + if file is not None: + print("Attempting to install from file: " + colorize("info", file)) + else: + print("Installing version: " + colorize("info", version)) + + self.make_lib(version) + self.make_bin() + self.make_env() + self.update_path() + + return 0 + + def make_lib(self, version): + """ + Packs everything into a single lib/ directory. + """ + if os.path.exists(POETRY_LIB_BACKUP): + shutil.rmtree(POETRY_LIB_BACKUP) + + # Backup the current installation + if os.path.exists(POETRY_LIB): + shutil.copytree(POETRY_LIB, POETRY_LIB_BACKUP) + shutil.rmtree(POETRY_LIB) + + try: + self._make_lib(version) + except Exception: + if not os.path.exists(POETRY_LIB_BACKUP): + raise + + shutil.copytree(POETRY_LIB_BACKUP, POETRY_LIB) + shutil.rmtree(POETRY_LIB_BACKUP) + + raise + finally: + if os.path.exists(POETRY_LIB_BACKUP): + shutil.rmtree(POETRY_LIB_BACKUP) + + def _make_lib(self, version): + # Check if an offline installer file has been specified + if self._offline_file is not None: + try: + self.extract_lib(self._offline_file) + return + except Exception: + raise RuntimeError("Could not install from offline file.") + + # We get the payload from the remote host + platform = sys.platform + if platform == "linux2": + platform = "linux" + + url = self._base_url + "{}/".format(version) + name = "poetry-{}-{}.tar.gz".format(version, platform) + checksum = "poetry-{}-{}.sha256sum".format(version, platform) + + try: + r = urlopen(url + "{}".format(checksum)) + except HTTPError as e: + if e.code == 404: + raise RuntimeError("Could not find {} file".format(checksum)) + + raise + + checksum = r.read().decode() + + try: + r = urlopen(url + "{}".format(name)) + except HTTPError as e: + if e.code == 404: + raise RuntimeError("Could not find {} file".format(name)) + + raise + + meta = r.info() + size = int(meta["Content-Length"]) + current = 0 + block_size = 8192 + + print( + " - Downloading {} ({:.2f}MB)".format( + colorize("comment", name), size / 1024 / 1024 + ) + ) + + sha = hashlib.sha256() + with temporary_directory(prefix="poetry-installer-") as dir_: + tar = os.path.join(dir_, name) + with open(tar, "wb") as f: + while True: + buffer = r.read(block_size) + if not buffer: + break + + current += len(buffer) + f.write(buffer) + sha.update(buffer) + + # Checking hashes + if checksum != sha.hexdigest(): + raise RuntimeError( + "Hashes for {} do not match: {} != {}".format( + name, checksum, sha.hexdigest() + ) + ) + + self.extract_lib(tar) + + def extract_lib(self, filename): + gz = GzipFile(filename, mode="rb") + try: + with tarfile.TarFile(filename, fileobj=gz, format=tarfile.PAX_FORMAT) as f: + f.extractall(POETRY_LIB) + finally: + gz.close() + + def _which_python(self): + """Decides which python executable we'll embed in the launcher script.""" + allowed_executables = ["python3", "python"] + if WINDOWS: + allowed_executables += ["py.exe -3", "py.exe -2"] + + # \d in regex ensures we can convert to int later + version_matcher = re.compile(r"^Python (?P\d+)\.(?P\d+)\..+$") + fallback = None + for executable in allowed_executables: + try: + raw_version = subprocess.check_output( + executable + " --version", stderr=subprocess.STDOUT, shell=True + ).decode("utf-8") + except subprocess.CalledProcessError: + continue + + match = version_matcher.match(raw_version.strip()) + if match: + return executable + + if fallback is None: + # keep this one as the fallback; it was the first valid executable we + # found. + fallback = executable + + if fallback is None: + raise RuntimeError( + "No python executable found in shell environment. Tried: " + + str(allowed_executables) + ) + + return fallback + + def make_bin(self): + if not os.path.exists(POETRY_BIN): + os.mkdir(POETRY_BIN, 0o755) + + python_executable = self._which_python() + + if WINDOWS: + with open(os.path.join(POETRY_BIN, "poetry.bat"), "w") as f: + f.write( + u( + BAT.format( + python_executable=python_executable, + poetry_bin=os.path.join(POETRY_BIN, "poetry").replace( + os.environ["USERPROFILE"], "%USERPROFILE%" + ), + ) + ) + ) + + with open(os.path.join(POETRY_BIN, "poetry"), "w", encoding="utf-8") as f: + if WINDOWS: + python_executable = "python" + + f.write(u("#!/usr/bin/env {}\n".format(python_executable))) + f.write(u(BIN)) + + if not WINDOWS: + # Making the file executable + st = os.stat(os.path.join(POETRY_BIN, "poetry")) + os.chmod(os.path.join(POETRY_BIN, "poetry"), st.st_mode | stat.S_IEXEC) + + def make_env(self): + if WINDOWS: + return + + with open(os.path.join(POETRY_HOME, "env"), "w") as f: + f.write(u(self.get_export_string())) + + def update_path(self): + """ + Tries to update the $PATH automatically. + """ + if not self._modify_path: + return + + if "fish" in SHELL: + return self.add_to_fish_path() + + if WINDOWS: + return self.add_to_windows_path() + + # Updating any profile we can on UNIX systems + export_string = self.get_export_string() + + addition = "\n{}\n".format(export_string) + + profiles = self.get_unix_profiles() + for profile in profiles: + if not os.path.exists(profile): + continue + + with open(profile, "r") as f: + content = f.read() + + if addition not in content: + with open(profile, "a") as f: + f.write(u(addition)) + + def add_to_fish_path(self): + """ + Ensure POETRY_BIN directory is on Fish shell $PATH + """ + current_path = os.environ.get("PATH", None) + if current_path is None: + print( + colorize( + "warning", + ( + "\nUnable to get the PATH value. It will not be updated" + " automatically." + ), + ) + ) + self._modify_path = False + + return + + if POETRY_BIN not in current_path: + fish_user_paths = subprocess.check_output( + ["fish", "-c", "echo $fish_user_paths"] + ).decode("utf-8") + if POETRY_BIN not in fish_user_paths: + cmd = "set -U fish_user_paths {} $fish_user_paths".format(POETRY_BIN) + set_fish_user_path = ["fish", "-c", "{}".format(cmd)] + subprocess.check_output(set_fish_user_path) + else: + print( + colorize( + "warning", + "\nPATH already contains {} and thus was not modified.".format( + POETRY_BIN + ), + ) + ) + + def add_to_windows_path(self): + try: + old_path = self.get_windows_path_var() + except WindowsError: + old_path = None + + if old_path is None: + print( + colorize( + "warning", + ( + "Unable to get the PATH value. It will not be updated" + " automatically" + ), + ) + ) + self._modify_path = False + + return + + new_path = POETRY_BIN + if POETRY_BIN in old_path: + old_path = old_path.replace(POETRY_BIN + ";", "") + + if old_path: + new_path += ";" + new_path += old_path + + self.set_windows_path_var(new_path) + + def get_windows_path_var(self): + with winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER) as root: + with winreg.OpenKey(root, "Environment", 0, winreg.KEY_ALL_ACCESS) as key: + path, _ = winreg.QueryValueEx(key, "PATH") + + return path + + def set_windows_path_var(self, value): + import ctypes + + with winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER) as root: + with winreg.OpenKey(root, "Environment", 0, winreg.KEY_ALL_ACCESS) as key: + winreg.SetValueEx(key, "PATH", 0, winreg.REG_EXPAND_SZ, value) + + # Tell other processes to update their environment + HWND_BROADCAST = 0xFFFF + WM_SETTINGCHANGE = 0x1A + + SMTO_ABORTIFHUNG = 0x0002 + + result = ctypes.c_long() + SendMessageTimeoutW = ctypes.windll.user32.SendMessageTimeoutW + SendMessageTimeoutW( + HWND_BROADCAST, + WM_SETTINGCHANGE, + 0, + "Environment", + SMTO_ABORTIFHUNG, + 5000, + ctypes.byref(result), + ) + + def remove_from_path(self): + if "fish" in SHELL: + return self.remove_from_fish_path() + + elif WINDOWS: + return self.remove_from_windows_path() + + return self.remove_from_unix_path() + + def remove_from_fish_path(self): + fish_user_paths = subprocess.check_output( + ["fish", "-c", "echo $fish_user_paths"] + ).decode("utf-8") + if POETRY_BIN in fish_user_paths: + cmd = "set -U fish_user_paths (string match -v {} $fish_user_paths)".format( + POETRY_BIN + ) + set_fish_user_path = ["fish", "-c", "{}".format(cmd)] + subprocess.check_output(set_fish_user_path) + + def remove_from_windows_path(self): + path = self.get_windows_path_var() + + poetry_path = POETRY_BIN + if poetry_path in path: + path = path.replace(POETRY_BIN + ";", "") + + if poetry_path in path: + path = path.replace(POETRY_BIN, "") + + self.set_windows_path_var(path) + + def remove_from_unix_path(self): + # Updating any profile we can on UNIX systems + export_string = self.get_export_string() + + addition = "{}\n".format(export_string) + + profiles = self.get_unix_profiles() + for profile in profiles: + if not os.path.exists(profile): + continue + + with open(profile, "r") as f: + content = f.readlines() + + if addition not in content: + continue + + new_content = [] + for line in content: + if line == addition: + if new_content and not new_content[-1].strip(): + new_content = new_content[:-1] + + continue + + new_content.append(line) + + with open(profile, "w") as f: + f.writelines(new_content) + + def get_export_string(self): + path = POETRY_BIN.replace(os.getenv("HOME", ""), "$HOME") + export_string = 'export PATH="{}:$PATH"'.format(path) + + return export_string + + def get_unix_profiles(self): + profiles = [os.path.join(HOME, ".profile")] + + if "zsh" in SHELL: + zdotdir = os.getenv("ZDOTDIR", HOME) + profiles.append(os.path.join(zdotdir, ".zshrc")) + + bash_profile = os.path.join(HOME, ".bash_profile") + if os.path.exists(bash_profile): + profiles.append(bash_profile) + + return profiles + + def display_pre_message(self): + if WINDOWS: + home = POETRY_BIN.replace(os.getenv("USERPROFILE", ""), "%USERPROFILE%") + else: + home = POETRY_BIN.replace(os.getenv("HOME", ""), "$HOME") + + kwargs = { + "poetry": colorize("info", "Poetry"), + "poetry_home_bin": colorize("comment", home), + } + + if not self._modify_path: + kwargs["platform_msg"] = PRE_MESSAGE_NO_MODIFY_PATH + else: + if "fish" in SHELL: + kwargs["platform_msg"] = PRE_MESSAGE_FISH + elif WINDOWS: + kwargs["platform_msg"] = PRE_MESSAGE_WINDOWS + else: + profiles = [ + colorize("comment", p.replace(os.getenv("HOME", ""), "$HOME")) + for p in self.get_unix_profiles() + ] + kwargs["platform_msg"] = PRE_MESSAGE_UNIX.format( + rcfiles="\n".join(profiles), plural="s" if len(profiles) > 1 else "" + ) + + print(PRE_MESSAGE.format(**kwargs)) + + def display_pre_uninstall_message(self): + home_bin = POETRY_BIN + if WINDOWS: + home_bin = home_bin.replace(os.getenv("USERPROFILE", ""), "%USERPROFILE%") + else: + home_bin = home_bin.replace(os.getenv("HOME", ""), "$HOME") + + kwargs = { + "poetry": colorize("info", "Poetry"), + "poetry_home_bin": colorize("comment", home_bin), + } + + print(PRE_UNINSTALL_MESSAGE.format(**kwargs)) + + def display_post_message(self, version): + print("") + + kwargs = { + "poetry": colorize("info", "Poetry"), + "version": colorize("comment", version), + } + + if WINDOWS: + message = POST_MESSAGE_WINDOWS + if not self._modify_path: + message = POST_MESSAGE_WINDOWS_NO_MODIFY_PATH + + poetry_home_bin = POETRY_BIN.replace( + os.getenv("USERPROFILE", ""), "%USERPROFILE%" + ) + elif "fish" in SHELL: + message = POST_MESSAGE_FISH + if not self._modify_path: + message = POST_MESSAGE_FISH_NO_MODIFY_PATH + + poetry_home_bin = POETRY_BIN.replace(os.getenv("HOME", ""), "$HOME") + else: + message = POST_MESSAGE_UNIX + if not self._modify_path: + message = POST_MESSAGE_UNIX_NO_MODIFY_PATH + + poetry_home_bin = POETRY_BIN.replace(os.getenv("HOME", ""), "$HOME") + kwargs["poetry_home_env"] = colorize( + "comment", POETRY_ENV.replace(os.getenv("HOME", ""), "$HOME") + ) + + kwargs["poetry_home_bin"] = colorize("comment", poetry_home_bin) + + print(message.format(**kwargs)) + + def call(self, *args): + return subprocess.check_output(args, stderr=subprocess.STDOUT) + + def _get(self, url): + request = Request(url, headers={"User-Agent": "Python Poetry"}) + + with closing(urlopen(request)) as r: + return r.read() + + +def main(): + parser = argparse.ArgumentParser( + description="Installs the latest (or given) version of poetry" + ) + parser.add_argument( + "-p", + "--preview", + help="install preview version", + dest="preview", + action="store_true", + default=False, + ) + parser.add_argument("--version", help="install named version", dest="version") + parser.add_argument( + "-f", + "--force", + help="install on top of existing version", + dest="force", + action="store_true", + default=False, + ) + parser.add_argument( + "--no-modify-path", + help="do not modify $PATH", + dest="no_modify_path", + action="store_true", + default=False, + ) + parser.add_argument( + "-y", + "--yes", + help="accept all prompts", + dest="accept_all", + action="store_true", + default=False, + ) + parser.add_argument( + "--uninstall", + help="uninstall poetry", + dest="uninstall", + action="store_true", + default=False, + ) + parser.add_argument( + "--file", + dest="file", + action="store", + help=( + "Install from a local file instead of fetching the latest version " + "of Poetry available online." + ), + ) + + args = parser.parse_args() + + base_url = Installer.BASE_URL + + if args.file is None: + try: + urlopen(Installer.REPOSITORY_URL) + except HTTPError as e: + if e.code == 404: + base_url = Installer.FALLBACK_BASE_URL + else: + raise + + installer = Installer( + version=args.version or os.getenv("POETRY_VERSION"), + preview=args.preview or string_to_bool(os.getenv("POETRY_PREVIEW", "0")), + force=args.force, + modify_path=not args.no_modify_path, + accept_all=args.accept_all + or string_to_bool(os.getenv("POETRY_ACCEPT", "0")) + or not is_interactive(), + file=args.file, + base_url=base_url, + ) + + if args.uninstall or string_to_bool(os.getenv("POETRY_UNINSTALL", "0")): + return installer.uninstall() + + return installer.run() + + +if __name__ == "__main__": + sys.exit(main()) From 84eb5e49f4318341cd71694e5a27485ef1065641 Mon Sep 17 00:00:00 2001 From: RaiBnod Date: Wed, 27 Nov 2024 14:40:38 +0545 Subject: [PATCH 4/5] Adding debugging points --- run.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/run.py b/run.py index 41a96b2..a295a95 100644 --- a/run.py +++ b/run.py @@ -11,13 +11,16 @@ app = Flask(__name__) # config uart pins +print("Configuring UART Pins") config_uart_pin() +print("UART Pins configured successfully") # BBB GPIO Lib import Adafruit_BBIO.GPIO as GPIO import Adafruit_BBIO.PWM as PWM import Adafruit_BBIO.ADC as ADC +print("Setting up PINS") # DOs GPIO.setup("P8_7", GPIO.OUT) GPIO.setup("P8_8", GPIO.OUT) @@ -49,9 +52,11 @@ # AIs ADC.setup() +print("PINS setup is successfully completed") + # API stuff api_ver = '1.1' # change version number as needed -api_port = 5000 # API PORT NUMBER +api_port = 5000 # API PORT NUMBER uo = 'uo' ui = 'ui' do = 'do' @@ -67,6 +72,12 @@ def not_found(error): return make_response(jsonify({'error': 'try again :('}), http_error) +@app.errorhandler(Exception) +def handle_exception(e): + logging.exception("Unhandled exception occurred") + return jsonify({'error': str(e)}), 500 + + # index page @app.route('/', methods=['GET']) def index_page(io_num=None, val=None): @@ -178,7 +189,7 @@ def read_ai_all(): if __name__ == '__main__': - app.run(host='0.0.0.0', port = api_port, debug=True) + app.run(host='0.0.0.0', port=api_port, debug=True) # # # READ ALL DOs From 4e518496839354896e681d68af76dd29505d40f8 Mon Sep 17 00:00:00 2001 From: RaiBnod Date: Wed, 27 Nov 2024 08:56:36 +0000 Subject: [PATCH 5/5] Correct version 0.0.3-rc.1 --- VERSION | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 7bcd0e3..2cae96c 100755 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.2 \ No newline at end of file +0.0.3-rc.1 \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 88e9d7a..db73d4b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "bbb-py-rest" -version = "0.0.2" +version = "0.0.3-rc.1" description = "Rubix Beaglebond Black App" authors = ["NubeDev "]