예제 #1
0
async def remove(ctx, arg):
    server = get_server(ctx)

    if arg == 'all':
        server.playlist.deleteAll()
        if server.voice: server.voice.stop()
        await ctx.send(embed=MsgEmbed.info('Удалил весь плейлист :fire:'))
        return

    if not arg.isdigit(): raise commands.MissingRequiredArgument()
    else: pos = int(arg)

    if not 0 <= pos < server.playlist.getLength():
        await ctx.send(embed=MsgEmbed.warning(
            'Как может в казино быть колода разложена в другом порядке?! Ты чё, бредишь, что ли?! Ёбаный твой рот, а!..'
        ))
        return

    mi = server.playlist.getByPosition(pos)
    playlist, voice = server.playlist, server.voice
    if pos == playlist.getPosition() and voice: voice.stop()
    if playlist.deleteByPosition(pos):
        await ctx.send(
            embed=MsgEmbed.info(f'Удалил: {mi.artist} - {mi.title} :fire:'))
    else:
        await ctx.send(embed=MsgEmbed.error('Ошибка удаления'))
예제 #2
0
 async def get_voice_channel_by_name() -> Optional[discord.VoiceChannel]:
     channels = list(
         filter(lambda x: x.name == channel_name, ctx.guild.voice_channels))
     if len(channels) == 0:
         await ctx.send(embed=MsgEmbed.error(
             'Ты инвалид? Название канала неправильное'))
         return None
     elif len(channels) == 1:
         return channels[0]
     else:
         choice = [f' {x} ({x.position + 1}-й)\n' for x in channels]
         choice.insert(0, 'Отмена')
         answer = await ask_user(ctx,
                                 'выбери канал',
                                 choice,
                                 icon_url=icons['list'])
         if answer is None: return None
         if answer == 0:
             await ctx.send(embed=MsgEmbed.warning('Подключение отменено'))
             return None
         if 1 <= answer <= len(channels):
             return channels[answer - 1]
         await ctx.send(
             embed=MsgEmbed.warning('Ты кто такой, сука, чтоб это делать?'))
         return None
예제 #3
0
async def leave(ctx):
    voice = get_server(ctx).voice
    if voice and voice.is_connected():
        await voice.disconnect()
        await ctx.send(embed=MsgEmbed.warning('Бот отключился'))
    else:
        await ctx.send(
            embed=MsgEmbed.warning('Этим можно просто брать и обмазываться'))
예제 #4
0
async def join(ctx, channel_name='', *, reconnect=True) -> bool:
    async def get_voice_channel() -> Optional[discord.VoiceChannel]:
        if channel_name == '':
            if not member_is_connected(ctx.author):
                await ctx.send(
                    embed=MsgEmbed.error('Присоединись к каналу, мудак'))
                return None
            return ctx.author.voice.channel
        return get_voice_channel_by_name()

    async def get_voice_channel_by_name() -> Optional[discord.VoiceChannel]:
        channels = list(
            filter(lambda x: x.name == channel_name, ctx.guild.voice_channels))
        if len(channels) == 0:
            await ctx.send(embed=MsgEmbed.error(
                'Ты инвалид? Название канала неправильное'))
            return None
        elif len(channels) == 1:
            return channels[0]
        else:
            choice = [f' {x} ({x.position + 1}-й)\n' for x in channels]
            choice.insert(0, 'Отмена')
            answer = await ask_user(ctx,
                                    'выбери канал',
                                    choice,
                                    icon_url=icons['list'])
            if answer is None: return None
            if answer == 0:
                await ctx.send(embed=MsgEmbed.warning('Подключение отменено'))
                return None
            if 1 <= answer <= len(channels):
                return channels[answer - 1]
            await ctx.send(
                embed=MsgEmbed.warning('Ты кто такой, сука, чтоб это делать?'))
            return None

    if not reconnect:
        voice = get_server(ctx).voice
        if voice and voice.is_connected(): return True

    channel = await get_voice_channel()
    if channel is None: return False

    result = await join_to_channel(ctx, channel)
    if result == 0:
        await ctx.send(
            embed=MsgEmbed.ok(f'Бот подключился к каналу: {channel}'))
    elif result == 1:
        await ctx.send(
            embed=MsgEmbed.warning(f'Бот уже подключен к каналу: {channel}'))
    elif result == 2:
        await ctx.send(embed=MsgEmbed.error(f'Ты че наделал?'))
    else:
        await ctx.send(
            embed=MsgEmbed.error('Ничего не понял, но очень интересно'))

    # Я не хачу пихать return в if'ы, что бы не нарушать гармонию форматирования
    return 0 <= result <= 1
