X-Git-Url: http://git.maemo.org/git/?p=theonering;a=blobdiff_plain;f=src%2Futil%2Ftp_utils.py;h=712e64285f1728002c609a96ad604b213875fb8c;hp=33716798f4c0278e777fb454a766f2beae3aef11;hb=ecddbf102cb0a26d02712f41740c1c16c12c7d0f;hpb=40ee22655fd7e0176ded5798a30d16494c755f47 diff --git a/src/util/tp_utils.py b/src/util/tp_utils.py old mode 100755 new mode 100644 index 3371679..712e642 --- a/src/util/tp_utils.py +++ b/src/util/tp_utils.py @@ -1,158 +1,31 @@ #!/usr/bin/env python -import sys -sys.path.insert(0,"../src") import logging -import pprint -import gobject import dbus -import dbus.mainloop.glib import telepathy import util.go_utils as gobject_utils -import gtk_toolbox +import misc -_moduleLogger = logging.getLogger("receptionist") +_moduleLogger = logging.getLogger("tp_utils") DBUS_PROPERTIES = 'org.freedesktop.DBus.Properties' -class AutoAcceptCall(object): - - def __init__(self, bus, conn, chan, on_success, on_error): - self._sessionBus = bus - self._conn = conn - self._chan = chan - self._outstandingRequests = [] - self._on_success = on_success - self._on_error = on_error - - self._initiatorHandle = None - self._initiatorID = None - self._targetHandle = None - self._targetID = None - self._requested = None - self._pendingHandles = None - - self._chan[DBUS_PROPERTIES].GetAll( - telepathy.interfaces.CHANNEL_INTERFACE, - reply_handler = self._on_got_all, - error_handler = self._custom_error(self._on_got_all), - ) - self._outstandingRequests.append(self._on_got_all) - - if False: - # @bug Unsure why this isn't working - self._chan[DBUS_PROPERTIES].Get( - telepathy.interfaces.CHANNEL_INTERFACE_GROUP, - 'LocalPendingMembers', - reply_handler = self._on_got_pending_members, - error_handler = self._custom_error(self._on_got_pending_members), - ) - else: - self._chan[telepathy.interfaces.CHANNEL_INTERFACE_GROUP].GetLocalPendingMembersWithInfo( - reply_handler = self._on_got_pending_members, - error_handler = self._custom_error(self._on_got_pending_members), - ) - self._outstandingRequests.append(self._on_got_pending_members) - - def is_inbound(self): - return not self._requested - isInbound = self._targetHandle == self._initiatorHandle - return isInbound - - @property - def initiator(self): - return self._initiatorID - - @property - def target(self): - return self._targetID - - def accept_call(self, on_accepted, on_error): - self._chan[telepathy.interfaces.CHANNEL_INTERFACE_GROUP].AddMembers( - self._pendingHandles, - "", - reply_handler = self._custom_on_accept(on_accepted), - error_handler = self._custom_on_accept_error(on_error), - ) - - def _custom_on_accept(self, callback): - - def on_accept(*args): - callback(self) - - return on_accept - - def _custom_on_accept_error(self, callback): - - def on_error(*args): - callback(self, *args) - - return on_error - - def _custom_error(self, action): - - def _on_error(*args): - _moduleLogger.error("Failed for %r (%r)" % (action, args)) - self._outstandingRequests.remove(action) - if self._outstandingRequests: - return - - self._on_error(self) - - return _on_error - - def _report_callback_done(self, action): - _moduleLogger.debug("Succeded with %r" % (action, )) - self._outstandingRequests.remove(action) - if self._outstandingRequests: - return - - assert None not in ( - self._initiatorHandle, - self._initiatorID, - self._targetHandle, - self._targetID, - self._pendingHandles, - self._requested, - ) - - self._on_success(self) - - @gtk_toolbox.log_exception(_moduleLogger) - def _on_got_all(self, properties): - self._initiatorID = properties["InitiatorID"] - self._initiatorHandle = properties["InitiatorHandle"] - self._targetID = properties["InitiatorID"] - self._targetHandle = properties["InitiatorHandle"] - self._requested = properties["Requested"] - - self._report_callback_done(self._on_got_all) - - @gtk_toolbox.log_exception(_moduleLogger) - def _on_got_pending_members(self, pendings): - for pendingHandle, instigatorHandle, reason, message in pendings: - print pendingHandle, instigatorHandle, reason, message - - self._pendingHandles = [pendingWithInfo[0] for pendingWithInfo in pendings] - - self._report_callback_done(self._on_got_pending_members) - - class WasMissedCall(object): def __init__(self, bus, conn, chan, on_success, on_error): - self._on_success = on_success - self._on_error = on_error + self.__on_success = on_success + self.__on_error = on_error self._requested = None self._didMembersChange = False self._didClose = False self._didReport = False - self._timeoutId = gobject_utils.timeout_add_seconds(10, self._on_timeout) + self._onTimeout = gobject_utils.Timeout(self._on_timeout) + self._onTimeout.start(seconds=10) chan[telepathy.interfaces.CHANNEL_INTERFACE_GROUP].connect_to_signal( "MembersChanged", @@ -167,7 +40,7 @@ class WasMissedCall(object): chan[DBUS_PROPERTIES].GetAll( telepathy.interfaces.CHANNEL_INTERFACE, reply_handler = self._on_got_all, - error_handler = self._on_got_all, + error_handler = self._on_error, ) def cancel(self): @@ -190,41 +63,36 @@ class WasMissedCall(object): def _report_success(self): assert not self._didReport self._didReport = True - if self._timeoutId: - gobject.source_remove(self._timeoutId) - self._timeoutId = None - self._on_success(self) + self._onTimeout.cancel() + self.__on_success(self) def _report_error(self, reason): assert not self._didReport self._didReport = True - if self._timeoutId: - gobject.source_remove(self._timeoutId) - self._timeoutId = None - self._on_error(self, reason) + self._onTimeout.cancel() + self.__on_error(self, reason) - @gtk_toolbox.log_exception(_moduleLogger) + @misc.log_exception(_moduleLogger) def _on_got_all(self, properties): self._requested = properties["Requested"] self._report_missed_if_ready() - @gtk_toolbox.log_exception(_moduleLogger) + @misc.log_exception(_moduleLogger) def _on_members_changed(self, message, added, removed, lp, rp, actor, reason): - pprint.pprint((message, added, removed, lp, rp, actor, reason)) if added: self._didMembersChange = True self._report_missed_if_ready() - @gtk_toolbox.log_exception(_moduleLogger) + @misc.log_exception(_moduleLogger) def _on_closed(self): self._didClose = True self._report_missed_if_ready() - @gtk_toolbox.log_exception(_moduleLogger) + @misc.log_exception(_moduleLogger) def _on_error(self, *args): self._report_error(args) - @gtk_toolbox.log_exception(_moduleLogger) + @misc.log_exception(_moduleLogger) def _on_timeout(self): self._report_error("timeout") return False @@ -254,95 +122,39 @@ class NewChannelSignaller(object): None ) - @gtk_toolbox.log_exception(_moduleLogger) + @misc.log_exception(_moduleLogger) def _on_new_channel( self, channelObjectPath, channelType, handleType, handle, supressHandler ): - connObjectPath = channelObjectPath.rsplit("/", 1)[0] - serviceName = connObjectPath[1:].replace("/", ".") - conn = telepathy.client.Connection(serviceName, connObjectPath) - chan = telepathy.client.Channel(serviceName, channelObjectPath) - self._on_user_new_channel(self._sessionBus, conn, chan, channelType) - - -class AutoAcceptManager(object): - - def __init__(self): - self._newChannelSignaller = NewChannelSignaller(self._on_new_channel) - - def start(self): - self._newChannelSignaller.start() - - @gtk_toolbox.log_exception(_moduleLogger) - def _on_new_channel(self, bus, conn, chan, channelType): - pprint.pprint((bus, conn, chan, channelType)) - if channelType != telepathy.interfaces.CHANNEL_TYPE_STREAMED_MEDIA: - return - - # @todo distinguish between preferred CMs - attemptPickup = AutoAcceptCall(bus, conn, chan, self._on_inbound_call, self._on_inbound_call_error) - - @gtk_toolbox.log_exception(_moduleLogger) - def _on_inbound_call(self, autoAcceptCall): - # @todo Add a comparison for picking up for only certain contacts - print autoAcceptCall.initiator, autoAcceptCall.target - if autoAcceptCall.is_inbound(): - autoAcceptCall.accept_call(self._on_call_pickedup, self._on_pickup_error) - else: - _moduleLogger.debug( - "Not an inbound call (initiator=%r, target=%r)" % (autoAcceptCall.initiator, autoAcceptCall.target) + 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") - @gtk_toolbox.log_exception(_moduleLogger) - def _on_inbound_call_error(self, *args): - _moduleLogger.info("Inbound call error") - - @gtk_toolbox.log_exception(_moduleLogger) - def _on_call_pickedup(self, autoAcceptCall): - _moduleLogger.info("Call picked up") - - @gtk_toolbox.log_exception(_moduleLogger) - def _on_pickup_error(self, autoAcceptCall, *args): - _moduleLogger.info("Call failed to pick up (%r)" % (args, )) - - -class MissedManager(object): - - def __init__(self): - self._newChannelSignaller = NewChannelSignaller(self._on_new_channel) - - def start(self): - self._newChannelSignaller.start() - - @gtk_toolbox.log_exception(_moduleLogger) - def _on_new_channel(self, bus, conn, chan, channelType): - pprint.pprint((bus, conn, chan, channelType)) - if channelType != telepathy.interfaces.CHANNEL_TYPE_STREAMED_MEDIA: - return - - missDetection = WasMissedCall( - bus, conn, chan, self._on_missed_call, self._on_error_for_missed - ) - - @gtk_toolbox.log_exception(_moduleLogger) - def _on_missed_call(self, missDetection): - _moduleLogger.info("Missed a call") - @gtk_toolbox.log_exception(_moduleLogger) - def _on_error_for_missed(self, missDetection, reason): - _moduleLogger.info("Error: %r claims %r" % (missDetection, reason)) +def channel_path_to_conn_path(channelObjectPath): + """ + >>> channel_path_to_conn_path("/org/freedesktop/Telepathy/ConnectionManager/theonering/sip/USERNAME/Channel1") + '/org/freedesktop/Telepathy/ConnectionManager/theonering/sip/USERNAME' + """ + return channelObjectPath.rsplit("/", 1)[0] -if __name__ == "__main__": - logging.basicConfig(level=logging.DEBUG) - l = dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) - if False: - manager = AutoAcceptManager() - else: - manager = MissedManager() +def path_to_service_name(path): + """ + >>> path_to_service_name("/org/freedesktop/Telepathy/ConnectionManager/theonering/sip/USERNAME/Channel1") + 'org.freedesktop.Telepathy.ConnectionManager.theonering.sip.USERNAME' + """ + return ".".join(path[1:].split("/")[0:7]) - gobject.threads_init() - gobject.idle_add(manager.start) - mainloop = gobject.MainLoop(is_running=True) - mainloop.run() +def cm_from_path(path): + """ + >>> cm_from_path("/org/freedesktop/Telepathy/ConnectionManager/theonering/sip/USERNAME/Channel1") + 'theonering' + """ + return path[1:].split("/")[4]