Tuesday, July 29, 2008

AJAX and Browser Caching Problem

For a long time, I have not been able to understand how to bypass the browser caching problem for developing AJAX applications. Internet Explorer simply looks at the URL, sees whether it has it in the CACHE, and brings up the cached version whenever possible.



The caching problem is observed for HTTP GET requests only. There is no caching issue for HTTP POST requests. It turns out that this is actually very easy to achieve.

A URL is different if it has any of the GET request keys are different. Hence to bypass caching, all one needs to do is add a parameter to the URL which has a new value everytime the URL is accessed, and is not really used by the client/server programs.

For more information see:
http://www.spacebug.com/solving_browser_caching_problem_of_ajax.html

http://www.howtoadvice.com/StopCaching

Friday, July 18, 2008

Running Python Scripts with Administrator Privileges on MAC OS X

Problem

I had a piece of software written in Python. I come primarily from Windows background where permissions etc. are quite hazy. 

On MAC OS X I wanted this software to be able to run with Administrator privileges. Apple has an Authentication API which enables an application to request for administrator privileges from the user whenever it needs it. Unfortunately I couldn't find out any way to access the authentication API directly from Python code.

Solution

AppleScript (MAC's built-in scripting language) has a very simple and straightfoward way to execute any script with admin privileges. 

Lets look at a simple example first:
do shell script ¬
"echo 'abc' > /Applications/MyTestFile" with administrator privileges


You can open Script Editor from /Applications/AppleScript/Script Editor.app and write the above example.

Interesting thing to note here is:
  • I am trying to do something which will not succeed with administrator privileges
  • The "with administrator privileges" clause ensures that AppleScript will ask you to grant administrator privileges to the shell script before execution
  • If you don't grant administrator privileges (may be you don't know or you forgot the password, or may be you don't want the shell script to run), the script will not be run.
  • If you grant the privileges, it will do as programmed above; i.e. write 'abc' to a file in /Applications.

Administrator privileges for Python programs

It must be easy for you to guess how to request for administrator privileges for running a Python program. Let me just put the code for clarity:
do shell script ¬
"/usr/bin/python myPythonProgram.py" with administrator privileges


Limitations
  • The solution requires you to request for privileges even before the python program started running. Thus if you wanted something where you could request the privileges only on need basis, this solution won't work. But at least something is better than nothing.



Thursday, July 17, 2008

SVK for SVN users

This post is about setting up SVK for SVN users. I assume you know enough about SVN, and you are looking for a quick documentation which can help in getting off the mark with SVK

Objectives

At the end of reading this article you should:
  • Understand how to mirror an SVN repository
  • Understand how to Synchronize development between your local SVK repository and your central SVN repository
  • Understand how to create local development branches
  • Know typical day to day tricks for SVK usage
Introduction

One problem with SVN is that you cannot take advantage of it when you are offline. Thats where SVK comes in which provides you the capability of distributed version control. 

Using SVK you:
  • Mirror an SVN repository in your local file system
  • Do your day to day development using the local SVK repository (online/offline)
  • Publish your changes back to the central SVN repository when deemed suitable (and when you are online)

Installation
Installation for different platforms is fairly well covered in

I just would like to let you know that I installed on my MAC and it was straightforward, without any surprises, and worked out of the box. 

SVK depotmap

SVK depot is a local database that SVK creates in which the mirrors of your SVN repositories are maintained .

Creating SVK depot

$svk depotmap --init

It will create a .svk directory inside your home directory. This is your default depot.

Setting up a mirror

Suppose you have the following svn repository structure:
svn://192.199.4.232/repos
- third-party
- mycalc
- trunk
- gui
- arithmetic
- tags
- branches
- crm
- trunk
- tags
- branches
Now you want to mirror the whole of trunk of your mycalc project. 
$svk mirror svn://192.199.4.232/repos/mycalc/trunk  //mycalc/trunk
The above will mirror the svn repository into your default svk depot

A bit of explanation

The command is:
svk mirror url_of_svn_repository path_to_local_mirror
The path to local mirror is formed as:
/depot_name/your_chosen_path
  • The default depot has no name. Hence // above
  • I chose to use mycalc/trunk as the local mirror path. This way I would essentially replicate the same directory structure as is there in the central repository, avoiding other parts of the structure which I don't wish to replicate (like branches and tags)
To see the list of mirrors, please try:
$svk mirror --list
Path            Source
=====================================================
//mycalc/trunk   svn://192.199.4.232/repos/mycalc/trunk


Note that the mirror doesn't yet have anything

Synchronizing the mirror with repository

$svk sync //mycalc/trunk
This will bring your local mirror //mycalc/trunk in sync with the central repository: svn://192.199.4.232/repos/mycalc/trunk. 
  • Entire revision history for this repository is downloaded from central SVN server
  • This operation would consume quite a lot of time depending upon how large the repository is

Note: This brings in the entire history of a repository to local repository. So it is very time consuming. It may not be what you want. See below on import.

Working with your local repository

The SVK commands are pretty much the same as SVN commands:

  • To checkout : svk co //mycalc/trunk
  • To update : svk update
  • To commit : svk commit
  • To see the status: svk status
  • Listing the contents of a folder on repository: svk ls //mycalc/trunk/gui


Receiving other changes from central repository

Other people are working also and committing their changes to central repository. To receive those changes into your repository, try:

$svk pull //mycalc/trunk


Publishing your changes to central repository

When you are ready to publish your changes to central repository, try: 
$svn push //mycalc/trunk


SVK Star Merge

Subversion as of now doesn't support automatic merges. One has to record the revision numbers before merging code between two branches. SVK implements Star Merge algorithm first introduced in GNU Arch which makes merging code between branches a lot easier. 

More on this later..


SVK Integration with GUI clients
I haven't found any integration with GUI clients yet. May be sometime in future! Who knows!



My WishList

SVK + Subclipse : Most of my development so far has been done using Eclipse with the SubClipse plugin for SVN integration. I would very much love to have SVK support built-into SubClipse itself.



Tuesday, July 15, 2008

Python Socket Library Hostname quirks

Python socket library has some pretty useful functions and probably a weird behavior?:

Objective
I wanted to setup a portable way to detect whether I am connected to network or not.

When a computer is connected to some TCP/IP network (using either static or dynamic IP), it gets an IP address. Otherwise by default it has got a loopback IP address which is 127.0.0.1.

So I thought that I could use this idea for detection of presence of network.


Problem


>>> import socket # imports the socket library
>>> print socket.gethostname()
shailesh-macbook-pro.local


The above is on the my macbook-pro laptop.

If I do the same on my windows laptop I get:
>>> import socket # imports the socket library
>>> print socket.gethostname()
shailesh_lap


So far so good.

Things get weird with the following:

On Windows
>>> print socket.gethostbyname(socket.gethostname())
192.9.199.152

And on MAC Book Pro

>>> print socket.gethostbyname(socket.gethostname())
...
socket.gaierror: (8, 'nodename nor servname provided, or not known')

Now I don't really know what went wrong here. I had just sometime back restarted the system.
After some time, I found that this started working fine again

On MAC Book Pro Again after some time
>>> print socket.gethostbyname(socket.gethostname())
192.9.199.159

It is my guess that either Python on MAC, or MAC OS itself takes some time in setting up some of these IP address hostname mappings for the local host.

Work Around

But I needed to get the IP address of the host computer. My objective was to identify whether my computer is connected to some network or not. So I eventually sat down and wrote the following:


def gethostaddress():
hostname = socket.gethostname()
hostaddr = u''
try:
hostaddr = socket.gethostbyaddr(hostname)
except socket.gaierror, e:
try:
hostaddr = socket.gethostbyaddr(u'localhost')
except: pass
except: pass
return hostaddr

def networkIsPresent():
return u'127.0.0.1' == gethostaddress()




Although this may not be perfect, but I guess I will work with this for now, till I have a better solution.

Monday, July 14, 2008

Background of this blog

Python is one of my favorite programming languages. (The other ones C/C++).

I have done a lot of Python based development over the last two years and learnt quite a few tricks.

Have always thought of writing a book on Python, but that seems to be too grand a project, and I probably don't yet know enough to be able to do justice to such an attempt.

Nevertheless I can at least start blogging on Python.

Hence this blog.

UPDATE

During development, I usually use a lot of other tools too. I wanted to write about them also. Initially I thought to create a separate blog for general software related activities. But later I decided, it won't be possible for me to maintain multiple blogs. Hence I am renaming this blog to Shailesh on Software Development and will collect all my discussions related to software under this blog only.