示例#1
0
文件: server.py 项目: cp9ev/xiaoma
class MusicServer:
    client_list = {}
    root_dir = './musics'
    search_tool = Search()
    download_queue = []

    def __init__(self):
        self.music_list = []
        self.music_player = MusicPlayer()
        self.api_map = self.init_router()

        self.start_flag = False
        self.playing_flag = False
        self.play_mode = 'loop'
        self.current_index = -1
        self.current_music = {}

        websocket_server = websockets.serve(self.service, '192.168.1.209', 8888)
        asyncio.get_event_loop().run_until_complete(websocket_server)
        asyncio.ensure_future(self.auto_next())
        asyncio.ensure_future(self.download_task())
        asyncio.get_event_loop().run_forever()

    async def service(self, websocket, path):
        client_name = self.handle_client(websocket, path)
        async for message in websocket:
            await self.router(client_name, json.loads(message))

    async def router(self, client_name, request):
        print(f'{client_name}:{request}')
        await self.api_map[request['path']](request=request, client_name=client_name)

    async def send_response(self, path, data, client_name=None):
        response = json.dumps({'api': path, 'data': data})
        if client_name is not None:
            await self.client_list[client_name].send(response)
        else:
            offline = []
            for client, ws in self.client_list.items():
                try:
                    await ws.send(response)
                except Exception as e:
                    print(f'{client} offline')
                    offline.append(client)
            for client in offline:
                self.client_list.pop(client)

    async def get_player_info(self, **kwargs):
        request = kwargs['request']
        data = {
            'mode': self.play_mode,
            'music': self.current_music,
            'play_status': self.playing_flag,
            'volume': self.music_player.get_music_volume()
        }
        await self.send_response(request['path'], data)

    async def get_local_music_list(self, **kwargs):
        request = kwargs['request']
        self.music_list = get_local_music_list(self.root_dir)
        data = {'player_status': self.start_flag, 'music_list': self.music_list}
        send_mode = kwargs['send_mode'] if kwargs.get('send_mode') else 1
        if send_mode == 1:
            await self.send_response(request['path'], data, kwargs['client_name'])
        else:
            await self.send_response(request['path'], data)

    async def search_music_list(self, **kwargs):
        request = kwargs['request']
        search_value = request['query']['search_value']
        music_list = await self.search_tool.search_song(search_value)
        data = {'player_status': self.start_flag, 'music_list': music_list}
        await self.send_response(request['path'], data, kwargs['client_name'])

    async def download_music(self, **kwargs):
        request = kwargs['request']
        music = request['query']['music']
        self.download_queue.append(music)
        await self.send_response(request['path'], self.download_queue)

    async def set_mode(self, **kwargs):
        request = kwargs['request']
        self.play_mode = request['query']['mode']
        await self.send_response(request['path'], {'play_mode': self.play_mode})

    async def play_music(self, **kwargs):
        request = kwargs['request']
        index = request['query']['index']
        music = self.music_list[index]
        music_file = parse_file_path(self.root_dir, music)
        self.music_player.play_click(music_file)
        self.start_flag = True
        self.playing_flag = True
        self.current_index = index
        self.current_music = music
        await self.send_response(request['path'], music)

    async def pause_music(self, **kwargs):
        request = kwargs['request']
        self.music_player.pause_click()
        self.playing_flag = False
        await self.send_response(request['path'], {'play_status': 'play'})

    async def unpause_music(self, **kwargs):
        if not self.start_flag:
            await self.next_music(request={'path': 'music/next'})
        else:
            request = kwargs['request']
            self.music_player.unpause_click()
            self.playing_flag = True
            await self.send_response(request['path'], {'play_status': 'pause'})

    async def pre_music(self, **kwargs):
        request = kwargs['request']
        index = self.get_index('pre')
        await self.play_music(request={'path': request['path'], 'query': {'index': index}})

    async def next_music(self, **kwargs):
        request = kwargs['request']
        index = self.get_index('next')
        await self.play_music(request={'path': request['path'], 'query': {'index': index}})

    async def set_volume(self, **kwargs):
        request = kwargs['request']
        volume = request['query']['volume_value']
        self.music_player.set_volume(round(volume/100, 2))
        await self.send_response(request['path'], volume)

    def get_index(self, click_type):
        if not self.start_flag:
            return 0
        if self.play_mode == 'loop':
            if click_type == 'pre':
                index = -1 if self.current_index == 0 else self.current_index-1
            if click_type == 'next':
                index = 0 if self.current_index == len(self.music_list) - 1 else self.current_index + 1
        elif self.play_mode == 'random':
            index = random.randrange(0, len(self.music_list))
        return index

    async def auto_next(self):
        while True:
            if self.start_flag:
                if self.music_player.get_music_pos() == -1:
                    await self.next_music(request={'path': 'music/next'})
            await asyncio.sleep(1)

    async def download_task(self):
        while True:
            if len(self.download_queue) >= 1:
                task_wait = self.download_queue[0]
                ret = await download_mp3(task_wait)
                self.download_queue.remove(task_wait)
                await self.send_response('music/download', self.download_queue)
                if ret['code'] == 1:
                    await self.get_local_music_list(request={'path': 'music/local'}, send_mode='2')
                await self.send_response('music/msg', ret['msg'])
            else:
                await asyncio.sleep(1)

    def init_router(self):
        return {
            'music/playerInfo': self.get_player_info,
            'music/local': self.get_local_music_list,
            'music/search': self.search_music_list,
            'music/download': self.download_music,
            'music/playMode': self.set_mode,
            'music/play': self.play_music,
            'music/pause': self.pause_music,
            'music/unpause': self.unpause_music,
            'music/pre': self.pre_music,
            'music/next': self.next_music,
            'music/volume': self.set_volume
        }

    def handle_client(self, ws, path):
        client_name = path.replace('/', '')
        self.client_list[client_name] = ws
        return client_name
