<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>Nuno Mariz - Latest blog entries</title><link>http://mariz.org/blog/</link><description>Nuno Mariz latest blog entries</description><atom:link href="http://mariz.org/blog/feeds/latest/" rel="self"></atom:link><language>en</language><lastBuildDate>Tue, 01 Apr 2014 15:05:23 +0100</lastBuildDate><item><title>Announcing MySQL Multi-Source Replication Utility</title><link>http://mariz.org/blog/2014/04/01/announcing-mysql-multi-source-replication-utility/</link><description>&lt;p&gt;The MySQL Utilities team is pleased to announce a new MySQL utility,
&lt;em&gt;mysqlrplms&lt;/em&gt;, that allows users to setup multi-source replication. This
utility is available for server versions 5.6.9 and later with GTIDs enabled.
The new utility is included in MySQL Utilities release-1.4.2 RC.&lt;/p&gt;
&lt;h2&gt;What is multi-source replication?&lt;/h2&gt;
&lt;p&gt;Multi-source replication is often regarded as a means to aggregate and
consolidate different streams of data (from master servers - also called
sources) into one single server (slave) instance. This is useful for
consolidating non-conflicting data changes into a central server. Not only
does this allow users to perform backups of the consolidated data,
it also permits users to execute queries that may span the datasets.&lt;/p&gt;
&lt;h2&gt;Requirements and assumptions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;em&gt;mysqlrplms&lt;/em&gt; utility supports MySQL 5.6.9 and higher version servers
  with GTIDs enabled.&lt;/li&gt;
&lt;li&gt;There must not be any overlap or data conflicts for the data from different
  masters. For example, there are no updates to the same object from multiple
  masters.&lt;/li&gt;
&lt;li&gt;Replication must be asynchronous.&lt;/li&gt;
&lt;li&gt;A round-robin scheduling is used to setup replication among all masters and
  slave.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Note: a POSIX system is required for using the daemon option.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Examples&lt;/h2&gt;
&lt;p&gt;Basic multi-source replication setup:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;shell&amp;gt; mysqlrplms --slave=root:pass@host1:3306 \
                  --masters=root:pass@host2:3306,root:pass@host3:3306
# Starting multi-source replication...
# Press CTRL+C to quit.
# Switching to master 'host2:3306'.
# master on localhost: ... connected.
# slave on localhost: ... connected.
#
# Current Master Information:
+-------------------+-----------+---------------+-------------------+
| Binary Log File   | Position  | Binlog_Do_DB  | Binlog_Ignore_DB  |
+-------------------+-----------+---------------+-------------------+
| clone-bin.000001  | 594       | N/A           | N/A               |
+-------------------+-----------+---------------+-------------------+
# GTID Executed Set: 0cd1200c-b5a2-11e3-a342-28d244017f26:1-2
#
# Health Status:
+------------+-------+---------+--------+------------+---------+
| host       | port  | role    | state  | gtid_mode  | health  |
+------------+-------+---------+--------+------------+---------+
| host2      | 3306  | MASTER  | UP     | ON         | OK      |
| host1      | 3306  | SLAVE   | UP     | ON         | OK      |
| host3      | 3306  | MASTER  | UP     | ON         | OK      |
+------------+-------+---------+--------+------------+---------+
(...)
# Switching to master host3:3306'.
# master on localhost: ... connected.
# slave on localhost: ... connected.
#
# Current Master Information:
+-------------------+-----------+---------------+-------------------+
| Binary Log File   | Position  | Binlog_Do_DB  | Binlog_Ignore_DB  |
+-------------------+-----------+---------------+-------------------+
| clone-bin.000001  | 594       | N/A           | N/A               |
+-------------------+-----------+---------------+-------------------+
# GTID Executed Set: c30a1796-b998-11e3-bd1a-28d244017f26:1-2
#
# Health Status:
+------------+-------+---------+--------+------------+---------+
| host       | port  | role    | state  | gtid_mode  | health  |
+------------+-------+---------+--------+------------+---------+
| host3      | 3306  | MASTER  | UP     | ON         | OK      |
| host1      | 3306  | SLAVE   | UP     | ON         | OK      |
| host2      | 3306  | MASTER  | UP     | ON         | OK      |
+------------+-------+---------+--------+------------+---------+
(...)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Multi-source replication setup using different report values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;shell&amp;gt; mysqlrplms --slave=root:pass@host1:3306 \
                  --masters=root:pass@host2:3306,root:pass@host3:3306 \
                  --report-values=health,gtid,uuid
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Start multi-source replication running as a POSIX daemon:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;shell&amp;gt; mysqlrplms --slave=root:pass@host1:3306 \
                  --masters=root:pass@host2:3306,root:pass@host3:3306 \
                  --log=rplms_daemon.log --pidfile=rplms_daemon.pid \
                  --daemon=start
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Restart a multi-source replication running as a POSIX daemon:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;shell&amp;gt; mysqlrplms --slave=root:pass@host1:3306 \
                  --masters=root:pass@host2:3306,root:pass@host3:3306 \
                  --log=rplms_daemon.log --pidfile=rplms_daemon.pid \
                  --daemon=restart
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Stop a multi-source replication running as a POSIX daemon:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;shell&amp;gt; mysqlrplms --slave=root:pass@host1:3306 \
                  --masters=root:pass@host2:3306,root:pass@host3:3306 \
                  --log=rplms_daemon.log --pidfile=rplms_daemon.pid \
                  --daemon=stop
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Send us your feedback&lt;/h2&gt;
&lt;p&gt;MySQL Utilities release-1.4.2 RC is available for download from the following
links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MySQL developers website: &lt;a href="http://dev.mysql.com/downloads/tools/utilities/"&gt;http://dev.mysql.com/downloads/tools/utilities/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Launchpad project: &lt;a href="https://launchpad.net/mysql-utilities"&gt;https://launchpad.net/mysql-utilities&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Commercial customers can get it here: &lt;a href="https://edelivery.oracle.com/"&gt;https://edelivery.oracle.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The documentation of MySQL Utilities can be obtained from the following link:
&lt;a href="http://dev.mysql.com/doc/index-gui.html"&gt;http://dev.mysql.com/doc/index-gui.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Contributing Ideas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Community users: &lt;a href="http://bugs.mysql.com"&gt;http://bugs.mysql.com&lt;/a&gt; (MySQL Workbench: Utilities)&lt;/li&gt;
&lt;li&gt;Oracle customers: &lt;a href="http://bug.oraclecorp.com"&gt;http://bug.oraclecorp.com&lt;/a&gt; (Product = MySQL Workbench,
  Component = WBUTILS)&lt;/li&gt;
&lt;/ul&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Tue, 01 Apr 2014 15:05:23 +0100</pubDate><guid>http://mariz.org/blog/2014/04/01/announcing-mysql-multi-source-replication-utility/</guid></item><item><title>New year, new job</title><link>http://mariz.org/blog/2012/12/14/new-year-new-job/</link><description>&lt;p&gt;Starting from January 2013, I'll be working at &lt;a href="http://www.oracle.com"&gt;Oracle&lt;/a&gt; on the &lt;a href="http://www.mysql.com"&gt;MySQL&lt;/a&gt; Utilities Team as a Software Developer.&lt;br /&gt;
It's a new chapter on my professional career and a unique opportunity for doing what I like the most, which is &lt;a href="http://www.python.org"&gt;Python&lt;/a&gt; programming on an open source project.&lt;/p&gt;
&lt;p&gt;I'm leaving &lt;a href="http://www.infoportugal.pt"&gt;InfoPortugal S.A.&lt;/a&gt;, a special company that was my home for the last 6 years. It was a pleasure working with such a talented team. A special Thanks to &lt;a href="http://www.linkedin.com/in/jalexgomes"&gt;Alexandre Gomes&lt;/a&gt;, a great professional with an incomparable commitment to the company.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Fri, 14 Dec 2012 10:02:45 +0000</pubDate><guid>http://mariz.org/blog/2012/12/14/new-year-new-job/</guid></item><item><title>PostgreSQL and PostGIS installation from source on Mac OS X Lion</title><link>http://mariz.org/blog/2012/06/19/postgresql-and-postgis-installation-source-mac-os-x-lion/</link><description>&lt;p&gt;This is a cookbook for installing &lt;a href="http://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt; and &lt;a href="http://postgis.refractions.net/"&gt;PostGIS&lt;/a&gt; on Mac OS X Lion from source, as alternative you can install the binaries from &lt;a href="http://www.enterprisedb.com/resources-community/pginst-guide"&gt;EnterpriseDB&lt;/a&gt; or &lt;a href="http://www.kyngchaos.com/software/postgres"&gt;KyngChaos&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You don't have to install all packages but if you're using &lt;a href="http://www.djangoproject.com"&gt;Django&lt;/a&gt; will be useful.&lt;/p&gt;

