Beispiel #1
0
 def _handle_currentsong(self, metadata):
     logging.debug('currentsong: %s', metadata)
     args = {}
     for key in ('title', 'artist', 'album'):
         if key in metadata:
             args[key] = metadata[key]
     if 'time' in metadata:
         args['length'] = int(metadata['time']) * 1000
     if 'track' in metadata:
         args['tracknum'] = int(metadata['track'].split('/')[0])
     self._metadata = Metadata(**args)
Beispiel #2
0
 def __init__(self, conn):
     dbus.service.Object.__init__(self,
                                  conn=conn,
                                  object_path=LYRICS_OBJECT_PATH)
     self._db = lrcdb.LrcDb()
     self._config = osdlyrics.config.Config(conn)
     self._metadata = Metadata()
Beispiel #3
0
 def GetRawLyrics(self, metadata):
     if isinstance(metadata, dict):
         metadata = Metadata.from_dict(metadata)
     uri = self.find_lrc_from_db(metadata)
     lrc = None
     if uri:
         if uri == 'none:':
             return True, uri, ''
         lrc = load_from_uri(uri)
         if lrc is not None:
             return True, uri, lrc
     uri = self.find_lrc_by_pattern(metadata)
     if uri:
         lrc = load_from_uri(uri)
         if lrc is not None:
             logging.info(
                 "LRC for track %s not found in db but fount by pattern: %s"
                 % (metadata_description(metadata), uri))
     if lrc is None:
         logging.info("LRC for track %s not found" %
                      metadata_description(metadata))
         return False, '', ''
     else:
         logging.info("LRC for track %s found: %s" %
                      (metadata_description(metadata), uri))
         return True, uri, lrc
Beispiel #4
0
 def __init__(self, proxy, name, caps):
     super(HttpPlayer, self).__init__(proxy, name)
     self._status = STATUS_STOPPED
     self._caps = caps
     self._metadata = Metadata()
     self._last_ping = datetime.datetime.now()
     self._timer = osdlyrics.timer.Timer()
     self._cmds = []
Beispiel #5
0
 def SetLyricContent(self, metadata, content):
     metadata = Metadata.from_dict(metadata)
     # Remove any existing file association and save the new lyrics content
     # to the configured patterns.
     self._db.delete(metadata)
     uri = self._save_to_patterns(metadata, content.rstrip(b'\0'))
     if uri and metadata == self._metadata:
         self.CurrentLyricsChanged()
     return uri
Beispiel #6
0
 def do_track_changed(self, params):
     player = self.get_player(params['id'])
     status = params['status']
     del params['status']
     del params['id']
     metadata = Metadata(**params)
     player.do_update_track(metadata)
     player.do_update_status(status)
     return ''
Beispiel #7
0
 def __init__(self, ):
     osdlyrics.App.__init__(self, 'Daemon', False)
     self._player = player.PlayerSupport(self.connection)
     self._lyrics = lyrics.LyricsService(self.connection)
     self._connect_metadata_signal()
     self._activate_config()
     self.request_bus_name(osdlyrics.APP_MPRIS2_NAME)
     self._daemon_object = DaemonObject(self)
     self._lyricsource = lyricsource.LyricSource(self.connection)
     self._lyrics.set_current_metadata(Metadata.from_dict(self._player.current_player.Metadata))
Beispiel #8
0
 def SetLyricContent(self, metadata, content):
     if isinstance(metadata, dict):
         metadata = Metadata.from_dict(metadata)
     uri = self.find_lrc_from_db(self._metadata)
     if uri is None or not save_to_uri(uri, content, False):
         uri = ''
     if uri == '':
         uri = self._save_to_patterns(metadata, content)
     if uri and metadata_equal(metadata, self._metadata):
         self.CurrentLyricsChanged()
     return uri
Beispiel #9
0
 def _handle_currentsong(self, metadata):
     logging.debug('currentsong: %s', metadata)
     args = {}
     for key in ('title', 'artist', 'album'):
         if key in metadata:
             args[key] = metadata[key]
     if 'time' in metadata:
         args['length'] = int(metadata['time']) * 1000
     if 'track' in metadata:
         args['tracknum'] = int(metadata['track'].split('/')[0])
     self._metadata = Metadata(**args)
