Tuesday, March 2, 2010

Simple URL shortener in less than 30 lines of python code

I needed an URL shortener for a project that I'm working on that keeps URLs in their short form for a limited time. No need to go into the details about the project as this URL shortener is a helper hack so we don't need to do last-minute rewrite of the app itself.

As an exercise, I decided to write a fully functional RESTful (*buzz*, *buzz*) app with a persistent store for the URLs. I chose Beaker cache for the storage and bobo as the boilerplate base for the app. Thanks to those two components, the actual script is less than 30 lines of python code.

To save the URL and get it's short ID, you POST the URL to the app. The script is caching the URL for an hour, but it's using persistent storage in case the app crashes (it restores the cache contents). I used my short_id() method I wrote about a while ago to generate the ID for the stored URL. If you supply the ID to the app it will redirect you to the stored URL.

You can check the app the git repo here. Feel free to comment and feel free to use it, of course!

To run the script, use: bobo -f shorty.py (bobo is the command to run an embedded bobo web server).
To save an URL, simply POST to it:
$ curl -d "url=http://www.a13x.info/" http://localhost:8080/
(you'll get something like "ax7dc" returned)
To fetch the URL do: http://localhost:8080/ax7dc. The app will redirect you to the saved URL or throw a 404 if it expired (or it didn't exist).

Simple!

Tuesday, January 12, 2010

Install CouchDB with Homebrew with existing Erlang

If you're using excellent Homebrew to install fantastic unix CLI utilities on your OS X, then you might find this handy. I wanted to install CouchDB using Homebrew, but I quickly realized it depends on Erlang being built with Homebrew as well.. As I have built my own Erlang (and don't need another one) for my machine, I decided to look into the formula for CouchDB to see if I can tweak it to use Erlang that's already on my machine.

It turned out that the fix is very easy to apply. Only thing you need to do is to open the couchdb.rb file (in /usr/local/Library/Formula) and do the following:

  • remove the depends_on 'erlang' line

  • edit the call to the configure script so the line --with-erlang points to your erlang installation (mine is in /usr/local/lib/erlang).

Here's the patch:

10d9
< depends_on 'erlang'
16c15
< "--with-erlang=#{HOMEBREW_PREFIX}/lib/erlang/usr/include"
---
> "--with-erlang=/usr/local/lib/erlang/usr/include/"


Now do brew install couchdb and make something wonderful. Don't forget to let me know about it!

Friday, December 11, 2009

Release early, release often!

Remember that mantra, known in the Open Source world? Well, it's a core part of Agile Methodologies for software development, for precisely the same reason: getting the feel on how your project/product/app is behaving in the real environment and getting feedback from your customer. Feedback is especially important, as the requirements for the project might change (and they usually do!) - you need to be aware of that!

But requirements are not the only ones that change; so does the environment in which your product is supposed to be running and used. While you might have total control over the development and test environments, you usually don't have little or no control over the live (production) environment. That environment is handled by some dedicated person or people.

Keep in mind that those people have their own schedule (backlog if you wish) by which they operate the environment under their control. Systems are upgraded or reinstalled, new versions of services get installed and so forth. Usually, you, the developer, are the last one to find out about that. You find out about those changes when your app is being deployed and (oddly!) doesn't work.

We all tried to talk to those people, hoping they will keep us in sync with the changes they make, but frankly (and I'm talking from personal expirience) that rarely goes as well as you think it would. So, make sure your product owners understand this as well, and push for releases as often as possible. That way, not only you'll be getting (great!) feedback from your owners, but will be able to keep tabs on your environment as well.

This post reflects thoughts, problems (and frustration) over the last week, while trying to get our (quite complex) project into production. While we were really trying to be agile and follow all (or most) of the principles during development, we still managed to fail to deliver our project often to the production environment.

What product owners sometimes fail to understand is that you must follow all of the principles, and follow them well. The developers often fail to help them understand. We must all learn from that, I say.

Wednesday, November 25, 2009

Andri Luka 2 years old && Erlang/OTP R13B03 released

This day is very special and remarkable - our son, Andri Luka was born on this day 2 years ago! Happy 2nd Birthday, dear son!

Also, on the other side, Erlang/OTP R13B03 is released. With this release comes the GIT (mirror) repository of Erlang/OTP source code (available here) to enable people to send in contributions. That is awesome! The release also marks the introduction of NIFs (Native Implemented Functions), but that's still in experimental stage.

Saturday, November 7, 2009

Icelandic Gaming Industry

Just came back from the first IGI workshop, first workshop for the IGIA10, the Icelandic Gaming Industry Awards competition.. It was an excellent starting point for icelandic indie game developers to meet and network. I came a bit late so I missed few talks, but the rest was really good. The talks were held by representatives from companies that are already established game developers (ie. CCP, Gogogic, Dexoris, etc). It was nice of them to share their expirience in their road to success.

I asked couple of questions, mainly focusing on getting more information on how to get connected to artists and/or designers that want to bring their talent into the gaming industry. Lots of indie developers (such as yours truly) have zero-to-none artistic (design) skills. In my opinion, IGI initiative should also focus on that talent, as well as developers.

As we all know, eye-candy and content is a huge help to make it in this business. I am close to a point where I would definitely need an artist to join me, otherwise it might be very difficult to get players to play the game. Not to mention possible funding :)

