You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
3.9 KiB
144 lines
3.9 KiB
import skema
|
|
|
|
from holster.enum import Enum
|
|
|
|
from disco.util.cache import cached_property
|
|
from disco.util.types import ListToDictType
|
|
from disco.types.base import BaseType
|
|
from disco.types.user import User
|
|
from disco.voice.client import VoiceClient
|
|
|
|
|
|
ChannelType = Enum(
|
|
GUILD_TEXT=0,
|
|
DM=1,
|
|
GUILD_VOICE=2,
|
|
GROUP_DM=3,
|
|
)
|
|
|
|
PermissionOverwriteType = Enum(
|
|
ROLE='role',
|
|
MEMBER='member'
|
|
)
|
|
|
|
|
|
class PermissionOverwrite(BaseType):
|
|
id = skema.SnowflakeType()
|
|
type = skema.StringType(choices=PermissionOverwriteType.ALL_VALUES)
|
|
|
|
allow = skema.IntType()
|
|
deny = skema.IntType()
|
|
|
|
|
|
class Channel(BaseType):
|
|
id = skema.SnowflakeType()
|
|
guild_id = skema.SnowflakeType(required=False)
|
|
|
|
name = skema.StringType()
|
|
topic = skema.StringType()
|
|
_last_message_id = skema.SnowflakeType(stored_name='last_message_id')
|
|
position = skema.IntType()
|
|
bitrate = skema.IntType(required=False)
|
|
|
|
recipient = skema.ModelType(User, required=False)
|
|
type = skema.IntType(choices=ChannelType.ALL_VALUES)
|
|
|
|
overwrites = ListToDictType('id', skema.ModelType(PermissionOverwrite), stored_name='permission_overwrites')
|
|
|
|
@property
|
|
def is_guild(self):
|
|
return self.type in (ChannelType.GUILD_TEXT, ChannelType.GUILD_VOICE)
|
|
|
|
@property
|
|
def is_dm(self):
|
|
return self.type in (ChannelType.DM, ChannelType.GROUP_DM)
|
|
|
|
@property
|
|
def is_voice(self):
|
|
return self.type in (ChannelType.GUILD_VOICE, ChannelType.GROUP_DM)
|
|
|
|
@property
|
|
def last_message_id(self):
|
|
if self.id not in self.client.state.messages:
|
|
return self._last_message_id
|
|
return self.client.state.messages[self.id][-1].id
|
|
|
|
@property
|
|
def messages(self):
|
|
return self.messages_iter()
|
|
|
|
def messages_iter(self, **kwargs):
|
|
return MessageIterator(self.client, self.id, before=self.last_message_id, **kwargs)
|
|
|
|
@cached_property
|
|
def guild(self):
|
|
return self.client.state.guilds.get(self.guild_id)
|
|
|
|
def get_invites(self):
|
|
return self.client.api.channels_invites_list(self.id)
|
|
|
|
def get_pins(self):
|
|
return self.client.api.channels_pins_list(self.id)
|
|
|
|
def send_message(self, content, nonce=None, tts=False):
|
|
return self.client.api.channels_messages_create(self.id, content, nonce, tts)
|
|
|
|
def connect(self, *args, **kwargs):
|
|
vc = VoiceClient(self)
|
|
vc.connect(*args, **kwargs)
|
|
return vc
|
|
|
|
|
|
class MessageIterator(object):
|
|
Direction = Enum('UP', 'DOWN')
|
|
|
|
def __init__(self, client, channel, direction=Direction.UP, bulk=False, before=None, after=None, chunk_size=100):
|
|
self.client = client
|
|
self.channel = channel
|
|
self.direction = direction
|
|
self.bulk = bulk
|
|
self.before = before
|
|
self.after = after
|
|
self.chunk_size = chunk_size
|
|
|
|
self.last = None
|
|
self._buffer = []
|
|
|
|
if len(filter(bool, (before, after))) > 1:
|
|
raise Exception('Must specify at most one of before or after')
|
|
|
|
if not any((before, after)) and self.direction == self.Direction.DOWN:
|
|
raise Exception('Must specify either before or after for downward seeking')
|
|
|
|
def fill(self):
|
|
self._buffer = self.client.api.channels_messages_list(
|
|
self.channel,
|
|
before=self.before,
|
|
after=self.after,
|
|
limit=self.chunk_size)
|
|
|
|
if not len(self._buffer):
|
|
raise StopIteration
|
|
|
|
self.after = None
|
|
self.before = None
|
|
|
|
if self.direction == self.Direction.UP:
|
|
self.before = self._buffer[-1].id
|
|
else:
|
|
self._buffer.reverse()
|
|
self.after == self._buffer[-1].id
|
|
|
|
def __iter__(self):
|
|
return self
|
|
|
|
def next(self):
|
|
if not len(self._buffer):
|
|
self.fill()
|
|
|
|
if self.bulk:
|
|
res = self._buffer
|
|
self._buffer = []
|
|
return res
|
|
else:
|
|
return self._buffer.pop()
|
|
|