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…

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.

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!

Follow

Get every new post delivered to your Inbox.