Tuesday, June 26, 2007

Releasing Desktop Flickr Organizer

About

Desktop Flickr Organizer is a flickr photos organizer right on your own desktop.


Why should you be using it?

Flickr's web based organizr is slow, updates take time. You can only use it when you're online. DFO on the other hand, stores all the updates offline, and with a simple and intuitive graphical interface, allows you to be way more productive. You'll never dread having to organize sets, edit titles, descriptions and tags for the hundreds or thousands of photos you've accumulated. And you can do all this editing, when you're just trying to kill your time in train, or that long plane trip.

What all does it provide?

1. Uploading and downloading of photos. You can download selected photos or the entire sets.
2. Edit information attached to photos; delete photos from stream.
3. Add/Remove tags associated with photos.
4. Create new sets, edit set information, add/remove photos from sets, delete sets.

More about it on its homepage http://code.google.com/p/dfo

Friday, April 13, 2007

अब तुम हिंदी में ब्लोग कर सकते हो

कभी सोचा है कितना fundoo होता अगर आप "Haal kaisa hai janaab ka" टाईप करते और वह अपने आप जादू से "हाल कैसा है जनाब का" में convert हो जाता? हमने आज वह संभव कर दिया है अपने नए blogger transliteration feature से। अब आप अपने विचार, अनुभव, और तो और अपने पसंदिदा bollywood गाने भी publish कर सकते हैं।

Transliteration option को enable कर आप हिंदी के शब्द टाईप कर सकते हैं, उनकी अंग्रेजी धव्नी के समान शब्द लिख कर, और अपनी आंखों के सामने आप इन अंग्रेजी शब्दों को देवनागरी में बदलते देखेंगे। और तो और, आपको अंग्रेजी शब्दों से हिंदी शब्दों कि mapping भी नहीं याद करनी पड़ेगी। इसका मतलब आपको WeiRD UpPerCasEing कि चिंता करने कि ज़रूरत नहीं सही हिंदी spelling के लिए। बस वैसे ही टाईप कीजिये जैसे कि आप करते हैं, अपने style में, और गूगल को आपका मन पढ़ने दीजिए। ह्म्म्म, लगभग। हमने जाना कि सबका हिंदी शब्दों को अंग्रेजी में लिखने का अपना अलग तरीका होता है -- इसलिये हमने एक personalization mechanism डाला है जो आपका लिखने का तरीका याद रखता है। एक बार ठीक किया, और अगली बार से आपको वह शब्द सही मिलेगा।

हम प्रष्ट्भूमी में machine learning technology इस्तेमाल करके आपको सबसे उत्तम transliteration देते हैं। इस तरह से, आप अपने लिखने और अपने आप को express करने पर ध्यान दे सकते हैं, ऐसी भाषा में जो आपके दिल के पास है। तो हो जाइए creative, इसे try कीजिये, और यहाँ discuss कीजिये। हमें उम्मीद है आपको इसे इस्तेमाल करने में उतना ही मज़ा आएगा, जितना कि हमें इसे बनाने में आया है!

नोटिस: ये translation लेखक मनीष ने गूगल कि original post से अपने हिंदी भाईयों के लिए किया है, इस उम्मीद में कि यह useful होगा। यदि इस translation में कुछ गड़बड़ हो तो लेखक क्षमा याचना करता है।

Friday, February 02, 2007

New Flickrfs release v1.3.9

After some long time, I again had a chance to work upon my favourite filesystem after reiserfs, flickrfs. This release doesn't add nice cool features, this one is targeted towards robustness, resource utilization and efficiency. The previous versions of flickrfs had various issues, namely:
  • Slow internet connection, time-outs or other errors, would grind flickrfs to a halt; forbidding it to download information about sets, and stream.
  • If the number of images grow, in order of thousands, flickrfs would start consuming tons of RAM and eventually swap space; and would literally make my old thinkpad R40 crash.
  • Retrieval of full metadata information for each image was time and network resource consuming, and mostly not required.
  • Sometimes flickr response would return error, even if the uploading of image succeeds, making flickrfs generate false error report; and confusing the end-user, who would then end up uploading the same image twice. (confusing huh? ;-))
  • For developers, a.k.a. me, flickrfs code was huge, all in one file, with lot of boilerplate code sections.