Beispiel #10
0
 def __init__(self, ):
     App.__init__(self, 'Daemon', False)
     self._player = player.PlayerSupport(self.connection)
     self._lyrics = lyrics.LyricsService(self.connection)
     self._connect_metadata_signal()
     self._activate_config()
     self.request_bus_name(DAEMON_MPRIS2_NAME)
     self._daemon_object = DaemonObject(self)
     self._lyricsource = lyricsource.LyricSource(self.connection)
     self._lyrics.set_current_metadata(
         Metadata.from_dict(self._player.current_player.Metadata))
Beispiel #11
0
 def SetLyricContent(self, metadata, content):
     if isinstance(metadata, dict):
         metadata = Metadata.from_dict(metadata)
     uri = self.find_lrc_from_db(self._metadata)
     if uri is None or not save_to_uri(uri, content, False):
         uri = ''
     if uri == '':
         uri = self._save_to_patterns(metadata, content)
     if uri and metadata_equal(metadata, self._metadata):
         self.CurrentLyricsChanged()
     return uri
Beispiel #12
0
    def _handle_status(self, status):
        logging.debug('status\n%s', status)
        changes = set()
        for prop, handler in self.STATUS_CHANGE_MAP.items():
            if not prop in status:
                value = None
            else:
                funcname = handler[0]
                func = getattr(__builtin__, funcname) \
                    if not funcname.startswith('_') \
                    else getattr(self, funcname)
                value = func(status[prop])
            if value != getattr(self, '_' + prop):
                logging.debug('prop %s changed to %s', prop, value)
                setattr(self, '_' + prop, value)
                changes.add(handler[1])

        if 'track' in changes:
            if self._songid is None:
                self._metadata = Metadata()
            else:
                self._send_cmd(Cmds.CURRENTSONG, sync=True)

        if 'status' in changes:
            if self._state == STATUS_PAUSED:
                self._elapsed.pause()
            elif self._state == STATUS_PLAYING:
                self._elapsed.play()
            else:
                self._elapsed.stop()
        if self._state == STATUS_STOPPED:
            elapsed = 0
        else:
            elapsed = float(status['elapsed']) * 1000
        if self._elapsed.set_time(elapsed):
            changes.add('position')
        if not self._inited:
            # Initializing, do not emit the change signals
            changes = set()
        for change in changes:
            getattr(self, change + '_changed')()
Beispiel #13
0
    def _handle_status(self, status):
        logging.debug('status\n%s', status)
        changes = set()
        for prop, handler in self.STATUS_CHANGE_MAP.items():
            if not prop in status:
                value = None
            else:
                funcname = handler[0]
                func = getattr(__builtin__, funcname) \
                    if not funcname.startswith('_') \
                    else getattr(self, funcname)
                value = func(status[prop])
            if value != getattr(self, '_' + prop):
                logging.debug('prop %s changed to %s', prop, value)
                setattr(self, '_' + prop, value)
                changes.add(handler[1])

        if 'track' in changes:
            if self._songid is None:
                self._metadata = Metadata()
            else:
                self._send_cmd(Cmds.CURRENTSONG, sync=True)

        if 'status' in changes:
            if self._state == STATUS_PAUSED:
                self._elapsed.pause()
            elif self._state == STATUS_PLAYING:
                self._elapsed.play()
            else:
                self._elapsed.stop()
        if self._state == STATUS_STOPPED:
            elapsed = 0
        else:
            elapsed = float(status['elapsed']) * 1000
        if self._elapsed.set_time(elapsed):
            changes.add('position')
        if not self._inited:
            # Initializing, do not emit the change signals
            changes = set()
        for change in changes:
            getattr(self, change + '_changed')()
