Commit Graph

50 Commits

Author SHA1 Message Date
shuki
47c93d1208 Add debug notifications to backup flow 2026-03-06 04:13:45 +02:00
shuki
4d4b55047b Fix OperationLog not rendering by removing LoadingIndicator
LoadingIndicator was causing OperationLog ModalScreen to fail silently
during compose. Replaced with a simple Static emoji spinner ().
Reverted screen push patterns back to simple callback approach.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 04:11:16 +02:00
shuki
f70ce53dc5 Fix operation log not showing by awaiting screen mount before CLI
Add wait_ready() to OperationLog and await it in all callers before
starting CLI commands. Ensures the modal with spinner is fully rendered
before streaming begins.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 03:25:25 +02:00
shuki
f9981831fa Add loading spinner to operation log during running tasks
Shows an animated spinner next to the title while backup, restore,
retention, remote test, and schedule operations are running. Spinner
hides when the operation completes via finish().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 03:19:57 +02:00
shuki
0e02ba6876 Hide time field for hourly schedules
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 03:13:46 +02:00
shuki
313d1fe873 Replace free-text day inputs with proper dropdowns per schedule type
- Daily: multi-select checkboxes for days of week (empty = every day)
- Weekly: single dropdown for day of week
- Monthly: dropdown with 1st/7th/14th/21st/28th of the month
- Cron generation supports daily with specific days via SCHEDULE_DAY

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 03:11:49 +02:00
shuki
a1c280ee3c Add hourly interval dropdown and toggle schedule fields by type
Show "Schedule Hours" dropdown (1/2/3/4/6/8/12h) only for hourly type.
Show time field for hourly/daily/weekly/monthly. Show day field only
for weekly/monthly. Show cron field only for custom type.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 03:10:22 +02:00
shuki
1d9d32c15f Replace schedule targets/remotes inputs with selection lists
Show checkable lists of existing targets and remotes instead of
free-text comma-separated inputs. Selected items are joined with
commas on save, empty selection means "all".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 03:08:41 +02:00
shuki
b3c055c9be Add configurable WORK_DIR instead of /tmp for temp files
Default: /usr/local/gniza/workdir (root) or ~/.local/state/gniza/workdir
(user). MySQL dumps and rclone temp configs now use WORK_DIR. Configurable
via gniza.conf or TUI Settings screen. Created during install.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 03:00:21 +02:00
shuki
791584aa60 Fix MySQL dump remote path to use _mysql/ instead of full temp path
Add optional dest_name parameter to transfer_folder to override the
remote subpath. MySQL dumps now land in _mysql/ inside the snapshot
instead of tmp/gniza-mysql-xxx/_mysql/.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 02:56:37 +02:00
shuki
fa01f1c3ea Toggle MySQL fields visibility by enabled/mode selection
Hide all MySQL fields when MySQL is disabled. When enabled, show
databases input only for mode=select and exclude input only for
mode=all.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 02:54:11 +02:00
shuki
e6aa828111 Toggle SSH key/password fields by auth method and add key file browser
Show only the SSH key path input (with Browse button) when auth method
is "key", and only the password input when auth method is "password".
Adds a FilePicker widget for browsing SSH key files, defaulting to
~/.ssh directory.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 02:53:31 +02:00
shuki
733bb5de62 Add MySQL database backup support
Dump MySQL/MariaDB databases as part of backup snapshots. Each database
is dumped to a separate gzipped file under _mysql/ in the snapshot.
Supports all-databases mode with exclude list, or explicit database
selection. Includes TUI form fields for full configuration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 02:48:47 +02:00
shuki
121a615e67 Remove legacy gum TUI and clean up install script
- Delete all lib/ui_*.sh files (gum-based TUI)
- Remove gum download from install script
- Remove gum fallback and show_logo from bin/gniza
- Update README to reference Textual TUI and web GUI

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 02:15:52 +02:00
shuki
5ecb9537b7 Add 'Create Folder' to folder picker dialog
Adds an input field and button to create a new folder inside the
currently selected directory, then refreshes the tree.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 02:13:36 +02:00
shuki
4bd9df3b5e Fix Select.BLANK checks across all screens
Replace `is Select.BLANK` / `is not Select.BLANK` with isinstance
checks, as the sentinel identity varies across Textual versions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 02:12:58 +02:00
shuki
e6b6d7684a Fix logo/menu vertical alignment on main screen
Remove leading blank line from logo markup and add top margin
to menu so both start at the same visual row.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 02:03:28 +02:00
shuki
3d5a9cdfdd Remove verify feature and align main menu layout
Remove verify screen, CLI subcommand, and all related functions.
Fix logo/menu height alignment on main menu screen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 01:57:55 +02:00
shuki
8149976170 Add Browse button for restore destination directory
Opens FolderPicker to select the destination path instead of
requiring manual typing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 01:48:47 +02:00
shuki
8098cb90cf Auto-load snapshots when target and remote are selected
Remove the Load Snapshots button. Snapshots are fetched
automatically when both target and remote have values,
triggered by Select.Changed events.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 01:47:59 +02:00
shuki
7793f02aa2 Fix NoMatches crash: buffer writes until OperationLog is mounted
The worker starts streaming output before the modal screen finishes
composing. Buffer writes until on_mount fires, then flush.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 01:44:37 +02:00
shuki
75f00f6521 Fix Rich markup rendering in operation log
Use Text.from_markup() for strings containing Rich tags
so [red]...[/red] renders as colored text instead of raw tags.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 01:31:15 +02:00
shuki
52912bfab7 Enable Rich markup in operation log output
Fixes raw [red]...[/red] tags showing instead of colored text.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 01:25:24 +02:00
shuki
4fb6d45c1a Fix web GUI crash: detect LAN IP for WebSocket public_url
public_url="" caused IndexError in textual-serve URL builder.
Now auto-detects the machine's LAN IP when binding to 0.0.0.0
so the browser can connect to the correct WebSocket endpoint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 01:23:55 +02:00
shuki
09ff0f9482 Fix web GUI WebSocket: use relative public_url
Setting public_url="" makes textual-serve generate relative
WebSocket URLs so the browser connects to the correct host
regardless of whether accessed via localhost or remote IP.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 01:02:15 +02:00
shuki
01cbe70c5d Fix install: copy tui/ package and install Python deps
- Install script now copies tui/ directory to install location
- Installs textual and textual-serve via pip after file copy
- __main__.py uses GNIZA_DIR env var for correct path resolution

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 00:58:58 +02:00
shuki
63e88d11df Fix web GUI: set env vars in process instead of command string
textual-serve shows the command string as the app title.
Set PYTHONPATH and GNIZA_DIR as real env vars so the spawned
subprocess inherits them. Add title="gniza" for clean display.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 00:56:32 +02:00
shuki
bd25d99056 Fix web GUI by setting PYTHONPATH in spawned command
textual-serve spawns the app as a subprocess which doesn't
inherit PYTHONPATH. Bake the project root into the command.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 00:55:43 +02:00
shuki
f21f652fea Add web GUI mode via textual-serve
Run `gniza web` or `gniza --web` to serve the TUI as a web app
on port 8080. Use --port to change. Requires textual-serve.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 00:52:59 +02:00
shuki
a434626cb3 Replace Switch with Select dropdown for Enabled field
Switch widget was not rendering visibly. Use a Yes/No Select
dropdown instead which works reliably.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 23:52:09 +02:00
shuki
111b5ee607 Fix logo display and side-by-side layout
Use full block-character logo from bin/gniza, place logo Static
and OptionList directly in Horizontal container without extra
nesting. Style with proper widths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 23:51:01 +02:00
shuki
85eb4232c8 Layout logo on left, menu on right in main screen
Use Horizontal container with logo-panel and menu-panel side by side,
centered vertically in the terminal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 23:50:07 +02:00
shuki
b13514e478 Replace main menu buttons with OptionList for arrow key navigation
OptionList supports up/down arrow keys and Enter to select,
giving a proper menu feel instead of Tab-through buttons.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 23:49:06 +02:00
shuki
fd0ccefad0 Make main menu responsive to terminal size
Use 1fr width with max-width, reduce button height/margins,
and enable overflow scroll so all items fit smaller terminals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 23:48:15 +02:00
shuki
9fb8aeb1ed Fix Enabled switch not visible in target edit screen
Give the switch Horizontal container an explicit ID and CSS
with height:auto and proper alignment.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 23:47:41 +02:00
shuki
587149f062 Add Python Textual TUI replacing gum-based bash TUI
New tui/ package with 14 screens (main menu, backup, restore, targets,
remotes, snapshots, verify, retention, schedule, logs, settings, wizard),
3 custom widgets (folder picker, confirm dialog, operation log), async
backend wrapper, pure-Python config parser, and TCSS theme.

