<?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>I can has weblog? &#187; Computers</title>
	<atom:link href="http://justin-hopkins.com/blog/category/computers/feed" rel="self" type="application/rss+xml" />
	<link>http://justin-hopkins.com/blog</link>
	<description>The thoughts and works of Justin Hopkins.</description>
	<lastBuildDate>Wed, 23 Jun 2010 15:32:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>MySQL Shutdown Problem During Upgrade to Ubuntu 9.10 (Karmic Koala)</title>
		<link>http://justin-hopkins.com/blog/2009/11/02/mysql-shutdown-problem-during-upgrade-to-ubuntu-9-10-karmic-koala</link>
		<comments>http://justin-hopkins.com/blog/2009/11/02/mysql-shutdown-problem-during-upgrade-to-ubuntu-9-10-karmic-koala#comments</comments>
		<pubDate>Mon, 02 Nov 2009 15:49:14 +0000</pubDate>
		<dc:creator>Justin</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[How-To]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://justin-hopkins.com/blog/2009/11/02/mysql-shutdown-problem-during-upgrade-to-ubuntu-9-10-karmic-koala</guid>
		<description><![CDATA[Immediately following the download of new packages for the upgrade to Karmic Koala, I noticed it had hung up while attempting to turn off services which were going to be upgraded. mysql stopping... It happened that MySQL was the hold up, and because killing the upgrade process seemed like a risky operation &#8211; I needed [...]]]></description>
			<content:encoded><![CDATA[<p>Immediately following the download of new packages for the upgrade to Karmic Koala, I noticed it had hung up while attempting to turn off services which were going to be upgraded.</p>

<code>


<pre>
mysql stopping...
</pre>


</code>

<p>It happened that MySQL was the hold up, and because killing the upgrade process seemed like a risky operation &#8211; I needed to find a way to move it along.</p>

<p>I wasn&#8217;t able to turn up any other posts from the community about this issue &#8211; so I decided to take the usual approach: <strong>Start killing process with fingers crossed and blog the outcome!</strong></p>

<p>Just so happens I nailed it on the first try:<br />
<code>


<pre>
$ ps aux | grep mysql
&lt;snip /&gt;
root      3624  0.0  0.0   5452  1744 pts/7    S+   09:05   0:00 /usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf shutdown

$ sudo kill -9 3624 #your pid would be different...
</pre>


</code></p>

<p>The upgrader picked up and moved right along at that point. Hurray!</p>]]></content:encoded>
			<wfw:commentRss>http://justin-hopkins.com/blog/2009/11/02/mysql-shutdown-problem-during-upgrade-to-ubuntu-9-10-karmic-koala/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How To: Export and Import of .csv data out of and into MySQL</title>
		<link>http://justin-hopkins.com/blog/2009/08/04/how-to-export-and-import-of-csv-data-out-of-and-into-mysql</link>
		<comments>http://justin-hopkins.com/blog/2009/08/04/how-to-export-and-import-of-csv-data-out-of-and-into-mysql#comments</comments>
		<pubDate>Tue, 04 Aug 2009 17:08:09 +0000</pubDate>
		<dc:creator>Justin</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[How-To]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://justin-hopkins.com/blog/?p=197</guid>
		<description><![CDATA[I keep having to do this, and have just got tired of Googling every time for it. Here is the method I use for pulling a table out of MySQL then putting it back later. It may not work for versions of MySQL other than 5, but hey, it works for me. Why do this? [...]]]></description>
			<content:encoded><![CDATA[<p>I keep having to do this, and have just got tired of Googling every time for it. Here is the method I use for pulling a table out of MySQL then putting it back later. It may not work for versions of MySQL other than 5, but hey, it works for me. <strong>Why do this?</strong> Because it&#8217;s a great way to schlep off work to others who don&#8217;t know MySQL. Rather than having folks submit changes to me, I like to just dump it out to a .csv, have them open it in Excel, make their changes, re-save as .csv, then I can import it at my leisure. I sometimes like to throw flour on my face (like in the old rice crispies commercial) and come out of my cube saying &#8216;Whew, that took forever! Next time tell them it&#8217;s going to take a couple weeks&#8230;&#8217;</p>

<h3>Exporting the MySQL data into a comma delimited (.csv) file</h3>

<p><code>SELECT * INTO OUTFILE '/var/tmp/data.csv' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '&quot;' LINES TERMINATED BY '\n' FROM tblWhatever;</code></p>

<p>This will dump your table into a file with each row from the database being on it&#8217;s own line, columns separated by commas, and if there are any spaces or funny business going on with the data in a field, the data will be enclosed in double quotes. You can make changes to this if you like by, for instance, substituting &#8216;,&#8217; with &#8216;\t&#8217; would result in a tab delmited file.</p>

<p><strong>some things:</strong> The reason I put the file into /var/tmp is because you need to put the file in a place that MySQL can write to. Put it wherever you want though. Also, your system may not use /var/tmp but /tmp or who knows what else. If you are using shared hosting, and are working with sensitive data &#8211; don&#8217;t do anything dumb like export credit card numbers to /tmp and then leave them there ;)</p>

<h3>Importing the comma delimited (.csv) file back into MySQL</h3>

<p>First thing, you&#8217;ll need to clear out your old table (otherwise the keys would collide):</p>

<p><code>DELETE FROM tblWhatever;</code></p>

<p>Then you can proceed with the import:</p>

<p><code>LOAD DATA INFILE '/home/youruser/data.csv' INTO TABLE tblWhatever FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '&quot;' LINES TERMINATED BY '\n';</code></p>

<p><strong>some things:</strong> Naturally the file will need to be readable by MySQL, but it can be anywhere. Older versions of MySQL used &#8216;LOAD <span class="caps">DATA LOCAL INFILE&#8217; </span>but MySQL5 uses just &#8216;LOAD <span class="caps">DATA INFILE&#8217; </span>and only accepts local files (a pretty good thing). So yeah you&#8217;ll have to scp your file to and fro.</p>]]></content:encoded>
			<wfw:commentRss>http://justin-hopkins.com/blog/2009/08/04/how-to-export-and-import-of-csv-data-out-of-and-into-mysql/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to get a .csv of subscribers on all your Mailman lists</title>
		<link>http://justin-hopkins.com/blog/2009/05/16/how-to-get-a-csv-of-subscribers-on-all-your-mailman-lists</link>
		<comments>http://justin-hopkins.com/blog/2009/05/16/how-to-get-a-csv-of-subscribers-on-all-your-mailman-lists#comments</comments>
		<pubDate>Sat, 16 May 2009 17:16:33 +0000</pubDate>
		<dc:creator>Justin</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[How-To]]></category>
		<category><![CDATA[Mailman]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://justin-hopkins.com/blog/?p=185</guid>
		<description><![CDATA[The boss asked me to create a list of everyone subscribed to every discussion list we have. Ended up being like 3000 lines&#8230;luckly there is a python script that polls the mailman admin web interface. The below script makes it quite a bit easier to perform on all the lists. First thing, you need a [...]]]></description>
			<content:encoded><![CDATA[<p>The boss asked me to create a list of everyone subscribed to every discussion list we have. Ended up being like 3000 lines&#8230;luckly there is a python script that polls the mailman admin web interface. The below script makes it quite a bit easier to perform on all the lists.</p>

<p>First thing, you need a file with all of your list names &#8211; this works:</p>


<pre>
ls /usr/local/mailman/lists | cat &gt; lists.txt ## This is where mailman is located on FreeBSD
</pre>



<p>Next, download <a href="http://www.msapiro.net/mailman-subscribers.py" title="Mailman Subscribers Script">mailman-subscribers.py</a> to your home directory.</p>

<p>Finally, you need to create a shell script (i.e. getallsubscribers.sh) and paste the following (substitute the [[bracketed text]] with the info for your system):</p>


<pre>
while read line
do
 echo $line | cat &gt;&gt; listsAndMembers.csv
  ~/mailman-subscribers.py -c [[your.mailman.host]] $line [[listAdminPassword]] | cat &gt;&gt; listsAndMembers.csv
  echo | cat &gt;&gt; listsAndMembers.csv
  echo | cat &gt;&gt; listsAndMembers.csv
done &lt; lists.txt
</pre>



Now make the file executable and run it:<br />
</pre>

<pre>
chmod +x getallsubscribers.sh
./getallsubscribers.sh
</pre>



<p>That's it. You should have a single file with all of your lists and their subscribers.</p>

<p><strong>edit:</strong> It came up later that it would be nice to get a list of who from each domain was subscribed. This regex will turn up the listname and name/email for each subscriber in the .csv</p>


<pre>
(?:.*(?:gmail\.com)&quot;|^[^&quot;].*$)
</pre>]]></content:encoded>
			<wfw:commentRss>http://justin-hopkins.com/blog/2009/05/16/how-to-get-a-csv-of-subscribers-on-all-your-mailman-lists/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Friends, don&#8217;t give away your passwords!</title>
		<link>http://justin-hopkins.com/blog/2009/03/04/friends-dont-give-away-your-passwords</link>
		<comments>http://justin-hopkins.com/blog/2009/03/04/friends-dont-give-away-your-passwords#comments</comments>
		<pubDate>Thu, 05 Mar 2009 02:11:15 +0000</pubDate>
		<dc:creator>Justin</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[How-To]]></category>

		<guid isPermaLink="false">http://justin-hopkins.com/blog/2009/03/04/friends-dont-give-away-your-passwords</guid>
		<description><![CDATA[So, despite having logged into my blog just now without doing this &#8211; I&#8217;m going to share with you the easy way that probably 90% of you can protect your passwords while using the public wifi: Step 1: ssh -D 9999 -C somebox.youcan.sshto Step 2 Go get something like FoxyProxy for Firefox and MM3 for [...]]]></description>
			<content:encoded><![CDATA[<p>So, despite having logged into my blog just now without doing this &#8211; I&#8217;m going to share with you the easy way that probably 90% of you can protect your passwords while using the public wifi:</p>

<h3>Step 1:</h3>

<code>


<pre>
ssh -D 9999 -C somebox.youcan.sshto
</pre>


</code>

<h3>Step 2</h3>

<p>Go get something like FoxyProxy for Firefox and <span class="caps">MM3 </span>for Thunderbird (especially if you are using any version of Thunderbird 3 &#8211; nothing else is compatible). </p>

<p>For Firefox, set up a <span class="caps">SOCKS5 </span>proxy (Prefs &gt; Advanced &gt; Network &gt; Settings) on localhost port 9999. Start using the proxy. Stop using the proxy when you kill your ssh connection and make sure you open the connection if you are using the proxy.</p>

<p>For thunderbird it&#8217;s basically the same if you are using FoxyProxy &#8211; but if you are using <span class="caps">MM3 </span>like me, you need to create (click edit, oh btw you will probably have to add the button to the toolbar first) a proxy with this config:</p>

<code>


<pre>
[Arbitrary_name
  socks=127.0.0.1:9999
]
</pre>


</code>

<p>That&#8217;s it. Now I can&#8217;t steal your passwordsss! If you want to encrypt <span class="caps">DNS </span>requests you can set network.proxy.socks_remote_dns to true in about:config</p>]]></content:encoded>
			<wfw:commentRss>http://justin-hopkins.com/blog/2009/03/04/friends-dont-give-away-your-passwords/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How To: Convert mbox to mailman archives using procmail</title>
		<link>http://justin-hopkins.com/blog/2008/12/10/how-to-convert-mbox-to-mailman-archives-using-procmail</link>
		<comments>http://justin-hopkins.com/blog/2008/12/10/how-to-convert-mbox-to-mailman-archives-using-procmail#comments</comments>
		<pubDate>Wed, 10 Dec 2008 16:55:23 +0000</pubDate>
		<dc:creator>Justin</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[How-To]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://justin-hopkins.com/blog/?p=139</guid>
		<description><![CDATA[Update: NATURALLY, after doing all of this I learned that I was given the wrong information. Turns out Mailman is more than happy to take a huge mbox file as input for the arch script. I did learn that running clean_arch on the mbox first is a good idea&#8230; Are you like me? Do you [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update:</strong> <em><span class="caps">NATURALLY, </span>after doing all of this I learned that I was given the wrong information. Turns out Mailman is more than happy to take a huge mbox file as input for the arch script. I did learn that running clean_arch on the mbox first is a good idea&#8230;</em></p>

<p><a href="http://justin-hopkins.com/blog/wp-content/uploads/2008/12/mailman.jpg"><img src="http://justin-hopkins.com/blog/wp-content/uploads/2008/12/mailman-240x300.jpg" alt="mailman" title="mailman" width="240" height="300" class="alignright size-medium wp-image-138" /></a>
Are you like me? Do you get upset when you have to deal with an almost decade old problem that you had nothing to do with? Well then I&#8217;ve got a story for you&#8230;</p>

<h2>So we&#8217;ve got these archives&#8230;</h2>

<p>Our organization was using Lyris ListServ for about the past 10 years to handle all of our discussion list. Like most <acronym title="Mailing List Managers">MLM</acronym>&#8216;s, ListServ does have the ability to keep list archives&#8230;but naturally we opted to not use them for all of our lists. Big mistake.</p>

<p>Instead of list archives we have a user on our webserver called &#8216;archive&#8217;. Archive is subscribed to each and every list and gets copies of all the messages. When the messages come in, Archive processes them with a procmail script and separates them into mbox mailboxes for each of the lists.</p>

<p>Each of the mails are then piped to a program called mhonarc which converts them into html and provides an index, etc &#8211; which can be displayed on our current(old) website. But now we&#8217;ve got a new website coming up&#8230;</p>

<h2>Enter <span class="caps">GNU</span> Mailman</h2>

<p>Me:</p>

<blockquote><p>Thank you for coming Mailman. I&#8217;m really glad to have you because you do a really good job, not to mention you&#8217;re free and uber-powerful&#8230; One thing though&#8230; We&#8217;ve got these uh, <strong>gulp</strong> &#8220;archives&#8221;. We, uh, need to keep them and everything but you know, they&#8217;re like, not in the greatest shape. See, there actually in mbox format&#8230; </p></blockquote>

<p>Mailman:</p>

<blockquote><p>Oh yeah, that&#8217;s not a problem at all. I&#8217;ve got a built in script to to do that. Just take all of the monthly mailbox files for each of your lists and drop them in my folder &#8211; I&#8217;ll knock them out in no time!</p></blockquote>

<p>Me:</p>

<blockquote><p><span class="caps">SWEET</span>! But what did you say about monthly whatevers?</p></blockquote>

<p>Mailman:</p>

<blockquote><p>The mailbox files that you create every month for each list&#8230; You are using your procmail script to start a new mailbox file every month aren&#8217;t you? Putting 10 years worth of emails into a single monolithic file would be retarded&#8230;</p></blockquote>

<p>Me:</p>

<blockquote><p>Oh yeah yeah&#8230; Of course we did that. I thought you were talking about something else. Silly me. Anyway, so uh, yeah, I&#8217;ll get those file to you real soon.</p></blockquote>

<h2>Breaking up the monolith</h2>

<p>So clearly I needed to edit the procmail script a little bit and reprocess all the mail &#8211; but <span class="caps">WTH</span>? </p>

<p>Last month I had a help desk ticket come my way about a list which was not appearing on the website, and hadn&#8217;t been for a number of months. After digging around, I realized that someone (almost certainly me) had made a mistake in the .procmailrc file which had kept it from processing mail for that list. This was embarrasing, but I discovered <a href="http://www.professional.org/procmail/sandbox.html">how to reprocess mail with formail</a>.</p>

<p>I knew I could probably reprocess all of the mail (many thousands) but had absolutely no clue how to do it. I had only this one clue from my procmail recipe:</p>

<code>

<pre>
LOGFILE=$PMDIR/list_archive-`date +%Y-%m`.log
</pre>

</code>

<p>They had written it to rotate the logs, but not the mailbox names! Uncool! But at least I had my answer &#8211; `date +%Y-%m` can get the date into the names&#8230;But wait!</p>

<p>When I rewrote my procmail file like so:</p>

<code>

<pre>
#this is just one of many
:0 E
     * ^Sender:.*LIST-L
     {
       :0 c
       LIST-L.`date +%Y%m` #to match mailmans archive format...
     }
</pre>

</code>

<p><strong>Totally not working!</strong> It created only one file, and the date was this month and this year. </p>

<p>I&#8217;ll fast-forward for the benefit of the reader at this point and just share an insight with you: <strong>date is a *nix command and has nothing to do with procmail and cannot get any data out of the emails themselves &#8211; like dates!</strong> Yes that&#8217;s right, you can put anything you want in between those little ticks, but because the date command only returns the system date, we&#8217;ve got to do two things:</p>


<ol>
<li>Get the date the email was sent out of the email header (Magic)</li>
<li>Process the date field to have only the 4 digit year and 2 digit month (More Magic)</li>
</ol>



<p>It gets easier from here&#8230;</p>

<h2>Getting the date field</h2>

<p>The first thing we need to do is nab the Date: header from the emails. This part is fairly straight forward. Procmail uses a variable $MATCH to hold the matched string for the rule that it&#8217;s matching on. We can use this to hold our Date header and then just pipe it to a script for processing.</p>

<p>Here&#8217;s the <del>recipe</del> magic!</p>

<code>

<pre>
# NOTE: I later found that this rule only seems to work
# when used as an ELSE rule (:0 E). I'm not sure why, but
# it was only matching the 'Date:' portion, and not the entire
# line. If you can help me understand why, please leave a comment.
# ANOTHER NOTE: The ticks in `echo $MATCH.... are ticks(the
# un-shifted tilde) and not single quotes.

:0 E
     * ^Sender:.*LIST-L
     {
       :0 c
       * ^\/Date:.*
       LIST-L.`echo $MATCH | php /path/to/dateconvert.php`
     }
</pre>

</code>

<h2>Transforming the date into Mailman&#8217;s monthly format</h2>

<p>Here&#8217;s <del>the php code</del> more magic to get your date cut down and switched around to a format Mailman will love. It uses <del>php&#8217;s built in functions</del> fairy dust to put the Date header into an array, and drop the empty elements. It was also necessary to create an array that maps the three letter month names used in the email header to their numerical equivalents. </p>

<code>

<pre>
&lt; ?php
 $date = trim(fgets(STDIN));
 
 $datearray = array_values(array_filter(explode(&quot; &quot;, $date)));
 
 $month = $datearray[3];
 $year = $datearray[4];
 
 $montharray = array(
 &quot;Jan&quot; =&gt; &quot;01&quot;,
 &quot;Feb&quot; =&gt; &quot;02&quot;,
 &quot;Mar&quot; =&gt; &quot;03&quot;,
 &quot;Apr&quot; =&gt; &quot;04&quot;,
 &quot;May&quot; =&gt; &quot;05&quot;,
 &quot;Jun&quot; =&gt; &quot;06&quot;,
 &quot;Jul&quot; =&gt; &quot;07&quot;,
 &quot;Aug&quot; =&gt; &quot;08&quot;,
 &quot;Sep&quot; =&gt; &quot;09&quot;,
 &quot;Oct&quot; =&gt; &quot;10&quot;,
 &quot;Nov&quot; =&gt; &quot;11&quot;,
 &quot;Dec&quot; =&gt; &quot;12&quot;
 );
 
 echo $year . $montharray[$datearray[3]];
?&gt;
</pre>

</code>

<p>At this point you&#8217;re probably thinking one of two things:</p>


<ol>
<li>&#8220;ZOMG you&#8217;re such a hack. You could have done that with so much less code! You have no style!&#8221;</li>
<li>&#8220;ZOMG you can totally do that with a sed/awk one liner!&#8221;</li>
</ol>



<p>Sorry for wasting everyone&#8217;s time yet again. </p>

<p>After you&#8217;ve got the recipe in place and the php file all ready to go, just give it one of these:</p>

<code>

formail -s procmail -m /path/to/yourprocmailfile &lt; /path/to/LIST-L

</code>

<h3>Final product</h3>

<p>Anyway, you should, after a few hours or days end up with a grip of mailbox files like this:</p>

<p></code><code>

<pre>
               LIST-L.200306  LIST-L.200502  LIST-L.200701
 	        LIST-L.200307  LIST-L.200503  LIST-L.200702
LIST-L.200112  LIST-L.200308  LIST-L.200504  LIST-L.200703
LIST-L.200201  LIST-L.200309  LIST-L.200505  LIST-L.200704
LIST-L.200202  LIST-L.200310  LIST-L.200506  LIST-L.200705
LIST-L.200203  LIST-L.200311  LIST-L.200507  LIST-L.200707
LIST-L.200204  LIST-L.200312  LIST-L.200509  LIST-L.200708
LIST-L.200205  LIST-L.200401  LIST-L.200511  LIST-L.200709
LIST-L.200206  LIST-L.200402  LIST-L.200512  LIST-L.200710
LIST-L.200207  LIST-L.200403  LIST-L.200601  LIST-L.200711
LIST-L.200208  LIST-L.200404  LIST-L.200602  LIST-L.200712
LIST-L.200209  LIST-L.200405  LIST-L.200603  LIST-L.200801
LIST-L.200210  LIST-L.200406  LIST-L.200604  LIST-L.200802
LIST-L.200211  LIST-L.200407  LIST-L.200605  LIST-L.200803
LIST-L.200212  LIST-L.200408  LIST-L.200606  LIST-L.200804
LIST-L.200301  LIST-L.200409  LIST-L.200607  LIST-L.200805
LIST-L.200302  LIST-L.200410  LIST-L.200608  LIST-L.200806
LIST-L.200303  LIST-L.200411  LIST-L.200610  LIST-L.200807
LIST-L.200304  LIST-L.200412  LIST-L.200611
LIST-L.200305  LIST-L.200501  LIST-L.200612
</pre>

</code></p>

<p>So there ya go. Now make with the comments.</p>]]></content:encoded>
			<wfw:commentRss>http://justin-hopkins.com/blog/2008/12/10/how-to-convert-mbox-to-mailman-archives-using-procmail/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How To: Setting Up Drupal File Framework On Ubuntu 8.10</title>
		<link>http://justin-hopkins.com/blog/2008/12/02/how-to-setting-up-drupal-file-framework-on-ubuntu-810</link>
		<comments>http://justin-hopkins.com/blog/2008/12/02/how-to-setting-up-drupal-file-framework-on-ubuntu-810#comments</comments>
		<pubDate>Tue, 02 Dec 2008 21:00:02 +0000</pubDate>
		<dc:creator>Justin</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[How-To]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://justin-hopkins.com/blog/?p=101</guid>
		<description><![CDATA[This document is continually changing! One of the ways it gets changed is by people communicating with me using comments. In the future, I will host a wiki for this purpose &#8211; but for the time being please help me out by posting your suggested changes/improvements as comments! *2010/05/17: New users will want to read [...]]]></description>
			<content:encoded><![CDATA[<p><strong>This document is continually changing! One of the ways it gets changed is by people communicating with me using comments. In the future, I will host a wiki for this purpose &#8211; but for the time being please help me out by posting your suggested changes/improvements as comments!</strong></p>

<p>*2010/05/17: New users will want to read down through all of the comments, as this post has become out of date in quite a few ways. Especially have a look at <a href="http://justin-hopkins.com/blog/2008/12/02/how-to-setting-up-drupal-file-framework-on-ubuntu-810#comment-172">this comment from Wouter</a>.*</p>

<p><a href="http://justin-hopkins.com/blog/wp-content/uploads/2008/11/logo2.png"><img src="http://justin-hopkins.com/blog/wp-content/uploads/2008/11/logo2.png" alt="Drupal Logo" title="Drupal Logo" width="49" height="57" class="alignright size-full wp-image-111" /></a>
In my <a href="http://justin-hopkins.com/blog/2008/11/26/document-management-woes">previous post</a> I described the troubles I had with standalone document management softwares. Many of the issues I had were related to a lack of flexibility and lack of integration with my <span class="caps">CMS </span>of choice: Drupal.</p>

<p>At first glance(and even after looking quite hard), Drupal seems to be weak when it comes to document management. But just like any Drupal solution, a careful examination of the available modules might turn up <strong>the ingredients for the perfect recipe!</strong></p>

<p>In this article, I&#8217;m going to describe the steps required to get off the ground with a Drupal based document management solution that will provide:</p>


<ul>
<li>Organization of documents</li>
<li>Revision control</li>
<li>WebDav access</li>
<li>Rich metadata</li>
<li>Indexing for search</li>
<li>In-browser display of documents</li>
<li>Document conversion services</li>
<li>All the goodness you get from building it inside Drupal
<ul>
<li>Free authentication</li>
<li>Free administration interface</li>
<li>Integration with other Drupal modules (Views anyone?)</li>
<li>Awesome community of developers</li>
</ul>
</li>
</ul>



<h2>Getting started</h2>

<p>I&#8217;d recommend testing this out on a fresh install of Drupal6.6 &#8211; should you encounter difficulty, the number of modules on an established site could make troubleshooting a bit more difficult. After you&#8217;ve got it down, you can move on to your active development site.</p>

<p>Thanks to <a href="http://drupal.org/user/26089">Arto Bendiken</a>, <a href="http://drupal.org/user/18741">Miglius Alaburda</a>, <a href="http://drupal.org/user/51124">Justin Miller</a>, <a href="http://drupal.org/user/186547">Ben Lavender</a>, <a href="http://drupal.org/user/43670">Frank Febbraro</a>, and of course <a href="http://drupal.org/user/23">Moshe Weitzman</a>. </p>

<p>This article is based on <a href="http://bhuga.net/2008/07/setting-your-system-file-conversions-with-file-framework">Setting up your system for file conversions with File Framework</a>. Ben gives a very helpful and accurate rundown of what it takes to get going under CentOS. Since I was trying it out under Ubuntu, I thought I&#8217;d spend the time documenting my troubles &#8211; and include instructions to add some extra bells and whistles.</p>

<h2>System stuff</h2>

<p>First things first, lets go ahead and get all the packages we need:</p>

<code>


<pre>
sudo apt-get install php5 php5-dev php-pear make php-getid3 libmagic-dev clamav swftools unrtf poppler-utils catdoc ghostscript tzdata tzdata-java alsa-tools alsa-utils libx11-6 libxext6 libxi6 libxtst6 asoundconf-gtk libfreetype6 libpng12-0 libjpeg62 giflib-tools libsm6 openjdk-6-jdk openoffice.org openoffice.org-headless code2html pstotext
sudo pecl install Fileinfo
sudo pear install http://download.pear.php.net/package/HTTP_WebDAV_Server-1.0.0RC4.tgz
sudo pear install http://download.pear.php.net/package/HTTP_WebDAV_Client-1.0.0.tgz
</pre>


</code>

<p>If you have trouble with the install of the pear modules, probably the version has changed &#8211; you should visit the <a href="http://pear.php.net/packages.php?catpid=11&amp;catname=HTTP"><span class="caps">HTTP </span>packages page</a>.</p>

<h3><span class="caps">JODC</span>onverter</h3>

<p>We also need to get the <span class="caps">JOD</span> Converter. It&#8217;s a few .jar files that we&#8217;ll stick in a directory in /opt. <span class="caps">JODC</span>onverter is the piece that actually manages the conversion process through openoffice.</p>

<code>
cd /opt &amp;&amp; wget http://internap.dl.sourceforge.net/sourceforge/jodconverter/jodconverter-2.2.1.zip &amp;&amp; unzip jodconverter-2.2.1.zip &amp;&amp; mv jodconverter-2.2.1 jodconverter
</code>

<h3>Run OpenOffice as a service</h3>

<p>Long story short, use a version later than 2.3 to avoid problems running it &#8216;headless&#8217;. This is essential for the file conversion process.</p>

<p><em><strong>edit</strong></em>: I realized that the OpenOffice service really needs to be running as www-data, so using an init script like this one is really necessary.</p>

<code>

<pre>
#!/bin/bash
#
# description: Open Office Service
#

export WEBUSER=www-data
export PATH=$PATH
export LANG=en_US.UTF-8

start() {
echo -n &quot;Starting OpenOffice service: &quot;
sudo -u $WEBUSER /opt/openoffice.org3/program/soffice -headless -accept=&quot;socket,host=127.0.0.1,port=8100;urp&quot; -nofirststartwizard &amp; 
echo &quot;OpenOffice Started&quot;
}

stop() {
echo -n &quot;Stopping soffice: &quot;
pkill soffice
echo &quot;OpenOffice Stopped&quot;
}

case &quot;$1&quot; in
start)
start
;;
stop)
stop
;;
status)
status soffice
;;
restart|reload|condrestart)
stop
start
;;
*)
echo $&quot;Usage: $0 {start|stop|restart|reload|status}&quot;
exit 1
esac

exit 0
</pre>

</code>

<p>If you want OpenOffice3 like I&#8217;m using, you might want to remove the 2.4 packages with apt-get remove and go to openoffice.org and download the .deb packages. I installed by extracting the archive, cd&#8217;ing into the folder and using </p>

<pre>sudo dpkg -i *.deb</pre>

<p> and doing the same in the desktop integration folder. I can&#8217;t really <em>recommend</em> using OOo3 because the Ubuntu folks don&#8217;t have it in the repos&#8230;and the <span class="caps">GUI </span>is very crash happy.</p>

<h2>Drupal stuff</h2>

<h3>Clean <span class="caps">URL</span>s</h3>

<p>Pop over to <a href="http://drupal.org/node/134439">the Drupal.org page</a> describing how to set up clean urls if you don&#8217;t have that going already. Clean urls aren&#8217;t necessary, but due to a bug currently in bitcaching &#8211; <strong>it is</strong>.</p>

<h3>Install Drush</h3>

<p>If you aren&#8217;t using the <a href="http://drupal.org/project/drush">Drush module</a>, I <strong>highly</strong> recommend it. Although not related to or necessary for this project, since I discovered it <strong>one day ago</strong>, it&#8217;s become one of my favorite modules. It provides a familiar way to install and update your packages &#8211; and has a number of modules that extend it&#8217;s functionality.</p>


<ul>
<li>Install the Drush module by downloading the tarball to your modules directory (sites/all/modules) and extract it.</li>
<li>Go into your modules page in Drupal and enable the Drush and associated modules. You won&#8217;t be able to turn on the simpletest runner module, that&#8217;s fine. Also &#8211; I wasn&#8217;t able to use the <span class="caps">CVS </span>support, so I have that disabled as well.</li>
</ul>



<p>One last thing &#8211; you need to add a softlink to drush.php somewhere in your path. For me, I just echoed the path variable and picked the place that looked the best&#8230; Make sure you change any paths to whatever works.</p>

<code>

<pre>
% echo $PATH
/home/hopkinsju/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

% ln -s /var/www/drupal/sites/all/modules/drush/drush.php /home/hopkinsju/bin/drush
</pre>

</code>

<p>Now you should be able to type &#8216;drush&#8217; and the computer will know what you&#8217;re talking about.</p>

<h3>Add required modules with Drush</h3>

<p>Now we just do this to get all the modules we need:</p>

<code>
drush pm install bitcache cck dav fileframework rdf views fileserver #FTW!
</code>

<p>Drush will go out and grab the latest version of each module and extract it in your &#8216;sites/all/modules&#8217; directory. </p>

<p><strong><em>note: As of this writing bitcache-alpha3 had a bug in it. Using alpha3 will result in the error &#8220;Fatal error: Unsupported operand types in serverpath/includes/common.inc on line 1546&#8243;. To resolve this, you can use either the <a href="http://drupal.org/node/192590/release">alpha2 or dev versions</a> of the bitcache module</em></strong></p>

<h3>A few other bits</h3>

<p>The File Framework can get metadata for and play flash and mp3 files. You need only add a couple things to the vendor folder of fileframeworks:</p>

<p><strong><em>edit</em></strong>: Using the commands below should get you going without a problem, but I wanted to clarify: You <span class="caps">MUST </span>use the &#8216;slim&#8217; version of the xspf player. Also, the path to getid3 should be /vendor/getid3 &#8211; there should also be a directory /vendor/getid3/getid3 containing the different modules. </p>

<p><strong><em>update</em></strong>: new versions of getID3 and flowplayer as of Mar 18, 2009 &#8211; also you need to make folders for them&#8230;I&#8217;ll update the lines in a bit.<br />
<code>

<pre>
cd /path/to/drupal/sites/all/modules/fileframework/vendor
wget http://voxel.dl.sourceforge.net/sourceforge/getid3/getid3-1.7.9.zip
unzip getid3-1.7.9.zip

wget http://flowplayer.org/releases/flowplayer/flowplayer-3.0.7.zip
unzip flowplayer-3.0.7.zip

wget http://voxel.dl.sourceforge.net/sourceforge/musicplayer/xspf_player_slim-correct-0.2.3.zip
unzip xspf_player_slim-correct-0.2.3.zip
</pre>

</code></p>

<h3>Enable the modules</h3>

<p>Visit your modules page and enable the modules you need. When I first attempted this, I did run into an error where I had enabled one module or another without first enabling the modules it required(I think it was the <span class="caps">RDF API </span>module that needed to be enabled before the File formats). You&#8217;ll want to actually look at what you&#8217;re installing rather that just checking all the boxes of course. But basically &#8211; check all the boxes ;)</p>

<h3>Drupal admin area things</h3>


<ul>
<li>Visit admin/settings/dav/dav_fs and save the page to create the dav directory</li>
<li>Enable <span class="caps">DAV</span> Server in admin/settings/dav</li>
<li>If you want html highlighting for text files admin/settings/file/format/text</li>
<li>Enable antivirus scanning (I chose to run it as a program) admin/settings/file/antivirus</li>
<li>Enable file formats admin/settings/file/format</li>
<li>Go tell the Fileserver that you want it to use the &#8216;Files&#8217; vocab. Doing this will enable automatic creation of file nodes when items are added to that folder via WebDAV.</li>
</ul>



<p><strong>Please post your comments if you can improve on what I&#8217;ve done!</strong> </p>

<p>Happy document managing!</p>]]></content:encoded>
			<wfw:commentRss>http://justin-hopkins.com/blog/2008/12/02/how-to-setting-up-drupal-file-framework-on-ubuntu-810/feed</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>Well, Well, Well &#8211; WordPress 2.7</title>
		<link>http://justin-hopkins.com/blog/2008/11/24/well-well-well-wordpress-27</link>
		<comments>http://justin-hopkins.com/blog/2008/11/24/well-well-well-wordpress-27#comments</comments>
		<pubDate>Tue, 25 Nov 2008 04:59:27 +0000</pubDate>
		<dc:creator>Justin</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://justin-hopkins.com/blog/?p=57</guid>
		<description><![CDATA[WordPress 2.7-beta3-9863, as its name suggests&#8230;is a landmark update for WordPress. Dashboard at a glance Besides the new layout, there are other changes obvious in the first 5 minutes: A new &#8220;Quick Press&#8221; section &#8211; I-&#8217;m writing- started writing this post using it. Ajaxy accordion widgets replace the top-nav sections in the new sidebar menu. [...]]]></description>
			<content:encoded><![CDATA[<p>WordPress 2.7-beta3-9863, as its name suggests&#8230;is a landmark update for WordPress.</p>

<h2>Dashboard at a glance</h2>

<p><a href="http://justin-hopkins.com/blog/wp-content/uploads/2008/11/screenshot_02.png"><img src="http://justin-hopkins.com/blog/wp-content/uploads/2008/11/screenshot_02-300x132.png" alt="wp-admin dashboard" title="wp-admin dashboard" width="300" height="132" class="alignright size-medium wp-image-55" /></a></p>

<p>Besides the new layout, there are other changes obvious in the first 5 minutes:</p>


<ul>
<li>A new &#8220;Quick Press&#8221; section &#8211; I-&#8217;m writing- started writing this post using it.</li>
<li>Ajaxy accordion widgets replace the top-nav sections in the new sidebar menu.</li>
<li>Sidebar can be minimized a la photoshop toolbar &#8211; child items pop-out on hover.</li>
<li>Totally new(rockin&#8217;) icon set &#8211; <a href="http://wordpress.org/development/2008/11/the-results-of-project-icon/">apparently they had a contest</a> &#8211; grats &#8220;BD&#8221;</li>
<li>Did I mention the Ajax?? I don&#8217;t mean to be a web2.0 fanboy here &#8211; but honestly &#8211; UI design can make or break the experience&#8230;and unfortunately it&#8217;s more often breaking it. </li>
</ul>



<p>No sooner than I say I&#8217;m not a web2.0 fanboy as I mentally say &#8220;Ooooeee!&#8221; upon noticing that the boxes can be repositioned via drag-and-drop. That&#8217;s, like, web2.0 meme numero uno. </p>

<p><a href="http://justin-hopkins.com/blog/wp-content/uploads/2008/11/screenshot-2.png"><img src="http://justin-hopkins.com/blog/wp-content/uploads/2008/11/screenshot-2-300x187.png" alt="using the drag-and-drop widgets" title="using the drag-and-drop widgets" width="300" height="187" class="aligncenter size-medium wp-image-56" /></a></p>

<h2>Editing content</h2>

<p><strong>Viewing the list of my posts</strong> I noticed two things: An alternate view of posts that shows excerpts(just in case you don&#8217;t use the most descriptive titles), and the ability to &#8220;quick edit&#8221; the titles, categories, and a few other things about the post. Unfortunately you can&#8217;t edit the body of the post without clicking &#8216;edit&#8217;.</p>

<p><a href="http://justin-hopkins.com/blog/wp-content/uploads/2008/11/excerpt-with-quick-edit.png"><img src="http://justin-hopkins.com/blog/wp-content/uploads/2008/11/excerpt-with-quick-edit-1024x406.png" alt="excerpt-with-quick-edit" title="excerpt-with-quick-edit" width="662" height="262" class="aligncenter size-large wp-image-59" /></a></p>

<h2>Revisions</h2>

<p>This might have already been there &#8211; but revisions are great. At the bottom of the &#8220;Edit Post&#8221; page you get this:</p>

<p><a href="http://justin-hopkins.com/blog/wp-content/uploads/2008/11/post-revisions.png"><img src="http://justin-hopkins.com/blog/wp-content/uploads/2008/11/post-revisions-300x95.png" alt="post-revisions" title="post-revisions" width="300" height="95" class="aligncenter size-medium wp-image-70" /></a></p>

<p>Clicking one of the links takes you to a page showing the text of your post along with an array of radio buttons for all previous revisions and their restore links. Talk about handy.</p>

<h2>Overall</h2>

<p>I&#8217;m very very happy with the upgrade. I know WP updates don&#8217;t come with much fanfare &#8211; but this one was touted as having &#8220;major improvements&#8221;. I certainly think they came through.</p>

<p>There are some minor issues &#8211; browser related positioning errors and what-not &#8211; but I&#8217;d expect an official launch in the very near future.</p>

<h2>Want what I have?</h2>

<p>If you&#8217;d like to upgrade, you can just visit Tools&gt;Update and get the &#8220;Nightly build&#8221;&#8230;Or, if you&#8217;re like me, and prefer to handle your upgrades with Subversion(it&#8217;s easier to go downgrade, faster to do multiple blogs, and simpler to merge your customizations with upstream code) &#8211; then you&#8217;d just ssh into your blog directory and&#8230;</p>

<p>If you are already tracking trunk(then you probably already know this):</p>

<p><code>svn update</code></p>

<p>OR</p>

<p>If you are tracking the latest stable version, but want to try the new stuff:</p>

<p><code>svn sw http://svn.automattic.com/wordpress/trunk/ .</code></p>

<p>If you hate it and want to switch back:</p>

<p><code>svn sw http://svn.automattic.com/wordpress/tags/2.6.3/ .</code></p>

<p>OR</p>

<p>If you don&#8217;t have a WP blog yet and want to get started with the latest stuff or don&#8217;t have anything in your media gallery worth keeping(you could always back that up) &#8211; and haven&#8217;t made any customizations to WP themes(again, you could always back those up). Basically if you don&#8217;t yet have your WP blog under revisioning, and need to get started with svn:</p>

<p><code>svn co http://svn.automattic.com/wordpress/trunk/ .</code></p>

<p>Enjoy!</p>]]></content:encoded>
			<wfw:commentRss>http://justin-hopkins.com/blog/2008/11/24/well-well-well-wordpress-27/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Is this &quot;Less Fail&quot;? Why I&#8217;m Replacing Typo</title>
		<link>http://justin-hopkins.com/blog/2008/10/21/is-this-less-fail-why-im-replacing-typo</link>
		<comments>http://justin-hopkins.com/blog/2008/10/21/is-this-less-fail-why-im-replacing-typo#comments</comments>
		<pubDate>Tue, 21 Oct 2008 13:06:00 +0000</pubDate>
		<dc:creator>Justin</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Typo]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Typo is blog software written in Ruby, and available as a gem for Rails. It&#8217;s what is currently running this website. It&#8217; has it&#8217;s pluses but over time it&#8217;s grown aggravating to me. I&#8217;ve decided to move on to another platform, but I&#8217;m not sure which at this point. If by the time you are [...]]]></description>
			<content:encoded><![CDATA[<p>Typo is blog software written in Ruby, and available as a gem for Rails. It&#8217;s what is currently running this website. It&#8217; has it&#8217;s pluses but over time it&#8217;s grown aggravating to me. I&#8217;ve decided to move on to another platform, but I&#8217;m not sure which at this point.</p>


	<p>If by the time you are done reading this post you feel like Typo would be a good fit for you, you can <a href="http://typosphere.org">download Typo</a> and try it yourself. I&#8217;m by no means the expert in these matters, and what might not work for me might be right up your alley.</p>


	<h3>Why I picked Typo in the first place</h3>


	<p>When I was originally looking for a blog software to use I had these basic requirements:</p>


	<ul>
	<li>Not what everyone else was using(WordPress, Blogger)</li>
		<li>Not written in <span class="caps"><span class="caps">PHP</span></span></li>
	</ul>


	<p>I didn&#8217;t want to use what everyone else was using because in most things &#8211; I like to be different. The fact is that I <strong>am</strong> different from most people, and I tend to make that known.</p>


	<p>I wanted to use a product that was not written in <span class="caps"><span class="caps">PHP</span></span> because as an aspiring programmer, I&#8217;d rather be using a more cutting edge language like Ruby or Python. Not only is the code of Ruby/Python easier to write and the languages more interesting, but the jobs you get when you know them pay very much more than with <span class="caps"><span class="caps">PHP</span></span>, whose programmers are a dime a dozen. I&#8217;m not saying that it&#8217;s not worth knowing &#8211; indeed <span class="caps"><span class="caps">PHP</span></span> may be <strong>the most useful</strong> language to know due to it&#8217;s ubiquity. Also, I don&#8217;t want to offend any of the <span class="caps"><span class="caps">PHP</span></span> programmers who may be reading &#8211; I&#8217;m envious of your skills(read: skillz).</p>


	<p><strong>Ok, so why Typo?</strong> Well looking back I didn&#8217;t look into things all that well. I ended up turning all the negatives into positives which isn&#8217;t a very smart thing to do. At some point, mostly for very shallow reasons I decided that Ruby was a little cooler than Python, so having eliminated all of the Python blog software(there aren&#8217;t many) I had a very very short list to choose from. When I tried the demo of Typo I was fairly impressed by the admin interface. Also even though there were very few themes available, I really liked the one I have applied here(scribbish).</p>


	<h3>What I don&#8217;t like about Typo</h3>


	<h4>Lack of community</h4>


	<p>One thing about open-source software is that it <strong>really</strong> needs a large and active community. This is extremely evident when you start using projects like Drupal, Ubuntu, Eclipse, and so on. Typo is not like that at all. It&#8217;s basically just one person developing with a few other making commits. This really leads to nowhere fast.</p>


	<p>If you read the first blog post I wrote on this website you&#8217;ll see the difficulty I encountered just getting up and running. This was due almost entirely because of Typo development that wasn&#8217;t keeping pace with the development of it&#8217;s fundaments &#8211; Ruby/Rails. Even after working around the issues I was having, an entire section of my admin area is broken. Looking in the svn repo for Typo I&#8217;ve found that there is an experimental branch for Ruby 1.8.7, but it&#8217;s pretty clear that it&#8217;s not going to be finished before Ruby increments again.</p>


	<h4>Lack of features</h4>


	<p>Obviously since this is an open-source project, this is intimately tied to the lack of community &#8211; but there are things that should have been available at the outset. For example: users(myself included) cannot log into the public side of the website. This makes it very annoying for commenters &#8211; having to retype their info each time, and not being able to edit their comments &#8211; but also for <strong>me</strong> If I want to edit anything I have to do it from the admin side.</p>


	<p>Another feature missing that is somewhat related to front-side logging in is a feature that I first saw in <acronym title="although I&#8217;m sure others have it">WP</acronym> &#8211; private posts. The ability to make a post that only permitted users can see is essential for the entire concept of weblog. The idea that everything I publish should be public is ludicrous.</p>


	<p>Plug-ins. Again, because plug-ins are almost by definition community contributed I wouldn&#8217;t expect to see too many of them &#8211; but the number available is really pathetic. Less than 20 are available, and almost all are totally useless to 99.9% of people on the internet.</p>


	<p>This brings me to my next point:</p>


	<h4>Why I&#8217;m dumb</h4>


	<p>I managed to turn every one of the things I&#8217;ve identified as negative about Typo into a positive.</p>


	<p><strong>Q:</strong> Don&#8217;t you want to use a product with a huge community?
<strong>A:</strong> No, I want to be different!</p>


	<p><strong>Q:</strong> Don&#8217;t you want to have thousands of plug-ins available?
<strong>A:</strong> I&#8217;ll just write whatever I need!</p>


	<p><strong>Q:</strong> Don&#8217;t you want blogging to be easy?
<strong>A:</strong> &#8230;</p>


	<p>So yeah, now I realize that if you want to actually, say, <strong>write blogs</strong> then you have to have the time to do that. I want to learn Ruby &#8211; of course &#8211; but I want to write quick blogs about my accomplishments too. Starting a blog as a learning project means you have neither a blog or a project &#8211; just a bunch of stagnation. In my case I opted to write blog after blog and never have the features I wanted, feeling pissed off all the while. not good.</p>


	<h3>So, what to use now?</h3>


	<p>Honestly I&#8217;m leaning towards WordPress. It&#8217;s the obvious choice for obvious reasons, but until I have a couple hours to look again at all of the(free, open-source) options &#8211; I can&#8217;t make a final decision.</p>


	<p>I&#8217;d still like to look at Ruby/Python blog softwares, and this time not because I want a pet project. I&#8217;ll look at performance issues &#8211; I know that Ruby, but especially Python will outperform <span class="caps"><span class="caps">PHP</span></span>, but after caching is taken into account the difference may be negligible.</p>


	<p>I don&#8217;t think WordPress is inherently insecure &#8211; as some assert it is due to it&#8217;s open-source nature(unlike windoze, which is SO secure!), but it might be vulnerable due to it&#8217;s high usage and therefore high rate of attack(just like windoze!). But that&#8217;s all anecdotal &#8211; I don&#8217;t know security in general much less the minute details of the WP code.</p>


	<p><a href="http://mephistoblog.com/">Mephisto</a> is another Ruby blog, but it looks like it suffers from the same problems as does Typo. I&#8217;d love to do either one of these if I could get paid to work on them.</p>


	<p>Anyway&#8230;I&#8217;ll just keep looking around for now. Post a comment if you want to make a suggestion! (Sorry it won&#8217;t remember your user info and I won&#8217;t be notified of new comments)</p>]]></content:encoded>
			<wfw:commentRss>http://justin-hopkins.com/blog/2008/10/21/is-this-less-fail-why-im-replacing-typo/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Henry&#8217;s Widgets: A Practice in XML/XSLT</title>
		<link>http://justin-hopkins.com/blog/2008/10/19/henrys-widgets-a-practice-in-xmlxslt</link>
		<comments>http://justin-hopkins.com/blog/2008/10/19/henrys-widgets-a-practice-in-xmlxslt#comments</comments>
		<pubDate>Mon, 20 Oct 2008 03:43:00 +0000</pubDate>
		<dc:creator>Justin</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Since attending HighEdWeb 2008 and going to Jason Woodward&#8217;s Workshop on XML/XSLT, I&#8217;ve been really interested in the possibilities of using XSL to tranform a well-formed XML file into almost anything&#8195;&#8211; especially another type of file, such as XHTML. This topic is totally new to me, and I&#8217;ve never had the chance to use it [...]]]></description>
			<content:encoded><![CDATA[<p>Since attending <a href="http://www.highedweb.org/2008">HighEdWeb 2008</a> and going to <a href="http://www.highedweb.org/2008/EventDetail.aspx?guid=dadead53-6e9f-4fe3-98bc-43cd6e253912">Jason Woodward&#8217;s Workshop</a> on <span class="caps"><span class="caps">XML</span></span>/XSLT, I&#8217;ve been really interested in the possibilities of using <span class="caps"><span class="caps">XSL</span></span> to tranform a well-formed <span class="caps"><span class="caps">XML</span></span> file into almost anything&#8195;&#8211; especially another type of file, such as <span class="caps"><span class="caps">XHTML</span></span>.</p>


	<p>This topic is totally new to me, and I&#8217;ve never had the chance to use it in a real life scenario. I have played around a little bit with a hypothetical exercise though, and wanted to post my solution for others to use, and hopefully, offer some criticism on. Please do comment if you can think of a better or more elegant solution.</p>


	<h2>The business need</h2>


	<p>Develop a single web page that shows Henry&#8217;s current inventory.&#8195;Develop a single page using <span class="caps"><span class="caps">XHTML</span></span> standards that shows the inventory using <span class="caps"><span class="caps">XSL</span></span>. <span class="caps">CSS </span>will be in the head of the <span class="caps"><span class="caps">XSL</span></span> page and will be used to style the page. The page will show the widgets grouped by the type of metal in alphabetical order, and then the widgets in order of price with the lowest price item shown first (the list of widgets is only shown once in the page). Lastly, the out of stock widgets should be formatted differently than the ones that are in stock. Tables will be used to layout the web page.</p>


	<h2>The <span class="caps"><span class="caps">XML</span></span></h2>


	<p>I developed this <span class="caps"><span class="caps">XML</span></span> a few weeks ago, and even wrote <a href="http://justin-hopkins.com/2008/10/12/my-first-xml-schema">another post</a> patting myself on the back for having authored a schema defining my widgets, but here is a snippet:</p>




<pre><code>
&lt; ?xml-stylesheet type=&quot;text/xsl&quot; href=&quot;inventory.xsl&quot;?&gt;
&lt;inventory xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; 
  xsi:noNamespaceSchemaLocation=&quot;inventory.xsd&quot;&gt;
  &lt;widget&gt;
    &lt;material&gt;Aluminium&lt;/material&gt;
    &lt;length units=&quot;ft&quot;&gt;1&lt;/length&gt;
    &lt;width units=&quot;in&quot;&gt;2&lt;/width&gt;
    &lt;thickness units=&quot;in&quot;&gt;.25&lt;/thickness&gt;
    &lt;price units=&quot;USD&quot;&gt;15.00&lt;/price&gt;
    &lt;stockqty&gt;25&lt;/stockqty&gt;
  &lt;/widget&gt;
...
&lt;/inventory&gt;
</code></pre>



	<h2>The good stuff &#8211; <span class="caps"><span class="caps">XSLT</span></span></h2>


	<p>I think learning <span class="caps"><span class="caps">XSLT</span></span> was equal parts learning to understand <span class="caps"><span class="caps">XSL</span></span> and then learning the intricacies of Xpath &#8211; especially as it relates to &lt;xsl:apply-templates /&gt; and matching/selecting the elements. Anyway here&#8217;s what I came up with:</p>




<pre><code>
&lt;xsl :stylesheet xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot; version=&quot;1.0&quot;&gt;
  &lt;/xsl&gt;&lt;xsl :template match=&quot;/&quot;&gt;
    &lt;html&gt;
      &lt;head&gt;
        &lt;title&gt;Henry's Widget Shoppe&lt;/title&gt;
        <style type="text/css"> #Inventory { border-collapse:collapse; } #Inventory td { border:1px
          solid #594E7A; padding: .1em 1em; } #Inventory .tableHead { background:#98D3D4;
          color:#302B26; font-weight:bold; } tr.widget td { text-align:center; } tr.widget td.price
          { color:#FF530D; } .outOfStock, tr.outOfStock td.price{ background:#aaa; color: #333; }
        </style>
      &lt;/head&gt;
      &lt;body&gt;
        &lt;h2&gt;Here's my available widgets!&lt;/h2&gt;
        &lt;table id=&quot;Inventory&quot;&gt;
          &lt;tr class=&quot;tableHead&quot;&gt;
            &lt;td&gt;Material Type&lt;/td&gt;
            &lt;td&gt;Length&lt;/td&gt;
            &lt;td&gt;Width&lt;/td&gt;
            &lt;td&gt;Thickness&lt;/td&gt;
            &lt;td&gt;Price&lt;/td&gt;
            &lt;td&gt;Stock Qty&lt;/td&gt;
          &lt;/tr&gt;
          &lt;xsl :apply-templates /&gt;
        &lt;/table&gt;
      &lt;/body&gt;
    &lt;/html&gt;
    &lt;/xsl&gt;

    &lt;xsl :template match=&quot;inventory&quot;&gt;
      &lt;/xsl&gt;&lt;xsl :for-each select=&quot;widget&quot;&gt;
        &lt;xsl :sort select=&quot;material&quot; order=&quot;ascending&quot;/&gt;
        &lt;xsl :sort select=&quot;price&quot; data-type=&quot;number&quot; order=&quot;ascending&quot;/&gt;
        &lt;/xsl&gt;&lt;xsl :choose&gt;
          &lt;/xsl&gt;&lt;xsl :when test=&quot;stockQty&gt;0&quot;&gt;
            &lt;tr class=&quot;widget&quot;&gt;
              &lt;xsl :apply-templates select=&quot;.&quot; /&gt;
            &lt;/tr&gt;
          &lt;/xsl&gt;
          &lt;xsl :otherwise&gt;
            &lt;tr class=&quot;widget outOfStock&quot;&gt;
              &lt;xsl :apply-templates select=&quot;.&quot; /&gt;
            &lt;/tr&gt;
          &lt;/xsl&gt;
          
                    
    

    &lt;xsl :template match=&quot;widget&quot;&gt;
            &lt;td class=&quot;material&quot;&gt;
              &lt;xsl :value-of select=&quot;material&quot;/&gt;
            &lt;/td&gt;
            &lt;td class=&quot;length&quot;&gt;
              &lt;xsl :value-of select=&quot;length&quot;/&gt;
              &lt;xsl :value-of select=&quot;length/@units&quot;/&gt;
            &lt;/td&gt;
            &lt;td class=&quot;width&quot;&gt;
              &lt;xsl :value-of select=&quot;width&quot;/&gt;
              &lt;xsl :value-of select=&quot;width/@units&quot;/&gt;
            &lt;/td&gt;
            &lt;td class=&quot;thickness&quot;&gt;
              &lt;xsl :value-of select=&quot;thickness&quot;/&gt;
              &lt;xsl :value-of select=&quot;thickness/@units&quot;/&gt;
            &lt;/td&gt;
            &lt;td class=&quot;price&quot;&gt;
              &lt;xsl :if test=&quot;price[@units] != 'USD'&quot;&gt;$&lt;/xsl&gt;
              &lt;xsl :value-of select=&quot;price&quot;/&gt;
            &lt;/td&gt;
            &lt;td class=&quot;stockQty&quot;&gt;
              &lt;xsl :value-of select=&quot;stockQty&quot;/&gt;
            &lt;/td&gt;
    &lt;/xsl&gt;


</code></pre>



	<h2>Conclusion</h2>


	<p>I did make several improvements and tried alternate strategies over the weekend, so this isn&#8217;t exactly what I first puked out. All in all, I&#8217;m very pleased with it. This was probably one of the most valuable self learning exercises I&#8217;ve yet had.</p>


	<p><a href="http://justin-hopkins.com/files/inventory/inventory101908.zip">Download the source here</a>
and/or <a href="http://justin-hopkins.com/files/inventory/inventory.xml">View the transformed <span class="caps"><span class="caps">XML</span></span> here</a></p>]]></content:encoded>
			<wfw:commentRss>http://justin-hopkins.com/blog/2008/10/19/henrys-widgets-a-practice-in-xmlxslt/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Thunderbird + FireTray FTW!</title>
		<link>http://justin-hopkins.com/blog/2008/10/12/thunderbird-firetray-ftw</link>
		<comments>http://justin-hopkins.com/blog/2008/10/12/thunderbird-firetray-ftw#comments</comments>
		<pubDate>Mon, 13 Oct 2008 03:17:00 +0000</pubDate>
		<dc:creator>Justin</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Who doesn&#8217;t love Firefox? Probably only this guy. But what about it&#8217;s cousin, Thunderbird? Thunderbird Thunderbird has always been a program I wanted to embrace, with only 1 real problem: NO MINIMIZE TO TRAY! For what it&#8217;s worth, if you&#8217;re using Windoze, you can download Minimize to Tray. The lack of a Linux version of [...]]]></description>
			<content:encoded><![CDATA[<p>Who doesn&#8217;t love Firefox? Probably only <a href="http://current.com/items/88938603_world_record_for_most_popped_collars">this guy</a>. But what about it&#8217;s cousin, Thunderbird?</p>


	<h4>Thunderbird</h4>


	<p>Thunderbird has always been a program I wanted to embrace, with only 1 real problem: <span class="caps">NO <span class="caps">MINIMIZE</span> TO <span class="caps">TRAY</span></span>! For what it&#8217;s worth, if you&#8217;re using Windoze, you can download <a href="https://addons.mozilla.org/en-US/thunderbird/addon/2110">Minimize to Tray</a>. The lack of a Linux version of Minimize to Tray has long kept me from using it. It sounds really stupid I know, and it IS stupid. Thank goodness that doesn&#8217;t matter anymore!</p>


	<h4>FireTray</h4>


	<p>That&#8217;s right folks. As the name might imply, <a href="https://addons.mozilla.org/en-US/firefox/addon/4868">FireTray</a> is a Firefox extension. I saw no mention of it&#8217;s compatitbility with Thunderbird &#8211; but out of desperation I decided to try to install it. Lo and behold, it worked.</p>


	<p>It&#8217;s the usual install process. Find the extension, but instead of clicking the Install button, right click and choose &#8220;Save link as&#8221; then save the .xpi to your desktop. In Thunderbird, go to Tools &gt; Add-ons, then click Install and browse to your .xpi file. Thunderbird will not give you the option to restart(I don&#8217;t think) but you will have to restart Thunderbird to get the tray icon. You can adjust the preferences for the extension &#8211; I recommend checking all three boxes for super tray goodness.</p>


	<p>FireTray should keep Thunderbird running in the tray(duh), notify you of new mails, and still provide you with a mail client that is 1 million times better than Evolution. HA!</p>]]></content:encoded>
			<wfw:commentRss>http://justin-hopkins.com/blog/2008/10/12/thunderbird-firetray-ftw/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My first XML Schema</title>
		<link>http://justin-hopkins.com/blog/2008/10/11/my-first-xml-schema</link>
		<comments>http://justin-hopkins.com/blog/2008/10/11/my-first-xml-schema#comments</comments>
		<pubDate>Sun, 12 Oct 2008 04:28:00 +0000</pubDate>
		<dc:creator>Justin</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Having only been really introduced to XML a week ago, I&#8217;m proud to announce my first go at authoring an XML Schema. I can&#8217;t say it was really fun, but it was very interesting to be sure. I think XML in general is neat, but creating a schema really gave new insights into how XML [...]]]></description>
			<content:encoded><![CDATA[<p>Having only been really introduced to <span class="caps"><span class="caps">XML</span></span> a week ago, I&#8217;m proud to announce my first go at authoring an <a href="http://www.w3.org/TR/xmlschema-0/"><span class="caps"><span class="caps">XML</span></span> Schema</a>. I can&#8217;t say it was really fun, but it was very interesting to be sure. I think <span class="caps"><span class="caps">XML</span></span> in general is neat, but creating a schema really gave new insights into how <span class="caps"><span class="caps">XML</span></span> files can and should be designed.</p>


	<p><strong>Please, if you can propose improvements &#8211; leave me a comment!</strong></p>


	<h4>The sample <span class="caps"><span class="caps">XML</span></span> file</h4>




<pre><code>
&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt; 
&amp;lt;inventory
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; 
    xsi:noNamespaceSchemaLocation=&quot;inventory.xsd&quot;&amp;gt;
    &amp;lt;widget&amp;gt;
        &amp;lt;material&amp;gt;Aluminium&amp;lt;/material&amp;gt;
        &amp;lt;length units=&quot;ft&quot;&amp;gt;1&amp;lt;/length&amp;gt;
        &amp;lt;width units=&quot;in&quot;&amp;gt;2&amp;lt;/width&amp;gt;
        &amp;lt;thickness units=&quot;in&quot;&amp;gt;.25&amp;lt;/thickness&amp;gt;
        &amp;lt;price units=&quot;USD&quot;&amp;gt;5.00&amp;lt;/price&amp;gt;
        &amp;lt;stockQty&amp;gt;25&amp;lt;/stockQty&amp;gt;
    &amp;lt;/widget&amp;gt;
    &amp;lt;widget&amp;gt;
        &amp;lt;material&amp;gt;Aluminium&amp;lt;/material&amp;gt;
        &amp;lt;length units=&quot;ft&quot;&amp;gt;1&amp;lt;/length&amp;gt;
        &amp;lt;width units=&quot;in&quot;&amp;gt;2&amp;lt;/width&amp;gt;
        &amp;lt;thickness units=&quot;in&quot;&amp;gt;.5&amp;lt;/thickness&amp;gt;
        &amp;lt;price units=&quot;USD&quot;&amp;gt;10.00&amp;lt;/price&amp;gt;
        &amp;lt;stockQty&amp;gt;15&amp;lt;/stockQty&amp;gt;
    &amp;lt;/widget&amp;gt;
    &amp;lt;widget&amp;gt;
        &amp;lt;material&amp;gt;Aluminium&amp;lt;/material&amp;gt;
        &amp;lt;length units=&quot;ft&quot;&amp;gt;1&amp;lt;/length&amp;gt;
        &amp;lt;width units=&quot;in&quot;&amp;gt;4&amp;lt;/width&amp;gt;
        &amp;lt;thickness units=&quot;in&quot;&amp;gt;.25&amp;lt;/thickness&amp;gt;
        &amp;lt;price units=&quot;USD&quot;&amp;gt;12.50&amp;lt;/price&amp;gt;
        &amp;lt;stockQty&amp;gt;16&amp;lt;/stockQty&amp;gt;
    &amp;lt;/widget&amp;gt;
    &amp;lt;widget&amp;gt;
        &amp;lt;material&amp;gt;Aluminium&amp;lt;/material&amp;gt;
        &amp;lt;length units=&quot;ft&quot;&amp;gt;1&amp;lt;/length&amp;gt;
        &amp;lt;width units=&quot;in&quot;&amp;gt;4&amp;lt;/width&amp;gt;
        &amp;lt;thickness units=&quot;in&quot;&amp;gt;.5&amp;lt;/thickness&amp;gt;
        &amp;lt;price units=&quot;USD&quot;&amp;gt;15.00&amp;lt;/price&amp;gt;
        &amp;lt;stockQty&amp;gt;8&amp;lt;/stockQty&amp;gt;
    &amp;lt;/widget&amp;gt;
    &amp;lt;widget&amp;gt;
        &amp;lt;material&amp;gt;Aluminium&amp;lt;/material&amp;gt;
        &amp;lt;length units=&quot;ft&quot;&amp;gt;10&amp;lt;/length&amp;gt;
        &amp;lt;width units=&quot;in&quot;&amp;gt;2&amp;lt;/width&amp;gt;
        &amp;lt;thickness units=&quot;in&quot;&amp;gt;.25&amp;lt;/thickness&amp;gt;
        &amp;lt;price units=&quot;USD&quot;&amp;gt;15.00&amp;lt;/price&amp;gt;
        &amp;lt;stockQty&amp;gt;25&amp;lt;/stockQty&amp;gt;
    &amp;lt;/widget&amp;gt;
    &amp;lt;widget&amp;gt;
        &amp;lt;material&amp;gt;Aluminium&amp;lt;/material&amp;gt;
        &amp;lt;length units=&quot;ft&quot;&amp;gt;10&amp;lt;/length&amp;gt;
        &amp;lt;width units=&quot;in&quot;&amp;gt;2&amp;lt;/width&amp;gt;
        &amp;lt;thickness units=&quot;in&quot;&amp;gt;.5&amp;lt;/thickness&amp;gt;
        &amp;lt;price units=&quot;USD&quot;&amp;gt;30.00&amp;lt;/price&amp;gt;
        &amp;lt;stockQty&amp;gt;13&amp;lt;/stockQty&amp;gt;
    &amp;lt;/widget&amp;gt;
    &amp;lt;widget&amp;gt;
        &amp;lt;material&amp;gt;Aluminium&amp;lt;/material&amp;gt;
        &amp;lt;length units=&quot;ft&quot;&amp;gt;10&amp;lt;/length&amp;gt;
        &amp;lt;width units=&quot;in&quot;&amp;gt;4&amp;lt;/width&amp;gt;
        &amp;lt;thickness units=&quot;in&quot;&amp;gt;.25&amp;lt;/thickness&amp;gt;
        &amp;lt;price units=&quot;USD&quot;&amp;gt;35.00&amp;lt;/price&amp;gt;
        &amp;lt;stockQty&amp;gt;11&amp;lt;/stockQty&amp;gt;
    &amp;lt;/widget&amp;gt;
    &amp;lt;widget&amp;gt;
        &amp;lt;material&amp;gt;Aluminium&amp;lt;/material&amp;gt;
        &amp;lt;length units=&quot;ft&quot;&amp;gt;10&amp;lt;/length&amp;gt;
        &amp;lt;width units=&quot;in&quot;&amp;gt;4&amp;lt;/width&amp;gt;
        &amp;lt;thickness units=&quot;in&quot;&amp;gt;.5&amp;lt;/thickness&amp;gt;
        &amp;lt;price units=&quot;USD&quot;&amp;gt;40.00&amp;lt;/price&amp;gt;
        &amp;lt;stockQty&amp;gt;4&amp;lt;/stockQty&amp;gt;
    &amp;lt;/widget&amp;gt;
    &amp;lt;widget&amp;gt;
        &amp;lt;material&amp;gt;Copper&amp;lt;/material&amp;gt;
        &amp;lt;length units=&quot;ft&quot;&amp;gt;1&amp;lt;/length&amp;gt;
        &amp;lt;width units=&quot;in&quot;&amp;gt;2&amp;lt;/width&amp;gt;
        &amp;lt;thickness units=&quot;in&quot;&amp;gt;.25&amp;lt;/thickness&amp;gt;
        &amp;lt;price units=&quot;USD&quot;&amp;gt;5.50&amp;lt;/price&amp;gt;
        &amp;lt;stockQty&amp;gt;19&amp;lt;/stockQty&amp;gt;
    &amp;lt;/widget&amp;gt;
    &amp;lt;widget&amp;gt;
        &amp;lt;material&amp;gt;Copper&amp;lt;/material&amp;gt;
        &amp;lt;length units=&quot;ft&quot;&amp;gt;1&amp;lt;/length&amp;gt;
        &amp;lt;width units=&quot;in&quot;&amp;gt;2&amp;lt;/width&amp;gt;
        &amp;lt;thickness units=&quot;in&quot;&amp;gt;.5&amp;lt;/thickness&amp;gt;
        &amp;lt;price units=&quot;USD&quot;&amp;gt;11.00&amp;lt;/price&amp;gt;
        &amp;lt;stockQty&amp;gt;17&amp;lt;/stockQty&amp;gt;
    &amp;lt;/widget&amp;gt;
    &amp;lt;widget&amp;gt;
        &amp;lt;material&amp;gt;Copper&amp;lt;/material&amp;gt;
        &amp;lt;length units=&quot;ft&quot;&amp;gt;1&amp;lt;/length&amp;gt;
        &amp;lt;width units=&quot;in&quot;&amp;gt;4&amp;lt;/width&amp;gt;
        &amp;lt;thickness units=&quot;in&quot;&amp;gt;.25&amp;lt;/thickness&amp;gt;
        &amp;lt;price units=&quot;USD&quot;&amp;gt;15.00&amp;lt;/price&amp;gt;
        &amp;lt;stockQty&amp;gt;3&amp;lt;/stockQty&amp;gt;
    &amp;lt;/widget&amp;gt;
    &amp;lt;widget&amp;gt;
        &amp;lt;material&amp;gt;Copper&amp;lt;/material&amp;gt;
        &amp;lt;length units=&quot;ft&quot;&amp;gt;1&amp;lt;/length&amp;gt;
        &amp;lt;width units=&quot;in&quot;&amp;gt;4&amp;lt;/width&amp;gt;
        &amp;lt;thickness units=&quot;in&quot;&amp;gt;.5&amp;lt;/thickness&amp;gt;
        &amp;lt;price units=&quot;USD&quot;&amp;gt;16.50&amp;lt;/price&amp;gt;
        &amp;lt;stockQty&amp;gt;8&amp;lt;/stockQty&amp;gt;
    &amp;lt;/widget&amp;gt;
    &amp;lt;widget&amp;gt;
        &amp;lt;material&amp;gt;Copper&amp;lt;/material&amp;gt;
        &amp;lt;length units=&quot;ft&quot;&amp;gt;10&amp;lt;/length&amp;gt;
        &amp;lt;width units=&quot;in&quot;&amp;gt;2&amp;lt;/width&amp;gt;
        &amp;lt;thickness units=&quot;in&quot;&amp;gt;.25&amp;lt;/thickness&amp;gt;
        &amp;lt;price units=&quot;USD&quot;&amp;gt;16.00&amp;lt;/price&amp;gt;
        &amp;lt;stockQty&amp;gt;21&amp;lt;/stockQty&amp;gt;
    &amp;lt;/widget&amp;gt;
    &amp;lt;widget&amp;gt;
        &amp;lt;material&amp;gt;Copper&amp;lt;/material&amp;gt;
        &amp;lt;length units=&quot;ft&quot;&amp;gt;10&amp;lt;/length&amp;gt;
        &amp;lt;width units=&quot;in&quot;&amp;gt;2&amp;lt;/width&amp;gt;
        &amp;lt;thickness units=&quot;in&quot;&amp;gt;.5&amp;lt;/thickness&amp;gt;
        &amp;lt;price units=&quot;USD&quot;&amp;gt;30.00&amp;lt;/price&amp;gt;
        &amp;lt;stockQty&amp;gt;13&amp;lt;/stockQty&amp;gt;
    &amp;lt;/widget&amp;gt;
    &amp;lt;widget&amp;gt;
        &amp;lt;material&amp;gt;Copper&amp;lt;/material&amp;gt;
        &amp;lt;length units=&quot;ft&quot;&amp;gt;10&amp;lt;/length&amp;gt;
        &amp;lt;width units=&quot;in&quot;&amp;gt;4&amp;lt;/width&amp;gt;
        &amp;lt;thickness units=&quot;in&quot;&amp;gt;.25&amp;lt;/thickness&amp;gt;
        &amp;lt;price units=&quot;USD&quot;&amp;gt;35.00&amp;lt;/price&amp;gt;
        &amp;lt;stockQty&amp;gt;18&amp;lt;/stockQty&amp;gt;
    &amp;lt;/widget&amp;gt;
    &amp;lt;widget&amp;gt;
        &amp;lt;material&amp;gt;Copper&amp;lt;/material&amp;gt;
        &amp;lt;length units=&quot;ft&quot;&amp;gt;10&amp;lt;/length&amp;gt;
        &amp;lt;width units=&quot;in&quot;&amp;gt;4&amp;lt;/width&amp;gt;
        &amp;lt;thickness units=&quot;in&quot;&amp;gt;.5&amp;lt;/thickness&amp;gt;
        &amp;lt;price units=&quot;USD&quot;&amp;gt;44.00&amp;lt;/price&amp;gt;
        &amp;lt;stockQty&amp;gt;2&amp;lt;/stockQty&amp;gt;
    &amp;lt;/widget&amp;gt;
&amp;lt;/inventory&amp;gt;
</code>
</pre>



	<h4>The Schema</h4>




<pre><code>
&amp;lt;xsd:schema xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;&amp;gt;
    &amp;lt;xsd:annotation&amp;gt;
        &amp;lt;xsd:documentation xml:lang=&quot;en&quot;&amp;gt;
            Widget Schema for Henry's Widgets.
            Copyright 2008 Henry's Widgets Inc.
        &amp;lt;/xsd:documentation&amp;gt;
    &amp;lt;/xsd:annotation&amp;gt;

    &amp;lt;xsd:element name=&quot;inventory&quot; type=&quot;inventoryType&quot;/&amp;gt; 

    &amp;lt;xsd:complexType name=&quot;inventoryType&quot;&amp;gt;
      &amp;lt;xsd:annotation&amp;gt;
        &amp;lt;xsd:documentation&amp;gt;
          The inventory contains a number of widget elements of 
          which are defined by the complexType 'widgetType'
        &amp;lt;/xsd:documentation&amp;gt;
      &amp;lt;/xsd:annotation&amp;gt;
        &amp;lt;xsd:sequence&amp;gt;
            &amp;lt;xsd:element name=&quot;widget&quot; type=&quot;widgetType&quot;  minOccurs=&quot;0&quot; maxOccurs=&quot;unbounded&quot; /&amp;gt;
        &amp;lt;/xsd:sequence&amp;gt;
    &amp;lt;/xsd:complexType&amp;gt;

  &amp;lt;xsd:simpleType name=&quot;materialType&quot;&amp;gt;
    &amp;lt;xsd:annotation&amp;gt;
      &amp;lt;xsd:documentation&amp;gt;
        This type defines the possible valid materials for widgets.
        This could be easily extended, but currently only includes 
        Aluminium and Copper.
      &amp;lt;/xsd:documentation&amp;gt;
    &amp;lt;/xsd:annotation&amp;gt;
    &amp;lt;xsd:restriction base=&quot;xsd:string&quot;&amp;gt;
      &amp;lt;xsd:enumeration value=&quot;Aluminium&quot;/&amp;gt;
      &amp;lt;xsd:enumeration value=&quot;Copper&quot;/&amp;gt;
    &amp;lt;/xsd:restriction&amp;gt;
  &amp;lt;/xsd:simpleType&amp;gt;

    &amp;lt;xsd:complexType name=&quot;widgetType&quot;&amp;gt;
      &amp;lt;xsd:annotation&amp;gt;
        &amp;lt;xsd:documentation&amp;gt;
          This type defines widgets. Some of the elements have 'unit' attributes that have fixed values. These could be extended.
        &amp;lt;/xsd:documentation&amp;gt;
      &amp;lt;/xsd:annotation&amp;gt;
        &amp;lt;xsd:sequence&amp;gt;
            &amp;lt;xsd:element name=&quot;material&quot;  type=&quot;materialType&quot;/&amp;gt;
            &amp;lt;xsd:element name=&quot;length&quot;&amp;gt;
                &amp;lt;xsd:complexType&amp;gt;
                    &amp;lt;xsd:simpleContent&amp;gt;
                        &amp;lt;xsd:extension base=&quot;xsd:decimal&quot;&amp;gt;
                            &amp;lt;xsd:attribute name=&quot;units&quot; type=&quot;xsd:string&quot; fixed=&quot;ft&quot; use=&quot;required&quot;/&amp;gt;
                        &amp;lt;/xsd:extension&amp;gt;
                    &amp;lt;/xsd:simpleContent&amp;gt;
                &amp;lt;/xsd:complexType&amp;gt;
            &amp;lt;/xsd:element&amp;gt;
            &amp;lt;xsd:element name=&quot;width&quot;&amp;gt;
                &amp;lt;xsd:complexType&amp;gt;
                    &amp;lt;xsd:simpleContent&amp;gt;
                        &amp;lt;xsd:extension base=&quot;xsd:decimal&quot;&amp;gt;
                            &amp;lt;xsd:attribute name=&quot;units&quot; type=&quot;xsd:string&quot; fixed=&quot;in&quot; use=&quot;required&quot;/&amp;gt;
                        &amp;lt;/xsd:extension&amp;gt;
                    &amp;lt;/xsd:simpleContent&amp;gt;
                &amp;lt;/xsd:complexType&amp;gt;
            &amp;lt;/xsd:element&amp;gt;
            &amp;lt;xsd:element name=&quot;thickness&quot;&amp;gt;
                &amp;lt;xsd:complexType&amp;gt;
                    &amp;lt;xsd:simpleContent&amp;gt;
                        &amp;lt;xsd:extension base=&quot;xsd:decimal&quot;&amp;gt;
                            &amp;lt;xsd:attribute name=&quot;units&quot; type=&quot;xsd:string&quot; fixed=&quot;in&quot; use=&quot;required&quot;/&amp;gt;
                        &amp;lt;/xsd:extension&amp;gt;
                    &amp;lt;/xsd:simpleContent&amp;gt;
                &amp;lt;/xsd:complexType&amp;gt;
            &amp;lt;/xsd:element&amp;gt;
            &amp;lt;xsd:element name=&quot;price&quot;&amp;gt;
                &amp;lt;xsd:complexType&amp;gt;
                    &amp;lt;xsd:simpleContent&amp;gt;
                        &amp;lt;xsd:extension base=&quot;xsd:decimal&quot;&amp;gt;
                            &amp;lt;xsd:attribute name=&quot;units&quot; type=&quot;xsd:string&quot; fixed=&quot;USD&quot; use=&quot;required&quot;/&amp;gt;
                        &amp;lt;/xsd:extension&amp;gt;
                    &amp;lt;/xsd:simpleContent&amp;gt;
                &amp;lt;/xsd:complexType&amp;gt;
            &amp;lt;/xsd:element&amp;gt;
            &amp;lt;xsd:element name=&quot;stockQty&quot;     type=&quot;xsd:nonNegativeInteger&quot;/&amp;gt;
        &amp;lt;/xsd:sequence&amp;gt;
    &amp;lt;/xsd:complexType&amp;gt;
&amp;lt;/xsd:schema&amp;gt;
</code></pre>



	<p>Again, this is just my first try at this. I hope to improve my skills. Next, <span class="caps"><span class="caps">XSLT</span></span>!</p>


	<p>Zipped source: <a href="http://justin-hopkins.com/files/inventory.zip">inventory.zip</a></p>]]></content:encoded>
			<wfw:commentRss>http://justin-hopkins.com/blog/2008/10/11/my-first-xml-schema/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Install Typo at A2hosting</title>
		<link>http://justin-hopkins.com/blog/2008/09/24/how-to-install-typo-at-a2hosting</link>
		<comments>http://justin-hopkins.com/blog/2008/09/24/how-to-install-typo-at-a2hosting#comments</comments>
		<pubDate>Thu, 25 Sep 2008 03:43:00 +0000</pubDate>
		<dc:creator>Justin</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Typo]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[I&#8217;m new at A2hosting, and just went through almost a weeks worth of back and forth with their tech support folks. Being that their wiki on installing a Typo blog is out of date &#8211; I thought I&#8217;d make this my first post on my new blog. Prep The first thing you&#8217;ll want to do [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m new at A2hosting, and just went through almost a weeks worth of back and forth with their tech support folks. Being that their wiki on installing a Typo blog is out of date &#8211; I thought I&#8217;d make this my first post on my new blog.</p>


	<h3>Prep</h3>


	<p>The first thing you&#8217;ll want to do is submit a ticket to have Rails 2.0.2 installed. The default Rails 2.1.1 will not work with Typo at this time. There is an experimental branch of Typo to support Rails 2.1.1, but being new to RoR &#8211; I didn&#8217;t want to go that route. Also, if you haven&#8217;t already &#8211; you might want to ask them to install wget for you, as it&#8217;s what I use to download stuff from the command line. You can use curl if you are comfortable with it also.</p>


	<p>While A2hosting is working on getting Rails ready to go, you can use cPanel to setup your MySQL and ruby app.</p>


	<h4>Set up your database</h4>


From the cPanel front page:<br />
	<ol>
	<li>Click &#8216;MySQL Databases&#8217;</li>
		<li>Name your new database &#8216;typo&#8217; and hit &#8216;Create Database&#8217; (Your username will be prefixed to the database name, i.e. &#8216;johndoe_typo&#8217;)</li>
		<li>Scroll down the page a bit and add a new user called &#8216;typo&#8217; and set a password(write this down) &#8211; hit &#8216;Create User&#8217; (Your username will be prefixed to the database name, i.e. &#8216;johndoe_typo&#8217;)</li>
		<li>Scroll back down and add the user to the database &#8211; select the user and database from the dropdowns and hit &#8216;Add&#8217;, on the resulting page, check the &#8220;ALL <span class="caps"><span class="caps">PRIVILEGES</span></span>&#8221; box and hit &#8216;Make Changes&#8217;</li>
	</ol>


	<h4>Create your Rails app</h4>


	<p>To be honest, I&#8217;m not totally sure this step is necessary. When working with A2hosting tech support, they claimed that their rails app showed up automagically when they extracted the typo archive into their web directory, which is the next step, but this didn&#8217;t happen for me, so here&#8217;s what I did instead:</p>


<p>You will need an empty directory to put your app. I&#8217;d suggest </p>


<pre><code>mkdir ~/www/typo</code></pre>



	<p>Then head back to the cPanel frontpage and look for &#8216;Ruby on Rails&#8217;</p>


	<ul>
	<li>app name = typo</li>
		<li>path = public_html/typo (www is a symlink to public_html)</li>
		<li>load on boot = checked</li>
		<li>environment = production (you could go with development, and should switch it if you have issues &#8211; but for now just go with production)</li>
		<li>Hit &#8216;Create&#8217;</li>
		<li>Create the rewrite you want(This is necessary if you want to use a rails app, but you can redirect the root directory of your domain like I&#8217;ve done)</li>
	</ul>


<p>Now you&#8217;re going to say I&#8217;m crazy &#8211; but go back to your shell and blow away the directory we created earlier</p>


<pre><code>rm -rf ~/www/typo</code></pre>



	<p>Like I said, this was really just to get the typo app listed in cPanel so that we can start/stop it, create a re-write, and toggle the other settings. We are going to recreate the typo directory but populate it with the actual Typo code in the next step.</p>


	<h3>Download Typo</h3>


	<p>After Rails 2.0.2 is installed, you can go ahead and download Typo. Connect to your server via ssh and then do the following:</p>




<pre>
<code>
wget http://rubyforge.org/frs/download.php/42257/typo-5.1.3.tgz
tar xzvpf typo-5.1.3.tgz
mv typo-5.1.3 typo
</code>
</pre>



	<h3>Configure the database connection</h3>


	<p>First things first, rename database.yml.example to database.yml:</p>




<pre><code>
mv ~/www/typo/config/database.yml.example ~/www/typo/database.yml
</code></pre>



<p>Now use your favorite text editor to make database.yml look like this(use the username/password and database names you created earlier):</p>


<pre>
login: &amp;#38;login
  adapter: mysql
  host: localhost
  username: yourusername_typo
  password: yourpassword
  database: yourusername_typo

development:
  database: yourusername_typo
  &amp;lt;&amp;lt;: *login

test:
  database: yourusername_typo
  &amp;lt;&amp;lt;: *login

production:
  database: yourusername_typo
  &amp;lt;&amp;lt;: *login
</pre>



	<p>Strictly speaking, you&#8217;re all set &#8211; but there are some issues that I had to work though before Typo started working for me.</p>


	<h3>Fixes</h3>


	<p>A couple issues came up at this point for me. A2hosting support was kind enough to provide one of these, but after some chiding from them &#8211; I was forced to look up the other myself ;)</p>


	<ol>
	<li>Open up ~/www/typo/config/boot.rb and browse down to line 29. The line begins with &#8216;require_gem&#8217; and needs to be replaced with just &#8216;gem&#8217;. Apparently this is depreciated code, and I suspect it has at least something to do with the next fix.</li>
		<li>Open up ~/www/typo/app/models/article.rb and pop down to line 296 and add:</li>
	</ol>




<pre><code>

#Added per http://www.typosphere.org/issues/show/1264 to correct error upon managing content
  def published?
    published
  end
</code></pre>



	<p>Both of these issues are probably caused by A2hosting using Rails 1.8.7 and Typo supporting 1.8.6 &#8211; but they seem to be workable this way. I&#8217;d be curious if anyone else tries downgrading to 1.8.6 and skipping these 2 steps.</p>


	<h3>Start yer app!</h3>


	<p>Go back into cPanel, Ruby on Rails section and hit &#8216;Run&#8217; for your Typo app. After the confirmation screen, use the &#8216;Go back&#8217; link and make sure it says &#8220;Running&#8221; <strong>and not</strong> &#8220;Not running&#8221;. If it&#8217;s going &#8211; direct your browser to whatever url you designated in your rewrite(or click the &#8216;URL&#8217; link in the app table). There should be/might/will be a delay while the Typo database structure is set up &#8211; then you&#8217;ll create your first user.</p>


	<p>If your app is not running at this point &#8211; please do leave a comment. It may be that I&#8217;ve left something out.</p>


	<p>The rest is up to you!</p>]]></content:encoded>
			<wfw:commentRss>http://justin-hopkins.com/blog/2008/09/24/how-to-install-typo-at-a2hosting/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