Beispiel #14
0
 def GetRawLyrics(self, metadata):
     if isinstance(metadata, dict):
         metadata = Metadata.from_dict(metadata)
     uri = self.find_lrc_from_db(metadata)
     lrc = None
     if uri:
         if uri == 'none:':
             return True, uri, ''
         lrc = load_from_uri(uri)
         if lrc is not None:
             return True, uri, lrc
     uri = self.find_lrc_by_pattern(metadata)
     if uri:
         lrc = load_from_uri(uri)
         if lrc is not None:
             logging.info("LRC for track %s not found in db but found by pattern: %s", metadata_description(metadata), uri)
     if lrc is None:
         logging.info("LRC for track %s not found", metadata_description(metadata))
         return False, '', ''
     else:
         logging.info("LRC for track %s found: %s", metadata_description(metadata), uri)
         return True, uri, lrc
Beispiel #15
0
 def _track_change_cb(self, metadata):
     metadata = Metadata.from_dict(metadata)
     self.track_changed(metadata)
Beispiel #16
0
 def get_metadata(self):
     mt = self._player.GetMetadata()
     logging.debug(repr(mt))
     return Metadata.from_dict(mt)
Beispiel #17
0
 def AssignLyricFile(self, metadata, filepath):
     if (isinstance(metadata, dict)):
         metadata = Metadata.from_dict(metadata)
     self.assign_lrc_uri(metadata, osdlyrics.utils.path2uri(filepath))
Beispiel #18
0
 def _track_change_cb(self, metadata):
     metadata = Metadata.from_dict(metadata)
     self.track_changed(metadata)
Beispiel #19
0
 def AssignLyricFile(self, metadata, filepath):
     if (isinstance(metadata, dict)):
         metadata = Metadata.from_dict(metadata)
     self.assign_lrc_uri(metadata, osdlyrics.utils.path2uri(filepath))
Beispiel #20
0
 def AssignLyricFile(self, metadata, uri):
     metadata = Metadata.from_dict(metadata)
     self.assign_lrc_uri(metadata, uri)
Beispiel #21
0
 def get_metadata(self):
     metadata = self._player_prop.Get(MPRIS2_IFACE, 'Metadata')
     return Metadata.from_mpris2(metadata)
Beispiel #22
0
 def _player_properties_changed(self, iface, changed, invalidated):
     if 'Metadata' in changed:
         self._lyrics.set_current_metadata(Metadata.from_dict(changed['Metadata']))
Beispiel #23
0
 def get_metadata(self):
     mt = self._player.GetMetadata()
     logging.debug(repr(mt))
     return Metadata.from_dict(mt)
