[totem] dbusservice: Port to MPRIS 2.1



commit e95f1fec8bcfbc15c7f815a5f704266f40d9f269
Author: Philip Withnall <philip tecnocode co uk>
Date:   Thu Aug 11 12:05:04 2011 +0200

    dbusservice: Port to MPRIS 2.1
    
    The port isn't quite complete, with TrackList support dropped and some
    notifications missing. This is because I've been told someone's working on
    porting the plugin to C (and MPRIS 2.1), making most of this work redundant.
    I thought I'd commit it anyway for posterity's sake.

 po/POTFILES.in                         |    1 +
 src/plugins/dbusservice/dbusservice.py |  505 +++++++++++++++----------------
 2 files changed, 245 insertions(+), 261 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index bcf7fc2..aa860b4 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -47,6 +47,7 @@ src/plugins/brasero-disc-recorder/totem-disc-recorder.c
 src/plugins/chapters/totem-chapters.c
 src/plugins/chapters/totem-cmml-parser.c
 [type: gettext/ini]src/plugins/dbusservice/dbusservice.plugin.in
+src/plugins/dbusservice/dbusservice.py
 [type: gettext/ini]src/plugins/im-status/totem-im-status.plugin.in
 src/plugins/im-status/totem-im-status.c
 [type: gettext/ini]src/plugins/gromit/gromit.plugin.in
diff --git a/src/plugins/dbusservice/dbusservice.py b/src/plugins/dbusservice/dbusservice.py
index da88755..83b96d1 100644
--- a/src/plugins/dbusservice/dbusservice.py
+++ b/src/plugins/dbusservice/dbusservice.py
@@ -1,3 +1,5 @@
+# -*- coding: utf-8 -*-
+
 ## Totem D-Bus plugin
 ## Copyright (C) 2009 Lucky <lucky1 data gmail com>
 ## Copyright (C) 2009 Philip Withnall <philip tecnocode co uk>
@@ -20,10 +22,14 @@
 ## Sunday 13th May 2007: Bastien Nocera: Add exception clause.
 ## See license_change file for details.
 
+import gettext
 from gi.repository import GObject, Peas, Totem # pylint: disable-msg=E0611
 import dbus, dbus.service
 from dbus.mainloop.glib import DBusGMainLoop
 
+gettext.textdomain ("totem")
+_ = gettext.gettext
+
 class DbusService (GObject.Object, Peas.Activatable):
     __gtype_name__ = 'DbusService'
 
@@ -33,331 +39,308 @@ class DbusService (GObject.Object, Peas.Activatable):
         GObject.Object.__init__ (self)
 
         self.root = None
-        self.player = None
-        self.track_list = None
 
     def do_activate (self):
         DBusGMainLoop (set_as_default = True)
 
-        name = dbus.service.BusName ('org.mpris.Totem',
+        name = dbus.service.BusName ('org.mpris.MediaPlayer2.totem',
                                      bus = dbus.SessionBus ())
         self.root = Root (name, self.object)
-        self.player = Player (name, self.object)
-        self.track_list = TrackList (name, self.object)
 
     def do_deactivate (self):
         # Ensure we don't leak our paths on the bus
         self.root.disconnect ()
-        self.player.disconnect ()
-        self.track_list.disconnect ()
 
-class Root (dbus.service.Object): # pylint: disable-msg=R0923
+class Root (dbus.service.Object): # pylint: disable-msg=R0923,R0904
     def __init__ (self, name, totem):
-        dbus.service.Object.__init__ (self, name, '/')
+        dbus.service.Object.__init__ (self, name, '/org/mpris/MediaPlayer2')
         self.totem = totem
 
+        self.null_metadata = {
+            'year' : '', 'tracknumber' : '', 'location' : '',
+            'title' : '', 'album' : '', 'time' : '', 'genre' : '',
+            'artist' : ''
+        }
+        self.current_metadata = self.null_metadata.copy ()
+        self.current_position = 0
+
+        totem.connect ('metadata-updated', self.__do_update_metadata)
+        totem.connect ('notify::playing', self.__do_notify_playing)
+        totem.connect ('notify::seekable', self.__do_notify_seekable)
+        totem.connect ('notify::current-mrl', self.__do_notify_current_mrl)
+        totem.connect ('notify::current-time', self.__do_notify_current_time)
+
     def disconnect (self):
+        self.totem.disconnect_by_func (self.__do_notify_current_time)
+        self.totem.disconnect_by_func (self.__do_notify_current_mrl)
+        self.totem.disconnect_by_func (self.__do_notify_seekable)
+        self.totem.disconnect_by_func (self.__do_notify_playing)
+        self.totem.disconnect_by_func (self.__do_update_metadata)
+
+        self.__do_update_metadata (self.totem, '', '', '', 0)
+
         self.remove_from_connection (None, None)
 
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
-                          in_signature = '', # pylint: disable-msg=C0103
-                          out_signature = 's')
-    def Identity (self):
-        return self.totem.get_version ()
+    def __calculate_playback_status (self):
+        if self.totem.is_playing ():
+            return 'Playing'
+        elif self.totem.is_paused ():
+            return 'Paused'
+        else:
+            return 'Stopped'
+
+    def __calculate_metadata (self):
+        metadata = {
+            'mpris:trackid': dbus.String (self.totem.props.current_mrl,
+                variant_level = 1),
+            'mpris:length': dbus.Int64 (
+                self.totem.props.stream_length * 1000L,
+                variant_level = 1),
+        }
 
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
-                          in_signature = '', # pylint: disable-msg=C0103
-                          out_signature = '')
-    def Quit (self):
-        self.totem.action_exit ()
+        if self.current_metadata['title'] != '':
+            metadata['xesam:title'] = dbus.String (
+                self.current_metadata['title'], variant_level = 1)
 
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
-                          in_signature = '', # pylint: disable-msg=C0103
-                          out_signature = '(qq)')
-    def MprisVersion (self):
-        return dbus.Struct ((dbus.UInt16 (1), dbus.UInt16 (0)),
-                            signature = '(qq)')
+        if self.current_metadata['artist'] != '':
+            metadata['xesam:artist'] = dbus.Array (
+                [ self.current_metadata['artist'] ], variant_level = 1)
 
-class Player (dbus.service.Object): # pylint: disable-msg=R0923,R0904
-    def __init__ (self, name, totem):
-        dbus.service.Object.__init__ (self, name, '/Player')
-        self.totem = totem
+        if self.current_metadata['album'] != '':
+            metadata['xesam:album'] = dbus.String (
+                self.current_metadata['album'], variant_level = 1)
 
-        self.null_metadata = {
-            "year" : "", "tracknumber" : "", "location" : "",
-            "title" : "", "album" : "", "time" : "", "genre" : "",
-            "artist" : ""
-        }
-        self.old_metadata = self.null_metadata.copy ()
-        self.current_metadata = self.null_metadata.copy ()
-        self.old_caps = 64 # at startup, we can only support a playlist
-        self.old_status = (2, 0, 0, 0) # startup state
+        if self.current_metadata['tracknumber'] != '':
+            metadata['xesam:trackNumber'] = dbus.Int32 (
+                self.current_metadata['tracknumber'], variant_level = 1)
 
-        totem.connect ("metadata-updated", self.__do_update_metadata)
-        totem.connect ("notify::playing", self.__do_notify)
-        totem.connect ("notify::seekable", self.__do_notify)
-        totem.connect ("notify::current-mrl", self.__do_notify)
+        return metadata
 
     def __do_update_metadata (self, totem, artist, # pylint: disable-msg=R0913
                               title, album, num):
         self.current_metadata = self.null_metadata.copy ()
         if title:
-            self.current_metadata["title"] = title
+            self.current_metadata['title'] = title
         if artist:
-            self.current_metadata["artist"] = artist
+            self.current_metadata['artist'] = artist
         if album:
-            self.current_metadata["album"] = album
+            self.current_metadata['album'] = album
         if num:
-            self.current_metadata["tracknumber"] = num
-
-        if totem.is_playing ():
-            self.__track_change (self.current_metadata)
-
-    def __do_notify (self, totem, status):
-        if totem.is_playing ():
-            self.__track_change (self.current_metadata)
-        else:
-            self.__track_change (self.null_metadata)
-
-        status = self.__calculate_status ()
-        if status != self.old_status:
-            self.__status_change (status)
-
-        caps = self.__calculate_caps ()
-        if caps != self.old_caps:
-            self.__caps_change (caps)
-
-    def __calculate_status (self):
-        if self.totem.is_playing ():
-            playing_status = 0
-        elif self.totem.is_paused ():
-            playing_status = 1
-        else:
-            playing_status = 2
-
-        if self.totem.action_remote_get_setting (Totem.RemoteSetting.SHUFFLE):
-            shuffle_status = 1
-        else:
-            shuffle_status = 0
-
-        if self.totem.action_remote_get_setting (Totem.RemoteSetting.REPEAT):
-            repeat_status = 1
-        else:
-            repeat_status = 0
-
-        return (
-            # 0 = Playing, 1 = Paused, 2 = Stopped
-            dbus.Int32 (playing_status),
-            # 0 = Playing linearly , 1 = Playing randomly
-            dbus.Int32 (shuffle_status),
-            # 0 = Go to the next element once the current has finished playing,
-            # 1 = Repeat the current element
-            dbus.Int32 (0),
-            # 0 = Stop playing once the last element has been played,
-            # 1 = Never give up playing
-            dbus.Int32 (repeat_status)
-        )
-
-    def __calculate_caps (self):
-        caps = 64 # we can always have a playlist
-        playlist_length = self.totem.get_playlist_length ()
-        playlist_pos = self.totem.get_playlist_pos ()
-
-        if playlist_pos < playlist_length - 1:
-            caps |= 1 << 0 # go next
-        if playlist_pos > 0:
-            caps |= 1 << 1 # go previous
-        if playlist_length > 0:
-            caps |= 1 << 2 # pause
-            caps |= 1 << 3 # play
-        if self.totem.is_seekable ():
-            caps |= 1 << 4 # seek
-        if self.current_metadata != self.null_metadata:
-            caps |= 1 << 5 # get metadata
-
-        return caps
-
-    def __track_change (self, metadata):
-        if self.old_metadata != metadata:
-            self.old_metadata = metadata.copy ()
-            self.TrackChange (metadata)
-
-    def __status_change (self, status):
-        if self.old_status != status:
-            self.old_status = status
-            self.StatusChange (status)
-
-    def __caps_change (self, caps):
-        if self.old_caps != caps:
-            self.old_caps = caps
-            self.CapsChange (caps)
-
-    def disconnect (self):
-        self.TrackChange (self.null_metadata)
-        self.remove_from_connection (None, None)
-
-    @dbus.service.signal (dbus_interface = "org.freedesktop.MediaPlayer",
-                          signature = 'a{sv}') # pylint: disable-msg=C0103
-    def TrackChange (self, metadata):
+            self.current_metadata['tracknumber'] = num
+
+        self.PropertiesChanged ('org.mpris.MediaPlayer2.Player',
+            { 'Metadata': self.__calculate_metadata () }, [])
+
+    def __do_notify_playing (self, totem, prop):
+        self.PropertiesChanged ('org.mpris.MediaPlayer2.Player',
+            { 'PlaybackStatus': self.__calculate_playback_status () }, [])
+
+    def __do_notify_current_mrl (self, totem, prop):
+        self.PropertiesChanged ('org.mpris.MediaPlayer2.Player', {
+            'CanPlay': (self.totem.props.current_mrl != None),
+            'CanPause': (self.totem.props.current_mrl != None),
+            'CanSeek': (self.totem.props.current_mrl != None and
+                        self.totem.props.seekable),
+        }, [])
+
+    def __do_notify_seekable (self, totem, prop):
+        self.PropertiesChanged ('org.mpris.MediaPlayer2.Player', {
+            'CanSeek': (self.totem.props.current_mrl != None and
+                        self.totem.props.seekable),
+        }, [])
+
+    def __do_notify_current_time (self, totem, prop):
+        # Only notify of seeks if we've skipped more than 3 seconds
+        if abs (totem.props.current_time - self.current_position) > 3:
+            self.Seeked (totem.props.current_time * 1000L)
+
+        self.current_position = totem.props.current_time
+
+    # org.freedesktop.DBus.Properties interface
+    @dbus.service.method (dbus_interface = dbus.PROPERTIES_IFACE,
+                          in_signature = 'ss', # pylint: disable-msg=C0103
+                          out_signature = 'v')
+    def Get (self, interface_name, property_name):
+        return self.GetAll (interface_name)[property_name]
+
+    @dbus.service.method (dbus_interface = dbus.PROPERTIES_IFACE,
+                          in_signature = 's', # pylint: disable-msg=C0103
+                          out_signature = 'a{sv}')
+    def GetAll (self, interface_name):
+        if interface_name == 'org.mpris.MediaPlayer2':
+            return {
+                'CanQuit': True,
+                'CanRaise': True,
+                'HasTrackList': False,
+                'Identity': self.totem.get_version (),
+                'DesktopEntry': 'totem',
+                'SupportedUriSchemes': self.totem.get_supported_uri_schemes (),
+                'SupportedMimeTypes': self.totem.get_supported_content_types (),
+            }
+        elif interface_name == 'org.mpris.MediaPlayer2.Player':
+            # Loop status (we don't support Track)
+            if self.totem.action_remote_get_setting (
+                Totem.RemoteSetting.REPEAT):
+                loop_status = 'Playlist'
+            else:
+                loop_status = 'None'
+
+            # Shuffle
+            shuffle = self.totem.action_remote_get_setting (
+                Totem.RemoteSetting.SHUFFLE)
+
+            return {
+                'PlaybackStatus': self.__calculate_playback_status (),
+                'LoopStatus': loop_status, # TODO: Notifications
+                'Rate': 1.0,
+                'MinimumRate': 1.0,
+                'MaximumRate': 1.0,
+                'Shuffle': shuffle, # TODO: Notifications
+                'Metadata': self.__calculate_metadata (),
+                'Volume': self.totem.get_volume (), # TODO: Notifications
+                'Position': self.totem.props.current_time * 1000L,
+                'CanGoNext': True, # TODO
+                'CanGoPrevious': True, # TODO
+                'CanPlay': (self.totem.props.current_mrl != None),
+                'CanPause': (self.totem.props.current_mrl != None),
+                'CanSeek': (self.totem.props.current_mrl != None and
+                            self.totem.props.seekable),
+                'CanControl': True,
+            }
+
+        raise dbus.exceptions.DBusException (
+            'org.mpris.MediaPlayer2.UnknownInterface',
+            _(u'The MediaPlayer2 object does not implement the â%sâ interface')
+                % interface_name)
+
+    @dbus.service.method (dbus_interface = dbus.PROPERTIES_IFACE,
+                          in_signature = 'ssv') # pylint: disable-msg=C0103
+    def Set (self, interface_name, property_name, new_value):
+        if interface_name == 'org.mpris.MediaPlayer2':
+            raise dbus.exceptions.DBusException (
+                'org.mpris.MediaPlayer2.ReadOnlyProperty',
+                _(u'The property â%sâ is not writeable.'))
+        elif interface_name == 'org.mpris.MediaPlayer2.Player':
+            if property_name == 'LoopStatus':
+                self.totem.action_remote_set_setting (
+                    Totem.RemoteSetting.REPEAT, (new_value == 'Playlist'))
+            elif property_name == 'Rate':
+                # Ignore, since we don't support setting the rate
+                pass
+            elif property_name == 'Shuffle':
+                self.totem.action_remote_set_setting (
+                    Totem.RemoteSetting.SHUFFLE, new_value)
+            elif property_name == 'Volume':
+                self.totem.action_volume (new_value)
+
+            raise dbus.exceptions.DBusException (
+                'org.mpris.MediaPlayer2.ReadOnlyProperty',
+                _(u'Unknown property â%sâ requested of a MediaPlayer 2 object')
+                    % interface_name)
+
+        raise dbus.exceptions.DBusException (
+            'org.mpris.MediaPlayer2.UnknownInterface',
+            _(u'The MediaPlayer2 object does not implement the â%sâ interface')
+                % interface_name)
+
+    @dbus.service.signal (dbus_interface = dbus.PROPERTIES_IFACE,
+                          signature = 'sa{sv}as') # pylint: disable-msg=C0103
+    def PropertiesChanged (self, interface_name, changed_properties,
+                           invalidated_properties):
         pass
 
