7. TELEFONIJA I PORUKE

 

Primeri koda:

 

File:PythonOnSymbianBookExampleCode CallNotes.zip

File:PythonOnSymbianBookExampleCode SmsAutoReply.zip

 

7.1. Uvod

Ukoliko razmislimo o akcijama koje poduzmemo da načinimo ili primimo telefonski poziv, ili da pošaljemo ili primimo tekstualnu poruku, shvatamo da su one vrlo jednostavne.

 

Funkcionalnosti ugrađene u Python module koji podržavaju telefoniju i poruke to reflektuju.
Funkcionalnost je implementirana pomoću callbacks-a, funkcija koje se pozivaju od strane operativnog sistema kada telefon prima telefonski poziv ili poruku.

 

U ovom poglavlju se razmatra podrška i za telefoniju i poruke. Promatramo podršku Pythona i demonstriramo je sa kompletnim primerima. Poglavlje završavamo sa pregledom kako Python dozvoljava pristup evidenciji (logs) koju telefon čuva o pozivima i porukama koji su načinjeni, poslati ili primljeni.

 

7.2. Operacije telefona (Telefonije)

Operacije telefona, kako ih ljudi čine, su vrlo jednostavne. Možemo pozvati broj telefona. Možemo se javiti dolaznom pozivu. Možemo prekinuti poziv. Python-ova podrška telefoniji prikazuje ovu jednostavnost. Python dodaje mogućnost praćenja telefona u vezi poziva, slično akciji koju mi činimo kada isčekujemo važan poziv.

 

Python-ova funkcionalnost telefonije je ugrađena u telephone modul. Ovaj modul se mora uvesti (import-ovati) da bi pristup ovoj funkcionalnosti bio moguć.

 

 

7.2.1. Uputiti telefonski poziv

Da bismo uputili telefonski poziv koristeći dial() funkciju, koristimo pozivajući sled (sekvencu):

 

telephone.dial(<number>)

 

Parametar <number> je string koji sadrži broj telefona koji pozivamo. Biće pozvan onakav kakav je zadat, stoga svi delovi broja moraju biti uključeni (pozivni broj za državu, grad itd.). Na primer, ovo će pozvati broj u SAD-u:

 

telephone.dial(u"+15075551122")

 

<number> mora biti kodiran u Unicode-u.

 

Ukoliko se telefonski poziv odvija kada se načini poziv funkcije dial(), postojeći telefonski poziv se stavlja automatski na čekanje i novi telefonski poziv postaje aktivan.


Za prekid (okončanje) telefonskog poziva koristimo hang_up() metod bez parametra. Pozivanje ovog metoda prekida se trenutni poziv ukoliko je taj poziv iniciran pozivom metode dial().

 

Evo jednog primera. Počnimo sa lokalnim pozivom:

 

import telephone
telephone.dial("5551234")

 

Ovo govori uređaju da načini telefonski poziv, što je prikazano na sledećoj slici (Slika 21).

 

 

Slika 21 - Symbian uređaj poziva broj koristeći dial() funkciju

 

PythonOnSymbian_Figure6-1.jpg

 

U ovom stadijumu, sledeći kod prekida telefonski poziv:

 

telephone.hang_up()

 

Evo nekoliko važnih napomena o Python-ovom shvatanju i upotrebi telefonski poziva:

  1. Python ima svoju sopstvenu ideju o uparivanju inicijacije poziva i prekidanju. Na primer, ako ukucamo telefonski broj i pokrenemo telefonski poziv ručno, a onda pozovemo hang_up(), dobijamo sledeću grešku:

    Traceback (most recent call last):
      File "<console>", line 1, in <module>
      File "c:\resource\python25\python25.zip\telephone.py", line 60, in hang_up
        _phone_answer.hang_up()
    RuntimeError: no call to hang up


    Iako je telefonski poziv u toku, Python nije započeo poziv, pa ga ne može ni prekinuti.

  2. Slično tome, ukoliko pokrenemo telefonski poziv pozivom funkcije dial(), moramo koristiti hang_up() pre narednog poziva, čak iako prekinemo ručno. Recimo da uradimo sledeću stvar:

    >>> telephone.dial("5551234")
    >>> # ...now we hang up the phone manually
    >>> telephone.dial("5551234")
    Traceback (most recent call last):
      File "<console>", line 1, in <module>
      File "c:\resource\python25\python25.zip\telephone.py", line 53, in dial
        _phone.dial()
    RuntimeError: call in progress, hang up first

 

