<?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>Pelago :: web design &#38; development blog</title>
	<atom:link href="http://www.pelagodesign.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.pelagodesign.com/blog</link>
	<description>Santa Barbara Web Design and Web Development Blog on the web world and other randoms</description>
	<lastBuildDate>Fri, 19 Feb 2010 16:58:27 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Breaking the &#8220;rules&#8221; of web development</title>
		<link>http://www.pelagodesign.com/blog/2010/01/19/breaking-the-rules-of-web-development/</link>
		<comments>http://www.pelagodesign.com/blog/2010/01/19/breaking-the-rules-of-web-development/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 23:58:26 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Creative Engineering]]></category>
		<category><![CDATA[denormalization]]></category>
		<category><![CDATA[frameworks]]></category>
		<category><![CDATA[sharding]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://www.pelagodesign.com/blog/?p=502</guid>
		<description><![CDATA[I&#8217;ve been developing for the web long enough &#8212; since my foray into PERL and HTML in 1994 &#8212; to know that there will always be a certain &#8220;rules&#8221; developers will adhere to when banging out lines of code. They are usually good rules because it is important for developers to follow them. However,  [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.pelagodesign.com/blog/wp-content/uploads/2010/01/394531457_b1ed281e28-300x199.jpg" alt="" title="Web development rules and when to break them" width="300" height="199" class="alignright size-medium wp-image-506" style="float: right; margin: 0 0 9px 7px;" />I&#8217;ve been developing for the web long enough &mdash; since my foray into PERL and HTML in 1994 &mdash; to know that there will always be a certain &#8220;rules&#8221; developers will adhere to when banging out lines of code. They are usually good rules because it is important for developers to follow them. However,  developers need to know when to break from convention, when a higher purpose requires them to sacrifice the brilliance and elegance of their code. I personally have a few favorite examples from my own years of experience and from working with other developers&hellip;</p>
<h3>The Almighty Framework</h3>
<p>Frameworks are great for web development. The Model-View-Controller (MVC) framework, in its many interpretations for languages such as PHP, Ruby and Python, has made building web sites so much faster. And MVC frameworks make for nice clean code and a logical separation of data, business logic, actions and content. The view layer in and of itself is a godsend and the MVC framework has finally provided recognition for all the hard work put in by templating engine developers (i.e. <a href="http://www.smarty.net/" title="Smarty Template Engine">Smarty</a>).</p>
<p>What happens when the framework becomes a performance barrier? While developing our online project management software, <a href="http://www.myintervals.com" title="Intervals, online time, task and project management software built by and for designers, developers and creatives">Intervals</a>, we&#8217;ve come across two main areas where we&#8217;ve had to lift the hood and require some of the framework internals. </p>
<p>First, web-based applications can be complex enough that the SQL queries can become cumbersome if they are not fine tuned. Using the default SELECT and JOIN conventions provided by the framework is not always ideal. When you start getting into the granular levels of optimizing SQL queries you have to get your hands dirty at the Model level. This means writing new queries, and tweaking and tuning them until they run as fast as possible. In some circumstances, this sometimes means associating a Model, especially list models, with a database table other than what it was intended. In addition, the framework is not going to optimize your database structure for you. Once the database is built you will need to tune the indices and learn about vacuuming and clustering. </p>
<p>Second, frameworks consume memory as they sift data up from the database, through layers of business logic, actions, and finally, into the view layer. For basic web-based applications that serve up limited information on a page, this is not a big concern and can usually be overcome using memcache if it does become one. However, if your web-based application is churning through a lot of data and presenting it to the user in real time, you will hit memory limits. This can happen, for example, with reports that contain a lot of data over a large date range (probably why Basecamp limits report data to a given number of months). In this case you will get the best performance with the View layer accessing the database directly using cursors. Yeah, I know developers won&#8217;t like this, but there comes a time when providing speed to your customers is more important than the framework upon which it is built. Anyways, cutting out the middle man you remove most of the strain on memory and increase the speed of the reports. </p>
<h3>The Normalized Database</h3>
<p>When we design databases our primary goal is to reduce the redundancy of data through the use of multiple tables, foreign keys, and queries that rely on JOINs. Developers will nitpick over a normalized database until every last bit of redundancy is ironed out. This approach works great for most web-based applications but when traffic increases all of those carefully crafted tables and keys, along with the JOIN-heavy queries begin costing you milliseconds, then seconds, before the app becomes unusable. </p>
<p>The solution is to begin denormalizing data. We called this a &#8220;necessary redundancy&#8221; at Pelago. You begin by identifying the slowest queries and removing their JOINs by placed the JOINed data in multiple tables. Than it&#8217;s up to stored procedures at the database level or developers at the code base level to make sure the redundant data is always kept redundant. The entire database doesn&#8217;t have to be denormalized all at once. Just the tables requiring JOINs that are causing you performance issues.</p>
<h3>One Database to Rule Them All</h3>
<p>Another harsh reality of web development is that the database may become too large and unwieldy for handling the number of people using the web-based application. Sys admins will start throwing around the four-letter word &#8220;sharding&#8221; as developers begin to cringe. If your app starts growing large enough, sharding may become a necessity for the app to scale. Breaking up your database onto multiple servers and keeping each copy of the database in sync with the others is a laborious task and should be a last resort. However, to dismiss sharding altogether in favor of throwing hardware at the problem is shortsighted. If your web-based application is growing you should be thinking about how you would shard the database if it becomes necessary in the long term. It&#8217;s better to have a plan in place before it&#8217;s needed than to be scrambling at the last moment to relieve an overloaded web application. </p>
<p>In fact, all of the &#8220;rules&#8221; I mentioned above should be addressed by web developers at some point if they have plans on scaling their web-based applications. Meanwhile, let&#8217;s hear from other web developers out there. What are some of the &#8220;rules&#8221; you&#8217;ve had to break? </p>
<div xmlns:cc="http://creativecommons.org/ns#" about="http://www.flickr.com/photos/brymo/394531457/" style="font-size: 10px; line-height: 12px; margin-bottom: 2em;">Photo credit:<br /><a rel="cc:attributionURL" href="http://www.flickr.com/photos/brymo/">http://www.flickr.com/photos/brymo/</a> / <a rel="license" href="http://creativecommons.org/licenses/by-sa/2.0/">CC BY-SA 2.0</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.pelagodesign.com/blog/2010/01/19/breaking-the-rules-of-web-development/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Crunchbang Linux a Speedy Alternative to Ubuntu</title>
		<link>http://www.pelagodesign.com/blog/2009/11/06/crunchbang-linux-a-speedy-alternative-to-ubuntu/</link>
		<comments>http://www.pelagodesign.com/blog/2009/11/06/crunchbang-linux-a-speedy-alternative-to-ubuntu/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 17:08:57 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Creative Engineering]]></category>
		<category><![CDATA[crunchbang]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.pelagodesign.com/blog/2009/11/06/crunchbang-linux-a-speedy-alternative-to-ubuntu/</guid>
		<description><![CDATA[Built using only Ubuntu, Crunchbang Linux has boiled down its distribution offering only the bare minimum needed to have a good balance between speed and functionality. Though not intended for older hardware, it is reported to work well in outdated environments where there is a premium placed on eking out as much speed as possible. [...]]]></description>
			<content:encoded><![CDATA[<p>Built using only Ubuntu, Crunchbang Linux has boiled down its distribution offering only the bare minimum needed to have a good balance between speed and functionality. Though not intended for older hardware, it is reported to work well in outdated environments where there is a premium placed on eking out as much speed as possible. Read more about it at <a href="http://crunchbanglinux.org/wiki/about" title="More about Crunchbang Linux">http://crunchbanglinux.org/wiki/about</a> and share with us any stories you might have in using it. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.pelagodesign.com/blog/2009/11/06/crunchbang-linux-a-speedy-alternative-to-ubuntu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to make Ubuntu Linux run faster on a laptop</title>
		<link>http://www.pelagodesign.com/blog/2009/07/21/how-to-make-ubuntu-linux-run-faster-on-a-laptop/</link>
		<comments>http://www.pelagodesign.com/blog/2009/07/21/how-to-make-ubuntu-linux-run-faster-on-a-laptop/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 20:20:03 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Creative Engineering]]></category>
		<category><![CDATA[laptop]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.pelagodesign.com/blog/?p=464</guid>
		<description><![CDATA[If you google around on the web you will find there are several tutorials on how to make your Ubuntu Linux installation run faster &#8212; especially on older hardware. These tips are very useful and range from minor tweaks to major overhauls. Being an intermediate Linux user myself, I found some of the more difficult [...]]]></description>
			<content:encoded><![CDATA[<p>If you google around on the web you will find there are several tutorials on how to make your Ubuntu Linux installation run faster &mdash; especially on older hardware. These tips are very useful and range from minor tweaks to major overhauls. Being an intermediate Linux user myself, I found some of the more difficult optimizations to be overwhelming and not something I would want to try at home &mdash; changes to how Linux writes to the hard drive, for example. While researching and implementing the optimizations I felt comfortable with on my older Dell laptop and my new Asus eeePC 901, I jotted down all of my notes for future reference. Below are some tips for the intermediate user on how to optimize your laptop (or desktop) running Ubuntu Linux.</p>
<p>&nbsp;</p>
<h3>Reduce Swappiness</h3>
<p>Most laptops have enough RAM installed that the swap space on the hard disk shouldn&#8217;t really be used. Yet the default setting for swappiness in Ubuntu is 60. By lowering it to 10 we can reduce the number of read/writes the the hard disk. This is especially handy for netbooks with solid state drives in them. To reduce the swappiness, follow these steps:</p>
<ol>
<li><code style="font-weight: bold;">sudo sysctl -w vm.swappiness=10</code></li>
<li>Add the following line to <em>/etc/sysctl.conf</em><br />
<code style="font-weight: bold;">vm.swappiness=10</code></li>
</ol>
<p>&nbsp;</p>
<h3>Preload</h3>
<p>Preload is an adaptive read-ahead daemon that monitors running applications and analyzes them for commonalities. It then uses this data to predict what applications you might run and preloads them into memory. The result is faster startup times for commonly used programs. Installing preload is as easy. Just run the following line in a terminal window:</p>
<p><code style="font-weight: bold;">sudo apt-get install preload</code></p>
<p><a href="http://www.goitexpert.com/general/load-application-quicker-in-ubuntu-with-preload/" title="Load Application Quicker in UBUNTU With Preload">&#187; For further explanation, read this article on loading applications quicker in Ubuntu using preload.<br />
</a></p>
<p>&nbsp;</p>
<h3>Boot-Up Manager</h3>
<p>The Boot-Up Manager (BUM) is a useful utility for starting and stopping boot-up scripts. Once installed it will appear in the <em>System -&gt; Administration</em> menu. You can use BUM disable unnecessary boot-up scripts that may be slowing down your boot time. For example, I disabled saned, an API library for scanners, because I know I&#8217;ll never be attaching a flatbed scanner to my laptop. To install BUM:</p>
<p><code style="font-weight: bold;">sudo apt-get install bum</code></p>
<p><a href="http://www.marzocca.net/linux/bumdocs.html" title="Boot-Up Manager Documentation">&#187; Read the documentation for Boot-Up Manager</a></p>
<p>&nbsp;</p>
<h3>Startup Applications</h3>
<p>If you are using Gnome for your desktop manager there will be an option to select which applications are started when you login. Go to <em>System -&gt; Preferences -&gt; Startup Applications</em> and uncheck the programs you don&#8217;t need. For example, I disabled the Evolution Alarm Notifier because I don&#8217;t use Evolution for setting alarms. I also disabled the Remote Desktop server, UME Desktop Launcher, and UNR Launcher. Just be careful to uncheck them and not remove them. In the case that you&#8217;ve removed something critical,  you&#8217;ll want to be able to get it back. </p>
<p>&nbsp;</p>
<h3>Replace Metacity with Openbox</h3>
<p>Openbox is a minimalistic and lightweight window manager that is known to run much faster than metacity, its bulkier counterpart. And you can easily get it working while still using Gnome as your window manager / desktop environment. By running Openbox inside the Gnome environment your desktop will become cleaner and faster. To install it, follow these steps:</p>
<ol>
<li>Install openbox using:<br />
<code style="font-weight: bold;">sudo apt-get install openbox obconf openbox-themes</code></li>
<li>Setup openbox as the default window manager by adding an entry in Startup Applications.<br />
To do this, go to <em>System -&gt; Preferences -&gt; Startup Applications and enter the following:</p>
<ul>
<li>Name: Openbox</li>
<li>Command: openbox &ndash;&ndash;replace</li>
</ul>
<p></em><em>Note: According to the Openbox documentation you can make it the default by choosing the GNOME/Openbox session when logging in and saving this as your default session. However, this functionality is broken in 9.04. The above steps are a workaround until this is fixed.</em>
</li>
<li>Choosing the Openbox theme and other configuration settings<br />
Go to <em>System -&gt; Preferences -&gt; Openbox Configuration Manager</em> to choose a theme you like and to update other settings such as Appearance and Windows.<br />
<em>Note: changing the Desktops setting doesn&#8217;t effect the Gnome applet controlling the number of desktops. To change the number of desktops, you will need to revert back to Metacity and change them, then re-enable Openbox</em>
</li>
</ol>
<p><a href="http://icculus.org/openbox/index.php/Main_Page" title="Openbox, a highly configurable, next generation window manager with extensive standards support.">&#187; More information, documentation and screenshots available at the Openbox web site</a></p>
<p>&nbsp;</p>
<h3>That&#8217;s all for now</h3>
<p>I found that making these few simple changes decreased load times on my older laptop significantly and made my newer netbook more minimal. Hopefully, these tips will help you as well.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pelagodesign.com/blog/2009/07/21/how-to-make-ubuntu-linux-run-faster-on-a-laptop/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Face detection in pure PHP</title>
		<link>http://www.pelagodesign.com/blog/2009/06/25/face-detection-in-pure-php/</link>
		<comments>http://www.pelagodesign.com/blog/2009/06/25/face-detection-in-pure-php/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 17:35:44 +0000</pubDate>
		<dc:creator>Jaime</dc:creator>
				<category><![CDATA[Creative Engineering]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.pelagodesign.com/blog/?p=459</guid>
		<description><![CDATA[Face detection in pure PHP
Technical description.
]]></description>
			<content:encoded><![CDATA[<p><a href="http://svay.com/blog/index/post/2009/06/19/Face-detection-in-pure-PHP-(without-OpenCV)">Face detection in pure PHP</a></p>
<p><a href="http://news.ycombinator.com/item?id=672250">Technical description.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.pelagodesign.com/blog/2009/06/25/face-detection-in-pure-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP crons, linux, and the hostname</title>
		<link>http://www.pelagodesign.com/blog/2009/05/28/php-crons-linux-and-the-hostname/</link>
		<comments>http://www.pelagodesign.com/blog/2009/05/28/php-crons-linux-and-the-hostname/#comments</comments>
		<pubDate>Thu, 28 May 2009 18:20:39 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Creative Engineering]]></category>
		<category><![CDATA[cron]]></category>
		<category><![CDATA[hostname]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.pelagodesign.com/blog/?p=457</guid>
		<description><![CDATA[When running PHP as a cron, the $_SERVER['HOSTNAME'] variable is not set, nor are any other variables that will identify which server your cron is running on. This can be problematic if you are running the same cron on multiple servers, such as in a load balanced environment, and you need the cron to report [...]]]></description>
			<content:encoded><![CDATA[<p>When running PHP as a cron, the $_SERVER['HOSTNAME'] variable is not set, nor are any other variables that will identify which server your cron is running on. This can be problematic if you are running the same cron on multiple servers, such as in a load balanced environment, and you need the cron to report back or log information about the server on which it ran. </p>
<p>Here is some code for getting the hostname value from your linux network configuration, assuming you have setup /etc/sysconfig/network properly.</p>
<p><code><br />
//get hostname info from /etc/sysconfig/network<br />
preg_match('/HOSTNAME=(.*)/', file_get_contents('/etc/sysconfig/network'), $network);<br />
$hostname = split("\=", $network[0]);<br />
echo $hostname[1]; //this equals the value of your HOSTNAME<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.pelagodesign.com/blog/2009/05/28/php-crons-linux-and-the-hostname/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ISO 8601 Date Validation That Doesn&#8217;t Suck</title>
		<link>http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/</link>
		<comments>http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/#comments</comments>
		<pubDate>Wed, 20 May 2009 16:38:25 +0000</pubDate>
		<dc:creator>Cameron</dc:creator>
				<category><![CDATA[Creative Engineering]]></category>
		<category><![CDATA[iso-8601]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[regular expressions]]></category>
		<category><![CDATA[validation]]></category>

		<guid isPermaLink="false">http://www.pelagodesign.com/blog/?p=448</guid>
		<description><![CDATA[UPDATED February 19th, 2010: As BobM pointed out, the original solution to this problem didn&#8217;t account for fractional decimals. Originally I didn&#8217;t include them because Intervals didn&#8217;t require that level of precision, but apparently fractional decimals are quite common elsewhere. Because of that, I&#8217;ve updated this post, along with the regex, to include support for [...]]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATED February 19th, 2010:</strong> <em>As <a href="#comment-6503" title="View BobM's comment">BobM</a> pointed out, the original solution to this problem didn&#8217;t account for fractional decimals. Originally I didn&#8217;t include them because Intervals didn&#8217;t require that level of precision, but apparently fractional decimals are quite common elsewhere. Because of that, I&#8217;ve updated this post, along with the regex, to include support for fractional decimals.</em></p>
<p>For the Intervals API, we&#8217;re wrestling with issues surrounding data input validation. This recently became interesting when the matter of date validation came up. Ordinarily, Intervals allows many, many different date formats, dependent on the locale that the customer is using (for example, Intervals may expect the date format &#8216;mm/dd/yyyy&#8217; for US customers, &#8216;dd.mm.yy&#8217; for a customer in Austria).</p>
<p>For our API developers, we wanted to use a common, universal format, one that would be easily compatible with our application and database layers. For that we selected ISO 8601, which is great in terms of widespread use, but not so great in terms of how complicated its specifications are.</p>
<p>Generally, ISO 8601 looks something like &#8216;2009-05-20&#8242; for dates and &#8216;2009-05-20 12:30:30&#8242; for date/time combinations. These two examples encompass 98% of the user input we&#8217;re likely to encounter. But we wanted to make sure that if we told developers they could use ISO 8601 dates, our system would support it. <span id="more-448"></span>Unfortunately, there&#8217;s not a lot of code out there for the validation of ISO 8601 dates (especially regular expressions), and most of the stuff that <em>is</em> out there doesn&#8217;t encompass the entirety of the ISO 8601 spec.</p>
<p>Starting off, here are some dates that the validator <strong>should</strong> match (all these are valid ISO 8601 dates to the best of my knowledge):</p>
<p>2009-12T12:34<br />
2009<br />
2009-05-19<br />
2009-05-19<br />
20090519<br />
2009123<br />
2009-05<br />
2009-123<br />
2009-222<br />
2009-001<br />
2009-W01-1<br />
2009-W51-1<br />
2009-W511<br />
2009-W33<br />
2009W511<br />
2009-05-19<br />
2009-05-19 00:00<br />
2009-05-19 14<br />
2009-05-19 14:31<br />
2009-05-19 14:39:22<br />
2009-05-19T14:39Z<br />
2009-W21-2<br />
2009-W21-2T01:22<br />
2009-139<br />
2009-05-19 14:39:22-06:00<br />
2009-05-19 14:39:22+0600<br />
2009-05-19 14:39:22-01<br />
20090621T0545Z<br />
2007-04-06T00:00<br />
2007-04-05T24:00</p>
<p><em>Added Feb 19 2010:</em><br />
2010-02-18T16:23:48.5<br />
2010-02-18T16:23:48,444<br />
2010-02-18T16:23:48,3-06:00<br />
2010-02-18T16:23.4<br />
2010-02-18T16:23,25<br />
2010-02-18T16:23.33+0600<br />
2010-02-18T16.23334444<br />
2010-02-18T16,2283<br />
2009-05-19 143922.500<br />
2009-05-19 1439,55</p>
<p>And here are some of the strings that the validator <strong>should not</strong> match (ie. reject):</p>
<p>200905<br />
2009367<br />
2009-<br />
2007-04-05T24:50<br />
2009-000<br />
2009-M511<br />
2009M511<br />
2009-05-19T14a39r<br />
2009-05-19T14:3924<br />
2009-0519<br />
2009-05-1914:39<br />
2009-05-19 14:<br />
2009-05-19r14:39<br />
2009-05-19 14a39a22<br />
200912-01<br />
2009-05-19 14:39:22+06a00</p>
<p><em>Added Feb 19 2010:</em><br />
2009-05-19 146922.500<br />
2010-02-18T16.5:23.35:48<br />
2010-02-18T16:23.35:48<br />
2010-02-18T16:23.35:48.45<br />
2009-05-19 14.5.44<br />
2010-02-18T16:23.33.600<br />
2010-02-18T16,25:23:48,444</p>
<p>The code we came up with was the following:</p>
<p><em>Updated Feb 19 2010:</em><br />
<code>^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$</code></p>
<p>I guess I should add the caveat that this code doesn&#8217;t support the time interval or duration part of the ISO 8601 spec, so I didn&#8217;t include it. And it only supports dates or date/times, since right now we don&#8217;t have to deal with time input (for the Intervals API, all time is input in decimal format, rather than ISO 8601). But it should support everything else. Please let me know if this works for you or doesn&#8217;t, of if you can fine tune it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Ubuntu Linux: How to setup a VPN connection to a SonicWall router using Openswan and Pre-shared Keys (PSK)</title>
		<link>http://www.pelagodesign.com/blog/2009/05/18/ubuntu-linux-how-to-setup-a-vpn-connection-to-a-sonicwall-router-using-openswan-and-pre-shared-keys-psk/</link>
		<comments>http://www.pelagodesign.com/blog/2009/05/18/ubuntu-linux-how-to-setup-a-vpn-connection-to-a-sonicwall-router-using-openswan-and-pre-shared-keys-psk/#comments</comments>
		<pubDate>Mon, 18 May 2009 19:27:59 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Creative Engineering]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[openswan]]></category>
		<category><![CDATA[psk]]></category>
		<category><![CDATA[sonicwall]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[vpn]]></category>

		<guid isPermaLink="false">http://www.pelagodesign.com/blog/?p=403</guid>
		<description><![CDATA[
Contents

Background
Configuring the Sonicwall Router
Installing Openswan
Configuring Openswan
Starting and stopping the VPN connection
References



Background
Pelago is a web design and development agency in Santa Barbara, California. Since our humble beginnings  in August of 2000, we&#8217;ve seen the Internet landscape evolve exponentially in the last nine years. Our most current challenge as a creative and engineering agency is in [...]]]></description>
			<content:encoded><![CDATA[<div style="float: right; width: 40%; margin: 23px 0 11px 9px; padding: 13px 17px 11px 5px; background-color: #EFEFE6; border: 1px solid #CCCCBB;">
Contents</p>
<ul>
<li><a href="#background" title="Background">Background</a></li>
<li><a href="#configuringsonicwall" title="Configuring the SonicWall Router">Configuring the Sonicwall Router</a></li>
<li><a href="#installingopenswan" title="Installing Openswan">Installing Openswan</a></li>
<li><a href="#configuringopenswan" title="Configuring Openswan">Configuring Openswan</a></li>
<li><a href="#startingstopping" title="Starting and stopping the VPN connection">Starting and stopping the VPN connection</a></li>
<li><a href="#references" title="References">References</a></li>
</ul>
</div>
<p><a name="background"></a><br />
<h2>Background</h2>
<p>Pelago is a web design and development agency in Santa Barbara, California. Since our humble beginnings  in August of 2000, we&#8217;ve seen the Internet landscape evolve exponentially in the last nine years. Our most current challenge as a creative and engineering agency is in embracing diversity in platforms and the inevitable shift towards the remote office. We use three different operating systems &mdash; Windows, OS X and Linux &mdash; on a daily basis. In addition to developing web-based project management software that is compatible with all three platforms, our designers and developers rely on them  inside and outside of the office. Tunneling through the firewall from outside the office was our next requirement for embracing a diverse and distributed remote office. </p>
<p>Our SonicWall router makes it easy enough to establish a VPN connection using Windows. There is a client that can be downloaded from the SonicWall web site. What about other operating systems? Our developers often use Ubuntu Linux from home and required a way to VPN into the office. Once established, a VPN connection allows access to development servers, remote desktops, and other network resources inside the firewall; so you can see why it would be essential for the remote office.</p>
<p>The problem, as most Linux users out there already know, is that setting up a VPN connection in Ubuntu Linux is not very easy. After much trial and error, here is how we got the VPN working on Ubuntu Linux using Openswan.</p>
<p><a name="configuringsonicwall"></a><br />
<h2>Configuring the SonicWall Router</h2>
<p>Login to your SonicWall router admin and make the following adjustments to the VPN settings.</p>
<ol>
<li style="margin: 6px 0 14px 0;">
<strong>Click on the VPN link and note the Unique Firewall Identifier for your SonicWall router. You will need it later for the value <code>sonicwall.unique.identifier</code>.</strong><br />
<img src="http://www.pelagodesign.com/blog/wp-content/uploads/2009/05/vpn_settings1.png" alt="SonicWall VPN Settings" title="SonicWall VPN Settings" width="640" height="372" class="size-full wp-image-406" />
</li>
<li style="margin: 6px 0 14px 0;">
<strong>Under VPN Policies, create or edit the &#8216;GroupVPN&#8217; policy.</strong>
</li>
<li style="margin: 6px 0 14px 0;"><strong>Click on the General tab and set the following:</strong><br />
<img src="http://www.pelagodesign.com/blog/wp-content/uploads/2009/05/vpn_general.png" alt="SonicWall VPN General Settings " title="SonicWall VPN General Settings " width="625" height="326" class="size-full wp-image-408" /></p>
<ul>
<li>IPSec Keying Mode: IKE using Preshared Secret</li>
<li>Shared Secret: shared.secret.key <em>(enter your secret key here)</em></li>
</ul>
<ul>
</ul>
</li>
<li style="margin: 6px 0 14px 0;">
<strong>Click on the Proposals tab and set the following:</strong><br />
<img src="http://www.pelagodesign.com/blog/wp-content/uploads/2009/05/vpn_proposals.png" alt="SonicWall VPN Proposals Settings" title="SonicWall VPN Proposals Settings" width="625" height="525" class="size-full wp-image-411" /></p>
<ul>
<li>IKE (Phase 1) Proposal<br />
		DH Group: Group 5<br />
		Encryption: 3DES<br />
		Authentication: SHA1
        </li>
<li>Ipsec (Phase 2) Proposal<br />
		Protocol: ESP<br />
		Encryption: 3DES<br />
		Authentication: SHA1
        </li>
<li>Enable Perfect Forward Secrecy <em>(checked)</em><br />
		DH Group: Group 5
        </li>
</ul>
</li>
</ol>
<p><a name="installingopenswan"></a><br />
<h2>Installing Openswan</h2>
<p>If you are using Ubuntu, open a terminal window and type in:<br />
<code>sudo apt-get install openswan</code><br />
The install will ask you a few questions about how you want to set it up. Select the suggested default for each step. This will install Openswan and create the ipsec.conf and ipsec.secrets configuration files.</p>
<p><a name="configuringopenswan"></a><br />
<h2>Configuring Openswan</h2>
<p><strong>Add the following connection parameters to your /etc/ipsec.conf file:</strong><br />
<code>conn sonicwall<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type=tunnel<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;left=192.168.2.31 #your IP<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;leftid=@home<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;leftxauthclient=yes<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;right=xxx.xxx.xxx.xxx #IP address of your sonicwall router<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rightsubnet=192.168.1.0/24 #gateway IP for your LAN. This will work for most<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rightxauthserver=yes<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rightid=@sonicwall.unique.identifier<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;keyingtries=0<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pfs=yes<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aggrmode=yes<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;auto=add<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;auth=esp<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;esp=3DES-SHA1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ike=3DES-SHA1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;authby=secret<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#xauth=yes<br />
</code></p>
<p>Update: After upgrading to Ubuntu 9.10 a few things changed in the conf file. First, I had to comment out &#8216;xauth=yes&#8217; as it was throwing an error. Second, I had to use my own static IP instead of %defaultroute. If you are using DHCP, %defaultroute may still work, but I have a static IP and had to change this.</p>
<p><strong>Add the following line to your /etc/ipsec.secrets file</strong><br />
<code>@home @sonicwall.unique.identifer : PSK "shared.secret.key"</code></p>
<p><a name="startingstopping"></a><br />
<h2>Starting and stopping the VPN connection</h2>
<p><strong>Starting ipsec and opening the VPN connection</strong><br />
<code>sudo ipsec setup &ndash;&ndash;start<br />
sudo ipsec auto &ndash;&ndash;add sonicwall <em>(note: if you change the configuration files, you'll need to run 'sudo ipsec auto &ndash;&ndash;replace sonicwall' to reload the file)</em><br />
sudo ipsec whack &ndash;&ndash;name sonicwall &ndash;&ndash;initiate<br />
</code><br />
<strong>Closing the VPN connection and stopping ipsec</strong><br />
<code>sudo ipsec whack &ndash;&ndash;name sonicwall &ndash;&ndash;terminate<br />
sudo ipsec setup &ndash;&ndash;stop<br />
</code></p>
<p><a name="references"></a><br />
<h2>References</h2>
<p>The following links were useful for getting the VPN connection up and running on Ubuntu Linux:<br />
<strong>Openswan wiki page for SonicWall routers:</strong><br />
<a href="http://wiki.openswan.org/index.php/Openswan/SonicWall" title="Openswan wiki page for SonicWall routers">http://wiki.openswan.org/index.php/Openswan/SonicWall</a><br />
<strong>SonicWall PDF instructions for using Agressive Mode and IKE with Pre-shared Keys</strong><br />
<a href="http://www.sonicwall.com/downloads/SonicOS_Enhanced_to_Openswan_Using_Aggressive_Mode_IKE_with_PreShared_key.pdf" title="SonicWall PDF instructions for using Agressive Mode and IKE with Pre-shared Keys">http://www.sonicwall.com/downloads<wbr />/SonicOS_Enhanced_to_Openswan_Using_Aggressive_Mode_IKE_with_PreShared_key.pdf<br />
</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.pelagodesign.com/blog/2009/05/18/ubuntu-linux-how-to-setup-a-vpn-connection-to-a-sonicwall-router-using-openswan-and-pre-shared-keys-psk/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Jesusita Fire in Santa Barbara has taken a turn for the worst</title>
		<link>http://www.pelagodesign.com/blog/2009/05/06/jesusita-fire-in-santa-barbara-has-taken-a-turn-for-the-worst/</link>
		<comments>http://www.pelagodesign.com/blog/2009/05/06/jesusita-fire-in-santa-barbara-has-taken-a-turn-for-the-worst/#comments</comments>
		<pubDate>Thu, 07 May 2009 00:38:43 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Creative Engineering]]></category>

		<guid isPermaLink="false">http://www.pelagodesign.com/blog/2009/05/06/jesusita-fire-in-santa-barbara-has-taken-a-turn-for-the-worst/</guid>
		<description><![CDATA[The last two hours have seen the Jesusita fire take a turn for the worst due to hi temps, hi winds, and low humidity.  Our offices are two blocks from the evactuation warning zone and most of downtown Santa Barbara is now in the evacuation warning area.  Here is an updated Google map [...]]]></description>
			<content:encoded><![CDATA[<p>The last two hours have seen the Jesusita fire take a turn for the worst due to hi temps, hi winds, and low humidity.  Our offices are two blocks from the evactuation warning zone and most of downtown Santa Barbara is now in the evacuation warning area.  <a href="http://maps.google.com/maps/ms?ie=UTF8&#038;lr=lang_en&#038;hl=en&#038;msa=0&#038;ll=34.447689,-119.799042&#038;spn=0.06809,0.21904&#038;z=13&#038;msid=117142631812589675118.00046936902cc1ed7baa8">Here is an updated Google map with the evacuation zone</a>.</p>
<p><a href="http://twitpic.com/4orwa" target="_blank" title="Jesusista Fire Santa Barbara">Here is the view from our office</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pelagodesign.com/blog/2009/05/06/jesusita-fire-in-santa-barbara-has-taken-a-turn-for-the-worst/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Online recession trends</title>
		<link>http://www.pelagodesign.com/blog/2009/04/02/online-recession-trends/</link>
		<comments>http://www.pelagodesign.com/blog/2009/04/02/online-recession-trends/#comments</comments>
		<pubDate>Thu, 02 Apr 2009 19:53:38 +0000</pubDate>
		<dc:creator>Jaime</dc:creator>
				<category><![CDATA[Creative Engineering]]></category>

		<guid isPermaLink="false">http://www.pelagodesign.com/blog/?p=398</guid>
		<description><![CDATA[http://airbnb.com/ &#8211; &#8220;Rent nightly from real people in 809 cities in 71 countries.&#8221;
http://www.popcuts.com/ &#8211; &#8220;Every time a song you bought sells, you get a cut of the proceeds.&#8221;
http://bountii.com/ &#8211; &#8220;Find a lower price on any of the products below and we&#8217;ll pay you the Bountii.&#8221;
]]></description>
			<content:encoded><![CDATA[<p><a href="http://airbnb.com/">http://airbnb.com/</a> &#8211; &#8220;Rent nightly from real people in 809 cities in 71 countries.&#8221;</p>
<p><a href="http://www.popcuts.com/">http://www.popcuts.com/</a> &#8211; &#8220;Every time a song you bought sells, you get a cut of the proceeds.&#8221;</p>
<p><a href="http://bountii.com/">http://bountii.com/</a> &#8211; &#8220;Find a lower price on any of the products below and we&#8217;ll pay you the Bountii.&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pelagodesign.com/blog/2009/04/02/online-recession-trends/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Free IP address geolocation SQL database</title>
		<link>http://www.pelagodesign.com/blog/2009/03/25/free-ip-address-geolocation-sql-database/</link>
		<comments>http://www.pelagodesign.com/blog/2009/03/25/free-ip-address-geolocation-sql-database/#comments</comments>
		<pubDate>Wed, 25 Mar 2009 20:48:17 +0000</pubDate>
		<dc:creator>Jaime</dc:creator>
				<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://www.pelagodesign.com/blog/?p=396</guid>
		<description><![CDATA[People are discussing whether it&#8217;s a complete copy of maxmind&#8217;s free database, but some are saying it&#8217;s not, either way nothing beats free.
IP address geolocation SQL database
]]></description>
			<content:encoded><![CDATA[<p>People are <a href="http://news.ycombinator.com/item?id=530086">discussing</a> whether it&#8217;s a complete copy of <a href="http://www.maxmind.com/">maxmind&#8217;s</a> free database, but some are saying it&#8217;s not, either way nothing beats free.</p>
<p><a href="http://blogama.org/node/58">IP address geolocation SQL database</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.pelagodesign.com/blog/2009/03/25/free-ip-address-geolocation-sql-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
