sms2twitter gate in 5 minutes

    imageThe purpose of this article is to demonstrate the capabilities of Python for s60 for working with SMS messages and databases. To make it more interesting, let’s take a look at a real example, create an application that will read new smartphone messages, parse them, save phone numbers with logins and passwords in your database, and post tweets that came from these numbers.

    What else can this come in handy for? Nowadays, SMS services are used quite widely. There are a lot of ways to implement them. I recently had a need to implement a service in which customers could send an order number by SMS and their status would come back. The problem was solved like this: for 500 rubles, an old Nokia 7610 was bought at a flea market in a crumbling state, half of the buttons did not work, there were problems with sound, etc. A SIM card was inserted from a local operator with an unlimited SMS package. Now this device will play the role of a server that will operate 24/7, with an uninterrupted power supply (battery), and will not know the problems with cooling :)

    Work with SMS messages

    Everything is simple here. There is an inbox module that allows us to work with messages on our phone. This module has the Inbox class of the same name, which allows you to read the message, sender and time. Each message has its own ID. A list of IDs of all messages can be obtained by the sms_messages () function. But we are more interested in the bind function, by which we specify a function that will be called immediately as soon as we receive a new message.

    It will look like this:

    1. #coding: utf-8
    2. import e32
    3. from appuifw import app
    4. import inbox
    6. class Main:
    8.     def incoming_callback (self, id):    
    9.         print 'incoming message'
    10.         # make a short pause so that there are no conflicts 
    11.         # with the Messages app
    12.         e32.ao_sleep (1)
    13.         #create a new instance of the Inbox class, as in the old
    14.         # new messages will not be visible
    15.         messages = inbox.Inbox ()
    16.         # we get the content of the message and the address where it came from
    17.         print messages.content (id)
    18.         print messages.address (id)
    19.         # and delete it so that it does not interfere with us
    20.         messages.delete (id)    
    22.     def __init __ (self):
    23.         # create an instance of the inbox class and bind to the incoming function
    24.         self.inb = inbox.Inbox ()
    25.         self.inb.bind (self.incoming_callback)
    26.         print 'start'
    28. lock = e32.Ao_lock ()
    29. app.exit_key_handler = lock.signal
    30. a = Main ()
    31. lock.wait ()

    I would like to mention the features of the address in the message. If we received a message whose sender’s number is in the phone’s notebook, then it will return a name, not a number, to address. If there is no subscriber and notebook, then we will get a line with a number.

    Work with the database

    Through python, it is possible to work with the native symbian database, dbms, which is a relational database and supports sql syntax. I had to work 600-800 thousand records on the relatively old smartphone nokia 3230, which pretty well coped with this amount of data.

    There are 2 modules for working with e32db databases, which works directly with the database and e32dbm, which is an add-on for e32db and implements a key-value database interface. Despite the fact that in this case we will use e32dbm, I would like to show how to work with e32db. Those who write in python are probably used to DB API 2, so the principles of working with this database will seem a bit strange.

    E32db has 2 classes. One for writing to the database, the other for reading.
    Creating a database, creating tables and filling them out looks like this:
    1. import e32db
    2. db_path = u'e: \\ data \\ python \\ test.db '
    3. db = e32db.Dbms ()
    4. db.create (db_path)
    5. (db_path)
    6. db.execute (u'CREATE TABLE users (number CHAR (12), login LONG VARCHAR, password LONG VARCHAR) ')
    7. db.execute (u "" "INSERT INTO users VALUES ('+ 79xxxxxxxxx', 'kAIST', 'password')" "")

    Do not forget that the path to the database and queries must be in Unicode.
    Reading from a database is a bit more complicated.
    1. db_view = e32db.Db_view ()
    2. # make a request indicating an already open database
    3. db_view.prepare (db, u'SELECT * from users')
    4. # go through all the lines
    5. for x in xrange (db_view.count_line ()):
    6.     # prepare a new line for output
    7.     db_view.get_line ()
    8.     # and look at what we have in the columns
    9.     # strange, but the numbering starts with 1 and not with 0
    10.     print db_view.col (1), db_view.col (2)
    11.     # go to the next line
    12.     db_view.next_line ()

    For the application to work, e32dbm is enough for us, working with which is as simple as possible:
    1. import e32dbm
    2. db = (u'e: \\ data \\ python \\ test ',' c ')
    3. db ['first'] = 'hello'
    4. db ['second'] = 'second key'
    5. db.sync ()
    6. db.close ()

    Let's go directly to our task.

    Let's take as a basis our code, which receives SMS messages. Add the following lines to the beginning:
    1. import e32dbm
    2. db = (u'e: \\ mydb ',' c ')

    It remains to write a function that will parse messages. In order for the subscriber to be able to work with this gate, his number must be associated with an account on Twitter. Let's not go through all possible authorization options and argue about security, but simply enter two commands: add login password and delete. The first command sent to the phone will add the username and password associated with the phone number to the database, and the second will be deleted. Accordingly, after such authorization, the user can simply write to the SMS gate number, which will go to Twitter.
    1.     def parse (self, content, address):
    2.         if content.startswith ('add'):
    3.             print 'Add:', address
    4.             db [address] = repr (content.split () [1: 3])
    5.             db.sync ()
    6.         elif content.startswith ('delete'):
    7.             if address in db.keys ():
    8.                 print 'Delete:', adress
    9.                 del db [address]
    10.                 db.sync ()
    11.         else:
    12.             if address in db.keys ():
    13.                 print 'Send:', address
    14.                 self.send_twit (db [address], content)

    and add the line to the incoming_callback function:
    self.parse (messages.content (id), str (hash (messages.address (id))))

    And it remains to implement the addition of a tweet, as we did in this topic.
        def send_twit (self, tw, content):
            login, password = eval (tw)
            api = ('basic', login, password)
            api.update_status (content)

    Now our gate is ready. Optionally, it can be packaged in sis and filed in terms of error handling.
    We take the source code here , and the ready sis is here.
    Fresh ideas to you!

    Also popular now: