Enabling call monitor
authorEd Page <eopage@byu.net>
Fri, 14 May 2010 02:25:34 +0000 (21:25 -0500)
committerEd Page <eopage@byu.net>
Fri, 14 May 2010 02:25:34 +0000 (21:25 -0500)
src/call_monitor.py [new file with mode: 0644]
src/mormonchannel_gtk.py
src/player.py

diff --git a/src/call_monitor.py b/src/call_monitor.py
new file mode 100644 (file)
index 0000000..97be5a7
--- /dev/null
@@ -0,0 +1,145 @@
+import logging
+
+import gobject
+import dbus
+import telepathy
+
+import gtk_toolbox
+
+
+_moduleLogger = logging.getLogger(__name__)
+DBUS_PROPERTIES = 'org.freedesktop.DBus.Properties'
+
+
+class NewChannelSignaller(object):
+
+       def __init__(self, on_new_channel):
+               self._sessionBus = dbus.SessionBus()
+               self._on_user_new_channel = on_new_channel
+
+       def start(self):
+               self._sessionBus.add_signal_receiver(
+                       self._on_new_channel,
+                       "NewChannel",
+                       "org.freedesktop.Telepathy.Connection",
+                       None,
+                       None
+               )
+
+       def stop(self):
+               self._sessionBus.remove_signal_receiver(
+                       self._on_new_channel,
+                       "NewChannel",
+                       "org.freedesktop.Telepathy.Connection",
+                       None,
+                       None
+               )
+
+       @gtk_toolbox.log_exception(_moduleLogger)
+       def _on_new_channel(
+               self, channelObjectPath, channelType, handleType, handle, supressHandler
+       ):
+               connObjectPath = channel_path_to_conn_path(channelObjectPath)
+               serviceName = path_to_service_name(channelObjectPath)
+               try:
+                       self._on_user_new_channel(
+                               self._sessionBus, serviceName, connObjectPath, channelObjectPath, channelType
+                       )
+               except Exception:
+                       _moduleLogger.exception("Blocking exception from being passed up")
+
+
+class ChannelClosed(object):
+
+       def __init__(self, bus, conn, chan, on_closed):
+               self.__on_closed = on_closed
+
+               chan[telepathy.interfaces.CHANNEL].connect_to_signal(
+                       "Closed",
+                       self._on_closed,
+               )
+
+       @gtk_toolbox.log_exception(_moduleLogger)
+       def _on_closed(self):
+               self.__on_closed(self)
+
+
+class CallMonitor(gobject.GObject):
+
+       __gsignals__ = {
+               'call_start' : (
+                       gobject.SIGNAL_RUN_LAST,
+                       gobject.TYPE_NONE,
+                       (),
+               ),
+               'call_end' : (
+                       gobject.SIGNAL_RUN_LAST,
+                       gobject.TYPE_NONE,
+                       (),
+               ),
+       }
+
+       def __init__(self):
+               gobject.GObject.__init__(self)
+               self._isActive = False
+               self._newChannelMonitor = NewChannelSignaller(self._on_new_channel)
+               self._channelClosedMonitors = []
+
+       def start(self):
+               self._isActive = True
+               self._newChannelMonitor.start()
+
+       def stop(self):
+               self._isActive = False
+               self._newChannelMonitor.stop()
+
+       def _on_new_channel(self, sessionBus, serviceName, connObjectPath, channelObjectPath, channelType):
+               if not self._isActive:
+                       return
+
+               if channelType != telepathy.interfaces.CHANNEL_TYPE_STREAMED_MEDIA:
+                       return
+
+               cmName = cm_from_path(connObjectPath)
+               conn = telepathy.client.Connection(serviceName, connObjectPath)
+               try:
+                       chan = telepathy.client.Channel(serviceName, channelObjectPath)
+               except dbus.exceptions.UnknownMethodException:
+                       _moduleLogger.exception("Client might not have implemented a deprecated method")
+                       return
+
+               missDetection = ChannelClosed(
+                       sessionBus, conn, chan, self._on_close
+               )
+               self._outstandingRequests.append(missDetection)
+               if len(self._outstandingRequests) == 1:
+                       self.emit("call_start")
+
+       def _on_close(self, channelCloseMonitor):
+               self._outstandingRequests.remove(channelCloseMonitor)
+               if not self._outstandingRequests:
+                       self.emit("call_stop")
+
+
+def channel_path_to_conn_path(channelObjectPath):
+       """
+       >>> channel_path_to_conn_path("/org/freedesktop/Telepathy/ConnectionManager/theonering/gv/USERNAME/Channel1")
+       '/org/freedesktop/Telepathy/ConnectionManager/theonering/gv/USERNAME'
+       """
+       return channelObjectPath.rsplit("/", 1)[0]
+
+
+def path_to_service_name(path):
+       """
+       >>> path_to_service_name("/org/freedesktop/Telepathy/ConnectionManager/theonering/gv/USERNAME/Channel1")
+       'org.freedesktop.Telepathy.ConnectionManager.theonering.gv.USERNAME'
+       """
+       return ".".join(path[1:].split("/")[0:7])
+
+
+def cm_from_path(path):
+       """
+       >>> cm_from_path("/org/freedesktop/Telepathy/ConnectionManager/theonering/gv/USERNAME/Channel1")
+       'theonering'
+       """
+       return path[1:].split("/")[4]
index fec2469..d6a64c9 100755 (executable)
@@ -6,7 +6,6 @@
 @todo Add additional sources
 @todo Track recent
 @todo Sequential playback
-@todo Enable Call Monitor
 @todo Audio seek bar
 @todo Persisted Pause
 @todo Favorites
@@ -21,6 +20,8 @@ import logging
 import ConfigParser
 
 import gobject
+import dbus
+import dbus.mainloop.glib
 import gtk
 
 try:
@@ -138,6 +139,7 @@ class MormonChannelProgram(hildonize.get_app_class()):
 def run():
        gobject.threads_init()
        gtk.gdk.threads_init()
+       l = dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
 
        hildonize.set_application_title(constants.__pretty_app_name__)
        app = MormonChannelProgram()
index 61ebf5c..54743c6 100644 (file)
@@ -4,6 +4,7 @@ import gobject
 
 import util.misc as misc_utils
 import stream
+import call_monitor
 
 
 _moduleLogger = logging.getLogger(__name__)
@@ -38,6 +39,9 @@ class Player(gobject.GObject):
                self._index = index
                self._node = None
 
+               self._calls = call_monitor.CallMonitor()
+               self._calls.connect("call_start", self._on_call_start)
+
                self._stream = stream.GSTStream()
                self._stream.connect("state-change", self._on_stream_state)
                self._stream.connect("eof", self._on_stream_eof)
@@ -83,6 +87,8 @@ class Player(gobject.GObject):
                _moduleLogger.info("play")
                self._stream.play()
 
+               self._calls.start()
+
        def pause(self):
                _moduleLogger.info("pause")
                self._stream.pause()
@@ -92,6 +98,8 @@ class Player(gobject.GObject):
                self._stream.stop()
                self.set_piece_by_node(None)
 
+               self._calls.stop()
+
        def back(self):
                _moduleLogger.info("back")
 
@@ -113,5 +121,10 @@ class Player(gobject.GObject):
                _moduleLogger.info("Error %s %s" % (error, debug))
                self.emit("error", error, debug)
 
+       @misc_utils.log_exception(_moduleLogger)
+       def _on_call_start(self, monitor):
+               _moduleLogger.info("Call in progress, pausing")
+               self.pause()
+
 
 gobject.type_register(Player)