7.2.2. Primanje telefonskog poziva (javljanje)

Druga jednostavna operacija koju ljudi rade jeste javljanje na telefon. Modul telephone ovo olakšava pozivom metode answer(). Kao što je javljanje na telefon kada nema telefonkog poziva pomalo suludo, jednostavno pozvati answer() je takođe besmisleno ukoliko zaista ne primamo poziv. Da bismo se propisno javili na poziv, telefon mora biti pripremljen ili konfigurisan da to uradi, a onda mora biti sposoban da prepozna kada stiže poziv.


Da bismo pripremili telefon, telephone modul obezbeđuje incoming_call() metod. Pozivanje ove funkcije 'namešta' telefon za prihvatanje poziva. Poziv ovoj metodi se vraća trenutno, ali Python runtime sistem sada osluškuje u potrazi za pristižućim pozivom. Kada poziv stigne, na njega se može javiti pozivanjem answer() metoda. Postoji nekoliko načina da nateramo našu aplikaciju da pozove answer() metod: na primer kao odgovor na korisnikov pritisak na taster unutar interfejsa korisničke aplikacije; ili kao reakciju na promenu stanja telefona (o tome će biti reči kasnije).


Javljanje na telefonski poziv zahteva samo spajanje dve strane poziva. Nakon toga nema više interakcija između aplikacija.

 

 

7.2.3. Praćenje (monitoring) aktivnosti telefona

Modul telephone obezbeđuje način za praćenje aktivnosti telefona. Modul identifikuje 12 stanja u kojima telefonska linija može biti, kao što je prikazano u sledećoj tabeli (Tabela 9 ):

 

 

Tabela 9 – Stanja telefonske linije

 

Python ime

Vrednost stanja

Opis

EStatusUnknown

0

Stanje pozivanja je nepoznato

EStatusIdle

1

Nema aktivnih poziva

EStatusDialling

2

Na telefonskoj liniji se događa pozivanje

EStatusRinging

3

Telefon zvoni

EStatusAnswering

4

Na telefon se javlja

EStatusConnecting

5

Telefonski poziv se spaja na remote phone

EStatusConnected

6

Telefonski poziv je spojen na remote phone

EStatusReconnectPending

7

Nešto je izazvalo gubitak kanala i poziv se ponovo uspostavlja

EStatusDisconnecting

8

Telefonski poziv se prekida

EStatusHold

9

Trenutni poziv je na čekanju

EStatusTransferring

10

Trenutni poziv se prebacuje

EStatusTransferAlerting

11

remote phone se upozorava da se poziv prebacuje

 

Modul telephone omogućuje da stanje bude praćeno preko callback function-je. Aplikacija mora specifikovati (odrediti) i registrovati funkciju koju operativni sistem treba da pozove svaki put kada telefon promeni stanje između gore navedenih stanja.


Pogledajmo primer. Funkcija ispisuje novo stanje kad god se stanje promeni.

 

import telephone
def newphonestate (stateInformation):
    newState = stateInformation[0]
    if newState == telephone.EStatusUnknown:
        msg = "The new state is unknown"
    elif newState == telephone.EStatusIdle:
        msg = "The phone is idle"
    elif newState == telephone.EStatusDialling:
        msg = "The phone is dialling"
    elif newState == telephone.EStatusRinging:
        msg = "The new phone is ringing, call is from %s" % stateInformation[1]
    elif newState == telephone.EStatusAnswering:
        msg = "A call is being answered"
    elif newState == telephone.EStatusConnecting:
        msg = "A call is connecting"
    elif newState == telephone.EStatusConnected:
        msg = "A call has been connected"
    elif newState == telephone.EStatusReconnectPending:
        msg = "The channel has been lost and a reconnect is being attempted"
    elif newState == telephone.EStatusDisconnecting:
        msg = "A call is being disconnected"
    elif newState == telephone.EStatusHold:
        msg = "A call is being placed on hold"
    elif newState == telephone.EStatusTransferring:
        msg = "A call is being transferred"
    elif newState == telephone.EStatusTransferAlerting:
        msg = "The phone is alerting the remote phone about a transferred call"
 
    print "The phone has changed states."
    print "   ",msg
 
