add re-parenting logic for new categories
This commit is contained in:
parent
27ace55242
commit
af0c9914ab
4 changed files with 63 additions and 16 deletions
|
|
@ -213,23 +213,47 @@ class MigrationEngine:
|
|||
categories = await self.discord_reader.get_categories()
|
||||
channels = await self.discord_reader.get_channels()
|
||||
|
||||
# Filter items if not forcing
|
||||
if not force:
|
||||
categories = [cat for cat in categories if not self.state.get_fluxer_category_id(str(cat.id))]
|
||||
channels = [ch for ch in channels if not self.state.get_fluxer_channel_id(str(ch.id))]
|
||||
# 1. Identify categories to create
|
||||
missing_categories = [cat for cat in categories if force or not self.state.get_fluxer_category_id(str(cat.id))]
|
||||
missing_category_ids = {str(cat.id) for cat in missing_categories}
|
||||
|
||||
total = len(categories) + len(channels)
|
||||
# 2. Identify channels to create or move
|
||||
# Fetch current Fluxer state to check parent_ids
|
||||
fluxer_channels = await self.fluxer_writer.get_channels()
|
||||
fluxer_parent_map = {str(c["id"]): (str(c.get("parent_id")) if c.get("parent_id") else None) for c in fluxer_channels}
|
||||
|
||||
channels_to_create = []
|
||||
channels_to_move = []
|
||||
|
||||
for ch in channels:
|
||||
discord_id = str(ch.id)
|
||||
fluxer_id = self.state.get_fluxer_channel_id(discord_id)
|
||||
discord_parent_id = str(ch.category_id) if ch.category_id else None
|
||||
|
||||
if force or not fluxer_id:
|
||||
# We'll resolve the parent_id in the loop after categories are created
|
||||
channels_to_create.append(ch)
|
||||
else:
|
||||
current_fluxer_parent = fluxer_parent_map.get(fluxer_id)
|
||||
# Case A: Its category is being created right now
|
||||
# Case B: It has a category that exists but is not set in Fluxer correctly
|
||||
will_create_parent = discord_parent_id in missing_category_ids
|
||||
expected_parent_fluxer_id = self.state.get_fluxer_category_id(discord_parent_id) if discord_parent_id else None
|
||||
|
||||
if will_create_parent or current_fluxer_parent != expected_parent_fluxer_id:
|
||||
channels_to_move.append((ch, fluxer_id))
|
||||
|
||||
total = len(missing_categories) + len(channels_to_create) + len(channels_to_move)
|
||||
current_idx = 0
|
||||
|
||||
if total == 0:
|
||||
return
|
||||
|
||||
# Migrate Categories first
|
||||
for cat in categories:
|
||||
for cat in missing_categories:
|
||||
if not self.is_running: break
|
||||
|
||||
state_key = str(cat.id)
|
||||
# 4 corresponds to Category type in Discord/Fluxer typically
|
||||
fluxer_id = await self.fluxer_writer.create_channel(cat.name, type=4)
|
||||
self.state.set_category_mapping(state_key, fluxer_id)
|
||||
|
||||
|
|
@ -237,8 +261,8 @@ class MigrationEngine:
|
|||
if progress_callback: await progress_callback(f"Cat: {cat.name}", "Copying", current_idx, total)
|
||||
await asyncio.sleep(self.config.migration.rate_limit_delay_seconds)
|
||||
|
||||
# Migrate Text Channels
|
||||
for channel in channels:
|
||||
# Create missing channels
|
||||
for channel in channels_to_create:
|
||||
if not self.is_running: break
|
||||
|
||||
state_key = str(channel.id)
|
||||
|
|
@ -257,6 +281,17 @@ class MigrationEngine:
|
|||
if progress_callback: await progress_callback(channel.name, "Copying", current_idx, total)
|
||||
await asyncio.sleep(self.config.migration.rate_limit_delay_seconds)
|
||||
|
||||
# Move existing channels if needed
|
||||
for channel, fluxer_id in channels_to_move:
|
||||
if not self.is_running: break
|
||||
|
||||
parent_id = self.state.get_fluxer_category_id(str(channel.category_id)) if channel.category_id else None
|
||||
await self.fluxer_writer.move_channel(fluxer_id, parent_id)
|
||||
|
||||
current_idx += 1
|
||||
if progress_callback: await progress_callback(channel.name, "Moving", current_idx, total)
|
||||
await asyncio.sleep(self.config.migration.rate_limit_delay_seconds)
|
||||
|
||||
async def sync_permissions(self, progress_callback: Callable[[str, int, int], Awaitable[None]] | None = None):
|
||||
"""Syncs category and channel role overrides/permissions."""
|
||||
categories = await self.discord_reader.get_categories()
|
||||
|
|
|
|||
|
|
@ -138,4 +138,5 @@ class DiscordReader:
|
|||
return await attachment.read()
|
||||
|
||||
async def close(self):
|
||||
if self.client:
|
||||
await self.client.close()
|
||||
|
|
|
|||
|
|
@ -119,6 +119,17 @@ class FluxerWriter:
|
|||
)
|
||||
return str(guild_channel["id"])
|
||||
|
||||
async def move_channel(self, channel_id: str, parent_id: Optional[str]) -> bool:
|
||||
"""
|
||||
Updates the parent category of an existing channel.
|
||||
"""
|
||||
assert self.client is not None
|
||||
await self.client.modify_channel(
|
||||
channel_id=channel_id,
|
||||
parent_id=parent_id
|
||||
)
|
||||
return True
|
||||
|
||||
async def get_channels(self) -> List[Dict[str, Any]]:
|
||||
"""Returns all channels in the community."""
|
||||
assert self.client is not None
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ class MigrationCLI:
|
|||
f_display = f"[bold green]\"{f_name}\"[/bold green]" if f_name else "[bold red]NOT SET UP[/bold red]"
|
||||
|
||||
console.print(f"[bold cyan]Discord Server:[/bold cyan] {d_display}")
|
||||
console.print(f"[bold magenta]Fluxer Community:[/bold magenta] {f_display}")
|
||||
console.print(f"[bold #4641D9]Fluxer Community:[/bold #4641D9] {f_display}")
|
||||
console.print("[bold]Main Menu[/bold]")
|
||||
console.print("(1) Clone Server Template (Channels & Categories)")
|
||||
console.print("(2) Copy Roles & Permissions")
|
||||
|
|
@ -249,7 +249,7 @@ class MigrationCLI:
|
|||
await self.engine.close_connections()
|
||||
return
|
||||
|
||||
table = Table(show_header=True, header_style="bold magenta")
|
||||
table = Table(show_header=True, header_style="bold #4641D9")
|
||||
table.add_column("Type", width=12)
|
||||
table.add_column("Discord Name")
|
||||
table.add_column("Status", justify="right")
|
||||
|
|
@ -370,7 +370,7 @@ class MigrationCLI:
|
|||
|
||||
roles = await self.engine.discord_reader.get_roles()
|
||||
|
||||
table = Table(show_header=True, header_style="bold magenta")
|
||||
table = Table(show_header=True, header_style="bold #4641D9")
|
||||
table.add_column("Discord Role")
|
||||
table.add_column("Status", justify="center")
|
||||
table.add_column("Fluxer ID", justify="right")
|
||||
|
|
@ -484,7 +484,7 @@ class MigrationCLI:
|
|||
emojis = await self.engine.discord_reader.get_emojis()
|
||||
stickers = await self.engine.discord_reader.get_stickers()
|
||||
|
||||
table = Table(show_header=True, header_style="bold magenta")
|
||||
table = Table(show_header=True, header_style="bold #4641D9")
|
||||
table.add_column("Type", width=10)
|
||||
table.add_column("Name")
|
||||
table.add_column("Status", justify="right")
|
||||
|
|
@ -804,7 +804,7 @@ class MigrationCLI:
|
|||
finally:
|
||||
self.engine.is_running = False
|
||||
|
||||
table = Table(show_header=True, header_style="bold magenta", title="Migration Summary & Estimates")
|
||||
table = Table(show_header=True, header_style="bold #4641D9", title="Migration Summary & Estimates")
|
||||
table.add_column("Item", width=15)
|
||||
table.add_column("Count", justify="right", width=10)
|
||||
table.add_column("Overhead/Details")
|
||||
|
|
@ -829,7 +829,7 @@ class MigrationCLI:
|
|||
console.print("")
|
||||
console.print(table)
|
||||
|
||||
if not Confirm.ask(f"\nMigrate messages from Discord [cyan]#{source_channel.name}[/cyan] to Fluxer [magenta]#{target_channel.get('name')}[/magenta]?"):
|
||||
if not Confirm.ask(f"\nMigrate messages from Discord [cyan]#{source_channel.name}[/cyan] to Fluxer [#4641D9]#{target_channel.get('name')}[/#4641D9]?"):
|
||||
return
|
||||
|
||||
# 5. Migration Execution
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue