From bdfba348e50ce6cfb1aa84dfb98de36f616bc5b8 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Sat, 21 Jun 2025 14:41:25 -0400 Subject: [PATCH] feat(cli): GUI text editor for body --- README.md | 2 +- voxvera/cli.py | 49 +++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e214ab6..0f127e7 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Generate printable flyers with QR codes linking to Tor (.onion) or HTTPS sites, ## 🚀 Key Features -* **Interactive setup**: `voxvera init` prompts for metadata or extracts from a PDF form. +* **Interactive setup**: `voxvera init` prompts for metadata or extracts from a PDF form. When editing body text, a simple GUI window opens with existing content pre-filled. * **Template support**: `voxvera init --template ` copies built‑in templates (`blank`, `voxvera`). * **Build assets**: `voxvera build [--pdf ] [--download ]` generates HTML, obfuscated JS/CSS, QR codes, and bundles PDFs. * **Batch import**: `voxvera import` processes all JSON configs in `imports/`. diff --git a/voxvera/cli.py b/voxvera/cli.py index 598dccc..027192b 100644 --- a/voxvera/cli.py +++ b/voxvera/cli.py @@ -84,20 +84,57 @@ def save_config(data: dict, path: str): json.dump(data, fh, indent=2) -def open_editor(initial: str) -> str: +def _open_editor_terminal(initial: str) -> str: + """Fallback to opening the user's $EDITOR in the terminal.""" import tempfile - editor = os.environ.get('EDITOR', 'nano') - fd, path = tempfile.mkstemp(suffix='.txt') + + editor = os.environ.get("EDITOR", "nano") + fd, path = tempfile.mkstemp(suffix=".txt") try: - with os.fdopen(fd, 'w', encoding='utf-8') as fh: - fh.write(initial or '') + with os.fdopen(fd, "w", encoding="utf-8") as fh: + fh.write(initial or "") subprocess.call([editor, path]) - with open(path, 'r', encoding='utf-8') as fh: + with open(path, "r", encoding="utf-8") as fh: return fh.read() finally: os.unlink(path) +def open_editor(initial: str) -> str: + """Open a simple GUI text editor when possible. + + The window is pre-populated with ``initial`` so users can edit existing + content. If the GUI cannot be displayed (e.g. running headless or Tkinter + is unavailable) the terminal editor fallback is used. + """ + + try: # Try to open a Tkinter GUI for editing + import tkinter as tk + from tkinter import scrolledtext + + result = {"text": initial or ""} + + root = tk.Tk() + root.title("Edit text") + + text = scrolledtext.ScrolledText(root, width=80, height=20) + text.pack(expand=True, fill="both") + text.insert("1.0", initial or "") + + def save_and_close(): + result["text"] = text.get("1.0", "end-1c") + root.destroy() + + save_btn = tk.Button(root, text="Save", command=save_and_close) + save_btn.pack() + + root.mainloop() + return result["text"] + except Exception: + # Anything from import failures to display issues falls back to terminal + return _open_editor_terminal(initial) + + def _len_transform(limit: int): def _t(val: str) -> str: length = len(val)