예제 #1
0
파일: manager.py 프로젝트: mcayland/remuco
    def __on_owner_change(self, name, old, new):

        log.debug("dbus name owner changed: '%s' -> '%s'" % (old, new))

        _stop_pa(self.__pa)
        if new:
            _start_pa(self.__pa)
예제 #2
0
파일: remythm.py 프로젝트: cpatulea/remuco
    def __get_position(self):

        sp = self.__shell.get_player()

        db = self.__shell.props.db

        position = 0
        
        id_now = self.__item_id
        
        if id_now is not None:
            
            if sp.props.playing_from_queue:
                qmodel = self.__queue_sc.props.query_model
            elif self.__playlist_sc is not None:
                qmodel = self.__playlist_sc.get_entry_view().props.model
            else:
                qmodel = None
                
            if qmodel is not None:
                for row in qmodel:
                    id = db.entry_get(row[0], rhythmdb.PROP_LOCATION)
                    if id_now == id:
                        break
                    position += 1
                    
        log.debug("position: %i" % position)
        
        return position
예제 #3
0
파일: remotem.py 프로젝트: mcayland/remuco
    def __notify_file_opened(self, totem, file):

        # XXX: does not get called for podcasts from BBC plugin

        log.debug("file opened: %s" % file)

        self.__update_item = True
예제 #4
0
    def __init__(self, sock, addr, clients, pinfo_msg, msg_handler_fn, c_type):

        self.__sock = sock
        self.__addr = addr
        self.__clients = clients
        self.__pinfo_msg = pinfo_msg
        self.__msg_handler_fn = msg_handler_fn
        self.__conn_type = c_type

        # client info
        self.info = ClientInfo()
        self.__psave = False

        # the following fields are used for iterative receiving on message data
        # see io_recv() and io_recv_buff()
        self.__rcv_buff_header = ReceiveBuffer()
        self.__rcv_buff_data = ReceiveBuffer()
        self.__rcv_msg_id = message.IGNORE
        self.__rcv_msg_size = 0

        self.__snd_buff = ""  # buffer for outgoing data

        # source IDs for various events
        self.__sids = [
            gobject.io_add_watch(self.__sock, gobject.IO_IN, self.__io_recv),
            gobject.io_add_watch(self.__sock, gobject.IO_ERR, self.__io_error),
            gobject.io_add_watch(self.__sock, gobject.IO_HUP, self.__io_hup)
        ]
        self.__sid_out = 0

        log.debug("send 'hello' to %s" % self)

        self.send(ClientConnection.IO_HELLO)
예제 #5
0
파일: remythm.py 프로젝트: cpatulea/remuco
    def start(self, shell):
        
        if self.__shell is not None:
            log.warning("already started")
            return
        
        remuco.PlayerAdapter.start(self)
        
        self.__shell = shell
        
        sp = self.__shell.get_player()
        
        # gconf is used to adjust repeat and shuffle
        self.__gconf = gconf.client_get_default()
        
        # shortcuts to RB data 
        
        self.__item_id = None
        self.__item_entry = None
        self.__playlist_sc = sp.get_playing_source()
        self.__queue_sc = self.__shell.props.queue_source
        
        # connect to shell player signals

        self.__signal_ids = (
            sp.connect("playing_changed", self.__notify_playing_changed),
            sp.connect("playing_uri_changed", self.__notify_playing_uri_changed),
            sp.connect("playing-source-changed", self.__notify_source_changed)
        )

        # state sync will happen by timeout
        # trigger item sync:
        self.__notify_playing_uri_changed(sp, sp.get_playing_path()) # item sync
        
        log.debug("start done")
예제 #6
0
파일: remythm.py 프로젝트: cpatulea/remuco
    def __notify_playing_uri_changed(self, sp, uri):
        """Shell player signal callback to handle an item change."""
        
        log.debug("playing uri changed: %s" % uri)
        
        db = self.__shell.props.db

        entry = sp.get_playing_entry()
        if entry is None:
            id = None
        else:
            id = db.entry_get(entry, rhythmdb.PROP_LOCATION)
        
        self.__item_id = id
        self.__item_entry = entry
        
        if entry is not None and id is not None:

            info = self.__get_item_from_entry(entry)
    
            img_data = db.entry_request_extra_metadata(entry, "rb:coverArt")
            if img_data is None:
                img_file = self.find_image(id)
            else:
                try:
                    img_file = "%s/art.png" % self.config.cache_dir
                    img_data.save(img_file, "png")
                except IOError, e:
                    log.warning("failed to save cover art (%s)" % e)
                    img_file = None
