示例#1
0
async def on_message(message: Message):
    if message.author.id == bot.user.id:
        return

    control_channel = get_bot_control_channel(message.server.channels)

    if not control_channel:
        return
    if control_channel.id != message.channel.id:
        return

    if not message.content:
        await bot.delete_message(message)
        return

    content = message.content.split(' ')
    command = content[0].lower()
    if len(content) > 1:
        args = content[1:]
    else:
        args = None

    if message.channel.is_private:
        if command != 'help':
            await bot.send_message(
                message.author,
                "I didn't get that. But there are available commands:")
        await bot.send_message(message.author, help_message)

        return

    m_player = bot.music_players.get(message.server.id, None)
    user_voice_channel = message.author.voice.voice_channel
    bot_voice_channel = bot.voice_channels.get(message.server.id, None)

    if command == 'summon' or command == 'summoning jutsu':
        if user_voice_channel:
            if m_player:
                await m_player.voice_client.disconnect()
                m_player.voice_client = await bot.join_voice_channel(
                    user_voice_channel)
            else:
                voice_client = await bot.join_voice_channel(user_voice_channel)
                m_player = MusicPlayer(
                    voice_client, next_song_event_generator(control_channel),
                    settings.MUSIC_DIRECTORY, settings.DEFAULT_VOLUME)

                bot.music_players.update({message.server.id: m_player})
                bot.voice_channels.update(
                    {message.server.id: user_voice_channel})

            username = message.author.nick if message.author.nick else message.author.name
            await bot.send_message(control_channel,
                                   'At your service, sir {}.'.format(username))
        else:
            await bot.send_message(control_channel,
                                   'Unable to join: unknown voice channel!')
    elif command == 'help':
        await bot.send_message(message.author, help_message)
    elif command == 'clear_messages':
        if not message.author.permissions_in(control_channel).manage_messages:
            return
        await bot.purge_from(control_channel, limit=50)
    elif command == 'update_songs':
        if not message.author.permissions_in(control_channel).manage_messages:
            return
        m_player.update_songs()
    elif m_player and user_voice_channel == bot_voice_channel:
        if command == 'bye':
            await bot.disconnect_from_server(message.server.id)
        elif command == 'play':
            success = await m_player.play()
            if not success:
                await incorrect_message(message)
        elif command == 'seek' and args:
            await m_player.seek(args[0])
        elif command == 'volume':
            if args:
                success = m_player.set_volume(args[0])
                if not success:
                    await incorrect_message(message)
                else:
                    await bot.send_message(
                        control_channel,
                        'New volume is {}%'.format(m_player.get_volume()))
            else:
                await bot.send_message(
                    control_channel,
                    'Current volume is {}%'.format(m_player.get_volume()))
        elif command == 'pause':
            m_player.pause()
        elif command == 'stop':
            await bot.change_presence(game=discord.Game(
                name='v. {}'.format(settings.BOT_VERSION)))
            m_player.reset_player()
        elif command == 'next':
            await m_player.play_next_song()
        elif command == 'prev':
            await m_player.play_previous_song()
        elif command == 'add' and args:
            success = m_player.add_to_playlist(args[0])
            if not success:
                await incorrect_message(message)
        elif command == 'delete':
            if args:
                song = await m_player.delete_from_playlist(args[0])
            else:
                song = await m_player.delete_from_playlist()

            if not song:
                await incorrect_message(message)
            else:
                # todo: execute playlist command here
                await bot.send_message(
                    control_channel,
                    '***{}.** {} was deleted from playlist!*'.format(
                        args[0], song.title))
        elif command == 'playlist':
            plist_msg = ''
            i = 1
            for song_title in m_player.get_playlist_titles():
                if m_player.current_song_id == i - 1:
                    song_title = '**' + song_title + '**'
                else:
                    song_title = '*' + song_title + '*'

                plist_msg += '**{}**. {}\n'.format(i, song_title)
                i += 1
            if plist_msg:
                await bot.send_message(control_channel, plist_msg)
            else:
                await bot.send_message(control_channel,
                                       '*The playlist is empty!*')
        elif command == 'select' and args:
            try:
                await m_player.select_song(args[0])
            except Exception:
                await incorrect_message(message)
        else:
            await incorrect_message(message)
    else:
        await incorrect_message(message)
