📜 ⬆️ ⬇️

sms2twitter gate in 5 minutes

image The 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 analyze the real example, create an application that will read new smartphone messages, parse them, save phone numbers with logins and passwords to your database, and post tweets from these numbers.

What is it still useful for? Nowadays, sms services are widely used. There are many ways to implement them. I recently had the need to implement a service in which customers could send an SMS with an order number and in response would receive its status. The task was solved in the following way: for 500 rubles, an old Nokia 7610 in a collapsing state was bought at the flea market, half the buttons did not work, there were problems with sound, etc. There 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 any problems with cooling :)


')

Work with SMS messages


It's simple. There is an inbox module that allows us to work with messages in our phone. This module has the same name class Inbox, which allows you to read the message, the sender and the time. Each message has its own ID. The list of IDs for all messages can be obtained using the sms_messages () function. But we are more interested in the bind function, where we specify the 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
  5. class Main:
  6. def incoming_callback ( self , id ) :
  7. print 'incoming message'
  8. # make a short pause so that there are no conflicts
  9. # with the application "Messages"
  10. e32. ao_sleep ( 1 )
  11. # create a new instance of the class Inbox, as in the old
  12. # new messages will not be visible
  13. messages = inbox. Inbox ( )
  14. # get the message content and the address where it came from
  15. print messages. content ( id )
  16. print messages. address ( id )
  17. # and remove it so that it does not interfere with us
  18. messages. delete ( id )
  19. def __init__ ( self ) :
  20. # create an instance of the inbox class and bind the incoming function
  21. self . inb = inbox. Inbox ( )
  22. self . inb . bind ( self . incoming_callback )
  23. print 'Start'
  24. lock = e32. Ao_lock ( )
  25. app. exit_key_handler = lock. signal
  26. a = Main ( )
  27. lock. wait ( )


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

Work with database


Through python there is an opportunity to work with the symbian native database - dbms, which is a relational database, and supports sql syntax. I used to work 600-800 thousands of records on a relatively old smartphone nokia 3230, which did quite well 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 on 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 to write to the database, the other to read.
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. open ( 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 the database is a bit more complicated.
  1. db_view = e32db. Db_view ( )
  2. # make a request, indicating the already open database
  3. db_view prepare ( db, u 'SELECT * from users' )
  4. # pass through all lines
  5. for x in xrange ( db_view. count_line ( ) ) :
  6. # prepare a new line for issue
  7. db_view get_line ( )
  8. # and see what we have in the columns
  9. # weird, 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 easier than ever:
  1. import e32dbm
  2. db = e32dbm. open ( 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 that receives SMS messages. Add the following lines to the beginning:
  1. import e32dbm
  2. db = e32dbm. open ( u 'e: \\ mydb' , 'c' )


It remains to write a function that will parse the message. In order for the subscriber to work with this gate, his number must be associated with the 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 login and password associated with the phone number to the database, and the second will be deleted. Accordingly, after such an authorization, the user will be able to simply write SMS to the 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 realize the addition of a tweet, as we did in this topic.
def send_twit ( self , tw, content ) :
login, password = eval ( tw )
api = tweepy. API . new ( 'basic' , login, password )
api. update_status ( content )

Now our gate is ready. If desired, it can be packaged in sis and fileed with a file in terms of error handling.
Outcomes, take here , and ready sis here
Fresh ideas to you!

Source: https://habr.com/ru/post/77761/


All Articles