telephone.call_state(newphonestate)

 

Na nekoliko stvari treba obratiti pažnju u ovom primeru.

 

 

Izlaz gore navedenog koda je prikazan ispod za poziv koji je upućen telefonu, prihvaćen od strane korisnika telefona i prekinut od strane pozivatelja:

 

The phone has changed states.
    The new phone is ringing, call is from 15055551234
The phone has changed states.
    A call is being answered
The phone has changed states.
    A call has been connected
The phone has changed states.
    A call is being disconnected
The phone has changed states.
    The phone is idle

 

 

7.2.4. Primer aplikacije: Informacije o pozivatelju

Pogledajmo primer telefonskog interfejsa.


Recimo da osoba koja se bavi prodajom čuva beleške o svojim klijentima u bazi podataka kontakata na svom telefonu. Ta osoba smatra da bi bilo korisno da se te informacije automatski izvuku kada je klijent pozove na telefon (Slika 22).

 

 

Slika 22 – Screenshot primera prodavca sa informacijama o klijentu

 

PythonOnSymbian_Screenshot0008-2.jpg

 

Ova aplikacija se izvršava u pozadini i izbaci informacioni prozor kada nađe informacije. Aplikaciju možemo staviti u pozadinu tako što je pokrenemo, pa onda pritisnemo taster aplikacije da prikažemo ikonu aplikacije. Aplikacija nastavlja da se izvršava u Python runtime enviroment dopuštajući nam interakciju sa drugim aplikacijama.


Ovaj primer možemo prilično lako implementirati. Zapravo, naredni kod ima više pretrage kontakata nego obrade poziva.

 

import telephone, contacts
import appuifw, e32, graphics, topwindow
 
#-----------------------------------------------------------------------
#  Ova funkcija se poziva kada se obavi pozivanje. Ona pretraži kontakte i #prikaz da 'info' prozoru
#-----------------------------------------------------------------------
 
def displayNotes(infoTuple):
 
    # Pribavi stanje telefona
    phoneState = infoTuple[0]
 
    # Reaguj samo kada telefon zvoni
    if phoneState == telephone.EStatusRinging:
 
        # Počni otvaranjem baze podataka kontakata i traženjem broja telefona
        db = contacts.open()
        contactList = db.find(infoTuple[1])
 
        # Izgradi listu 'notes'-a u obliku string-a, odvojenih pomoću "\n"
        if contactList:
            try:
                noteString = '\n'.join(note.value for note in contactList[0].find(type='note'))
            except:
                noteString = u"No notes available"
        else:
            noteString = u"The phone number was not found"
 
        # Sada izgrađujemo 'topwindow' prozor od 'notes'-a
        notes = noteString.split("\n")
        window = topwindow.TopWindow()
        window.size = (350, 40+(30*len(notes)))
        window.position = (10, 40)
        img = graphics.Image.new((310, 30*len(notes)))
        img.clear(0x99CCFF)
        position = 20
        for note in notes:
            img.text((20, position), unicode(note), font = 'title')
            position += 30
        window.add_image(img, (20, 20))
        window.background_color = 0xDDDDDD
        window.shadow = 4
        window.corner_type = 'corner5'
 
        # Prikaži prozor i čekaj 5 sekundi. Onda ga sakrij.
        window.show()
        e32.ao_sleep(5)
        window.hide()
 
# Konačno, instaliraj funkciju kao callback telefona
 
telephone.call_state(displayNotes)

 

Pogledajmo ovaj kod u delovima. Import izjava otkriva šta nam je potrebno da bi ova zamisao funkcionisala:

 

import telephone, contacts
import appuifw, e32, graphics, topwindow

 

Glavni deo koda je implementiran u funkciji displayNotes(), koja je callback za sistem kada se stanje promeni. Kao što smo primetili u prethodnom poglavlju, ova funkcija je definisana sa parametrom, nazvanim infoTuple ovde, koji ima informaciju o pozivu. Prvo što moramo da uradimo jeste da izvučemo stanje telefona:

 

