async def party_is_over(client, message): guild = message.guild if guild is None: return while True: voice_client = client.voice_client_for(message) if voice_client is None: text = 'I don\'t see any parties arround me.' break Task(voice_client.disconnect(), KOKORO) channel = voice_client.channel users=[] for state in guild.voice_states.values(): if (state.channel is not channel): continue user = state.user if (user is client): continue users.append(user) if not users: return for user in users: Task(client.user_voice_kick(user,guild), KOKORO) return await client.message_create(message.channel,text)
async def party_is_over(client, message_or_event): voice_client = client.voice_client_for(message_or_event) if voice_client is None: yield 'I don\'t see any parties around me.' return channel = voice_client.channel if not channel.cached_permissions_for(client).can_move_users: yield 'I must have move users permission in the respective channel to invoke this command.' return yield tasks = [] task = Task(voice_client.disconnect(), KOKORO) tasks.append(task) users = [] for state in GUILD__NEKO_DUNGEON.voice_states.values(): if (state.channel is not channel): continue user = state.user if (user is client): continue users.append(user) for user in users: task = Task(client.user_voice_kick(user, GUILD__NEKO_DUNGEON), KOKORO) tasks.append(task) await WaitTillAll(tasks, KOKORO) yield 'Nooo, the party is over nyaaa~~h!' return
async def request_sync(client, days_allowed): async with SYNC_LOCK: await client.message_create(CHANNEL__SYSTEM__SYNC, INITIAL_MESSAGE) try: await wait_for_message(client, CHANNEL__SYSTEM__SYNC, check_approved, 30.) except TimeoutError: sys.stderr.write('Sync request failed, timeout.\n') return files = get_modified_files(days_allowed) for file in files: sending_task = Task(send_file(client, file), KOKORO) response_task = wait_for_message(client, CHANNEL__SYSTEM__SYNC, check_received, 60.) await WaitTillAll([sending_task, response_task], KOKORO) try: sending_task.result() except BaseException as err: sys.stderr.write(f'Sync failed, {err!r}.\n') raise try: response_task.result() except TimeoutError: sys.stderr.write('Sync failed, timeout.\n') return await client.message_create(CHANNEL__SYSTEM__SYNC, SYNC_DONE)
async def embed_update(self, client, message, flag): Task(self.old_events['embed_update'](client, message, flag), KOKORO) if self.channel is None: return result = [f'Message {message.id} got embed update:'] channel = message.channel result.append(f'At channel : {channel:d} {channel.id}') guild = channel.guild if guild is not None: result.append(f'At guild : {guild.name} {guild.id}') if flag == 3: result.append('Less embeds than before???') else: if flag == 1: result.append('Only sizes were update.') elif flag == 2: result.append('Links! Links everywhere...') embeds = message.embeds if embeds is None: result.append('This should not happen, there are no embeds...') else: if flag == 1: for index, embed in enumerate(embeds, 1): if flag == 1: collected = [] image = embed.image if image is not None: collected.append( ('image.height', image.height)) collected.append(('image.width', image.width)) thumbnail = embed.thumbnail if thumbnail is not None: collected.append( ('thumbnail.height', thumbnail.height)) collected.append( ('thumbnail.width', thumbnail.width)) video = embed.video if video is not None: collected.append( ('video.height', video.height)) collected.append(('video.width', video.width)) if collected: result.append( f'Sizes got update at embed {index}:') for name, value in collected: result.append(f'- {name} : {value}') elif flag == 2: for index, embed in enumerate(embeds, 1): if embed.type in EXTRA_EMBED_TYPES: result.append( f'New embed appeared at index {index}:') result.extend(pretty_print(embed)) text = cchunkify(result) pages = [Embed(description=chunk) for chunk in text] await Pagination(client, self.channel, pages, timeout=120.)
async def start_waiting(self): try: await self.waiter except CancelledError: pass except InterruptedError: return self.cancel() else: return self.cancel() full_map = MAPS[self.map_name].copy() limit = len(full_map) - 1 self.map = [ full_map.pop(randint(0, limit)) for limit in range(limit, limit - self.amount, -1) ] if self.possibilities: self.romajis = {element[1] for element in self.map} else: self.options = None self.history = [] self.answers = {} self.running = True self.client.events.message_create.append(self.channel, self) Task(self.run(), self.client.loop)
async def __call__(self, client, message): if not isinstance(message.author, (Client, User)): return attachments = message.attachments if attachments is None: files = None else: files = [] for attachment in attachments: file = await client.download_attachment(attachment) files.append((attachment.name, file)) source_channel = message.channel for channel, webhook in self.pairs: if channel is source_channel: continue Task( client.webhook_message_create( webhook, content=message.clean_content, embed=message.clean_embeds, file=files, tts=message.tts, name=message.author.name_at(webhook.guild), avatar_url=message.author.avatar_url, ), client.loop)
async def __call__(self, client, message): if not isinstance(message.author, (Client, User)): return source_channel = message.channel user = message.author content = message.clean_content embed = message.clean_embeds file = None if message.attachments is None else [ attachment.name for attachment in message.attachments ] tts = message.tts #avatar_url = message.author.avatar_url #cannot compare avatar urls. for channel, webhook in self.parent.pairs: if channel is source_channel: continue for message in channel.messages: if isinstance(message.author, (Client, User)): continue if (user.name_at(webhook.guild) != message.author.name or #avatar_url != message.author.avatar_url or \ content != message.clean_content or file != (None if message.attachments is None else [attachment.name for attachment in message.attachments]) or \ embed != message.clean_embeds or tts != message.tts ): continue Task(client.message_delete(message), client.loop) break
async def user_profile_edit(self,client, user, guild, old): Task(self.old_events['user_profile_edit'](client, user, old, guild), KOKORO) if self.channel is None: return result=[f'{user.full_name} {user.id} profile was edited at guild {guild.name!r} {guild.id}:'] profile=user.guild_profiles[guild] for key, value in old.items(): if key in ('nick', 'boosts_since'): result.append(f'{key} changed: {value!r} -> {getattr(profile, key)!r}') continue if key=='roles': removed, added = listdifference(value, profile.roles) if removed: result.append(f'Roles removed: ({len(removed)})') for role in removed: result.append(f'- {role.name} {role.id}') if added: result.append(f'Roles added: ({len(added)})') for role in added: result.append(f'- {role.name} {role.id}') continue raise RuntimeError(key) pages=[Embed(description=chunk) for chunk in cchunkify(result)] await Pagination(client, self.channel, pages,120.)
def __new__(cls, join_waiter): self = object.__new__(cls) self.client = client = join_waiter.client self.channel = channel = join_waiter.channel self.users = join_waiter.users self.map_name = map_name = join_waiter.map_name self.length = join_waiter.length self.possibilities = possibilities = join_waiter.possibilities self.cancelled = False self.waiter = None self.history = [] self.answers = {} full_map = MAPS[map_name].copy() limit = len(full_map) - 1 self.map = map_ = [ full_map.pop(randint(0, limit)) for limit in range(limit, limit - self.length, -1) ] if possibilities: romajis = {element[1] for element in map_} else: romajis = None self.romajis = romajis self.options = None ACTIVE_GAMES[channel.id] = self client.events.message_create.append(channel, self) Task(self.runner(), KOKORO) return self
async def emoji_edit(self,client, emoji, old): Task(self.old_events['emoji_edit'](client, emoji, old), KOKORO) if self.channel is None: return result=[] result.append(f'Emoji edited: {emoji.name} {emoji.id} at guild {emoji.guild!r}') for key, value in old.items(): if key=='roles': removed, added = listdifference(value, emoji.roles) if removed: result.append(f'Removed roles: ({len(removed)})') for role in removed: result.append(f'- {role.name} {role.id}') if added: result.append(f'Added roles: ({len(added)})') for role in added: result.append(f'- {role.name} {role.id}') continue result.append(f'{key}: {value} -> {getattr(emoji, key)}') continue pages = [Embed(description=chunk) for chunk in cchunkify(result)] await Pagination(client, self.channel, pages,120.)
def remove(self, user): while True: try: index = self.users.index(user) except ValueError: message = 'You are not part of the game.' break if len(self.users) == 1: try: self.waiter.set_exception(InterruptedError) except InvalidStateError: self.waiter.add_done_callback(lambda future: setattr( future, '_exception', InterruptedError)) return message = f'{user:f} left from the game.' if self.running: del self.users[index] for element in self.history: del element.answers[index] if not self.answers.pop(user.id, '') and len( self.answers) == len(self.users) - 1: self.waiter.set_result_if_pending(None) break Task( self.client.message_create(self.channel, embed=Embed('', message, KANAKO_COLOR)), self.client.loop)
async def role_edit(self, client, role, old): Task(self.old_events['role_edit'](client, role, old), KOKORO) if self.channel is None: return result = [f'A role got edited at {role.guild.name} {role.guild.id}\nRole: {role.name} {role.id}'] for key, value in old.items(): if key in ('name', 'separated', 'managed', 'mentionable', 'position',): result.append(f'{key} : {value} -> {getattr(role, key)}') continue if key == 'color': result.append(f'{key} : {value.as_html} -> {role.color.as_html}') continue if key == 'permissions': result.append('permissions :') other = role.permissions for name,index in Permission.__keys__.items(): old_value = (value>>index)&1 new_value = (other>>index)&1 if old_value != new_value: result.append(f'{name} : {bool(old_value)} -> {bool(new_value)}') continue pages=[Embed(description=chunk) for chunk in cchunkify(result)] await Pagination(client, self.channel, pages,120.)
async def user_voice_update(self, client, voice_state, old_attributes): Task(self.old_events['user_voice_update'](client, voice_state, old_attributes), KOKORO) if self.channel is None: return result = [] result.append('Voice state update') user = voice_state.user if user.partial: result.append(f'user : Parital user {user.id}') else: result.append(f'user : {user.full_name} ({user.id})') guild = voice_state.channel.guild if guild is not None: result.append(f'guild : {guild.name} ({guild.id})') result.append(f'session_id : {voice_state.session_id!r}') result.append('Changes:') for key, value in old_attributes.items(): if key == 'channel': other = voice_state.channel result.append(f'channel : {value.name} {value.id} -> {other.name} {other.id}') continue result.append(f'{key} : {value} -> {getattr(voice_state, key)}') pages = [Embed(description=chunk) for chunk in cchunkify(result)] await Pagination(client, self.channel, pages, 120.)
async def sync_request_waiter(client, message): if message.content != INITIAL_MESSAGE: return if SYNC_LOCK.locked(): return Task(receive_sync(client, message.author), KOKORO)
async def webhook_update(self,client,channel): Task(self.old_events['webhook_update'](client,channel), KOKORO) if self.channel is None: return text = f'```\nwebhooks got updated at guild: {channel.name} {channel.id}```' pages = [Embed(description=text)] await Pagination(client, self.channel, pages, 120.)
async def role_delete(self,client,role, guild): Task(self.old_events['role_delete'](client,role, guild), KOKORO) if self.channel is None: return text=f'```\nA role got deleted at {role.guild.name} {role.guild.id}\nRole: {role.name} {role.id}```' pages=[Embed(description=text)] await Pagination(client, self.channel, pages,120.)
async def guild_ban_delete(self,client, guild, user): Task(self.old_events['guild_ban_delete'](client, guild, user), KOKORO) if self.channel is None: return text=f'```\nUser {user:f} {user.id} got UNbanned at {guild.name} {guild.id}.```' pages=[Embed(description=text)] await Pagination(client, self.channel, pages,120.)
async def channel_delete(self, client, channel, guild): Task(self.old_events['channel_delete'](client, channel, guild), KOKORO) if self.channel is None: return text = f'```\nA channel was deleted: {channel.name} {channel.id}\nchannel type: {channel.__class__.__name__} ({channel.type})```' pages = [Embed(description=text)] await Pagination(client, self.channel, pages, timeout=120.)
async def channel_pin_update(self,client,channel): Task(self.old_events['channel_pin_update'](client,channel), KOKORO) if self.channel is None: return text=f'```\nA channel\'s pins changed: {channel.name} {channel.id}\nchannel type: {channel.__class__.__name__} ({channel.type})```' pages=[Embed(description=text)] await Pagination(client, self.channel, pages,120.)
async def __call__(self, client, message, command, time_left): user_id = message.author.id try: notification, waiter = self.cache[user_id] except KeyError: pass else: if notification.channel is message.channel: try: await client.message_edit( notification, f'**{message.author:f}** please cool down, {time_left:.0f} seconds left!' ) except BaseException as err: if isinstance(err, ConnectionError): return if isinstance(err, DiscordException): if err.code in ( ERROR_CODES.unknown_message, # message deleted ERROR_CODES.unknown_channel, # channel deleted ERROR_CODES.invalid_access, # client removed ): return await client.events.error(client, f'{self!r}.__call__', err) return waiter.cancel() try: notification = await client.message_create( message.channel, f'**{message.author:f}** please cool down, {time_left:.0f} seconds left!' ) except BaseException as err: if isinstance(err, ConnectionError): return if isinstance(err, DiscordException): if err.code in ( ERROR_CODES.unknown_message, # message deleted ERROR_CODES. unknown_channel, # message's channel deleted ERROR_CODES.invalid_access, # client removed ERROR_CODES. invalid_permissions, # permissions changed meanwhile ERROR_CODES. invalid_message_send_user, # user has dm-s disallowed ): return await client.events.error(client, f'{self!r}.__call__', err) waiter = Task(self.waiter(client, user_id, notification), KOKORO) self.cache[user_id] = (notification, waiter)
async def message_delete(self,client, message): Task(self.old_events['message_delete'](client, message), KOKORO) if self.channel is None: return text = pretty_print(message) text.insert(0, f'Message {message.id} got deleted') pages = [Embed(description=chunk) for chunk in cchunkify(text)] await Pagination(client, self.channel, pages,120.)
async def role_create(self,client,role): Task(self.old_events['role_create'](client,role,), KOKORO) if self.channel is None: return result=pretty_print(role) result.insert(0, f'A role got created at {role.guild.name} {role.guild.id}') pages=[Embed(description=chunk) for chunk in cchunkify(result)] await Pagination(client, self.channel, pages,120.)
async def invite_delete(self,client,invite): Task(self.old_events['invite_delete'](client, invite), KOKORO) if self.channel is None: return text = pretty_print(invite) text.insert(0, f'Invite deleted:') pages = [Embed(description=chunk) for chunk in cchunkify(text)] await Pagination(client, self.channel, pages,120.)
async def channel_create(self,client,channel): Task(self.old_events['channel_create'](client,channel), KOKORO) if self.channel is None: return result=pretty_print(channel) result.insert(0, f'A channel was created: {channel.name} {channel.id}\nchannel type: {channel.__class__.__name__} ({channel.type})') pages=[Embed(description=chunk) for chunk in cchunkify(result)] await Pagination(client, self.channel, pages,120.)
async def emoji_delete(self,client, emoji, guild): Task(self.old_events['emoji_delete'](client, emoji, guild), KOKORO) if self.channel is None: return result=pretty_print(emoji) result.insert(0, f'Emoji deleted: {emoji.name} {emoji.id} at guild {guild!r}') pages=[Embed(description=chunk) for chunk in cchunkify(result)] await Pagination(client, self.channel, pages,120.)
async def guild_user_add(self, client, guild, user): Task(self.old_events['guild_user_add'](client, guild, user), KOKORO) if self.channel is None: return await client.message_create( self.channel, f'Welcome to the Guild {user:f}!\nThe guild reached {guild.user_count} members!' )
async def guild_create(self,client, guild): Task(self.old_events['guild_create'](client, guild,), KOKORO) if self.channel is None: return result = pretty_print(guild) result.insert(0, f'Guild created: {guild.id}') pages = [Embed(description=chunk) for chunk in cchunkify(result)] await Pagination(client, self.channel, pages,120.)
async def client_edit_settings(self,client, old): Task(self.old_events['client_edit_settings'](client, old), KOKORO) if self.channel is None: return result = ['The client\'s settings were updated:', '```'] for key, value in old.items(): result.append(f' {key} : {value!r} -> {getattr(client.settings, key)!r}') result.append('```') await client.message_create(self.channel, '\n'.join(result))
def cancel(self): client = self.client if self.process is None: Task(self.cancel_later(), KOKORO) return del self.other if self.process.__func__ is type(self).process_state_1: client.events.reaction_add.remove(self.message, self) client.events.reaction_delete.remove(self.message, self)
async def integration_edit(self, client, guild, integration): Task(self.old_events['integration_edit'](client, guild, integration), KOKORO) if self.channel is None: return text = pretty_print(integration) text.insert(0, f'integration_edit at {guild.name} ({guild.id}):') pages = [Embed(description=chunk) for chunk in cchunkify(text)] await Pagination(client, self.channel, pages, 120.)