예제 #5
0
async def on_command_error(ctx, error):
    if isinstance(error, commands.CheckFailure):
        await ctx.send(embed=MsgEmbed.error('Не дорос ещё!'))
    elif isinstance(error, commands.CommandNotFound):
        await ctx.send(embed=MsgEmbed.error(
            f'Такой команды нет! `{ctx.prefix}help` - для справки'))
    elif isinstance(error, commands.MissingRequiredArgument) or isinstance(
            error, commands.BadArgument):
        await ctx.send(embed=MsgEmbed.error(
            f'Глаза разуй! Такого аргумента нет! `{ctx.prefix}help {ctx.command}` - для справки'
        ))
    else:
        raise error
예제 #6
0
async def queue(ctx):
    server = get_server(ctx)

    if server.playlist.getLength() == 0:
        await ctx.send(embed=MsgEmbed.info('Плейлист пуст'))
    else:
        mi_list = server.playlist.getAll()
        _list = [
            f'{i} :  {mi.artist} - {mi.title}' for i, mi in enumerate(mi_list)
        ]
        pos = server.playlist.getPosition()
        _list[pos] = f'**{_list[pos]}**'

        emb = MsgEmbed.info('')
        emb.set_author(name='текущий плейлист', icon_url=icons['playlist'])
        await send_long_list(ctx, _list, emb, MsgEmbed.info(''))
예제 #7
0
 async def get_voice_channel() -> Optional[discord.VoiceChannel]:
     if channel_name == '':
         if not member_is_connected(ctx.author):
             await ctx.send(
                 embed=MsgEmbed.error('Присоединись к каналу, мудак'))
             return None
         return ctx.author.voice.channel
     return get_voice_channel_by_name()
예제 #8
0
 async def add_all():
     added_songs, songs_count = 0, len(mi_list)
     message = await ctx.send(embed=MsgEmbed.info('Загрузка плейлиста...'))
     for mi in mi_list:
         if server.playlist.add(mi): added_songs += 1
     if added_songs == songs_count:
         await message.edit(
             embed=MsgEmbed.ok('Все песни успешно добавлены!'))
         return True
     elif added_songs == 0:
         await message.edit(
             embed=MsgEmbed.warning('Ни одна песня не была добавлена!'))
         return False
     else:
         await message.edit(embed=MsgEmbed.warning(
             f'Добавлено: {added_songs}/{songs_count}'))
         return True
예제 #9
0
 async def add_one():
     songs_list = [f' {mi.artist} - {mi.title}' for mi in mi_list]
     songs_list.insert(0, 'Отмена')
     answer = await ask_user(ctx,
                             'выбери песню',
                             songs_list,
                             icon_url=icons['search'])
     if answer is None: return None
     if answer == 0: return await cancel()
     if 1 <= answer <= len(mi_list): mi = mi_list[answer - 1]
     else: return bad_answer()
     if server.playlist.add(mi):
         await ctx.send(
             embed=MsgEmbed.ok(f'Добавил: {mi.artist} - {mi.title}'))
         return True
     else:
         await ctx.send(embed=MsgEmbed.warning('Ошибка добавления!'))
         return False
예제 #10
0
async def mix(ctx):
    server = get_server(ctx)
    playlist = server.playlist
    if playlist.getLength() == 0:
        await ctx.send(embed=MsgEmbed.warning('Плейлист пуст, животное'))
        return
    playlist.mix()
    playlist.position = playlist.getLength() - 1
    await skip(ctx)
예제 #11
0
async def skip(ctx, count: int = 1):
    server = get_server(ctx)
    voice = server.voice
    playlist = server.playlist
    if playlist.getLength() == 0:
        await ctx.send(embed=MsgEmbed.warning('Скипалка не отросла'))
        return
    for i in range(count - 1):
        playlist.next()
    if voice:
        voice.stop()