-    @dbus.service.signal (dbus_interface = "org.freedesktop.MediaPlayer",
-                          signature = '(iiii)') # pylint: disable-msg=C0103
-    def StatusChange (self, status):
-        pass
+    # org.mpris.MediaPlayer2 interface
+    @dbus.service.method (dbus_interface = 'org.mpris.MediaPlayer2',
+                          in_signature = '', # pylint: disable-msg=C0103
+                          out_signature = '')
+    def Raise (self):
+        main_window = self.totem.get_main_window ()
+        main_window.present ()
 
-    @dbus.service.signal (dbus_interface = "org.freedesktop.MediaPlayer",
-                          signature = 'i') # pylint: disable-msg=C0103
-    def CapsChange (self, caps):
-        pass
+    @dbus.service.method (dbus_interface = 'org.mpris.MediaPlayer2',
+                          in_signature = '', # pylint: disable-msg=C0103
+                          out_signature = '')
+    def Quit (self):
+        self.totem.action_exit ()
 
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
+    # org.mpris.MediaPlayer2.Player interface
+    @dbus.service.method (dbus_interface = 'org.mpris.MediaPlayer2.Player',
                           in_signature = '', # pylint: disable-msg=C0103
                           out_signature = '')
     def Next (self):
+        if self.totem.is_playing () or self.totem.is_paused ():
+            return
+
         self.totem.action_next ()
 
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
+    @dbus.service.method (dbus_interface = 'org.mpris.MediaPlayer2.Player',
                           in_signature = '', # pylint: disable-msg=C0103
                           out_signature = '')
