<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ronny.haryan.to &#187; Code</title>
	<atom:link href="http://ronny.haryan.to/archives/category/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://ronny.haryan.to</link>
	<description>Print: $9.50 -- Online: free</description>
	<lastBuildDate>Thu, 04 Feb 2010 13:05:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Build Your Own URL Shortening Service</title>
		<link>http://ronny.haryan.to/archives/2009/04/07/build-your-own-url-shortening-service/</link>
		<comments>http://ronny.haryan.to/archives/2009/04/07/build-your-own-url-shortening-service/#comments</comments>
		<pubDate>Tue, 07 Apr 2009 11:11:29 +0000</pubDate>
		<dc:creator>ronny</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://ronny.haryan.to/?p=191</guid>
		<description><![CDATA[Everyone seems to have their own favourite URL shortening service, TinyURL, is.gd, tr.im, pendek.in, and so on. Some even do more than just shorten URLs, e.g. tr.im can track stats. It&#8217;s relatively easy to roll own your own URL shortening service once you know the magic behind it. I&#8217;m going to explain the basic idea [...]]]></description>
			<content:encoded><![CDATA[<p>Everyone seems to have their own favourite URL shortening service, <a href="http://tinyurl.com">TinyURL</a>, <a href="http://is.gd">is.gd</a>, <a href="http://tr.im">tr.im</a>, <a href="http://pendek.in">pendek.in</a>, and so on. Some even do more than just shorten URLs, e.g. tr.im can track stats.</p>

<p>It&#8217;s relatively easy to roll own your own URL shortening service once you know the magic behind it. I&#8217;m going to explain the basic idea so you can start rolling out your own.</p>

<p><ins datetime="2009-04-13T08:35:39+00:00">UPDATE</ins>: check out <a href="http://github.com/jacobian/django-shorturls/tree/master">django-shorturls</a>, a Django app recently created by Simon Willison and Jacob Kaplan-Moss, it uses a similar base 62 approach.</p>

<p><span id="more-191"></span></p>

<h2>How it works</h2>

<p>The basic idea of how these services work is by storing URLs in a database, each with its own
unique ID, which is normally an integer. The ID is then magically converted into a series of
characters which can be used to make up a complete URL that people can pass around to people.</p>

<p>When someone opens the shortened URL with the code, the server will convert the code back into
the unique ID so that it can retrieve the URL in the database. Once the URL is retrieved then
the server will send a HTTP redirect response to the browser.</p>

<h2>The magic</h2>

<p>It&#8217;s not magic, really.</p>

<p>The conversion function from an integer to the short code must produce as short code as possible
while still being practical: the characters in the code must be valid for URLs, no &#8220;funny&#8221;
characters (&#8220;?&#8221;, &#8220;/&#8221;, &#8220;&amp;&#8221;, &#8220;%&#8221;, &#8220;+&#8221; are probably a bad idea).</p>

<p>One of the easiest functions to use for this purpose is to encode the integer (decimal,
base 10 number) into base 36.</p>

<p>Normally we use base 10 to count. In base 10 numbers we only have 10 possibilities (0 to 9) for each
digit before we need add another digit in front of it and roll over to the starting symbol
(&#8220;10&#8243; is two digits, because we have no more possibile symbol to use after &#8220;9&#8243;).</p>

<p>In base 16 (hexadecimal) we add 6 more symbols (&#8220;ABCDEF&#8221;) so that we can count to &#8220;F&#8221; (or 15)
before we need to add a digit in front and roll over to the starting symbol (&#8220;10&#8243;, or 16 in
hexadecimal). If you&#8217;re having trouble following, imagine having 16 fingers and 16 toes to
count with.</p>

<p>Same idea for base 36, but we add the whole 26 Roman alphabets, &#8220;A&#8221; to &#8220;Z&#8221;. So &#8220;Z&#8221; is 35
in base 36, and &#8220;10&#8243; is 36.</p>

<h2>How short is short?</h2>

<p>With a 3-digit base 10 numbers, we can only have 1000 possible combinations (0 to 999).
If I remember my high school math correctly, the formula is N<sup>D</sup> where N is the number of
possibilities for each digit (or the base number, 10 in this case), and D is the number
of digits (3 in this case), so 10<sup>3</sup> = 1000.</p>

<p>The goal is to have as many combinations as possible with as little number of digits as possible.
Since the number of digits will grow over time (as we store more URLs) then the only way
we can increase the number of possible combinations is by increasing the base number.</p>

<p>That&#8217;s why converting from base 10 to base 36 works.</p>

<p>So why stop at 36, you ask. As a matter of fact, we can make use of both uppercase and lowercase
letters of the alphabets so that we can use base 62. If you&#8217;re willing to have non-alphanumeric
characters in your short codes, you can even push it further with a few more characters. In fact,
this is what essentially base 64 encoding does. Be careful though, the commonly found <a href="http://en.wikipedia.org/wiki/Base64">base 64</a> encoding
normally works on <em>strings</em> instead of <em>numbers</em>, converting 6 bits of data at a time, and it
can add paddings, the output is 33.3% longer than the input. Quite different from what we want.</p>

<p>I would probably use base 62 because it&#8217;s slightly more pragmatic and it has less chance of screwing up, but if you insist on using
base 64 (for numbers, not strings), then I suggest you use &#8220;-&#8221; and &#8220;=&#8221; as the additional symbols.
I&#8217;d avoid underscores (&#8220;_&#8221;) because they can be hard to see in links, which are normally shown
underlined.</p>

<p>The following table shows the number of possibilities for some of the bases:</p>

<div class="scrollview">
<table id="comparison-table" border="0">
<thead>
<tr>
    <th>Digits</th>
    <th>Base 10</th>
    <th>Base 26</th>
    <th>Base 36</th>
    <th>Base 62</th>
    <th>Base 64</th>
</tr>
</thead>
<tbody>
<tr>
    <th>2</th>
    <td>100</td>
    <td>676</td>
    <td>1,296</td>
    <td>3,844</td>
    <td>4,096</td>
</tr>
<tr>
    <th>3</th>
    <td>1,000</td>
    <td>17,576</td>
    <td>46,656</td>
    <td>238,328</td>
    <td>262,144</td>
</tr>
<tr>
    <th>4</th>
    <td>10,000</td>
    <td>456,976</td>
    <td>1,679,616</td>
    <td>14,776,336</td>
    <td>16,777,216</td>
</tr>
<tr>
    <th>5</th>
    <td>100,000</td>
    <td>11,881,376</td>
    <td>60,466,176</td>
    <td>916,132,832</td>
    <td>1,073,741,824</td>
</tr>
<tr>
    <th>6</th>
    <td>1,000,000</td>
    <td>308,915,776</td>
    <td>2,176,782,336</td>
    <td>56,800,235,584</td>
    <td>68,719,476,736</td>
</tr>
</tbody>
</table>
</div>

<p>Say, you add 1 million new URLs every month on average. With base 62, it would take a little over a year to use up all the possible 4 digits, and after that it would take another 75 years to use up
all the possible 5 digits, and after that it would take another 4,658 years to use up all the
possible 6 digits, and so on.</p>

<p>It would probably take even longer to use up the digits if you don&#8217;t add URLs that are already in
the database. Conversely, you might use up the digits faster if you want to do per-user tracking,
for example.</p>

<h2>Sample code</h2>

<p>Here&#8217;s a simple Python code that you can use to convert an integer to a base N &#8220;number&#8221;
(actually string), and vice versa.</p>

<pre><code># Code adapted from: http://en.wikipedia.org/wiki/Base_36#Python_Conversion_Code
# This is base 62:
ALPHABETS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

def base_n_decode(s, alphabets=ALPHABETS):
    n = len(alphabets)
    rv = pos = 0
    charlist = list(s)
    charlist.reverse()
    for char in charlist:
        rv += alphabets.find(char) * n**pos
        pos += 1
    return rv

def base_n_encode(num, alphabets=ALPHABETS):
    n = len(alphabets)
    rv = ""
    while num != 0:
        rv = alphabets[num % n] + rv
        num /= n
    return rv
</code></pre>

<h2>Can&#8217;t we just use MD5?</h2>

<p>No. We can&#8217;t use hash functions like MD5, because hash functions are one-way, irreversible, meaning
we can&#8217;t get the original input just from knowing the hash code. Also, hash functions can have
collisions, meaning from one hash code there is a remote possibility that it &#8220;maps&#8221; back to two
or more URLs. Plus, the output of hash functions are normally long-ish fixed-length strings.</p>

<h2>So, what are you waiting for?</h2>

<p>Now that the magic is revealed, you can create your own URL shortening service. Be creative and
innovative so you can compete with all the other URL shortening services out there.</p>

<p>As a bonus, you can also use this technique to shorten the permalinks or absolute URLs for your
objects in your <a href="http://djangoproject.com">Django</a> (or Rails, etc.) websites. So instead of <code>http://example.com/post/12345</code>
it would be <code>http://example.com/post/3D7</code>. Note that this has nothing to do with security
whatsoever. The coded ID can still be reversed with some effort. And you shouldn&#8217;t rely on
obfuscation to protect anything anyway.</p>
]]></content:encoded>
			<wfw:commentRss>http://ronny.haryan.to/archives/2009/04/07/build-your-own-url-shortening-service/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>psycopg2 and 64-bit Apache on Leopard</title>
		<link>http://ronny.haryan.to/archives/2008/09/12/psycopg2-and-64-bit-apache-on-leopard/</link>
		<comments>http://ronny.haryan.to/archives/2008/09/12/psycopg2-and-64-bit-apache-on-leopard/#comments</comments>
		<pubDate>Fri, 12 Sep 2008 11:27:07 +0000</pubDate>
		<dc:creator>ronny</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://ronny.haryan.to/archives/2008/09/12/psycopg2-and-64-bit-apache-on-leopard/</guid>
		<description><![CDATA[The Apache httpd that comes with Mac OS X Leopard runs in 64-bit mode, so everything else that&#8217;s loaded, including mod_wsgi and psycopg2 must be able to run in 64-bit mode as well. Graham Dumpleton explained this behaviour in a post to the django-users mailing list. Compiling psycopg2 using MacPorts as well as from the [...]]]></description>
			<content:encoded><![CDATA[<p>The Apache httpd that comes with Mac OS X Leopard runs in 64-bit mode, so everything else that&#8217;s loaded, including <a href="http://code.google.com/p/modwsgi/">mod_wsgi</a> and <a href="http://initd.org/pub/software/psycopg/">psycopg2</a> must be able to run in 64-bit mode as well. Graham Dumpleton explained this behaviour in <a href="http://groups.google.com/group/django-users/msg/1c2537650eb3c79b">a post to the django-users mailing list</a>.</p>

<p>Compiling psycopg2 using MacPorts as well as from the tarball would result in something like this when loaded from a web application that runs on Apache:</p>

<pre><code>ImproperlyConfigured: Error loading psycopg2 module: dlopen(/Library/Python/2.5/site-packages/psycopg2/_psycopg.so, 2): no suitable image found.  Did find: /Library/Python/2.5/site-packages/psycopg2/_psycopg.so: no matching architecture in universal wrapper
</code></pre>

<p>So all I needed to do was force psycopg2 extension to be built for 64-bit as well as 32-bit. After extracting the latest psycopg2 source, do this instead:</p>

<pre><code>LDFLAGS="-arch ppc -arch i386 -arch x86_64" CFLAGS="-arch ppc -arch i386 -arch x86_64" python setup.py build
</code></pre>

<p>Then <code>sudo python setup.py install</code>. After that, check the .so file, it should look something like this:</p>

<pre><code>$ file /Library/Python/2.5/site-packages/psycopg2/_psycopg.so 
/Library/Python/2.5/site-packages/psycopg2/_psycopg.so: Mach-O universal binary with 3 architectures
/Library/Python/2.5/site-packages/psycopg2/_psycopg.so (for architecture i386): Mach-O bundle i386
/Library/Python/2.5/site-packages/psycopg2/_psycopg.so (for architecture ppc7400):      Mach-O bundle ppc
/Library/Python/2.5/site-packages/psycopg2/_psycopg.so (for architecture x86_64):       Mach-O 64-bit bundle x86_64
</code></pre>

<p>Don&#8217;t forget to restart Apache, and that should be it.</p>

<p>Update: It happened to <a href="http://www.pythonware.com/products/pil/">PIL</a> too, it was giving this error: <code>The _imaging C module is not installed</code>, so I had to do the same thing as above: <code>LDFLAGS=... CFLAGS=... python setup.py build</code> followed by <code>sudo python setup.py install</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://ronny.haryan.to/archives/2008/09/12/psycopg2-and-64-bit-apache-on-leopard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D-Bus Multimedia Keys Plugin for Quod Libet</title>
		<link>http://ronny.haryan.to/archives/2007/05/11/d-bus-multimedia-keys-plugin-for-quod-libet/</link>
		<comments>http://ronny.haryan.to/archives/2007/05/11/d-bus-multimedia-keys-plugin-for-quod-libet/#comments</comments>
		<pubDate>Fri, 11 May 2007 00:09:53 +0000</pubDate>
		<dc:creator>ronny</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://ronny.haryan.to/archives/2007/05/11/d-bus-multimedia-keys-plugin-for-quod-libet/</guid>
		<description><![CDATA[Since upgrading my Ubuntu desktop to Feisty my multimedia keys stopped working when using Quod Libet, although they work fine with Rhythmbox and Totem. This is because in GNOME 2.18 that comes with Feisty, gnome-settings-daemon &#8216;grabs&#8217; all multimedia keys preventing other applications to capture them. Multimedia key press events are now being broadcast via D-Bus. [...]]]></description>
			<content:encoded><![CDATA[<p>Since upgrading my Ubuntu desktop to <a href="https://wiki.ubuntu.com/FeistyFawn">Feisty</a> my multimedia keys stopped working when using <a href="http://ronny.haryan.to/archives/2006/08/26/quod-libet-and-mutagen/">Quod Libet</a>, although they work fine with Rhythmbox and Totem. This is because in GNOME 2.18 that comes with Feisty, gnome-settings-daemon &#8216;grabs&#8217; all multimedia keys preventing other applications to capture them. Multimedia key press events are now being broadcast via D-Bus. Therefore applications that need to listen to those events could subscribe to the proper D-Bus interface. Other GNOME apps like Rhythmbox and Totem had picked up the changes and had been adjusted accordingly. That&#8217;s why they still work in Feisty. But Quod Libet is not a GNOME application, so this new method of multimedia keys handling that is specific to GNOME should not be implemented inside the Quod Libet core. This is documented in <a href="https://bugs.launchpad.net/bugs/43464">bug #43464</a> in Launchpad.</p>

<p>Joe Wreschnig, Quod Libet&#8217;s author, suggested that this could be implemented as a plugin. After an email conversation with him, and seeing a patch posted to the bug in launchpad, I started writing the plugin last night. Now the multimedia keys work again in Quod Libet. The plugin can be downloaded <a href="http://librarian.launchpad.net/7598413/dbusmmkey.py">from launchpad</a> or <a href="http://ronny.haryan.to/files/dbusmmkey.py.txt">from here</a> (rename to <code>dbusmmkey.py</code>). Simply put this file in <code>~/.quodlibet/plugins/events/</code> and enable it in Quod Libet.</p>

<p>PS. <a href="http://www.python.org/">Python</a> is so much fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://ronny.haryan.to/archives/2007/05/11/d-bus-multimedia-keys-plugin-for-quod-libet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WP Yahoo! Smileys Plugin Hacking</title>
		<link>http://ronny.haryan.to/archives/2005/03/26/wp-yahoo-smileys-plugin-hacking/</link>
		<comments>http://ronny.haryan.to/archives/2005/03/26/wp-yahoo-smileys-plugin-hacking/#comments</comments>
		<pubDate>Fri, 25 Mar 2005 14:14:17 +0000</pubDate>
		<dc:creator>ronny</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://ronny.haryan.to/archives/2005/03/26/wp-yahoo-smileys-plugin-hacking/</guid>
		<description><![CDATA[I&#8217;ve spent most of my Good Friday holiday installing Priyadi&#8217;s im_smiley plugin. The install process itself was very quick and painless, but I found some bugs, and I wanted to have clickable smileys, and I had to figure out how to have live preview of the comment, so it took a while. The bugs were [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve spent most of my Good Friday holiday installing <a href="http://priyadi.net/archives/2005/02/27/wordpress-yahoomsn-messenger-style-smileys-plugin/">Priyadi&#8217;s im_smiley plugin</a>. The install process itself was very quick and painless, but I found some bugs, and I wanted to have clickable smileys, and I had to figure out how to have live preview of the comment, so it took a while. The bugs were quickly ironed out by Priyadi. The live preview bit didn&#8217;t take very long to implement either.</p>

<p>The clickable smileys was not part of the original plugin, so I modified the plugin to provide that functionality. I notified Priyadi about my modifications, he quickly incorporated my changes and adjusted them to his code. He released version 4.0 of the plugin right away. :D</p>

<p>You can get the plugin from <a href="http://priyadi.net/archives/2005/02/27/wordpress-yahoomsn-messenger-style-smileys-plugin/">Priyadi&#8217;s im_smiley plugin</a>, or from my <a href="/files/im_smiley.txt">local copy</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://ronny.haryan.to/archives/2005/03/26/wp-yahoo-smileys-plugin-hacking/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>My .muttrc for Mutt</title>
		<link>http://ronny.haryan.to/archives/2005/03/03/my-muttrc-for-mutt/</link>
		<comments>http://ronny.haryan.to/archives/2005/03/03/my-muttrc-for-mutt/#comments</comments>
		<pubDate>Thu, 03 Mar 2005 03:24:47 +0000</pubDate>
		<dc:creator>ronny</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://ronny.haryan.to/archives/2005/03/03/my-muttrc-for-mutt/</guid>
		<description><![CDATA[Yes, let&#8217;s make the RC day complete. Here&#8217;s my .muttrc for Mutt as well. This time it&#8217;s a bit different than before, because I split my original muttrc into several files. So here&#8217;s the complete set of the files: muttrc keybindings colors gpg hooks lists mailcap smime vimrc I put everything in $HOME/.mutt/ except the [...]]]></description>
			<content:encoded><![CDATA[<p>Yes, let&#8217;s make the RC day complete. Here&#8217;s <a href="/files/muttrc">my <code>.muttrc</code></a> for <a href="http://www.mutt.org">Mutt</a> as well. This time it&#8217;s a bit different than before, because I split my original muttrc into several files. So here&#8217;s the complete set of the files:</p>

<ul>
<li><a href="/files/muttrc">muttrc</a></li>
<li><a href="/files/mutt/keybindings">keybindings</a></li>
<li><a href="/files/mutt/colors">colors</a></li>
<li><a href="/files/mutt/gpg">gpg</a></li>
<li><a href="/files/mutt/hooks">hooks</a></li>
<li><a href="/files/mutt/lists">lists</a></li>
<li><a href="/files/mutt/mailcap">mailcap</a></li>
<li><a href="/files/mutt/smime">smime</a></li>
<li><a href="/files/mutt/vimrc">vimrc</a></li>
</ul>

<p>I put everything in <code>$HOME/.mutt/</code> except the <code>.muttrc</code> file. You also need your own <code>$HOME/.mutt/aliases</code> containing your personal address book. </p>
]]></content:encoded>
			<wfw:commentRss>http://ronny.haryan.to/archives/2005/03/03/my-muttrc-for-mutt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My .vimrc for Vim</title>
		<link>http://ronny.haryan.to/archives/2005/03/03/my-vimrc/</link>
		<comments>http://ronny.haryan.to/archives/2005/03/03/my-vimrc/#comments</comments>
		<pubDate>Thu, 03 Mar 2005 01:18:44 +0000</pubDate>
		<dc:creator>ronny</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://ronny.haryan.to/archives/2005/03/03/my-vimrc/</guid>
		<description><![CDATA[Here&#8217;s my .vimrc configuration file for Vim. I will update the file from time to time but the URL for the file will remain the same. I use the same .vimrc when I&#8217;m in Linux, Windows, Solaris and Mac OS X. The file is mostly commented so you can change or customize it to your [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s <a href="/files/vimrc">my <code>.vimrc</code></a> configuration file for <a href="http://www.vim.org">Vim</a>. I will update the file from time to time but the URL for the file will remain the same.</p>

<p>I use the same <code>.vimrc</code> when I&#8217;m in Linux, Windows, Solaris and Mac OS X. The file is mostly commented so you can change or customize it to your own liking. Some parts are taken from various sources but maybe I forgot to write credits in the comments, if you spot any please inform me. </p>
]]></content:encoded>
			<wfw:commentRss>http://ronny.haryan.to/archives/2005/03/03/my-vimrc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Indonesian Wikipedia Search Plugin for Mozilla/Firefox</title>
		<link>http://ronny.haryan.to/archives/2004/11/04/indonesian-wikipedia-search-plugin-for-mozillafirefox/</link>
		<comments>http://ronny.haryan.to/archives/2004/11/04/indonesian-wikipedia-search-plugin-for-mozillafirefox/#comments</comments>
		<pubDate>Thu, 04 Nov 2004 10:29:54 +0000</pubDate>
		<dc:creator>ronny</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://ronny.haryan.to/archives/2004/11/04/indonesian-wikipedia-search-plugin-for-mozillafirefox/</guid>
		<description><![CDATA[Add Indonesian Wikipedia Search Plugin. Based on the original English Wikipedia plugin from mycroft. Note: see my previous post if you&#8217;re using Firefox on a non-Windows platform.]]></description>
			<content:encoded><![CDATA[<script type="text/javascript" src="/files/addengine.js"></script>

<p><a href="javascript:addEngine('wikipedia-id','png','Reference')">Add Indonesian Wikipedia Search Plugin</a>. Based on the <a href="http://mycroft.mozdev.org/quick/wikipedia.html">original English Wikipedia plugin from mycroft</a>.</p>

<p>Note: see <a href="http://ronny.haryan.to/archives/2004/11/03/firefox-search-plugins-linux/trackback/">my previous post</a> if you&#8217;re using Firefox on a non-Windows platform.</p>
]]></content:encoded>
			<wfw:commentRss>http://ronny.haryan.to/archives/2004/11/04/indonesian-wikipedia-search-plugin-for-mozillafirefox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