예제 #12
0
async def ask_user(ctx,
                   title: str,
                   choice: List[str],
                   *,
                   icon_url: str = icons['list'],
                   timeout=10,
                   start_index=0,
                   step_index=1) -> Optional[int]:
    choice = [f'{i + start_index}. {x}' for i, x in enumerate(choice)]
    emb = MsgEmbed.info('')
    emb.set_author(name=title, icon_url=icon_url)
    await send_long_list(ctx, choice, emb, MsgEmbed.info(''))
    try:
        msg = await client.wait_for('message',
                                    check=get_message_check(ctx.author),
                                    timeout=timeout)
    except asyncio.exceptions.TimeoutError:
        await ctx.send(embed=MsgEmbed.warning('Кто не успел - тот опоздал'))
        return None
    else:
        return int(msg.content)
예제 #13
0
async def about(ctx):
    await ctx.send(embed=MsgEmbed.info(about_docs))
    pass
예제 #14
0
async def add(ctx, *args) -> Optional[bool]:
    """
		Добавляет в плейлист сервера новые треки
		
		args == ['--id', '...'] - поиск плейлиста по id
		args == ['url'] - поиск плейлиста по ссылке
		args == [...] - поиск трека по ключевым словам

		return True  - в плейлист был добавлен хотя бы 1 трек
		return False - в плейлист не было ничего добавлено
		return None  - таймаут, некорректные данные пользователя, ошибка апи
	"""
    async def cancel():
        await ctx.send(embed=MsgEmbed.warning('Отменено'))
        return False

    async def bad_answer():
        await ctx.send(
            embed=MsgEmbed.warning('Ты кто такой, сука, чтоб это делать?'))
        return None

    async def add_all():
        added_songs, songs_count = 0, len(mi_list)
        message = await ctx.send(embed=MsgEmbed.info('Загрузка плейлиста...'))
        for mi in mi_list:
            if server.playlist.add(mi): added_songs += 1
        if added_songs == songs_count:
            await message.edit(
                embed=MsgEmbed.ok('Все песни успешно добавлены!'))
            return True
        elif added_songs == 0:
            await message.edit(
                embed=MsgEmbed.warning('Ни одна песня не была добавлена!'))
            return False
        else:
            await message.edit(embed=MsgEmbed.warning(
                f'Добавлено: {added_songs}/{songs_count}'))
            return True

    async def add_one():
        songs_list = [f' {mi.artist} - {mi.title}' for mi in mi_list]
        songs_list.insert(0, 'Отмена')
        answer = await ask_user(ctx,
                                'выбери песню',
                                songs_list,
                                icon_url=icons['search'])
        if answer is None: return None
        if answer == 0: return await cancel()
        if 1 <= answer <= len(mi_list): mi = mi_list[answer - 1]
        else: return bad_answer()
        if server.playlist.add(mi):
            await ctx.send(
                embed=MsgEmbed.ok(f'Добавил: {mi.artist} - {mi.title}'))
            return True
        else:
            await ctx.send(embed=MsgEmbed.warning('Ошибка добавления!'))
            return False

    async def load_playlist():
        method = {
            0: cancel,
            1: add_one,
            2: add_all,
            None: lambda: None
        }.get(
            await ask_user(ctx, 'че ты хочешь?',
                           ['Отмена', 'Одна песня', 'Весь плейлист']),
            bad_answer)
        return await method()

    server = get_server(ctx)  # используется в подпрограммах (server.playlist)

    if len(args) == 0:
        await ctx.send(embed=MsgEmbed.error('Нифига ты быдло'))
        return

    # я не смог избавиться от флага
    if args[0] == '--id':
        if len(args) < 2:
            await ctx.send(
                embed=MsgEmbed.error('Недосдача по аргументам, жмот'))
            return
        if len(args) > 2:
            await ctx.send(embed=MsgEmbed.warning('Слишком много аргументов'))
        mi_list = VkSearch.byPlaylistId(args[1])
        is_playlist = True
    elif VkSearch.isCorrectPlaylistUrl(args[0]):
        if len(args) > 1:
            await ctx.send(embed=MsgEmbed.warning('Слишком много аргументов'))
        mi_list = VkSearch.byPlaylistUrl(args[0])
        is_playlist = True
    else:
        mi_list = VkSearch.byString(' '.join(args), 5)
        is_playlist = False
        return await add_one()

    if mi_list is None:
        await ctx.send(embed=MsgEmbed.error('Ошибка поиска!'))
        return
    if mi_list == []:
        await ctx.send(embed=MsgEmbed.warning('Ничего не найдено!'))
        return False

    if is_playlist: return await load_playlist()
    else: return await add_one()