&lt;h2&gt;Requirements&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://developer.apple.com/technologies/tools/"&gt;Xcode&lt;/a&gt; with "Command Line Tools": Installation via Xcode &amp;gt; Preferences &amp;gt; Downloads.&lt;/p&gt;

&lt;h2&gt;PostgreSQL&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Create the postgres user via System Preferences(for simplicity), use "postgres" as username.&lt;/li&gt;

&lt;li&gt;Compiling and installing PostgreSQL:
&lt;pre class="code"&gt;
$ curl -O http://ftp.postgresql.org/pub/source/v9.1.3/postgresql-9.1.3.tar.gz
$ tar xzfp postgresql-9.1.3.tar.gz
$ cd postgresql-9.1.3
$ ./configure CC=/usr/bin/clang CXX=/usr/bin/clang++ "CFLAGS=-arch x86_64" "LDFLAGS=-arch x86_64" "CXXFLAGS=-arch x86_64"
$ make
$ sudo make install
$ cd ..
&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;Create PostgreSQL Database Cluster:
&lt;pre class="code"&gt;
$ sudo mkdir /usr/local/pgsql/data
$ sudo chown postgres /usr/local/pgsql/data
$ sudo -u postgres /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;Start PostgreSQL Server:
&lt;pre class="code"&gt;
$ sudo -u postgres /usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data start
&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;After installation add to .profile or .zshrc:
&lt;pre class="code"&gt;
export PATH=/usr/local/pgsql/bin:$PATH
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;PROJ4&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://trac.osgeo.org/proj/"&gt;PROJ.4&lt;/a&gt; is a library for converting geospatial data to different coordinate reference systems.&lt;/p&gt;
&lt;pre class="code"&gt;
$ curl -O http://download.osgeo.org/proj/proj-4.8.0.tar.gz
$ curl -O http://download.osgeo.org/proj/proj-datumgrid-1.5.zip
$ tar xzfp proj-4.8.0.tar.gz
$ cd proj-4.8.0/nad
$ unzip ../../proj-datumgrid-1.5.zip
$ cd ..
$ ./configure CC=/usr/bin/clang CXX=/usr/bin/clang++ "CFLAGS=-arch x86_64" "LDFLAGS=-arch x86_64" "CXXFLAGS=-arch x86_64"
$ make
$ sudo make install
$ cd ..
&lt;/pre&gt;

&lt;h2&gt;GEOS&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://trac.osgeo.org/geos/"&gt;GEOS&lt;/a&gt; is a C++ library for performing geometric operations.&lt;/p&gt;
&lt;pre class="code"&gt;
$ curl -O http://download.osgeo.org/geos/geos-3.3.3.tar.bz2
$ tar xjfp geos-3.3.3.tar.bz2
$ cd geos-3.3.3
$ ./configure CC=/usr/bin/clang CXX=/usr/bin/clang++ "CFLAGS=-arch x86_64" "LDFLAGS=-arch x86_64" "CXXFLAGS=-arch x86_64"
$ make
$ sudo make install
$ cd ..
&lt;/pre&gt;

&lt;h2&gt;GDAL&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://trac.osgeo.org/gdal/"&gt;GDAL&lt;/a&gt; is an open source geospatial library that has support for reading most vector and raster spatial data formats. GEOS and PROJ.4 should be installed prior to building GDAL.&lt;/p&gt;
&lt;pre class="code"&gt;
$ curl -O http://download.osgeo.org/gdal/gdal-1.9.1.tar.gz
$ tar xzfp gdal-1.9.1.tar.gz
$ cd gdal-1.9.1
$ ./configure CC=/usr/bin/clang CXX=/usr/bin/clang++ "CFLAGS=-arch x86_64" "LDFLAGS=-arch x86_64" "CXXFLAGS=-arch x86_64"
$ make
$ sudo make install
$ cd ..
&lt;/pre&gt;

&lt;h2&gt;PostGIS&lt;/h2&gt;
&lt;p&gt;Spatial extensions for PostgreSQL.&lt;/p&gt;
&lt;pre class="code"&gt;
$ curl -O http://postgis.refractions.net/download/postgis-1.5.4.tar.gz
$ tar xzfp postgis-1.5.4.tar.gz
$ cd postgis-1.5.4
$ ./configure CC=/usr/bin/clang CXX=/usr/bin/clang++ "CFLAGS=-arch x86_64" "LDFLAGS=-arch x86_64" "CXXFLAGS=-arch x86_64"
$ make
$ sudo make install
&lt;/pre&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Tue, 19 Jun 2012 11:59:10 +0100</pubDate><guid>http://mariz.org/blog/2012/06/19/postgresql-and-postgis-installation-source-mac-os-x-lion/</guid></item><item><title>Gabriela Barbosa Mariz</title><link>http://mariz.org/blog/2012/03/12/gabriela-barbosa-mariz/</link><description>&lt;img src="http://mariz.org/media/images/posts/gabriela.jpg"  alt="Gabriela" /&gt;&lt;br /&gt;
Gabriela Barbosa Mariz was born at 16h36, March 12, 2012. She weighed 3.710 Kg and was 51 cm long.&lt;br /&gt;
Gabriela and &lt;a href="http://wedding.mariz.org"&gt;Marta&lt;/a&gt; are doing well.
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Mon, 12 Mar 2012 16:36:00 +0000</pubDate><guid>http://mariz.org/blog/2012/03/12/gabriela-barbosa-mariz/</guid></item><item><title>ITJobs Android App</title><link>http://mariz.org/blog/2012/02/27/itjobs-android-app/</link><description>&lt;p&gt;
Just released the &lt;a href="http://www.itjobs.pt"&gt;ITJobs&lt;/a&gt; Android app, it was a fun(sometimes) project to make.&lt;br /&gt;
The application supports devices with Android 1.6 or greater. For those people that says Android fragmentation is a non issue, I've to say they are wrong, it turns the life of developers extremely difficult and boring.&lt;br /&gt;
Too many versions and resolutions to take care about. I had the feeling of continuous patching just to support the largest devices that I could.&lt;br /&gt;
I've also found some nonsense and sometimes ridiculous bugs on Android SDK, I'll post about this later.
&lt;/p&gt;

&lt;p&gt;
But overall it's not a bad platform to develop. What I've enjoyed the most was the flexibility about the XML layouts and shapes, the Eclipse IDE does the job and I think Java is a nice programming language.&lt;br /&gt;
Please send me some feedback, the app is available on Android Market: &lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://market.android.com/details?id=org.mariz.itjobs.android"&gt;
&lt;img src="http://mariz.org/media/images/available-android-market.png" alt="ITJobs Android Market" title="ITJobs Android Market" /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;hr class="space" /&gt;

