mirror of
https://github.com/Benexl/FastAnime.git
synced 2025-12-26 04:41:34 -08:00
255 lines
7.8 KiB
Python
255 lines
7.8 KiB
Python
"""
|
|
Session management menu for the interactive CLI.
|
|
Provides options to save, load, and manage session state.
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from typing import Callable, Dict
|
|
|
|
from rich.console import Console
|
|
from rich.table import Table
|
|
|
|
from ....core.constants import APP_DIR
|
|
from ...utils.feedback import create_feedback_manager
|
|
from ..session import Context, session
|
|
from ..state import ControlFlow, State
|
|
|
|
MenuAction = Callable[[], str]
|
|
|
|
|
|
@session.menu
|
|
def session_management(ctx: Context, state: State) -> State | ControlFlow:
|
|
"""
|
|
Session management menu for saving, loading, and managing session state.
|
|
"""
|
|
icons = ctx.config.general.icons
|
|
feedback = create_feedback_manager(icons)
|
|
console = Console()
|
|
console.clear()
|
|
|
|
# Show current session stats
|
|
_display_session_info(console, icons)
|
|
|
|
options: Dict[str, MenuAction] = {
|
|
f"{'💾 ' if icons else ''}Save Current Session": lambda: _save_session(
|
|
ctx, feedback
|
|
),
|
|
f"{'📂 ' if icons else ''}Load Session": lambda: _load_session(ctx, feedback),
|
|
f"{'📋 ' if icons else ''}List Saved Sessions": lambda: _list_sessions(
|
|
ctx, feedback
|
|
),
|
|
f"{'🗑️ ' if icons else ''}Cleanup Old Sessions": lambda: _cleanup_sessions(
|
|
ctx, feedback
|
|
),
|
|
f"{'💾 ' if icons else ''}Create Manual Backup": lambda: _create_backup(
|
|
ctx, feedback
|
|
),
|
|
f"{'⚙️ ' if icons else ''}Session Settings": lambda: _session_settings(
|
|
ctx, feedback
|
|
),
|
|
f"{'🔙 ' if icons else ''}Back to Main Menu": lambda: "BACK",
|
|
}
|
|
|
|
choice_str = ctx.selector.choose(
|
|
prompt="Select Session Action",
|
|
choices=list(options.keys()),
|
|
header="Session Management",
|
|
)
|
|
|
|
if not choice_str:
|
|
return ControlFlow.BACK
|
|
|
|
result = options[choice_str]()
|
|
|
|
if result == "BACK":
|
|
return ControlFlow.BACK
|
|
else:
|
|
return ControlFlow.CONTINUE
|
|
|
|
|
|
def _display_session_info(console: Console, icons: bool):
|
|
"""Display current session information."""
|
|
session_stats = session.get_session_stats()
|
|
|
|
table = Table(title=f"{'📊 ' if icons else ''}Current Session Info")
|
|
table.add_column("Property", style="cyan")
|
|
table.add_column("Value", style="green")
|
|
|
|
table.add_row("Current States", str(session_stats["current_states"]))
|
|
table.add_row("Current Menu", session_stats["current_menu"] or "None")
|
|
table.add_row(
|
|
"Auto-Save", "Enabled" if session_stats["auto_save_enabled"] else "Disabled"
|
|
)
|
|
table.add_row("Has Auto-Save", "Yes" if session_stats["has_auto_save"] else "No")
|
|
table.add_row(
|
|
"Has Crash Backup", "Yes" if session_stats["has_crash_backup"] else "No"
|
|
)
|
|
|
|
console.print(table)
|
|
console.print()
|
|
|
|
|
|
def _save_session(ctx: Context, feedback) -> str:
|
|
"""Save the current session."""
|
|
session_name = ctx.selector.ask("Enter session name (optional):")
|
|
description = ctx.selector.ask("Enter session description (optional):")
|
|
|
|
if not session_name:
|
|
session_name = f"session_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
|
|
|
|
sessions_dir = APP_DIR / "sessions"
|
|
file_path = sessions_dir / f"{session_name}.json"
|
|
|
|
if file_path.exists():
|
|
if not feedback.confirm(f"Session '{session_name}' already exists. Overwrite?"):
|
|
feedback.info("Save cancelled")
|
|
return "CONTINUE"
|
|
|
|
success = session.save(file_path, session_name, description or "")
|
|
if success:
|
|
feedback.success(f"Session saved as '{session_name}'")
|
|
|
|
return "CONTINUE"
|
|
|
|
|
|
def _load_session(ctx: Context, feedback) -> str:
|
|
"""Load a saved session."""
|
|
sessions = session.list_saved_sessions()
|
|
|
|
if not sessions:
|
|
feedback.warning("No saved sessions found")
|
|
return "CONTINUE"
|
|
|
|
# Create choices with session info
|
|
choices = []
|
|
session_map = {}
|
|
|
|
for sess in sessions:
|
|
choice_text = f"{sess['name']} - {sess['description'][:50]}{'...' if len(sess['description']) > 50 else ''}"
|
|
choices.append(choice_text)
|
|
session_map[choice_text] = sess
|
|
|
|
choices.append("Cancel")
|
|
|
|
choice = ctx.selector.choose(
|
|
"Select session to load:", choices=choices, header="Available Sessions"
|
|
)
|
|
|
|
if not choice or choice == "Cancel":
|
|
return "CONTINUE"
|
|
|
|
selected_session = session_map[choice]
|
|
file_path = Path(selected_session["path"])
|
|
|
|
if feedback.confirm(
|
|
f"Load session '{selected_session['name']}'? This will replace your current session."
|
|
):
|
|
success = session.resume(file_path, feedback)
|
|
if success:
|
|
feedback.info("Session loaded successfully. Returning to main menu.")
|
|
# Return to main menu after loading
|
|
return "MAIN"
|
|
|
|
return "CONTINUE"
|
|
|
|
|
|
def _list_sessions(ctx: Context, feedback) -> str:
|
|
"""List all saved sessions."""
|
|
sessions = session.list_saved_sessions()
|
|
|
|
if not sessions:
|
|
feedback.info("No saved sessions found")
|
|
return "CONTINUE"
|
|
|
|
console = Console()
|
|
table = Table(title="Saved Sessions")
|
|
table.add_column("Name", style="cyan")
|
|
table.add_column("Description", style="yellow")
|
|
table.add_column("States", style="green")
|
|
table.add_column("Created", style="blue")
|
|
|
|
for sess in sessions:
|
|
# Format the created date
|
|
created = sess["created"]
|
|
if "T" in created:
|
|
created = created.split("T")[0] # Just show the date part
|
|
|
|
table.add_row(
|
|
sess["name"],
|
|
sess["description"][:40] + "..."
|
|
if len(sess["description"]) > 40
|
|
else sess["description"],
|
|
str(sess["state_count"]),
|
|
created,
|
|
)
|
|
|
|
console.print(table)
|
|
feedback.pause_for_user()
|
|
|
|
return "CONTINUE"
|
|
|
|
|
|
def _cleanup_sessions(ctx: Context, feedback) -> str:
|
|
"""Clean up old sessions."""
|
|
sessions = session.list_saved_sessions()
|
|
|
|
if len(sessions) <= 5:
|
|
feedback.info("No cleanup needed. You have 5 or fewer sessions.")
|
|
return "CONTINUE"
|
|
|
|
max_sessions_str = ctx.selector.ask("How many sessions to keep? (default: 10)")
|
|
try:
|
|
max_sessions = int(max_sessions_str) if max_sessions_str else 10
|
|
except ValueError:
|
|
feedback.error("Invalid number entered")
|
|
return "CONTINUE"
|
|
|
|
if feedback.confirm(f"Delete sessions older than the {max_sessions} most recent?"):
|
|
deleted_count = session.cleanup_old_sessions(max_sessions)
|
|
feedback.success(f"Deleted {deleted_count} old sessions")
|
|
|
|
return "CONTINUE"
|
|
|
|
|
|
def _create_backup(ctx: Context, feedback) -> str:
|
|
"""Create a manual backup."""
|
|
backup_name = ctx.selector.ask("Enter backup name (optional):")
|
|
|
|
success = session.create_manual_backup(backup_name or "")
|
|
if success:
|
|
feedback.success("Manual backup created successfully")
|
|
|
|
return "CONTINUE"
|
|
|
|
|
|
def _session_settings(ctx: Context, feedback) -> str:
|
|
"""Configure session settings."""
|
|
current_auto_save = session._auto_save_enabled
|
|
|
|
choices = [
|
|
f"Auto-Save: {'Enabled' if current_auto_save else 'Disabled'}",
|
|
"Clear Auto-Save File",
|
|
"Clear Crash Backup",
|
|
"Back",
|
|
]
|
|
|
|
choice = ctx.selector.choose("Session Settings:", choices=choices)
|
|
|
|
if choice and choice.startswith("Auto-Save"):
|
|
new_setting = not current_auto_save
|
|
session.enable_auto_save(new_setting)
|
|
feedback.success(f"Auto-save {'enabled' if new_setting else 'disabled'}")
|
|
|
|
elif choice == "Clear Auto-Save File":
|
|
if feedback.confirm("Clear the auto-save file?"):
|
|
session._session_manager.clear_auto_save()
|
|
feedback.success("Auto-save file cleared")
|
|
|
|
elif choice == "Clear Crash Backup":
|
|
if feedback.confirm("Clear the crash backup file?"):
|
|
session._session_manager.clear_crash_backup()
|
|
feedback.success("Crash backup cleared")
|
|
|
|
return "CONTINUE"
|