# Pribavi stanje telefona
phoneState = infoTuple[0]

 

Želimo raditi nešto samo kada telefon zvoni, pa je stoga ovo jedino stanje na koje funkcija reaguje:

 

# Reaguj samo kada telefon zvoni
if phoneState == telephone.EStatusRinging:
...

 

Kod nastavlja sa otvaranjem baze podataka kontakata i traži kontakt koristeći broj telefona u infoTuple promenljivoj:

 

# Počni otvaranjem baze podataka kontakata i traženjem broja telefona
db = contacts.open()
contactList = db.find(infoTuple[1])

 

Ostatak displayNotes() funkcije pribavlja beleške o kontaktu, potom gradi TopWindow prozor da to prikaže. Ovaj kod možete sami ispitati.

 

Kod konačno registruje displayNotes() funkciju kao callback za telefonske pozive:

 

# Konačno, instaliraj funkciju kao callback telefona
telephone.call_state(displayNotes)

 

 

7.3. Operacije sa porukama

Kao i operacije sa telefonijom, operacije rukovanja sa SMS i MMS porukama su jednostavne. Možemo slati poruke; možemo ih primati; i možemo ih skladištiti. Svaka od ovih operacije se rukuje kroz Python modul.

 

 

7.3.1. Slanje SMS poruka

Modul messaging rukuje slanjem SMS poruka. Metod koji se koristi za slanje SMS poruke u messaging modulu je sms_send() metod, čiji je format prikazan ispod:

 

sms_send(<number>, <message>,[<encoding>, <callback>, <name>])

 

Parametri su sledeći:

 

Poruka može biti u jednom od devet stanja, od 'kreirana' do 'poslata'. Modul messaging ima konstante koje predstavljaju svako stanje, kao što je prikazano u sledećoj tabeli (Tabela 10 ):

 

 

Tabela 10 – Konstante koje predstavljaju moguća stanja poruke

 

Python ime

Vrednost stanja

Opis

ECreated

0

Poruka je kreirana

EMovedToOutBox

1

Poruka je premeštena u Outbox

EScheduledForSend

2

Poruka čeka da je telefon pošalje

ESent

3

Poruka je poslata

EDeleted

4

Poruka je izbrisana iz Outbox-a

EScheduleFailed

5

Poruka ne može biti 'zakazana' za slanje

ESendFailed

6

Poruka ne može biti poslata

ENoServiceCentre

7

Stanje za poruku u emulatoru telefona, pokazuje da servis nije moguć

EFatalServerError

8

Poruka je naišla na grešku od strane telefonovog servisa grešaka poruka

 

Veze između ovih stanja se prikazane na sledećem grafikonu (Grafik 4):

 

 

Grafik 4 – Veze između različitih stanja poruke

 

PythonOnSymbian_PythonOnSymbian_Figure6-2.png

 

Linije grafikona prikazuju putanje promena stanja za poruke. Na primer, poruka bi mogla biti kreirana, premeštena u Outbox, 'zakazano' joj je slanje, onda je poslata. Poruka bi takođe mogla biti kreirana, premeštena u Outbox, 'zakazano' joj je slanje i onda je izbrisana.

 

Pogledajmo ovaj primer slanja poruke. Kao i sa primerom telefoniranja, naš callback jednostavno ispiše string koji prikazuje stanja naše poruke kako se menjaju od kreiranja do slanja.

 

import messaging
def newmessagestate (newState):
    if newState == messaging.ECreated:
        msg = "A message has been created"
    elif newState == messaging.EMovedToOutBox:
        msg = "The message has been moved to the Outbox"
    elif newState == messaging.EScheduledForSend:
        msg = "The message has been scheduled for sending"
    elif newState == messaging.ESent:
        msg = "The message has been sent"
    elif newState == messaging.EDeleted:
        msg = "The message has been deleted"
    elif newState == messaging.EScheduleFailed:
        msg = "The message scheduling has failed"
    elif newState == messaging.EStatusConnected:
        msg = "Attempts to send the message have failed"
    elif newState == messaging.ENoServiceCentre:
        msg = "You are using an emulator; you cannot send from the emulator"
    elif newState == messaging.EFatalServerError:
        msg = "A fatal error has occured with the messaging system"
 
    print "The message has changed states."
    print "   ",msg
 
