42

Looking for fun, Feeling groovy…

Category: Tips

Save your staplers!

Picture this. You are at work on a Friday evening. You are all pumped up! Who wouldn’t be. Two full days of zero work ahead! You shutdown your computer, rise up, turn around to leave and BAM! This happens,

The key to ‘Lumberg Evasion‘ is not only to stay ‘hidden’ but also to be aware of your boss’ whereabouts. Information is wealth and can potentially save your weekend.

I wanted to check out Pygame and hacked out a little python script which does this. The idea is that you position your webcam (el-cheapo-no-brand webcams sell for peanuts) near your cubicle/desk and get notified if there is some movement in a predefined area. Also works great if you have a laptop and want to know if someone is peeking over your shoulder (yeah, yeah… I know about mirrors).

The script can detect movements within the red rectangle. Here is how it does this

  • When we start the script, the average color within the red rectangle is determined. This will act as the reference color.
  • Deviations in this average color is monitored in consecutive frames. If its more than a certain threshold, there is some movement.
  • When this happens, play a sound and pop up a little notification

All is well

 

Dad walks in and gets caught

 

Notifications using pynotify

Of course, it goes without saying that its just a simple hack. Works well if the background color is of an uniform color.

[1]: The Source Code: Needs pygame and pynotify (for desktop notifications) to be installed. Very crude. Use at your own risk. The script is released under WTFPL. Its rather simple but should be enough to be a starting point for more evil deeds :D .

P.S: No, I don’t work for an ‘Initech’.

P.P.S: If you are one of those ‘Bill Lumberg’ types, Fuck you!

simplejson’s simple gotcha

I like simple things. Anything more complex more than ‘simple’ is tough to deal with. Therefore it comes as no surprise that I love JSON. Heck, the entire grammar fits in a business card.

If you take a closer look at the spec above, you will notice that the keys for a JSON ‘dictionary’ should be strings. I have a feeling that programmers like me whose language-of-mass-destruction is python are likely to overlook this minor gotcha.

This is where it gets interesting. Python’s json module tries to do something smart when you try to encode a python dictionary into a JSON string. In this case, all the keys are python ints.

In [3]: json.dumps({ 1 : 'Foo', 3: 'Baz'})
Out[3]: '{"1": "Foo", "3": "Baz"}'

When I decode it back to a python object…
In [4]: json.loads(json.dumps({ 1 : 'Foo', 3: 'Baz'}))
Out[4]: {u'1': u'Foo', u'3': u'Baz'}

BAM! The json module silently converts all my integer keys to strings. I, for one, would have preferred an Exception to be raised instead.

Something like this, for example.
In [19]: class F: pass
...
In [20]: f = F()
In [21]: json.loads(json.dumps({ f : 'Foo', 3: 'Baz'}))
... snip errors ...
TypeError: key <__main__.F instance at 0x92b4b2c> is not a string

In this case, I get the desired behaviour where a ‘TypeError’ is raised. Stupid example, but you get the idea.

If I am missing something obvious here please do comment. This particular cheekiness of the json module caught me unawares recently. Or maybe I was wrong in expecting the decode operation to return something that is identical to the source.

Interestingly, the json support modules that ship with TurboGears error out if you try to return a dictionary having non-string keys from your controller methods.

Touring, now a Breeze!

India, is a wonderful place for touring on a motorbike. With terrains ranging from high mountainous North, North Eastern India to the Coastal plains and lush Ghats down South, we sure have a huge load of places to see and experience. Motorbike touring can also be risky since a disproportionate rate of road accidents involve two-wheelers. Therefore it is absolutely necessary for the rider to protect himself on the road with proper riding gears.

The ideal mode of getting riding gear would be to look for clearance sales outside our country and ask the relatives or friends to ship it down to India for us. For people like me, whom the relatives hate to be related to, there are local players like Cramster and DSG who provide gear that are priced competitively. I already have a nice helmet but the lack of a proper armoured touring jacket was preventing me from getting adventurous enough to go out on long road trips.

Requirements

I wanted a jacket that that could satisfy all the following requirements.

  • Should be made of a fabric that doesn’t tear easily protecting me against scraping injuries.
  • Armor in the joints and some padding in the back for protection against hard falls.
  • Since Chennai is not blessed with a good weather, the Jacket shouldn’t boil me alive when I am wearing it. Should be bearable in hot weather atleast when the bike is in motion.
  • Extra brownie points for usability in the rains.

Alpinestars are great but they are simply too expensive for me. DSG distributes them in India in case you have saved enough moola to buy one. Be wary of fake imitation Alpinestars gear that are sold here in Chennai for 5 – 6k. They look genuine but they are, at the end of the day; fake.

Narrowing down the choices:

DSG Maze (Photo from planetdsg.com)