&lt;img src="http://mariz.org/media/images/posts/itjobs_screenshot.jpg" alt="ITJobs Android Screenshot" title="ITJobs Android Screenshot" /&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Mon, 27 Feb 2012 13:38:16 +0000</pubDate><guid>http://mariz.org/blog/2012/02/27/itjobs-android-app/</guid></item><item><title>Happy new year</title><link>http://mariz.org/blog/2011/12/31/happy-new-year/</link><description>&lt;p&gt;No resolutions, just goals and dreams. Have a healthy baby girl, love, health, run half marathon in 2h and success for my upcoming projects.&lt;/p&gt;
&lt;br /&gt;
&lt;p&gt;&lt;strong&gt;Happy new year!&lt;/strong&gt;&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Sat, 31 Dec 2011 23:03:48 +0000</pubDate><guid>http://mariz.org/blog/2011/12/31/happy-new-year/</guid></item><item><title>Announcing Daddy 2.0</title><link>http://mariz.org/blog/2011/08/18/announcing-daddy-20/</link><description>&lt;img src="http://mariz.org/media/images/posts/daddy_2.jpg" alt="Daddy 2.0" /&gt;
&lt;p&gt;The project is under development and my &lt;a href="http://wedding.mariz.org/"&gt;co-worker&lt;/a&gt; is doing her best to provide the most beautiful layout.&lt;/p&gt;
&lt;p&gt;For my english speaking readers the photo says: "Pregnant 3+"&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Thu, 18 Aug 2011 14:46:08 +0100</pubDate><guid>http://mariz.org/blog/2011/08/18/announcing-daddy-20/</guid></item><item><title>Believe in your ideas!</title><link>http://mariz.org/blog/2011/05/03/believe-your-ideas/</link><description>Later in 2007 I had almost 200 feeds subscriptions on my &lt;a href="http://www.google.com/reader"&gt;Google Reader&lt;/a&gt; account and I had a problem, sometimes I didn't have the time to read a full article and I wanted to read it later.&lt;br /&gt;
At that time I was not aware of a tool that would help me with this problem and my solution was to add a bookmark to &lt;a href="http://www.delicious.com/"&gt;Delicious&lt;/a&gt; with a &lt;i&gt;readlater&lt;/i&gt; tag. &lt;br /&gt;
It worked, but I didn't want to mess my bookmarks with links to articles that I wanted to read later.&lt;br /&gt;
I felt that I needed a tool for the job and for about a week in my spare time I built a simple website to manage my online readings. It was simple, It had a bookmarklet that I could call to save a link of the page that I was visiting, add a title, description, tags and the ability to save it privately.&lt;br /&gt;
On February, 8th, 2008 &lt;a href="http://mariz.org/blog/2008/01/03/fullread/"&gt;I announced on my blog&lt;/a&gt; the release of &lt;a href="http://fullread.com/"&gt;Fullread&lt;/a&gt;. The feedback was a mix of &lt;i&gt;"I use delicious with a tag for that"&lt;/i&gt; and &lt;i&gt;"Looks nice, but not very useful"&lt;/i&gt;.&lt;br /&gt;
At that time I built the tool mainly for myself and I truly believed that there was a need for this kind of thing, but the majority of the feedback was not that great. I continued using the tool but I didn't add more features to it. If the people didn't liked why bother?&lt;br /&gt;
Well, 25 days later &lt;a href="http://www.marco.org/"&gt;Marco Arment&lt;/a&gt; released &lt;a href="http://www.instapaper.com/"&gt;Instapaper&lt;/a&gt; and &lt;a href="http://www.marco.org/2008/01/28/instapaper"&gt;posted on his blog&lt;/a&gt;. Marco went further and added an iPhone app, that was in my opinion the killer feature.&lt;br /&gt;
Right now Instapaper is the market leader in this category, it's a fantastic tool with a continuous development and I use it every day.&lt;br /&gt;
&lt;br /&gt;
So, why &lt;a href="http://fullread.com/"&gt;Fullread&lt;/a&gt; had no success compared to &lt;a href="http://www.instapaper.com/"&gt;Instapaper&lt;/a&gt;?&lt;br /&gt;
In my opinion the factors were:
&lt;ul&gt;
  &lt;li&gt;Mainly because Marco made a great job.&lt;/li&gt;
  &lt;li&gt;Marco was the CTO of &lt;a href="http://www.tumblr.com/"&gt;Tumblr&lt;/a&gt; and was well known by the community, this helped with the media coverage. I'm a simple software engineer in Portugal.&lt;/li&gt;
  &lt;li&gt;I abandoned &lt;a href="http://fullread.com/"&gt;Fullread&lt;/a&gt; development.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
 What's the future of &lt;a href="http://fullread.com/"&gt;Fullread&lt;/a&gt;?&lt;br /&gt;
 The answer is not simple. It’s very difficult to compete with &lt;a href="http://www.instapaper.com/"&gt;Instapaper&lt;/a&gt; or &lt;a href="http://readitlaterlist.com/"&gt;Read it Later&lt;/a&gt; at this time of the game. But, in the name of pride, I'll eventually improve/rebuild &lt;a href="http://fullread.com/"&gt;Fullread&lt;/a&gt;, maybe with a different approach.
&lt;br /&gt;
&lt;br /&gt;
So, is there a lesson to take from all this, I ask?&lt;br /&gt;
Yes: &lt;strong&gt;Believe in yourself, believe in your ideas!&lt;/strong&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Tue, 03 May 2011 17:16:31 +0100</pubDate><guid>http://mariz.org/blog/2011/05/03/believe-your-ideas/</guid></item><item><title>My daily tools</title><link>http://mariz.org/blog/2011/03/23/my-daily-tools/</link><description>&lt;h2&gt;Hardware&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;At home&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Laptop: &lt;a href="http://www.apple.com/macbookpro/"&gt;MacBook Pro&lt;/a&gt; 15" - Intel Core 2 2.4Ghz, 2Gb RAM(needs an upgrade) and 150Gb HD, connected to a &lt;a href="http://h10010.www1.hp.com/wwpc/au/en/ho/WF06b/382087-382087-3284302-215012-215012-3770740-4194787.html"&gt;HP 2310e&lt;/a&gt; 23" monitor and a &lt;a href="http://www.raindesigninc.com/mstand.html"&gt;mStand&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Phone: &lt;a href="http://www.apple.com/iphone/"&gt;iPhone 3G&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;At work&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Computer 1: &lt;a href="http://www.apple.com/imac/"&gt;iMac&lt;/a&gt; 21.5" - Intel Core 2 3.0Ghz, 4Gb RAM and 500Gb HD.&lt;/li&gt;
  &lt;li&gt;Computer 2: &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu Linux&lt;/a&gt; - Intel Quad-Core 2.4Ghz, 4Gb RAM, WD Raptor 150Gb + Samsung HD502 750Gb. Used for testing and processing maps.&lt;/li&gt;
  &lt;li&gt;Phone: &lt;a href="http://www.htc.com/europe/product/hd2/overview.html"&gt;HTC HD2&lt;/a&gt; with a custom Android 2.3 Gingerbread ROM.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Software&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;For development&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.gnu.org/software/emacs/"&gt;Emacs&lt;/a&gt;: I'm using it for all web development, scripting and text editing.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://developer.apple.com/tools/xcode/"&gt;Xcode&lt;/a&gt;: For &lt;a href="http://developer.apple.com/devcenter/ios/index.action"&gt;iOS&lt;/a&gt; development.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.eclipse.org/"&gt;Eclipse&lt;/a&gt;: For &lt;a href="http://developer.android.com/"&gt;Android&lt;/a&gt; development.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://getfirebug.com/"&gt;Firebug&lt;/a&gt;: For web development.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://mercurial.selenic.com/"&gt;Mercurial&lt;/a&gt;: The distributed source control management of my choice.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://pypi.python.org/pypi/virtualenv"&gt;Virtualenv&lt;/a&gt;: Virtual Python environment builder.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt;: The relational database of my choice.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://postgis.refractions.net/"&gt;PostGIS&lt;/a&gt;: Adds support for geographic objects to the PostgreSQL relational database.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.mongodb.org/"&gt;MongoDB&lt;/a&gt;: A document-oriented database.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Other tools&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.evernote.com/"&gt;Evernote&lt;/a&gt;: My information organization tool for all my projects ideas, notes etc.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.dropbox.com/"&gt;Dropbox&lt;/a&gt;: For file sync, no more pen drives!&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://reederapp.com/"&gt;Reeder&lt;/a&gt;: I use both iPhone and desktop versions to consume RSS feeds.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://iconfactory.com/software/twitterrific/"&gt;Twitterrific&lt;/a&gt;: I use both iPhone and desktop versions, it's the &lt;a href="http://www.twitter.com"&gt;Twitter&lt;/a&gt; client that's fast enough on my iPhone 3G.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What's yours?&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Wed, 23 Mar 2011 13:00:00 +0000</pubDate><guid>http://mariz.org/blog/2011/03/23/my-daily-tools/</guid></item><item><title>New website</title><link>http://mariz.org/blog/2011/03/16/new-website/</link><description>The new website is up. After almost 2 years, I'm blogging again.&lt;br /&gt;