messaging.sms_send("15055551234", "This is a text message for testing state changes", callback=newmessagestate)

 

Koristeći ovaj kod sa pravim brojem telefona (pravi primatelj) dobili bismo sledeći izlaz:

 

The message has changed states.
    A message has been created
The message has changed states.
    The message has been moved to the Outbox
The message has changed states.
    The message has been scheduled for sending
The message has changed states.
    The message has been sent
The message has changed states.
    The message has been deleted

 

Treba primetiti nekoliko stvari o proceduri slanja i sms_send() metodi:

 

 

7.3.2. Slanje MMS poruka

MMS poruke su slične SMS porukama. Sadrže kratko tekstualno telo, ali takođe mogu sadržati priloge. U pitanju su medijski prilozi poput slika, videa, zvučnih fajlova i sl.


Slanje MMS poruke sa Python-om nije ni približno detaljno ili informativno kao slanje SMS poruka. Modul messaging podržava MMS poruke kroz jedan medot, mms_send(), koji ima sledeći format:

 

mms_send(<number>, <message>, [<attachment>])

 

Parametri su vrlo slični onima za sms_send(). <number> je telefonski broj primaoca. <message> je string čija je vrednost poruka za slanje. Opcioni <attachment> je putanja u telefonskom fajl sistemu za fajl koji treba biti priložen poruci.
Na primer, želimo poslati prijatelju svoju sliku. Fotografisali bismo se našim telefonom, a onda to poslali koristeći sledeći poziv:

 

messaging.mms_send("15055554321", "Here is picture of me.  Aren't I beautiful?", "E:\Images\12262008038.jpg")

 

Metod mms_send() dozvoljava samo jedan prilog.

 

 

7.3.3. Inbox modul

Modul inbox podržava rukovanje mailbox-om (skladištem poruka) u Symbian-u. U konfuznoj igri imena, inbox modul definiše Inbox klasu koja predstavlja direktorijum u Symbian-ovom skladištu poruka. Zbunjujuće je zato što Inbox objekat (instanca Inbox klase) može ispitati sadržaj Outbox-a, foldera Sent i Drafts, kao i sadržaj Inbox-a.

 

Objekti kreirani iz Inbox klase mogu ispitati sva četiri foldera skladišta poruka (Tabela 11 ):

 

 

Tabela 11 – Direktorijumi skladišta poruka

 

Python ime

Opis

EInbox

Inbox folder na Symbian OS-u

EOutbox

Outbox folder na Symbian OS-u

ESent

Folder poslatih poruka

EDraft

Folder poruka u nacrtima

 

Inbox objekat se kreira ovako:

 

inbox = Inbox([<foldertype>])

 

Ovde je <foldertype> jedno od imena iz gornje tabele. Ukoliko nije određen, koristi se Einbox.

 

Nakon što kreiramo Inbox objekat, možemo dobiti listu SMS poruka korištenjem sms_messages() metoda. Ovo vraća listu ID-ja poruka u obliku integer-a. Ovaj kod ispisuje broj SMS poruka u našem Inbox-u:

 

import inbox
box = inbox.Inbox(inbox.EInbox)
messages = box.sms_messages()
print "You have %d SMS messages waiting." % len(messages)

 

Većina preostalih metoda u inbox modulu rade na pojedinačnim porukama, koje se odabiru korištenjem <messageID>.

 

 

U narednom primeru biramo tekstualnu poruku za ispitivanje tako što uzimamo prvi ID poruke u listi poruka.

 

import inbox
box = inbox.Inbox(inbox.EInbox)
messages = box.sms_messages()
id = messages[0]

 

Ispitajmo sada atribute poruke. Primljena je preko Twitter-a i postavio ju je ljubitelj Nokia-e.

 

>>> box.content(id)
u'nokconv: Post: You say business phones need long haul batteries... but do all phones? http://ow.ly/15RMSR'
>>> print time.strftime("Message received on %a, %d %b %Y at %H:%M:%S", time.localtime(box.time(id)))
Message received on Tue, 29 Sep 2009 at 07:43:52
>>> print "Message received from %s" % box.address(id)
Message received from Twitter
>>> print box.unread(id)
1

 

