improve startup behaviour

This commit is contained in:
rambros 2026-02-24 21:53:44 +05:30
parent 478fa85b32
commit 7267253f8b
3 changed files with 128 additions and 28 deletions

View file

@ -1,18 +1,71 @@
import sys
import asyncio
import logging
from pathlib import Path
from src.ui.app import run_cli
from src.core.configuration import load_config
def setup_logging():
def select_config():
from rich.console import Console
from rich.prompt import Prompt
from rich.panel import Panel
console = Console()
fluxer_exists = Path("fluxer.config.yaml").exists()
stoat_exists = Path("stoat.config.yaml").exists()
if fluxer_exists and not stoat_exists:
return "fluxer.config.yaml"
elif stoat_exists and not fluxer_exists:
return "stoat.config.yaml"
elif fluxer_exists and stoat_exists:
console.print(Panel.fit(
"[bold]Both Fluxer and Stoat configurations found.[/bold]\n"
"Which one do you want to use?",
title="[bold cyan]Configuration Selection[/bold cyan]"
))
console.print("(1) [bold blue]Fluxer[/bold blue]")
console.print("(2) [bold red]Stoat[/bold red]")
console.print("(Q) [bold dim]Quit[/bold dim]")
console.print("")
choice = Prompt.ask("Select an option [[bold cyan]1/2/Q[/bold cyan]]", choices=["1", "2", "Q", "q"], show_choices=False).upper()
if choice == "1":
return "fluxer.config.yaml"
elif choice == "2":
return "stoat.config.yaml"
else:
sys.exit(0)
else:
console.print(Panel.fit(
"[bold]First setup, Tool configuration[/bold]\n"
"Which platform do you want to migrate to?",
title="[bold cyan]Initial Setup[/bold cyan]"
))
console.print("(1) [bold blue]Fluxer[/bold blue]")
console.print("(2) [bold red]Stoat[/bold red]")
console.print("(Q) [bold dim]Quit[/bold dim]")
console.print("")
choice = Prompt.ask("Select an option [[bold cyan]1/2/Q[/bold cyan]]", choices=["1", "2", "Q", "q"], show_choices=False).upper()
if choice == "1":
return "fluxer.config.yaml"
elif choice == "2":
return "stoat.config.yaml"
else:
sys.exit(0)
def setup_logging(config_path):
try:
config = load_config()
config = load_config(config_path)
log_level_str = config.migration.log_level.upper()
level = getattr(logging, log_level_str, logging.INFO)
except Exception:
level = logging.INFO
handlers = [logging.FileHandler('fluxer.migration.log', mode='a')]
platform = config_path.split('.')[0]
handlers = [logging.FileHandler(f'{platform}.migration.log', mode='a')]
if level == logging.DEBUG:
handlers.append(logging.StreamHandler(sys.stdout))
@ -87,9 +140,10 @@ def relaunch_in_terminal():
def main():
relaunch_in_terminal()
setup_logging()
config_path = select_config()
setup_logging(config_path)
try:
asyncio.run(run_cli())
asyncio.run(run_cli(config_path))
except KeyboardInterrupt:
print("\nOperation terminated by user.")
sys.exit(0)

View file