Beispiel #24
0
class MpdPlayer(BasePlayer):

    CMD_HANDLERS = {
        Cmds.CURRENTSONG: '_handle_currentsong',
        Cmds.NEXT: None,
        Cmds.PAUSE: None,
        Cmds.PLAY: None,
        Cmds.PREVIOUS: None,
        Cmds.RANDOM: None,
        Cmds.REPEAT: None,
        Cmds.REPLAY_GAIN_MODE: None,
        Cmds.REPLAY_GAIN_STATUS: '_handle_replay_gain_status',
        Cmds.SEEK: None,
        Cmds.SEEKCUR: None,
        Cmds.SEEKID: None,
        Cmds.SETVOL: None,
        Cmds.SINGLE: None,
        Cmds.STATUS: '_handle_status',
        Cmds.STOP: None,
    }

    CHANGE_CMDS = {
        'player': [Cmds.STATUS],
        'options': [Cmds.STATUS],
    }

    STATUS_CHANGE_MAP = {
        'songid': ('int', 'track'),
        'playlist': ('int', 'track'),
        'repeat': ('int', 'repeat'),
        'single': ('int', 'repeat'),
        'random': ('int', 'shuffle'),
        'state': ('_parse_status', 'status'),
    }

    def __init__(self, proxy, playername):
        super(MpdPlayer, self).__init__(proxy, playername)
        self._inited = False
        self._metadata = None
        self._songid = -1
        self._playlist = -1
        self._repeat = None
        self._single = None
        self._random = None
        self._state = None
        self._elapsed = Timer(100)
        self._send_cmd(Cmds.STATUS, sync=True)
        self._inited = True

    def _send_cmd(self, cmd, *args, **kwargs):
        """ Send a cmd. Can use sync=[True|False] to send in a blocking or
        non-blocking way. Default is non-blocking
        """
        sync = False if 'sync' not in kwargs else kwargs['sync']
        if cmd not in self.CMD_HANDLERS:
            raise RuntimeError('Unknown command: %s', cmd)
        handler = self.CMD_HANDLERS[cmd]
        if handler is not None:
            handler = getattr(self, handler)
        else:
            handler = self._handle_nothing
        if sync:
            self.proxy.send_command_sync(cmd, handler, *args)
        else:
            self.proxy.send_command(cmd, handler, *args)

    def _handle_status(self, status):
        logging.debug('status\n%s', status)
        changes = set()
        for prop, handler in self.STATUS_CHANGE_MAP.items():
            if not prop in status:
                value = None
            else:
                funcname = handler[0]
                func = getattr(__builtin__, funcname) \
                    if not funcname.startswith('_') \
                    else getattr(self, funcname)
                value = func(status[prop])
            if value != getattr(self, '_' + prop):
                logging.debug('prop %s changed to %s', prop, value)
                setattr(self, '_' + prop, value)
                changes.add(handler[1])

        if 'track' in changes:
            if self._songid is None:
                self._metadata = Metadata()
            else:
                self._send_cmd(Cmds.CURRENTSONG, sync=True)

        if 'status' in changes:
            if self._state == STATUS_PAUSED:
                self._elapsed.pause()
            elif self._state == STATUS_PLAYING:
                self._elapsed.play()
            else:
                self._elapsed.stop()
        if self._state == STATUS_STOPPED:
            elapsed = 0
        else:
            elapsed = float(status['elapsed']) * 1000
        if self._elapsed.set_time(elapsed):
            changes.add('position')
        if not self._inited:
            # Initializing, do not emit the change signals
            changes = set()
        for change in changes:
            getattr(self, change + '_changed')()

    def _handle_currentsong(self, metadata):
        logging.debug('currentsong: %s', metadata)
        args = {}
        for key in ('title', 'artist', 'album'):
            if key in metadata:
                args[key] = metadata[key]
        if 'time' in metadata:
            args['length'] = int(metadata['time']) * 1000
        if 'track' in metadata:
            args['tracknum'] = int(metadata['track'].split('/')[0])
        self._metadata = Metadata(**args)

    def _parse_status(self, value):
        status_map = {
            'play': STATUS_PLAYING,
            'pause': STATUS_PAUSED,
            'stop': STATUS_STOPPED,
        }
        if value not in status_map:
            raise RuntimeError('Unknown status ' + value)
        return status_map[value]

    def _handle_replay_gain_status(self, status):
        pass

    def _handle_nothing(self, *args):
        pass

    def handle_changes(self, changes):
        cmds = set()
        for change in changes:
            if change in self.CHANGE_CMDS:
                for cmd in self.CHANGE_CMDS[change]:
                    cmds.add(cmd)
        logging.debug('changes: %s', changes)
        logging.debug('cmds: %s', cmds)
        for cmd in cmds:
            self._send_cmd(cmd)

    def get_status(self):
        return self._state

    def get_metadata(self):
        return self._metadata

    def get_position(self):
        return self._elapsed.time

    def get_caps(self):
        return set([CAPS_PLAY, CAPS_PAUSE, CAPS_NEXT, CAPS_PREV, CAPS_SEEK])

    def get_repeat(self):
        if not self._repeat:
            return REPEAT_NONE
        if not self._single:
            return REPEAT_ALL
        return REPEAT_TRACK

    def set_repeat(self, mode):
        repeat_mode_map = {
            REPEAT_NONE: (0, 0),
            REPEAT_TRACK: (1, 1),
            REPEAT_ALL: (1, 0),
        }
        if mode not in repeat_mode_map:
            raise ValueError('Unknown repeat mode: %s', mode)
        self._repeat = repeat_mode_map[mode][0]
        self._single = repeat_mode_map[mode][1]
        self._send_cmd(Cmds.REPEAT, self._repeat)
        self._send_cmd(Cmds.SINGLE, self._single)

    def get_shuffle(self):
        return bool(self._random)

    def set_shuffle(self, shuffle):
        self._random = 1 if shuffle else 0
        self._send_cmd(Cmds.RANDOM, self._random)

    def play(self):
        if self._state == STATUS_PAUSED:
            self._send_cmd(Cmds.PAUSE, 0)
        elif self._state == STATUS_STOPPED:
            self._send_cmd(Cmds.PLAY)

    def pause(self):
        self._send_cmd(Cmds.PAUSE, 1)

    def stop(self):
        self._send_cmd(Cmds.STOP)

    def prev(self):
        self._send_cmd(Cmds.PREVIOUS)

    def next(self):
        self._send_cmd(Cmds.NEXT)

    def set_position(self, pos):
        self._send_cmd(Cmds.SEEK, self._songid, int(pos / 1000))

    def debug_info(self):
        ret = dbus.Dictionary(signature='sv')
        ret.update({
            'state': self._state,
            'metadata': self._metadata.to_mpris1(),
            'repeat': self._repeat,
            'single': self._single,
            'position': self.get_position()
        })
        return ret