*Napomene: Imam telefonski broj Twitter servisa unešen u moje kontakte pod “Twitter”, pa sistem prijavljuje izvor poruke kao „Twitter“, a ne broj telefona. Takođe, iako smo ispisali sadržaj poruke, poruka ostaje nepročitana. Nepročitani status poruke je svojstvo korisničkog interfejsa.

 

 

7.3.4. Primanje poruka

Klasa Inbox koristi callback funkciju za obradu primljenih poruka. Callback funkcija mora biti registrovana pomoću bind() funkcije, kao što je prikazano ispod.

 

inbox.bind(<function name>)

 

Kada poruka stigne, sistem poziva callback funkciju sa ID-jem poruke kao parametrom. Pogledajmo sledeći primer:

 

import inbox
import time
 
box = inbox.Inbox(inbox.EInbox)
 
def incomingMsg(messageID):
   print messageID
   print time.strftime("Message received on %a, %d %b %Y at %H:%M:%S", time.localtime(box.time(messageID)))
 
box.bind(incomingMsg)

 

Ovaj kod izgleda kao da bi trebao ispisati ID poruke i vreme kada je stigla, lepo formatirano. Međutim, pokreće izuzetak kao što je prikazano ispod:

 

Traceback (most recent call last):
  File "<console>", line 3, in incomingMsg
SymbianError: [Errno -21] KErrAccessDenied

 

Da bismo shvatili gde je problem u ovom kodu, prvo moramo razumeti šta se događa u telefonu. Ugrađena Messaging aplikacija telefona, ona koja prikazuje poruke, se izvršava i takođe je registrovala callback sa operativnim sistemom. Kada izvršimo naš Python kod postoje dva programa koji se nadmeću za isti resurs (skladiše poruka). Messaging aplikacija je dizajnirana da se izvršava brzo i skoro će uvek pristupiti skladištu poruka pre našeg Python koda. Naš kod ne može pristupiti skladištu poruka u isto vreme i stoga nastaje izuzetak.

 

Da bismo rešili stanje trke, možemo dodati poziv time.sleep(). Ovo pauzira kod dovoljno dugo da messaging aplikacija oslobodi pristup skladištu poruka. Naš primer sada izgleda ovako:

 

import inbox
import time
 
box = inbox.Inbox(inbox.EInbox)
 
def incomingMsg(messageID):
   time.sleep(5)
   print messageID
   print time.strftime("Message received on %a, %d %b %Y at %H:%M:%S", time.localtime(box.time(messageID)))
 
box.bind(incomingMsg)

 

Rezultat ovog koda izgleda ovako:

 

1051799
Message received on Tue, 06 Oct 2009 at 15:58:52

 

Navedeni kod radi u veći slučajeva, ali nije garantovano da radi uvek. Najbolje rešenje je pokušati pristupiti skladištu poruka određeni broj puta i uhvatiti izuzetak kao način za brojanje koliko puta pristup nije uspeo. Pogledajmo sledeći kod:

 

import inbox
import time
 
box = inbox.Inbox(inbox.EInbox)
 
def incomingMsg(messageID):
   print messageID  
   for times in range(10):
      try:
         print time.strftime("Message received on %a, %d %b %Y at %H:%M:%S", time.localtime(box.time(messageID)))
         break
      except:
         pass
 
box.bind(incomingMsg)

 

 

7.3.5. Primer aplikacije: SMS Autoreply (automatski odgovor)

Pogledajmo veći primer. Evo aplikacije koja automatski odgovara dolaznoj SMS poruci sa odgovarajućom porukom, koja je formatirana sa imenom pošiljaoca koja naznačuje da ćemo poslati odgovor. Ovo radimo samo ako možemo pronaći ime pošiljaoca; ne želimo da naša poruka odgovora izgleda neuredno, a biće tako ako upotrebimo telefonski broj kao ime.

 

Pogledajmo navedeni kod kao verziju 1.:

 

import messaging, inbox, time
 
box = inbox.Inbox(inbox.EInbox)
 