예제 #7
0
    def send(self, msg):
        """Send a message to the client.
        
        @param msg:
            complete message (incl. ID and length) in binary format
            (net.build_message() is your friend here)
        
        @see: net.build_message()
        
        """

        if msg is None:
            log.error("** BUG ** msg is None")
            return

        if self.__sock is None:
            log.debug("cannot send message to %s, already disconnected" % self)
            return

        if self.__psave:
            log.debug("%s is in sleep mode, send nothing" % self)
            return

        self.__snd_buff = "%s%s" % (self.__snd_buff, msg)

        # if not already trying to send data ..
        if self.__sid_out == 0:
            # .. do it when it is possible:
            self.__sid_out = gobject.io_add_watch(self.__sock, gobject.IO_OUT,
                                                  self.__io_send)
예제 #8
0
파일: net.py 프로젝트: gkfabs/remuco
    def __io_send(self, fd, cond):
        """ GObject callback function (when data can be written). """
        
        if not self.__snd_buff:
            self.__sid_out = 0
            return False

        log.debug("try to send %d bytes to %s" % (len(self.__snd_buff), self))

        try:
            sent = self.__sock.send(self.__snd_buff)
        except socket.error as e:
            log.warning("failed to send data to %s (%s)" % (self, e))
            self.disconnect()
            return False

        log.debug("sent %d bytes" % sent)
        
        if sent == 0:
            log.warning("failed to send data to %s" % self)
            self.disconnect()
            return False
        
        self.__snd_buff = self.__snd_buff[sent:]
        
        if not self.__snd_buff:
            self.__sid_out = 0
            return False
        else:
            return True
예제 #9
0
파일: adapter.py 프로젝트: cpatulea/remuco
    def update_item(self, id, info, img):
        """Set currently played item.
        
        @param id:
            item ID (str)
        @param info:
            meta information (dict)
        @param img:
            image / cover art (either a file name or URI or an instance of
            Image.Image)
        
        @note: Call to synchronize player state with remote clients.

        @see: find_image() for finding image files for an item.
        
        @see: remuco.INFO_... for keys to use for 'info'
               
        """

        log.debug("new item: (%s, %s %s)" % (id, info, img))

        change = self.__item_id != id
        change |= self.__item_info != info
        change |= self.__item_img != img

        if change:
            self.__item_id = id
            self.__item_info = info
            self.__item_img = img
            self.__sync_trigger(self.__sync_item)
예제 #10
0
파일: net.py 프로젝트: igoralmeida/remuco
 def __init__(self, sock, addr, clients, pinfo_msg, msg_handler_fn, c_type):
     
     self.__sock = sock
     self.__addr = addr
     self.__clients = clients
     self.__pinfo_msg = pinfo_msg
     self.__msg_handler_fn = msg_handler_fn
     self.__conn_type = c_type
     
     # client info
     self.info = ClientInfo()
     self.__psave = False
     
     # the following fields are used for iterative receiving on message data
     # see io_recv() and io_recv_buff()
     self.__rcv_buff_header = ReceiveBuffer()
     self.__rcv_buff_data = ReceiveBuffer()
     self.__rcv_msg_id = message.IGNORE
     self.__rcv_msg_size = 0
     
     self.__snd_buff = "" # buffer for outgoing data
     
     # source IDs for various events
     self.__sids = [
         gobject.io_add_watch(self.__sock, gobject.IO_IN, self.__io_recv),
         gobject.io_add_watch(self.__sock, gobject.IO_ERR, self.__io_error),
         gobject.io_add_watch(self.__sock, gobject.IO_HUP, self.__io_hup)
         ]
     self.__sid_out = 0
     
     log.debug("send 'hello' to %s" % self)
     
     self.send(ClientConnection.IO_HELLO)
예제 #11
0
파일: remythm.py 프로젝트: mcayland/remuco
    def __notify_playing_uri_changed(self, sp, uri):
        """Shell player signal callback to handle an item change."""

        log.debug("playing uri changed: %s" % uri)

        db = self.__shell.props.db

        entry = sp.get_playing_entry()
        if entry is None:
            id = None
        else:
            id = db.entry_get(entry, rhythmdb.PROP_LOCATION)

        self.__item_id = id
        self.__item_entry = entry

        if entry is not None and id is not None:

            info = self.__get_item_from_entry(entry)

            img_data = db.entry_request_extra_metadata(entry, "rb:coverArt")
            if img_data is None:
                img_file = self.find_image(id)
            else:
                try:
                    img_file = "%s/rhythmbox.cover" % self.config.cache
                    img_data.save(img_file, "png")
                except IOError, e:
                    log.warning("failed to save cover art (%s)" % e)
                    img_file = None