bin/gniza now launches Textual TUI when available, falls back to gum.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 23:39:48 +02:00
shuki
611fe7da3f Add test connection step when creating remotes
- SSH: tests ssh connection before saving, option to save anyway on failure
- Local: checks if directory exists
- S3: tests rclone connection if rclone is available
- GDrive: tests rclone connection if rclone is available
- All tests are optional and can be skipped

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 22:57:57 +02:00
shuki
74efc08903 Trigger wizard when either remote or target is missing
- Changed condition from AND to OR: wizard runs if remotes OR targets
  are not configured (not only when both are empty)
- Wizard skips steps that are already done (e.g. if remote exists,
  jumps straight to target creation)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 22:47:56 +02:00
shuki
73d51a76bb Fix user-mode log dir path in uninstall script
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 22:46:18 +02:00
shuki
4306b9e3b3 Open file browser immediately in folder picker
- First gum file browser opens right after target name entry
- Shows selected folders list, then offers Add/Remove/Done
- No extra menu step before the first folder selection

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 22:43:45 +02:00
shuki
4f9ab94c69 Clarify target name prompt mentions file browser next
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 22:41:24 +02:00
shuki
a956bd9e30 Fix gum file browser returning relative paths
gum file returns paths relative to the start directory.
Prepend / to ensure absolute paths for backup targets.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 22:29:30 +02:00
shuki
f80c786597 Use gum file browser for folder selection in target picker
Replace manual path input with gum file --directory for browsing
and selecting folders. Adds duplicate detection. Shows selected
count in menu header.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 22:22:33 +02:00
shuki
a27ae7faf4 Bundle gum binary with gniza installation
- Install script auto-downloads gum from GitHub releases into
  $INSTALL_DIR/bin/gum (supports x86_64, arm64, armv7, i386)