def autoreply(messageID):
    time.sleep(5)
    sender = box.address(messageID)
    text = box.content(messageID)
    if not any(c.isdigit() for c in sender):
        reply = sender + \
            ", I am not able to read your message at this time." + \
            "  I will respond soon."
        print 'Sending "'+reply+'" to '+sender
        messaging.sms_send(sender, reply)
 
box.bind(autoreply)

 

Ovaj kod koristi funkciju isdigit() da odredi da li je bilo koji od karaktera od sender cifra. Istina, ovo je vrlo „krut“ način da utvrdimo da li je sender (telefonski) broj.
Kada pokrenemo ovaj kod i onda primimo tekstualnu poruku, izlaz izgleda ovako:

 

Sending "Joe Smith, I am not able to read your message at this time.  I will respond soon." to Joe Smith

 

Međutim, poruka nije poslata. Zapravo, kada pogledamo u Outbox, vidimo (Slika 23):

 

 

Slika 23 – Poruka u Outbox-u

 

PythonOnSymbian_Figure6-3.jpg

 

I kada premestimo poruku u Drafts folder i pokušamo da je uredimo, dobijamo sledeću grešku (Slika 24):

 

 

Slika 24 – Greška pri premeštanju poruke

 

PythonOnSymbian_Figure6-4.jpg

 

Dobijamo ovu grešku jer je:

  1. telefon „filtrirao“ poruku kroz naše kontakte, što nam je dalo ime („Joe Smith“) umesto telefonskog broja kao izvora poruke i
  2. onda smo pokušali da pošaljemo poruku „Joe Smith“-u umesto telefonskom broju.

Da bismo ispravili ovo, moramo pribaviti telefonski broj kontakta iz baze podataka kontakata. Pogledajmo sledeći kod:

 

import messaging, inbox, time, contacts
 
box = inbox.Inbox(inbox.EInbox)
 
def autoreply(messageID):
    time.sleep(5)
    sender = box.address(messageID)
    text = box.content(messageID)
    if not any(c.isdigit() for c in sender):
        db = contacts.open()
        firstName = sender.split(" ")[0]
        lastName = sender.split(" ")[1]
        contactList = db.find(firstName)
        for contact in contactList:
            if contact.find("last_name")[0].value == lastName:
                phoneNumber = contact.find('phone_number')[0].value
                reply = sender + \
                        ", I am not able to read your message at this time." + " I will respond soon."
                print 'Sending "'+reply+'" to '+phoneNumber
                messaging.sms_send(phoneNumber, reply)
                break
 
box.bind(autoreply)

 

Pogledajmo autoreply() funkciju. Prvi deo funkcije je isti: „spavamo“ 5 sekundi i onda izvlačimo pošiljaoca i tekst iz poruke. Ukoliko nema cifara u string-u pošiljaoca, počinjemo da obrađujemo poruku.


Ovaj deo koda otvara bazu podataka kontakata, pronalazi ime i prezime i pronalazi sve kontakte u bazi podataka sa imenom koje smo izvukli:

 

db = contacts.open()
firstName = sender.split(" ")[0]
lastName = sender.split(" ")[1]
contactList = db.find(firstName)

 

Zagarantovano je da će kontakt biti u bazi podataka jer je telefon već vratio ime ovoj funkciji umesto telefonskog broja. Već je pregledao bazu podataka kontakata i pronašao odgovarajući kontakt.


Međutim, moglo bi biti više kontakata sa istim imenom. Stoga ih moramo sve pregledati u potrazi za odgovarajućim prezimenom:

 

for contact in contactList:
    if contact.find("last_name")[0].value == lastName:

 

Ostaje još samo da se izvuče telefonski broj i da se pošalje poruka:

 

phoneNumber = contact.find('phone_number')[0].value
reply = sender + \
        ", I am not able to read your message at this time." + \
        "  I will respond soon."
print 'Sending "'+reply+'" to '+phoneNumber
messaging.sms_send(phoneNumber, reply)
break

 

Ovaj kod ispravno šalje poruku.

 

 

7.3.6. Pristup i upotreba log-ova (LOG = ZAPIS)

