Commits

Luke Plant committed abe4477

Replaced specific MPRIS players with support for all of them.

Comments (0)

Files changed (11)

 Currently supported players are:
 """
     for P in players:
-        help += " " + P.process_name + "\n"
+        n = getattr(P, 'friendly_name', None)
+        if n is not None:
+            help += " " + n + "\n"
 
     return help
 

playerdo/backends/__init__.py

-from playerdo.backends.amarok import *
-from playerdo.backends.clementine import *
-from playerdo.backends.exaile import *
 from playerdo.backends.moc import *
 from playerdo.backends.rhythmbox import *
 from playerdo.backends.shellfm import *
+from playerdo.backends.mpris import *

playerdo/backends/amarok.py

-from playerdo.backends.mpris import MprisPlayer
-
-
-class Amarok(MprisPlayer):
-
-    process_name = "amarok"
-    bus_name = "org.mpris.amarok"

playerdo/backends/base.py

 # Base class useful for implementing players
 class Player(object):
 
-    process_name = None
-
-    @classmethod
-    def is_concrete(cls):
-        """
-        Returns True if this class corresponds to a real program
-        """
-        return cls.process_name is not None
+    process_name = None # used for pidof
+    friendly_name = None # used for display in help
 
     def is_running(self):
         """

playerdo/backends/clementine.py

-from playerdo.backends.mpris import MprisPlayer
-
-
-class Clementine(MprisPlayer):
-
-    process_name = "clementine"
-    bus_name = "org.mpris.clementine"

playerdo/backends/exaile.py

-from playerdo.backends.mpris import MprisPlayer
-from playerdo.utils import DBusObject
-
-
-class Exaile(MprisPlayer):
-
-    process_name = "exaile"
-    bus_name = "org.mpris.exaile"
-
-    def is_stopped(self):
-        exaile = DBusObject(self.bus_name, "/org/exaile/Exaile")
-        return not bool(exaile.IsPlaying())

playerdo/backends/moc.py

 class Moc(Player):
 
     process_name = "mocp"
+    friendly_name = "moc"
 
     def is_stopped(self):
         info = process_stdout(["mocp", "-i"])

playerdo/backends/mpris.py

 import dbus
 
 
+def get_all_mpris_buses():
+    bus = dbus.SessionBus()
+    return [str(s) for s in bus.list_names() if str(s).startswith('org.mpris.')]
+
+
 class MprisPlayer(Player):
 
-    bus_name = None
+    friendly_name = "Any MPRIS player"
     player_object_name = "/Player"
     tracklist_object_name = "/TrackList"
 
     @property
+    def bus_name(self):
+        # Use the first one we find.
+        try:
+            return self._bus_name
+        except AttributeError:
+            candidates = get_all_mpris_buses()
+            # Sort by status - playing = 0, paused = 1, stopped = 2
+            l = [(int(DBusObject(n, self.player_object_name).GetStatus()[0]), n)
+                 for n in candidates]
+            l.sort()
+            if len(l) > 0:
+                bus_name = l[0][1]
+            else:
+                bus_name = None
+            self._bus_name = bus_name
+            return bus_name
+
+    @property
     def player(self):
         if self.bus_name is None or self.player_object_name is None:
             raise NotImplementedError
             return obj
 
     def is_running(self):
-        # pidof doesn't work for some apps (e.g. exaile), but this should work
-        # for all Mpris apps.
+        if self.bus_name is None:
+            return False
         try:
             # Force evaluation:
             bus = self.player._bus
             return False
 
     def is_stopped(self):
-        # This seems to work for exaile and clementine
-        return self.tracklist.GetCurrentTrack() == -1
+        return self.player.GetStatus()[0] == 2
 
     def play(self):
         self.player.Play()
         self.player.ShowOSD()
 
 
+

playerdo/backends/rhythmbox.py

 class RhythmBox(Player):
 
     process_name = "rhythmbox"
+    friendly_name = "rhythmbox"
 
     def is_stopped(self):
         # rhythmbox doesn't seem to have this state

playerdo/backends/shellfm.py

     #  shc (compiled version of shc.hs from shell-fm's sources)
 
     process_name = "shell-fm"
+    friendly_name = "shell-fm"
 
     def is_stopped(self):
         return not os.path.isfile(os.path.join(os.environ['HOME'],
     try:
         player.do_command(command)
     except NotImplementedError:
-        sys.stderr.write("Operation '%s' not supported for player '%s'.\n" % (command, player.process_name))
+        sys.stderr.write("Operation '%s' not supported for player '%s'.\n" % (command, player.friendly_name))
         sys.exit(1)
 
 
 def find_players():
-    return [v for v in globals().values() if type(v) is type and issubclass(v, Player) and v.is_concrete()]
+    return [v for v in globals().values() if type(v) is type and issubclass(v, Player)]