예제 #12
0
파일: remythm.py 프로젝트: mcayland/remuco
    def __get_position(self):

        sp = self.__shell.get_player()

        db = self.__shell.props.db

        position = 0

        id_now = self.__item_id

        if id_now is not None:

            if sp.props.playing_from_queue:
                qmodel = self.__queue_sc.props.query_model
            elif self.__playlist_sc is not None:
                qmodel = self.__playlist_sc.get_entry_view().props.model
            else:
                qmodel = None

            if qmodel is not None:
                for row in qmodel:
                    id = db.entry_get(row[0], rhythmdb.PROP_LOCATION)
                    if id_now == id:
                        break
                    position += 1

        log.debug("position: %i" % position)

        return position
예제 #13
0
파일: remotem.py 프로젝트: sayanriju/remuco
    def __notify_file_opened(self, totem, file):

        # XXX: does not get called for podcasts from BBC plugin

        log.debug("file opened: %s" % file)

        self.__update_item = True
예제 #14
0
파일: net.py 프로젝트: igoralmeida/remuco
    def send(self, msg):
        """Send a message to the client.
        
        @param msg:
            complete message (incl. ID and length) in binary format
            (net.build_message() is your friend here)
        
        @see: net.build_message()
        
        """
        
        if msg is None:
            log.error("** BUG ** msg is None")
            return
        
        if self.__sock is None:
            log.debug("cannot send message to %s, already disconnected" % self)
            return

        if self.__psave:
            log.debug("%s is in sleep mode, send nothing" % self)
            return

        self.__snd_buff = "%s%s" % (self.__snd_buff, msg)
        
        # if not already trying to send data ..
        if self.__sid_out == 0:
            # .. do it when it is possible:
            self.__sid_out = gobject.io_add_watch(self.__sock, gobject.IO_OUT,
                                                  self.__io_send)
예제 #15
0
파일: art.py 프로젝트: cpatulea/remuco
def get_art(resource, prefer_thumbnail=False):
    
    if resource is None:
        return None
    
    uri = __resource_to_file_uri(resource)
    if uri is None:
        log.debug("resource '%s' is not local, ignore" % resource)
        return None
    
    if prefer_thumbnail:
        file = __get_art_from_thumbnails(uri)
        if file is not None:
            return file
        
    file = __get_art_in_folder(uri)
    if file is not None:
        return file
    
    if not prefer_thumbnail:
        file = __get_art_from_thumbnails(uri)
        if file is not None:
            return file
    
    return None
예제 #16
0
 def __on_owner_change(self, name, old, new):
     
     log.debug("dbus name owner changed: '%s' -> '%s'" % (old, new))
     
     _stop_pa(self.__pa)
     if new:
         _start_pa(self.__pa)
예제 #17
0
파일: net.py 프로젝트: gkfabs/remuco
 def __recv_buff(self, rcv_buff):
     """ Receive some data and put it into the given ReceiveBuffer.
     
     @param rcv_buff: the receive buffer to put received data into
     
     @return: true if some data has been received, false if an error occurred
     """
    
     try:
         log.debug("try to receive %d bytes" % rcv_buff.rest)
         data = self.__sock.recv(rcv_buff.rest)
     except socket.timeout as e: # TODO: needed?
         log.warning("connection to %s broken (%s)" % (self, e))
         self.disconnect()
         return False
     except socket.error as e:
         log.warning("connection to %s broken (%s)" % (self, e))
         self.disconnect()
         return False
     
     received = len(data)
     
     log.debug("received %d bytes" % received)
     
     if received == 0:
         log.warning("connection to %s broken (no data)" % self)
         self.disconnect()
         return False
     
     rcv_buff.data = rcv_buff.data + data
     rcv_buff.rest -= received
     
     return True
