42

Looking for fun, Feeling groovy…

Adios WordPress

After 7 long years of hosting my blog on WordPress, I am migrating all my content to an Octopress based blog on top of Github pages. 

WordPress has been a good home for my blog but its editor has recently turned out to be unintuitive especially when it comes to posting code snippets. I felt I should write more often and the WordPress editor somehow gained the ability to make me rage every time I tried to start writing something new or profound.

I have been punting on the migration for a long time till Srini pointed me to exitwp. The tool worked great except for some encoding issues and custom WordPress tags which I had to clean up.

Migrating the comments to Disqus took some work but it’s all done. I will post my notes on the migration at the new home very soon for people who are at the brink of moving away from WordPress.

To the 3 kind souls who subscribe to my blog’s rss feed, please point your reader to http://sudharsh.me/atom.xml.

Adios wordpress…

Advertisements

Hiccup: Organizing templates using multimethods

There are two major templating libraries for Clojure, Enlive and Hiccup. Since I am not that much of a designer, I chose Hiccup for my side project written in Clojure. I liked the DSL’s unification of code and templating; right in my comfort zone. This post is a little log on how I ended up using multimethods for organizing my Hiccup template functions.

DRY in Jinja

In my previous Flask projects, Jinja was my templating engine of choice. The DRY flow in Jinja templates consists of setting up a base.html with a common layout markup. The ‘children’ would then ‘inherit’ and optionally override those blocks in their own templates.

Composition in Hiccup

However, In the world of Clojure (and therefore Hiccup), functions (duh!) are used to modularize templates.  For example,

(ns foobar.views
  (:require [hiccup.core :as h]
            [hiccup.page :as hp]))

(defn head [title]
  [:head
   [:title title]
   (hp/include-css "/static/css/bootstrap.min.css"
                   "/static/css/bootstrap-theme.min.css")
   (hp/include-js "/static/js/jquery-1.10.2.min.js"
                  "/static/js/bootstrap.min.js"
                  "/static/js/bluth.js")])

(defn get-page [title context]
  (hp/html5
    ;; Since hiccup DSL is just code, we will just inject the
    ;; <head> right here
    (head title)
    ;; Rest of the template
    ;; I'd probably have a (body..) somewhere
    (body context)
    ;; Rest of the template
))

Multi-methods

In the above example, there is a chance of repetitiveness of functions like get-page as the number of routes increases. In most cases, there is one (or few) container div that changes across the templates. To avoid this, I have found using multimethods to be a great way of dispatching templates at runtime.

For instance,


(defmulti container :template :default :not-found)