Beispiel #25
0
 def get_metadata(self):
     metadata = self._player_prop.Get(MPRIS2_PLAYER_INTERFACE, 'Metadata')
     return Metadata.from_mpris2(metadata)
Beispiel #26
0
class MpdPlayer(BasePlayer):

    CMD_HANDLERS = {
        Cmds.CURRENTSONG: '_handle_currentsong',
        Cmds.NEXT: None,
        Cmds.PAUSE: None,
        Cmds.PLAY: None,
        Cmds.PREVIOUS: None,
        Cmds.RANDOM: None,
        Cmds.REPEAT: None,
        Cmds.REPLAY_GAIN_MODE: None,
        Cmds.REPLAY_GAIN_STATUS: '_handle_replay_gain_status',
        Cmds.SEEK: None,
        Cmds.SEEKCUR: None,
        Cmds.SEEKID: None,
        Cmds.SETVOL: None,
        Cmds.SINGLE: None,
        Cmds.STATUS: '_handle_status',
        Cmds.STOP: None,
    }

    CHANGE_CMDS = {
        'player': [Cmds.STATUS],
        'options': [Cmds.STATUS],
    }

    STATUS_CHANGE_MAP = {
        'songid': (int, 'track'),
        'playlist': (int, 'track'),
        'repeat': (int, 'repeat'),
        'single': (int, 'repeat'),
        'random': (int, 'shuffle'),
        'state': ('_parse_status', 'status'),
    }

    def __init__(self, proxy, playername):
        super().__init__(proxy, playername)
        self._inited = False
        self._metadata = None
        self._songid = -1
        self._playlist = -1
        self._repeat = None
        self._single = None
        self._random = None
        self._state = None
        self._elapsed = Timer(100)
        self._send_cmd(Cmds.STATUS, sync=True)
        self._inited = True

    def _send_cmd(self, cmd, *args, **kwargs):
        """ Send a cmd. Can use sync=[True|False] to send in a blocking or
        non-blocking way. Default is non-blocking
        """
        sync = False if 'sync' not in kwargs else kwargs['sync']
        if cmd not in self.CMD_HANDLERS:
            raise RuntimeError('Unknown command: %s', cmd)
        handler = self.CMD_HANDLERS[cmd]
        if handler is not None:
            handler = getattr(self, handler)
        else:
            handler = self._handle_nothing
        if sync:
            self.proxy.send_command_sync(cmd, handler, *args)
        else:
            self.proxy.send_command(cmd, handler, *args)

    def _handle_status(self, status):
        logging.debug('status\n%s', status)
        changes = set()
        for prop, handler in self.STATUS_CHANGE_MAP.items():
            if prop not in status:
                value = None
            else:
                func = handler[0]
                if not callable(func):
                    func = getattr(self, func)
                value = func(status[prop])
            if value != getattr(self, '_' + prop):
                logging.debug('prop %s changed to %s', prop, value)
                setattr(self, '_' + prop, value)
                changes.add(handler[1])

        if 'track' in changes:
            if self._songid is None:
                self._metadata = Metadata()
            else:
                self._send_cmd(Cmds.CURRENTSONG, sync=True)

        if 'status' in changes:
            if self._state == STATUS.PAUSED:
                self._elapsed.pause()
            elif self._state == STATUS.PLAYING:
                self._elapsed.play()
            else:
                self._elapsed.stop()
        if self._state == STATUS.STOPPED:
            elapsed = 0
        else:
            elapsed = float(status['elapsed']) * 1000
        if self._elapsed.set_time(elapsed):
            changes.add('position')
        if not self._inited:
            # Initializing, do not emit the change signals
            changes = set()
        for change in changes:
            getattr(self, change + '_changed')()

    def _handle_currentsong(self, metadata):
        logging.debug('currentsong: %s', metadata)
        args = {}
        for key in ('title', 'artist', 'album'):
            if key in metadata:
                args[key] = metadata[key]
        if 'time' in metadata:
            args['length'] = int(metadata['time']) * 1000
        if 'track' in metadata:
            args['tracknum'] = int(metadata['track'].split('/')[0])
        self._metadata = Metadata(**args)

    @staticmethod
    def _parse_status(value):
        status_map = {
            'play': STATUS.PLAYING,
            'pause': STATUS.PAUSED,
            'stop': STATUS.STOPPED,
        }
        if value not in status_map:
            raise RuntimeError('Unknown status ' + value)
        return status_map[value]

    def _handle_replay_gain_status(self, status):
        pass

    def _handle_nothing(self, *args):
        pass

    def handle_changes(self, changes):
        cmds = set()
        for change in changes:
            if change in self.CHANGE_CMDS:
                for cmd in self.CHANGE_CMDS[change]:
                    cmds.add(cmd)
        logging.debug('changes: %s', changes)
        logging.debug('cmds: %s', cmds)
        for cmd in cmds:
            self._send_cmd(cmd)

    def get_status(self):
        return self._state

    def get_metadata(self):
        return self._metadata

    def get_position(self):
        return self._elapsed.time

    def get_caps(self):
        return set([CAPS.PLAY, CAPS.PAUSE, CAPS.NEXT, CAPS.PREV, CAPS.SEEK])

    def get_repeat(self):
        if not self._repeat:
            return REPEAT.NONE
        if not self._single:
            return REPEAT.ALL
        return REPEAT.TRACK

    def set_repeat(self, mode):
        repeat_mode_map = {
            REPEAT.NONE: (0, 0),
            REPEAT.TRACK: (1, 1),
            REPEAT.ALL: (1, 0),
        }
        if mode not in repeat_mode_map:
            raise ValueError('Unknown repeat mode: %s', mode)
        self._repeat = repeat_mode_map[mode][0]
        self._single = repeat_mode_map[mode][1]
        self._send_cmd(Cmds.REPEAT, self._repeat)
        self._send_cmd(Cmds.SINGLE, self._single)

    def get_shuffle(self):
        return bool(self._random)

    def set_shuffle(self, shuffle):
        self._random = 1 if shuffle else 0
        self._send_cmd(Cmds.RANDOM, self._random)

    def play(self):
        if self._state == STATUS.PAUSED:
            self._send_cmd(Cmds.PAUSE, 0)
        elif self._state == STATUS.STOPPED:
            self._send_cmd(Cmds.PLAY)

    def pause(self):
        self._send_cmd(Cmds.PAUSE, 1)

    def stop(self):
        self._send_cmd(Cmds.STOP)

    def prev(self):
        self._send_cmd(Cmds.PREVIOUS)

    def next(self):
        self._send_cmd(Cmds.NEXT)

    def set_position(self, pos):
        self._send_cmd(Cmds.SEEK, self._songid, int(pos // 1000))

    def debug_info(self):
        ret = dbus.Dictionary(signature='sv')
        ret.update({
            'state': self._state,
            'metadata': self._metadata.to_mpris1(),
            'repeat': self._repeat,
            'single': self._single,
            'position': self.get_position()
        })
        return ret
Beispiel #27
0
 def _player_properties_changed(self, iface, changed, invalidated):
     if 'Metadata' in changed:
         self._lyrics.set_current_metadata(
             Metadata.from_dict(changed['Metadata']))
Beispiel #28
0
 def get_metadata(self):
     mt = self._player.GetMetadata()
     print mt
     return Metadata.from_dict(mt)