예제 #18
0
파일: serial.py 프로젝트: gkfabs/remuco
 def write_string(self, s):
     """ Write a string. 
     
     If the string is a unicode string, it will be encoded as a normal string
     in Bin.NET_ENCODING. If it already is a normal string it will be
     converted from Bin.HOST_ENCODING to Bin.NET_ENCODING.
     
     """
     if s is None:
         self.__write_string(s)
         return
     
     if Bin.HOST_ENCODING not in Bin.NET_ENCODING_ALT:
         log.debug("convert '%s' from %s to %s" %
                   (s, Bin.HOST_ENCODING, Bin.NET_ENCODING))
         try:
             s = unicode(s, Bin.HOST_ENCODING).encode(Bin.NET_ENCODING)
         except UnicodeDecodeError as e:
             log.warning("could not decode '%s' with codec %s (%s)" %
                         (s, Bin.HOST_ENCODING, e))
         except UnicodeEncodeError as e:
             log.warning("could not encode '%s' with codec %s (%s)" %
                         (s, Bin.NET_ENCODING, e))
     
     self.__write_string(s)
예제 #19
0
파일: mpris.py 프로젝트: gkfabs/remuco
    def _notify_tracklist_change(self, new_len):

        log.debug("tracklist change")
        try:
            self._mp_t.GetCurrentTrack(reply_handler=self._notify_position, error_handler=self._dbus_error)
        except DBusException as e:
            log.warning("dbus error: %s" % e)
예제 #20
0
파일: remythm.py 프로젝트: gkfabs/remuco
    def __get_position(self):

        sp = self.__shell.props.shell_player

        db = self.__shell.props.db

        position = 0
        
        id_now = self.__item_id
        
        if id_now is not None:
            
            if sp.props.playing_from_queue:
                qmodel = self.__queue_sc.props.query_model
            elif self.__playlist_sc is not None:
                qmodel = self.__playlist_sc.get_entry_view().props.model
            else:
                qmodel = None
                
            if qmodel is not None:
                for row in qmodel:
                    id = row[0].get_string(RB.RhythmDBPropType.LOCATION)
                    if id_now == id:
                        break
                    position += 1
                    
        log.debug("position: %i" % position)
        
        return position
예제 #21
0
파일: art.py 프로젝트: cpatulea/remuco
def __get_art_in_folder(uri):
    """Try to find art images in the given URI's folder.
    
    @param uri:
        a file URI ('file://...')
    
    @return:
        path to an image file or None if there is no matching image file in the
        URI's folder
             
    """
    elems = urlparse.urlparse(uri)
    
    path = urllib.url2pathname(elems[2])
    path = os.path.dirname(path)
    
    log.debug("looking for art image in %s" % path)

    files = glob.glob(os.path.join(path, "*"))
    files = [os.path.basename(f) for f in files if os.path.isfile(f)]
    
    for rx in RE_FILE:
        for file in files:
            if rx.match(file):
                return os.path.join(path, file)
            
    return None
예제 #22
0
파일: mpris.py 프로젝트: gkfabs/remuco
    def __init__(
        self,
        name,
        display_name=None,
        poll=2.5,
        mime_types=None,
        rating=False,
        extra_file_actions=None,
        extra_playlist_actions=None,
    ):

        display_name = display_name or name

        if rating:
            max_rating = 5
        else:
            max_rating = 0

        all_file_actions = FILE_ACTIONS + tuple(extra_file_actions or ())

        PlayerAdapter.__init__(
            self,
            display_name,
            max_rating=max_rating,
            playback_known=True,
            volume_known=True,
            repeat_known=True,
            shuffle_known=True,
            progress_known=True,
            file_actions=all_file_actions,
            mime_types=mime_types,
        )

        self.__playlist_actions = PLAYLIST_ACTIONS
        if self.config.getx("playlist-jump-enabled", "0", int):
            self.__playlist_actions.append(IA_JUMP)
        if extra_playlist_actions:
            self.__playlist_actions.extend(extra_playlist_actions)

        self.__name = name

        self.__dbus_signal_handler = ()
        self._mp_p = None
        self._mp_t = None

        self._repeat = False
        self._shuffle = False
        self._playing = PLAYBACK_STOP
        self.__volume = 0
        self.__progress_now = 0
        self.__progress_max = 0
        self.__can_pause = False
        self.__can_play = False
        self.__can_seek = False
        self.__can_next = False
        self.__can_prev = False
        self.__can_tracklist = False

        log.debug("init done")
예제 #23
0
    def stop(self):

        remuco.PlayerAdapter.stop(self)

        xl.event.remove_callback(self.__notify_track_change)
        xl.event.remove_callback(self.__notify_playback_change)

        log.debug("remuco exaile adapter stopped")