Taking into account all these and reading user posts from xBHP (in addition to rabid googling), I shortlisted DSG Maze and the Cramster Breezer 2.0. Earlier, I had almost decided to order Maze online, but after seeing the Cramster in action during the Vedanthangal xBHP G2G, I noticed that the Cramster Breezer 2.0 qualified  as a worthy competition to the more expensive Maze, both of which met my requirements except for the usability in the rains. Also the presence of Leather shoulders and cuffs in Maze was putting me off. They are damn cool and sexy, but leather doesn’t go well with rain. To add to the confusion of choices, I learnt that Cramster had released a new all black Breezer 3.0 phasing out the 2nd revision.

The presence of a removable waterproof inner liner was the killer feature for me, which was not present in Breezer 2.0 and Maze (Correct me if I am wrong). Finally, I made the decision and took my little FZ on a road trip to Cramster’s Bangalore office yesterday to get the damn jacket. (also some balaclavas for myself and friends). I chose to ride to Bangalore instead of ordering it online since it would give me a chance to test the jacket on my way back ;) (no nagging confusion about choosing the right size as well)

Sorry for the soddy pics.

The back

3M reflectors (the grey lines) are absolutely awesome

Inner lining.

The Jacket is heavy in the hands but fits snuggly when I wear it. I had to wear the inner lining in Bangalore because of  the windchill in the early hours of dawn when I was leaving the city. Once the sun came out, I removed it and all was well. I am quite happy with the finish and the quality of materials that have gone into this jacket. Like most other jackets, it comes with the Cordura fabric that doesn’t tear and 3M reflectors for added visibility to other motorists for spotting you in the dark.

Verdict:

Unfortunately, I have no means to compare it with others and offer a shootout of sorts since I haven’t really tried any other jacket before. I would love to hear from the users of other jackets. If you are not a fan of an all-black jacket, DSG Maze comes in red in addition to the all-black version.

Ride hard and ride safe!

P.S: Thanks to Sudarsan (no, not me) and Pradeep for allowing me to camp at their place for the weekend.

P.P.S: Thanks to my boss for buying my LCD monitor!

24camp – Be there

Last week, 24camp started out as a means for people to get together and work on interesting projects/ideas.

Serendio will be hosting one this weekend, 13th February. We have place for about 20 – 25 in our office premises. More information can be found here.

You can also participate virtually by logging on to #24camp IRC channel on the Freenode servers. If you want to start a local, group of your own add your group in the wiki page mentioned above.

Mashing Twitter and FSO

I really love Twitter and it didn’t make any sense to me to shell out a rupee for every tweet sent through my Airtel Mobile. Moreover, I am on one of those monthly booster packs which allows you to send 22000 text messages for free. I simply had to exploit this by setting up my own little ‘OC’ twitter forwarder written in python. (I know of smstweet.in service but I am still charged 1.50 for every tweet I send)

Its insanely simple to write such a ‘forwarder’ in python using the services provided by the FSO (freesmartphone.org) Framework,

  1. Send messages to your old/unused number whose SIM is in the Freerunner (or any other device supported by the FSO framework)
  2. Handle the incoming messages and use python-twitter API (or) raw urllib2 to post updates. Of course, the device should be connected to the internet, you can tether this device to an old unused computer. Simply put, the Freerunner should be able to access the internet.

I know this is dumb given cheap GPRS and all, but what the heck; Sundays _are_ reserved for dumb things and I wanted to show off how easy it is to develop and conjure up simple but powerful scripts using open hackable hardware like the Freerunner. So take off your pedantic hats ;)

Here is the actual python code,

#!/usr/bin/env python
# Written By Sudharshan S, http://sudharsh.wordpress.com

import dbus
import time
import logging
import twitter

import gobject
from gobject import MainLoop

from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop (set_as_default = True)

# Use OAUTH?
USERNAME = "username"
PASSWORD = "password"

log = logging.getLogger("TweetForwarder")

class TweetForwarder:

   """Process Incoming messages and update twitter status
      if the message startswith 'tweet'
   """

   def __init__(self, username, password):
       log.warning("Starting up....")
       self.twitter_api = twitter.Api(username=username, password=password)

       # Get proxies and add signal handlers
       bus = dbus.SystemBus()
       _usage = bus.get_object("org.freesmartphone.ousaged",
                               "/org/freesmartphone/Usage")
       _proxy = bus.get_object("org.freesmartphone.ogsmd", \
                               "/org/freesmartphone/GSM/Device")
       self.usage_iface = dbus.Interface(_usage, "org.freesmartphone.Usage")
       self.usage_iface.RequestResource('GSM')
       self.sms_iface = dbus.Interface (_proxy, "org.freesmartphone.GSM.SMS")
       self.sms_iface.connect_to_signal ("IncomingMessage", self.onIncomingMessage)

   def onIncomingMessage(self, sender, message, kwargs):
       log.warning("Received SMS from %s:%s" % (sender, message))
       # We don't ALL messages to this number to be tweeted
       if message.strip().startswith("tweet "):
           log.warning("Trying to update status : %s" % message[6:].strip())
           self.twitter_api.PostUpdate(message[6:])
           log.warning("Updated Status")

   def run(self):
       loop = MainLoop()
       loop.run()

