add graceful handling of duplicate channel names
This commit is contained in:
parent
fea2f8f573
commit
27f8d98c69
4 changed files with 58 additions and 10 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import sys
|
||||
import asyncio
|
||||
import logging
|
||||
from src.ui.disco_reaper_app import run_disco_reaper
|
||||
from src.ui.reaper_app import run_disco_reaper
|
||||
from src.core.configuration import load_config
|
||||
|
||||
def setup_logging():
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import sys
|
|||
import asyncio
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from src.ui.app import run_cli
|
||||
from src.ui.shuttle_app import run_cli
|
||||
from src.core.configuration import load_config
|
||||
|
||||
def setup_logging():
|
||||
|
|
|
|||
|
|
@ -85,10 +85,10 @@ class DiscoReaperCLI:
|
|||
console.print("(1) Backup Server Profile")
|
||||
console.print("(2) Backup Messages")
|
||||
console.print("(3) Update & Sync Backup")
|
||||
console.print("(C) Configuration")
|
||||
console.print("(4) Configuration")
|
||||
console.print("(Q) Exit")
|
||||
|
||||
choice = Prompt.ask("\nSelect an option", choices=["1", "2", "3", "C", "Q"], default="Q", show_choices=False).upper()
|
||||
choice = Prompt.ask("\nSelect an option", choices=["1", "2", "3", "4", "Q"], default="Q", show_choices=False).upper()
|
||||
|
||||
if choice == "1":
|
||||
await self.backup_server_profile()
|
||||
|
|
@ -96,7 +96,7 @@ class DiscoReaperCLI:
|
|||
await self.backup_messages()
|
||||
elif choice == "3":
|
||||
await self.sync_backup()
|
||||
elif choice == "C":
|
||||
elif choice == "4":
|
||||
await self.edit_configuration()
|
||||
elif choice == "Q":
|
||||
await self.engine.close_connections()
|
||||
|
|
@ -154,7 +154,11 @@ class DiscoReaperCLI:
|
|||
await self.exporter.export_channels_structure()
|
||||
|
||||
# 2. Select Channels
|
||||
all_channels = await self.engine.discord_reader.get_channels()
|
||||
with console.status("[yellow]Fetching channels & categories...[/yellow]"):
|
||||
all_channels = await self.engine.discord_reader.get_channels()
|
||||
all_categories = await self.engine.discord_reader.get_categories()
|
||||
cat_map = {c.id: c.name for c in all_categories}
|
||||
|
||||
# Filter for exportable channels
|
||||
eligible_channels = [
|
||||
c for c in all_channels
|
||||
|
|
@ -166,8 +170,19 @@ class DiscoReaperCLI:
|
|||
return
|
||||
|
||||
console.print(f"\n[bold]Select Channels to Backup ({len(eligible_channels)} total):[/bold]")
|
||||
|
||||
# Identify duplicate names to show categories for them
|
||||
name_counts = {}
|
||||
for chan in eligible_channels:
|
||||
name_counts[chan.name] = name_counts.get(chan.name, 0) + 1
|
||||
|
||||
for i, chan in enumerate(eligible_channels):
|
||||
console.print(f"({i+1}) {chan.name}")
|
||||
display_name = chan.name
|
||||
if name_counts[chan.name] > 1:
|
||||
cat_name = cat_map.get(chan.category_id)
|
||||
if cat_name:
|
||||
display_name = f"{chan.name} [{cat_name}]"
|
||||
console.print(f"({i+1}) {display_name}")
|
||||
|
||||
console.print("(A) [bold green]All Channels[/bold green]")
|
||||
console.print("(B) Back")
|
||||
|
|
@ -1065,17 +1065,30 @@ class MigrationCLI:
|
|||
return
|
||||
|
||||
try:
|
||||
with console.status("[yellow]Fetching Discord channels...[/yellow]"):
|
||||
with console.status("[yellow]Fetching Discord channels & categories...[/yellow]"):
|
||||
await self.engine.start_connections()
|
||||
d_channels = await self.engine.discord_reader.get_channels()
|
||||
d_categories = await self.engine.discord_reader.get_categories()
|
||||
d_cat_map = {c.id: c.name for c in d_categories}
|
||||
|
||||
if not d_channels:
|
||||
console.print("[yellow]No text channels found in Discord server.[/yellow]")
|
||||
return
|
||||
|
||||
console.print("\n[bold]Select Source Discord Channel:[/bold]")
|
||||
|
||||
# Identify duplicate names to show categories for them
|
||||
d_name_counts = {}
|
||||
for ch in d_channels:
|
||||
d_name_counts[ch.name] = d_name_counts.get(ch.name, 0) + 1
|
||||
|
||||
for i, ch in enumerate(d_channels):
|
||||
console.print(f"({i+1}) {ch.name}")
|
||||
display_name = ch.name
|
||||
if d_name_counts[ch.name] > 1:
|
||||
cat_name = d_cat_map.get(ch.category_id)
|
||||
if cat_name:
|
||||
display_name = f"{ch.name} [{cat_name}]"
|
||||
console.print(f"({i+1}) {display_name}")
|
||||
|
||||
console.print("(B) Back")
|
||||
d_choices = [str(i+1) for i in range(len(d_channels))] + ["B", "b"]
|
||||
|
|
@ -1113,8 +1126,28 @@ class MigrationCLI:
|
|||
|
||||
console.print(f"\n[bold]Select Target {platform_name} Channel:[/bold]")
|
||||
|
||||
# Identify duplicate names to show categories for them
|
||||
f_name_counts = {}
|
||||
for ch in f_channels:
|
||||
name = ch.get('name', 'Unnamed Channel')
|
||||
f_name_counts[name] = f_name_counts.get(name, 0) + 1
|
||||
|
||||
# Get category map for target platform
|
||||
# For Fluxer/Stoat, the channel object in f_channels contains 'parent_id'
|
||||
# We need to resolve these IDs to names.
|
||||
target_cat_names = {}
|
||||
for ch in full_f_channels: # use full list including categories (type 4)
|
||||
if ch.get('type') == 4:
|
||||
target_cat_names[str(ch.get('id'))] = ch.get('name')
|
||||
|
||||
for i, ch in enumerate(f_channels):
|
||||
console.print(f"({i+1}) {ch.get('name', 'Unnamed Channel')}")
|
||||
name = ch.get('name', 'Unnamed Channel')
|
||||
display_name = name
|
||||
if f_name_counts[name] > 1:
|
||||
parent_id = ch.get('parent_id')
|
||||
if parent_id and str(parent_id) in target_cat_names:
|
||||
display_name = f"{name} [{target_cat_names[str(parent_id)]}]"
|
||||
console.print(f"({i+1}) {display_name}")
|
||||
|
||||
f_choices = [str(i+1) for i in range(len(f_channels))] + ["B", "b", "N", "n"]
|
||||
|
||||
Loading…
Add table
Reference in a new issue