Category Archives: Scripting

Google Finance bookmarklet

I use Google Finance to track stock/fund portfolios. Many of these portfolios track some investment policies and I enter the actual trades in there too. But the portfolios keep showing the old (i.e. closed) positions in the table making it look cluttered. I checked on their product blog/forum and this seems to be requested by some people (and ignored). Here is a small bookmarklet which will do this. You will need to drag the link to your bookmarks bar (Tested only with google chrome). Next, when you are on the google portfolio page, just click on the bookmark and it will hide all the closed positions! Woohoo!

Drag this link to Bookmarks bar: GFinance: Hide Closed Positions

P.S. If there is interest, I can turn this into a google chrome extension (greasemonkey) so this gets done automatically when you go to google portfolios page.

RSS Feeds for Indian Columnists

Frustrated by Indian Express's inability to provide individual syndication feeds for its columnists, I have written scripts to parse the HTML pages and generate the feeds myself.

Here are the feeds for
Shekhar Gupta
Tavleen Singh.
R. Jagannathan (DNA India)
Arun Shourie
Sudheendra Kulkarni
Ila Patnaik
Pratap Bhanu Mehta

If you want this for another columnist, let me know and I will add that too. This is very easy to do for Indian Express columnists as I already have the script, but I can also help with other websites.

P.S. The script is in ruby and I will release the source after I fix some things and clean it up some more.

Update: May 29, 2009
Added new feeds for Arun Shourie, Sudheendra Kulkarni and Ila Patnaik

Update: June 22, 2009 - Added columns feed for R. Jagannathan of DNA India

Update: August 11, 2009 - Feeds for C. Rajamohan , Harsha Bhogle , Shailaja Bajpai.

Update: Sept. 10, 2009 - You can use my shared page from Google Reader to see all the new posts from all of these columnists on a single page.

Update: July 18, 2011 - Added Karan Thapar.

Simple way to share files on intranet.

If you want to download files from machine A to machine B and have python installed on machine A, here is a very simple way to do it:

On machine A, open a command window and change directory to where the files are and run this command:

python -m SimpleHTTPServer

This command starts a web server serving files from that directory.

On machine B, just open a browser and type the ip address of machine A and port 8000 and you can see all the files. When the transfer is done, simply press control-C in the command window. A simple way to temporarily share your files across the network!

