improve role mapping and permission syncing
This commit is contained in:
parent
c5abc6d0e5
commit
ab31f889a4
4 changed files with 107 additions and 11 deletions
|
|
@ -158,6 +158,36 @@ class MigrationEngine:
|
|||
if updates > 0 or removals > 0:
|
||||
logger.info(f"Channel sync: {updates} mapped, {removals} stale mappings removed")
|
||||
|
||||
async def sync_roles_state(self):
|
||||
"""
|
||||
Scans Fluxer for roles matching Discord names and updates state.json mappings.
|
||||
"""
|
||||
discord_roles = await self.discord_reader.get_roles()
|
||||
fluxer_roles = await self.fluxer_writer.client.get_guild_roles(self.config.fluxer_community_id)
|
||||
|
||||
# Build name -> id maps and ID sets for Fluxer for fast lookup
|
||||
fluxer_role_map = {r.get("name"): str(r.get("id")) for r in fluxer_roles if r.get("name")}
|
||||
fluxer_role_ids = {str(r.get("id")) for r in fluxer_roles}
|
||||
|
||||
updates = 0
|
||||
removals = 0
|
||||
|
||||
# Verify and Sync Roles
|
||||
for role in discord_roles:
|
||||
discord_id = str(role.id)
|
||||
fluxer_id = self.state.get_fluxer_role_id(discord_id)
|
||||
|
||||
if fluxer_id:
|
||||
if fluxer_id not in fluxer_role_ids:
|
||||
self.state.remove_role_mapping(discord_id)
|
||||
removals += 1
|
||||
elif role.name in fluxer_role_map:
|
||||
self.state.set_role_mapping(discord_id, fluxer_role_map[role.name])
|
||||
updates += 1
|
||||
|
||||
if updates > 0 or removals > 0:
|
||||
logger.info(f"Role sync: {updates} mapped, {removals} stale mappings removed")
|
||||
|
||||
async def sync_assets_state(self):
|
||||
"""
|
||||
Scans Fluxer for emojis and stickers matching Discord names and updates state.json mappings.
|
||||
|
|
@ -310,12 +340,38 @@ class MigrationEngine:
|
|||
if total == 0:
|
||||
return
|
||||
|
||||
async def _sync_overwrites(discord_item, fluxer_id):
|
||||
"""Helper to sync role overwrites for a given channel or category."""
|
||||
for target, overwrite in discord_item.overwrites.items():
|
||||
if type(target).__name__ == "Role":
|
||||
discord_role_id = str(target.id)
|
||||
# Handle @everyone role special case
|
||||
if discord_role_id == self.config.discord_server_id:
|
||||
fluxer_role_id = self.config.fluxer_community_id
|
||||
else:
|
||||
fluxer_role_id = self.state.get_fluxer_role_id(discord_role_id)
|
||||
|
||||
if not fluxer_role_id:
|
||||
continue
|
||||
|
||||
allow_val, deny_val = overwrite.pair()
|
||||
await self.fluxer_writer.set_channel_permission(
|
||||
channel_id=fluxer_id,
|
||||
overwrite_id=fluxer_role_id,
|
||||
allow=allow_val.value,
|
||||
deny=deny_val.value,
|
||||
is_role=True
|
||||
)
|
||||
|
||||
# Sync Category Permissions (Role Overwrites)
|
||||
for cat in categories:
|
||||
if not self.is_running: break
|
||||
fluxer_id = self.state.get_fluxer_channel_id(str(cat.id))
|
||||
# In a real implementation, we would diff discord perms
|
||||
# and apply them to fluxer_id using client methods.
|
||||
fluxer_id = self.state.get_fluxer_category_id(str(cat.id))
|
||||
if fluxer_id:
|
||||
try:
|
||||
await _sync_overwrites(cat, fluxer_id)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed syncing permissions for category {cat.name}: {e}")
|
||||
|
||||
current_idx += 1
|
||||
if progress_callback: await progress_callback(f"Cat: {cat.name}", current_idx, total)
|
||||
|
|
@ -324,7 +380,11 @@ class MigrationEngine:
|
|||
for channel in channels:
|
||||
if not self.is_running: break
|
||||
fluxer_id = self.state.get_fluxer_channel_id(str(channel.id))
|
||||
# apply perms
|
||||
if fluxer_id:
|
||||
try:
|
||||
await _sync_overwrites(channel, fluxer_id)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed syncing permissions for channel {channel.name}: {e}")
|
||||
|
||||
current_idx += 1
|
||||
if progress_callback: await progress_callback(channel.name, current_idx, total)
|
||||
|
|
|
|||
|
|
@ -107,6 +107,10 @@ class MigrationState:
|
|||
def get_fluxer_role_id(self, discord_id: str) -> str | None:
|
||||
return self.role_map.get(str(discord_id))
|
||||
|
||||
def remove_role_mapping(self, discord_id: str):
|
||||
self.role_map.pop(str(discord_id), None)
|
||||
self.save()
|
||||
|
||||
def set_emoji_mapping(self, discord_id: str, fluxer_id: str):
|
||||
self.emoji_map[str(discord_id)] = str(fluxer_id)
|
||||
self.save()
|
||||
|
|
|
|||
|
|
@ -436,9 +436,16 @@ class FluxerWriter:
|
|||
overwrites = ch.get("permission_overwrites", [])
|
||||
for ow in overwrites:
|
||||
try:
|
||||
await self.client.delete_channel_permission(ch["id"], ow["id"])
|
||||
except Exception:
|
||||
pass
|
||||
await self.client.request(
|
||||
self.client._route(
|
||||
"DELETE",
|
||||
"/channels/{channel_id}/permissions/{overwrite_id}",
|
||||
channel_id=ch["id"],
|
||||
overwrite_id=ow["id"]
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to delete overwrite {ow['id']} for channel {ch['id']}: {e}")
|
||||
processed += 1
|
||||
if progress_callback:
|
||||
await progress_callback(ch.get("name", "Unknown"), processed, total)
|
||||
|
|
@ -446,6 +453,21 @@ class FluxerWriter:
|
|||
print(f"Failed to reset permissions for channel {ch.get('name')}: {e}")
|
||||
return processed
|
||||
|
||||
async def set_channel_permission(self, channel_id: str, overwrite_id: str, allow: int, deny: int, is_role: bool = True):
|
||||
"""Sets a permission overwrite for a channel or category."""
|
||||
assert self.client is not None
|
||||
try:
|
||||
await self.client.edit_channel_permissions(
|
||||
channel_id=int(channel_id),
|
||||
overwrite_id=int(overwrite_id),
|
||||
allow=allow,
|
||||
deny=deny,
|
||||
type=0 if is_role else 1
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to set permission on channel {channel_id} for overwrite {overwrite_id}: {e}")
|
||||
|
||||
|
||||
async def delete_all_roles(self, progress_callback=None) -> int:
|
||||
"""
|
||||
Deletes all non-managed, non-default roles in the Fluxer community,
|
||||
|
|
|
|||
|
|
@ -71,7 +71,8 @@ class MigrationCLI:
|
|||
"discord_intents": {}, "discord_permissions": {},
|
||||
"fluxer_token": False, "fluxer_bot_name": None,
|
||||
"fluxer_community": False, "fluxer_community_name": None,
|
||||
"fluxer_permissions": {}
|
||||
"fluxer_permissions": {},
|
||||
"discord_timeout": False, "fluxer_timeout": False
|
||||
}
|
||||
self.tokens_valid = False
|
||||
|
||||
|
|
@ -108,6 +109,7 @@ class MigrationCLI:
|
|||
console.print(f"[bold red]Discord validation failed with error: {e}[/bold red]")
|
||||
else:
|
||||
console.print("[bold red]Discord bot token validation timed out after 10 seconds.[/bold red]")
|
||||
self.validation_results["discord_timeout"] = True
|
||||
discord_task.cancel()
|
||||
|
||||
# Process Fluxer Result
|
||||
|
|
@ -130,6 +132,7 @@ class MigrationCLI:
|
|||
console.print(f"[bold red]Fluxer validation failed with error: {e}[/bold red]")
|
||||
else:
|
||||
console.print("[bold red]Fluxer bot token validation timed out after 10 seconds.[/bold red]")
|
||||
self.validation_results["fluxer_timeout"] = True
|
||||
fluxer_task.cancel()
|
||||
|
||||
# Only tokens and server/community existence are strictly required for 'tokens_valid'
|
||||
|
|
@ -168,10 +171,10 @@ class MigrationCLI:
|
|||
console.print("")
|
||||
console.print(Panel.fit("Fluxer Reaper", style="bold blue"))
|
||||
d_name = self.validation_results.get("discord_server_name")
|
||||
d_display = f"[bold green]\"{d_name}\"[/bold green]" if d_name else "[bold red]NOT SET UP[/bold red]"
|
||||
d_display = f"[bold green]\"{d_name}\"[/bold green]" if d_name else ("[bold yellow]TIMEOUT ERROR[/bold yellow]" if self.validation_results.get("discord_timeout") else "[bold red]NOT SET UP[/bold red]")
|
||||
|
||||
f_name = self.validation_results.get("fluxer_community_name")
|
||||
f_display = f"[bold green]\"{f_name}\"[/bold green]" if f_name else "[bold red]NOT SET UP[/bold red]"
|
||||
f_display = f"[bold green]\"{f_name}\"[/bold green]" if f_name else ("[bold yellow]TIMEOUT ERROR[/bold yellow]" if self.validation_results.get("fluxer_timeout") else "[bold red]NOT SET UP[/bold red]")
|
||||
|
||||
console.print(f"[bold cyan]Discord Server:[/bold cyan] {d_display}")
|
||||
console.print(f"[bold #4641D9]Fluxer Community:[/bold #4641D9] {f_display}")
|
||||
|
|
@ -190,7 +193,7 @@ class MigrationCLI:
|
|||
val_status = "[bold green][VALID][/bold green]"
|
||||
|
||||
console.print(f"(6) Configuration {val_status}")
|
||||
console.print("(7) [bold red]⚠ Danger Zone[/bold red]")
|
||||
console.print("(7) [red]Danger Zone ⚠[/red]")
|
||||
|
||||
console.print("(Q) Exit")
|
||||
|
||||
|
|
@ -466,6 +469,13 @@ class MigrationCLI:
|
|||
return
|
||||
elif sub_choice == "F":
|
||||
force = True
|
||||
else:
|
||||
if not Confirm.ask("Clone roles?", default=True):
|
||||
await self.engine.close_connections()
|
||||
return
|
||||
if not Confirm.ask("Are you sure?", default=True):
|
||||
await self.engine.close_connections()
|
||||
return
|
||||
|
||||
console.print("\n[bold green]Starting Role Migration...[/bold green]")
|
||||
with Progress(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue