Complete Phase 1: parallel sync, IPC, theme colors, lazy CLI loading
- Sync: Parallelize message downloads with asyncio.gather (batch size 5) - Sync: Increase HTTP semaphore from 2 to 5 concurrent requests - Sync: Add IPC notifications to sync daemon after sync completes - Mail: Replace all hardcoded RGB colors with theme variables - Mail: Remove envelope icon/checkbox gap (padding cleanup) - Mail: Add IPC listener for refresh notifications from sync - Calendar: Style current time line with error color and solid line - Tasks: Fix table not displaying (CSS grid to horizontal layout) - CLI: Implement lazy command loading for faster startup (~12s to ~0.3s) - Add PROJECT_PLAN.md with full improvement roadmap - Add src/utils/ipc.py for Unix socket cross-app communication
This commit is contained in:
@@ -1,37 +1,55 @@
|
||||
# CLI module for the application
|
||||
# Uses lazy imports to speed up startup time
|
||||
|
||||
import click
|
||||
|
||||
from .sync import sync
|
||||
from .drive import drive
|
||||
from .email import email
|
||||
from .calendar import calendar
|
||||
from .ticktick import ticktick
|
||||
from .godspeed import godspeed
|
||||
from .gitlab_monitor import gitlab_monitor
|
||||
from .tasks import tasks
|
||||
import importlib
|
||||
|
||||
|
||||
@click.group()
|
||||
class LazyGroup(click.Group):
|
||||
"""A click Group that lazily loads subcommands."""
|
||||
|
||||
def __init__(self, *args, lazy_subcommands=None, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._lazy_subcommands = lazy_subcommands or {}
|
||||
|
||||
def list_commands(self, ctx):
|
||||
base = super().list_commands(ctx)
|
||||
lazy = list(self._lazy_subcommands.keys())
|
||||
return sorted(base + lazy)
|
||||
|
||||
def get_command(self, ctx, cmd_name):
|
||||
if cmd_name in self._lazy_subcommands:
|
||||
return self._load_command(cmd_name)
|
||||
return super().get_command(ctx, cmd_name)
|
||||
|
||||
def _load_command(self, cmd_name):
|
||||
module_path, attr_name = self._lazy_subcommands[cmd_name]
|
||||
# Handle relative imports
|
||||
if module_path.startswith("."):
|
||||
module = importlib.import_module(module_path, package="src.cli")
|
||||
else:
|
||||
module = importlib.import_module(module_path)
|
||||
return getattr(module, attr_name)
|
||||
|
||||
|
||||
# Create CLI with lazy loading - commands only imported when invoked
|
||||
@click.group(
|
||||
cls=LazyGroup,
|
||||
lazy_subcommands={
|
||||
"sync": (".sync", "sync"),
|
||||
"drive": (".drive", "drive"),
|
||||
"email": (".email", "email"),
|
||||
"mail": (".email", "email"), # alias
|
||||
"calendar": (".calendar", "calendar"),
|
||||
"ticktick": (".ticktick", "ticktick"),
|
||||
"tt": (".ticktick", "ticktick"), # alias
|
||||
"godspeed": (".godspeed", "godspeed"),
|
||||
"gs": (".godspeed", "godspeed"), # alias
|
||||
"gitlab_monitor": (".gitlab_monitor", "gitlab_monitor"),
|
||||
"glm": (".gitlab_monitor", "gitlab_monitor"), # alias
|
||||
"tasks": (".tasks", "tasks"),
|
||||
},
|
||||
)
|
||||
def cli():
|
||||
"""Root command for the CLI."""
|
||||
"""LUK - Local Unix Kit for productivity."""
|
||||
pass
|
||||
|
||||
|
||||
cli.add_command(sync)
|
||||
cli.add_command(drive)
|
||||
cli.add_command(email)
|
||||
cli.add_command(calendar)
|
||||
cli.add_command(ticktick)
|
||||
cli.add_command(godspeed)
|
||||
cli.add_command(gitlab_monitor)
|
||||
cli.add_command(tasks)
|
||||
|
||||
# Add 'mail' as an alias for email
|
||||
cli.add_command(email, name="mail")
|
||||
# Add 'tt' as a short alias for ticktick
|
||||
cli.add_command(ticktick, name="tt")
|
||||
# Add 'gs' as a short alias for godspeed
|
||||
cli.add_command(godspeed, name="gs")
|
||||
# Add 'glm' as a short alias for gitlab_monitor
|
||||
cli.add_command(gitlab_monitor, name="glm")
|
||||
|
||||
@@ -14,6 +14,7 @@ from typing import Optional, Dict, Any
|
||||
|
||||
from src.cli.sync import _sync_outlook_data, should_run_godspeed_sync, should_run_sweep
|
||||
from src.cli.sync import run_godspeed_sync, run_task_sweep, load_sync_state
|
||||
from src.utils.ipc import notify_all, notify_refresh
|
||||
|
||||
|
||||
class SyncDaemon:
|
||||
@@ -247,6 +248,13 @@ class SyncDaemon:
|
||||
notify=self.config.get("notify", False),
|
||||
)
|
||||
self.logger.info("Sync completed successfully")
|
||||
|
||||
# Notify all running TUI apps to refresh their data
|
||||
results = await notify_all({"source": "sync_daemon"})
|
||||
notified = [app for app, success in results.items() if success]
|
||||
if notified:
|
||||
self.logger.info(f"Notified apps to refresh: {', '.join(notified)}")
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"Sync failed: {e}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user