dotfiles

Repositório dotfiles
git clone git://git.sivaldodavi.com/dotfiles.git
Log | Files | Refs | README

commit de9963c92f4be07a94f9103b78ac364ffac205cc
parent c23929aadf2d74a805c4656a232f25afb81af68f
Author: Sivaldo <gxixtx@xsxixvxaxlxdxoxdxaxvxix.xcxoxm>
Date:   Fri, 31 Jul 2026 14:22:11 -0300

refactor: remove suporte ao password-store e script de desenho

Diffstat:
M.config/X11/profile | 2--
D.local/bin/draw | 302------------------------------------------------------------------------------
2 files changed, 0 insertions(+), 304 deletions(-)

diff --git a/.config/X11/profile b/.config/X11/profile @@ -7,7 +7,6 @@ export TERMINAL="st" export BROWSER="firefox" export READER="zathura" export PATH="$HOME/.local/bin:$PATH" -export PASSWORD_STORE_GPG_OPTS="--trust-model always" # --------------------------- # Variáveis de base (XDG) @@ -25,7 +24,6 @@ export XDG_VIDEOS_DIR="$HOME/videos" # --------------------------- # Pastas de programas # --------------------------- -export PASSWORD_STORE_DIR="$XDG_DATA_HOME/password-store" export GNUPGHOME="$XDG_DATA_HOME/gnupg" export GOPATH="$XDG_DATA_HOME/go" export HISTFILE="$XDG_CACHE_HOME/ash_history" diff --git a/.local/bin/draw b/.local/bin/draw @@ -1,302 +0,0 @@ -#!/usr/bin/env python3 -""" -Servidor local minimalista para Excalidraw. -Assets JS ficam em ~/.cache/excalidraw para sobreviver a reboots. -Bibliotecas em ~/.local/share/excalidraw são mescladas automaticamente -num único all-libraries.excalidrawlib servido pelo servidor. -""" - -import json -import mimetypes -import os -import signal -import sys -import urllib.request -from concurrent.futures import ThreadPoolExecutor, as_completed -from datetime import datetime, timezone -from http.server import HTTPServer, BaseHTTPRequestHandler -from pathlib import Path -from socketserver import ThreadingMixIn - -# ── Configurações ──────────────────────────────────────────────────────────── -PORT = 8080 -CACHE_DIR = Path.home() / ".cache" / "excalidraw" -LIBS_DIR = Path.home() / ".local" / "share" / "excalidraw" -MERGED_LIB = CACHE_DIR / "all-libraries.excalidrawlib" - -ASSETS = { - "react.js": "https://unpkg.com/react@18.2.0/umd/react.production.min.js", - "react-dom.js": "https://unpkg.com/react-dom@18.2.0/umd/react-dom.production.min.js", - "excalidraw.js": "https://unpkg.com/@excalidraw/excalidraw@0.17.6/dist/excalidraw.production.min.js", -} - -EXCALIDRAW_ASSET_PATH = "https://unpkg.com/@excalidraw/excalidraw@0.17.6/dist/" -# ───────────────────────────────────────────────────────────────────────────── - - -def fetch_asset(filename: str, url: str, retries: int = 4) -> None: - dest = CACHE_DIR / filename - if dest.exists() and dest.stat().st_size > 1024: - return - - req = urllib.request.Request( - url, - headers={"User-Agent": "Mozilla/5.0 (compatible; ExcalidrawLocal/1.0)", "Accept": "*/*"}, - ) - - last_exc: Exception = RuntimeError("sem tentativas") - for attempt in range(1, retries + 1): - try: - with urllib.request.urlopen(req, timeout=20) as response: - data = response.read() - if len(data) < 1024: - raise RuntimeError(f"payload suspeito ({len(data)} bytes)") - dest.write_bytes(data) - return - except Exception as exc: - last_exc = exc - wait = 2 ** attempt # 2, 4, 8, 16 s - print(f" ↺ {filename} tentativa {attempt}/{retries} falhou ({exc}); aguardando {wait}s…") - import time; time.sleep(wait) - - raise last_exc - - -def bootstrap_assets() -> None: - CACHE_DIR.mkdir(parents=True, exist_ok=True) - os.chdir(CACHE_DIR) - - with ThreadPoolExecutor(max_workers=3) as pool: - futures = {pool.submit(fetch_asset, name, url): name for name, url in ASSETS.items()} - for future in as_completed(futures): - name = futures[future] - try: - future.result() - print(f" ✓ {name}") - except Exception as exc: - print(f" ✗ {name}: {exc}") - sys.exit(1) - - -def merge_libraries() -> None: - """ - Varre ~/.local/share/excalidraw, mescla todos os .excalidrawlib - num único arquivo em ~/.cache/excalidraw/all-libraries.excalidrawlib. - IDs duplicados são ignorados para o caso de re-execução. - """ - if not LIBS_DIR.is_dir(): - print(" – Diretório de bibliotecas não encontrado, pulando merge.") - return - - files = sorted(LIBS_DIR.glob("*.excalidrawlib")) - if not files: - print(" – Nenhuma biblioteca encontrada em ~/.local/share/excalidraw.") - return - - all_items: list = [] - seen_ids: set = set() - - for f in files: - try: - data = json.loads(f.read_text(encoding="utf-8")) - except Exception as e: - print(f" ✗ {f.name}: {e}") - continue - - version = data.get("version", 1) - - # v2: libraryItems é uma lista plana de elementos individuais (cada um é 1 item). - # v1: library é uma lista de grupos, onde cada grupo é uma lista de elementos - # que formam juntos um único item da biblioteca. - if version >= 2: - raw_items = data.get("libraryItems", []) - else: - # Converte cada grupo de elementos v1 num libraryItem v2. - raw_items = [] - import uuid as _uuid - for group in data.get("library", []): - raw_items.append({ - "id": str(_uuid.uuid4()), - "status": "published", - "elements": group, - "created": 0, - }) - - added = 0 - for item in raw_items: - uid = item.get("id") - if uid in seen_ids: - continue - seen_ids.add(uid) - all_items.append(item) - added += 1 - - print(f" ✓ {f.name:45s} {added:3d} itens (v{version})") - - merged = { - "type": "excalidrawlib", - "version": 2, - "source": f"merged:{datetime.now(timezone.utc).isoformat()}", - "libraryItems": all_items, - } - MERGED_LIB.write_text(json.dumps(merged, ensure_ascii=False), encoding="utf-8") - print(f" → {len(all_items)} itens mesclados → {MERGED_LIB}") - - -class SPAHandler(BaseHTTPRequestHandler): - _html_payload: bytes = b"" - - def _send_headers(self, status: int = 200) -> None: - self.send_response(status) - self.send_header("X-Content-Type-Options", "nosniff") - - def _serve_file(self, filepath: Path) -> None: - try: - data = filepath.read_bytes() - except (OSError, IOError): - self.send_error(404) - return - - self._send_headers(200) - mime, _ = mimetypes.guess_type(filepath.name) - self.send_header("Content-Type", mime or "application/octet-stream") - - if filepath.suffix == ".js": - self.send_header("Cache-Control", "public, max-age=31536000, immutable") - elif filepath.suffix == ".excalidrawlib": - # Lib mesclada pode ser regenerada; não cachear no browser. - self.send_header("Cache-Control", "no-store") - - self.send_header("Content-Length", str(len(data))) - self.end_headers() - self.wfile.write(data) - - def _serve_spa(self) -> None: - self._send_headers(200) - self.send_header("Content-Type", "text/html; charset=utf-8") - self.send_header("Cache-Control", "no-store") - self.end_headers() - self.wfile.write(self._html_payload) - - def do_GET(self) -> None: - requested = self.path.lstrip("/") or "index.html" - filepath = CACHE_DIR / requested - if filepath.is_file(): - self._serve_file(filepath) - else: - self._serve_spa() - - def log_message(self, format, *args) -> None: - pass - - -class ThreadedHTTPServer(ThreadingMixIn, HTTPServer): - daemon_threads = True - allow_reuse_address = True - - -def generate_index_html() -> bytes: - if MERGED_LIB.exists(): - bootstrap_js = """ - function startApp(libraryItems) { - var initialData = libraryItems ? { libraryItems: libraryItems } : null; - - var App = function() { - return React.createElement( - "div", - { style: { height: "100vh", width: "100vw" } }, - React.createElement(window.ExcalidrawLib.Excalidraw, { - initialData: initialData, - }) - ); - }; - - ReactDOM.createRoot(document.getElementById("root")).render(React.createElement(App)); - } - - fetch("/all-libraries.excalidrawlib") - .then(function(r) { return r.json(); }) - .then(function(data) { startApp(data.libraryItems || []); }) - .catch(function(e) { - console.warn("Biblioteca não carregada:", e); - startApp(null); - }); -""" - else: - bootstrap_js = """ - var App = function() { - return React.createElement( - "div", - { style: { height: "100vh", width: "100vw" } }, - React.createElement(window.ExcalidrawLib.Excalidraw) - ); - }; - ReactDOM.createRoot(document.getElementById("root")).render(React.createElement(App)); -""" - - html = f"""<!DOCTYPE html> -<html lang="pt-BR"> -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Excalidraw Local</title> - <script src="/react.js"></script> - <script src="/react-dom.js"></script> - <script src="/excalidraw.js"></script> - <style> - body, html {{ margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; background: #ffffff; }} - #root {{ width: 100vw; height: 100vh; }} - </style> -</head> -<body> - <div id="root"></div> - <script> - window.EXCALIDRAW_ASSET_PATH = "{EXCALIDRAW_ASSET_PATH}"; - - window.addEventListener("DOMContentLoaded", function() {{ - if (!window.React || !window.ReactDOM || !window.ExcalidrawLib) {{ - document.getElementById("root").innerHTML = - '<div style="padding:2rem;color:#d32f2f;font-family:sans-serif;">' + - '<strong>Falha de carga:</strong> bibliotecas não disponíveis.</div>'; - return; - }} - - {bootstrap_js} - }}); - </script> -</body> -</html> -""" - return html.encode("utf-8") - - -def shutdown_handler(signum, frame) -> None: - print("\nEncerrando servidor...") - sys.exit(0) - - -def main() -> None: - signal.signal(signal.SIGINT, shutdown_handler) - signal.signal(signal.SIGTERM, shutdown_handler) - - print(f"Cache: {CACHE_DIR}") - print("\nBaixando assets JS...") - bootstrap_assets() - - print("\nMesclando bibliotecas...") - merge_libraries() - - SPAHandler._html_payload = generate_index_html() - - server = ThreadedHTTPServer(("", PORT), SPAHandler) - print(f"\nServidor ativo em http://localhost:{PORT}") - print("Pressione Ctrl+C para encerrar.\n") - - try: - server.serve_forever() - finally: - server.server_close() - - -if __name__ == "__main__": - main()