if __name__ == "__main__":
    logging.basicConfig()
    server = TweetForwarder(USERNAME, PASSWORD)
    server.run()

Make sure you have python-netclient and python-json installed on your Freerunner. These can be installed using the ‘opkg install’ command.

The script and the accompanying dependency can be downloaded from here. Just change the USERNAME and PASSWORD accordingly after scp’ing the tarball to your device.

Some useful links,

[1]: The FSO API reference

[2]: DBus Tutorial

Konsole monitoring with twitter and python

This happens to me all the time, especially when running programs that takes hours to complete.

  1. Start the code
  2. Go out for some tea or movie.
  3. When you come back, you find that the program had decided to piss you off by crashing 2 seconds after you went away from the keyboard.

The amount of cuss words thrown at the code/program is directly proportional to the silliness of the cause of the crash or error. Even more, if its a typo. Now that twitter allows tweets to be sent to Bharti AirTel (Boohoo others) numbers, and add Python + python-twitter + konsole (Terminal emulator from KDE) to the mix, you can get a very rudimentary notification system which can DM you when konsole activity changes.

To do this, First Enable ‘Monitor for Silence’ in ‘View’ Menu

Then  ‘Settings’ -> ‘Configure Notifications’. In the dialog that pops us, configure the notifications such that it executes a python script. The dialog should look something like this,

dialog

Notifications

The real deal is in the script. It uses the python-twitter module to send a DM from a dummy account to whatever account you want the notifications to go to.

#!/usr/bin/env python

import twitter

username = "dummy_account"
password = "password"

receiver = "sup3rkiddo"

def sendDM():
    try:
        api = twitter.Api(username=username, password=password)
        stats = api.PostDirectMessage(receiver, "*Done compiling*")
    except:
        print "Error!"

if __name__ == '__main__':
    sendDM()

Thats it! Simple but useful ;p (Of course, change the message according your needs)

Nai Sekar, your not-so-friendly translation bot..

SekarRecently I had to make use of Google’s translation engine to translate phrases at work. Given the lazy big bum I am, I found using the Google’s web UI a bit tiresome to use. I thought “heck, why not write a little jabber bot to make things a bit easier..”. (Agreed, writing a bot is nowhere near to the best solution.)

Writing a Jabber bot is incredibly easy with python. You will need the JabberBot package, which offers a really really simple and straightforward way to write bots. The little script below proves how easy it is.

The bot translates phrases/sentences using the python-pygtrans package. I had to name the script *something* and Nai Sekar seemed to be a good idea. Apologies if you just went ‘WTF?!’.  (I am quite lame when it comes to naming code/function/classes)

#
# Released Under WTFPL
# http://sam.zoy.org/wtfpl/
#
from jabberbot import JabberBot
import gtrans
import random

# Gmail uses Jabber, but their TOS doesn't allow automated scripts. So be warned
username = 'yourJabberID@example.com'
password = 'password'

# Just some famous dialogues from Vadivelu comedy tracks. Might not make sense if you
# don't know who or what vadivelu is.
error_dialogues = [
    "Nee yaaru kitta paysikittu irrukaynu theriyuma? Sekar ngara oru TERROR kitta",
    "Saykar settutaan",
    "Tirisa illana Divya",
    "Huh.. yennaku body strong basement weeeku",
    "Naanum rowdy.. naanum rowdy.. naanum rowdy",
    "Shabba... ippovae kannu kattudae",
    "Heloooo.. Ennoda biruther maark irukaara",
    "Don't worry.. Be gaaapy",
    "But andha dealing enaku pudichi irundhuchi",
    "lighta...",
    "Vaynda... Vallikidu.... Azuthuduvane.. Azhuthuduvane",
    "Sing in the raine... I am swoying in the raine..",
    "Helloo.. Prabha wine shop ownerungala? Kadaiya.. yeppo saar tharapeenga?",
    " romba nallavanu enna pathu sollitanmaaaaa..."
]

class NaiSaykarBot(JabberBot):

    def bot_trans(self, msg, args):
       """Translate the phrase/sentence from the source language to the required language
          ex: trans en pl Apples grow in trees
          would translate the above phrase from english to polish
       """
       split = args.split()
       if len(split) == 0:
            return
       src_language = split[0].strip()
       required_language = split[1].strip()
       phrase = ' '.join(split[2:])
       try:
            translated = gtrans.translate(src_language, required_language, phrase)
            return translated
       except gtrans.InvalidLanguage, e:
            print "Invalid args : %s" %(args)
            # Return a random error message
            return random.choic e(error_dialogues)

    # Overridden from JabberBot
    def unknown_command( self, mess, cmd, args):
        print "Unknown Command %s" %(args)
        return random.choice(error_dialogues)