-    def Prev (self):
+    def Previous (self):
+        if self.totem.is_playing () or self.totem.is_paused ():
+            return
+
         self.totem.action_previous ()
 
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
+    @dbus.service.method (dbus_interface = 'org.mpris.MediaPlayer2.Player',
                           in_signature = '', # pylint: disable-msg=C0103
                           out_signature = '')
     def Pause (self):
+        self.totem.action_pause ()
+
+    @dbus.service.method (dbus_interface = 'org.mpris.MediaPlayer2.Player',
+                          in_signature = '', # pylint: disable-msg=C0103
+                          out_signature = '')
+    def PlayPause (self):
         self.totem.action_play_pause ()
 
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
+    @dbus.service.method (dbus_interface = 'org.mpris.MediaPlayer2.Player',
                           in_signature = '', # pylint: disable-msg=C0103
                           out_signature = '')
     def Stop (self):
         self.totem.action_stop ()
 
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
+    @dbus.service.method (dbus_interface = 'org.mpris.MediaPlayer2.Player',
                           in_signature = '', # pylint: disable-msg=C0103
                           out_signature = '')
     def Play (self):
-        # If playing : rewind to the beginning of current track,
-        # else : start playing.
-        if self.totem.is_playing ():
-            self.totem.action_seek_time (0, False)
-        else:
-            self.totem.action_play ()
+        # If playing or no track loaded: do nothing,
+        # else: start playing.
+        if self.totem.is_playing () or self.totem.props.current_mrl == None:
+            return
 
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
-                          in_signature = 'b', # pylint: disable-msg=C0103
-                          out_signature = '')
-    def Repeat (self, value):
-        # We don't support repeating individual tracks
-        pass
+        self.totem.action_play ()
 
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
-                          in_signature = '', # pylint: disable-msg=C0103
-                          out_signature = '(iiii)')
-    def GetStatus (self):
-        status = self.__calculate_status ()
-        self.old_status = status
-        return dbus.Struct (status, signature = '(iiii)')
-
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
-                          in_signature = '', # pylint: disable-msg=C0103
-                          out_signature = 'a{sv}')
-    def GetMetadata (self):
-        return self.current_metadata
-
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
-                          in_signature = '', # pylint: disable-msg=C0103
-                          out_signature = 'i')
-    def GetCaps (self):
-        caps = self.__calculate_caps ()
-        self.old_caps = caps
-        return caps
-
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
-                          in_signature = 'i', # pylint: disable-msg=C0103
+    @dbus.service.method (dbus_interface = 'org.mpris.MediaPlayer2.Player',
+                          in_signature = 'x', # pylint: disable-msg=C0103
                           out_signature = '')
