Add category support.
This adds: * CategoryChannel, which represents a category * Guild.by_category() which traverses the channels grouping by category * Guild.categories to get a list of categories * abc.GuildChannel.category to get the category a channel belongs to * sync_permissions keyword argument to abc.GuildChannel.edit to sync permissions with a pre-existing or new category * category keyword argument to abc.GuildChannel.edit to move a channel to a category
This commit is contained in:
		@@ -250,11 +250,11 @@ class Guild(Hashable):
 | 
			
		||||
            channels = data['channels']
 | 
			
		||||
            for c in channels:
 | 
			
		||||
                if c['type'] == ChannelType.text.value:
 | 
			
		||||
                    channel = TextChannel(guild=self, data=c, state=self._state)
 | 
			
		||||
                    self._add_channel(channel)
 | 
			
		||||
                    self._add_channel(TextChannel(guild=self, data=c, state=self._state))
 | 
			
		||||
                elif c['type'] == ChannelType.voice.value:
 | 
			
		||||
                    channel = VoiceChannel(guild=self, data=c, state=self._state)
 | 
			
		||||
                    self._add_channel(channel)
 | 
			
		||||
                    self._add_channel(VoiceChannel(guild=self, data=c, state=self._state))
 | 
			
		||||
                elif c['type'] == ChannelType.category.value:
 | 
			
		||||
                    self._add_channel(CategoryChannel(guild=self, data=c, state=self._state))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
@@ -309,6 +309,52 @@ class Guild(Hashable):
 | 
			
		||||
        r.sort(key=lambda c: c.position)
 | 
			
		||||
        return r
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def categories(self):
 | 
			
		||||
        """List[:class:`CategoryChannel`]: A list of categories that belongs to this guild.
 | 
			
		||||
 | 
			
		||||
        This is sorted by the position and are in UI order from top to bottom.
 | 
			
		||||
        """
 | 
			
		||||
        r = [ch for ch in self._channels.values() if isinstance(ch, CategoryChannel)]
 | 
			
		||||
        r.sort(key=lambda c: c.position)
 | 
			
		||||
        return r
 | 
			
		||||
 | 
			
		||||
    def by_category(self):
 | 
			
		||||
        """Returns every :class:`CategoryChannel` and their associated channels.
 | 
			
		||||
 | 
			
		||||
        These channels and categories are sorted in the official Discord UI order.
 | 
			
		||||
 | 
			
		||||
        If the channels do not have a category, then the first element of the tuple is
 | 
			
		||||
        ``None``.
 | 
			
		||||
 | 
			
		||||
        Returns
 | 
			
		||||
        --------
 | 
			
		||||
        List[Tuple[Optional[:class:`CategoryChannel`], List[:class:`abc.GuildChannel`]]]:
 | 
			
		||||
            The categories and their associated channels.
 | 
			
		||||
        """
 | 
			
		||||
        grouped = {}
 | 
			
		||||
        for channel in self._channels.values():
 | 
			
		||||
            if isinstance(channel, CategoryChannel):
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            try:
 | 
			
		||||
                channels = grouped[channel.category_id]
 | 
			
		||||
            except KeyError:
 | 
			
		||||
                channels = grouped[channel.category_id] = []
 | 
			
		||||
 | 
			
		||||
            channels.append(channel)
 | 
			
		||||
 | 
			
		||||
        def key(t):
 | 
			
		||||
            k, v = t
 | 
			
		||||
            return (k.position if k else -1, v)
 | 
			
		||||
 | 
			
		||||
        _get = self._channels.get
 | 
			
		||||
        as_list = [(_get(k), v) for k, v in grouped.items()]
 | 
			
		||||
        as_list.sort(key=key)
 | 
			
		||||
        for _, channels in as_list:
 | 
			
		||||
            channels.sort(key=lambda c: c.position)
 | 
			
		||||
        return as_list
 | 
			
		||||
 | 
			
		||||
    def get_channel(self, channel_id):
 | 
			
		||||
        """Returns a :class:`abc.GuildChannel` with the given ID. If not found, returns None."""
 | 
			
		||||
        return self._channels.get(channel_id)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user