diff --git a/pyproject.toml b/pyproject.toml index 3230c09..c833253 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,7 @@ +# vim: set ft=toml ts=4 sw=4 et: fenc=utf-8 +# SPDX-FileCopyrightText: 2025-present RenatoXSR +# SPDX-License-Identifier: BSD-3-Clause-Clear + [build-system] requires = ["setuptools>=61.0.0", "setuptools-scm[simple]>=9.2"] build-backend = "setuptools.build_meta" @@ -28,6 +32,7 @@ dependencies = [ "python-datauri", "rich", "Jinja2", + "base58", ] authors = [ @@ -54,12 +59,17 @@ Homepage = "https://git.silveirarosa.com/renatoxsr/monorepo" Issues = "https://git.silveirarosa.com/renatoxsr/monorepo/issues" [project.scripts] -composectl = "scripts.composectl.main" +composectl = "renatoxsr.scripts.composectl:main" # SETUPTOOLS [tool.setuptools.packages.find] -where = ["src/renatoxsr-py"] -exclude = ["src/vendor*"] +where = ["src-py"] +exclude = ["vendor*"] +# See: https://setuptools.pypa.io/en/latest/userguide/package_discovery.html#src-layout +# # Reserved package names +# FlatLayoutPackageFinder.DEFAULT_EXCLUDE: ClassVar[tuple[str, ...]] = ('ci', 'ci.*', 'bin', 'bin.*', 'debian', 'debian.*', 'doc', 'doc.*', 'docs', 'docs.*', 'documentation', 'documentation.*', 'manpages', 'manpages.*', 'news', 'news.*', 'newsfragments', 'newsfragments.*', 'changelog', 'changelog.*', 'test', 'test.*', 'tests', 'tests.*', 'unit_test', 'unit_test.*', 'unit_tests', 'unit_tests.*', 'example', 'example.*', 'examples', 'examples.*', 'scripts', 'scripts.*', 'tools', 'tools.*', 'util', 'util.*', 'utils', 'utils.*', 'python', 'python.*', 'build', 'build.*', 'dist', 'dist.*', 'venv', 'venv.*', 'env', 'env.*', 'requirements', 'requirements.*', 'tasks', 'tasks.*', 'fabfile', 'fabfile.*', 'site_scons', 'site_scons.*', 'benchmark', 'benchmark.*', 'benchmarks', 'benchmarks.*', 'exercise', 'exercise.*', 'exercises', 'exercises.*', 'htmlcov', 'htmlcov.*', '[._]*', '[._]*.*') +# # Reserved top-level module names +# FlatLayoutModuleFinder.DEFAULT_EXCLUDE: ClassVar[tuple[str, ...]] = ('setup', 'conftest', 'test', 'tests', 'example', 'examples', 'build', 'toxfile', 'noxfile', 'pavement', 'dodo', 'tasks', 'fabfile', '[Ss][Cc]onstruct', 'conanfile', 'manage', 'benchmark', 'benchmarks', 'exercise', 'exercises', '[._]*') [tool.setuptools.dynamic] #version = {attr = "__version__"} @@ -126,4 +136,4 @@ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" # Allow unused vari quote-style = "double" # Use double quotes (like Black) indent-style = "space" # Like Black, indent with spaces, rather than tabs. skip-magic-trailing-comma = false # Like Black, respect magic trailing commas. -line-ending = "auto" # Like Black, automatically detect the appropriate line ending. \ No newline at end of file +line-ending = "auto" # Like Black, automatically detect the appropriate line ending. diff --git a/src/renatoxsr-py/__init__.py b/src-py/renatoxsr/__init__.py similarity index 72% rename from src/renatoxsr-py/__init__.py rename to src-py/renatoxsr/__init__.py index fd10ba1..a7862d7 100644 --- a/src/renatoxsr-py/__init__.py +++ b/src-py/renatoxsr/__init__.py @@ -3,14 +3,16 @@ # SPDX-FileCopyrightText: 2025-present RenatoXSR # SPDX-License-Identifier: BSD-3-Clause-Clear """RenatoXSR's Python Utilities (monorepo)""" +import os, sys, platform # Setup -import const -import logger +import renatoxsr.const +import renatoxsr.logger +logger = renatoxsr.logger.logger logger.debug("platform: %s", platform.platform()) logger.debug("system: %s", platform.system()) logger.debug("node: %s", platform.node()) # Import modules that should be exported -import utils -import scripts.composectl \ No newline at end of file +import renatoxsr.utils +import renatoxsr.scripts.composectl diff --git a/src/renatoxsr-py/__version__.py b/src-py/renatoxsr/__version__.py similarity index 100% rename from src/renatoxsr-py/__version__.py rename to src-py/renatoxsr/__version__.py diff --git a/src/renatoxsr-py/const.py b/src-py/renatoxsr/const.py similarity index 100% rename from src/renatoxsr-py/const.py rename to src-py/renatoxsr/const.py diff --git a/src/renatoxsr-py/logger.py b/src-py/renatoxsr/logger.py similarity index 100% rename from src/renatoxsr-py/logger.py rename to src-py/renatoxsr/logger.py diff --git a/src/renatoxsr-py/scripts/composectl.py b/src-py/renatoxsr/scripts/composectl.py similarity index 95% rename from src/renatoxsr-py/scripts/composectl.py rename to src-py/renatoxsr/scripts/composectl.py index b09fc9f..96e6ac2 100644 --- a/src/renatoxsr-py/scripts/composectl.py +++ b/src-py/renatoxsr/scripts/composectl.py @@ -290,6 +290,7 @@ class ACTION(Enum): LOGSF = ("--progress=plain", "logs","-f") LS = ("--progress=plain", "ls",) BUILD = ("--progress=plain", "build", "--pull", "--push") + PUSH = ("--progress=plain", "push") @@ -300,11 +301,15 @@ def main(): p.add_argument("--root", type=Path, default="/srv/containers") #p.add_argument("--prefix", default="", help="Prefix of compose files") #p.add_argument("--suffix", default="", help="Suffix to find compose files, before .yml extension") - p.add_argument("--subdir", default="", help="Subdir to find containers") + p.add_argument("--subdir", default="./", help="Subdir to find containers") p.add_argument("--name", default="*", help="Name of folder to find compose.yml file") p.add_argument("--cmd", default="docker compose", help="compose command") p.add_argument("--file", default="compose.yml") + p.add_argument("--profiles", help="Comma separated list of compose profiles") + #p.add_argument("--project", help="Project directories to find compose.yml and/or names") + p.add_argument("--services", help="services of compose file") p.add_argument("action", choices=[a.name.lower() for a in ACTION]) + p.add_argument("project_and_or_services", nargs="*", help="project and/or services (this list will be parsed before used)") args = p.parse_args() logger.debug("Args:") for k,v in vars(args).items(): @@ -360,4 +365,4 @@ if __name__ == "__main__": logger.critical("[RuntimeError] %s", str(e)) #sys.exit(1) -#EOF \ No newline at end of file +#EOF diff --git a/src/renatoxsr-py/utils/__init__.py b/src-py/renatoxsr/utils/__init__.py similarity index 87% rename from src/renatoxsr-py/utils/__init__.py rename to src-py/renatoxsr/utils/__init__.py index 9756a6b..20f5bc2 100644 --- a/src/renatoxsr-py/utils/__init__.py +++ b/src-py/renatoxsr/utils/__init__.py @@ -3,4 +3,4 @@ # SPDX-FileCopyrightText: 2025-present RenatoXSR # SPDX-License-Identifier: BSD-3-Clause-Clear """`utils` package of RenatoXSR's Python Utilities (monorepo)""" -import uuid7_base58 \ No newline at end of file +import renatoxsr.utils.uuid7_base58 diff --git a/src-py/renatoxsr/utils/uuid7_base58.py b/src-py/renatoxsr/utils/uuid7_base58.py new file mode 100644 index 0000000..47cbdec --- /dev/null +++ b/src-py/renatoxsr/utils/uuid7_base58.py @@ -0,0 +1,38 @@ +import sys +import uuid +import base58 + +### Garante suporte nativo no Python 3.14+ ou usa fallback para versões anteriores + +if sys.version_info >= (3, 14): + from uuid import uuid7 +else: + from uuid6 import uuid7 + +def uuid7_to_base58() -> tuple[str, str]: + """Gera um UUIDv7 e o codifica em uma string compacta Base58.""" + ### 1. Gera o UUIDv7 padrão (128 bits / 16 bytes) + u7 = uuid7() + ### 2. Transforma os 16 bytes do UUID em Base58 (sem o checksum do Bitcoin) + # .zfill(22) garante que ele sempre tenha 22 caracteres se houver zeros à esquerda + encoded_b58 = base58.b58encode(u7.bytes).decode('utf-8').zfill(22) + return str(u7), encoded_b58 + +def base58_to_uuid7(b58_string: str) -> str: + """Decodifica uma string Base58 de volta para o formato original de UUIDv7.""" + ### 1. Decodifica a string de volta para os 16 bytes originais + decoded_bytes = base58.b58decode(b58_string) + ### 2. Reconstrói o objeto UUID a partir dos bytes + return str(uuid.UUID(bytes=decoded_bytes)) + +def demo(): + """ --- Demonstração de Uso ---""" + ### Gerando o ID compactado + uuid_original, id_base58 = uuid7_to_base58() + print(f"UUIDv7 Original (36 chars): {uuid_original}") + print(f"UUIDv7 em Base58 (22 chars): {id_base58}") + ### Revertendo para provar que é bidirecional (lossless) + uuid_revertido = base58_to_uuid7(id_base58) + print(f"Decodificado de volta: {uuid_revertido}") + assert uuid_original == uuid_revertido, "Erro: Os UUIDs não coincidem!" + print("\nSucesso! Conversão perfeita e segura para URLs.") diff --git a/src/renatoxsr-py/utils/zwid.py b/src-py/renatoxsr/utils/zwid.py similarity index 100% rename from src/renatoxsr-py/utils/zwid.py rename to src-py/renatoxsr/utils/zwid.py diff --git a/src/renatoxsr-py/utils/uuid7_base58.py b/src/renatoxsr-py/utils/uuid7_base58.py deleted file mode 100644 index 83ffb66..0000000 --- a/src/renatoxsr-py/utils/uuid7_base58.py +++ /dev/null @@ -1,55 +0,0 @@ -import sys -import uuid -import base58 - -### Garante suporte nativo no Python 3.14+ ou usa fallback para versões anteriores - -if sys.version_info >= (3, 14): -from uuid import uuid7 -else: -from uuid6 import uuid7 - -def uuid7_to_base58() -> tuple[str, str]: -"""Gera um UUIDv7 e o codifica em uma string compacta Base58.""" - -### 1. Gera o UUIDv7 padrão (128 bits / 16 bytes) - -u7 = uuid7() - -### 2. Transforma os 16 bytes do UUID em Base58 (sem o checksum do Bitcoin) - -# .zfill(22) garante que ele sempre tenha 22 caracteres se houver zeros à esquerda - -encoded_b58 = base58.b58encode(u7.bytes).decode('utf-8').zfill(22) - -return str(u7), encoded_b58 - -def base58_to_uuid7(b58_string: str) -> str: -"""Decodifica uma string Base58 de volta para o formato original de UUIDv7.""" - -### 1. Decodifica a string de volta para os 16 bytes originais - -decoded_bytes = base58.b58decode(b58_string) - -### 2. Reconstrói o objeto UUID a partir dos bytes - -return str(uuid.UUID(bytes=decoded_bytes)) - -### --- Demonstração de Uso --- - -if **name** == "**main**": - -### Gerando o ID compactado - -uuid_original, id_base58 = uuid7_to_base58() - -print(f"UUIDv7 Original (36 chars): {uuid_original}") -print(f"UUIDv7 em Base58 (22 chars): {id_base58}") - -### Revertendo para provar que é bidirecional (lossless) - -uuid_revertido = base58_to_uuid7(id_base58) -print(f"Decodificado de volta: {uuid_revertido}") - -assert uuid_original == uuid_revertido, "Erro: Os UUIDs não coincidem!" -print("\nSucesso! Conversão perfeita e segura para URLs.") \ No newline at end of file