nfdos/src/tui/menu_libs.py
neo.webmaster.2@gmail.com f4f41e5d03
Some checks are pending
Build NFDOS ISO / build (push) Waiting to run
"Auto-commit via make git"
2025-11-11 05:16:53 +01:00

155 lines
5.2 KiB
Python

import os
import json
import subprocess
import urllib.request
from pathlib import Path
from rich.console import Console
from rich.table import Table
console = Console()
def safe_run(cmd, shell=False):
subprocess.run(cmd, check=True, shell=shell)
def get_latest_version(name):
"""Obtém a versão mais recente de um pacote PyPI."""
url = f"https://pypi.org/pypi/{name}/json"
try:
with urllib.request.urlopen(url, timeout=5) as response:
data = json.load(response)
return data["info"]["version"]
except Exception:
return None
def install_lib(name, version=None):
base_dir = Path(__file__).resolve().parents[1]
nfdos_dir = base_dir / "_nfdos"
libs_dir = nfdos_dir / "libs"
libs_dir.mkdir(parents=True, exist_ok=True)
console.print(f"[cyan]📦 Instalando biblioteca:[/] {name} {version or ''}")
cmd = f"pip download {name}{'==' + version if version else ''} -d {libs_dir}"
safe_run(cmd, shell=True)
# Registo no manifest
manifest_path = libs_dir / "libs_manifest.json"
manifest = json.loads(manifest_path.read_text()) if manifest_path.exists() else {}
manifest[name] = {"version": version or "latest"}
manifest_path.write_text(json.dumps(manifest, indent=4))
console.print(f"[green]✔ {name} adicionada ao manifesto.[/green]")
def remove_lib(name):
base_dir = Path(__file__).resolve().parents[1]
libs_dir = base_dir / "_nfdos" / "libs"
manifest_path = libs_dir / "libs_manifest.json"
if not manifest_path.exists():
console.print("[red]Nenhuma biblioteca instalada ainda.[/red]")
return
manifest = json.loads(manifest_path.read_text())
if name not in manifest:
console.print(f"[yellow]⚠ Biblioteca '{name}' não encontrada no manifesto.[/yellow]")
return
# Remover ficheiros relacionados
removed = False
for file in libs_dir.glob(f"{name}-*"):
try:
file.unlink()
removed = True
except Exception as e:
console.print(f"[red]Erro ao remover {file}: {e}[/red]")
# Atualizar manifest
del manifest[name]
manifest_path.write_text(json.dumps(manifest, indent=4))
if removed:
console.print(f"[green]✔ Biblioteca '{name}' removida com sucesso.[/green]")
else:
console.print(f"[yellow]⚠ Nenhum ficheiro físico encontrado para '{name}'.[/yellow]")
def update_lib(name):
"""Compara e atualiza biblioteca para a versão mais recente do PyPI."""
base_dir = Path(__file__).resolve().parents[1]
libs_dir = base_dir / "_nfdos" / "libs"
manifest_path = libs_dir / "libs_manifest.json"
if not manifest_path.exists():
console.print("[red]Nenhuma biblioteca instalada ainda.[/red]")
return
manifest = json.loads(manifest_path.read_text())
if name not in manifest:
console.print(f"[yellow]⚠ Biblioteca '{name}' não está instalada.[/yellow]")
return
current_version = manifest[name].get("version")
latest_version = get_latest_version(name)
if not latest_version:
console.print(f"[red]❌ Falha ao consultar PyPI para {name}.[/red]")
return
if current_version == latest_version or current_version == "latest":
console.print(f"[green]✔ {name} já está na versão mais recente ({latest_version}).[/green]")
return
console.print(f"[yellow]🔄 Atualizando {name} ({current_version}{latest_version})...[/yellow]")
remove_lib(name)
install_lib(name, latest_version)
console.print(f"[green]✅ {name} atualizado para a versão {latest_version}.[/green]")
def list_libs():
base_dir = Path(__file__).resolve().parents[1]
libs_dir = base_dir / "_nfdos" / "libs"
manifest_path = libs_dir / "libs_manifest.json"
if not manifest_path.exists():
console.print("[red]Nenhuma biblioteca instalada ainda.[/red]")
return
manifest = json.loads(manifest_path.read_text())
table = Table(title="Bibliotecas do Neurotron")
table.add_column("Nome", style="cyan")
table.add_column("Versão", style="green")
for name, data in manifest.items():
table.add_row(name, data.get("version", "?"))
console.print(table)
def run():
while True:
console.clear()
console.rule("[bold yellow]📚 Bibliotecas do Neurotron[/bold yellow]")
console.print("1. Instalar biblioteca")
console.print("2. Listar bibliotecas instaladas")
console.print("3. Atualizar biblioteca")
console.print("4. Remover biblioteca")
console.print("0. Voltar")
choice = console.input("\n[cyan]nfdos> [/cyan]")
if choice == "1":
name = console.input("Nome da biblioteca: ")
version = console.input("Versão (ou vazio p/ latest): ")
install_lib(name, version or None)
elif choice == "2":
list_libs()
console.input("\n[grey]Pressiona Enter para continuar...[/grey]")
elif choice == "3":
name = console.input("Nome da biblioteca: ")
update_lib(name)
elif choice == "4":
name = console.input("Nome da biblioteca a remover: ")
remove_lib(name)
elif choice == "0":
break
else:
console.print("[red]Opção inválida![/red]")