The reason for this gap It's a mix of &lt;a href="http://twitter.com"&gt;Twitter&lt;/a&gt; usage and laziness.&lt;br /&gt;
In the migration process I've messed up the RSS feed, solved, my apologies that.
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Wed, 16 Mar 2011 19:32:49 +0000</pubDate><guid>http://mariz.org/blog/2011/03/16/new-website/</guid></item><item><title>Getting the client IP address behind a proxy in Apache</title><link>http://mariz.org/blog/2009/05/20/getting-client-ip-address-behind-proxy-apache/</link><description>&lt;p&gt;Typically in my &lt;a href="http://www.djangoproject.com"&gt;Django&lt;/a&gt; projects deployments I use &lt;a href="http://nginx.net/"&gt;Nginx&lt;/a&gt; as a front-end web server to handle static content while proxying all other requests to &lt;a href="http://httpd.apache.org/"&gt;Apache&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When the request arrives to &lt;a href="http://httpd.apache.org/"&gt;Apache&lt;/a&gt;, the client IP address is &lt;code&gt;127.0.0.1&lt;/code&gt;. We need to configure &lt;a href="http://httpd.apache.org/"&gt;Apache&lt;/a&gt; to accept the IP address from X-Real-IP or X-Forwarded-For headers set by &lt;a href="http://nginx.net/"&gt;Nginx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To solve this problem I use &lt;code&gt;&lt;a href="http://stderr.net/apache/rpaf/"&gt;mod_rpaf&lt;/a&gt;&lt;/code&gt; that does exactly the opposite of &lt;code&gt;&lt;a href="http://develooper.com/code/mpaf/"&gt;mod_proxy_add_forward&lt;/a&gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In my &lt;a href="http://nginx.net/"&gt;Nginx&lt;/a&gt; virtualhost configuration I have something like:&lt;/p&gt;

&lt;pre class="code"&gt;
server {
    ...
    location  / {
        proxy_pass        http://127.0.0.1:8080;
        proxy_set_header  Host             $http_host;
        proxy_set_header  X-Real-IP        $remote_addr;
        proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
        ...
    }
    ...
}
&lt;/pre&gt;

&lt;p&gt;This also applies if your are using a different webserver as front-end such as  &lt;a href="http://www.lighttpd.net"&gt;Lighttpd&lt;/a&gt; or another instance of &lt;a href="http://httpd.apache.org/"&gt;Apache&lt;/a&gt;.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Wed, 20 May 2009 09:45:21 +0100</pubDate><guid>http://mariz.org/blog/2009/05/20/getting-client-ip-address-behind-proxy-apache/</guid></item><item><title>Portuguese Python User Group</title><link>http://mariz.org/blog/2009/05/18/portuguese-python-user-group/</link><description>&lt;img src="http://mariz.org/media/images/posts/python_pt-logo.gif" alt="Python Portugal" /&gt;&lt;br /&gt;
I've created a Python User Group in Portugal. The idea is to join people who enjoy programming in Python.&lt;br /&gt;
No membership is required to participate, experienced programmers and absolute beginners are both welcome!&lt;br /&gt;
You can visit the &lt;a href="http://python.pt"&gt;site&lt;/a&gt; or follow us on &lt;a href="http://twitter.com/python_pt"&gt;Twitter&lt;/a&gt;.</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Mon, 18 May 2009 08:45:53 +0100</pubDate><guid>http://mariz.org/blog/2009/05/18/portuguese-python-user-group/</guid></item><item><title>Django 1.0 released!</title><link>http://mariz.org/blog/2008/09/04/django-10-released/</link><description>Yes, is finally &lt;a href="http://www.djangoproject.com/weblog/2008/sep/03/1/"&gt;here&lt;/a&gt;.</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Thu, 04 Sep 2008 01:23:26 +0100</pubDate><guid>http://mariz.org/blog/2008/09/04/django-10-released/</guid></item><item><title>Portuguese translation of Django 1.0</title><link>http://mariz.org/blog/2008/08/29/portuguese-translation-django-10/</link><description>I've just submitted a &lt;a href="http://code.djangoproject.com/ticket/8685"&gt;patch&lt;/a&gt; for the Portuguese translation.&lt;br /&gt;
If you are a &lt;a href="http://www.djangoproject.com"&gt;Django&lt;/a&gt; user and know Portuguese, please take a look to the translation strings and submit any fix before the &lt;a href="http://code.djangoproject.com/wiki/VersionOneRoadmap#schedule"&gt;final 1.0 release&lt;/a&gt;.&lt;br /&gt;
Meanwhile, you can &lt;a href="http://mariz.org/downloads/file/4/"&gt;download&lt;/a&gt; the unofficial version in the &lt;a href="http://mariz.org/downloads/"&gt;downloads section&lt;/a&gt;.&lt;br /&gt;
&lt;strong&gt;Update:&lt;/strong&gt; The patch is already in SVN.</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Fri, 29 Aug 2008 15:09:06 +0100</pubDate><guid>http://mariz.org/blog/2008/08/29/portuguese-translation-django-10/</guid></item><item><title>Rafael Barbosa Mariz</title><link>http://mariz.org/blog/2008/07/26/rafael-barbosa-mariz/</link><description>&lt;img src="http://mariz.org/media/images/posts/rafael.jpg"  alt="Rafael" /&gt;&lt;br /&gt;
Rafael Barbosa Mariz was born at 00h48, July 26, 2008. He weighed 3.580 Kg and was 50 cm long.&lt;br /&gt;
Rafael and &lt;a href="http://wedding.mariz.org"&gt;Marta&lt;/a&gt; are doing well.
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Sat, 26 Jul 2008 05:48:33 +0100</pubDate><guid>http://mariz.org/blog/2008/07/26/rafael-barbosa-mariz/</guid></item><item><title>Django 1.0 roadmap and timeline</title><link>http://mariz.org/blog/2008/06/12/django-1-roadmap-and-timeline/</link><description>Finally we have a Django 1.0 roadmap and timeline. &lt;a href="http://www.jacobian.org/"&gt;Jacob Kaplan-Moss&lt;/a&gt; posted today on &lt;a href="http://groups.google.com/group/django-developers/browse_thread/thread/5ce124e7526dad"&gt;Django devolopers&lt;/a&gt;.&lt;br /&gt;
I must say this roadmap seems very realistic and the only thing that I will miss is the aggregation support, that is promised to be released in a future version, maybe in 1.1.</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Thu, 12 Jun 2008 09:38:56 +0100</pubDate><guid>http://mariz.org/blog/2008/06/12/django-1-roadmap-and-timeline/</guid></item><item><title>Internet lifestream with Django</title><link>http://mariz.org/blog/2008/04/04/internet-lifestream-with-django/</link><description>My goal was to archive and display my internet lifestream. My first approach was writing a client for each API of the social networks that I'm in.&lt;br /&gt;
This turned out to be a complete waste of time and effort. All that I needed after all was a &lt;a href="http://friendfeed.com"&gt;FriendFeed&lt;/a&gt; account that would centralize all my feeds.&lt;br /&gt;
&lt;p&gt;Archiving and displaying your entries with Django is quite simple.&lt;br /&gt;
First of all, you need to download the &lt;a href="http://code.google.com/p/friendfeed-api/downloads/list"&gt;Python FriendFeed API&lt;/a&gt; client. Then start a new application in your project, lets call it &lt;span class="code"&gt;lifestream&lt;/span&gt;:&lt;/p&gt;