示例#2
0
class MusicScreen(Screen):
    ''' Shows the popup to choose the file to play
    '''
    '''def show_load(self):
        content = LoadDialog(load=self.load, cancel=self.dismiss_popup)
        self._popup = Popup(title="Load file", content=content,
                            size_hint=(0.9, 0.9))
        self._popup.open()

    def dismiss_popup(self):
        self._popup.dismiss()'''
    def __init__(self, **kwargs):
        super(MusicScreen, self).__init__(**kwargs)
        #self.library_manager = LibraryManager()
        self.player = MusicPlayer()

        # # Getting the layout to dinamically add the buttons
        #ml_list_view = self.ids.ml_list_view

        # adding files to library
        #songs = self.library_manager.parse_library()

        # for song in songs:
        #    btn = Button(text=os.path.basename(song), font_size=14)# , on_press=self.play_station(radio)
        #    #btn.bind(on_press=self.pressed)
        #    #btn.bind(on_press=self.play_station)
        #    ml_layout.add_widget(btn)

        # list_adapter = ListAdapter(data=songs, cls=ListItemButton, selection_mode='single')
        # list_adapter.bind(on_selection_change=self.selection_change)

        # ml_list_view.adapter = list_adapter

        # songs_text = ''
        # for song in songs:
        #     songs_text = songs_text + song

        # library_text.text = songs_text#''.join('aaaa ').join('bbbb')#, 'and something else')
        #library_text.text = library_text.text.join('bbbb')

    def selection_change(self, adapter, *args):
        print "selection changed"

    def load(self, path, filename):
        pass
        #self.player.stop_audio()
        self.player.load_audio(filename[0])
        #self.dismiss_popup()

    '''Playing or pausing a song.
        1) If stopped play it again from the 'elapsed' value.
           If it's 0 play it from the beginning.
        2) If it's playing store the elapsed time and stop the song.
    '''

    def play_pause_audio(self):
        pass
        self.player.play_pause_audio()

    def pause_audio(self):
        pass
        self.player.pause_audio()

    def play_audio(self):
        pass
        self.player.play_audio()

    ''' Stopping the song.
        1) self.elapsed set to 0 so the next song (or the same)
           will be played from the beginning
        2) actually stop the song
    '''

    def stop_audio(self):
        pass
        self.player.stop_audio()

    ''' Reloading the song if it's currently playing.
        Just call self.stop_song and then self.play_pause_song        
    '''

    def reload_audio(self):
        pass
        self.player.reload_audio()

    ''' Setting the volume.
        When the value of the slider is changed, this will affect the 
        volume of the played song.
    '''

    def set_volume(self, value):
        pass
        self.player.set_volume(value)
