Inspirated

 
 

May 12, 2009

SMS Inbox statistics for Series 60 mobile phones v0.2

Filed under: Blog — krkhan @ 7:04 pm

Update: New version

Improvements in the new version:

  • Previous version hung up while calculating the statistics. The new version dispatches a thread for the dirty work and keeps the user interface responsive with a “Processing” notification.
  • Contact stats are sorted in descending order by the number of messages per each contact.
  • Code improvements for making it more “Pythonic”.

inboxstats.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# -*- coding: utf-8 -*-
"""Script for printing trivial statistics about inbox, such as:
	Number of texts
	Number of unique contacts who sent the texts
	Number of texts sent by respective contacts
"""
 
__author__ = "Kamran Riaz Khan"
__email__ = "krkhan@inspirated.com"
__version__ = "0.2"
__copyright__ = "Copyright (c) 2009 Kamran Riaz Khan"
__license__ = "Python"
__status__ = "Production"
 
import appuifw, e32, inbox, thread
 
def exit_key_handler():
	"Release app_lock."
	app_lock.signal()
 
def parse_inbox_stats(stats):
	"""Parse the inbox statistics,
	Updates the stats dictionary with:
		sms-count : Number of texts
		sms-contacts: List of tuples with following pairs:
			Name of contact, Number of corresponding
			(ordered according to decreasing number of texts)"""
	curr_inbox = inbox.Inbox()
	messages = curr_inbox.sms_messages()
	contacts = {}
 
	for i in messages:
		address = curr_inbox.address(i)
		if contacts.has_key(address):
			contacts[address] = contacts[address] + 1
		else:
			contacts[address] = 1
 
	contacts = contacts.items()
	contacts.sort(lambda x, y: cmp(x[1], y[1]))
	contacts.reverse()
 
	stats["sms-count"] = len(messages)
	stats["sms-contacts"] = contacts
 
def print_inbox_stats(content, stats):
	"""Print inbox stats in the content Text field,
	Remembers the cursor position of Text before the call
	and points at it again after updating the content."""
	pos = content.get_pos()
 
	statsmap = [
		(u"SMS Count", unicode(stats["sms-count"])),
		(u"Unique Contacts", unicode(len(stats["sms-contacts"]))),
		(u"", u"")
		]
 
	statsmap += [(k, unicode(v)) for k, v in stats["sms-contacts"]]
 
	for i in statsmap:
		content.style = appuifw.STYLE_BOLD
		content.add(i[0] + (i[0] and u": " or u""))
		content.style = 0
		content.add(i[1] + u"n")
 
	content.set_pos(pos)
 
if __name__ == "__main__":
	content = appuifw.Text()
	appuifw.app.title = u'Inbox Stats'
	appuifw.app.body = content
	appuifw.app.exit_key_handler = exit_key_handler
 
	stats = {}
	t = thread.start_new_thread(parse_inbox_stats, (stats,))
 
	content.style = appuifw.STYLE_ITALIC
	content.add(u"Processing text messages...n")
	thread.ao_waittid(t)
	content.add(u"Done!nn")
	content.style = 0
 
	print_inbox_stats(content, stats)
 
	app_lock = e32.Ao_lock()
	app_lock.wait()

Inbox Stats v0.2 Screenshot

Tags: , , , , , , , , , , ,

May 10, 2009

SMS Inbox statistics for Series 60 mobile phones

Filed under: Blog — krkhan @ 8:03 pm

Update: New version

Self-indulgence is what I do best. It usually results in me trying to figure out random statistics about my personal life; e.g., graphs about which hours of day I’m mostly awake on and pie-charts about my bathroom habits. Such stuff doesn’t only make me feel more important than I actually am, but also polishes my fundamental math skills which were lost while trying to calculate average number of viruses a Windows user is hit by on an yearly basis.

Texting is what I do second best. Combine the two of my most productive practices and the need emerges of having a way to produce useless statistics about my cell phone’s inbox. This is where PyS60 comes to the rescue. In my previous post I praised Python’s s** appeal. Here’s the demonstration:

  • Total time spent with Python: Less than a week
  • Total time spent with PyS60: Less than a minute
  • Total time spent with Symbian development: Less than never

And still, even a total n00b like me could easily accomplish what he wanted to, using only the library reference manual and 70 lines of understandable code:

inboxstats.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
"""Script for printing trivial statistics about inbox, such as:
	Number of texts
	Number of unique contacts who sent the texts
	Number of texts sent by respective contacts
"""
 
__author__ = "Kamran Riaz Khan <krkhan@inspirated.com>"
__version__ = "$Revision: 0.1 $"
__date__ = "$Date: 2009/05/10 15:30:00 $"
__copyright__ = "Copyright (c) 2009 Kamran Riaz Khan"
__license__ = "Python"
 
import appuifw
import e32
import inbox
 
def exit_key_handler():
	"Release app_lock."
	app_lock.signal()
 
def inbox_stats():
	"""Parse the inbox statistics,
	Returns the dictionary:
		sms-count : Number of texts
		sms-contacts: Dictionary with the pairs:
			contact-name : Number of texts from contact"""
	cur_inbox = inbox.Inbox()
	messages = cur_inbox.sms_messages()
	contacts = {}
 
	for i in messages:
		address = cur_inbox.address(i)
		if contacts.has_key(address):
			contacts[address] = contacts[address] + 1
		else:
			contacts[address] = 1
 
	return {
		"sms-count" :  len(messages),
		"sms-contacts" :  contacts
		}
 
