From b93016cc87de3be7cc151a038d4673550fe9c0a3 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 13 May 2010 21:25:34 -0500 Subject: [PATCH 1/1] Enabling call monitor --- src/call_monitor.py | 145 ++++++++++++++++++++++++++++++++++++++++++++++ src/mormonchannel_gtk.py | 4 +- src/player.py | 13 +++++ 3 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 src/call_monitor.py diff --git a/src/call_monitor.py b/src/call_monitor.py new file mode 100644 index 0000000..97be5a7 --- /dev/null +++ b/src/call_monitor.py @@ -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] diff --git a/src/mormonchannel_gtk.py b/src/mormonchannel_gtk.py index fec2469..d6a64c9 100755 --- a/src/mormonchannel_gtk.py +++ b/src/mormonchannel_gtk.py @@ -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() diff --git a/src/player.py b/src/player.py index 61ebf5c..54743c6 100644 --- a/src/player.py +++ b/src/player.py @@ -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) -- 1.7.9.5