示例#3
0
class MusicServer:
    client_list = {}
    root_dir = './musics'
    search_tool = Search()
    download_queue = []

    def __init__(self):
        # 0是全部列表
        self.current_menu_id = 0
        self.music_list = []
        self.music_player = MusicPlayer()
        self.album_manager = InstanceAsyncAlbumManager
        self.api_map = self.init_router()
        self.start_flag = False
        self.playing_flag = False
        self.play_mode = 'loop'
        self.current_index = -1
        self.current_music = {}

        websocket_server = websockets.serve(self.service, '0.0.0.0', 8888)
        asyncio.get_event_loop().run_until_complete(websocket_server)
        asyncio.ensure_future(self.auto_next())
        asyncio.ensure_future(self.download_task())
        asyncio.get_event_loop().run_forever()

    async def service(self, websocket, path):
        client_name = self.handle_client(websocket, path)
        async for message in websocket:
            await self.router(client_name, json.loads(message))

    async def router(self, client_name, request):
        print(f'{client_name}:{request}')
        await self.api_map[request['path']](request=request,
                                            client_name=client_name)

    async def send_response(self, path, data, client_name=None):
        response = json.dumps({'api': path, 'data': data})
        if client_name:
            await self.client_list[client_name].send(response)
        else:
            offline = []
            for client, ws in self.client_list.items():
                try:
                    await ws.send(response)
                except:
                    print(f'{client} offline')
                    offline.append(client)
            for client in offline:
                self.client_list.pop(client)

    async def get_player_info(self, **kwargs):
        request = kwargs['request']
        data = {
            'mode': self.play_mode,
            'music': self.current_music,
            'play_status': self.playing_flag,
            'volume': self.music_player.get_music_volume(),
            'menu_list': await self.album_manager.get_album_list(),
            'current_menu': self.album_manager.current_album_id
        }
        await self.send_response(request['path'], data)

    async def get_all_songs(self, **kwargs):
        self.current_menu_id = 0
        request = kwargs['request']
        self.music_list = await self.album_manager.all_songs()
        data = {
            'player_status': self.start_flag,
            'music_list': self.music_list
        }
        # send_mode = kwargs['send_mode'] if kwargs.get('send_mode') else 1
        await self.send_response(request['path'], data, kwargs['client_name'])

    async def get_menu_songs(self, **kwargs):
        request = kwargs['request']
        album_id = request['query']['menu_id']
        # self.current_menu_id = menu_id
        music_list = await self.album_manager.get_album_songs(album_id)
        data = {'menu_id': album_id, 'music_list': music_list}
        await self.send_response(request['path'], data, kwargs['client_name'])

    async def search_music_list(self, **kwargs):
        request = kwargs['request']
        search_value = request['query']['search_value']
        music_list = await self.search_tool.search_song(search_value)
        data = {'player_status': self.start_flag, 'music_list': music_list}
        await self.send_response(request['path'], data, kwargs['client_name'])

    async def download_music(self, **kwargs):
        request = kwargs['request']
        music = request['query']['music']
        self.download_queue.append(music)
        await self.send_response(request['path'], self.download_queue)

    async def set_mode(self, **kwargs):
        request = kwargs['request']
        self.play_mode = request['query']['mode']
        await self.send_response(request['path'],
                                 {'play_mode': self.play_mode})

    # 前端回传song_id 和 album_id
    async def play_music(self, **kwargs):
        if not self.start_flag:
            await self.send_response(
                'music/volume',
                self.music_player.get_music_volume() * 100)

        request = kwargs['request']
        index = request['query']['index']
        song_id = request['query']['song_id']
        album_id = request['query'].get('album_id', 0)
        song = await self.album_manager.set_current_song(song_id)
        print(song)
        # 设置歌单
        await self.album_manager.set_current_play_list(album_id)
        self.album_manager.set_current_album_id(album_id)
        self.album_manager.set_next_song()
        music_file = parse_file_path(self.root_dir, song)
        # music = await self.album_manager.get_song_info(self.current_menu_id, song_id)
        self.music_player.play_click(music_file)
        self.start_flag = True
        self.playing_flag = True
        self.current_index = index
        self.current_music = song
        # self.album_manager.set_current_album_id(album_id)
        song["album_id"] = album_id

        await self.send_response(request['path'], song)

    async def pause_music(self, **kwargs):
        request = kwargs['request']
        self.music_player.pause_click()
        self.playing_flag = False
        await self.send_response(request['path'], {'play_status': 'play'})

    async def unpause_music(self, **kwargs):
        if not self.start_flag:
            await self.next_music(request={'path': 'music/next'})
        else:
            request = kwargs['request']
            self.music_player.unpause_click()
            self.playing_flag = True
            await self.send_response(request['path'], {'play_status': 'pause'})

    async def pre_music(self, **kwargs):
        request = kwargs['request']
        index = self.get_index('pre')
        await self.play_music(request={
            'path': request['path'],
            'query': {
                'index': index
            }
        })

    async def next_music(self, **kwargs):
        request = kwargs['request']
        # index = self.get_index('next')
        song = self.album_manager.next_song if self.play_mode == "loop" else self.album_manager.get_random_song(
        )
        print(song)

        # index的逻辑没有动
        await self.play_music(
            request={
                'path': request['path'],
                'query': {
                    'index': 0,
                    'song_id': song['song_id'],
                    'album_id': self.album_manager.current_album_id
                }
            })

    async def set_volume(self, **kwargs):
        request = kwargs['request']
        volume = request['query']['volume_value']
        self.music_player.set_volume(volume / 100)
        await self.send_response(request['path'], volume)

    async def add_menu(self, **kwargs):
        request = kwargs['request']
        menu_name = request['query']['menu_name']
        await self.album_manager.add_album(menu_name, '')
        await self.send_response(request['path'], await
                                 self.album_manager.get_album_list())

    async def add_song_to_menu(self, **kwargs):
        request = kwargs['request']
        menu_id = request['query']['menu_id']
        song = request['query']['song']
        await self.album_manager.add_album_song(menu_id, song)

    async def del_song_from_menu(self, **kwargs):
        request = kwargs['request']
        song = request['query']['song']
        await self.album_manager.del_album_song(song['album_id'],
                                                song['song_id'])
        self.music_list = await self.album_manager.get_album_songs(
            song['album_id'])
        await self.get_menu_songs(request={
            'path': 'music/menu',
            'query': {
                'menu_id': song['album_id']
            }
        })

    def get_index(self, click_type):
        index = 0
        if not self.start_flag:
            return index
        if self.play_mode == 'loop':
            if click_type == 'pre':
                index = -1 if self.current_index == 0 else self.current_index - 1
            if click_type == 'next':
                index = 0 if self.current_index == len(
                    self.music_list) - 1 else self.current_index + 1
        elif self.play_mode == 'random':
            index = random.randrange(0, len(self.music_list))
        return index

    async def auto_next(self):
        while True:
            if self.start_flag:
                if self.music_player.get_music_pos() == -1:
                    await self.next_music(request={'path': 'music/next'})
            await asyncio.sleep(1)

    async def download_task(self):
        while True:
            if len(self.download_queue) >= 1:
                task_wait = self.download_queue[0]
                ret = await download_mp3(task_wait)
                self.download_queue.remove(task_wait)
                await self.send_response('music/download', self.download_queue)
                if ret['code'] == 1:
                    await self.album_manager.add_song(ret['song'])
                await self.send_response('music/msg', ret['msg'])
            else:
                await asyncio.sleep(1)

    def init_router(self):
        return {
            'music/playerInfo': self.get_player_info,
            'music/local': self.get_all_songs,
            'music/menu': self.get_menu_songs,
            'music/search': self.search_music_list,
            'music/download': self.download_music,
            'music/playMode': self.set_mode,
            'music/play': self.play_music,
            'music/pause': self.pause_music,
            'music/unpause': self.unpause_music,
            'music/pre': self.pre_music,
            'music/next': self.next_music,
            'music/volume': self.set_volume,
            'music/menu/add': self.add_menu,
            'music/menu/add/song': self.add_song_to_menu,
            'music/menu/del/song': self.del_song_from_menu,
        }

    def handle_client(self, ws, path):
        client_name = path.replace('/', '')
        self.client_list[client_name] = ws
        return client_name