- Skips download if gum is already installed system-wide
- bin/gniza adds $GNIZA_DIR/bin to PATH so bundled gum is found
- No system package installation required

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 22:20:00 +02:00
shuki
31586547dc Update logo - wider base triangle
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 22:08:28 +02:00
shuki
6c16f65c3c Replace whiptail TUI with gum (charmbracelet/gum)
- Rewrite ui_common.sh wrappers to use gum choose, gum input,
  gum confirm, gum style, gum pager
- Menu items display as "TAG  Description" for reliable tag extraction
  (handles duplicate descriptions safely)
- Replace whiptail --gauge with text-based progress bar
- Use printf %b instead of echo -e to avoid escape injection
- Read msgbox keypress from /dev/tty to work in piped contexts
- Update bin/gniza, install.sh, README.md references

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 21:45:15 +02:00
shuki
0004dbed9f Add first-time setup wizard for new installations
Guides users through creating their first remote and target when gniza
launches with no configuration. Optionally runs a first backup.
Triggers only when both remotes.d/ and targets.d/ are empty.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 21:38:19 +02:00
shuki
30c87a9147 Add curl one-liner install support
- Switch REPO_URL to HTTPS for machines without SSH keys
- Handle piped execution (curl | bash) where BASH_SOURCE is unavailable
- Add one-liner install commands to README (root and user mode)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 21:33:11 +02:00
shuki
43daeec779 Update REPO_URL to Gitea server in install script and README
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 21:31:24 +02:00
shuki
928d5af54c Initial implementation of gniza4linux backup tool
Complete Linux backup manager with Whiptail TUI and CLI interface.
Adapted from gniza4cp (cPanel backup tool) with target/profile-based
system replacing cPanel-specific features.

- 14 core engine modules (backup, restore, targets, remotes, transfer, etc.)
- 11 Whiptail TUI screens (full CRUD for targets/remotes/schedules)
- CLI entrypoint with subcommands for scripting/cron
- Support for SSH, local, S3, and Google Drive remotes
- rsync --link-dest incremental snapshots
- Root and user mode (XDG paths)
- 70 passing tests
- Config templates, installer, uninstaller

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 21:15:29 +02:00