예제 #24
0
파일: mpris.py 프로젝트: mcayland/remuco
    def _notify_tracklist_change(self, new_len):

        log.debug("tracklist change")
        try:
            self._mp_t.GetCurrentTrack(reply_handler=self._notify_position,
                                       error_handler=self._dbus_error)
        except DBusException, e:
            log.warning("dbus error: %s" % e)
예제 #25
0
파일: remythm.py 프로젝트: mcayland/remuco
    def ctrl_next(self):

        sp = self.__shell.get_player()

        try:
            sp.do_next()
        except gobject.GError, e:
            log.debug("do next failed: %s" % str(e))
예제 #26
0
    def stop(self):
        
        remuco.PlayerAdapter.stop(self)
        
        xl.event.remove_callback(self.__notify_track_change)
        xl.event.remove_callback(self.__notify_playback_change)

        log.debug("remuco exaile adapter stopped")
예제 #27
0
파일: remythm.py 프로젝트: gkfabs/remuco
 def ctrl_next(self):
     
     sp = self.__shell.props.shell_player
     
     try:
         sp.do_next()
     except GObject.GError as e:
         log.debug("do next failed: %s" % str(e))
예제 #28
0
파일: remythm.py 프로젝트: cpatulea/remuco
 def ctrl_rate(self, rating):
     
     if self.__item_entry is not None:
         db = self.__shell.props.db
         try:
             db.set(self.__item_entry, rhythmdb.PROP_RATING, rating)
         except gobject.GError, e:
             log.debug("rating failed: %s" % str(e))
예제 #29
0
파일: remythm.py 프로젝트: mcayland/remuco
    def action_queue_item(self, action_id, positions, ids):

        if action_id == IA_JUMP.id:

            try:
                self.__jump_in_plq(self.__queue_sc, positions[0])
            except gobject.GError, e:
                log.debug("queue jump failed: %s" % e)
예제 #30
0
파일: remythm.py 프로젝트: mcayland/remuco
    def ctrl_toggle_playing(self):

        sp = self.__shell.get_player()

        try:
            sp.playpause()
        except gobject.GError, e:
            log.debug("toggle play pause failed: %s" % str(e))
예제 #31
0
파일: remythm.py 프로젝트: mcayland/remuco
    def ctrl_seek(self, direction):

        sp = self.__shell.get_player()

        try:
            sp.seek(direction * 5)
        except gobject.GError, e:
            log.debug("seek failed: %s" % str(e))
예제 #32
0
파일: remythm.py 프로젝트: cpatulea/remuco
 def ctrl_toggle_playing(self):
     
     sp = self.__shell.get_player()
     
     try:
         sp.playpause()
     except gobject.GError, e:
         log.debug("toggle play pause failed: %s" % str(e))
예제 #33
0
파일: remythm.py 프로젝트: mcayland/remuco
    def ctrl_rate(self, rating):

        if self.__item_entry is not None:
            db = self.__shell.props.db
            try:
                db.set(self.__item_entry, rhythmdb.PROP_RATING, rating)
            except gobject.GError, e:
                log.debug("rating failed: %s" % str(e))
예제 #34
0
파일: remythm.py 프로젝트: cpatulea/remuco
    def ctrl_seek(self, direction):
        
        sp = self.__shell.get_player()

        try:
            sp.seek(direction * 5)
        except gobject.GError, e:
            log.debug("seek failed: %s" % str(e))
예제 #35
0
파일: remythm.py 프로젝트: gkfabs/remuco
 def ctrl_rate(self, rating):
     
     if self.__item_entry is not None:
         db = self.__shell.props.db
         try:
             db.entry_set(self.__item_entry, RB.RhythmDBPropType.RATING, rating)
         except GObject.GError as e:
             log.debug("rating failed: %s" % str(e))
예제 #36
0
파일: remythm.py 프로젝트: cpatulea/remuco
    def action_queue_item(self, action_id, positions, ids):

        if action_id == IA_JUMP.id:
            
            try:
                self.__jump_in_plq(self.__queue_sc, positions[0])
            except gobject.GError, e:
                log.debug("queue jump failed: %s" % e)
예제 #37
0
파일: remythm.py 프로젝트: cpatulea/remuco
 def ctrl_next(self):
     
     sp = self.__shell.get_player()
     
     try:
         sp.do_next()
     except gobject.GError, e:
         log.debug("do next failed: %s" % str(e))