示例#4
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)
示例#5
0
class Bot(commands.Bot):
    def __init__(
        self,
        spam_time=600,
        spam_messages=[],
        custom_rewards=[],
        tts_engine=None,
        greeting_message=''
    ):
        super().__init__(
            irc_token=os.environ.get('TMI_TOKEN'),
            client_id=os.environ.get('CLIENT_ID'),
            nick=os.environ.get('BOT_NICK'),
            prefix=os.environ.get('BOT_PREFIX'),
            initial_channels=[os.environ.get('CHANNEL')],
            client_secret=os.environ.get('CLIENT_SECRET'))

        self.user_id = os.environ.get('TWITCH_USER_ID')
        self.ignore_users = [self.nick]
        self.only_owner_commands = ['dtts', 'atts']
        self.only_mod_commands = ['vol', 'next', 'stop']
        self.owner_nick = os.environ.get('CHANNEL').replace('#', '').lower()
        self.spam_time = spam_time
        self.spam_messages = spam_messages
        self.chatters_list = []
        self.custom_rewards = custom_rewards
        self.greeting_message = greeting_message

        self.riot_api = RiotAPI()
        self.cats_api = CatsAPI()
        self.tts_engine = tts_engine
        self.music_player = MusicPlayer(os.environ.get('DOWNLOADS_PATH'))
        self.music_dl = MusicDL(download_path=os.environ.get('DOWNLOADS_PATH'))

    async def event_ready(self):
        print(f'{self.nick} is ready')
        if len(self.spam_messages) > 0:
            await self.spam()

    async def event_command_error(self, message, ex):
        if ex.__class__ is CommandNotFound:
            await send_exception(message, 'No se reconoce el comando. Usa !c para ver todos los comandos.')
            return
        await send_exception(message, ex)

    async def event_raw_usernotice(self, channel, tags):
        print(tags)

    async def event_message(self, message):
        try:
            if message.author.name.lower() in self.ignore_users:
                return

            if message.author.name.lower() not in self.chatters_list:
                await message.channel.send(self.greeting_message.format(message.author.name))
                self.chatters_list.append(message.author.name)

            await self.handle_commands(message)
            await self.handle_custom_rewards(message)
        except Exception as ex:
            print(ex)

    async def handle_custom_rewards(self, message):
        try:
            reward_id = message.tags.get("custom-reward-id", None)

            if not reward_id:
                return
            if reward_id not in self.custom_rewards:
                return

            reward_action = self.custom_rewards[reward_id]

            if type(reward_action) == str:
                return

            reward_action(message)
        except Exception as ex:
            print(ex)

    async def spam(self):
        channel = self.get_channel(self.owner_nick)
        while True:
            await asyncio.sleep(self.spam_time)
            selected_message = random.choice(self.spam_messages)
            await channel.send(selected_message)

    @commands.command(name='michi')
    async def cat(self, message):
        try:
            cat_url = self.cats_api.get_random_cat()
            await message.channel.send(f'{message.author.name}, disfruta tu michi {cat_url}')
        except RandomCatException as ex:
            await self.send_exception(message, ex)
        except Exception as ex:
            print(ex)

    @commands.command(name='redes')
    async def social_media(self, message):
        try:
            social_media = [
                'https://twitter.com/Luis_LiraC',
                'https://www.youtube.com/c/luislira',
                'https://www.instagram.com/luislirac/',
            ]
            response = 'Me puedes seguir en:\n' + '\n'.join(social_media)
            await message.channel.send(response)
        except Exception as ex:
            print(ex)

    @commands.command(name='mt')
    async def mastery(self, message):
        try:
            result = self.riot_api.get_mastery_info(message.message.content)
            await message.channel.send(f"""{message.author.name}. 
            Tengo {result['points']} puntos de maestría con {result['name']}.
            La última vez que lo jugué fue en {result['date']}
            """)
        except ChampionException as ex:
            await send_exception(message, ex)
        except NotPlayedException as ex:
            await send_exception(message, ex)
        except Exception as ex:
            print(ex)

    @commands.command(name='c')
    async def cmd(self, message):
        try:
            keys = list(map(lambda c: f'!{c}' if c not in self.only_owner_commands and c not in self.only_mod_commands else '', [
                        *self.commands.keys()]))

            if message.author.is_mod:
                for c in self.only_mod_commands:
                    keys.append(f'{c}')

            response = f'{message.author.name} Puedes usar estos comandos:\n' + \
                '\n'.join(keys)
            await message.channel.send(response)
        except Exception as ex:
            print(ex)

    @commands.command(name='followage')
    async def follow_age(self, message):
        try:
            follower_name = message.author.name.lower()
            followers_list = await self.get_followers(self.user_id)
            follow_date = None

            for follower in followers_list:
                if follower['from_name'].lower() == follower_name:
                    follow_date = follower['followed_at']
                    break

            if follow_date is None:
                await message.channel.send(f'{follower_name}, no me sigues :(')
                return

            utc_date = datetime.strptime(follow_date, '%Y-%m-%dT%H:%M:%SZ')
            date = utc_date.replace(tzinfo=timezone.utc).astimezone(tz=None)
            now = datetime.utcnow().replace(tzinfo=timezone.utc).astimezone(tz=None)
            following_days = (now - date).days

            if following_days == 1 or following_days == 0:
                await message.channel.send(f'{follower_name}, tienes 1 día siguiéndome. Muchas gracias 🥳')
            elif following_days > 1:
                await message.channel.send(f'{follower_name}, tienes {following_days} días siguiéndome. Muchas gracias 🥳')
        except Exception as ex:
            print(ex)

    @commands.command(name='atts')
    async def activate_tts(self, message):
        if self.tts_engine is None:
            return
        if message.author.name.lower() == self.owner_nick:
            self.tts_engine.activate()

    @commands.command(name='dtts')
    async def deactivate_tts(self, message):
        if self.tts_engine is None:
            return
        if message.author.name.lower() == self.owner_nick:
            self.tts_engine.deactivate()

    @commands.command(name='bonk')
    async def bonk(self, message):
        playsound('./sounds/bonk.mp3')

    @commands.command(name='sr')
    async def song_request(self, message):
        try:
            user_input = message.content.replace('!sr', '').strip()
            if user_input == '':
                raise NotResultsException

            song_reference = self.music_dl.download(user_input)

            if song_reference is None:
                raise NotResultsException
            song_name = self.music_dl.get_song_name(song_reference)
            await self.music_player.add_to_playlist(song_reference, message, song_name)
        except MaxDurationException as ex:
            await send_exception(message, ex)
        except NotResultsException as ex:
            await send_exception(message, ex)
        except Exception as ex:
            print('----------')
            print(ex)
            print('----------')
            # I needed to do this because only this "fix" a weird bug
            # When the player stop and then play music again the volume change to -1 and it ignore every
            # validation that I do to change it again to the initial volume
            self.music_player = MusicPlayer(os.environ.get('DOWNLOADS_PATH'))
            print(f'[Music Player Restarted at {datetime.now()}]')
            print('----------')

    @commands.command(name='next')
    async def next_song(self, message):
        try:
            if message.author.is_mod:
                await self.music_player.next()
        except Exception as ex:
            print(ex)

    @commands.command(name='vol')
    async def volume(self, message):
        try:
            if message.author.is_mod:
                volume = message.content.replace('!vol ', '').strip()
                self.music_player.set_volume(volume)
        except Exception as ex:
            print(ex)

    @commands.command(name='currentsong')
    async def currentsong(self, message):
        try:
            reference = self.music_player.get_song_reference()
            song_name = self.music_dl.get_song_name(reference)

            if song_name is not None:
                await message.channel.send(f'{message.author.name}. La canción es: {song_name}')
        except Exception as ex:
            print(ex)

    @commands.command(name='stop')
    async def stop(self, message):
        try:
            if message.author.is_mod:
                self.music_player.stop()
        except Exception as ex:
            print(ex)
示例#6
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)