Fix font problems on firefox (or is a marathi news website using unicode fonts. But it does not display correctly on firefox browser. The problem is because of a single HTML div which uses justified font style. It displays correctly on IE (which is why it is not getting fixed) - this could be because of firefox's buggy implementation of "align: justify" or that IE simply ignores that style (likely).

Anyway, here is a javascript one liner that you can bookmark and once the page is loaded, click on it to fix your font problem.

Fix Ma. Ta. -- Drag this link to your bookmarks.

I tried to create a greasemonkey script to do this automatically, but it's not working for some reason...

Update: Apparently it *is* a mozilla/firefox bug open for 4+ years. See here and here.

Update2: Here is a greasemonkey script by Saravana Kumar to fix this issue. Caution: you might want to change the included domains carefully (it by default runs on all http and https sites!)

Update3: Here is my greasemonkey script specific for maharashtratimes. Enjoy!

Update4: (2009-02-16) The original site seems to have removed this style attribute now. So the above post is now only for posterity.

Using Ruby for integer format conversions

Here are some recipes for interpreting stream of bytes as different C types. I will keep adding more to this as I go...

Convert a byte stream (embedded in a string) into 1 byte signed integers:
=> [-4, -3, -2, -1]
Convert a byte stream (embedded in a string) into 1 byte unsigned integers:
=> [252, 253, 254, 255]

Check if a site is phishing site.

Here is the updated bookmarklet: Phishy? (tested on firefox 2.0 only!)

1. Drag this link to your bookmark. This checks if the site you are currently on is a phishing site.
2. Drag this link to your bookmark. This prompts for a URL and checks if it is a phising site.

Uses phishtank's check URL API.

If this does not work try turning debug to true above if you want to see the encoding.

Update: This still uses the GET method for checking the URL. Phishtank recommends using the POST interface (which will remove limitations on URL length: base64 inflates the length by 33%). Implementing that would need some kind of xmlhttprequest hackery. Stay tuned...

Update2: I got the AJAX bookmarklet ready, (thanks!)but it hits the infamous "uncaught exception: Permission denied to call method" bug. i.e. you cannot do cross-domain xmlhttprequests. To solve that I think I need to convince PhishTank to host the javascript code, so the bookmarklet will insert a hidden iframe into the current page which will load the javascript from phishtank page, which will eventually make xmlhttprequest to phistank and display the result back. Are you listening PhishTank ?

Update3: Thanks to "till" who commented below, here is the bookmarklet using the POST method so now the solution will also work for really long URLs. Till's solution is good, but it makes users trust his site (in addition to phishtank). So basically user has to trust that he is not trying to filter the results being presented..

I have also merged the two earlier bookmarklets so that the current site location will be autopopulated in the prompt, so that user can easily change it if he wants to check a URL different from the one he currently is on.

Escaping URLs vs escaping HTML

I often get confused between two types of escaping you need to do when developing web applications: URL escaping and HTML escaping. This is a short note about when should you use what.

URL Escaping (or HTTP encoding or URL encoding) is used to escape the characters not allowed to be permitted for a URL (e.g. To generate the query string to be passed from forms). The way to encode these characters is to use % and hexadecimal code for the ASCII character code. e.g. %20 for space character. (RFC 1738 defines the syntax and symantics of URLs)

HTML escaping is used when writing HTML documents where you do not want the browser to interpret the HTML special characters. e.g. You need to use & to represent &. Wikipedia has an article describing escape sequences for comonly used special HTML characters.

Scripting languages have libraries which can do URL and HTML encoding and decoding for you:

Python: urllib.quote and urllib.unquote , ???, ???

Ruby: CGI::escape, CGI::unescape, CGI::escapeHTML, CGI::unescapeHTML

Playing mp3 links right in your browser

The folks have a nifty javascript piece of code which adds a small button to all the mp3 links on your webpage. (This infact embeds a small shockwave/flash script for each link). All you need to do is include the following code in the head section of your webpage:

<script type="text/javascript" src=""></script>

Here is a link to their webpage (Notice the small play button just before the link to audio file.

Here are some popular audio links contributed by users.

Update: And then there is Yahoo! Media player with nicer look and more features. You just need to add
<script type="text/javascript" src=""></script>

at the end of the html (just before closing </body>)

Yahoo Geocoding in ruby…

Find lattitude and longitude of any address

Yahoo just released a new beta of their maps webservice. Here is a small ruby script (inspired by Rasmus's PHP code ) that I wrote that returns Lattitude, Longitude of the address provided...

require 'open-uri'
require "rexml/document"
include REXML
puts 'Enter Location: '
doc = result
print "Precision: ", r.attributes["precision"],"\n"
r.children.each { |c| print, " : ",c.text,"\n"}

Update: Here is a link to the script in github or to the .

Library Lookup greasemonkey script for San Diego public library and San Diego County library

I promised here that I will polish my library lookup script and post it here, but haven't yet found any time to do that. I am posting it here so someone could work on it and make it better...

I have tried to look for the ISBN in both SDCL and SDPL, and it inserts the message and the link correctly. However in some of the cases, amazon inserts some more elements inside the same div container, so the links appear much later. (not immediately following the title). I have an idea of how to fix this and am going to fix this very soon...

Get the LibraryLookup Greasemonkey script from here.

(Usage: RIght click on the link and select "Install User Script" from the menu. OR open it in forefox, go to tools/Install this user script, click ok and now on you will see if any book that you are browsing on is in SDCL or SDPL!)

Update: 11/30/05. The new bookburro extension for firefox supports SDPL and SDCL libraries by default, I will not have to update my miserly scripts now...

Django middleware

In the django project settings there is a key called MIDDLEWARE_CLASSES which is a tuple of strings implementing the middleware methods. Django base handler (TBD explain what this class does) reads this setting and initializes three of its own attributes: _request_middleware, _view_middleware and _response_middleware. It goes through the list of middleware classes instantiates each of them and adds the bound method process_request to the _request_middleware attribute, process_view method to view_middleware and process_reponse method to _response middleware.

If the middleware class method returns something (indicating that it has taken some action), the basehandler get_response method returns immediately. Otherwise it proceeds further.

There are 4 middleware classes built in:

  • AdminUserRequired middleware class implements the process_view method and silently returns if the user in the request is logged in and is a valid admin user. Otherwise it returns login page with appropriate error message.
  • CommonMiddleware implements process_view and process_response methods. process_view rejects forbidden user-agents and prepends URL with www and appends trailing slash if desired. process_response checks if there is a matching flat file present that can be sent for 404's and can also send email note to managers about broken links. process_response also manages ETags
  • CacheMiddleware implements process_request to check pages (not containing any query string) against cache. process_response adds pages to cache as needed.
  • XViewMiddleware (used internally for documentation) implements process_view and attaches 'X-View' header to internal HEAD requests.

Update: 10/14/2005. There are some updates to the middleware that ships with django and is now "officially" documented here.

Getting to know the django web framework

I was just about to abandon python and join the ruby camp to be able to use the wonderful rails framework for web application development. (They do have very good documentation and impressive video demo which you should check out!) But then came the announcement of Django. I really like the python language and feel that I can understand someone else's python code, (though ruby looks equally fascinating). I read through the tutorials and checked out the svn repository and worked with the tutorials. This framework looks easy to use and seemingly makes your application portable enough to use any of the underlying database backends (postgresql, mysql, sqlite) and webservers (apache, lighthttpd, twistedweb etc). The initial few days after the announcement, there were very hectic updates on the code and documentation front (with support for sqlite backend , standalone server and new tutorial and documentation about generic views and form fields coming in a matter of a couple of days). This has now gradually slowed down.

I decided to write a sample application (rebate tracking) and immediately hit some issues. I am trying to make the user registration and login/logout part work, but am not following how that is hooked into the framework. The users added with admin interface do not get recognized by the authentication code. Tried IRC help, but haven't been able to get anyone who can help. I am studying the code right now. I am going to look closely into the decorator and middleware code now. I will write about my progress here.

Greasemonkey: Control your web!

Greasemonkey is a plugin for Firefox browser that lets you assign DHTML scripts to various domains. What's the big deal you ask ? This lets you correct some annoying problems some websites have or even add some nice features to your regular websites.

There are tons of user contributed scripts for doing fun things, like Adding waypoints to google maps., Remove ads from etc.

The disadvantages of this are 1. this is firefox specific and 2. This works only on the computer that you installed the extension and scripts on. But hey! it's still way cool...

Update: 02/22/05
Here is a very nice application of this: Let's say you are browsing for some books, how about checking out your local public library's catalogue for the same book and displaying that information right next to amazon book title ? This has been done by Jon Udel (but looks like he has taken down his script) and Bill Stilwell. I managed to tweak his script to search San Diego Public Library. Hurray! Contact me if you are interested. I will polish the script and put it here in a few days anyway...

Some more blog posts on greasemonkey:

**Update: 05/05/12**
Hmmm... [Dive into Greasemonkey]( "Dive into Greasemonkey")

**Update: 05/18/05**
Wow this monkey is getting bigger and bigger.

[Here is](,1282,67527,00.html "Firefox Users Monkey With the Web") a link to a recent wired article on greasemonkey.

Lateral Thinking…

How will you write a program to find jumbled words ?

The shotgun approach is the first one anyone is bound to follow at first. i.e. For all permutations of the letters, find if there is a match in the dictionary of words. You might do some optimizations to ignore repetitions etc. But this is O(n^2) complexity solution.

I read an elegant way to solve this here. The trick is to notice that the real answer and the jumbled word look the same when they the letters are sorted.
(Let's ignore the time to sort the words for now, which is O(n*log(n)) I believe for decent algorithms.)

Here is a python snippet to solve the jumble:

#!/bin/env python
def find_jumble(jumble, word_file='/usr/dict/words'):
    sorted_jumble = sort_chars(jumble)
    for dictword in open(word_file, 'r').xreadlines():
        if sorted_jumble == sort_chars(dictword):
            yield dictword

def sort_chars(word):
    w = list(word.strip().lower())
    return w

    inp = raw_input("Enter word: ")
    if not inp: break
    for ans in find_jumble(inp):
        print "Answer = ", ans