&lt;pre class="code"&gt;./manage.py startapp lifestream&lt;/pre&gt;

&lt;p&gt;On the &lt;span class="code"&gt;settings.py&lt;/span&gt; add the &lt;span class="code"&gt;lifestream&lt;/span&gt; project to the INSTALLED_APPS and a variable to store your FriendFeed username:

&lt;pre class="code"&gt;FRIENDFEED_USERNAME = 'your_username'&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;span class="code"&gt;models.py&lt;/span&gt; add a model named &lt;span class="code"&gt;Entry&lt;/span&gt;:

&lt;pre class="code"&gt;from django.db import models

class Entry(models.Model):
    id = models.CharField(max_length=255, primary_key=True)
    service_id = models.CharField(max_length=50, null=True, blank=True)
    service_name = models.CharField(max_length=50, null=True, blank=True)
    service_icon = models.URLField(max_length=255, verify_exists=False, null=True, blank=True)
    service_profile = models.URLField(max_length=255, verify_exists=False, null=True, blank=True)
    title = models.CharField(max_length=255, null=True, blank=True)
    link = models.URLField(max_length=255, verify_exists=False, null=True, blank=True)
    updated = models.DateTimeField(null=True, blank=True)
    published = models.DateTimeField(null=True, blank=True)
    media_title = models.CharField(max_length=255, null=True, blank=True)
    media_link = models.URLField(max_length=255, verify_exists=False, null=True, blank=True)
    media_thumbnail = models.URLField(max_length=255, verify_exists=False, null=True, blank=True)
    created = models.DateTimeField(auto_now_add=True)

    def __unicode__(self):
        return self.title

    class Meta:
        ordering = ['-published']
        verbose_name = 'Entry'
        verbose_name_plural = 'Entries'

    class Admin:
        list_display = ['title', 'service_name', 'published']
        list_filter = ['service_name']
        date_hierarchy = 'published'&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;Create an &lt;span class="code"&gt;url.py&lt;/span&gt; on the &lt;span class="code"&gt;lifestream&lt;/span&gt; folder:

&lt;pre class="code"&gt;from django.conf.urls.defaults import *
from lifestream.models import Entry
 
entry_list_dict = {
    'queryset' : Entry.objects.all(),
    'paginate_by' : 30,
}

urlpatterns = patterns('',   
    (r'^$', 'django.views.generic.list_detail.object_list', entry_list_dict),
)&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;As you can see, I've used a &lt;a href="http://www.djangoproject.com/documentation/generic_views/"&gt;generic view&lt;/a&gt;. You can also use the &lt;a href="http://www.djangoproject.com/documentation/generic_views/#date-based-generic-views"&gt;date based generic views&lt;/a&gt; and &lt;a href="http://www.djangoproject.com/documentation/generic_views/#notes-on-pagination"&gt;pagination&lt;/a&gt; to build an archive like &lt;a href="http://mariz.org/lifestream/"&gt;mine&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Add to your project root &lt;span class="code"&gt;urls.py&lt;/span&gt;:

&lt;pre class="code"&gt;(r'^lifestream/', include('lifestream.urls'))&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;Create a template &lt;span class="code"&gt;lifestream/entry_list.html&lt;/span&gt;:

&lt;pre class="code"&gt;{% for entry in object_list %}
&amp;lt;div class="source"&amp;gt;
  &amp;lt;a href="{{ entry.service_profile }}" title="{{ entry.service_name }}"&amp;gt;&amp;lt;img src="{{ entry.service_icon }}" alt="{{ entry.service_name }}" alt="{{ entry.service_name }}" /&amp;gt;&amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class="details"&amp;gt;
  &amp;lt;ul&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href="{{ entry.link }}"&amp;gt;{{ entry.title }}&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;{{ entry.published|timesince }} ago&amp;lt;/li&amp;gt;
    {% if entry.media_thumbnail %}&amp;lt;li&amp;gt;&amp;lt;a href="{{ entry.media_link }}"&amp;gt;&amp;lt;img src="{{ entry.media_thumbnail }}" alt="{{ entry.media_title }}" /&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;{% endif %}
  &amp;lt;/ul&amp;gt;
&amp;lt;/div&amp;gt;
{% endfor %}&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;Finally, create a script to synchronize your feeds:&lt;br /&gt;
&lt;pre class="code"&gt;#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import os

ROOT_PATH = os.path.realpath(os.path.dirname(__file__))
PROJECT_PATH, PROJECT_DIR = os.path.split(ROOT_PATH)

sys.path.insert(0, ROOT_PATH)
sys.path.insert(1, PROJECT_PATH)

os.environ['DJANGO_SETTINGS_MODULE'] = '%s.settings' % PROJECT_DIR

from friendfeed import FriendFeed
from django.conf import settings
from lifestream.models import Entry

ff = FriendFeed()
feed = ff.fetch_user_feed(settings.FRIENDFEED_USERNAME)

for e in feed.get('entries'):
    entry, created = Entry.objects.get_or_create(id=e.get('id'))
    if created:
        service = e.get('service')
        entry.service_id = service.get('id')
        entry.service_name = service.get('name')
        entry.service_icon = service.get('iconUrl')
        entry.service_profile = service.get('profileUrl')
        entry.title = e.get('title')
        entry.link = e.get('link')
        entry.updated = e.get('updated')
        entry.published = e.get('published')
        media = e.get('media')
        if media:
            entry.media_title = media[0].get('title')
            entry.media_link = media[0].get('player') or entry.link
            thumbnails = media[0].get('thumbnails')
            entry.media_thumbnail = thumbnails[0].get('url')
        entry.save()&lt;/pre&gt;&lt;/p&gt; 

&lt;p&gt;If you want, you can add a job in your &lt;span class="code"&gt;crontab&lt;/span&gt;:
&lt;pre class="code"&gt;# synchronize every 15 mins
*/15 * * * *   root   /path/to/your/application/lifestream_cron.py&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;See my &lt;a href="http://mariz.org/lifestream/"&gt;lifestream&lt;/a&gt; as the working example.&lt;/p&gt;

&lt;p&gt;&lt;span class="bold"&gt;UPDATE:&lt;/span&gt; &lt;a href="http://friendfeed.com/"&gt;Friendfeed&lt;/a&gt; sends the time in UTC, if you want to use your timezone you have do some hacking:&lt;/p&gt;
&lt;p&gt;Install &lt;span class="code"&gt;&lt;a href="http://pytz.sourceforge.net/"&gt;pytz&lt;/a&gt;&lt;/span&gt;:&lt;/p&gt;
&lt;pre class="code"&gt;easy_install pytz&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Import and assign your timezone to a variable:&lt;/p&gt;
&lt;pre class="code"&gt;import pytz
tz = pytz.timezone(settings.TIME_ZONE)&lt;/pre&gt;
&lt;p&gt;And replace &lt;span class="code"&gt;entry.updated&lt;/span&gt; and &lt;span class="code"&gt;entry.published&lt;/span&gt; with:
&lt;pre class="code"&gt;updated = e.get('updated')
updated = updated.replace(tzinfo=pytz.utc).astimezone(tz)
published = e.get('published')
published = published.replace(tzinfo=pytz.utc).astimezone(tz)
if settings.DATABASE_ENGINE == 'mysql': # http://code.djangoproject.com/ticket/5304
    updated = updated.replace(tzinfo=None)
    published = published.replace(tzinfo=None)