Next to come, a bit of introduction to the game itself.

p.s. I encourage you, dear reader, to check the Icelandic Gaming Industry website and join me and others in very interesting endeavour of bringing more games in the future..

Saturday, July 11, 2009

Check if an application is running

I'm working on a utility application for Mac OS X, which will display the currently played song in iTunes on the OS X status bar. While working on it, I've made a small utility method to check if a program (identified by BundleID) is running or not.

Here it is:


-(BOOL)isRunning:(NSString *)programBundleId {
return [[[NSWorkspace sharedWorkspace]
valueForKeyPath:@"launchedApplications.NSApplicationBundleIdentifier"]
containsObject:programBundleId] ? YES : NO;
}


The method returns YES if an application is running - in my case, it was useful to check if iTunes is running or not.

Monday, June 29, 2009

TinyURLs reloaded, now with Python3

Few days ago, very smart and great people behind Python project released stable version of Python 3.1; that brings bunch of improvements (including performance ones) and new features. You can check what's new in this release right here, if you wish.

I was quite impressed by the speed improvements over the 3.0.1 version of Python. It's quite fast and comparable to Python 2.6 version (which is pretty damn fast). Running few of my sources with the new version (to test speed and comformance) I noticed that my TinyURL example doesn't work anymore.

The string.letters is gone, and print is (as mentioned before) no longer a statement; it's a function. The updated function now looks like this:


import random
import string

def short_id(num): return "".join(random.sample(string.digits + string.ascii_letters, num))

print(short_id(6))


The only noticable change in the function itself is use of string.ascii_letters. There you have it - now Py3 compliant! :)

Friday, January 30, 2009

Tiny URLs

Want tinyurl.com-style links in your application? Need to generate a random sequence of alphanumerics? Here's a quick function in Python:


import random
import string

def short_id(num): return "".join(random.sample(string.digits + string.letters, num))

print short_id(6)

It will return something like AnLrJl or 9mLXut, or even bK5D4O. Simple and powerful.

Wednesday, January 7, 2009

Христос се роди! Срећан Божић!

To all the people that celebrate Christmas today, we wish you a Merry Christmas and that you and your family are healthy, happy and wealthy!

Wednesday, December 24, 2008

Merry Christmas and Happy Holidays!

To all the people that celebrate Christmas, to all my friends and their families, we wish a very Merry Christmas!

Happy Holidays!

Monday, December 22, 2008

Python 3.0 and print function

I have been following the python mailing list for quite some time now. I recommend it for any pythonista who's not afraid of a bit of spam and flame war here and there.

There has been a lot of discussion and arguments about a change in Python 3.0 in which print is a built-in function now instead of a language-specific statement. The arguments started flowing in to the mailing list just minutes after Python 3.0 final was officially released.

Most complaints seem to revolve around the fact that *now* we have to write extra two parenthesis, ie. print("something") instead of print "something". Let us ignore that complaint for now, as it is minor (not to mention pointless) issue, something to get used to and easily solved with IDEs. Besides, we all *know* how to use functions, right? This is a non-issue.

Another (much larger) complaint is about string formatting (PEP-3101 - Advanced String Formatting), which is a very big improvement over the formatting using "%". New built-in function, format(), has been introduced along with (so-called) "Format Specification mini-language" to specify and control formatting. Quite powerful, if you ask me.

Particularly interesting formatting option is formatting of positive and negative numbers (a sign option). Consider implementing this in the old syntax:


print(format(-123456,'#> 20'))
print(format(123456, '#> 20'))
print(format(123456, '#>+20'))


Furthermore, you can implement __format__() method in your classes, which will be called by the format() built-in function for producing a formatted version of the object. However, implementing formatting specification is up to you - you can use the standard formatting syntax or implement your own.

Bottom line is, Python 3.0 brought a lot of changes and improvements; those changes have been discussed and polished over a period of several years prior to releasing the final version. What I don't understand is those people who are complaining about it now, instead of doing it before and contributing to those discussions. It will get some time to get used to the new changes, sure; but don't dismiss them straight away - give it a chance and try it out. You will soon realize that those changes are in fact good ones.

Friday, December 5, 2008

Python 3.0 released

Interestingly, my previous post was about Python 2.6... This one is about 3.0, which finally saw the light of day in final edition two days ago! I just noticed it now (obvious proof I'm spending too much time on meetings here at work :).

Sadly, no official package for OS X as of yet, but I'm sure it will arrive after the weekend. I'm itching to take it for a spin on my code.. There will be some incompatibility issues, but 2.6 version helps a lot to sort that out.

Have a nice weekend, folks!

Thursday, October 2, 2008

Python 2.6 final

It's here, the final version of Python 2.6 has been released. This is the last 2.x release of Python before the almighty Py3K. You can read what is new in Python 2.6 and of course, grab your own copy.

I'm fetching the installation now, eager to see if the installation will work with PyObjC on my Mac. Next thing on the list is to install Stackless.