예제 #38
0
파일: remythm.py 프로젝트: gkfabs/remuco
 def ctrl_toggle_playing(self):
     
     sp = self.__shell.props.shell_player
     
     try:
         sp.playpause(True)
     except GObject.GError as e:
         log.debug("toggle play pause failed: %s" % str(e))
예제 #39
0
파일: config.py 프로젝트: cpatulea/remuco
    def __load(self):

        log.debug("try to load config from %s" % self.__file_config)
        
        try:
            self.__cp.read(self.__file_config)
        except ConfigParser.Error, e:
            log.warning("failed to read config from %s (%s) -> %s" %
                        (self.__file_config, e, "using defaults"))
예제 #40
0
파일: remythm.py 프로젝트: cpatulea/remuco
 def __notify_playing_changed(self, sp, b):
     """Shell player signal callback to handle a change in playback."""
     
     log.debug("playing changed: %s" % str(b))
     
     if b:
         self.update_playback(remuco.PLAYBACK_PLAY)
     else:
         self.update_playback(remuco.PLAYBACK_PAUSE)
예제 #41
0
파일: remythm.py 프로젝트: mcayland/remuco
    def __notify_playing_changed(self, sp, b):
        """Shell player signal callback to handle a change in playback."""

        log.debug("playing changed: %s" % str(b))

        if b:
            self.update_playback(remuco.PLAYBACK_PLAY)
        else:
            self.update_playback(remuco.PLAYBACK_PAUSE)
예제 #42
0
파일: remythm.py 프로젝트: cpatulea/remuco
 def ctrl_previous(self):
     
     sp = self.__shell.get_player()
     
     try:
         sp.set_playing_time(0)
         time.sleep(0.1)
         sp.do_previous()
     except gobject.GError, e:
         log.debug("do previous failed: %s" % str(e))
예제 #43
0
파일: remythm.py 프로젝트: mcayland/remuco
    def ctrl_previous(self):

        sp = self.__shell.get_player()

        try:
            sp.set_playing_time(0)
            time.sleep(0.1)
            sp.do_previous()
        except gobject.GError, e:
            log.debug("do previous failed: %s" % str(e))
예제 #44
0
파일: mpris.py 프로젝트: gkfabs/remuco
    def ctrl_previous(self):

        if not self.__can_prev:
            log.debug("go to previous is currently not possible")
            return

        try:
            self._mp_p.Prev(reply_handler=self._dbus_ignore, error_handler=self._dbus_error)
        except DBusException as e:
            log.warning("dbus error: %s" % e)
예제 #45
0
파일: adapter.py 프로젝트: cpatulea/remuco
    def __sync_trigger(self, sync_fn):

        if self.stopped:
            return

        if sync_fn in self.__sync_triggers:
            log.debug("trigger for %s already active" % sync_fn.func_name)
            return

        self.__sync_triggers[sync_fn] = gobject.idle_add(sync_fn, priority=gobject.PRIORITY_LOW)
예제 #46
0
파일: mpris.py 프로젝트: mcayland/remuco
    def __init__(self,
                 name,
                 display_name=None,
                 poll=2.5,
                 mime_types=None,
                 rating=False,
                 extra_file_actions=None,
                 extra_playlist_actions=None):

        display_name = display_name or name

        if rating:
            max_rating = 5
        else:
            max_rating = 0

        all_file_actions = FILE_ACTIONS + tuple(extra_file_actions or ())

        PlayerAdapter.__init__(self,
                               display_name,
                               max_rating=max_rating,
                               playback_known=True,
                               volume_known=True,
                               repeat_known=True,
                               shuffle_known=True,
                               progress_known=True,
                               file_actions=all_file_actions,
                               mime_types=mime_types)

        self.__playlist_actions = PLAYLIST_ACTIONS
        if self.config.getx("playlist-jump-enabled", "0", int):
            self.__playlist_actions.append(IA_JUMP)
        if extra_playlist_actions:
            self.__playlist_actions.extend(extra_playlist_actions)

        self.__name = name

        self.__dbus_signal_handler = ()
        self._mp_p = None
        self._mp_t = None

        self._repeat = False
        self._shuffle = False
        self._playing = PLAYBACK_STOP
        self.__volume = 0
        self.__progress_now = 0
        self.__progress_max = 0
        self.__can_pause = False
        self.__can_play = False
        self.__can_seek = False
        self.__can_next = False
        self.__can_prev = False
        self.__can_tracklist = False

        log.debug("init done")