entry.updated = updated
entry.published = published&lt;/pre&gt;
&lt;p&gt;Thanks to &lt;a href="http://ckelly.net"&gt;Chris Kelly&lt;/a&gt; that send me an email reporting this.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Fri, 04 Apr 2008 01:30:50 +0100</pubDate><guid>http://mariz.org/blog/2008/04/04/internet-lifestream-with-django/</guid></item><item><title>Django error notification with jabber</title><link>http://mariz.org/blog/2008/03/07/django-error-notification-with-jabber/</link><description>Django has a code error notifications mechanism when a view raises an exception. It will email the people in &lt;span class="code"&gt;ADMIN&lt;/span&gt; tuple(&lt;a href="http://www.djangoproject.com/documentation/settings/#admins" title="Django Settings"&gt;settings documentation&lt;/a&gt;) in &lt;span class="code"&gt;settings.py&lt;/span&gt; with the full exception information and displays the default 500.html template.&lt;br /&gt;
This only happens when &lt;span class="code"&gt;DEBUG=False&lt;/span&gt; in the &lt;span class="code"&gt;settings.py&lt;/span&gt;.

&lt;p&gt;
It's possible to set a handle that change this behavior with a &lt;span class="code"&gt;handler500&lt;/span&gt; variable in the root &lt;span class="code"&gt;urls.py&lt;/span&gt;.&lt;br /&gt;
So, we can easily write a simple view that sends an error notification to our &lt;a href="http://www.jabber.org/" title="Jabber"&gt;jabber&lt;/a&gt; account.
&lt;/p&gt;

&lt;p&gt;
First of all, you need to install &lt;span class="code"&gt;&lt;a href="http://xmpppy.sourceforge.net/" title="xmpppy"&gt;xmpppy&lt;/a&gt;&lt;/span&gt; and &lt;span class="code"&gt;&lt;a href="http://www.dnspython.org/" title="dnspython"&gt;dnspython&lt;/a&gt;&lt;/span&gt;:
&lt;pre class="code"&gt;$ easy_install xmpppy
$ easy_install dnspython&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;
Add to &lt;span class="code"&gt;settings.py&lt;/span&gt; the jabber parameters such as the jabber id, password, recipient, etc.:
&lt;pre class="code"&gt;JABBER_ERROR_NOTIFICATION = True
JABBER_ID = 'your_jabberid@jabberdomain.com'
JABBER_PASSWORD = 'your_jabber_password'
JABBER_RECIPIENT = 'recipient@jabberdomain.com'
JABBER_ERROR_TEXT = 'An error occurred in "Project Name", please check your email.'&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;
Start a new app named &lt;span class="code"&gt;errors&lt;/span&gt; or something else and add it to the &lt;span class="code"&gt;INSTALLED_APPS&lt;/span&gt; tuple in the &lt;span class="code"&gt;settings.py&lt;/span&gt;:
&lt;pre class="code"&gt;python manage.py startapp errors&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;

Add a &lt;span class="code"&gt;handler500&lt;/span&gt; variable with the view in the root &lt;span class="code"&gt;urls.py&lt;/span&gt;:
&lt;pre class="code"&gt;handler500 = 'errors.views.server_error_jabber'&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;
Finally add the view in &lt;span class="code"&gt;errors.views&lt;/span&gt; that sends a jabber notification and returns a 500 error page:
&lt;pre class="code"&gt;
from django.views.defaults import server_error
from django.conf import settings
import xmpp, time

def server_error_jabber(request, template_name='500.html'):
   if settings.JABBER_ERROR_NOTIFICATION:
       jid = xmpp.protocol.JID(settings.JABBER_ID)
       cl = xmpp.Client(jid.getDomain(), debug=[])
       conn = cl.connect()
       if conn:
           auth = cl.auth(jid.getNode(), settings.JABBER_PASSWORD, resource=jid.getResource())
           if auth:
               id = cl.send(xmpp.protocol.Message(settings.JABBER_RECIPIENT, settings.JABBER_ERROR_TEXT))
               # Some older servers will not send the message if you disconnect immediately after sending
               time.sleep(1)
   return server_error(request, template_name)
&lt;/pre&gt;
&lt;/p&gt;
&lt;strong&gt;NOTE:&lt;/strong&gt; Don't forget to set &lt;span class="code"&gt;DEBUG=False&lt;/span&gt; in the &lt;span class="code"&gt;settings.py&lt;/span&gt;.</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Fri, 07 Mar 2008 13:26:46 +0000</pubDate><guid>http://mariz.org/blog/2008/03/07/django-error-notification-with-jabber/</guid></item><item><title>I'm addicted</title><link>http://mariz.org/blog/2008/02/28/im-addicted/</link><description>&lt;a href="http://nikeplus.nike.com/nikeplus/" tittle="Nike Plus"&gt;&lt;img src="http://mariz.org/media/images/posts/nikeplus.gif" alt="Nike Plus"/&gt;&lt;/a&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Thu, 28 Feb 2008 14:46:23 +0000</pubDate><guid>http://mariz.org/blog/2008/02/28/im-addicted/</guid></item><item><title>Twitter user timeline with a Django templatetag</title><link>http://mariz.org/blog/2008/02/11/twitter-user-timeline-django-templatetag/</link><description>&lt;a href="http://www.twitter.com" tittle="Twitter"&gt;&lt;img src="http://mariz.org/media/images/posts/twitter.gif" alt="Twitter"/&gt;&lt;/a&gt;&lt;br /&gt;
A simple &lt;a href="http://www.djangoproject.com/documentation/templates/"&gt;templatetag&lt;/a&gt; for adding to the template context a variable with the user timeline from &lt;a href="http://www.twitter.com"&gt;Twitter&lt;/a&gt;.&lt;br /&gt;
It uses the &lt;span class="code"&gt;CachedContextUpdatingNode&lt;/span&gt; &lt;a href="http://www.djangosnippets.org/snippets/223/"&gt;snippet&lt;/a&gt;
 for caching from &lt;a href="http://www.jacobian.org"&gt;Jacob Kaplan-Moss&lt;/a&gt;.&lt;br /&gt;
The reason that is necessary to cache content is because &lt;a href="http://www.twitter.com" tittle="Twitter"&gt;Twitter&lt;/a&gt; limits the number of accesses to the &lt;a href="http://groups.google.com/group/twitter-development-talk/web/api-documentation"&gt;API&lt;/a&gt;.&lt;br /&gt;
This only works if the &lt;a href="http://www.djangoproject.com/documentation/cache/"&gt;cache&lt;/a&gt; is enabled on your &lt;span class="code"&gt;settings.py&lt;/span&gt;.
&lt;pre class="code"&gt;class TwitterNode(CachedContextUpdatingNode):

    cache_timeout = 1800 # 30 Minutes, maybe you want to change this
    
    def __init__(self, username, varname):
        self.username = username
        self.varname = varname

    def make_datetime(self, created_at):
        return datetime.fromtimestamp(mktime(strptime(created_at, '%a %b %d %H:%M:%S +0000 %Y')))

    def get_cache_key(self, context):
        return 'twitter_user_timeline_cache'

    def get_content(self, context):
        try:
            response = urllib.urlopen('http://twitter.com/statuses/user_timeline/%s.json' % self.username).read()
            json = simplejson.loads(response)
        except:
            return {self.varname : None}
        for i in range(len(json)):
            json[i]['created_at'] = self.make_datetime(json[i]['created_at'])
        return {self.varname : json}
    
@register.tag
def twitter_user_timeline(parser, token):
    bits = token.contents.split()
    if len(bits) != 4:
        raise TemplateSyntaxError, "twitter_user_timeline tag takes exactly three arguments"
    if bits[2] != 'as':
        raise TemplateSyntaxError, "second argument to twitter_user_timeline tag must be 'as'"
    return TwitterNode(bits[1], bits[3])&lt;/pre&gt;