示例#2
0
class MusicWorker(Worker):
    def __init__(self, holder):
        super().__init__(holder)
        random.seed()
        self._config = Config()
        self._player = MusicPlayer()
        self._load_config()

    def on_connect(self, client, userdata, flags):
        super().on_connect(client, userdata, flags)
        client.subscribe(MUSIC_TOPIC_SUBSCRIBE)

    def on_message(self, client, userdata, msg):
        super().on_message(client, userdata, msg)

        payload = msg.payload.decode('UTF-8')

        if msg.topic.startswith(MUSIC_TOPIC_ROOT):
            command = msg.topic.rsplit("/", 1)[-1]
            if command == 'play':
                mp3_file = payload
                result = self._play_music(mp3_file)
                client.publish(msg.topic + '/reply', payload=result, qos=1)
            elif command == 'stop':
                self._stop_music()
            elif command == 'play_random_one':
                self._play_random_one()
            elif command == 'list_music':
                mp3_list = self._get_mp3_list()
                file_list = [mp3.rsplit('/', 1)[-1] for mp3 in mp3_list]
                client.publish(msg.topic + '/reply',
                               payload='{}:{}'.format(payload,
                                                      ','.join(file_list)),
                               qos=1,
                               retain=True)
            elif command == 'get_volume':
                volume = self._get_volume()
                client.publish(msg.topic + '/reply',
                               payload='{}'.format(volume),
                               qos=1,
                               retain=True)
            elif command == 'set_volume':
                result = self._set_volume(payload)
                client.publish(msg.topic + '/reply', payload=result, qos=1)
                if result == 'ok':
                    client.publish(MUSIC_TOPIC_ROOT + 'get_volume/reply',
                                   payload='{}'.format(payload),
                                   qos=1,
                                   retain=True)

    def _play_music(self, mp3_file=None, remote_command=True):
        self._stop_music()

        result = 'ok'

        if mp3_file is None or len(mp3_file) == 0:
            self._player.play(SAFE_MP3)
            result = 'ok'
        elif remote_command:
            if mp3_file.find('..') != -1 or mp3_file.find(
                    '/') != -1 or mp3_file.find('\\') != -1:
                # bad guy
                self._player.play(SAFE_MP3)
                result = 'File not exist!'
            else:
                full_path = '{}/{}'.format(self._config.mp3_folder, mp3_file)
                if os.path.isfile(full_path):
                    self._player.play(full_path)
                    result = 'ok'
                else:
                    self._player.play(SAFE_MP3)
                    result = 'File not exist!'
        else:
            self._player.play(mp3_file)
            result = 'ok'

        return result

    def _stop_music(self):
        self._player.stop()

    def _get_mp3_list(self):
        mp3_list = glob.glob('{}/*.[mM][pP]3'.format(self._config.mp3_folder))
        return mp3_list

    def _play_random_one(self):
        mp3_list = self._get_mp3_list()
        mp3_file = random.choice(mp3_list)
        print('Playing: {}'.format(mp3_file))
        self._play_music(mp3_file, remote_command=False)

    def _get_volume(self):
        return self._player.get_volume()

    def _set_volume(self, volume):
        v = -1
        try:
            v = int(volume)
        except:
            pass

        if v >= 0 and v <= 100:
            self._player.set_volume(v)
            self._music_config.volume = v
            self._save_config()
            return 'ok'
        else:
            return 'volume is valid!'

    def _save_config(self):
        with open(MUSIC_SAVE_FILE, 'wb') as f:
            pickle.dump(self._music_config, f)

    def _load_config(self):
        self._music_config = None
        if os.path.isfile(MUSIC_SAVE_FILE):
            try:
                with open(MUSIC_SAVE_FILE, 'rb') as f:
                    self._music_config = pickle.load(f)
            except:
                pass

        if self._music_config is None:
            self._music_config = MusicConfig()

        print('Volume:', self._music_config.volume)

        self._player.set_volume(self._music_config.volume)

    def pause(self):
        self._player.pause()
        # 为了解决 alarm 设置不了音量的问题
        # 也不彻底,先这样了!
        self._player.set_volume(100)

    def resume(self):
        self._player.resume()
        # 为了解决 alarm 设置不了音量的问题
        # 也不彻底,先这样了!
        self._player.set_volume(self._music_config.volume)