This version v1.3.9 of flickrfs tackles all these issues (also see features list):
  1. Robustness - Flickr operations, as in, interactions with flickr server are now fail-safe. flickrfs handles the URLError exceptions thrown by the operation, checks its result, and retries the operation multiple times in case of failure. Thus, even if connection is lost temporarily, flickrfs would continue its operations unaffected.
  2. Efficiency - flickrfs retrieves the sets information in parallel, background threads. Hence, the directory structure is created quickly, allowing users to start working. If some sets couldn't be retrieved the first time, they'd be taken care of when *syncing* kicks in. Secondly, full metadata information of images would only be retrieved when asked for; though they'll always be listed in the directory. Its just like the way flickrfs handles images.
  3. Resource Saving - flickrfs would now store the image information in Berkeley db database, instead of storing it in memory. Let come millions of images, flickrfs would still consume only negligible amounts of RAM; regarding hard disk space, it would be in 10s of Megabytes; not an issue for today's computers.
  4. Refactoring of code - Developers, again a.k.a. me, the code is now divided into 3 different files and... wait! hmm.. you shouldn't care about it. Just know that its more beautiful :-).
So, just give it a whirl. I'm sure you'd like it. More about flickrfs on its homepage.

Friday, December 01, 2006

Lost memories : Tech Talk by Guido in Google

Some time back there was a tech talk in Google given by Guido about Python 3000. I blogged live from the talk, but never came around to publishing it publically. So, here's it, copying as it is.
---------------
"Hi, I'm Guido. Creator of Python Programming Language. I joined Google last december, and its great working here."

Idea behind Python 3000:
- Dun design a new language.
- Lot of bug fixes, even old ones from 90~91.
- Dun become Perl 6

Concerns:
- backward compatibility
- migration of code from 2.x to 3.x

Process:
- Certain python features from 3.x will be provided to 2.x as well
- Development of 2.x and 3.x will go parallel
- 2.6 - certainly, 2.7 likely, beyond 2.9 never!

Features:
- All string unicode by default
- dict.keys(), range(), and zip() won't return List
- keys() shd have iterator
- Drop <> as alias for !=
- Redesign I/O library. Currently based upon C I/O library. Core dump in C is fine, but not in Python. Need to know how many bytes are already buffered, while doing I/O (?).

NOT going to DO:
- change hash, keys to attributes - dict.keys() to dict.keys
- have programmable syntax / macros
- change look and feel of language
- add radical new features (can always do it later!)

Migration:
- Use pychecker to do an 80-90% job - but can't do it with certainity.
- warns about doomed code - like dict.keys().sort() (Note, dict.keys() is no longer a List. Its an iterator. Do I agree with Guido on this? Probably not!).

Some operations:
- In 2.x -> x//y will return float, not x/y!
- In 3.x -> If x and y are Integers: x/y will return float.
- Say "if key in dict" rather than dict.has_key()


Cleanup:
- Kill classic classes. Classic classes will no longer exist in 3000
- Exceptions must derive from BaseException
- Remove last differences b/w int and long
- Scenario: Suppose you have a sub module named sys, whenever, you say "import sys", it will utilize the sub module, rather than the python library.
3.x - When you say "import sys", it will always get python library. To utilize your sub module named sys, you need to say "import .sys"
- Kill ancient library modules

Minor changes:
- exec becomes function again
- [f(x) for x in S] is a syntactic sugar for list(f(x) for x in S)
- kill raise E,arg in favor of raise E(arg)
- print no longer a statement!
- print x,y,z becomes print(x,y,z)
- print >> f, x, y, z becomes print(x,y,z, file=f)
- alternative to skip the space/newline:
- print (format, x, y, z)?
Why not f.print(x,y,z):
- some file types dun have print method. they have write method.

Inequalities:
- x == y. If x is completely diff type than y, return false
- x < y. has a random decision based upon location in memory, but its problamatic in jython, where objects can move in memory.
- Raise TypeError exception

Check PEP245/246 - take an object to the type, so that the return object is either the same type, or at least behaves as that type.

References
- Read PEP 3100 for a much larger laundry list.
- follow the list: python-3000@python.org
- artima.com/weblogs
- range() no longer returns list, use xrange
- bytes and str instead of str and unicode
- bytes have some str-ish methods like b1.find(b2), but not others like b1.upper()

I/O Stack:
- C stdio has problems:
- dunno how many bytes are in the buffer

Lambda lives!
- Last year Guido wanted lambda to die!
- lambda has hard core following of people, who tried convincing.
- We still dun have a better version, even after an year of trying!
- lambda lives!