if __name__ == '__main__':
     bot = NaiSaykarBot(username, password)
     bot.serve_forever()

Give your boss the illusion of managing you… with pidgin and dbus

Dilbert.com

Oh yeah!. With the power of DBus and libpurple APIs it is possible to give your boss the illusion of managing you. Just run the following script (under WTFPL). Tested with jabber accounts in a live office environment :P .

#!/usr/bin/env python
# By Sudharshan S, released under WTFPL

import dbus
import gobject
import time

class PointyHairedBoss:

    def __init__(self, boss_id, source, frequency=30):
        self.boss_id = boss_id
        self.source = source
        self.frequency = frequency
        bus = dbus.SessionBus()
        _pidgin_proxy = bus.get_object("im.pidgin.purple.PurpleService", \
                                                       "/im/pidgin/purple/PurpleObject")
        self.purple = dbus.Interface (_pidgin_proxy, "im.pidgin.purple.PurpleService")
        # FIXME:
        account_id = self.purple.PurpleAccountsGetAllActive()[0]
        self.boss_conversation = self.purple.PurpleConversationNew(1, account_id, self.boss_id)
        self.boss_im = self.purple.PurpleConvIm(self.boss_conversation)
        print self.boss_im

    def start_nonsense(self):
        question_list = open(self.source)
        for q in question_list:
            self.purple.PurpleConvImSend(self.boss_im, q)
            time.sleep(self.frequency)

if __name__ == "__main__":
   # Change the jabber id and the path to your questions, with an optional frequency
   o = PointyHairedBoss("foo@gmail.com", "questions")
   o.start_nonsense()

The fat penguin on Sony Vaio CR

As I said in my earlier post, Vista didn’t last long. I was planning to install Gentoo in my Vaio CR 36 but couldnt, as it had problems with the ethernet card ( not to mention the wireless). My option was to install Ubuntu Gutsy as it has very good support for laptops out of the box. But Gutsy couldn’t get sound working and hence found a perfect excuse to upgrade to hardy beta.

24 after upgrading to hardy, came to know that beta_1 of gentoo 2008.0 is out. Downloaded the 64 bit mrinimal iso and got it up and running on my laptop. Things that doesn’t work in both the distros (as of now. May change as I RTFM more)..

  • Fn keys for the brightness controls. I have a brightness applet in my panel, so no real big deal.
  • The Ricoh webcam. lsusb picks up the device and whats more strange; the r5u870 driver gets loaded and the device node ‘/dev/video0′ is getting created properly. Neither cheese nor camorama could pick up the camera. The device id is “05ca:1839″, which seems to be well supported. Maybe I am missing something obvious (yes, the firmware files are in place)
  • The fingerprint reader. Its the same as that of the ones from the Thinkpads but thinkfinger doesn’t support vaios :S
  • Bluetooth, gets detected by hciconfig but other devices can’t see my laptop. (See below)

If anyone had any luck with the above, please let me know.

What works..

  • DRI with the binary ‘fglrx’
  • Sound works well
  • Wireless pwns with the iwl4965 module
  • Ethernet with the realtek modules
  • Software suspend to disk (and RAM) using patches from the TuxOnIce project
  • Volume keys and media keys work like a charm.
  • Adobe doesn’t offer support for flash on amd64. You can getaway with it by installing a 32 bit firefox binary alongside your 64 bit installation. ‘emerge mozilla-firefox-bin netscape-flash’ and you are all set.
  • Bluetooth works beautifully. I have had issues with I/O errors with the chipset. But a post to the gentoo forums solved the issue. This VAIO comes with a Broadcom 2046 chipset. Be sure to ‘emerge bluez-firmware’ just in case. Click here for the thread. Be sure to follow the wonderful gentoo bluetooth guide. emerge gnome-phone-manager and gnome-bluetooth for extra fun

The kernel .config and the xorg.conf with hardware acceleration for my laptop is here, in case if anyone is interested.

Gentoo-wiki has been a great resource. Information about other vaios here.

Add personality to your already powerful firefox

I dunno if it adds functionality to your already functional firefox, but still its damn cute and quite interesting from the technical point of view. Add a new “persona” to your browser on the fly. No crashes bringing down the house although, I am not able to resize the browser. Only a matter of time before someone comes up with a LOLCAT persona..

Heres a cute screenshot

screenshot.png

Get it here .

Follow

Get every new post delivered to your Inbox.