Tuesday, December 26, 2006

Simplest way to add "Cygwin Prompt Here" to Windows Explorer

Just like Eric Sink, the first thing I install on my windows laptop is Cygwin and, well not Emacs anymore, gvim. I just can't image using windows so pre-mature shell to get anything done. One little problem with Cygwin is since it uses a unix like directory structure, switching back and forth between Windows Explorer and Cygwin has been a pain in the ass for a long time. Now, time to scratch the itch.

A quick Google search redirects me to Bruce Eckel's article on this same problem. It proposes two solutions but unfortunately none of them works perfectly on my environment. After hacking around, here is my solution. Different from the existing ones, this is the simplest solution I could find so far. No .bashrc, no .bat file, only one tiny .reg file. Enjoy it and see my code comments in lines.

Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Folder\shell\Cmd Here]
@="Cygwin &Prompt Here"
[HKEY_CLASSES_ROOT\Folder\shell\Cmd Here\command]
@="cmd.exe /c c:\\cygwin\\bin\\bash.exe --login -c \"cd '%1'; exec /bin/bash\""

Notes:

  1. Save the above text into any reg in any folder, double click it and you should be all set. (Assuming you're using the Cygwin default installation path, of course.)
  2. cmd.exe /c : launch the cmd.exe and execute the command after the /c parameter. Close the command window when the bash exits.
  3. bash.exe --login :load the user settings for the login user. -c means to execute the commands after login.
  4. cd %1; :retrieve the folder path from Windows Explorer
  5. exec /bin/bash: to open the bash environment.

Monday, December 25, 2006

How to automatically install a button onto FireFox Toolbar?

Here are some facts about rdf:local-store in Mozilla architecture from XULPlanet:

  • The datasource rdf:local-store is included with Mozilla and is used to hold state information such as the position of the browser window, which columns in tree views are displayed, and which toolbars and sidebars are displayed.
  • This information is saved when Mozilla exits, and is re-applied automatically to the XUL content when the appropriate window is opened again.
  • Although the local store normally holds XUL state information, you can actually put anything you want into it.
  • The local store is saved to an RDF/XML file 'localstore.rdf' in your Mozilla profile directory. Since it's an RDF/XML file, you can open it in a text editor and view the information it contains. It's possible to modify the file as well, although that isn't
So the answer to our question on how to add a button to the browser's toolbar lies in the localstore.rdf file. Open the file and find the triple, or assertion, on chrome://browser/content/browser.xul#nav-bar and you should be able to see something like this:
RDF:Description
RDF:about="chrome://browser/content/browser.xul#nav-bar"
mode="icons"
currentset="back-button,forward-button,reload-button,search-container"

Just add your toolbar 'ID' to the currentset and you're done.

Sunday, December 24, 2006

RDF support in Mozilla

nsIRDFSerivce. The RDF service is an utility interface that serves three primary purposes. First, it is used to manage “named” datasources. A named datasource is a singleton datasource that can be acquired using simple URI-like name [4]; e.g., rdf:bookmarks. Second, it is used to implement the function that maps a URI to a resource (which is the inverse of the one-to-one resource-to-URI function described above). Third, it is used to implement the function that maps a string value to a literal (similarly, the inverse of the one-to-one literal-to-string function described above).

nsIRDFNode. This is an interface for a node in the RDF graph. A node must either be an nsIRDFResource or an nsIRDFLiteral [5]. Objects that implement these interfaces must be acquired from the nsIRDFService.

nsIRDFDataSource. This is the interface that provides access to a collection of “related statements” (or a “subgraph”). This interface includes methods that allow testing for the presence of a statement, enumerating the statements contained in the collection, and adding and removing statements to the set.

nsIRDFCompositeDataSource. This interface is derived from nsIRDFDataSource. An implementation of this interface will typically combine the statements from several datasources together as a collective. Because the nsIRDFCompositeDataSource interface is derived from nsIRDFDataSource, it can be queried and modified just like an individual data source.

nsIRDFObserver. This is an interface that an RDF client implements. The interface allows a client to be notified when a change occurs to the statements in a datasource.

nsIRDFContainer. This is an interface that allows for simplified access to an RDF container object (a bag, sequence, or alternation). This interface, in conjunction with nsIRDFContainerUtils provide straightforward, Java vector-esque methods for manipulating and querying RDF container objects.

I've also updated a few sections on MDC's RDF FAQ.

Wednesday, December 20, 2006

Setup FireFox Extension Development Environment

I've found that these links are very helpful:

Due to the nature of its graphical user interface, windows shell has been ignored for a long time. It's true that having a point-and-click interface doesn't require learning and remembering, but to boost your productivity, master the art of command line is a must. Be sure to install the cygwin environment and expose its bin folder into your %PATH% variable will bring tons of powerful Unix tools into your windows arsenal with almost no cost.

One thing I really love about the shell is its capability to jump right into your destination folder. For example, if you're developing your FireFox extension, following tips might be quite handy to you.

1. Jump into folders

set FIREFOX_INSTALL_DIR = "C:\Program Files\Mozilla Firefox"
set FIREFOX_DEV_PROFILE = "C:\Documents and Settings\adong\Application Data\Mozilla\Firefox\Profiles\k5b2sa
58.Dev"
// Now you could jump right into it by typing:
cd %FIREFOX_INSTALL_DIR%
cd %FIREFOX_DEV_PROFILE%
2. Start the FireFox in a 'dev' mode by
// instead of "C:\Program Files\Mozilla Firefox\firefox.exe" -P dev
set MOZ_NO_REMOTE=1
%FIREFOX_INSTALL_DIR%\firefox.exe -P dev
3. Or, find the merge point id for the "stausbar"
$ grep -r -n "statusbar .* id=" %firefox_install_dir% | grep ".\.xul:"

Tuesday, December 19, 2006

Goal: to see a python file code structure from command line.
 egrep 'def |class ' {python file}

The grep comes with cygwin seems to have problem with this:

 grep 'def |class ' web.py

but egrep works fine. Seems like 'def |class ' is not supported by standard regular expression. Or put it in another way, it's part of the extended regular expression set.

This article gives a good quick overview on grep, fgrep, and egrep.

When debugging firefox bookmark javascript, I found myself always concatenate multiple line javascript code into one line.

Here is the shell script to redirect it to a local file, where the "notepad" kicks in and automatically load it.
js_merger.py bookmark.js  bookmark.txt  notepad bookmark.txt

And here is the code to automatically do this:
import sys
if len(sys.argv)!=2:
print "Usage: js_merger.py {file.js}"
else:
l = open(sys.argv[1]).readlines()
print "javascript:(function(){" + ' '.join([i.strip() for i in l]) + "})();"


Problem

I have two websites, say one is alex.com and the other is dong.com. I want a javascript in alex.com to send a Ajax.Request to dong.com. In prototype framework, it should be done like this:
new Ajax.Updater('mydiv', 'dong.com/foo/bar', {asynchronous:true});
.The problem is that the second parameter could only be the directory on the same server. AjaxPatterns.com has an article on this topic.

Solution
A little bit HTML+CSS trick,
$('hidden_panel').innerHTML = ' id="cuti_service_request" style="display: none;" src="%27%20+%20url%20+%20%27" title="Server update" iframe -->';

The recommended steps from Bruce Kroeze works perfectly with a few minor modifications. Here are the steps I took to make it work. Check out Bruce's link post for detail explanations.

# Get the code and some other prep works
mkdir ~/tmp
cd ~/tmp
wget http://jaist.dl.sourceforge.net/sourceforge/cheetahtemplate/Cheetah-2.0rc7.tar.gz

# Build Cheetah without copying it to system wide site-package
tar xzf Cheetah-2.0rc7.tar.gz
cd Cheetah-2.0rc7.tar.gz
python setup.py bdist_dumb --relative

# Setup the environment
cd dist
mv lib ~/
mv bin ~/
vim ~/.bash_profile
PATH=$PATH:~/bin
PYTHONPATH=$PYTHONPATH:~/lib/python2.4/site-packages
export PATH PYTHONPATH
source ~/.bash_profile

# Final step: create the symbolic link
cd ~/web/public/{your_web_project}
ln -s ~/lib/python2.4/site-packages/Cheetah .

My day job project is down all in FireFox. We just can't image how to write web applications with FireFox and all its wonderful extensions. There have been many friends who asked me which FireFox extensions I use for web development. Well, I can never give them a full list until I ran into this list: http://lesliefranke.com/files/firefoxwdev/firefoxwdev.htm

Friday, December 15, 2006

What happened before Skype?

Yesterday night, I had a 90 minutes chat with Skype's core founder: Toivo. He is now running Ambient Sound Investment company on behalf of the other three co-founders. Here is a brief list of interesting things we've talked about.

On the team
The average startup founders are 2.5. Yet Skype has four founders. I was wondering how could they make decisions quick enough and, on the same time, have a fair discussion.
Voivo said that they've known each other since elementary school. Have been working together for 4 years when the idea of Skype hit their heads. They know each other's weakness and advantages very clearly. Voivo was managing the project with the other three focused on architecture and implementation.

On the idea
This is the most interesting topic. It turned out that Skype is the forth product the same team have built. Here are some projects Voivo gave out:

  • 1999: A web portal, with basically everything. From news to Email. It didn't go well.
  • 2001: Kazza: Open source P2P technology. This is when they get exposed to the P2P idea I guess.
  • 2002: A CDN, plus PeerCache product. These products brought them some, but not many, customers. The important thing is that during the development process, they used the money to grow the team into 10 people and build Skype as a side project.
  • Nov 2003: The idea of Skype hit them. It took them 4 months to just "think", do architecture work and layout the features.
Lessons learned
At least from Skype's case, they had the team first, then figure out the general direction, a right product is only a natural result of continuous thinking and packaging the same technology for different problems.

Wednesday, December 13, 2006

"""

Synchronize FireFox 2.0 and Microsoft Dictionaries
Author: Alex Dong
Email: $ python -c "'YWxleC5kb25nQGdtYWlsLmNvbQ==\n'.decode('base64')
Blog: http://thetruelight.blogspot.com/
License: GPL
ReadMe:
Please change the 'word_dict_path' and 'ff_dict_path' to point
them to your local directories.
"""

word_dict_path = 'c:/Documents and Settings/adong/Application Data/Microsoft/Proof/custom.dic'
ff_dict_path = 'C:/Documents and Settings/adong/Application Data/Mozilla/Firefox/Profiles/yl9sxfvv.default/persdict.dat'
wd = open(word_dict_path).readlines()
fd = open(ff_dict_path).readlines()

def merge(a, b):
c = [i for i in a]
for i in b:
if c.count(i)==0: c.append(i)
return c

l = merge(wd, fd)
l.sort()

def update(f, l):
fp = open(f, 'w')
fp.writelines(l)
fp.close()
update(word_dict_path, l)
update(ff_dict_path, l)

print "Updated %d entries"%((len(l)-len(wd)) + (len(l)-len(fd)))