initial checki
[tpathy-callback] / src / SMSListener.py
diff --git a/src/SMSListener.py b/src/SMSListener.py
new file mode 100755 (executable)
index 0000000..689e486
--- /dev/null
@@ -0,0 +1,229 @@
+#!/usr/bin/env python
+'''
+Created on 03.12.2009
+
+@author: muelli
+'''
+
+import dbus.glib
+import gobject
+import logging; logging.basicConfig(level=logging.DEBUG)
+
+import telepathy
+from telepathy.interfaces import CLIENT, \
+                                 CLIENT_OBSERVER, \
+                                 CHANNEL
+
+
+log = logging.getLogger("telepathy-callback")
+
+sender = None
+receiver = None
+gsm_connection = None
+gsm_account = None
+
+def is_number(nr):
+    """Checks whether a given string looks like an international phone
+    number"""
+    return True
+
+def handle_msg(msg, magic="call: ", filter=is_number):
+    """Handles a message, i.e. check for it containing the message containing
+    the magic keyword.
+    Returns the valid number or None
+    """
+    number_candidate = None
+    if msg.startswith(magic):
+        number_candidate = msg[len(magic):]
+        
+    retval = None
+    log.debug("Number candidate: %s" % number_candidate)
+    if number_candidate:
+        valid_number = filter(msg)
+        if valid_number:
+            retval = number_candidate
+            
+    return retval
+
+
+def request_call(bus, number):
+    channel_dispatcher = bus.get_object('org.freedesktop.Telepathy.ChannelDispatcher',
+                        '/org/freedesktop/Telepathy/ChannelDispatcher')
+    request_args = {'org.freedesktop.Telepathy.Channel.ChannelType:':
+                            dbus.String('org.freedesktop.Telepathy.Channel.Type.StreamedMedia', variant_level=1),
+                'org.freedesktop.Telepathy.Channel.TargetHandleType':
+                            dbus.String('Contact', variant_level=1),
+                'org.freedesktop.Telepathy.Channel.TargetID':
+                            dbus.String(sender, variant_level=1),
+                }
+    # Hopefully, the name of the Handler is correct
+    channel_request_object_name = channel_dispatcher.CreateChannel(gsm_account, request_args,
+                                    dbus.Int64(0),
+                                 "org.freedesktop.Telepathy.Client.Callback")
+    # Stupid DBus Binding don't return an object itself
+    # FIXME: Check whether the bus_name is correct
+    channel_request = bus.get_object('org.freedesktop.Telepathy.ChannelRequest',
+                                     channel_request_object_name)
+    log.debug("Returning Channel Request: %s", channel_request)
+    return channel_request
+
+def received_message_handler(sender=None, *args, **kwargs):
+    """Listens on the MessageReceived signal by Telepathy.
+    Turns out, that most of the application logic landed here instead
+    of the class created below
+    """
+    print "received_message_handler: %s" % locals()
+    global receiver
+    
+    bus = dbus.SessionBus()
+    
+    if isinstance(sender, dbus.Array):
+        for elem in sender:
+            if isinstance(elem, dbus.Dictionary):
+                msg = elem.get(u'content', None)
+                if msg: 
+                    print "Message: %s" % msg
+                    # TODO: Check for Prefix
+                    number = handle_msg(msg)
+                    
+                    if not number == None:
+                        receiver = number
+                        assert sender != None, "Somehow Sender is None, although it should have been set earlier"
+                        
+                        # FIXME: Get connection object
+
+                        
+                        # TODO: Get GSM Account
+#                        account_manager = bus.get_object('org.freedesktop.Telepathy.AccountManager',
+#                                                '/org/freedesktop/Telepathy/AccountManager')
+#                        accounts = account_manager.ValidAccounts()
+#                        log.debug('Accounts: %s', accounts) 
+                        
+                        # TODO: Call Sender
+                        channel_request = request_call(bus, sender)
+                        # TODO: Listen on channel_request signal: Succeeded
+                        def opened_channel(*args, **kwargs):
+                            log.debug("Opened channel. %s", locals())
+                        
+                                      
+                        bus.add_signal_receiver(opened_channel,
+                                               "Succeeded" )
+                        log.debug("msg: %s, %s", channel_request, dir(channel_request))
+                        channel_request.Proceed()
+                        
+                        # TODO: Call Receiver
+                        channel_request = request_call(bus, receiver)
+                        bus.add_signal_receiver(opened_channel,
+                                                "Succeeded" )
+                        channel_request.Proceed()
+                        
+                                                
+                        
+                        
+
+class Callback(dbus.service.Object, telepathy.server.DBusProperties):
+    name = 'org.freedesktop.Telepathy.Client.Callback'
+    def __init__(self, *args):
+        self.bus = dbus.SessionBus()
+        bus_name = dbus.service.BusName(Callback.name, bus = self.bus)
+        dbus.service.Object.__init__(self, bus_name, '/%s' % Callback.name.replace('.', '/'))
+        
+        self.log = logging.getLogger("Callback")
+        
+        self._interfaces = set()
+        
+        telepathy.server.DBusProperties.__init__(self)
+        
+        self._implement_property_get(CLIENT, {
+            'Interfaces': lambda: [ CLIENT_OBSERVER ],
+          })
+        self._implement_property_get(CLIENT_OBSERVER, {
+            'ObserverChannelFilter': lambda: dbus.Array([
+                    dbus.Dictionary({
+                        'org.freedesktop.Telepathy.Channel.ChannelType': dbus.String('org.freedesktop.Telepathy.Channel.Type.Text'),
+                        'org.freedesktop.Telepathy.Channel.TargetHandleType': dbus.UInt32(1),
+                    }, signature='sv'),
+                    dbus.Dictionary({
+                        'org.freedesktop.Telepathy.Channel.ChannelType': dbus.String('org.freedesktop.Telepathy.Channel.Type.Text'),
+                        'org.freedesktop.Telepathy.Channel.TargetHandleType': dbus.UInt32(2),
+                    }, signature='sv')
+
+                ], signature='a{sv}')
+          })
+        
+        self.first_call = None
+        self.second_call = None
+        
+        
+        
+    def listen(self):
+        loop = gobject.MainLoop()
+        loop.run()
+
+    
+
+    @dbus.service.method('org.freedesktop.Telepathy.Client.Observer',
+                     in_signature='ooa(oa{sv})oaoa{sv}', out_signature='')
+    def ObserveChannels(self, account, connection, channels, dispatch_operation,
+                        requests_satisfied, observer_info):
+        global sender
+        global gsm_connection
+        global gsm_account
+        
+        print "Incoming"
+        print "account %s" % account
+        print "connection %s" % connection
+        print "\n\n"
+        log = file('/tmp/incoming','wa')
+        log.write( "Incoming channels on %s:" % (connection))
+        log.write("Locals: %s" % locals())
+        
+        sender = None
+        for channel_object, props in channels:
+            print "Channel: %s" % channel_object
+            for k, v in props.iteritems():
+                print "k: %s :: %s " % (k, v)
+                print ""
+                
+            sender = props['org.freedesktop.Telepathy.Channel.InitiatorID']
+            # TODO: Check for SMS
+            gsm_connection = connection
+            gsm_account = account
+            self.bus.add_signal_receiver(received_message_handler,
+                                               "MessageReceived" )
+            print "\n\n"
+            log.write( " - %s :: %s" % (props[CHANNEL + '.ChannelType'],
+                                   props[CHANNEL + '.TargetID'])
+            )
+            
+        
+        print "Sender: %s" % sender    
+
+    
+    @dbus.service.method('org.freedesktop.Telepathy.Client.Handler',
+                     in_signature='ooa(oa{sv})aota{sv}', out_signature='')
+    def HandleChannels(self, account, connection, channels,
+                        requests_satisfied, user_action_time, handler_info):
+        self.log.debug("Hndling channels: %s", locals())
+        if self.first_call == None:
+            self.log.debug('first call set')
+            self.first_call = connection
+        elif self.second_call == None:
+            self.second_call = connection
+            self.log.debug('second call set')
+            
+            # TODO: Merge Calls
+            request_conference = "com.nokia.Telepathy.Channel.Interface.Conference"
+            conference_service = self.bus.get_object(request_conference)
+            request_args = [self.first_call, self.second_call]
+            handles = conference_service.get_dbus_method("AddMemberChannels", request_args)
+
+            
+        else:
+            self.log.critical("Handler got called but two calls apparently "\
+                                "have been initiated: %s %s",
+                                self.first_call, self.second_call)
+
+if __name__ == '__main__':
+    myservice = Callback()
+    myservice.listen()