if __name__ == "__main__":
	content = appuifw.Text()
	appuifw.app.title = u'Inbox Stats'
	appuifw.app.body = content
	appuifw.app.exit_key_handler = exit_key_handler
 
	stats = inbox_stats()
	statsmap = (
		(u"SMS Count", unicode(stats["sms-count"])),
		(u"Unique Contacts", unicode(len(stats["sms-contacts"]))),
		)
 
	for i in statsmap:
		content.style = appuifw.STYLE_BOLD
		content.add(i[0] + u": ")
		content.style = 0
		content.add(i[1] + u"n")
 
	content.add(u"n")
	for k, v in stats["sms-contacts"].iteritems():
		content.style = appuifw.STYLE_BOLD
		content.add(k + u": ")
		content.style = 0
		content.add(unicode(v) + u"n")
 
	app_lock = e32.Ao_lock()
	app_lock.wait()

Which gives me:

Inbox Stats Screenshot

Tags: , , , , , , , , , , ,

May 9, 2009

Python for Series 60: Reinvent the ophidian addiction on mobile phones

Filed under: Blog — krkhan @ 9:31 pm

Remember the good old days when playing Snakes on mobile used to be about the most productive thing you could do in a classroom? Well, those days are back, but this time taking guise of another fun reptilian phenomenon: Python for Series 60. If you need to develop/prototype applications on Series 60 devices while having some real fun, you might find PyS60 to be the best thing Nokia did since 1100.

In past, I have tried demystifying the beast known as Symbian development. Truth be told, I really ended up wishing that I had never attempted to do so in the first place. The whole development process was:

  • Extremely bloated: You need about a supercomputer to crunch out one innocent little SIS file without waiting for eons.
  • Error prone: Put the SDKs in a non-standard path and you’re foobar-ed.
  • Intimidatingly cryptic: For a beginner (and by beginner I mean beginner to Symbian, C++ experience apparently proves to be of no help over here), reading Symbian C++ is more or less like reading Perl. Especially since the humor that has developed over the decades resembling Perl code to line noise doesn’t lose any of its appeal here either.

For example, to create a simple notification which would read “Spam and eggs”, I would need to spend about 8 hours downloading, configuring, compiling, comprehending, troubleshooting the development tools. Further 4 for trying to understand how to accomplish something so simple in Symbian code. Granted, such painful development procedures might be required in some scenarios (e.g., where speed is a factor or where masochistic programmers prevail); in PyS60, producing the notification was as simple as:

Python for S60 on Nokia N72

import appuifw
appuifw.note(u"Spam and eggs", "info")

A mammoth two lines of code which I can easily understand without even referring to a book — I feel so cheap.

Tags: , , , , , ,

March 15, 2009

HOWTO: Use USB devices in Virtual Machine Manager with QEMU

Filed under: Blog — krkhan @ 3:09 pm

Every once a while, I need to take the backup of my Nokia N72 using PC Suite. Since the task had to be performed on Windows, I expected my virtualized machine to be able to do so. Unfortunately, Virtual Machine Manager does not provide any option in its interface which would allow me to use my USB devices in virtualized machines. Going through the documentation though, here’s the method through which I was able to solve my issue.

First of all, you should have the vendor and product ID’s of the USB device you want to use. Sounds alien? Use the command:

[user@host ~]$ lsusb

Which will show you something like:

Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 002: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 003: ID 0421:04c4 Nokia Mobile Phones
Bus 003 Device 002: ID 09da:000a A4 Tech Co., Ltd Port Mouse
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

The bold numbers in the line containing “Nokia Mobile Phones” are the vendor and product IDs respectively. Once you’ve noted them down for your required device (in my case: 0x421 and 0x4c4), list the virtual machines’ configuration files:

[user@host ~]$ sudo ls /etc/libvirt/qemu

networks windoze.xml

My virtual machine was named “windoze”, so windoze.xml is the file that I need to edit:

[user@host ~]$ sudo gedit /etc/libvirt/qemu/windoze.xml

In the editor, add the highlighted hostdev lines under the devices section (replacing the vendor and product IDs with the ones noted down from lsusb output):

<devices>
<emulator>/usr/bin/qemu-kvm</emulator>
<hostdev mode='subsystem' type='usb'>
<source>
<vendor id='0x0421' />
<product id='0x04c4' />
</source>
</hostdev>

Save and close the file. Restart the service:

[user@host ~]$ sudo service libvirtd restart

If everything went smoothly, the USB device should now be accessible from within the virtual machine:

Screenshot of Nokia PC Suite connected to a USB device in virtualized Windows
(Click on the thumbnail for larger version.)

Tags: , , , , , , , , , , , ,

January 30, 2007

ObexFS troubles

Filed under: Blog — krkhan @ 2:26 am

Instances of unmaintained valuable open-source software have been greatly reduced over the last couple of years. Nowadays, good software is quickly forked off if its developers aren’t active anymore, a recent example of which would be the XMMS/Audacious fork.

Nevertheless, one can still find some true gems lying around that are apparently abandoned by their developers because of not generating enough public interest and ObexFS definitely belongs to this category. Its purpose is (or was) to implement a FUSE based file system for browsing OBEX devices (e.g. Nokia cell phones). However, the most recent version of ObexFS (0.10) was released on July 4th, 2006. While trying to use it, I found out that even the basic autotools configuration wasn’t done properly in the tarball, so compiling the program still tried to link to bluetooth libraries even though –disable-bluetooth option was given to the configure script.

I am not an autotools guru myself, so I couldn’t fix the script. The most obvious solution for me was to install the bluetooth libraries. Even worse, there’s no CVS access for obexfs where someone would be able to commit a patch. I just hope that some developer decides soon that it’s now time to fork the whole OpenOBEX project for a more active resource.

Note: If you want to use the ObexFS software, please note that the latest tarballs of ObexFS and ObexFTP are available on the ObexFTP download directory, not the SourceForge repository.

Tags: , , , , , ,
« Previous Page