5 import dbus.mainloop.glib
9 DBUS_PROPERTIES = 'org.freedesktop.DBus.Properties'
12 class AutoAcceptAttempt(object):
13 # @todo Make this more composable by just checking for incoming call. Why
14 # incoming rather than just call? Because it has more demands on what
15 # properties to get which we can then get them in parallel. The callback
16 # would then chose to pickup based on the caller's number, wait to see if
17 # the call is ignored/rejected, etc
19 def __init__(self, bus, conn, chan):
20 self._sessionBus = bus
24 self._selfHandle = None
25 self._initiatorHandle = None
26 self._initiatorID = None
27 self._targetHandle = None
29 self._pendingHandles = None
32 # @bug Unsure why this isn't working
33 self._conn[DBUS_PROPERTIES].Get(
34 telepathy.interfaces.CONNECTION_INTERFACE,
36 reply_handler = self._on_got_self_handle,
37 error_handler = self._on_nothing,
40 self._conn[telepathy.interfaces.CHANNEL_INTERFACE_GROUP].GetSelfHandle(
41 reply_handler = self._on_got_self_handle,
42 error_handler = self._on_nothing,
45 self._chan[DBUS_PROPERTIES].GetAll(
46 telepathy.interfaces.CHANNEL_INTERFACE,
47 reply_handler = self._on_got_all,
48 error_handler = self._on_nothing,
52 # @bug Unsure why this isn't working
53 self._chan[DBUS_PROPERTIES].Get(
54 telepathy.interfaces.CHANNEL_INTERFACE_GROUP,
55 'LocalPendingMembers',
56 reply_handler = self._on_got_pending_members,
57 error_handler = self._on_nothing,
60 self._chan[telepathy.interfaces.CHANNEL_INTERFACE_GROUP].GetLocalPendingMembersWithInfo(
61 reply_handler = self._on_got_pending_members,
62 error_handler = self._on_nothing,
65 def _pickup_if_ready(self):
68 self._initiatorHandle,
74 # Note ready yet, still some outstanding requests
77 if self._selfHandle != self._targetHandle:
78 # Turns out it was an inbound call
81 # @bug does not distinguish between who the call is from for use for TOR auto-pickup
82 self._chan[telepathy.interfaces.CHANNEL_INTERFACE_GROUP].AddMembers(
83 reply_handler = self._on_members_added,
84 error_handler = self._on_nothing,
87 def _on_got_self_handle(self, selfHandle):
88 self._pickup_if_ready()
90 def _on_got_all(self, properties):
91 self._initiatorID = properties["InitiatorID"]
92 self._initiatorHandle = properties["InitiatorHandle"]
93 self._targetID = properties["InitiatorID"]
94 self._targetHandle = properties["InitiatorHandle"]
96 self._pickup_if_ready()
98 def _on_got_pending_members(self, pendings):
99 for pendingHandle, instigatorHandle, reason, message in pendings:
100 print pendingHandle, instigatorHandle, reason, message
102 self._pendingHandles = [pendingWithInfo[0] for pendingWithInfo in pendings]
103 self._pickup_if_ready()
105 def _on_members_added(self):
106 print "Should be picked up now"
108 def _on_nothing(*args):
112 class AutoAcceptCall(object):
113 # @todo Make this more composable by switchig it to just handle monitoring
114 # for new channels. Other the callback on a new channel will filter for
118 self._sessionBus = dbus.SessionBus()
119 self._activeAttempts = []
122 self._sessionBus.add_signal_receiver(
123 self._on_new_channel,
125 "org.freedesktop.Telepathy.Connection",
130 def _on_new_channel(self, channelObjectPath, channelType, handleType, handle, supressHandler):
131 if channelType != telepathy.interfaces.CHANNEL_TYPE_STREAMED_MEDIA:
134 connObjectPath = channelObjectPath.rsplit("/", 1)[0][1:]
135 serviceName = connObjectPath.replace("/", ".")
136 conn = telepathy.client.Channel(serviceName, connObjectPath)
137 chan = telepathy.client.Channel(serviceName, channelObjectPath)
138 # @bug does not distinguish between preferred CMs
139 # @todo Need a way to be notified on error, ignored, or if picked up
140 attemptPickup = AutoAcceptAttempt(self._sessionBus, conn, chan)
141 self._activeAttempts.append(attemptPickup)
143 def _on_nothing(*args):
147 if __name__ == "__main__":
148 l = dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
149 autoaccept = AutoAcceptCall()
151 gobject.threads_init()
152 gobject.idle_add(autoaccept.start)
154 mainloop = gobject.MainLoop(is_running=True)