예제 #47
0
파일: remythm.py 프로젝트: mcayland/remuco
    def ctrl_volume(self, direction):

        sp = self.__shell.get_player()

        if direction == 0:
            sp.set_volume(0)
        else:
            try:
                sp.set_volume_relative(direction * 0.05)
            except gobject.GError, e:
                log.debug("set volume failed: %s" % str(e))
예제 #48
0
파일: mpris.py 프로젝트: mcayland/remuco
    def ctrl_previous(self):

        if not self.__can_prev:
            log.debug("go to previous is currently not possible")
            return

        try:
            self._mp_p.Prev(reply_handler=self._dbus_ignore,
                            error_handler=self._dbus_error)
        except DBusException, e:
            log.warning("dbus error: %s" % e)
예제 #49
0
파일: mpris.py 프로젝트: mcayland/remuco
    def ctrl_next(self):

        if not self.__can_next:
            log.debug("go to next item is currently not possible")
            return

        try:
            self._mp_p.Next(reply_handler=self._dbus_ignore,
                            error_handler=self._dbus_error)
        except DBusException, e:
            log.warning("dbus error: %s" % e)
예제 #50
0
파일: remotem.py 프로젝트: mcayland/remuco
    def __notify_metadata_updated(self, totem, artist, title, album, track=0):

        # 'track' has been added in Totem 2.26

        log.debug("metadata updated: %s, %s, %s" % (artist, title, album))

        # in Totem < 2.26 meta data is always None

        self.__md_artist = artist
        self.__md_title = title
        self.__md_album = album

        self.__update_item = True
예제 #51
0
    def down(self):
        """ Shut down the server. """

        if self.__sid is not None:
            gobject.source_remove(self.__sid)

        if self._sock is not None:
            log.debug("closing %s server socket" % self._get_type())
            try:
                self._sock.shutdown(socket.SHUT_RDWR)
            except socket.error:
                pass
            self._sock.close()
            self._sock = None
예제 #52
0
    def __recv_buff(self, rcv_buff):
        """ Receive some data and put it into the given ReceiveBuffer.
        
        @param rcv_buff: the receive buffer to put received data into
        
        @return: true if some data has been received, false if an error occurred
        """

        try:
            log.debug("try to receive %d bytes" % rcv_buff.rest)
            data = self.__sock.recv(rcv_buff.rest)
        except socket.timeout, e:  # TODO: needed?
            log.warning("connection to %s broken (%s)" % (self, e))
            self.disconnect()
            return False
예제 #53
0
    def __io_send(self, fd, cond):
        """ GObject callback function (when data can be written). """

        if not self.__snd_buff:
            self.__sid_out = 0
            return False

        log.debug("try to send %d bytes to %s" % (len(self.__snd_buff), self))

        try:
            sent = self.__sock.send(self.__snd_buff)
        except socket.error, e:
            log.warning("failed to send data to %s (%s)" % (self, e))
            self.disconnect()
            return False
예제 #54
0
파일: remythm.py 프로젝트: mcayland/remuco
    def request_mlib(self, reply, path):

        slm = self.__shell.props.sourcelist_model

        ### root ? ###

        if not path:
            for group in slm:
                group_name = group[2]
                reply.nested.append(group_name)
            reply.send()
            return

        ### group ? ### Library, Playlists

        if len(path) == 1:
            for group in slm:
                group_name = group[2]
                if path[0] == group_name:
                    for sc in group.iterchildren():
                        source_name = sc[2]
                        # FIXME: how to be l10n independent here?
                        if source_name.startswith("Play Queue"):
                            continue
                        if source_name.startswith("Import Error"):
                            continue
                        log.debug("append %s" % source_name)
                        reply.nested.append(source_name)
                    break
            reply.list_actions = MLIB_LIST_ACTIONS
            reply.send()
            return

        ### regular playlist (source) ! ### Library/???, Playlists/???

        sc = self.__mlib_path_to_source(path)

        if sc is None:
            reply.send()
            return

        qm = sc.get_entry_view().props.model

        try:
            reply.ids, reply.names = self.__get_item_list_from_qmodel(qm)
        except gobject.GError, e:
            log.warning("failed to list items: %s" % e)