예제 #15
0
async def on_voice_state_update(member, before, after):
    before_channel = before.channel  # это понятно
    after_channel = after.channel  # это тоже
    if before_channel is None: return  # если нечего ещё смотреть, выходим
    # если просто кто-то подключился к каналу, выходим
    if after_channel and before_channel.id == after_channel.id: return
    sid = before_channel.guild.id  # это понятно (sid - server id)
    if not sid in servers: return  # если нам нечего взять, выходим
    server = servers[sid]  # это понятно
    voice = server.voice  # это тоже
    if voice is None: return  # если нам нечего взять, выходим
    bot_id = client.user.id  # это понятно

    def is_it_only_robots(
        members
    ):  # это тоже, но объясню, если весь канал состоит из ботов, то True, в противном случае False
        for member in members:
            if member.bot == False:
                return False
        return True

    async def disconnect_with_msg(msg):  # это понятно
        await voice.disconnect()  # это тоже
        await server.ctx.send(embed=MsgEmbed.hearts(msg))  # и это

    voice_members = voice.channel.members
    if len(voice_members) > 1:  # если мы не одни
        # если мы не одни и тут только боты, отключаемся
        if is_it_only_robots(voice_members):
            await disconnect_with_msg('Пока-пока, безчувственные машины')
        return  # это понятно
    before_members = before_channel.members
    if after_channel and after_channel.members[
            0].id == bot_id:  # если нас переместили, то преследуем
        await voice.disconnect()
        try:
            voice = await before_channel.connect(
            )  # само преследование (почему говнокодим, я объясняю в конце функции)
        except asyncio.exceptions.TimeoutError:
            await disconnect_with_msg(
                'Ай-яй-яй'
            )  # если мы не смогли преследовать (нет прав), то отключаемся
        else:
            await server.ctx.send(embed=MsgEmbed.hearts('Не надо стесняться'))
            server.voice = voice
        # тут преследование удастся в любом случае, но если поменять со скоростью света права before_channel, то преследование не удастся
        return  # это понятно
    if voice.channel.id != before_channel.id: return  # я уже забыл, зачем оно
    if voice.is_connected():
        # нас кикают или никого не осталось, отключаемя
        if after_channel is None: await disconnect_with_msg('Пока-пока')
        else:  # от нас уходят в другой канал, преследуем
            after_members = after_channel.members  # это понятно
            a_mention = after_members[len(after_members) -
                                      1].mention  # это тоже
            await voice.disconnect()  # читабельность, пока
            try:
                voice = await after_channel.connect(timeout=5
                                                    )  # само преследование
            except asyncio.exceptions.TimeoutError:
                await disconnect_with_msg(
                    f'Увидимся, {a_mention}'
                )  # если мы не смогли преследовать (нет прав), то отключаемся (я бы ещё юзера нахер послал, но ладно)
            else:
                await server.ctx.send(
                    embed=MsgEmbed.hearts(f'Ты куда, {a_mention}?'))
                server.voice = voice
예제 #16
0
async def playing(ctx):
    playlist = get_server(ctx).playlist
    if playlist.getLength() == 0:
        await ctx.send(embed=MsgEmbed.warning('Плейлист пуст'))
        return
    await ctx.send(embed=get_mi_embed(playlist.getCurrent()))
예제 #17
0
 async def disconnect_with_msg(msg):  # это понятно
     await voice.disconnect()  # это тоже
     await server.ctx.send(embed=MsgEmbed.hearts(msg))  # и это
예제 #18
0
def get_mi_embed(mi: MusicInfo) -> discord.Embed:
    emb = MsgEmbed.info('')
    emb.set_author(name=f'{mi.artist} - {mi.title} [ {mi.time} сек ]',
                   icon_url=mi.image_url)
    return emb
예제 #19
0
 async def bad_answer():
     await ctx.send(
         embed=MsgEmbed.warning('Ты кто такой, сука, чтоб это делать?'))
     return None
예제 #20
0
 async def cancel():
     await ctx.send(embed=MsgEmbed.warning('Отменено'))
     return False
예제 #21
0
async def on_error(event, ctx, *args, **kwargs):
    logger.exception(f'Exception in on_error. Event: {event}')
    await ctx.send(embed=MsgEmbed.error('!!! ОШИБКА !!!'))