<?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>Silas Sewell - Programming</title>
        <atom:link href="http://www.silassewell.com/blog/tag/programming/rss2.xml" rel="self" type="application/rss+xml" />
        <link>http://www.silassewell.com/blog/tag/programming</link>
        <description>Infrastructure Development</description>
        <lastBuildDate>Sat, 08 Jan 2011 00:00:00 GMT</lastBuildDate>
        <generator>http://www.silassewell.com/</generator>
        <language>en</language>
        <sy:updatePeriod>hourly</sy:updatePeriod>
        <sy:updateFrequency>1</sy:updateFrequency>

        <item>
            <title>Stomping with Python and ActiveMQ (Stomp Framework)</title>
            <link>http://www.silassewell.com/blog/2009/08/27/stomping-with-python-and-activemq-stomp-framework/</link>
            <pubDate>Thu, 27 Aug 2009 00:00:00 GMT</pubDate>
            <dc:creator>silas</dc:creator>
            <category><![CDATA[ActiveMQ]]></category><category><![CDATA[Fedora]]></category><category><![CDATA[Programming]]></category><category><![CDATA[Projects]]></category><category><![CDATA[Python]]></category><category><![CDATA[python-stomping]]></category><category><![CDATA[STOMP]]></category>
            <guid isPermaLink="true">http://www.silassewell.com/blog/2009/08/27/stomping-with-python-and-activemq-stomp-framework/</guid>
            <description><![CDATA[<p><a href="http://silassewell.googlecode.com/svn/trunk/projects/python-stomping" title="Python Stomping">python-stomping</a> is a simple <a href="http://en.wikipedia.org/wiki/Streaming_Text_Orientated_Messaging_Protocol" title="Stomp">Stomp</a> framework I wrote which makes
creating stomp services in Python easy.</p>

<ol>
<li><p>Install requirements</p>

<pre><code class="prettyprint">$ sudo yum install python-twisted python-stomper
</code></pre></li>
<li><p>Checkout stomping</p>

<pre><code class="prettyprint">$ svn export http://silassewell.googlecode.com/svn/trunk/projects/python-stomping python-stomping
$ cd python-stomping
</code></pre></li>
<li><p>Update the <code class="prettyprint">example.py</code> file to use your <code class="prettyprint">host</code>, <code class="prettyprint">port</code>, <code class="prettyprint">username</code> and
<code class="prettyprint">password</code> ActiveMQ/Stomp broker settings</p>

<pre><code class="prettyprint">from stomping import Stomping, route

class MyStomping(Stomping):

def init(self):
    self.send('/queue/test1', 'init test1')
    self.send('/queue/test2', 'init test2')

@route('/queue/test1')
def a_test(self, message):
    print 'a_test: %s' % message['body']

@route('/queue/test1')
@route('/queue/test2')
def b_test(self, message):
    print 'b_test: %s' % message['body']

if __name__ == '__main__':
    stomp = MyStomping(host='127.0.0.1', port=61613, username='guest', password='guest')
    stomp.run()
</code></pre></li>
<li><p>Run <code class="prettyprint">example.py</code> (Ctrl+c to quit)</p>

<pre><code class="prettyprint">$ python example.py 
a_test: init test1
b_test: init test1
b_test: init test2
</code></pre></li>
</ol>

<p>NOTE: python-stomping is just a light wrapper around Twisted and stomper and is
based on an <a href="http://code.google.com/p/stomper/source/browse/trunk/lib/stomper/examples/sender.py" title="sender example">example</a> provided in the stomper code.</p>]]></description>
        </item>

        <item>
            <title>Python Line-by-line Profiler (line_profiler and kernprof)</title>
            <link>http://www.silassewell.com/blog/2009/05/28/python-line-by-line-profiler-line_profiler-and-kernprof/</link>
            <pubDate>Thu, 28 May 2009 00:00:00 GMT</pubDate>
            <dc:creator>silas</dc:creator>
            <category><![CDATA[Fedora]]></category><category><![CDATA[kernprof]]></category><category><![CDATA[line_profiler]]></category><category><![CDATA[Programming]]></category><category><![CDATA[Python]]></category><category><![CDATA[RPM]]></category>
            <guid isPermaLink="true">http://www.silassewell.com/blog/2009/05/28/python-line-by-line-profiler-line_profiler-and-kernprof/</guid>
            <description><![CDATA[<p>The following is a quick and dirty guide to getting started with
<a href="http://packages.python.org/line_profiler/" title="line profiler">line_profiler</a>, a Python line-by-line profiler, on Fedora.</p>

<ol>
<li><a href="http://code.google.com/p/silassewell/wiki/PackagingRPMs" title="Packaging RPMS">Build</a> and install the <a href="http://silassewell.googlecode.com/files/python-line_profiler-1.0-0.1.b2.fc10.src.rpm" title="line profiler SRPM">python-line_profiler</a> package</li>
<li><p>Create a file called <code class="prettyprint">test.py</code> with the code below</p>

<pre><code class="prettyprint">import random, time

def sleep():
    seconds = random.randint(0, 5)
    print 'Sleeping %s seconds' % seconds
    time.sleep(seconds)

@profile
def test():
    sleep()
    sleep()
    sleep()

test()
</code></pre></li>
<li><p>Profile <code class="prettyprint">test.py</code></p>

<pre><code class="prettyprint">[silas@silas ~]$ kernprof.py -l test.py
Sleeping 4 seconds
Sleeping 5 seconds
Sleeping 2 seconds
Wrote profile results to test.py.lprof
</code></pre></li>
<li><p>View the results</p>

<pre><code class="prettyprint">[silas@silas ~]$ python -m line_profiler test.py.lprof
Timer unit: 1e-06 s

File: test.py
Function: test at line 8
Total time: 10.9994 s

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     8                                           @profile
     9                                           def test():
    10         1      3999416 3999416.0     36.4      sleep()
    11         1      4999982 4999982.0     45.5      sleep()
    12         1      1999990 1999990.0     18.2      sleep()
</code></pre></li>
</ol>

<p>NOTE: I have a <a href="https://bugzilla.redhat.com/show_bug.cgi?id=502978" title="Package Review">package review</a> up for line_profiler and it should be
available via yum eventually.</p>]]></description>
        </item>

        <item>
            <title>funcshell — A Shell Interface to Func</title>
            <link>http://www.silassewell.com/blog/2009/04/22/funcshell-a-shell-interface-to-func/</link>
            <pubDate>Wed, 22 Apr 2009 00:00:00 GMT</pubDate>
            <dc:creator>silas</dc:creator>
            <category><![CDATA[Fedora]]></category><category><![CDATA[Func]]></category><category><![CDATA[FuncShell]]></category><category><![CDATA[Programming]]></category><category><![CDATA[Projects]]></category><category><![CDATA[Systems Administration]]></category>
            <guid isPermaLink="true">http://www.silassewell.com/blog/2009/04/22/funcshell-a-shell-interface-to-func/</guid>
            <description><![CDATA[<h3>Features</h3>

<ul>
<li>advanced client selection (you can use + and - to add/remove hosts/groups)</li>
<li>tab completion</li>
<li>persistent history</li>
<li>a command sub-shell</li>
<li>quick help (just hit the "?" key)</li>
</ul>

<p><strong>funcshell</strong> took a similar approach to features as Func; it allows developers to easily extend and customize its functionality using a plugin system. It also assumes the most useful commands will be the ones you write yourself. That being said, funcshell currently comes with both the command and service module.</p>

<p>Here are some things you can do with funcshell.</p>

<p>Get a list of all clients (not very useful if you have hundreds):</p>

<pre><code class="prettyprint">funcshell&gt; set clients *
funcshell&gt; get clients
webapp001.example.net
webapp002.example.net
webapp003.example.net
webstatic001.example.net
webstatic002.example.net
</code></pre>

<p>Assuming <code class="prettyprint">webapp00[1-3].example.net</code> are in the <code class="prettyprint">app</code> and <code class="prettyprint">bpstatic00[1-2].example.net1</code> are in the <code class="prettyprint">static</code> groups; remove some clients and restart a service:</p>

<pre><code class="prettyprint">funcshell&gt; set clients - @static;webapp001*
funcshell&gt; get clients
webapp002.example.net
webapp003.example.net
funcshell&gt; service httpd restart
==&gt; webapp003.example.net &lt;==
True
==&gt; webapp002.example.net &lt;==
True
</code></pre>

<p>Run a command and get the results:</p>

<pre><code class="prettyprint">funcshell&gt; set clients - webapp003*
funcshell&gt; set clients + webstatic002*
funcshell&gt; command run grep MemTotal /proc/meminfo | awk '{ print $2/1024 }'
==&gt; webstatic002.example.net :: 0 &lt;==
4099.44
==&gt; webapp002.example.net :: 0 &lt;==
8198.88
</code></pre>

<p>Get help:</p>

<pre><code class="prettyprint">funcshell&gt; command &lt;TAB&gt;&lt;TAB&gt;
exists   run      shell
funcshell&gt; command ?
  exists Check if a command exists
  run    Run a command
  shell  Run a command shell
</code></pre>

<p>Run a couple of commands in a row:</p>

<pre><code class="prettyprint">funcshell&gt; set c&lt;TAB&gt; @static
funcshell&gt; command shell
&gt; du -sh /tmp
==&gt; webstatic002.example.net :: 0 &lt;==
7.2M    /tmp
==&gt; webstatic001.example.net :: 0 &lt;==
3.4M    /tmp
&gt; cp -r /tmp /tmp
==&gt; webstatic002.example.net :: 1 &lt;==
cp: cannot copy a directory, '/tmp', into itself, '/tmp/tmp'
==&gt; webstatic001.example.net :: 1 &lt;==
cp: cannot copy a directory, '/tmp', into itself, '/tmp/tmp'
&gt; asdf
==&gt; webstatic002.example.net :: 127 &lt;==
/bin/sh: asdf: command not found
==&gt; webstatic001.example.net :: 127 &lt;==
/bin/sh: asdf: command not found
&gt; &lt;CTRL-D&gt;
funcshell&gt; exit
</code></pre>

<p><a href="http://github.com/silas/funcshell" title="funcshell">funcshell</a> is a shell interface to <a href="https://fedorahosted.org/func/" title="func">Func</a> which provides some useful features for managing a large number of machines.</p>]]></description>
        </item>

        <item>
            <title>Getting Started with AMQP, Qpid, Python &amp; Fedora</title>
            <link>http://www.silassewell.com/blog/2009/03/29/getting-started-with-amqp-qpid-python-fedora/</link>
            <pubDate>Sun, 29 Mar 2009 00:00:00 GMT</pubDate>
            <dc:creator>silas</dc:creator>
            <category><![CDATA[AMQP]]></category><category><![CDATA[Enterprise Messaging]]></category><category><![CDATA[Fedora]]></category><category><![CDATA[Programming]]></category><category><![CDATA[python-qpid]]></category><category><![CDATA[Qpid]]></category>
            <guid isPermaLink="true">http://www.silassewell.com/blog/2009/03/29/getting-started-with-amqp-qpid-python-fedora/</guid>
            <description><![CDATA[<p>The <a href="http://en.wikipedia.org/wiki/AMQP" title="Advanced Message Queuing Protocol">Advanced Message Queuing Protocol</a> (AMQP) is the first open
standard for Enterprise Messaging and has been adopted by Cisco,
[Microsoft][microsoft], Novel, <a href="http://www.redhat.com/solutions/specifications/amqp/" title="Red Hat">Red Hat</a> and <a href="http://jira.amqp.org/confluence/display/AMQP/AMQP+Working+Group" title="others">others</a>.</p>

<p>One implementation of AMQP currently packaged by <a href="http://www.redhat.com/mrg/messaging/" title="Red Hat">Red Hat</a> and Fedora is
Qpid. <a href="http://qpid.apache.org/" title="Qpid">Qpid</a> is a collection of brokers (C++, Java) and clients (C++,
Java, Python, Ruby) which <a href="http://qpid.apache.org/amqp-compatibility.html">aims to be 100% AMQP Compliant</a>.</p>

<p>Below is a step-by-step tutorial on getting started with Qpid and the Python
client in Fedora.</p>

<ol>
<li><p>Install the Qpid broker and Python client</p>

<pre><code class="prettyprint">yum install qpidd python-qpid
</code></pre></li>
<li><p>Start the broker</p>

<pre><code class="prettyprint">service qpidd start
</code></pre></li>
<li><p>Create a message producer (<code class="prettyprint">producer.py</code>)</p>

<pre><code class="prettyprint">from qpid.connection import Connection
from qpid.datatypes import Message, uuid4
from qpid.util import connect

# Create connection and session
socket = connect('localhost', 5672)
connection = Connection(sock=socket, username='guest', password='guest')
connection.start()
session = connection.session(str(uuid4()))

# Setup queue
session.queue_declare(queue='message_queue')
session.exchange_bind(exchange='amq.direct', queue='message_queue', binding_key='routing_key')

# Setup routing properties
properties = session.delivery_properties(routing_key='routing_key')

# Send messages
session.message_transfer(destination='amq.direct', message=Message(properties, 'Message one'))
session.message_transfer(destination='amq.direct', message=Message(properties, 'Message two'))
session.message_transfer(destination='amq.direct', message=Message(properties, 'Done'))

# Close session
session.close(timeout=10)
</code></pre></li>
<li><p>Create a message consumer (<code class="prettyprint">consumer.py</code>)</p>

<pre><code class="prettyprint">from qpid.connection import Connection
from qpid.datatypes import RangedSet, uuid4
from qpid.util import connect

# Create connection and session
socket = connect('localhost', 5672)
connection = Connection(sock=socket, username='guest', password='guest')
connection.start()
session = connection.session(str(uuid4()))

# Define local queue
local_queue_name = 'my_local_queue'

# Create local queue
queue = session.incoming(local_queue_name)

# Route messages from message_queue to my_local_queue
session.message_subscribe(queue='message_queue', destination=local_queue_name)
queue.start()

content = ''

while content != 'Done':
    # Get message from the local queue
    message = queue.get(timeout=10)
    # Get body of the message
    content = message.body
    # Accept message (removes it from the queue)
    session.message_accept(RangedSet(message.id))
    # Print message content
    print content

# Close session
session.close(timeout=10)
</code></pre></li>
<li><p>First run the producer and then the consumer</p>

<pre><code class="prettyprint">Message one
Message two
Done
</code></pre></li>
</ol>

<p>Source: <a href="https://svn.apache.org/repos/asf/qpid/trunk/qpid/python/examples/direct/" title="Qpid direct example">Qpid direct example</a></p>]]></description>
        </item>

        <item>
            <title>String Slicing in Bash (like Python)</title>
            <link>http://www.silassewell.com/blog/2009/03/12/string-slicing-in-bash-like-python/</link>
            <pubDate>Thu, 12 Mar 2009 00:00:00 GMT</pubDate>
            <dc:creator>silas</dc:creator>
            <category><![CDATA[Bash]]></category><category><![CDATA[Programming]]></category><category><![CDATA[Python]]></category><category><![CDATA[String]]></category><category><![CDATA[Systems Administration]]></category>
            <guid isPermaLink="true">http://www.silassewell.com/blog/2009/03/12/string-slicing-in-bash-like-python/</guid>
            <description><![CDATA[<p>A simple function to slice strings in Bash similar to Python's string slicing functionality.</p>

<h3>Examples</h3>

<pre><code class="prettyprint">[silas@pluto ~]$ string_slice "12345" 0 1
1
[silas@pluto ~]$ string_slice "12345" 0 3
123
[silas@pluto ~]$ string_slice "12345" 2 3
3
[silas@pluto ~]$ string_slice "12345" 2 -2
3
[silas@pluto ~]$ string_slice "12345" -3
345
</code></pre>

<h3>Implementation</h3>

<pre><code class="prettyprint">function string_slice {
    STRING="$1"
    declare -i LENGTH="${#STRING}"
    declare -i START="$2"
    declare -i END="$3"
    if [ $START -lt 0 ]; then
        START=$[ $LENGTH + $START ]
    fi
    if [ $END -le 0 ]; then
        END=$[ $LENGTH + $END ]
    fi
    START=$[ $START + 1 ]
    (echo "$STRING" | cut -c $START-$END) 2&gt; /dev/null
}
</code></pre>]]></description>
        </item>

        <item>
            <title>Push: Func Module to Run Arbitrary Python Code</title>
            <link>http://www.silassewell.com/blog/2008/11/18/push-func-module-to-run-arbitrary-python-code/</link>
            <pubDate>Tue, 18 Nov 2008 00:00:00 GMT</pubDate>
            <dc:creator>silas</dc:creator>
            <category><![CDATA[Func]]></category><category><![CDATA[Programming]]></category><category><![CDATA[Python]]></category><category><![CDATA[Systems Administration]]></category>
            <guid isPermaLink="true">http://www.silassewell.com/blog/2008/11/18/push-func-module-to-run-arbitrary-python-code/</guid>
            <description><![CDATA[<p><a href="https://fedorahosted.org/func/" title="Func">Func</a> is a nifty, although not yet polished, Python-based service for
running tasks on many hosts at once. It lets you do things like restart
<a href="https://fedorahosted.org/func/wiki/ServiceModule" title="Service Module">Apache instances</a>, <a href="https://fedorahosted.org/func/wiki/YumModule" title="Yum Module">run yum updates</a> or
<a href="https://fedorahosted.org/func/wiki/VirtModule" title="Virt Module">provision virtual machines</a>.</p>

<p>You can accomplish theses tasks via the command line interface</p>

<pre><code class="prettyprint">func web-*.example.net call service restart httpd
</code></pre>

<p>or through the Python API</p>

<pre><code class="prettyprint">import func.overlord.client as fc

client = fc.Client('web-*.example.net')

print client.service.restart('httpd')
</code></pre>

<p>One of the annoying issues I'm dealing with right now is the distribution of
Func modules, which for various reasons isn't as simple as packaging the
modules and pushing them to all the hosts (it is, just not in my network).</p>

<p>My solution is <a href="http://www.silassewell.com/blog/2008/11/18/push-func-module-to-run-arbitrary-python-code/push.py">Push</a>, a Func module which lets you instantly run Python
code on any or all hosts in your network.</p>

<p>Example usage:</p>

<pre><code class="prettyprint">import func.overlord.client as fc

client = fc.Client('web-*.example.net')

source = """
def main():
    return 'Hello World'
"""

print client.push.code(source)
</code></pre>

<p>I realize this isn't the most elegant solution, but its very useful and
extremely simple.</p>

<p>I also realize that I could use the copyfile module to push modules via Func,
but I haven't found a way to restart funcd via Func (required to initialize
modules), so until that happens I need a solution which doesn't require
restarting Func.</p>

<p><a href="http://www.silassewell.com/blog/2008/11/18/push-func-module-to-run-arbitrary-python-code/push.py">Get Push Module</a></p>]]></description>
        </item>

        <item>
            <title>C GMP Hello World on Leopard (OS X 10.5)</title>
            <link>http://www.silassewell.com/blog/2008/10/19/c-gmp-hello-world-on-leopard-os-x-105/</link>
            <pubDate>Sun, 19 Oct 2008 00:00:00 GMT</pubDate>
            <dc:creator>silas</dc:creator>
            <category><![CDATA[C]]></category><category><![CDATA[GMP]]></category><category><![CDATA[Hello World]]></category><category><![CDATA[Mathematics]]></category><category><![CDATA[Programming]]></category>
            <guid isPermaLink="true">http://www.silassewell.com/blog/2008/10/19/c-gmp-hello-world-on-leopard-os-x-105/</guid>
            <description><![CDATA[<p>A simple <a href="http://gmplib.org/" title="GMP">GMP</a> Hello World example in C.</p>

<h3>Makefile</h3>

<pre><code class="prettyprint">all:
    gcc -o gmp_hello_world gmp_hello_world.c -lgmp -m64

clean:
    rm gmp_hello_world
</code></pre>

<h3>gmp_hello_world.c</h3>

<pre><code class="prettyprint">/*
 * GMP Hello World on OS X 10.5
*/
#include &lt;gmp.h&gt;
#include &lt;stdio.h&gt;

int main() {
  mpz_t add_total1, add_total2, sub_total1, sub_total2, mul_total1, mul_total2;
  mpz_t num1, num2;

  // Initialize variables
  mpz_init_set_str(num1, "345192567923875922375736284875732", 10);
  mpz_init_set_str(num2, "937929298382994742939293857584837", 10);
  mpz_init(add_total1);
  mpz_init(add_total2);
  mpz_init(sub_total1);
  mpz_init(sub_total2);
  mpz_init(mul_total1);
  mpz_init(mul_total2);

  // Do arithmetic
  mpz_add(add_total1, num1, num2);
  mpz_add_ui(add_total2, num1, 10);
  mpz_sub(sub_total1, num1, num2);
  mpz_sub_ui(sub_total2, num1, 10);
  mpz_mul(mul_total1, num1, num2);
  mpz_mul_ui(mul_total2, num1, 10);

  // Display results
  gmp_printf("Add Total 1: %Zd\n", add_total1);
  gmp_printf("Add Total 2: %Zd\n", add_total2);
  gmp_printf("Subtract Total 1: %Zd\n", sub_total1);
  gmp_printf("Subtract Total 2: %Zd\n", sub_total2);
  gmp_printf("Multiply Total 1: %Zd\n", mul_total1);
  gmp_printf("Multiply Total 2: %Zd\n", mul_total2);

  // Free space
  mpz_clear(num1);
  mpz_clear(num2);
  mpz_clear(add_total1);
  mpz_clear(add_total2);
  mpz_clear(sub_total1);
  mpz_clear(sub_total2);
  mpz_clear(mul_total1);
  mpz_clear(mul_total2);

  return 0;
}
</code></pre>]]></description>
        </item>

        <item>
            <title>Persistent Queuing in Python</title>
            <link>http://www.silassewell.com/blog/2008/09/26/persistent-queuing-python/</link>
            <pubDate>Fri, 26 Sep 2008 00:00:00 GMT</pubDate>
            <dc:creator>silas</dc:creator>
            <category><![CDATA[Programming]]></category><category><![CDATA[Python]]></category><category><![CDATA[Ruby]]></category>
            <guid isPermaLink="true">http://www.silassewell.com/blog/2008/09/26/persistent-queuing-python/</guid>
            <description><![CDATA[
<p><a href="http://code.google.com/p/peafowl/">Peafowl</a> is a Python port of Ruby's <a href="http://rubyforge.org/projects/starling/">Starling</a>.</p>
]]></description>
        </item>

        <item>
            <title>Universal Feed Parser to JSON</title>
            <link>http://www.silassewell.com/blog/2008/05/05/universal-feed-parser-json/</link>
            <pubDate>Mon, 05 May 2008 00:00:00 GMT</pubDate>
            <dc:creator>silas</dc:creator>
            <category><![CDATA[JSON]]></category><category><![CDATA[Programming]]></category><category><![CDATA[Python]]></category><category><![CDATA[Universal Feed Parser]]></category>
            <guid isPermaLink="true">http://www.silassewell.com/blog/2008/05/05/universal-feed-parser-json/</guid>
            <description><![CDATA[<p>My attempt at wrangling a Universal Feed Parser object into JSON.</p>

<pre><code class="prettyprint">import feedparser

def json_make_normal(obj):
    if type(obj) in [str, unicode, int, float, bool, dict, set, list, tuple]:
        return obj
    try: return dict(obj)
    except: pass
    try: return list(obj)
    except: pass
    return None

def json_handle(obj):
    obj = json_make_normal(obj)
    if type(obj) in [str, unicode]:
        obj = obj.replace('\\', '\\\\')
        obj = obj.replace('"', '\\"')
        obj = obj.replace('\b', '\\\b')
        obj = obj.replace('\f', '\\\f')
        obj = obj.replace('\n', '\\\n')
        obj = obj.replace('\r', '\\\r')
        obj = obj.replace('\t', '\\\t')
        return '"%s"' % obj
    elif type(obj) in [int, float]:
        return obj
    elif type(obj) is bool:
        if obj: return 'true'
        else: return 'false'
    elif type(obj) is type(None):
        return 'null'
    elif type(obj) is dict:
        temp = ''
        for key in obj.keys():
            temp += '%s:%s, ' % (json_handle(key), json_handle(obj[key]))
        return '{%s}' % temp[:-2]
    elif type(obj) in [set, list, tuple]:
        temp = ''
        for value in obj:
            temp += '%s, ' % json_handle(value)
        return '[%s]' % temp[:-2]
    return 'null'

data = feedparser.parse('http://digg.com/rss/index.xml')

print json_handle(data)
</code></pre>

<p>Link: <a href="http://www.silassewell.com/blog/2008/05/05/universal-feed-parser-json/feed_parser_to_json.py" title="feed parser to json">feed_parser_to_json.py</a></p>

<p><strong>Update:</strong> According to <a href="http://code.google.com/u/john.paulett/" title="John Paulett">John Paulett</a> <a href="http://code.google.com/p/jsonpickle/" title="jsonpickle">jsonpickle</a> now supports Universal Feed Parser objects. Thanks for letting me know!</p>]]></description>
        </item>

        <item>
            <title>Post a Get</title>
            <link>http://www.silassewell.com/blog/2008/03/30/post-a-get/</link>
            <pubDate>Sun, 30 Mar 2008 00:00:00 GMT</pubDate>
            <dc:creator>silas</dc:creator>
            <category><![CDATA[Firefox]]></category><category><![CDATA[Keywords]]></category><category><![CDATA[PHP]]></category><category><![CDATA[Programming]]></category><category><![CDATA[Projects]]></category>
            <guid isPermaLink="true">http://www.silassewell.com/blog/2008/03/30/post-a-get/</guid>
            <description><![CDATA[<p>I've created a PHP script called <a href="http://www.silassewell.com/blog/2008/03/30/post-a-get/index.php" title="Post a Get">Post a Get</a> which can be copied to
any PHP capable server and used to created a POST request using GET syntax.</p>

<p>Let's say you use GoDaddy as your domain registrar and you would like to see if
a domain is available using Firefox keywords, but they don't offer a GET
search.</p>

<p>For a traditional keyword, you could construct a GET request like:</p>

<pre><code class="prettyprint">https://www.godaddy.com/gdshop/registrar/search.asp&amp;checkAvail=1&amp;fblur=1&amp;tld=.com&amp;domainToCheck=%s
</code></pre>

<p>But as of right now Firefox doesn't offer a way to create POST keywords. What
Post a Fix does is allow you to construct a POST request using GET syntax and
pass it to the <a href="http://www.silassewell.com/blog/2008/03/30/post-a-get/index.php" title="Post a Get">Post a Get code</a>.</p>

<p>So if you wanted to submit the above GET as a POST, you would construct the URL
and append the special __action parameter with target URL. So the final URL
would look something like:</p>]]></description>
        </item>

    </channel>
</rss>
