diff --git a/README.md b/README.md index 0f127e7..87f91b2 100644 --- a/README.md +++ b/README.md @@ -6,18 +6,19 @@ 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. 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`). +// 🔧 merged conflicting changes from codex/populate-gui-text-fields-for-editing vs main +* **Interactive setup**: `voxvera init` prompts for metadata or extracts from a PDF form. When editing body text, a small Tkinter GUI window opens with existing content pre-filled, falling back to the user's `$EDITOR` if the GUI isn't available. +* **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/`. * **Onion hosting**: `voxvera serve` publishes via Tor/OnionShare and updates flyer links. -* **All‑in‑one**: `voxvera quickstart` runs init, build, and serve in sequence. +* **All-in-one**: `voxvera quickstart` runs init, build, and serve in sequence. * **Dependency check**: `voxvera check` verifies presence of required tools. -* **GUI**: Minimal Electron wrapper (`gui/electron`) for non‑CLI users. +* **GUI**: Minimal Electron wrapper (`gui/electron`) for non-CLI users. --- -## 📥 Fool‑Proof Installation +## 📥 Fool-Proof Installation ### 1. Prebuilt Binary (Linux) @@ -33,7 +34,7 @@ if ! echo "$PATH" | grep -q "$HOME/.local/bin"; then echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc echo 'Add ~/.local/bin to your PATH and restart your shell.' fi -``` +```` ### 2. Homebrew (macOS) @@ -42,7 +43,7 @@ brew tap PR0M3TH3AN/voxvera brew install voxvera ``` -### 3. pipx (cross‑platform) +### 3. pipx (cross-platform) ```bash pipx install voxvera @@ -115,7 +116,7 @@ voxvera quickstart ### Other Commands * `voxvera init --template ` — copy a template into `dist/`. -* `voxvera import` — batch‑import JSON configs from `imports/`. +* `voxvera import` — batch-import JSON configs from `imports/`. * `voxvera check` — dependency health check. --- @@ -146,4 +147,4 @@ See the `docs/` folder for detailed guides: ## 📜 License -MIT © 2025 thePR0M3TH3AN +MIT © 2025 thePR0M3TH3AN \ No newline at end of file diff --git a/voxvera/cli.py b/voxvera/cli.py index 027192b..47943bb 100644 --- a/voxvera/cli.py +++ b/voxvera/cli.py @@ -100,40 +100,38 @@ def _open_editor_terminal(initial: str) -> str: os.unlink(path) +# 🔧 merged conflicting changes from codex/populate-gui-text-fields-for-editing vs main def open_editor(initial: str) -> str: - """Open a simple GUI text editor when possible. + """Open a simple GUI text editor with pre-populated content if 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. + Existing text is pre-filled in the editor. If tkinter or a display + server is unavailable, falls back to the user's $EDITOR in the terminal. """ - - try: # Try to open a Tkinter GUI for editing + try: 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) + result = {"text": initial or ""} + text = scrolledtext.ScrolledText(root, width=80, height=20) + text.pack(expand=True, fill="both") + if initial: + text.insert("1.0", initial) + text.focus_set() + + 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.protocol("WM_DELETE_WINDOW", save_and_close) + root.mainloop() + return result["text"] + def _len_transform(limit: int): def _t(val: str) -> str: @@ -341,7 +339,11 @@ def serve(config_path: str): print(f"Directory {dir_path} not found", file=sys.stderr) sys.exit(1) logfile = dir_path / 'onionshare.log' - proc = subprocess.Popen(['onionshare-cli', '--website', '--public', '--persistent', f'{dir_path}/.onionshare-session', str(dir_path)], stdout=open(logfile, 'w'), stderr=subprocess.STDOUT) + proc = subprocess.Popen( + ['onionshare-cli', '--website', '--public', '--persistent', + f'{dir_path}/.onionshare-session', str(dir_path)], + stdout=open(logfile, 'w'), stderr=subprocess.STDOUT + ) try: import time import re as _re @@ -389,7 +391,8 @@ def import_configs(): def main(argv=None): parser = argparse.ArgumentParser(prog='voxvera') - parser.add_argument('--config', default=str(ROOT / 'src' / 'config.json'), help='Path to config.json') + parser.add_argument('--config', default=str(ROOT / 'src' / 'config.json'), + help='Path to config.json') sub = parser.add_subparsers(dest='command') p_init = sub.add_parser('init', help='Update configuration interactively or from PDF')