Python for S60 Daniel Rocha Forum Nokia Agenda • Introduction to Python for S60 (PyS60) • Getting started with PyS60 • Packages • Installation on a device • Running sample apps • Application development basics • Tools, Emulators, Utilities packages • Creating a stand-alone Python app • PyS60 API Tour and Example apps • Conclusion © 2007 Nokia Slide 2 Company Introduction About Python, the language... • Open Source development since 1990, led by Guido van Rossum • Design goals: maximizing programmer productivity and extensibility • Special emphasis on code readability • “small language, large library” • Easily extensible with native code • Modern, full featured: classes, inheritance, function objects, exceptions, automatic memory management, threads © 2007 Nokia Slide 4 Company Quick code example ## first python script - this is a comment ## >>> Numbers are 10, 30, 40 x = y = z = 0 ## multiple assignment List 3, 5, 7, 10], List[0] is 1, List[0:2] is [1, 3] Is 9 in list? False x = is 10 [1, ##variable attribution Looping: 1 3 5 7 10 y = x + 20 z = y is + x Tuple (10, 20, 30), Typle[0] is 10 Unpacking tuple (10, 20, 30) into: a=10, b=20, c=30 print "Numbers are %s, %s, %s" % (x,y,z) Assoc is {'daniel': 29, 'jack': '80', 'susan': 28}, Assoc['daniel'] is 29, Is assoc?and True ## susan lists,intuples associative arrays >>> list = [1,3,5,7,10] tuple = (10,20,30) assoc = {'daniel': 29, 'susan': 28, 'jack':'80'} print "List is %s, List[0] is %s, List[0:2] is %s" % (list, list[0], list[:2]) print "Is 9 in list?", 9 in list print "Looping:", for x in list: print x, print "Tuple is %s, Typle[0] is %s" % (tuple, tuple[0]) a, b, c = tuple print "Unpacking tuple %s into: a=%s, b=%s, c=%s" % (tuple, a, b, c) print "Assoc is %s, Assoc['daniel'] is %s, Is susan in assoc? %s" % (assoc,assoc['daniel'],'susan' in assoc) © 2007 Nokia Slide 5 Company Python for S60 (PyS60) • Simplifies application development and provides a scripting solution for Symbian C++ APIs • Usable in different ways: • GUI application • background (“daemon”) process • embeddable in your C++ app • Easier way of writing native applications • Open source implementation, easy to extend using Python/C API © 2007 Nokia Slide 6 Company Python for S60 (PyS60) – contd. • Based on Python 2.2.2 • Consists of: • Python runtime: • Python interpreter DLL • Standard and proprietary Python library modules • Python Script Shell: • Execution environment for Python scripts • For S60 prior to 3rd. Edition: • Recognizer plug-in • Automatic Installer • SDK Plug-in for writing extensions and testing scripts on a PC (Windowsonly) © 2007 Nokia Slide 7 Company Python for S60 (PyS60) – Libraries • Support for Python Standard Libraries – not all standard and optional modules but most can be added without modifications to PyS60 • Support of many custom S60 libraries • e32 • contacts • sysinfo • calendar • appuifw • e32db • graphics • E32dbm • camera • keycapture • audio • telephone • inbox • positioning • sensor • messaging © 2007 Nokia Slide 8 Company Getting started with PyS60 Python on S60 Mobile Phones • SourceForge project site: http://sourceforge.net/projects/pys60 • Source code • Docs • Distributed by flavor of S60 • Interpreter • SDK • Script Shell © 2007 Nokia Slide 10 Company What’s available at SourceForge • pyS60 full C++ source code • pyS60 Runtime, distributed by flavor of S60: • PythonForS60_1_4_4_<yourS60version>.SIS for devices • PythonForS60_1_4_4_SDK_<yourS60SDK>.zip for running Python scripts on S60 emulator and compiling your own extensions (Windows-only) • pyS60 Script Shell, distributed by flavor of S60: • Ideal for testing and developing scripts • PythonScriptShell_1_4_4_<yourS60version>.SIS • Also unsigned version, if more capabilities are needed. • Complete API reference guide • Release notes © 2007 Nokia Slide 11 Company Getting started – PyS60 on a mobile device • Install PyS60 Runtime interpreter package. In our example, Nokia E61i is a 3rd. Edition device so we install PythonForS60_1_4_4_3rd .SIS • You can perform installation either via PC Suite (Windows) or by sending the .SIS file via Bluetooth (Mac and Linux) • This is the runtime package, script shell will be installed next © 2007 Nokia Slide 12 Company Getting started – PyS60 on a mobile device • Install PyS60 Script Shell. In our example, Nokia E61i is a 3rd. Edition device so we install PythonScriptShell_1_4_4_ 3rd.SIS • Script shell is useful for quickly running and testing scripts, run interactive consoles • Python app visible in the main application menu © 2007 Nokia Slide 13 Company Getting started – PyS60 on a mobile device • Run script -> Reads from E:\Python and C:\Python • There is an interactive console for on-device editing • Bluetooth console for remote editing of Python scripts • Not required for running Python stand-alone apps! Interpreter and Script shell are not dependent on each other © 2007 Nokia Slide 14 Company Testing PyS60 example scripts • Start the Python Script Shell • Click Options / Run Script • Choose one of the scripts in the list and hit OK © 2007 Nokia Slide 15 Company Application development basics Tools of the trade - Windows • Some version of Python installed and running -> ActivePython (www.activestate.com) comes with Python 2.5.1, PyWin editor and Python shell. • S60 Platform SDKs for Symbian OS, for C++ -> provides PCbased emulation environment for creating and running scripts and Python extensions (www.forum.nokia.com/tools) • Package PythonForS60_1_4_4_SDK_3rdEd.zip for plugging Python into the S60 SDK • Packaging tool for creating .SIS installable files (Ensymble http://www.nbl.fi/~nbl928/ensymble.html) – Py2sis tool comes with the SDK, not usable outside Windows • If using Ensymble, OpenSSL command-line utilities -> http://www.stunnel.org/download/binaries.html • S60 device with optional memory card • Nokia PC Suite – optional but a timesaver © 2007 Nokia Slide 17 Company Basic development cycle - Windows • Create a .py file using PyWin containing valid Python for S60 code • Save it to C:\Symbian\9.1\S60_3rd_ MR\Epoc32\winscw\c\pytho n • Start the S60 SDK Emulator • Click on the Python Script Shell, choose your script from the list • Click “Select” to run it © 2007 Nokia Slide 18 Company Tools of the trade - Linux • Some version of Python installed and running • Emulation environment not available • Packaging tool for creating .SIS installable files (Ensymble - http://www.nbl.fi/~nbl928/ensymble.html) + OpenSSL command line utilities • PyS60-compat – Emulation library for some PyS60 APIs (http://sourceforge.net/projects/pys60-compat/) • S60 device. Having a memory card greatly facilitiates script testing • Bluetooth-enabled workstation © 2007 Nokia Slide 19 Company Basic development cycle - Linux • Create a .py file using any text editor • Send your script to the E:\Python phone using obexftp or connecting the phone as a usb drive • Start Python Script Shell • Choose your script from the list • Click “Select” to run it • No emulator, you have to run your script on the phone, or with PyS60compat © 2007 Nokia Slide 20 Company Creating a Stand-alone Python Application • Easiest: Ensymble • http://www.nbl.fi/~nbl928/ensymble.html • For S60 3rd Edition, PyS60 1.4.0 or later • Linux, Mac, Windows • py2sis with standard PyS60 source distribution • Both tools create a .sis file which can be installed on the phone as a native application, appear in the main menu and have its own C:\dev\python>ensymble_python2.5-0.26.py py2sis simplecube.py icon © 2007 Nokia Slide 21 Company Symbian OS 9.1 Platform Security – affects Python • www.symbiansigned.com • Accessing potentially sensitive features now requires capabilities • • • • • Global key capture Reading the cell ID Reading the (internal) GPS location Setting the system time Protected File Access • Need devcert (w/ Publisher ID) or Open Signed Online • • • • Register with www.symbiansigned.com Register your phone IMEI with the devcert Sign your application with the devcert Install your application on your phone © 2007 Nokia Slide 22 Company PyS60 API Tour and Example apps Application framework basics •Application type can be used to access and modify the UI = appuifw.app • UI elements: • • • • Title Tabs Body (Text, ListBox, Canvas) LSK and RSK • Define handlers for Options menu and Exit key • Wait for user input using an Active Object lock – other threads cannot access UI © 2007 Nokia Slide 24 Company Application framework basics • UI Controls are implemented as Python types: • ListBox • Text • Canvas • Controls are set to the application body (using app.body = control) • Dialogs are implemented as module-level functions • Form is a dialog implemented as a type, due to its versatility • Content_handler object used to open files of given types © 2007 Nokia Slide 25 Company UI framework – Components • Dialogs – notes, query, multi-query, popupmenu, selection list, multi-selection list • Form • Canvas • Menus • Text • Listbox © 2007 Nokia Slide 26 Company UI framework – Components © 2007 Nokia Slide 27 Company Multimedia – audio, video, camera • Multimedia applications can be developed using modules: • Audio – allows playing and recording of audio and text-tospeech functions • Camera – for taking pictures, recording videos, controlling camera aspects and querying camera capabilities • Graphics – Image saving and loading © 2007 Nokia Slide 28 Company Messaging and Inbox – sms • Inbox module is used to read through your message Inbox • Messaging module is for sending SMS and MMS messages © 2007 Nokia Slide 29 Company Messaging and Inbox – sms example Source: sms.py import inbox, appuifw, inbox, messaging box = inbox.Inbox() for sms_id in box.sms_messages()[:5]: msg = box.content(sms_id) appuifw.note(msg) messaging.sms_send("+551185417677", u"Hello Bossa!") © 2007 Nokia Slide 30 Company Connectivity: Bluetooth, TCP, HTTP • Python applications can use standard socket module for communication, via Bluetooth, TCP, etc. • High-level urllib can be used for HTTP and Web commnucations Demo: Tracker © 2007 Nokia Slide 31 Company Connectivity – urllib Source: webclient.py import urllib, appuifw, e32 URL = "http://www.python.org/images/python-logo.gif" dest_file = u"C:\\Data\\Images\\python-logo.gif" urllib.urlretrieve(URL, dest_file) lock = e32.Ao_lock() viewer = appuifw.Content_handler(lock.signal) viewer.open(dest_file) lock.wait() © 2007 Nokia Slide 32 Company Connectivity – bluetooth photo sender Source: bluetooth.py import camera, e32, socket, appuifw PHOTO = u"C:\\Data\\Images\\bt_photo_send.jpg" def send_photo(): try: address, services = socket.bt_obex_discover() except: appuifw.note(u"OBEX Push not available", "error") return if u'OBEX Object Push' in services: channel = services[u'OBEX Object Push'] socket.bt_obex_send_file(address, channel, PHOTO) appuifw.note(u"photo sent", "info") else: appuifw.note(u"OBEX Push not available", "error") © 2007 Nokia Slide 33 Company Many more! Explore the API • Positioning • Location • E32dbm • Telephone • Contacts • Sensor… Demo: Shake your music © 2007 Nokia Slide 34 Company Conclusion • Introduction to the Python Language www.python.org/doc • Examples from http://www.mobilepythonbook.com • http://wiki.forum.nokia.com/index.php/Category:Pytho n • http://wiki.opensource.nokia.com/projects/Python_for_ S60 • http://mobilepythonbook.com/ • http://croozeus.googlepages.com/py60 © 2007 Nokia Slide 35 Company Backup UI framework – Dialog notes and queries Source: notes.py import appuifw, time ##### note appuifw.note(u"Hello!",'info') ## may also take 'error' and 'conf' ##### query name = appuifw.query(u"Type your name:",'text',"Daniel") age = appuifw.query(u"Type your age:",'number') date = appuifw.query(u"Type a date:",'date') code = appuifw.query(u"Type a password:",'code') query = appuifw.query(u"Wanna see your data?",'query') timetuple = time.localtime(date) input = u"You name is: %s, your age is: %s, year is %s, pwd is %s" % (name, age, timetuple[0],code) if query: appuifw.note(input) else: appuifw.note(u"Insensitive clod!",'error') © 2007 Nokia Slide 37 Company UI framework – List dialogs Source: lists.py import appuifw ##### popup fruits = [u"Apple",u"Banana",u"Orange"] index = appuifw.popup_menu(fruits,u"Select a fruit:") if index in range(len(fruits)): appuifw.note(u"You've chosen:" + fruits[index]) ##### selection list phones = [u"Nokia",u"Nokia",u"The ones from Finnish company"] index = appuifw.selection_list(phones,0) if index in range(len(phones)): appuifw.note(u"You've chosen:" + phones[index]) ##### multi selection with search cars = [u"Ferrari",u"Lamborghini",u"McLaren",u"Renault"] selections = appuifw.multi_selection_list(cars,'checkbox',1) ## search field result = "" if len(selections) > 0: for x in selections: result+= cars[x] + "," appuifw.note(u"Your choices:"+result[:-1]) else: appuifw.note(u"You don't like cars") © 2007 Nokia Slide 38 Company Application framework – Basic application example Source: app1.py import appuifw, e32 ##handler for Exit def quit(): appuifw.note(u"Application exiting...") app_lock.signal() ##sets app UI title appuifw.app.exit_key_handler = quit appuifw.app.title = u"Hello!!!" appuifw.note(u"Application has been started...") ##wait for input app_lock = e32.Ao_lock() app_lock.wait() © 2007 Nokia Slide 39 Company UI framework – Menu example Source: menu.py import appuifw, e32 ##menu def menu_choice1(): appuifw.note(u"Choice 1") def menu_choice2(): appuifw.note(u"Choice 2") def menu_choice3(): appuifw.note(u"Choice 3") ## main mymenu = [(u"Choice 1",menu_choice1), (u"Choice 2",menu_choice2), (u"Choice 3",((u"Sub-choice",menu_choice3), (u"Sub-choice1",menu_choice1)))] appuifw.app.menu = mymenu © 2007 Nokia Slide 40 Company UI framework – Text example Source: text.py ##sets Text tx=appuifw.Text() tx.color=(0,0,128) tx.font=u'LatinBold17' tx.style = appuifw.STYLE_BOLD tx.set(u"Text") ## new color and style tx.color=(0,0,0) tx.style = appuifw.STYLE_ITALIC tx.add(u"Italic!") ## new font tx.font = u"albi17b" # tx.add(u"Albi17b text!") appuifw.app.body = tx ## Code for handling exit key omitted © 2007 Nokia Slide 41 Company UI framework – ListBox example Source: listbox.py import appuifw, e32 ##handler for Exit def quit(): appuifw.note(u"Application exiting...") app_lock.signal() ##sets app UI title appuifw.app.exit_key_handler = quit appuifw.app.title = u"Hello!!!" ##callback def lbox_observe(): appuifw.note(u"You have chosen " + entries[listBox.current()][0]) ##sets ListBox icon1 = appuifw.Icon(u'z:\\resource\\apps\\avkon2.mbm', 28, 29) icon2 = appuifw.Icon(u'z:\\resource\\apps\\avkon2.mbm', 40, 41) entries = [(u"Signal", icon1), (u"Battery", icon2)] listBox = appuifw.Listbox(entries, lbox_observe) appuifw.app.body = listBox © 2007 Nokia Slide 42 Company Multimedia framework – audio example Source: audio.py import appuifw, audio, os MENU = [u"Play",u"Record",u"Delete",u"Say!"] SOUNDFILE = u'C:\\Data\\Images\\sound.wav' sound = None while True: index = appuifw.popup_menu(MENU,u"Select operation") if sound: sound.stop() sound = audio.Sound.open(SOUNDFILE) if index == 0: sound.play() sound.close() elif index == 1: sound.record() appuifw.query(u"Press OK to stop",'query') sound.stop() sound.close() elif index == 2: os.remove(SOUNDFILE) © 2007 Nokia Slide 43 Company Multimedia framework – camera example Source: camera.py import e32, camera, appuifw, key_codes def viewfinder(img): canvas.blit(img) def shoot(): camera.stop_finder() photo = camera.take_photo(size = (640, 480)) w, h = canvas.size canvas.blit(photo, target = (0, 0, w, 0.75 * w), scale = 1) photo.save('e:\\Images\\photo.jpg') appuifw.app.body = canvas = appuifw.Canvas() appuifw.app.title = u"Camera" camera.start_finder(viewfinder) canvas.bind(key_codes.EKeySelect, shoot) © 2007 Nokia Slide 44 Company Multimedia framework – camera example Source: video.py import e32, camera, appuifw, key_codes, time def viewfinder(img): canvas.blit(img) def shoot(): camera.start_record("C:\\Data\\Videos\\video.mp4",donothing) appuifw.query(u"Press OK to stop",'query') camera.stop_record() def donothing(a,b): pass canvas = appuifw.Canvas() appuifw.app.body = canvas appuifw.app.title = u"Camera" camera.start_finder(viewfinder) canvas.bind(key_codes.EKeySelect, shoot) © 2007 Nokia Slide 45 Company Messaging and Inbox – sms example Source: sms.py import inbox, appuifw, inbox, messaging box = inbox.Inbox() for sms_id in box.sms_messages()[:5]: msg = box.content(sms_id) appuifw.note(msg) messaging.sms_send("+551185417677", u"Hello Bossa!") © 2007 Nokia Slide 46 Company Connectivity – urllib Source: webclient.py import urllib, appuifw, e32 URL = "http://www.python.org/images/python-logo.gif" dest_file = u"C:\\Data\\Images\\python-logo.gif" urllib.urlretrieve(URL, dest_file) lock = e32.Ao_lock() viewer = appuifw.Content_handler(lock.signal) viewer.open(dest_file) lock.wait() © 2007 Nokia Slide 47 Company Connectivity – bluetooth photo sender Source: bluetooth.py import camera, e32, socket, appuifw PHOTO = u"C:\\Data\\Images\\bt_photo_send.jpg" def send_photo(): try: address, services = socket.bt_obex_discover() except: appuifw.note(u"OBEX Push not available", "error") return if u'OBEX Object Push' in services: channel = services[u'OBEX Object Push'] socket.bt_obex_send_file(address, channel, PHOTO) appuifw.note(u"photo sent", "info") else: appuifw.note(u"OBEX Push not available", "error") © 2007 Nokia Slide 48 Company Thank you! Questions? daniel.rocha@nokia.com