def __init__(self, client, max_messages: int = 500): #: The current user of this bot. #: This is automatically set after login. self._user = None # type: BotUser #: The client associated with this connection. self.client = client #: The private channel cache. self._private_channels = {} #: The guilds the bot can see. self._guilds = {} # type: Dict[int, Guild] #: The current user cache. self._users = {} #: The deque of messages. #: This is bounded to prevent the message cache from growing infinitely. self.messages = collections.deque(maxlen=max_messages) self.__shards_is_ready = collections.defaultdict(lambda: False) self.__voice_state_crap = collections.defaultdict( lambda *args, **kwargs: ((multio.Event(), multio.Event()), {}) )
def __init__(self, session_id: str, token: str, endpoint: str, user_id: str, guild_id: str): #: The current websocket object. self.websocket = None # type: Websocket self._open = False self.session_id = session_id self.token = token self.user_id = user_id self.guild_id = guild_id self.sequence = 0 self.ssrc_mapping = {} #: The main gateway object. self.main_gateway = None # type: Gateway #: The current threading event used to signal if we need to stop heartbeating. self._stop_heartbeating = multio.Event() #: Voice server stuff self.endpoint = endpoint self.port = None # type: int self.ssrc = None # type: int self.secret_key = b"" self._ready = multio.Event() self._got_secret_key = multio.Event()
async def typing(self) -> _typing.AsyncContextManager[None]: """ :return: A context manager that sends typing repeatedly. Usage: .. code-block:: python3 async with channel.typing: res = await do_long_action() await channel.messages.send("Long action:", res) """ running = multio.Event() async def runner(): await self.send_typing() while True: try: async with multio.timeout_after(5): await running.wait() except multio.asynclib.TaskTimeout: await self.send_typing() else: return async with multio.asynclib.task_manager() as tg: await multio.asynclib.spawn(tg, runner) try: yield finally: await multio.asynclib.cancel_task_group(tg)
def __init__(self, token: str, connection_state, *, large_threshold: int = 250): """ :param token: The bot token to connect with. """ #: The token used to identify with. self.token = token #: The current websocket connection. self.websocket = None # type: Websocket #: The current sequence number. self.sequence_num = 0 #: The connection state used for this connection. self.state = connection_state #: The shard ID this gateway is representing. self.shard_id = 0 #: The number of shards the client is connected to. self.shard_count = 1 #: The current session ID for this gateway. self.session_id = None #: The current heartbeat statistic counter for this gateway. self.hb_stats = HeartbeatStats() #: The current game for this gateway. #: Only set when sending a change status packet. self.game = None #: The current status for this gateway. self.status = None #: The "large threshold" for this Gateway. #: For guilds with members above this number, offline members will not be sent. self.large_threshold = min(250, large_threshold) # bound to 250 #: The data format for this gateway. self.format = _fmt self._prev_seq = 0 self._dispatches_handled = collections.Counter() self._enqueued_guilds = [] self._stop_heartbeating = multio.Event() self._logger = None self._cached_gateway_url = None # type: str self._open = False self._close_code = None self._close_reason = None
def __init__(self, gw_state: _GatewayState): #: The current state being used for this gateway. self.gw_state = gw_state #: The current heartbeat stats being used for this gateway. self.heartbeat_stats = HeartbeatStats() #: The current :class:`.BasicWebsocketWrapper` connected to Discord. self.websocket: BasicWebsocketWrapper = None #: The current task group for this gateway. self.task_group = None self._logger = None self._stop_heartbeating = multio.Event() self._dispatches_handled = Counter()
async def _start_heartbeating(self, heartbeat_interval: float) -> threading.Thread: """ Starts the heartbeat thread. :param heartbeat_interval: The number of seconds between each heartbeat. """ if not self._stop_heartbeating.is_set(): # cancel some poor thread elsewhere await self._stop_heartbeating.set() del self._stop_heartbeating self._stop_heartbeating = multio.Event() # dont reference the task - it'll die by itself task = await curio.spawn(_heartbeat_loop(self, heartbeat_interval), daemon=True) return task
def __init__(self, bot, **kwargs) -> None: super().__init__(kwargs.get("id"), bot) #: If the guild is unavailable or not. #: If this is True, many fields return `None`. self.unavailable = kwargs.get("unavailable", False) # Placeholder values. #: The name of this guild. self.name = None # type: str #: The icon hash of this guild. #: Used to construct the icon URL later. self.icon_hash = None # type: str #: The splash hash of this guild. #: Used to construct the splash URL later. self.splash_hash = None # type: str #: The AFK channel ID of this guild. self.afk_channel_id = None # type: int #: The ID of the system channel for this guild. #: This is where welcome messages and the likes are sent. #: Effective replacement for default channel for bots. self.system_channel_id = None # type: int #: The widget channel ID for this guild. self.widget_channel_id = None # type: int #: The owner ID of this guild. self.owner_id = None # type: int #: The AFK timeout for this guild. None if there's no AFK timeout. self.afk_timeout = None # type: int #: The voice region of this guild. self.region = None # type: str #: The features this guild has. self.features = None # type: typing.List[str] #: The MFA level of this guild. self.mfa_level = MFALevel.DISABLED #: The verification level of this guild. self.verification_level = VerificationLevel.NONE #: The notification level of this guild. self.notification_level = NotificationLevel.ALL_MESSAGES #: The content filter level of this guild. self.content_filter_level = ContentFilterLevel.SCAN_NONE #: The shard ID this guild is associated with. self.shard_id = None # type: int #: The roles that this guild has. self._roles = {} #: The members of this guild. self._members = {} #: The channels of this guild. self._channels = {} #: The emojis that this guild has. self._emojis = {} #: The voice states that this guild has. self._voice_states = {} #: The number of numbers this guild has. #: This is automatically updated. self.member_count = 0 # type: int #: Is this guild a large guild according to Discord? self._large = None # type: bool #: Has this guild finished chunking? self._finished_chunking = multio.Event() self._chunks_left = 0 #: The current voice client associated with this guild. self.voice_client = None #: The :class:`.GuildChannelWrapper` that wraps the channels in this Guild. self.channels = GuildChannelWrapper(self, self._channels) #: The :class:`.GuildRoleWrapper` that wraps the roles in this Guild. self.roles = GuildRoleWrapper(self, self._roles) #: The :class:`.GuildEmojiWrapper` that wraps the emojis in this Guild. self.emojis = GuildEmojiWrapper(self, self._emojis) #: The :class:`.GuildBanContainer` for this Guild. self.bans = GuildBanContainer(self) if kwargs: self.from_guild_create(**kwargs)