-    def VolumeSet (self, volume):
-        self.totem.action_volume (volume / 100.0)
+    def Seek (self, offset):
+        self.totem.action_seek_relative (offset / 1000L, False)
 
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
-                          in_signature = '', # pylint: disable-msg=C0103
-                          out_signature = 'i')
-    def VolumeGet (self):
-        return dbus.Int32 (self.totem.get_volume () * 100)
-
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
-                          in_signature = 'i', # pylint: disable-msg=C0103
+    @dbus.service.method (dbus_interface = 'org.mpris.MediaPlayer2.Player',
+                          in_signature = 'ox', # pylint: disable-msg=C0103
                           out_signature = '')
-    def PositionSet (self, position):
-        self.totem.action_seek_time (position, False)
-
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
-                          in_signature = '', # pylint: disable-msg=C0103
-                          out_signature = 'i')
-    def PositionGet (self):
-        return dbus.Int32 (self.totem.props.current_time)
-
-class TrackList (dbus.service.Object): # pylint: disable-msg=R0923
-    def __init__ (self, name, totem):
-        dbus.service.Object.__init__ (self, name, '/TrackList')
-        self.totem = totem
-
-    def disconnect (self):
-        self.remove_from_connection (None, None)
+    def SetPosition (self, track_id, position):
+        position = position / 1000L
 
-    @dbus.service.signal (dbus_interface = "org.freedesktop.MediaPlayer",
-                          signature = 'i') # pylint: disable-msg=C0103
-    def TrackListChange (self, length):
-        # TODO: we can't implement this until TotemPlaylist is exposed in the
-        # Python API
-        pass
-
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
-                          in_signature = 'i', # pylint: disable-msg=C0103
-                          out_signature = 'a{sv}')
-    def GetMetadata (self, pos):
-        # Since the API doesn't currently exist in Totem to get the rest of the
-        # metadata, we can only return the title
-        return { "title" : self.totem.get_title_at_playlist_pos (pos) }
+        # Bail if the position is not in the permitted range
+        if position < 0 or position > self.totem.props.stream_length:
+            return
 
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
-                          in_signature = '', # pylint: disable-msg=C0103
-                          out_signature = 'i')
-    def GetCurrentTrack (self):
-        return self.totem.get_playlist_pos ()
+        self.totem.action_seek_time (position, False)
 
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
-                          in_signature = '', # pylint: disable-msg=C0103
-                          out_signature = 'i')
-    def GetLength (self):
-        return self.totem.get_playlist_length ()
-
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
-                          in_signature = 'sb', # pylint: disable-msg=C0103
-                          out_signature = 'i')
-    def AddTrack (self, uri, play_immediately):
-        # We can't currently support !play_immediately
-        self.totem.add_to_playlist_and_play (str (uri), '', True)
-        return 0
-
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
-                          in_signature = 'i', # pylint: disable-msg=C0103
+    @dbus.service.method (dbus_interface = 'org.mpris.MediaPlayer2.Player',
+                          in_signature = 's', # pylint: disable-msg=C0103
                           out_signature = '')
-    def DelTrack (self, pos):
-        # TODO: we need TotemPlaylist exposed by the Python API for this
-        pass
+    def OpenUri (self, uri):
+        if self.totem.action_set_mrl (uri):
+            self.totem.action_play ()
 
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
-                          in_signature = 'b', # pylint: disable-msg=C0103
-                          out_signature = '')
-    def SetLoop (self, loop):
-        self.totem.action_remote_set_setting (Totem.RemoteSetting.REPEAT, loop)
+        raise dbus.exceptions.DBusException (
+            'org.mpris.MediaPlayer2.InvalidUri',
+            _(u'The URI â%sâ is not supported.') % uri)
 
-    @dbus.service.method (dbus_interface='org.freedesktop.MediaPlayer',
-                          in_signature = 'b', # pylint: disable-msg=C0103
-                          out_signature = '')
-    def SetRandom (self, random):
-        self.totem.action_remote_set_setting (Totem.RemoteSetting.SHUFFLE,
-                                              random)
+    @dbus.service.signal (dbus_interface = 'org.mpris.MediaPlayer2.Player',
+                          signature = 'x') # pylint: disable-msg=C0103
+    def Seeked (self, position):
+        pass



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]