@ -55,9 +55,10 @@ console = Console()
class MigrationCLI:
"""Standard CLI app to manage the Discord to Fluxer migration."""
def __init__(self):
def __init__(self, config_path="fluxer.config.yaml"):
self.config_path = config_path
try:
self.config = load_config()
self.config = load_config(self.config_path)
except Exception as e:
console.print(f"[bold red]Failed to load config: {e}[/bold red]")
sys.exit(1)
@ -83,20 +84,38 @@ class MigrationCLI:
}
self.tokens_valid = False
d_token = self.config.discord_bot_token
f_token = self.config.fluxer_bot_token
discord_dummy = d_token in ["YOUR_DISCORD_TOKEN", "DISCORD_BOT_TOKEN", ""]
fluxer_dummy = f_token in ["YOUR_FLUXER_TOKEN", "FLUXER_BOT_TOKEN", "YOUR_STOAT_TOKEN", "STOAT_BOT_TOKEN", ""]
discord_task = None
if not discord_dummy:
discord_task = asyncio.create_task(self.engine.discord_reader.validate())
fluxer_task = None
if not fluxer_dummy:
fluxer_task = asyncio.create_task(self.engine.fluxer_writer.validate())
tasks_to_wait = [t for t in [discord_task, fluxer_task] if t is not None]
try:
with console.status("[yellow]Validating tokens...[/yellow]"):
start_time = asyncio.get_event_loop().time()
done = set()
pending = set()
if tasks_to_wait:
done, pending = await asyncio.wait(
[discord_task, fluxer_task],
tasks_to_wait,
timeout=10.0,
return_when=asyncio.ALL_COMPLETED
)
# Process Discord Result
if discord_task in done:
if discord_dummy:
console.print("[bold yellow]Discord setup incomplete (Using default token).[/bold yellow]")
elif discord_task in done:
try:
res = discord_task.result()
self.validation_results["discord_token"] = res.get("token", False)
@ -120,7 +139,9 @@ class MigrationCLI:
discord_task.cancel()
# Process Fluxer Result
if fluxer_task in done:
if fluxer_dummy:
console.print("[bold yellow]Target Platform setup incomplete (Using default token).[/bold yellow]")
elif fluxer_task in done:
try:
res = fluxer_task.result()
self.validation_results["fluxer_token"] = res.get("token", False)
@ -169,9 +190,24 @@ class MigrationCLI:
finally:
# Ensure tasks are cleaned up
for t in [discord_task, fluxer_task]:
if not t.done(): t.cancel()
if t is not None and not t.done(): t.cancel()
async def run(self):
if self.config.discord_bot_token == "YOUR_DISCORD_TOKEN":
console.print("\n[bold yellow]First time setup detected. Redirecting to configuration...[/bold yellow]")
self.validation_results = {
"discord_token": False, "discord_bot_name": None,
"discord_server": False, "discord_server_name": None,
"discord_intents": {}, "discord_permissions": {},
"fluxer_token": False, "fluxer_bot_name": None,
"fluxer_community": False, "fluxer_community_name": None,
"fluxer_permissions": {},
"discord_timeout": False, "fluxer_timeout": False
}
self.tokens_valid = False
self.permissions_complete = False
await self.edit_configuration(skip_validation=True)
else:
await self.validate_config()
while True:
@ -225,7 +261,8 @@ class MigrationCLI:
await self.engine.close_connections()
break
async def edit_configuration(self):
async def edit_configuration(self, skip_validation=False):
if not skip_validation:
await self.validate_config()
# Display Required Permissions FIRST
@ -264,8 +301,8 @@ class MigrationCLI:
return status
console.print(f"Discord Bot Token {get_status_str(self.validation_results.get('discord_token', False), self.validation_results.get('discord_bot_name'))}")
console.print(f"Fluxer Bot Token {get_status_str(self.validation_results.get('fluxer_token', False), self.validation_results.get('fluxer_bot_name'))}")
console.print(f"Discord Server ID {get_status_str(self.validation_results.get('discord_server', False), self.validation_results.get('discord_server_name'))}")
console.print(f"Fluxer Bot Token {get_status_str(self.validation_results.get('fluxer_token', False), self.validation_results.get('fluxer_bot_name'))}")
console.print(f"Fluxer Community ID {get_status_str(self.validation_results.get('fluxer_community', False), self.validation_results.get('fluxer_community_name'))}")
console.print("\n(1) Edit tokens")
@ -284,8 +321,8 @@ class MigrationCLI:
console.print("\n[bold]Configuration Editor[/bold] (leave blank to keep current)")
d_token = Prompt.ask("Discord Bot Token", default=self.config.discord_bot_token)
f_token = Prompt.ask("Fluxer Bot Token", default=self.config.fluxer_bot_token)
d_server = Prompt.ask("Discord Server ID", default=self.config.discord_server_id)
f_token = Prompt.ask("Fluxer Bot Token", default=self.config.fluxer_bot_token)
f_comm = Prompt.ask("Fluxer Community ID", default=self.config.fluxer_community_id)
# Only rewrite if changed
@ -299,7 +336,7 @@ class MigrationCLI:
self.config.discord_server_id = d_server
self.config.fluxer_community_id = f_comm
save_config(self.config)
save_config(self.config, self.config_path)
# Recreate engine with new config
self.engine = MigrationContext(self.config)
@ -308,11 +345,11 @@ class MigrationCLI:
await self.update_validation_status()
console.print(f"\nDiscord Bot Token {get_status_str(self.validation_results.get('discord_token', False))}")
console.print(f"Fluxer Bot Token {get_status_str(self.validation_results.get('fluxer_token', False))}")
console.print(f"Discord Server ID {get_status_str(self.validation_results.get('discord_server', False))}")
console.print(f"Fluxer Bot Token {get_status_str(self.validation_results.get('fluxer_token', False))}")
console.print(f"Fluxer Community ID {get_status_str(self.validation_results.get('fluxer_community', False))}")
console.print("[bold green]Configuration updated and saved to fluxer.config.yaml![/bold green]")
console.print(f"[bold green]Configuration updated and saved to {self.config_path}![/bold green]")
else:
console.print("[yellow]No changes made.[/yellow]")
@ -1290,6 +1327,6 @@ class MigrationCLI:
async def run_cli():
cli = MigrationCLI()
async def run_cli(config_path="fluxer.config.yaml"):
cli = MigrationCLI(config_path)
await cli.run()

View file

@ -0,0 +1,9 @@
discord_bot_token: DISCORD_BOT_TOKEN # Token used to connect the Discord Bot
discord_server_id: 'DISCORD_SERVER_ID' # ID of the source Discord Server
stoat_bot_token: STOAT_BOT_TOKEN # Token used to connect the Stoat Bot
stoat_server_id: 'STOAT_SERVER_ID' # ID of the target Stoat Server
stoat_api_url: 'default' # URL of the Stoat API (default is https://api.stoat.chat)
migration:
batch_size: 50
rate_limit_delay_seconds: 2
log_level: INFO