Usage:
&lt;pre class="code"&gt;{% twitter_user_timeline username as twitter_entries %}
{% if twitter_entries %}
  {% for entry in twitter_entries %}
  {{ entry.created_at|date:"d M Y H:i" }} - {{ entry.text }}
  {% endfor %}
{% endif %}&lt;/pre&gt;
Use the &lt;a href="http://mariz.org/downloads/file/3/"&gt;source&lt;/a&gt;, Luke.</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Mon, 11 Feb 2008 10:45:44 +0000</pubDate><guid>http://mariz.org/blog/2008/02/11/twitter-user-timeline-django-templatetag/</guid></item><item><title>My best project ever!</title><link>http://mariz.org/blog/2008/01/14/my-best-project-ever/</link><description>&lt;a href="http://mariz.org/media/images/posts/baby_1.jpg"&gt;&lt;img src="http://mariz.org/media/images/posts/baby_1_thumbnail.gif" alt="Baby" /&gt;&lt;/a&gt; &lt;a href="http://mariz.org/media/images/posts/baby_2.jpg"&gt;&lt;img src="http://mariz.org/media/images/posts/baby_2_thumbnail.gif" alt="Baby" /&gt;&lt;/a&gt;&lt;br /&gt;
The project is still under development. My &lt;a href="http://wedding.mariz.org"&gt;co-worker&lt;/a&gt; is doing her best to provide the most beautiful layout.</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Mon, 14 Jan 2008 23:14:39 +0000</pubDate><guid>http://mariz.org/blog/2008/01/14/my-best-project-ever/</guid></item><item><title>Fullread updates</title><link>http://mariz.org/blog/2008/01/10/fullread-updates/</link><description>New features on &lt;a href="http://fullread.com"&gt;Fullread&lt;/a&gt;:
&lt;ul class="squares"&gt;
  &lt;li&gt;Feeds in the latest and user bookmarks.        
        &lt;ul class="circles"&gt;
          &lt;li&gt;&lt;span class="code"&gt;http://fullread.com/feeds/latest/[rss/atom]/&lt;/span&gt; (By latest - all users)&lt;/li&gt;
          &lt;li&gt;&lt;span class="code"&gt;http://fullread.com/feeds/[username]/[rss/atom]/&lt;/span&gt; (By user)&lt;/li&gt;
        &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;List of users that bookmarked the same URL.&lt;/li&gt;
  &lt;li&gt;Multiple bookmarking service support.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class="bold"&gt;NOTE:&lt;/span&gt; If you are using a bookmarking service that is not available, please let me know: &lt;a href="http://fullread.com/contacts/?subject=Bookmarking%20service%20support"&gt;http://fullread.com/contacts/?subject=Bookmarking%20service%20support&lt;/a&gt;.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Thu, 10 Jan 2008 10:34:34 +0000</pubDate><guid>http://mariz.org/blog/2008/01/10/fullread-updates/</guid></item><item><title>A quote from Theo Schlossnagle</title><link>http://mariz.org/blog/2008/01/09/quote-theo-schlossnagle/</link><description>&lt;blockquote&gt;The language is mostly irrelevant. I can’t count the number of times I’ve hear people say "Java doesn’t scale" or "PHP doesn’t scale". No languages scales; solutions scale.&lt;/blockquote&gt;
Theo Schlossnagle in "Scalable Internet Architectures"</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Wed, 09 Jan 2008 14:30:32 +0000</pubDate><guid>http://mariz.org/blog/2008/01/09/quote-theo-schlossnagle/</guid></item><item><title>Fullread</title><link>http://mariz.org/blog/2008/01/03/fullread/</link><description> &lt;a href="http://fullread.com"&gt;&lt;img src="http://mariz.org/media/images/posts/fullread.gif" alt="fullread.com" /&gt;&lt;/a&gt;
&lt;br /&gt;
&lt;a href="http://fullread.com"&gt;Fullread&lt;/a&gt; is online. It's just a
simple tool that helps you organize your online readings.&lt;br /&gt;
I use &lt;a href="http://del.icio.us"&gt;del.icio.us&lt;/a&gt; a lot, mainly for bookmarking, but right
now my &lt;a href="http://del.icio-us"&gt;account&lt;/a&gt; is a complete mess because I’m constantly adding links that I want to read later and I don't delete them.&lt;br /&gt;
&lt;a href="http://fullread.com"&gt;Fullread&lt;/a&gt; uses a simple concept: I add an URL to my account to read later, then I decide to archive, delete or 
add it to my &lt;a href="http://del.icio.us"&gt;del.icio.us&lt;/a&gt;
account.&lt;br /&gt;
Feel free to &lt;a href="http://mariz.org/contacts/"&gt;send me&lt;/a&gt; any feature request or something else.&lt;br /&gt;
I hope you enjoy it.</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Thu, 03 Jan 2008 19:53:02 +0000</pubDate><guid>http://mariz.org/blog/2008/01/03/fullread/</guid></item><item><title>Swim across the Atlantic Ocean</title><link>http://mariz.org/blog/2007/11/30/swim-across-atlantic-ocean/</link><description>&lt;img src="http://mariz.org/media/images/posts/google-maps.gif" alt="Google Maps" /&gt;
&lt;br /&gt;
Try to get directions from "Belo Horizonte" to "Miami" on &lt;a href="http://maps.google.com"&gt;Google Maps&lt;/a&gt;.&lt;br /&gt;
Here is a shortcut: &lt;a href="http://smallr.net/google-maps"&gt;http://smallr.net/google-maps&lt;/a&gt;.
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Fri, 30 Nov 2007 14:53:27 +0000</pubDate><guid>http://mariz.org/blog/2007/11/30/swim-across-atlantic-ocean/</guid></item><item><title>Smallr updates</title><link>http://mariz.org/blog/2007/11/23/smallr-updates/</link><description>After I've messed up about the domain issue(see this &lt;a href="http://mariz.org/blog/2007/nov/22/smallr/#comments"&gt;comments&lt;/a&gt;), I've just updated &lt;a href="http://smallr.net"&gt;smallr&lt;/a&gt; with some features. Now provides an &lt;a href="http://smallr.net/api/"&gt;API&lt;/a&gt; to access the service by &lt;a href="http://en.wikipedia.org/wiki/REST"&gt;REST&lt;/a&gt;.&lt;br /&gt;
Right now &lt;s&gt;only&lt;/s&gt; supports &lt;a href="http://en.wikipedia.org/wiki/Json"&gt;JSON&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Xml"&gt;XML&lt;/a&gt; &lt;s&gt;will be&lt;/s&gt; is also available &lt;s&gt;soon&lt;/s&gt;.&lt;br /&gt;
A &lt;a href="http://smallr.net/buttons/"&gt;bookmarklet&lt;/a&gt; is also available.
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Fri, 23 Nov 2007 17:56:27 +0000</pubDate><guid>http://mariz.org/blog/2007/11/23/smallr-updates/</guid></item><item><title>Smallr</title><link>http://mariz.org/blog/2007/11/22/smallr/</link><description>&lt;a href="http://smallr.net"&gt;&lt;img src="http://mariz.org/media/images/posts/smallr.gif" alt="small.net" /&gt;&lt;/a&gt;
&lt;br /&gt;
I've just released &lt;a href="http://smallr.net"&gt;smallr&lt;/a&gt;. It lets you generate small web addresses with a keyword that make it easy to remember, will not break in emails and will never expire.&lt;br /&gt;
Basically is a &lt;a href="http://tinyurl.com/"&gt;TinyURL&lt;/a&gt; clone, with a keyword addon.&lt;br /&gt; There will be an &lt;a href="http://en.wikipedia.org/wiki/Api"&gt;API&lt;/a&gt; for webservices with &lt;a href="http://en.wikipedia.org/wiki/Json"&gt;JSON&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Xml"&gt;XML&lt;/a&gt;, eventually a &lt;a href="http://www.mozilla.com/firefox/"&gt;Firefox&lt;/a&gt; extension.&lt;br /&gt;
Test it and send me some feedback.&lt;br /&gt;
I hope you enjoy it.
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Thu, 22 Nov 2007 19:51:01 +0000</pubDate><guid>http://mariz.org/blog/2007/11/22/smallr/</guid></item><item><title>Weekend in Sintra</title><link>http://mariz.org/blog/2007/10/11/weekend-in-sintra/</link><description>&lt;a href="http://flickr.com/photos/nmariz/1526278293/in/set-72157602337207286/"&gt;&lt;img src="http://farm3.static.flickr.com/2066/1526278293_8becf00efb_s.jpg" alt="Sintra" class="float-left" /&gt;&lt;/a&gt;
&lt;a href="http://flickr.com/photos/nmariz/1527126226/in/set-72157602337207286/"&gt;&lt;img src="http://farm3.static.flickr.com/2300/1527126226_05eaba6361_s.jpg" alt="Quinta das Sequóias" class="float-left" /&gt;&lt;/a&gt;
&lt;br /&gt;

