42

Looking for fun, Feeling groovy…

Tag: Python

Cloudcraft: Easy minecraft server management

2013-05-25_00.39.01

 

I started working on Cloudcraft as a toy project over the weekend. It aims to be an end-to-end toolbelt for managing minecraft servers on EC2. As of now it’s very Alpha quality but it can spawn instances and setup minecraft servers automatically with just a couple of commands. For example in the screenshot below, cloudcraft started the minecraft server on a spawned EC2 instance and reported the address needed for a multiplayer game.

 

2. zsh 2013-05-27 00-23-17

 

Autoscaling instances, plugin management, automatic updates are some of the things that are in the pipeline.

The project is on github and as usual, suggestions, bug reports, bug fixes are welcome.

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.

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)

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()

Why Python?

Ever had that feeling of insignificance? The feeling that your very existence is a microscopic peanut in the grand scheme of things. By grand, I mean the Whole Sort of General Mish Mash. I am going through that right now. We are, according to our own theories an extremely smart species, yet for every answer we discover, 10 more questions creep up like one of those annoying LOLCATS shouting ‘OH HAI’. What the hell is the purpose of life? Why do we exist? What is our place in this infinite Cosmos (See the embedded video)? Its incredibly creepy even to think that our entire life is just a mega-complex probability equation, which most likely is too complex for our puny brains to comprehend.

Yeah, so basically what I am coming at is simple. Party now, Life is too short to be spent over unnecessary complications. Or in other words Frigging Use Python!!!!

(Strip from XKCD)

fsod status

Its been a while since I blogged about odeviced. In my earlier posts I had mentioned the possibility of integrating odeviced and others (which do not exist at the moment) into a single daemon for avoiding too much fracture. I have pushed some code that does this, converting odeviced into a Device subsystem that is loaded by a master daemon called fsod. This, of course is very similar to the python implementation (frameworkd) which is pretty awesome at what it does and has become a sort of success story for using DBus as the fudgy layer separating toolkits and the underlying systems which in themselves are tightly coupled.

The current code base is written in vala (and C where it is required) which unfortunately lacks certain features of DBus like async callbacks and some method signatures at the moment (I may be horribly wrong. I would be glad if someone points out in that case. The mailing list discussion on async support here). But at the same time, writing GObject code in vala is infinitely easier and lots of fun too :D .

It would be also be pretty awesome if fsod could support loading python plugins, kind of like what gedit does. The GSM code especially could benefit from this since there is not much to gain in terms of performance here.

As for fsod, the sources are available here. In case anyone wants to get hold of a opk of the current code to install on the Freerunner, it is available here. Comments are welcome

pyjana: yet another lazy afternoon

I havent been a big fan of creating python extensions using gobjects but noticed that the libjana by chris doesnt have one. So just my bit to help around.

Bindings for the above libjana library. Still really really really……..really (500th) super prototype code.

Get the bindings here

As always all sorts of help is appreciated

pygsmd-shell: Shell mode of libgsmd-tool in python

Got some sms and phonebook code in the svn, but not all. So once I had some bindings finished. I decided to write a sort of example script that uses our pygsmd module. libgsmd-tool have always been a friend of mine in knowing whats up with gsmd. Therefore to pay a tribute to my good “friend”, I came up with a python script that mimics ‘libgsmd-tool -m shell’. Of course since pygsmd itself is yet to be completed, the script is incomplete although functional. Its been a long time since I had written a real python script, so if its not pythonic, please comment..The script is already in the svn, so if you are interested take a look and most importantly test it out and extend it..=D

Heres a more sane version(88) from the svn

http://projects.openmoko.org/plugins/scmsvn/viewcvs.php/*checkout*/python-gsmd/examples/pygsmd_shell.py?content-type=text%2Fplain&rev=88&root=python-openmoko

And the screenshot of pygsmd-shell in action. Notice the AT commands in Phonesim to the right. And the screenshot of the script running in the neo.

pygsmd-shell     pygsmd-shell-neo

For pygsmd svn repository, click here

Follow

Get every new post delivered to your Inbox.