#!/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",
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):
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
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")
+class EnableSystemContactIntegration(object):
- @gtk_toolbox.log_exception(_moduleLogger)
- def _on_pickup_error(self, autoAcceptCall, *args):
- _moduleLogger.info("Call failed to pick up (%r)" % (args, ))
+ ACCOUNT_MGR_NAME = "org.freedesktop.Telepathy.AccountManager"
+ ACCOUNT_MGR_PATH = "/org/freedesktop/Telepathy/AccountManager"
+ ACCOUNT_MGR_IFACE_QUERY = "com.nokia.AccountManager.Interface.Query"
+ ACCOUNT_IFACE_COMPAT = "com.nokia.Account.Interface.Compat"
+ ACCOUNT_IFACE_COMPAT_PROFILE = "com.nokia.Account.Interface.Compat.Profile"
+ DBUS_PROPERTIES = 'org.freedesktop.DBus.Properties'
+ def __init__(self, profileName):
+ self._bus = dbus.SessionBus()
+ self._profileName = profileName
-class MissedManager(object):
+ def start(self):
+ self._accountManager = self._bus.get_object(
+ self.ACCOUNT_MGR_NAME,
+ self.ACCOUNT_MGR_PATH,
+ )
+ self._accountManagerQuery = dbus.Interface(
+ self._accountManager,
+ dbus_interface=self.ACCOUNT_MGR_IFACE_QUERY,
+ )
- def __init__(self):
- self._newChannelSignaller = NewChannelSignaller(self._on_new_channel)
+ self._accountManagerQuery.FindAccounts(
+ {
+ self.ACCOUNT_IFACE_COMPAT_PROFILE: self._profileName,
+ },
+ reply_handler = self._on_found_accounts_reply,
+ error_handler = self._on_error,
+ )
- def start(self):
- self._newChannelSignaller.start()
+ @misc.log_exception(_moduleLogger)
+ def _on_found_accounts_reply(self, accountObjectPaths):
+ for accountObjectPath in accountObjectPaths:
+ print accountObjectPath
+ account = self._bus.get_object(
+ self.ACCOUNT_MGR_NAME,
+ accountObjectPath,
+ )
+ accountProperties = dbus.Interface(
+ account,
+ self.DBUS_PROPERTIES,
+ )
+ accountProperties.Set(
+ self.ACCOUNT_IFACE_COMPAT,
+ "SecondaryVCardFields",
+ ["TEL"],
+ reply_handler = self._on_field_set,
+ error_handler = self._on_error,
+ )
- @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
+ @misc.log_exception(_moduleLogger)
+ def _on_field_set(self):
+ _moduleLogger.info("SecondaryVCardFields Set")
- missDetection = WasMissedCall(
- bus, conn, chan, self._on_missed_call, self._on_error_for_missed
- )
+ @misc.log_exception(_moduleLogger)
+ def _on_error(self, error):
+ _moduleLogger.error("%r" % (error, ))
- @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/gv/USERNAME/Channel1")
+ '/org/freedesktop/Telepathy/ConnectionManager/theonering/gv/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/gv/USERNAME/Channel1")
+ 'org.freedesktop.Telepathy.ConnectionManager.theonering.gv.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/gv/USERNAME/Channel1")
+ 'theonering'
+ """
+ return path[1:].split("/")[4]