We went to &lt;a href="http://www.visitportugal.com/NR/exeres/6BEF1189-D6BD-4473-856B-604FCEF22106,frameless.htm"&gt;Sintra&lt;/a&gt; this weekend. &lt;br /&gt;
&lt;a href="http://www.visitportugal.com/NR/exeres/6BEF1189-D6BD-4473-856B-604FCEF22106,frameless.htm"&gt;Sintra&lt;/a&gt; is a magical place where you feel like you've just entered a time machine and you find yourself in a land of castles and palaces surrounded by a luxurious vegetation. 
It's inevitable to lose yourself in all the historical details that are related to this place and the numerous points of interest. &lt;br /&gt;
To put the cherry on top of the cake, our choice for accommodation could not have been better! 
If you are looking for tranquility and be surrounded by all that magical atmosphere and... brace yourselves... have a room view to Pena Palace you will want to discover &lt;a href="http://www.quintadasequoias.com/"&gt;Quinta das Sequóias&lt;/a&gt;. A cosy and warm reception are expecting you as well as a delicious breakfast. We are absolutely going to return there. &lt;br /&gt;
Some photos &lt;a href="http://flickr.com/photos/nmariz/sets/72157602337207286/"&gt;here&lt;/a&gt;.</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Thu, 11 Oct 2007 00:15:24 +0100</pubDate><guid>http://mariz.org/blog/2007/10/11/weekend-in-sintra/</guid></item><item><title>iPhone says Welcome to Django</title><link>http://mariz.org/blog/2007/08/20/iphone-says-welcome-to-django/</link><description>&lt;a href="http://www.flickr.com/photos/jacobian/1160698795/"&gt;&lt;img src="http://farm2.static.flickr.com/1203/1160698795_9ff6c12a1f.jpg?v=0" alt="Django on iPhone"  /&gt;&lt;/a&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Mon, 20 Aug 2007 20:50:16 +0100</pubDate><guid>http://mariz.org/blog/2007/08/20/iphone-says-welcome-to-django/</guid></item><item><title>A simple WSGI middleware dispatcher</title><link>http://mariz.org/blog/2007/06/08/simple-wsgi-middleware-dispatcher/</link><description>&lt;blockquote&gt;The Web Server Gateway Interface (&lt;a href="http://www.python.org/dev/peps/pep-0333/"&gt;WSGI&lt;/a&gt;) is a standard interface between web server software and web applications written in Python. Having a standard interface makes it easy to use an application that supports WSGI with a number of different web servers.&lt;/blockquote&gt;


One implementation is &lt;a href="http://docs.python.org/lib/module-wsgiref.html"&gt;wsgiref&lt;/a&gt; that was added to Python 2.5 Standard Library.&lt;br /&gt;
Here is a simple web application that writes "Hello World":

&lt;pre class="code"&gt;
def index(environ, start_response):
    start_response("200 Ok", [('content-type', 'text/html')])
    return ['Hello World!']

if __name__ == "__main__":
    from wsgiref.simple_server import make_server
    server = make_server(HOST, PORT, index)
    print 'Starting up HTTP server on port %i...' % PORT
    server.serve_forever()
&lt;/pre&gt;

&lt;br /&gt;
This is nice, but is not very useful for us, so lets add some kind of controller(or url dispatcher):

&lt;pre class="code"&gt;
from dispatcher import Dispatcher

dispatcher = Dispatcher()
dispatcher.add(r'^/$', 'views.index')
dispatcher.add(r'^/hello/(?P&amp;lt;username&amp;gt;\w+)/$', 'views.hello')

HOST = 'localhost'
PORT = 8000

if __name__ == "__main__": 
    from wsgiref.simple_server import make_server
    server = make_server(HOST, PORT, dispatcher)
    print 'Starting up HTTP server on port %i...' % PORT
    server.serve_forever()
&lt;/pre&gt;

&lt;br /&gt;
As you can see I've used a regular expression for the url mapping, just like &lt;a href="http://www.djangoproject.com"&gt;Django&lt;/a&gt; uses.&lt;br /&gt;
Here is the dispatcher(dispatcher.py):

&lt;pre class="code"&gt;
import re

class Dispatcher(object):
    def __init__(self, handle404 = None):
        self.urls = dict()
        self.request_path = ''
        if handle404:
            self.handle404 = handle404
        else:
            self.handle404 = self._404

    def __call__(self, environ, start_response):
        self.request_path = environ.get('PATH_INFO', '')
        for url in self.urls:            
            regex = re.compile(url)
            if regex.match(self.request_path):
                m = regex.match(self.request_path)                        
                mod_name, func_name = self._get_mod_func(self.urls[url])                
                try:
                    callback = getattr(__import__(mod_name, {}, {}, ['']), func_name)
                except ImportError, e:
                    raise Exception, "Could not import %s. Error was: %s" % (mod_name, str(e))
                except AttributeError, e:
                    raise Exception, "Tried %s in module %s. Error was: %s" % (func_name, mod_name, str(e))                
                args = (environ, start_response)
                kwargs = dict()                
                for i in regex.groupindex:
                    kwargs[i] = m.group(i)
                # Run callback with environ, start_response and args
                return callback(*args, **kwargs)
        # No match with the defined urls
        return self.handle404(environ, start_response)
            
    def _get_mod_func(self, callback):
        """
        Converts 'path.to.module.funtion' to ['path.to.module', 'function']
        """
        try:
            d = callback.rindex('.')
        except ValueError:
            return callback, ''
        return callback[:d], callback[d+1:]
    
    def _404(self, environ, start_response):
        start_response("404 Not Found", [('content-type', 'text/html')])
        return ['Not Found']

    def add(self, regex, handler):
        self.urls[regex] = handler
&lt;/pre&gt;

&lt;br /&gt;
And here is the views(views.py):

&lt;pre class="code"&gt;
def index(environ, start_response):
    start_response("200 Ok", [('content-type', 'text/html')])
    return ['Index']

def hello(environ, start_response, username):
    start_response("200 Ok", [('content-type', 'text/html')])
    return ['Hello %s' % username]
&lt;/pre&gt;

&lt;br/&gt;
Simple eh?&lt;br /&gt;
This is just a start, now we can add more features, like encapsulate the &lt;span class="code"&gt;start_response&lt;/span&gt; method and add some kind of &lt;span class="code"&gt;HttpResponse&lt;/span&gt;.&lt;br /&gt;
I don't what do reinvent the wheel here and add another web framework to &lt;a href="http://www.python.org"&gt;Python&lt;/a&gt;, just like Joe Gregorio says in &lt;a href="http://bitworking.org/news/Why_so_many_Python_web_frameworks"&gt;this article&lt;/a&gt;. But to prove how trivial is to make a simple framework with &lt;a href="http://www.python.org/dev/peps/pep-0333/"&gt;WSGI&lt;/a&gt; and don't worry about the deployment at development phase.</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Nuno Mariz</dc:creator><pubDate>Fri, 08 Jun 2007 10:41:25 +0100</pubDate><guid>http://mariz.org/blog/2007/06/08/simple-wsgi-middleware-dispatcher/</guid></item></channel></rss>