Svi S60 uređaju čuvaju zapise telefonskih poziva i aktivnosti sa porukama. Ovi zapisi su dostupni preko logs Python modula.


Stavke zapisa se gledaju kao dictionary-ji u Python-u. Na primer, zapis telefonskog poziva (kako izgleda u Python-u) je prikazan ispod. Zbog velike količine podataka koja se prikupi po zapisu, ovaj tip prezentacije može biti zbunjujuć, pa su podaci razdvojeni u key/value parove, po jedan u svakom redu. Primetimo da su vrednosti string predstavljene sa Unicode kodiranjem.

 

{
'status': u'No delivery',
'direction': u'Incoming',
'description': u'Voice call',
'duration type': 1,
'number': u'1616xxxxxxx',
'name': u'',
'contact': -1,
'flags': 0,
'time': 1254283601.7287519,
'duration': 80,
'link': 0,
'data': '',
'id': 8500,
'subject': u'6'
}

 

Evo objekta dictionary koji prikazuje zapis tekstualne poruke. Svaki key je opisan u tabeli ispod (Tabela 12 ).

 

{
'status': u'Delivered',
'direction': u'Incoming',
'description': u'Short message',
'duration type': -1,
'number': u'40404',
'name': u'',
'contact': -1,
'flags': 0,
'time': 1254333004.285248,
'duration': 0,
'link': 0,
'data': '\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00',
'id': 8576,
'subject': u'AAS: Ovi Developer Day  http://bit.ly/ImAiO'
}

 

 

Tabela 12 – Opis key-ova

 

Python ime

Opis

status

Kratak opis događaja

direction

Smer: ili „Incoming“ – dolazni ili „Outgoing“ – odlazni

description

Duži opis događaja

duration type

Opis tipa događaja, poput događaja podataka ili događaja telefona

number

Broj telefona uređaja koji je povezan sa događajem

name

Ime koje je povezano sa događajem

contact

ID broj kontakta povezanim sa događajem

flags

Indikacija šta je izazvalo događaj: npr. korisnik je pogledao da li ima propušteni poziv

time

Vreme, u standardnoj notaciji, kada se događaj dogodio

duration

Broj sekundi koliko je događaj trajao

link

Validan ukoliko je događaj bio povezan sa drugom aplikacijom

data

Podaci povezani sa događajem (npr. tekst poruke)

id

ID događaja u bazi podataka zapisa (log-ova)

subject

Tema događaja, npr. tekst poruke

 

Zapisi se čuvaju za nekoliko različitih tipova komunikacijskih događaja. Ovi tipovi su: call, sms, data, fax, email i scheduler. Ovi tipovi su jasni i ne zahtevaju posebna objašnjenja.

 

Metode u logs modulu su poprilični direktne. Možemo pribaviti sve podatke zapisa, podatke zapise određenog tipa ili podatke zapisa određenog tipa u određenom vremenskom okviru. Kada pribavljamo zapise, možemo filtrirati zapise pomoću mode-a, opisnika svake poruke. Mode specifikatori mogu biti in, out, fetched, missed, in_alt i out_alt. Ukoliko se ne naznači, mode zauzima default vrednost in.


Metode logs modula su sledeće. Podaci zapisa se vraćaju kao lista dictionary objekata.

 

 

Ovi pozivi pribavljaju određene tipove zapisa – koji su jasni sami po sebi – sa jednakim opcionim parametrima. Možemo odrediti početnu tačku pribavljanja, broj (količinski) zapisa za pribavljanje i mode zapisa koji treba pribaviti.


Evo nekoliko primera. Ako želimo da izbrojimo pozive koje smo propustili u poslednja 24 sata, možemo izvršiti sledeći kod:

 

import logs
 
missed = logs.log_data_by_time('call', time.time()-86400, time.time(), 'missed')
print 'You missed ' + str(len(missed)) + ' calls.'

 

Ukoliko želimo prikazati pošiljaoce zadnjih 10 primljenih poruka, izvršavamo ovaj kod:

 

import logs
 
for msg in logs.sms(num_of_logs=10):
   print msg['number']

 

Važno je napomenuti da ovaj kod ispisuje najnovijih 10 primljenih poruka, a ne prvih 10 primljenih poruka.

 

 

PyS60