Quotations by Guido (including random jokes):
- "I had no life, so I created Python!"
- "To start developing a great software, you'd be having no life outside!" (i lost the essence! :()
- "I'm going to believe my gut feeling on this, and its getting bigger!"

Python Sprint @ Google
Aug 21 - 24. Where: NY, and MV
What: Hack Python 2.6 and Python 3000, 2.5 bug fixing

Update: Ola pointed out that the video is available on Google Video.

Sunday, November 19, 2006

Thousands of mails? You need a powerful Genie!

My home doesn't have internet connection. Though this is generally fine, because I spend most of my time in office, enjoying Google's bandwidth and food. But, lately, I had couple of problems with my health leading me to spend time in my room. Its crazy spending time in a dark dungeon (hi friend!) like room, no T.V., no internet connection, with just a standalone computer and myself. Gossip magazines, which btw I am fond of, talking about Brad Pitt, sexy Angelina Jolie and their (almost always?) newly adopted kids is fine for some time, but then it has its limits. It was then that this idea occured to me, of pushing some of my online interests offline. Totally not a new idea; but isn't it true, that you get them, only when you really need them.

This was the time when I thought of installing Thunderbird, to download and crank upon the thousands of mails I need to browse through while at work. Thunderbird is open source, and a great mailing client, but my love for easy on RAM command line stuff just doesn't seem to like it. This also removes out Evolution. PLUS, I always wanted to be able to mail my attachments without having to open up firefox, login to Gmail, and waiting for the file to be uploaded to the server. Nautilus send can serve the purpose, but again, its not command line. My first intuition was to use libgmail, and write up a script to send mails. But then, it has limited usage. That's when, the age-old powerful client showed up to my mind, there is Pine, there is Elm, but there is nothing like Mutt. So, serving my old love for Gentoo (replaced practically by Ubuntu, but it can never even come close in terms of documentation. hmm.. shd I add yet?!), I browsed through its docs to configure Mutt with Procmail, Fetchmail, and msmtp. Took some time, to configure it exactly, but things worked up fine. And I got myself a Genie!

Know that, I had to download 27,000 mails over one long evening and night, when I replaced my mailing solution for Google internal mails, with Mutt. However, somehow the number of mails I get now, just doesn't seem to be enough for what I'm capable of! And talk about it, just a week back, I was complaining about the huge volume of mails I've been getting.

Edit, Addition: My initial intuition for Mutt was to just use it for reading mails occasionally, and send attachments. But then, there is something more to it. There is no doubt that web-based clients are portable, but the problem is that almost all of them take their own loading times, when showing mails. Its not that this is wrong or unexpected, but when you have so many mails which you need to just browse for your reference, the time adds up. On the other hand, desktop based clients download these mails in the background, and provide you with a smooth and quick browsing experience. Very productive! So, I have decided to give Mutt a shot as my sole email client. It would be interesting to try it out for a couple of weeks, and see if it suits well. As it goes, I'll keep you posted on my experiences with Mutt.

Sunday, November 12, 2006

Printing beautiful code

While writing beautiful code is an art, printing it beautifully is a frustation. I've long been bugged by this problem, and interestingly Dr. Google has been silent about my query. So, here's my search results for the world:
Use enscript, which is installed by default on linux systems.
$ enscript --help
will show you a whole list of options to choose from. If you're as lazy as me, just rely upon the configuration which I found most useful:
$ enscript -2rGC --color -Ec code.c
The options passed along with what they do is as follows:
  • -2 : 2 columns. To have single column, you can use -1. Use --columns=NUM, if you want to specify more than 2 columns.
  • -r : landscape view.
  • -G : cool fancy looking header, which includes file name, page number and creation time.
  • -C : print line number in front of each line.
  • --color : colored output
  • -Ec : formatted using C syntax. Though enscript supports various coding syntaxes, which range from Java to Python to Tcl etc., it is not intelligent enough to understand which language is the code written in, so you need to pass this flag. For e.g. To get the code formatted using python syntax, use -Epython.
By default, the output will be sent directly to a printer. However, you can retrieve a postscript output by specifying '-p filename.ps' flag.
$ enscript -2rGC --color -p testing.ps -Ec code.c
That's it! Enjoy code reading!

Wednesday, September 20, 2006

Interesting discover about pys60 v1.3.1

To store a list of names in the database against a key, I use marshal.dumps(list). I got an interesting error while doing this:

len(l)
128
>>> db['check'] = marshal.dumps(l)
Traceback (most recent call last):
File "", line 1, in ?
File "C:\system\libs\e32dbm.py", line 145, in __setitem__
self._dbset(key,value)
File "C:\system\libs\e32dbm.py", line 100, in _dbset
self._execute(u"INSERT INTO data VALUES (%d,'%s','%s')"% (hash(key),sqlquote(key),sqlquote(value)))
UnicodeError: ASCII decoding error: ordinal not in range(128)


If the length of the list is 127, it stores fine in the database. Strange, huh? No! Doing, a db['check'] = unicode(marshal.dumps()) doesn't work either.

Workaround?
db['check'] = ';'.join(list)
list = db['check'].split(';')