Skip to content

Commit 6b8dc05

Browse files
refactor: enhance category and channel positioning logic for template application
- Improved the logic for updating category and channel positions to ensure they align with their intended order in the YAML configuration. - Implemented smart positioning checks to prevent unnecessary updates, enhancing performance and reducing potential errors. - Updated related comments for clarity and consistency in the codebase.
1 parent 9146df8 commit 6b8dc05

File tree

2 files changed

+62
-34
lines changed

2 files changed

+62
-34
lines changed

src/gitcord/cogs/admin.py

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ async def git_command(self, ctx: commands.Context, *args):
252252
await ctx.send(embed=warning_embed)
253253

254254
try:
255+
# Always apply template to ensure Discord matches the template
256+
# (Even if git says "up to date", Discord might not match the template)
255257
result_msgs = await self._apply_template_from_dir(ctx.guild, meta["local_path"], ctx=ctx)
256258

257259
# Convert to git-style diff
@@ -534,8 +536,11 @@ async def _apply_template_from_dir(
534536
category = existing_category
535537
msg = f"ℹ️ Category '{category_name}' already exists. Will update channels."
536538

537-
# Update category position based on order
538-
if category.position != category_index:
539+
# Check if category is in correct relative order (smart positioning)
540+
guild_categories = sorted(guild.categories, key=lambda cat: cat.position)
541+
current_relative_index = guild_categories.index(category)
542+
543+
if current_relative_index != category_index:
539544
try:
540545
await category.edit(position=category_index)
541546
msg += f" Moved to position {category_index}."
@@ -592,9 +597,15 @@ async def _apply_template_from_dir(
592597
):
593598
update_kwargs["nsfw"] = channel_config.get("nsfw", False)
594599

595-
# Update position based on channel order in YAML
596-
if hasattr(existing_channel, "position") and existing_channel.position != channel_index:
597-
update_kwargs["position"] = channel_index
600+
# Check if channel is in correct relative order (smart positioning)
601+
if hasattr(existing_channel, "position"):
602+
# Get all channels in category sorted by position
603+
category_channels = sorted(category.channels, key=lambda ch: ch.position)
604+
current_relative_index = category_channels.index(existing_channel)
605+
606+
# Only move if the channel is not at the correct relative position
607+
if current_relative_index != channel_index:
608+
update_kwargs["position"] = channel_index
598609

599610
if update_kwargs:
600611
await existing_channel.edit(**update_kwargs)
@@ -732,12 +743,15 @@ async def _apply_monolithic_template(self, guild, template_path, ctx=None, inter
732743
category = existing_category
733744
msg = f"ℹ️ Category '{category_name}' already exists. Will update channels."
734745

735-
# Update category position based on YAML order
736-
desired_position = category_index
737-
if category.position != desired_position:
746+
# Check if category is in correct relative order
747+
desired_yaml_index = category_index
748+
guild_categories = sorted(guild.categories, key=lambda cat: cat.position)
749+
current_relative_index = guild_categories.index(category)
750+
751+
if current_relative_index != desired_yaml_index:
738752
try:
739-
await category.edit(position=desired_position)
740-
msg += f" Moved to position {desired_position}."
753+
await category.edit(position=desired_yaml_index)
754+
msg += f" Moved to position {desired_yaml_index}."
741755
except (discord.Forbidden, discord.HTTPException) as e:
742756
self.logger.warning(f"Failed to update category position: {e}")
743757
else:
@@ -779,15 +793,21 @@ async def _apply_monolithic_template(self, guild, template_path, ctx=None, inter
779793
):
780794
update_kwargs["nsfw"] = channel_config.get("nsfw", False)
781795

782-
# Update position based on YAML order
783-
desired_position = channel_index
784-
if hasattr(existing_channel, "position") and existing_channel.position != desired_position:
785-
update_kwargs["position"] = desired_position
796+
# Check if channel is in correct relative order (smart positioning)
797+
desired_yaml_index = channel_index
798+
if hasattr(existing_channel, "position"):
799+
# Get all channels in category sorted by position
800+
category_channels = sorted(category.channels, key=lambda ch: ch.position)
801+
current_relative_index = category_channels.index(existing_channel)
802+
803+
# Only move if the channel is not at the correct relative position
804+
if current_relative_index != desired_yaml_index:
805+
update_kwargs["position"] = desired_yaml_index
786806

787807
if update_kwargs:
788808
await existing_channel.edit(**update_kwargs)
789809
updated += 1
790-
position_msg = f" (position {desired_position})" if "position" in update_kwargs else ""
810+
position_msg = f" (position {desired_yaml_index})" if "position" in update_kwargs else ""
791811
msg = f"🔄 Updated channel: {existing_channel.name} in {category_name}{position_msg}"
792812
else:
793813
skipped += 1

src/gitcord/utils/category_helpers.py

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,25 @@ async def process_existing_category(
4747
existing_category, yaml_channel_names, category_config["name"]
4848
)
4949

50-
# Update category position if needed
50+
# Update category position if needed (smart positioning)
5151
category_updated = False
52-
if (
53-
category_position is not None
54-
and existing_category.position != category_position
55-
):
56-
try:
57-
await existing_category.edit(position=category_position)
58-
logger.info(
59-
"Updated category '%s' position to %d",
60-
category_config["name"],
61-
category_position,
62-
)
63-
category_updated = True
64-
except (discord.Forbidden, discord.HTTPException) as e:
65-
logger.warning("Failed to update category position: %s", e)
52+
if category_position is not None:
53+
# Get all categories in guild sorted by position
54+
guild_categories = sorted(guild.categories, key=lambda cat: cat.position)
55+
current_relative_index = guild_categories.index(existing_category)
56+
57+
# Only move if the category is not at the correct relative position
58+
if current_relative_index != category_position:
59+
try:
60+
await existing_category.edit(position=category_position)
61+
logger.info(
62+
"Updated category '%s' position to %d",
63+
category_config["name"],
64+
category_position,
65+
)
66+
category_updated = True
67+
except (discord.Forbidden, discord.HTTPException) as e:
68+
logger.warning("Failed to update category position: %s", e)
6669

6770
# Process channels in the category
6871
created_channels, updated_channels, skipped_channels = (
@@ -188,14 +191,19 @@ async def _update_existing_channel(
188191
update_kwargs["nsfw"] = channel_config.get("nsfw", False)
189192
channel_updated = True
190193

191-
# Check if position needs updating based on YAML order
194+
# Check if position needs updating based on YAML order (smart positioning)
192195
if (
193196
channel_position is not None
194197
and hasattr(existing_channel, "position")
195-
and existing_channel.position != channel_position
196198
):
197-
update_kwargs["position"] = channel_position
198-
channel_updated = True
199+
# Get all channels in category sorted by position
200+
category_channels = sorted(existing_channel.category.channels, key=lambda ch: ch.position)
201+
current_relative_index = category_channels.index(existing_channel)
202+
203+
# Only move if the channel is not at the correct relative position
204+
if current_relative_index != channel_position:
205+
update_kwargs["position"] = channel_position
206+
channel_updated = True
199207

200208
if channel_updated:
201209
try:

0 commit comments

Comments
 (0)