(defmethod container :home [context]
 [:h2 "Welcome to the Bluth Company"]
 [:button#queue-button.btn.btn-info "Backup"])

(defmethod container :users [{:keys [query-params]}]
 [:h2 (str query-params)])

(defmethod container :not-found [context]
 [:h2 "Generic Content"])

Now that I have a group of ‘container’ divs, I can invoke them from get-page like so,


(defn get-page [{:keys [title]
             :or {title "Bluth Co. - Welcome"}
             :as context }]
  (hp/html5
   (head title)
   [:body
    [:div#wrap
     [:div.container
      ;; Invoke container here
      ;; and dispatch the right template function
      (container context)
      ]]]))

Meanwhile, my routes will end up looking something like this,

(defroutes app-routes
  (GET "/" [] (get-page { :template :home }))
  ;; Due to the destructuring in get-page,
  ;; I can pass in arbitrary context to be handled by
  ;; the container multimethods. In this case, we
  ;; are passing in the query-params
  (GET "/users" [& query-params] (get-page
                                       {:title "User list"
                                        :template :users
                                        :query-params query-params}))
  (route/not-found (get-page
                    {:title "Pluto - Not found!"
                     :template :not-found}))

As you can see, get-page is the point of entry for my templates and the container div is injected according to the dispatched function. In fact, by abusing using compojure’s route destructuring, we can have true runtime dispatching of templates!

(defroutes app-routes
  (GET "/foo/:template [template]
     ;; We don't know which container will be invoked until runtime
     ;; Instead of adding more routes, I can just add more multimethods
     (get-page {:template template})))

get-page function isn’t going to change much and I can mix and match templates as much as I want.

I must admit that I am super new to Clojure. Therefore I am not sure if this approach is idiomatic enough in the Clojure world. Would love to hear suggestions on how it is usually done.

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.

I

More than Death, losing my memory scares the shit out of me.
It makes me queasy to think that all the wonderful experiences I had, the secrets in my head, my tough times and failures can go poof; slowly or in an instant without warning.

Doesn’t matter if its due to some fucked up illness like Alzheimer’s or a freak accident from sheer bad luck. It is very possible that I won’t be me one day.

The only bright side is that at least parts of my identity will live on as memories in people close to me if that happens. Coming to think of it, things won’t be that bad after all :). As they say,

8x10 keep calm carry on gray

 

“Brooks was here”

Minor spoilers ahead

Like many others I love Shawshank Redemption. The scene where Brooks is out of prison and is unable to catch up with the world is just plain sad. One of my favorite all time movie scenes that gives me the chills every time.

I keep hoping Brooks found his Freedom.

 

Chile, allá vamos!

It all started as a little hack by Srini and I at the Yahoo! Openhack Event conducted in Bangalore. The hack by itself wasn’t that fancy when compared to the other finalists but we did feel good when our hack got shortlisted for the finals. We wrote a little web app which would index delicious bookmarks and enable Full Text Search on the Content with a neat tagging mechanism.

Meanwhile, applications were open for the second round of StartupChile program. A seed of 40K equity-free USD and an exotic location, sounded rather interesting. We added some new ideas to the original delicious hack, drafted a nice crisp application and applied a few hours before the deadline.

Fast forward a month, We are delighted to announce that Cruns is one of the 154 startups that made it through the 2nd round of the program.

These are still early days, I am all excited, happy, anxious and scared, all the same time. Never have I budgeted for things months in advance. Ever since I passed out of college, I have been living in the relative comfort of working under a great team at Serendio where I began my baby steps as a programmer.

I have to admit, I am finding myself outside my comfort zone all of a sudden. Something which I hope I will adapt to sooner or later. One thing is for sure, Interesting times wait ahead :)

So there, Announcing Cruns; Something which we hope will help you to organize your information better.

Congratulations to the other 153 teams that made it through. Looking forward to meeting you all this January!

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!

Over the Hills and not so Far Away

I had been itching to go on a motorbike roadtrip to Kerala. Sitting in the back of the car isn’t exactly my idea of a fun and fulfilling roadtrip.

Therefore from Oct 2 – 10, I was on my motorbike riding through some diverse terrain and landscapes that included arid countrysides, coastal plains, villages, forests, hill stations and plantations of cardamom, sandalwood, rubber and tea.

The 2118 odd kilometers was done on my little 150cc Yamaha FZ16 laden with saddle bags and supplies. Given a chance, I’d gladly re-do the same roadtrip again on a more powerful machine.

 

The Short Way Round - The route

 

My itinerary for the trip was as follows

  • Oct 2, Sat: Home – Salem – Avinashi – Coonoor
  • Oct 3, Sun: Coonoor – *crash in the mountains* – Ooty – Gudalur – Sultan Bathery (Wayanad)
  • Oct 4, Mon: Sultan Bathery – Kalpetta – Calicut
  • Oct 5, Tue: Calicut – Thrissur – Chalakudi – Athirappally/Vazhachal falls
  • Oct 6, Wed: Athirapally – Unknown shortcut through rubber plantations – Kaladi – Muvattupuzha (Rendezvous with my friends here and was no longer alone) – Munnar
  • Oct 7, Thur: Munnar – Marayoor – Chinnar – Offroading at Anaimudi – Munnar
  • Oct 8, Fri: Munnar – Idukki – Elapara (with lots of detours taking us to awesome spots)
  • Oct 9, Sat: Elapara – Vagamon – Parunthumpara – Pambanar (Goodbyes over a heavy lunch and was all alone again) – VandiPeriyar – Kumily – Theni – Madurai
  • Oct 10, Sun: Madurai – Trichy – Home

It was a long, wet weekend with rains lashing through Kerala rather heavily. Nevertheless, I was having lots of fun except for the crash in the mountains near Ooty. That was not fun AT ALL. Detailed logs to follow soon.

 

En route Wayanad

 

 

 

Crashed 5 minutes later

 

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.

Roadtrip to Pondy

Made an unplanned roadtrip to Pondicherry on my FZ yesterday. Driving on the ECR with the sunset on your right is pure bliss. The weather was good with occasional chilly bursts of sea breeze. Cruised the entire stretch at a comfortable 80km/hr.

Although not as long as my earlier Yelagiri trip, it was fun nevertheless. The former French colony seems to be at its best charm when it rains :D.

It is amazing how your senses become tuned to the road after riding for an hour or two. Hopefully, I will be doing far more longer trips this winter.

(Sorry for the poor image quality)