4949
5050
5151def match_overwrites (overwrites : Overwrites , guild : Guild ) -> Mapping [Role | Member | Object , PermissionOverwrite ]:
52- role_overwrites : Mapping [Role | Member | Object , PermissionOverwrite ] = {
53- guild .default_role : PermissionOverwrite (** overwrites .get (RoleType .EVERYONE , {})),
54- find_role_by_name (guild .roles , VERIFIED_ROLE ): PermissionOverwrite (** overwrites .get (RoleType .VERIFIED , {})),
55- find_role_by_name (guild .roles , VOLUNTEER_ROLE ): PermissionOverwrite (** overwrites .get (RoleType .BLUESHIRT , {})),
56- find_role_by_name (guild .roles , TEAM_LEADER_ROLE ): PermissionOverwrite (
57- ** overwrites .get (RoleType .SUPERVISOR , {}),
58- ),
59- find_role_by_name (guild .roles , SPECIAL_ROLE ): PermissionOverwrite (
60- ** overwrites .get (RoleType .UNVERIFIED_BLUESHIRT , {}),
61- ),
52+ return {
53+ guild .default_role : overwrites .get (RoleType .EVERYONE , PermissionOverwrite ()),
54+ find_role_by_name (guild .roles , VERIFIED_ROLE ): overwrites .get (RoleType .VERIFIED , PermissionOverwrite ()),
55+ find_role_by_name (guild .roles , VOLUNTEER_ROLE ): overwrites .get (RoleType .BLUESHIRT , PermissionOverwrite ()),
56+ find_role_by_name (guild .roles , TEAM_LEADER_ROLE ): overwrites .get (RoleType .SUPERVISOR , PermissionOverwrite ()),
57+ find_role_by_name (guild .roles , SPECIAL_ROLE ): overwrites .get (RoleType .UNVERIFIED_BLUESHIRT , PermissionOverwrite ()),
6258 }
63- return role_overwrites
6459
6560
6661class ChannelSet :
@@ -84,14 +79,11 @@ def _get_role_type(self, role: Role, guild: Guild) -> RoleType:
8479 return self ._role_map [role ]
8580
8681 def _get_overwrites (self , channel : GuildChannel ) -> Overwrites :
87- overwrites : Overwrites = {}
88- for subject , permissions in channel .overwrites .items ():
89- if isinstance (subject , Role ):
90- overwrites [self ._get_role_type (subject , channel .guild )] = {}
91- for permission , value in permissions :
92- if value is not None :
93- overwrites [self ._get_role_type (subject , channel .guild )][permission ] = value
94- return overwrites
82+ return {
83+ self ._get_role_type (subject , channel .guild ): permissions
84+ for subject , permissions in channel .overwrites .items ()
85+ if isinstance (subject , Role )
86+ }
9587
9688 def count (self , category : Channel | None ) -> int :
9789 """Count the number of channels in a category, or top-level channels if category is None."""
@@ -197,7 +189,6 @@ def create_forum_channel(
197189 def diff (cls , old : ChannelSet , new : ChannelSet ) -> list [ChannelCommand ]:
198190 """Calculate the difference between two ChannelSets."""
199191 commands : list [ChannelCommand ] = []
200- # TODO: Diff categories first (in case one gets renamed)
201192 cls ._diff_channels (old ._channels , new ._channels , commands )
202193 return commands
203194
@@ -253,7 +244,7 @@ def _diff_channels(cls, old: list[Channel], new: list[Channel], commands: list[C
253244 commands .append (command )
254245 else :
255246 seen_old_channel_names .add (old_channel .name )
256- command = AlterChannelCommand .diff (old_channel , new_channel , new_index , old_channel .channel_type )
247+ command = AlterChannelCommand .diff (old_channel , new_channel , old_channel .channel_type )
257248 if command .has_changes :
258249 commands .append (command )
259250
@@ -424,7 +415,6 @@ class AlterChannelCommand(Command):
424415 overwrites : Overwrites | None = None
425416 topic : str | None = None
426417 category : Channel | None = None
427- position : int | None = None
428418 is_category : bool = False # Whether this command is for a category, only for display purposes
429419 channel_type : ChannelType = ChannelType .text # Used for sorting
430420 # Forum-specific:
@@ -434,8 +424,7 @@ class AlterChannelCommand(Command):
434424 use_case : ChannelUseCase | None = None
435425
436426 @classmethod
437- def diff (cls , old_channel : Channel , new_channel : Channel ,
438- new_position : int , channel_type : ChannelType ) -> AlterChannelCommand :
427+ def diff (cls , old_channel : Channel , new_channel : Channel , channel_type : ChannelType ) -> AlterChannelCommand :
439428 command = cls (old_name = old_channel .name , new_name = new_channel .name ,
440429 is_category = new_channel .is_category , channel_type = channel_type , use_case = new_channel .use_case )
441430 changed_category = new_channel .category is not None and old_channel .category != new_channel .category
@@ -445,7 +434,6 @@ def diff(cls, old_channel: Channel, new_channel: Channel,
445434 command .topic = new_channel .topic
446435 if not old_channel .category or changed_category :
447436 command .category = new_channel .category
448- command .position = new_position
449437 return command
450438
451439 def is_rename (self ) -> bool :
@@ -484,6 +472,22 @@ def __str__(self) -> str:
484472 return f"ALTER Category \" { self .old_name } \" ({ ', ' .join (changes )} )"
485473 return f"ALTER Channel #{ self .old_name } ({ ', ' .join (changes )} )"
486474
475+ @classmethod
476+ def get_role_by_role_type (cls , role_type : RoleType , guild : Guild ) -> Role :
477+ if role_type == RoleType .EVERYONE :
478+ return guild .default_role
479+
480+ role_names = {
481+ RoleType .VERIFIED : VERIFIED_ROLE ,
482+ RoleType .BLUESHIRT : VOLUNTEER_ROLE ,
483+ RoleType .SUPERVISOR : TEAM_LEADER_ROLE ,
484+ RoleType .UNVERIFIED_BLUESHIRT : SPECIAL_ROLE ,
485+ }
486+
487+ if role := discord .utils .get (guild .roles , name = role_names [role_type ]):
488+ return role
489+ raise ValueError ("Invalid role type" )
490+
487491 async def apply (self , guild : Guild ) -> None :
488492 channel = discord .utils .get (guild .channels , name = self .old_name )
489493 if channel is None :
@@ -499,8 +503,13 @@ async def apply(self, guild: Guild) -> None:
499503 if self .category is not None :
500504 kwargs ["category" ] = find_channel_by_name (guild .channels , self .category .name ) # type: ignore
501505
502- if self .overwrites is not None and self .overwrites != {}:
503- kwargs ["overwrites" ] = self .overwrites # type: ignore
506+ if self .overwrites is not None :
507+ overwrites = {
508+ AlterChannelCommand .get_role_by_role_type (role_type , guild ): permissions
509+ for role_type , permissions in self .overwrites .items ()
510+ }
511+ if overwrites != channel .overwrites :
512+ kwargs ["overwrites" ] = overwrites # type: ignore
504513
505514 if channel .type == ChannelType .forum :
506515 await guild .fetch_emojis ()
@@ -547,7 +556,7 @@ async def apply(self, guild: Guild) -> None:
547556@dataclasses .dataclass (frozen = True )
548557class CreateCategoryCommand (Command ):
549558 name : str
550- overwrites : Overwrites | None = None
559+ overwrites : Overwrites = dataclasses . field ( default_factory = dict )
551560
552561 def __str__ (self ) -> str :
553562 return f'CREATE Category "{ self .name } "'
@@ -563,7 +572,7 @@ class CreateChannelCommand(Command):
563572 name : str
564573 channel_type : ChannelType
565574 category : Channel | None = None
566- overwrites : Overwrites | None = None
575+ overwrites : Overwrites = dataclasses . field ( default_factory = dict )
567576 topic : str = ""
568577 # Bot use only:
569578 use_case : ChannelUseCase | None = None
@@ -615,7 +624,7 @@ async def apply(self, guild: Guild) -> None:
615624class CreateForumCommand (Command ):
616625 name : str
617626 category : Channel | None = None
618- overwrites : Overwrites | None = None
627+ overwrites : Overwrites = dataclasses . field ( default_factory = dict )
619628 topic : str = ""
620629 default_reaction_emoji : str | None = None
621630 available_tags : list [ForumTagDefinition ] = dataclasses .field (default_factory = list )
0 commit comments