예제 #55
0
    def start(self):

        remuco.PlayerAdapter.start(self)

        for event in ("playback_track_start", "playback_track_end"):
            xl.event.add_callback(self.__notify_track_change, event)

        for event in ("playback_player_end", "playback_player_start",
                      "playback_toggle_pause"):
            xl.event.add_callback(self.__notify_playback_change, event)

        self.__update_track(self.__ex.player.current)
        self.__update_position()
        self.__update_playback()
        # other updates via poll()

        log.debug("remuco exaile adapter started")
예제 #56
0
파일: remotem.py 프로젝트: mcayland/remuco
    def __poll_item(self):

        try:
            mrl = self.__to.get_current_mrl()
        except AttributeError:  # totem < 2.24
            mrl = self.__to.get_main_window().get_title()  # <- fake mrl

        if not self.__update_item and mrl == self.__last_mrl:
            return

        # reset seek step

        len = self.__to.get_property("stream-length")

        if len < 10000:
            self.__seek_step_initial = 0
        else:
            self.__seek_step_initial = max(5000, len // 200)

        self.__seek_step = self.__seek_step_initial

        log.debug("reset seek step to %d" % self.__seek_step)

        # update meta information

        log.debug("update item")

        self.__update_item = False
        self.__last_mrl = mrl

        info = {}

        if ((self.__md_artist, self.__md_title,
             self.__md_album) == (None, None, None)):
            info[remuco.INFO_TITLE] = self.__get_title_from_window()
        else:
            info[remuco.INFO_ARTIST] = self.__md_artist
            info[remuco.INFO_TITLE] = self.__md_title
            info[remuco.INFO_ALBUM] = self.__md_album

        info[remuco.INFO_LENGTH] = int(len / 1000)

        img = self.find_image(mrl)

        self.update_item(mrl, info, img)
예제 #57
0
파일: remotem.py 프로젝트: mcayland/remuco
    def __check_seek_step(self, progress_before, exp_min_diff, new_step):
        """Check if a seek had some effect and adjust seek step if not.
        
        @param progress_before:
            playback progress before seeking
        @param new_step:
            new seek step to set if progress did not change significantly
            
        """
        progress_now = self.__to.get_current_time()

        log.debug("seek diff: %d" % abs(progress_now - progress_before))

        if abs(progress_now - progress_before) < exp_min_diff:
            log.debug("adjust seek step to %d" % new_step)
            self.__seek_step = new_step

        self.__css_sid = 0
예제 #58
0
파일: mpris.py 프로젝트: mcayland/remuco
    def ctrl_seek(self, direction):

        if not self.__can_seek:
            log.debug("seeking is currently not possible")
            return

        self.__progress_now += 5 * direction
        self.__progress_now = min(self.__progress_now, self.__progress_max)
        self.__progress_now = max(self.__progress_now, 0)

        log.debug("new progress: %d" % self.__progress_now)

        try:
            self._mp_p.PositionSet(self.__progress_now * 1000,
                                   reply_handler=self._dbus_ignore,
                                   error_handler=self._dbus_error)
        except DBusException, e:
            log.warning("dbus error: %s" % e)
예제 #59
0
    def zc_publish(player, port):
        """Publish a service for the given player at the given port."""

        zc_unpublish()

        log.debug("publishing zeroconf service")
        try:
            bus = dbus.SystemBus()
            obj = bus.get_object(_DBA_NAME, _DBA_PATH_SERVER)
            server = dbus.Interface(obj, _DBA_INTERFACE_SERVER)
            obj = bus.get_object(_DBA_NAME, server.EntryGroupNew())
            group = dbus.Interface(obj, _DBA_INTERFACE_ENTRY_GROUP)
            group.AddService(-1, -1, 0, "Remuco %s" % player, _ZC_TYPE,
                             "local", "", port, "")
            group.Commit()
        except dbus.DBusException, e:
            log.warning("failed to publish zeroconf service (%s)" % e)
            group = None
예제 #60
0
파일: remythm.py 프로젝트: mcayland/remuco
    def action_mlib_list(self, action_id, path):

        if action_id == LA_PLAY.id:

            sc = self.__mlib_path_to_source(path)
            if sc is None:
                log.warning("no source for path %s" % path)
                return

            sp = self.__shell.get_player()

            if sc != self.__playlist_sc:
                try:
                    sp.set_selected_source(sc)
                    sp.set_playing_source(sc)
                    self.__jump_in_plq(sc, 0)
                except gobject.GError, e:
                    log.debug("switching source failed: %s" % str(e))