Make TUI the default mode for luk sync command

- luk sync now launches interactive TUI dashboard by default
- Add --once flag for single sync (non-interactive)
- Add --daemon flag for background daemon mode
- Keep 'luk sync run' as legacy subcommand for backwards compatibility
- Move common options (org, vdir, notify, etc.) to group level
This commit is contained in:
Bendt
2025-12-19 10:33:48 -05:00
parent d4226caf0a
commit 48d2455b9c

View File

@@ -588,10 +588,149 @@ async def _sync_outlook_data(
click.echo("Sync complete.")
@click.group()
def sync():
"""Email and calendar synchronization."""
pass
@click.group(invoke_without_command=True)
@click.option(
"--once",
is_flag=True,
help="Run a single sync and exit (non-interactive).",
default=False,
)
@click.option(
"--daemon",
is_flag=True,
help="Run in background daemon mode.",
default=False,
)
@click.option(
"--org",
help="Specify the organization name for the subfolder to store emails and calendar events",
default="corteva",
)
@click.option(
"--vdir",
help="Output calendar events in vdir format to the specified directory",
default="~/Calendar",
)
@click.option(
"--notify/--no-notify",
help="Send macOS notifications for new email messages",
default=True,
)
@click.option(
"--dry-run",
is_flag=True,
help="Run in dry-run mode without making changes.",
default=False,
)
@click.option(
"--demo",
is_flag=True,
help="Run with simulated sync (demo mode)",
default=False,
)
@click.option(
"--days-back",
type=int,
help="Number of days to look back for calendar events",
default=1,
)
@click.option(
"--days-forward",
type=int,
help="Number of days to look forward for calendar events",
default=30,
)
@click.option(
"--download-attachments",
is_flag=True,
help="Download email attachments",
default=False,
)
@click.option(
"--two-way-calendar",
is_flag=True,
help="Enable two-way calendar sync (sync local changes to server)",
default=False,
)
@click.pass_context
def sync(
ctx,
once,
daemon,
org,
vdir,
notify,
dry_run,
demo,
days_back,
days_forward,
download_attachments,
two_way_calendar,
):
"""Email and calendar synchronization.
By default, opens the interactive TUI dashboard.
Use --once for a single sync, or --daemon for background mode.
"""
# If a subcommand is invoked, let it handle everything
if ctx.invoked_subcommand is not None:
return
# Handle the default behavior (no subcommand)
if daemon:
# Run in daemon mode
from .sync_daemon import create_daemon_config, SyncDaemon
config = create_daemon_config(
dry_run=dry_run,
vdir=vdir,
icsfile=None,
org=org,
days_back=days_back,
days_forward=days_forward,
continue_iteration=False,
download_attachments=download_attachments,
two_way_calendar=two_way_calendar,
notify=notify,
)
daemon_instance = SyncDaemon(config)
daemon_instance.start()
elif once:
# Run a single sync (non-interactive)
asyncio.run(
_sync_outlook_data(
dry_run,
vdir,
None, # icsfile
org,
days_back,
days_forward,
False, # continue_iteration
download_attachments,
two_way_calendar,
notify,
)
)
else:
# Default: Launch interactive TUI dashboard
from .sync_dashboard import run_dashboard_sync
sync_config = {
"org": org,
"vdir": vdir,
"notify": notify,
"dry_run": dry_run,
"days_back": days_back,
"days_forward": days_forward,
"download_attachments": download_attachments,
"two_way_calendar": two_way_calendar,
"continue_iteration": False,
"icsfile": None,
}
asyncio.run(
run_dashboard_sync(notify=notify, sync_config=sync_config, demo_mode=demo)
)
def daemonize():
@@ -682,18 +821,6 @@ def daemonize():
help="Enable two-way calendar sync (sync local changes to server)",
default=False,
)
@click.option(
"--daemon",
is_flag=True,
help="Run in daemon mode.",
default=False,
)
@click.option(
"--dashboard",
is_flag=True,
help="Run with TUI dashboard.",
default=False,
)
@click.option(
"--notify",
is_flag=True,
@@ -710,59 +837,23 @@ def run(
continue_iteration,
download_attachments,
two_way_calendar,
daemon,
dashboard,
notify,
):
if dashboard:
from .sync_dashboard import run_dashboard_sync
sync_config = {
"dry_run": dry_run,
"vdir": vdir,
"icsfile": icsfile,
"org": org,
"days_back": days_back,
"days_forward": days_forward,
"continue_iteration": continue_iteration,
"download_attachments": download_attachments,
"two_way_calendar": two_way_calendar,
"notify": notify,
}
asyncio.run(run_dashboard_sync(notify=notify, sync_config=sync_config))
elif daemon:
from .sync_daemon import create_daemon_config, SyncDaemon
config = create_daemon_config(
dry_run=dry_run,
vdir=vdir,
icsfile=icsfile,
org=org,
days_back=days_back,
days_forward=days_forward,
continue_iteration=continue_iteration,
download_attachments=download_attachments,
two_way_calendar=two_way_calendar,
notify=notify,
)
daemon_instance = SyncDaemon(config)
daemon_instance.start()
else:
asyncio.run(
_sync_outlook_data(
dry_run,
vdir,
icsfile,
org,
days_back,
days_forward,
continue_iteration,
download_attachments,
two_way_calendar,
notify,
)
"""Run a single sync operation (legacy command, prefer 'luk sync --once')."""
asyncio.run(
_sync_outlook_data(
dry_run,
vdir,
icsfile,
org,
days_back,
days_forward,
continue_iteration,
download_attachments,
two_way_calendar,
notify,
)
)
@sync.command()