<?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"
	>

<channel>
	<title>mattdorn.com &#187; technology</title>
	<atom:link href="http://www.mattdorn.com/categories/technology/feed" rel="self" type="application/rss+xml" />
	<link>http://www.mattdorn.com</link>
	<description></description>
	<pubDate>Sat, 05 Jul 2008 19:18:34 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>Plone i18n: a brief tutorial</title>
		<link>http://www.mattdorn.com/content/plone-i18n-a-brief-tutorial/</link>
		<comments>http://www.mattdorn.com/content/plone-i18n-a-brief-tutorial/#comments</comments>
		<pubDate>Fri, 20 Apr 2007 12:47:54 +0000</pubDate>
		<dc:creator>mdorn</dc:creator>
		
		<category><![CDATA[i18n]]></category>

		<category><![CDATA[plone]]></category>

		<category><![CDATA[technology]]></category>

		<guid isPermaLink="false">http://67.207.132.145/wordpress/?p=44</guid>
		<description><![CDATA[.. -*- mode: rst -*-

The following tutorial details the steps I took to internationalize (starting with a Spanish translation) the interface of `Plone Translation Hub`_, a Plone Archetypes-based product.

.. _Plone Translation Hub: http://plonexl8.textmethod.com]]></description>
			<content:encoded><![CDATA[
<div class="document">
<!-- -*- mode: rst -*- -->
<p>The following tutorial details the steps I took to internationalize (starting with a Spanish translation) the interface of <a class="reference" href="http://plonexl8.textmethod.com">Plone Translation Hub</a>, a Plone Archetypes-based product.</p>
<div class="contents topic">
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#basic-plone-i18n-with-i18ndude" id="id1" name="id1">Basic Plone i18n with i18ndude</a></li>
<li><a class="reference" href="#advanced-plone-i18n" id="id2" name="id2">Advanced Plone i18n</a><ul>
<li><a class="reference" href="#translating-workflow-states-and-transitions" id="id3" name="id3">Translating workflow states and transitions</a></li>
<li><a class="reference" href="#accessing-the-plone-translation-machinery-directly" id="id4" name="id4">Accessing the Plone translation machinery directly</a></li>
</ul>
</li>
<li><a class="reference" href="#resources" id="id5" name="id5">Resources</a></li>
</ul>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id1" id="basic-plone-i18n-with-i18ndude" name="basic-plone-i18n-with-i18ndude">Basic Plone i18n with i18ndude</a></h3>
<p>First, processing your UML model via ArchGenXML (assuming you have <a class="reference" href="http://plone.org/products/i18ndude">i18ndude</a> installed) will produce a file called <tt class="docutils literal"><span class="pre">generated.pot</span></tt> and place it in your product&#8217;s <tt class="docutils literal"><span class="pre">i18n</span></tt> directory, which is where all translations must go.  Plone makes somewhat customized use of a the GNU <a class="reference" href="http://oriya.sarovar.org/docs/gettext/">gettext</a> architecture for i18n of applications.  So <tt class="docutils literal"><span class="pre">generated.pot</span></tt> is a template that contains the labels and text for your Archetypes objects.</p>
<p>Before you can begin translating, though, you&#8217;ll need to ensure that the elements in your your page templates that expose text to the user are tagged for translation by the Plone translation architecture.  First you want to make sure that you specify the <tt class="docutils literal"><span class="pre">domain</span></tt> element in the template&#8217;s root (<tt class="docutils literal"><span class="pre">html</span></tt>) element to correspond to your product:</p>
<pre class="literal-block">
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot;
    lang=&quot;en&quot;
    metal:use-macro=&quot;here/main_template/macros/master&quot;
    i18n:domain=&quot;PRODUCT_NAME&quot;&gt;
</pre>
<p>Next, for field labels, help indicators, etc.&#8211;any text that&#8217;s visible to your user&#8211;you&#8217;ll need to apply the <tt class="docutils literal"><span class="pre">i18n:translate</span></tt> attribute:</p>
<pre class="literal-block">
&lt;label for=&quot;my_field&quot; i18n:translate=&quot;PRODUCT_NAME_label_my_field&quot;&gt;Enter your name&lt;/label&gt;
</pre>
<p>Once you&#8217;ve finished applying this attribute in your page templates, if your product is fairly simple, you&#8217;re nearly finished.  All you need to do is merge the original PO file from your Archetypes product with your new translatable items from your page templates.  Assuming i18ndude is in your path, from your product&#8217;s root directory, execute it like so:</p>
<pre class="literal-block">
i18ndude rebuild-pot --pot i18n/PRODUCT_NAME.pot --create PRODUCT_NAME --merge i18n/generated.pot skins/PRODUCT_NAME/*.pt
</pre>
<p>Then create an empty PO file for the language(s) you want to create.  E.g., for Spanish, you&#8217;d want:</p>
<pre class="literal-block">
touch i18n/PRODUCT_NAME-es.po
</pre>
<p>Finally, to populate the PO file with the text from the original template so that you can translate it:</p>
<pre class="literal-block">
i18ndude sync --pot i18n/PRODUCT_NAME.pot i18n/PRODUCT_NAME-es.po
</pre>
<p>You can now perform your translations with a tool like <a class="reference" href="http://www.poedit.net/">POEdit</a>.</p>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id2" id="advanced-plone-i18n" name="advanced-plone-i18n">Advanced Plone i18n</a></h3>
<div class="section">
<h4><a class="toc-backref" href="#id3" id="translating-workflow-states-and-transitions" name="translating-workflow-states-and-transitions">Translating workflow states and transitions</a></h4>
<p>Now, if your product has its own workflow states and transitions, you&#8217;ll want to translate those as well.  Enabling those translations is not included in the above process.  You&#8217;ll need to create a separate file with a name reflecting the &quot;plone&quot; domain:</p>
<pre class="literal-block">
touch i18n/plone-PRODUCT_NAME-es.po
</pre>
<p>(Note also that the PO file header includes a &quot;Domain&quot; key to which you&#8217;ll want to assign the value &quot;plone&quot;.)</p>
<p>Essentially you&#8217;ll need to edit this file by hand, assigning the <tt class="docutils literal"><span class="pre">msgid</span></tt> key with the original text and the <tt class="docutils literal"><span class="pre">msgstr</span></tt> with your translation:</p>
<pre class="literal-block">
msgid &quot;Open&quot;
msgstr &quot;Abierto&quot;

msgid &quot;Closed&quot;
msgstr &quot;Cerrado&quot;
</pre>
</div>
<div class="section">
<h4><a class="toc-backref" href="#id4" id="accessing-the-plone-translation-machinery-directly" name="accessing-the-plone-translation-machinery-directly">Accessing the Plone translation machinery directly</a></h4>
<p>You may have some text in your application that appears neither in your page templates nor in your workflow (obviously a situation that you want to avoid if possible).  If so, you may need to access the Plone translation machinery directly, which is best illustrated with an example taken from an External Method used by my product:</p>
<pre class="literal-block">
from Products.CMFCore.utils import getToolByName
...
translation_service = getToolByName(self, 'translation_service')
msg = translation_service.utranslate(domain='PloneXL8',
                                     msgid='You have taken ownership of this translation.',
                                     default='You have taken ownership of this translation.',
                                     context=self)
msg = msg.encode('utf-8')
</pre>
<p>Note that you&#8217;ll need to add the <tt class="docutils literal"><span class="pre">msgid</span></tt> and <tt class="docutils literal"><span class="pre">msgstr</span></tt> for such into your PRODUCT_NAME.pot and/or PRODUCT_NAME-xx.po file by hand.</p>
</div>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id5" id="resources" name="resources">Resources</a></h3>
<p>Some helpful links:</p>
<ul class="simple">
<li><a class="reference" href="http://docs.neuroinf.de/programming-plone/i18n">Basic Plone i18n</a></li>
<li><a class="reference" href="http://plone.org/products/archgenxml/documentation/how-to/handling-i18n-translation-files-with-archgenxml-and-i18ndude">Archetypes and i18ndude</a></li>
<li><a class="reference" href="http://plone.org/documentation/manual/plone-developer-reference/patterns/referencemanual-all-pages">Plone best practices</a></li>
<li><a class="reference" href="http://plone.org/development/teams/i18n/datetime">Date and time localization</a></li>
</ul>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.mattdorn.com/content/plone-i18n-a-brief-tutorial/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Open Source i18n</title>
		<link>http://www.mattdorn.com/content/open-source-i18n/</link>
		<comments>http://www.mattdorn.com/content/open-source-i18n/#comments</comments>
		<pubDate>Tue, 17 Apr 2007 11:05:04 +0000</pubDate>
		<dc:creator>mdorn</dc:creator>
		
		<category><![CDATA[i18n]]></category>

		<category><![CDATA[technology]]></category>

		<category><![CDATA[translation]]></category>

		<guid isPermaLink="false">http://67.207.132.145/wordpress/?p=43</guid>
		<description><![CDATA[


Not so long ago I found myself in the rather embarrassing position of having authored a translation collaboration tool for use by an international user base without having implemented the platform&#8217;s (Plone) internationalization (i18n) facilities.  That is, I gave the application an English interface and left it at that.  Furthermore I began to [...]]]></description>
			<content:encoded><![CDATA[
<div class="document">
<!-- -*- mode: rst -*- -->
<p>Not so long ago I found myself in the rather embarrassing position of having authored a <a class="reference" href="http://plonexl8.textmethod.com">translation collaboration tool</a> for use by an international user base without having implemented the platform&#8217;s (<a class="reference" href="http://plone.org">Plone</a>) internationalization (i18n) facilities.  That is, I gave the application an English interface and left it at that.  Furthermore I began to consider how I might extend this application to enable the more professional users to leverage their existing translation tools, like the industry-standard <a class="reference" href="http://www.trados.com/">Trados</a>, rather than being confined to using my application&#8217;s Web interface when actually performing a translation (even if a cut-and-paste workaround is available).  Correcting the first problem and laying the groundwork for solving the second entailed giving myself a pretty extensive lesson in both open standards and Open Source software for Computer Aided Translation (CAT), which I summarize below.</p>
<div class="contents topic">
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#translating-software-interfaces" id="id1" name="id1">Translating software interfaces</a></li>
<li><a class="reference" href="#translating-documents" id="id2" name="id2">Translating documents</a></li>
<li><a class="reference" href="#translation-memory-tm" id="id3" name="id3">Translation Memory (TM)</a></li>
</ul>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id1" id="translating-software-interfaces" name="translating-software-interfaces">Translating software interfaces</a></h3>
<p>First, I discovered that there are two aspects of what I&#8217;m currently trying to achieve with this tool, both of which have different, but related, technological solutions.  First of all, I need translations for the interface of the tool itself. To accomplish this, Plone makes somewhat customized use of a the GNU <a class="reference" href="http://oriya.sarovar.org/docs/gettext/">gettext</a> architecture for i18n of applications.  In that model, translations are stored in message catalogs which match original translations with their target language translations contained and which are contained in files with the <tt class="docutils literal"><span class="pre">.po</span></tt> format, which essentially maintains translations through original/translation key-value pairs.  In the case of Plone, a utility called <a class="reference" href="http://plone.org/products/i18ndude">i18ndude</a> handles much of the heavy lifing involved in preparing these files for use with your Plone Product, while a PO file editor like <a class="reference" href="http://www.poedit.net/">POEdit</a> helps you actually perform the translations.</p>
<p>The gettext/PO file approach appears to be the most common solution for translating the interfaces for Linux-based open source projects as well as Web applications (though there are some sui-generis exceptions, such as the <a class="reference" href="http://www.globalize-rails.org/">Globalize plugin</a> for Ruby on Rails).</p>
<p>So I went ahead and created a Spanish translation for the application, but its current users include translators of French and Portuguese as well, and potentially Italian, Swahili, Greek, and Arabic.  I can&#8217;t translate the interface into those languages (though I might be able to create a passable Portuguese interface), and I&#8217;d like to make it as easy as possible for those who can to help me out.  A solution to this problem might be to set up a server tool like <a class="reference" href="http://www.wordforge.org/drupal/projects/wordforge/tools/pootle">Pootle</a>, which lets  you visualize progress made on translation of PO files, to help manage the project.  Ubuntu/Launchpad&#8217;s <a class="reference" href="https://launchpad.net/rosetta">Rosetta</a>, which is not (yet) open source, appears to be a more sophisticated implementation of the same idea.  In conjunction with the server app, I could provide a brief overview of client-side tools that can be used to edit the PO files.  I have already mentioned <a class="reference" href="http://www.poedit.net/">POEdit</a>, but <a class="reference" href="http://sourceforge.net/projects/omegat">OmegaT</a>, a more ambitious suite of Open Source CAT tools, a also has support for PO files.</p>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id2" id="translating-documents" name="translating-documents">Translating documents</a></h3>
<p>So, software interface translation is the first order of translation business for my project.  The second issue is the translation of documents, which is the purpose of the application itself.  Take the documentation of a software program, for example, with an original document in, say, HTML.  A translator could simply translate it free-form, using copy-and-paste and whatever tools she happens to have available.  But translation-specific editors like that provided by <a class="reference" href="http://sourceforge.net/projects/omegat">OmegaT</a>&#8211;which supports HTML, OpenOffice, and ODF among several other formats&#8211;can help present the text in a way that&#8217;s more comfortable for translation, in addition to providing access to Translation Memory tools.  As long as the program is capable of exporting the translation to the format of the original (which is presumably what would be reqeusted in most translation jobs), this would appear to be the preferable route.</p>
<p>The problem with this process is that translators are likely to receive documents in any number of formats&#8211;the tools they use may be more capable of dealing with some formats than with others, and a separate workflow or collaboration process may need to be defined depending on the type of file.  This is the problem that <a class="reference" href="http://www.opentag.com/xliff.htm">XLIFF</a>, an XML format for translations, attempts to address, by providing a set of elements for tracking information common to translation activity.  I don&#8217;t go into detail on XLIFF here (and in fact have quite a bit more to learn about it), but Trados and other major translation software vendors already include support for XLIFF, and given its emergence as a standard, any software meant to support translation collaboration should also support XLIFF.</p>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id3" id="translation-memory-tm" name="translation-memory-tm">Translation Memory (TM)</a></h3>
<p>Finally, both activities&#8211;the translation of software interfaces and the translation of documents&#8211;benefit from the use of a Translation Memory (TM) system.  POEdit can generate a TM for you by letting you import previously existing PO files based on the language(s) you want to work with.  OmegaT generates one for you based on the translations you provide while working on your project, but also allows you to import existing TMs based on the <a class="reference" href="http://www.lisa.org/standards/tmx/">TMX</a> standard.</p>
<p>Pending further investigation, I&#8217;m considering complementing Plone Translation Hub with a repository of TMX files for enhanced collaboration.  Because it&#8217;s Zope/Plone, <a class="reference" href="http://www.tumatxa.com/">Tumatxa</a> might provide a good starting point.</p>
<p>Note that the effectiveness of TM relies on a program&#8217;s ability to &quot;segment&quot; a source document properly, <a class="reference" href="http://www.lisa.org/standards/srx/srx.html">SRX</a> is the emerging standard for defining segmentation rules.</p>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.mattdorn.com/content/open-source-i18n/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Updating Plone user roles programatically</title>
		<link>http://www.mattdorn.com/content/updating-plone-user-roles-programatically/</link>
		<comments>http://www.mattdorn.com/content/updating-plone-user-roles-programatically/#comments</comments>
		<pubDate>Mon, 12 Mar 2007 13:35:46 +0000</pubDate>
		<dc:creator>mdorn</dc:creator>
		
		<category><![CDATA[plone]]></category>

		<category><![CDATA[technology]]></category>

		<guid isPermaLink="false">http://67.207.132.145/wordpress/?p=42</guid>
		<description><![CDATA[


Today for a site using Plone Translation Hub I had to programatically update the roles for all users who had logged in since March 9th, given that this group was known to be responsible enough to be worthy of the &#34;Reviewer&#34; role.  One of the site managers asked that I simply run a &#34;SQL [...]]]></description>
			<content:encoded><![CDATA[
<div class="document">
<!-- -*- mode: rst -*- -->
<p>Today for a site using <a class="reference" href="http://plonexl8.textmethod.com/">Plone Translation Hub</a> I had to programatically update the roles for all users who had logged in since March 9th, given that this group was known to be responsible enough to be worthy of the &quot;Reviewer&quot; role.  One of the site managers asked that I simply run a &quot;SQL query&quot; to do this&#8211;if only it were that easy!  Actually it&#8217;s not that much harder with the ZODB, but it took me a while to find the &quot;userFolderEditUser&quot; method that I needed to do this, which was frustrating.  I ended up simply using a temporary script object placed in the root of the portal:</p>
<pre class="literal-block">
recent_date=DateTime('2007/03/09')
total=0
recent=0

mship = context.portal_membership
acl_users = context.acl_users
for user in mship.listMembers():
    login_time=DateTime(user.last_login_time)
    roles = list(user.getRoles())
    if login_time.greaterThanEqualTo(recent_date) and 'Reviewer' not in roles:
        roles.append('Reviewer')
        acl_users.userFolderEditUser(user.id, None, roles, user.getDomains())
        recent += 1
    total += 1
print &quot;Recent users: &quot; + str(recent)
print &quot;Total users: &quot; + str(total)
return printed
</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.mattdorn.com/content/updating-plone-user-roles-programatically/feed/</wfw:commentRss>
		</item>
		<item>
		<title>reStructuredText tools for gedit</title>
		<link>http://www.mattdorn.com/content/restructuredtext-tools-for-gedit/</link>
		<comments>http://www.mattdorn.com/content/restructuredtext-tools-for-gedit/#comments</comments>
		<pubDate>Thu, 15 Feb 2007 09:20:07 +0000</pubDate>
		<dc:creator>mdorn</dc:creator>
		
		<category><![CDATA[gnome]]></category>

		<category><![CDATA[programming]]></category>

		<category><![CDATA[reStructuredText]]></category>

		<category><![CDATA[technology]]></category>

		<guid isPermaLink="false">http://67.207.132.145/wordpress/?p=41</guid>
		<description><![CDATA[


Over the last couple of days, I put together some reStructuredText tools for gedit, the lightweight text editor for the Gnome desktop on Linux.  They include syntax highlighting, some keyboard shortcuts, and an HTML preview feature that I derived from another developer&#8217;s earlier work on Markdown support.
This was made possible by gedit&#8217;s excellent plugin [...]]]></description>
			<content:encoded><![CDATA[
<div class="document">
<!-- -*- mode: rst -*- -->
<p>Over the last couple of days, I put together some <a class="reference" href="http://textmethod.com/wiki/ReStructuredTextToolsForGedit">reStructuredText tools for gedit</a>, the lightweight text editor for the Gnome desktop on Linux.  They include syntax highlighting, some keyboard shortcuts, and an HTML preview feature that I derived from another developer&#8217;s earlier work on <a class="reference" href="http://live.gnome.org/Gedit/MarkdownSupport">Markdown support</a>.</p>
<p>This was made possible by gedit&#8217;s excellent plugin system, which allows you extend the application via <a class="reference" href="http://python.org">Python</a>.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.mattdorn.com/content/restructuredtext-tools-for-gedit/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Gnapsack 0.2 released</title>
		<link>http://www.mattdorn.com/content/gnapsack-02-released/</link>
		<comments>http://www.mattdorn.com/content/gnapsack-02-released/#comments</comments>
		<pubDate>Wed, 07 Feb 2007 16:03:33 +0000</pubDate>
		<dc:creator>mdorn</dc:creator>
		
		<category><![CDATA[backpack]]></category>

		<category><![CDATA[gnapsack]]></category>

		<category><![CDATA[python]]></category>

		<category><![CDATA[software]]></category>

		<category><![CDATA[technology]]></category>

		<category><![CDATA[web services]]></category>

		<guid isPermaLink="false">http://67.207.132.145/wordpress/?p=40</guid>
		<description><![CDATA[


Version 0.2 of my client for the Backpack Web Services API, Gnapsack, was released today, and now has a new home.  The two main enhancements are Windows compatibility and ability to handle multiple lists.

]]></description>
			<content:encoded><![CDATA[
<div class="document">
<!-- -*- mode: rst -*- -->
<p>Version 0.2 of my client for the <a class="reference" href="http://www.backpackit.com/">Backpack</a> Web Services API, Gnapsack, was released today, and now has a <a class="reference" href="http://gnapsack.textmethod.com/">new home</a>.  The two main enhancements are Windows compatibility and ability to handle multiple lists.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.mattdorn.com/content/gnapsack-02-released/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Agile tools in Ruby and Python</title>
		<link>http://www.mattdorn.com/content/agile-tools-in-ruby-and-python/</link>
		<comments>http://www.mattdorn.com/content/agile-tools-in-ruby-and-python/#comments</comments>
		<pubDate>Thu, 01 Feb 2007 12:51:31 +0000</pubDate>
		<dc:creator>mdorn</dc:creator>
		
		<category><![CDATA[agile]]></category>

		<category><![CDATA[python]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[ruby]]></category>

		<category><![CDATA[technology]]></category>

		<guid isPermaLink="false">http://67.207.132.145/wordpress/?p=39</guid>
		<description><![CDATA[


I spent a few months at the end of last year working on a Ruby on Rails project.  While I constantly found myself longing for Python, I did appreciate the extent to which RoR carried certain best practices&#8211;among them an MVC architecture and Test-Driven Development&#8211;to an extreme, baking them into the framework.
The following table [...]]]></description>
			<content:encoded><![CDATA[
<div class="document">
<!-- -*- mode: rst -*- -->
<p>I spent a few months at the end of last year working on a Ruby on Rails project.  While I constantly found myself longing for Python, I did appreciate the extent to which RoR carried certain best practices&#8211;among them an MVC architecture and Test-Driven Development&#8211;to an extreme, baking them into the framework.</p>
<p>The following table identifies a series of functions relevant to &quot;agile&quot; development and indicates which tools are typically used with which language.  I may update this table as more functions or more appropriate tools occur to me.</p>
<table border="1" class="docutils">
<colgroup>
<col width="44%" />
<col width="26%" />
<col width="30%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">Function</th>
<th class="head" colspan="2">Tool</th>
</tr>
<tr><th class="head">()()</th>
<th class="head">Ruby</th>
<th class="head">Python</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>Continuous integration</td>
<td><a class="reference" href="http://rubyforge.org/projects/cerberus/">Cerberus</a></td>
<td><a class="reference" href="http://buildbot.sourceforge.net/">buildbot</a></td>
</tr>
<tr><td>Test coverage</td>
<td><a class="reference" href="http://eigenclass.org/hiki.rb?rcov">Rcov</a></td>
<td><a class="reference" href="http://nedbatchelder.com/code/modules/coverage.html">coverage.py</a></td>
</tr>
<tr><td>Documentation</td>
<td><a class="reference" href="http://rdoc.sourceforge.net/">RDoc</a></td>
<td><a class="reference" href="http://epydoc.sourceforge.net/">EpyDoc</a></td>
</tr>
<tr><td>Code versioning</td>
<td><a class="reference" href="http://subversion.tigris.org/">Subversion</a></td>
<td><a class="reference" href="http://subversion.tigris.org/">Subversion</a></td>
</tr>
<tr><td>Project management</td>
<td><a class="reference" href="http://trac.edgewall.org/">Trac</a></td>
<td><a class="reference" href="http://trac.edgewall.org/">Trac</a></td>
</tr>
<tr><td>App Deployment</td>
<td><a class="reference" href="http://wiki.rubyonrails.org/rails/pages/Capistrano">Capistrano</a> *</td>
<td><a class="reference" href="http://pythonpaste.org/">PythonPaste</a> ?</td>
</tr>
</tbody>
</table>
<p>* Capistrano is language-agnostic.  Other tools may be as well.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.mattdorn.com/content/agile-tools-in-ruby-and-python/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Trac + Darcs + reStructuredText</title>
		<link>http://www.mattdorn.com/content/trac-darcs-restructuredtext/</link>
		<comments>http://www.mattdorn.com/content/trac-darcs-restructuredtext/#comments</comments>
		<pubDate>Thu, 01 Feb 2007 10:50:08 +0000</pubDate>
		<dc:creator>mdorn</dc:creator>
		
		<category><![CDATA[darcs]]></category>

		<category><![CDATA[project management]]></category>

		<category><![CDATA[reStructuredText]]></category>

		<category><![CDATA[software]]></category>

		<category><![CDATA[technology]]></category>

		<category><![CDATA[trac]]></category>

		<guid isPermaLink="false">http://67.207.132.145/wordpress/?p=38</guid>
		<description><![CDATA[


Edgewall Software&#8217;s Trac seems to have become something of a standard for agile management of software projects both within the Open Source community and within closed organizations, and after having the opportunity to use it on a recent project, I can appreciate why.  It&#8217;s simple to setup and manage, and its self-described &#34;minimalistic approach [...]]]></description>
			<content:encoded><![CDATA[
<div class="document">
<!-- -*- mode: rst -*- -->
<p>Edgewall Software&#8217;s <a class="reference" href="http://trac.edgewall.org/">Trac</a> seems to have become something of a standard for agile management of software projects both within the Open Source community and within closed organizations, and after having the opportunity to use it on a recent project, I can appreciate why.  It&#8217;s simple to setup and manage, and its self-described &quot;minimalistic approach to web-based software project management&quot; is exactly along the lines of my own philosophy.</p>
<p>For that project I used a default setup with a <a class="reference" href="http://subversion.tigris.org/">Subversion</a> repository, and composed Wiki pages using the default Wiki markup. While Subversion is obviously a standard, for personal projects I prefer to use the distributed versioning system <a class="reference" href="/content/getting-started-with-darcs">Darcs</a>, and I usually insist on doing the majority of my text composition in <a class="reference" href="/content/the-pleasure-of-the-restructured-text">reStructuredText</a>.  So when I found out that there was a <a class="reference" href="http://progetti.arstecnica.it/trac+darcs/">Darcs plugin</a> for Trac and that it also <a class="reference" href="http://trac.edgewall.org/wiki/WikiRestructuredText">supports reStructuredText</a> , I got motivated to get a couple of <a class="reference" href="http://gnapsack.textmethod.com/">my own</a> <a class="reference" href="http://plonexl8.textmethod.com">projects</a> up and running. What follows is a brief description of the steps I took to do so.</p>
<div class="contents topic">
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
<ul class="auto-toc simple">
<li><a class="reference" href="#get-the-software" id="id1" name="id1">1&nbsp;&nbsp;&nbsp;Get the software</a></li>
<li><a class="reference" href="#set-up-your-trac-instance" id="id2" name="id2">2&nbsp;&nbsp;&nbsp;Set up your Trac instance</a></li>
<li><a class="reference" href="#install-and-configure-the-trac-plugins" id="id3" name="id3">3&nbsp;&nbsp;&nbsp;Install and configure the Trac plugins</a></li>
<li><a class="reference" href="#configure-apache-and-mod-python" id="id4" name="id4">4&nbsp;&nbsp;&nbsp;Configure Apache and mod_python</a></li>
<li><a class="reference" href="#configure-user-authentication-and-permissions" id="id5" name="id5">5&nbsp;&nbsp;&nbsp;Configure user authentication and permissions</a></li>
<li><a class="reference" href="#final-notes" id="id6" name="id6">6&nbsp;&nbsp;&nbsp;Final notes</a><ul class="auto-toc">
<li><a class="reference" href="#darcs-tracs-bug" id="id7" name="id7">6.1&nbsp;&nbsp;&nbsp;Darcs+Tracs bug</a></li>
<li><a class="reference" href="#restructuredtext-in-trac" id="id8" name="id8">6.2&nbsp;&nbsp;&nbsp;reStructuredText in Trac</a></li>
</ul>
</li>
</ul>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id1" id="get-the-software" name="get-the-software">1&nbsp;&nbsp;&nbsp;Get the software</a></h3>
<p>I&#8217;m assuming your system has fundamentals like Python and Apache installed.  In addition:</p>
<ul>
<li><p class="first">Trac (I&#8217;m using v0.10.x)</p>
</li>
<li><p class="first">Darcs (I&#8217;m using v. 1.0.8)</p>
</li>
<li><p class="first">sqlite2 (I personally had problems with version 3 and the Darcs plugin on a Fedora Core 4 system, which have been reported to the project maintainers)</p>
</li>
<li><dl class="first docutils">
<dt>Trac plugins</dt>
<dd><ul class="first last simple">
<li><a class="reference" href="http://progetti.arstecnica.it/trac+darcs/">Darcs plugin</a></li>
<li><a class="reference" href="http://trac.edgewall.org/wiki/WebAdmin">Web Admin plugin</a></li>
<li><a class="reference" href="http://trac-hacks.org/wiki/AccountManagerPlugin">Account Manager plugin</a></li>
</ul>
</dd>
</dl>
</li>
<li><p class="first">Python docutils (for reStructuredText support)</p>
</li>
<li><p class="first"><a class="reference" href="http://silvercity.sourceforge.net/">SilverCity</a> (for syntax coloring of your code)</p>
</li>
<li><p class="first">Python setuptools (for working with Trac plugins)</p>
</li>
<li><p class="first">Apache mod_python</p>
</li>
</ul>
<p>Note that the items that are not linked above should be available via the package manager of most modern Linux systems.  You&#8217;ll want to install everything except that Trac plugins before moving on to the next step.</p>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id2" id="set-up-your-trac-instance" name="set-up-your-trac-instance">2&nbsp;&nbsp;&nbsp;Set up your Trac instance</a></h3>
<p>Create a directory where you want to maintain your Trac projects and use the <tt class="docutils literal"><span class="pre">trac-admin</span></tt> command to create the instance and associate it with your Darcs repository:</p>
<pre class="literal-block">
trac-admin /path/to/MyProject initenv &quot;My Project&quot; sqlite:db/trac.db darcs /path/to/repo /usr/share/trac/templates/
</pre>
<p>The instance is successfully created, but you&#8217;ll get a warning that Trac is not supported.  That&#8217;s because you haven&#8217;t setup the plugins yet.</p>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id3" id="install-and-configure-the-trac-plugins" name="install-and-configure-the-trac-plugins">3&nbsp;&nbsp;&nbsp;Install and configure the Trac plugins</a></h3>
<p>Download the source for each plugin into a temporary directory.  Trac handles plugins in the Python &quot;egg&quot; format.  So in the source directory of each, run the following command:</p>
<pre class="literal-block">
python setup.py bdist_egg
</pre>
<p>That will create a file with a <tt class="docutils literal"><span class="pre">.egg</span></tt> extension in the <tt class="docutils literal"><span class="pre">dist</span></tt> directory of the plugin you&#8217;ve downloaded, which you can now copy to the <tt class="docutils literal"><span class="pre">plugins</span></tt> directory of your new Trac instance.  Be sure to copy all three of them.</p>
<p>Now you need to update your Trac instance to understand the Darcs plugin:</p>
<pre class="literal-block">
trac-admin /path/to/MyProject upgrade
trac-admin /path/to/MyProject resync
</pre>
<p>Finally, add the following to the <tt class="docutils literal"><span class="pre">conf/trac.ini</span></tt> file of your instance, under the <tt class="docutils literal"><span class="pre">[components]</span></tt> section:</p>
<pre class="literal-block">
[components]
trac.web.auth.LoginModule = disabled
acct_mgr.web_ui.LoginModule = enabled
trac.ticket.report.* = disabled
</pre>
<p>You may wish to test your instance now, using Trac&#8217;s built-in Web server, and browsing to <tt class="docutils literal"><span class="pre">localhost:8000</span></tt>:</p>
<pre class="literal-block">
tracd --port 8000 /path/to/MyProject
</pre>
<p>or:</p>
<pre class="literal-block">
/usr/sbin/tracd --port 8000 /path/to/MyProject
</pre>
<p>Make sure you can browse your Darcs repo to confirm that the Darcs plugin is working.  If you&#8217;re not seeing syntax highlighting, check to make sure <a class="reference" href="http://silvercity.sourceforge.net/">SilverCity</a> has been installed correctly.</p>
<p>In this setup, however, we&#8217;ll ultimately be using Apache and mod_python to server the instance, and a few extra steps are needed.</p>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id4" id="configure-apache-and-mod-python" name="configure-apache-and-mod-python">4&nbsp;&nbsp;&nbsp;Configure Apache and mod_python</a></h3>
<p><a class="reference" href="http://trac.edgewall.org/wiki/TracModPython">Trac&#8217;s documentation on mod_python</a> is mostly adequate, with one exception.  You need to identify a cache directory for your instance&#8217;s egg plugins.  In your <tt class="docutils literal"><span class="pre">Location</span></tt> directive, composed in accordance with that documentation, including the following line should be sufficient:</p>
<pre class="literal-block">
SetEnv PYTHON_EGG_CACHE /tmp/trac-eggs
</pre>
<p>For the sake of completeness, the <tt class="docutils literal"><span class="pre">Location</span></tt> directive inside the VirtualHost setup for your site should look something like this, if you have multiple Trac instances:</p>
<pre class="literal-block">
&lt;Location /projects&gt;
  SetHandler mod_python
  PythonHandler trac.web.modpython_frontend
  PythonOption TracEnvParentDir /path/to/my/trac/projects
  SetEnv PYTHON_EGG_CACHE /tmp/trac-eggs
  PythonOption TracUriRoot /projects
&lt;/Location&gt;
</pre>
<p>Finally, the user under which Apache is run will need read and write access to the following directories in your instance:</p>
<ul class="simple">
<li>db</li>
<li>attachments</li>
<li>log</li>
</ul>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id5" id="configure-user-authentication-and-permissions" name="configure-user-authentication-and-permissions">5&nbsp;&nbsp;&nbsp;Configure user authentication and permissions</a></h3>
<p>By default, Trac allows the anonymous user access to nearly everything, so you&#8217;ll want to make some changes.  Fortunately the Web Admin and Account Manager plugins make this fairly easy to do.  Before you create any user accounts, I found it was easiest simply to start by adding the TRAC_ADMIN permission to the anonymous group via the command line admin tool:</p>
<pre class="literal-block">
trac-admin /path/to/projenv permission add anonymous TRAC_ADMIN
</pre>
<p>Once I have access to the &quot;Admin&quot; button in the Web interface as anonymous I performed the following:</p>
<ol class="arabic simple">
<li>In Accounts &gt; Configuration, identify the path to the HtPasswdStore.  Ideally this will probably be a location within your instance.  The Web server user will need to be able to write to the location.</li>
<li>In Accounts &gt; Users, add a user.  Note that you could also add a user by registering yourself via the &quot;Register&quot; link that should appear after having installed the Account Manager plugin.</li>
<li>In General &gt; Permissions, create an &quot;admin&quot; group in the &quot;Add Subject to Group&quot; box.</li>
<li>In the same box, add the newly created user to the admin group.</li>
<li>Now, remove any &quot;CREATE&quot; or &quot;DELETE&quot; or write-related permissions, especially TRAC_ADMIN, from the anonymous subject.</li>
<li>Using the &quot;Grant Permission&quot; box, add anything appropriate for your setup to the &quot;authenticated&quot; subject.  Make sure the TRAC_ADMIN permission is assigned to the newly created admin group.</li>
<li>Add any other groups appropriate to your project (e.g., developers, who would probably have access to everything except TRAC_ADMIN)</li>
</ol>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id6" id="final-notes" name="final-notes">6&nbsp;&nbsp;&nbsp;Final notes</a></h3>
<p>It&#8217;s up to you to configure your ticket system with the appropriate values for components, milestones, versions, etc.</p>
<div class="section">
<h4><a class="toc-backref" href="#id7" id="darcs-tracs-bug" name="darcs-tracs-bug">6.1&nbsp;&nbsp;&nbsp;Darcs+Tracs bug</a></h4>
<p>Note that the only <a class="reference" href="http://trac.edgewall.org/ticket/4449">major bug with the Darcs plugin</a> that I&#8217;ve found is the broken &quot;view changes&quot; button.  That will need to be fixed before Trac+Darcs is a completely legitimate product.</p>
</div>
<div class="section">
<h4><a class="toc-backref" href="#id8" id="restructuredtext-in-trac" name="restructuredtext-in-trac">6.2&nbsp;&nbsp;&nbsp;reStructuredText in Trac</a></h4>
<p>Composing your Wiki pages in RST simply requires you to enclose your text with the following syntax:</p>
<pre class="literal-block">
{{{
#!rst

Your text goes here.

}}}
</pre>
<p>That&#8217;s an inconvenience, however minor, and I think a great Trac enhancement (which too my knowledge has not yet been suggested) would be the ability to set a default markup syntax in the configuration file.</p>
</div>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.mattdorn.com/content/trac-darcs-restructuredtext/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Getting AWStats to show Plone-authenticated users</title>
		<link>http://www.mattdorn.com/content/getting-awstats-to-show-plone-authenticated-users/</link>
		<comments>http://www.mattdorn.com/content/getting-awstats-to-show-plone-authenticated-users/#comments</comments>
		<pubDate>Sun, 15 Oct 2006 19:12:36 +0000</pubDate>
		<dc:creator>mdorn</dc:creator>
		
		<category><![CDATA[apache]]></category>

		<category><![CDATA[awstats]]></category>

		<category><![CDATA[plone]]></category>

		<category><![CDATA[technology]]></category>

		<category><![CDATA[zope]]></category>

		<guid isPermaLink="false">http://67.207.132.145/wordpress/?p=36</guid>
		<description><![CDATA[


I&#8217;m using AWStats to track usage on a Plone site that&#8217;s essentially a portal for collaborative document translation.  That means that most users of the site need to login to do anything useful, and I want to see who&#8217;s logging in along with the rest of the stats on my site.
For hosting the site, [...]]]></description>
			<content:encoded><![CDATA[
<div class="document">
<!-- -*- mode: rst -*- -->
<p>I&#8217;m using AWStats to track usage on a Plone site that&#8217;s essentially a portal for collaborative document translation.  That means that most users of the site need to login to do anything useful, and I want to see who&#8217;s logging in along with the rest of the stats on my site.</p>
<p>For hosting the site, I&#8217;m using the recommended setup which uses Zope&#8217;s Virtual Host Monser to route requests and responses between Apache and the Zope application server appropriately.  I.e., I include the following two key lines in my Apache directive:</p>
<pre class="literal-block">
RewriteEngine On
RewriteRule ^/(.*) http://localhost:8080/VirtualHostBase/http/%{SERVER_NAME}:80/MyApp/VirtualHostRoot/$1 [NC,P,L]
</pre>
<p>Since I&#8217;m going thru Apache, I can record requests in log files as with any other site.  Unfortunately, Zope/Plone does not pass information about the users who authenticate via its own system to the HTTP headers.  Taking a cue from <a class="reference" href="http://mail.zope.org/pipermail/zope/2006-May/166316.html">this thread</a>, I came up with the following solution.  It&#8217;s tested on Plone 2.1.3, but probably won&#8217;t work on Plone 2.5, given the latter&#8217;s use of Pluggable Authentication Service.</p>
<p>First, I found a place in the Plone page rendering mechanism that gets executed on each page view.  I suppose the place that I chose was somewhat arbitrary, but in the &quot;authenticate&quot; method of the file <tt class="docutils literal"><span class="pre">GroupUserFolder/GroupUserFolder.py</span></tt>, I set a header called <tt class="docutils literal"><span class="pre">X-PloneUser</span></tt>, as shown in the following patch, available for your use:</p>
<pre class="literal-block">
1020,1022d1019
&lt;         # PATCH FOR TRACKING AUTH USER IN APACHE LOGS --mdorn:
&lt;         if name is not None:
&lt;             request.RESPONSE.setHeader('X-PloneUser', name)
</pre>
<p>In my Apache configuration, I had to change <tt class="docutils literal"><span class="pre">LogFormat</span></tt> from &quot;combined&quot; to something more specific, and reference the label in the <tt class="docutils literal"><span class="pre">CustomLog</span></tt>:</p>
<pre class="literal-block">
LogFormat &quot;%h %l %{X-Ploneuser}o %t \&quot;%r\&quot; %&gt;s %b \&quot;%{Referer}i\&quot; \&quot;%{User-agent}i\&quot;&quot; plone
CustomLog &quot;|/usr/local/sbin/cronolog /home/httpd/MYDOMAIN/logs/%m-%Y/access_log&quot; plone
</pre>
<p>To see authenticated users in your AWStats configuration file, you&#8217;ll need to change the default value for that setting:</p>
<pre class="literal-block">
ShowAuthenticatedUsers=1
</pre>
<p>That&#8217;s it.  Next time AWStats processes your logs, assuming you had visits from authenticated users, you&#8217;ll now see them in the appropriate location on your AWStats report.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.mattdorn.com/content/getting-awstats-to-show-plone-authenticated-users/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Automating AWStats configuration for multiple domains</title>
		<link>http://www.mattdorn.com/content/automating-awstats-configuration-for-multiple-domains/</link>
		<comments>http://www.mattdorn.com/content/automating-awstats-configuration-for-multiple-domains/#comments</comments>
		<pubDate>Sun, 15 Oct 2006 18:34:52 +0000</pubDate>
		<dc:creator>mdorn</dc:creator>
		
		<category><![CDATA[apache]]></category>

		<category><![CDATA[awstats]]></category>

		<category><![CDATA[sysadmin]]></category>

		<category><![CDATA[technology]]></category>

		<guid isPermaLink="false">http://67.207.132.145/wordpress/?p=35</guid>
		<description><![CDATA[


Like most Web sites, this site shares server space with a number of other domains.  When I recently undertook to set up AWStats after years of not knowing anything about what kind of traffic my personal sites were getting, I figured it would probably be relatively easy to make it so that anybody else [...]]]></description>
			<content:encoded><![CDATA[
<div class="document">
<!-- -*- mode: rst -*- -->
<p>Like most Web sites, this site shares server space with a number of other domains.  When I recently undertook to set up AWStats after years of not knowing anything about what kind of traffic my personal sites were getting, I figured it would probably be relatively easy to make it so that anybody else with an account on the box who also wanted stats could avoid the hassle.</p>
<p>With a bit of help from <a class="reference" href="http://www.dotvoid.com/view.php?id=29">another tutorial</a>, I came up with the following solution.</p>
<p>First of all, I installed the AWStats package on my server&#8217;s Fedora system via yum.  With that installation, I ended up with AWStats&#8217; default config file in <tt class="docutils literal"><span class="pre">/etc/awstats/awstats.model.conf</span></tt>.</p>
<p>This setup needs a separate AWStats configuration file for each domain, so this default file is the model from which all others will be generated.  For that reason, I needed to tweak a few of the default values to work the script described later:</p>
<pre class="literal-block">
LogFile=&quot;/home/httpd/$USERNAME/logs/%MM-0-%YYYY-0/access_log&quot;
SiteDomain=&quot;$DOMAIN&quot;
HostAliases=&quot;$ALIASES&quot;
DirData=&quot;/home/httpd/$USERNAME/awstats&quot;
AllowAccessFromWebToFollowingAuthenticatedUsers=&quot;$USERNAME&quot;
</pre>
<p>(I should also note that I enabled the GeoIP plugin in this file, but that&#8217;s a subject for a different post.)</p>
<p>Now, on the Apache side of things, you need to decide on a standard location for the Apache log files for all the accounts.  In my case, that&#8217;s /home/httpd/ACCOUNT_NAME/logs.  (In that directory, the setup described below will generate directories named by month and year (like so: MM-YYYY), and put the log file there.)  The Apache virtual host directives of course will need to specify that location.  Since I don&#8217;t actually know or have any communication with my neighbors who share the box, I&#8217;ll leave that to them, but my new directives look like this:</p>
<pre class="literal-block">
CustomLog &quot;|/usr/local/sbin/cronolog /home/httpd/DOMAIN/logs/%m-%Y/access_log&quot; combined
</pre>
<p>Where <tt class="docutils literal"><span class="pre">DOMAIN</span></tt> is the name of the directory that holds the Web files (htdocs, logs, etc.) for a given domain on the server.</p>
<p>I&#8217;ve also installed <a class="reference" href="http://cronolog.org/">cronolog</a> as an easy way to rotate logs.  As you can see the Apache config pipes to that program. That&#8217;s not strictly necessary for this setup, but if you want to do it differently (e.g., with logrotate), you&#8217;re on your own.</p>
<p>Making use of this information, anytime you want AWStats set up for a new domain, you can use the following script, which is named <tt class="docutils literal"><span class="pre">/usr/local/sbin/awstats_script.sh</span></tt> in my setup, and which was adapted from <a class="reference" href="http://www.dotvoid.com/view.php?id=29">another tutorial</a> , mentioned previously:</p>
<pre class="literal-block">
#!/bin/bash
echo &quot;Enter the username:&quot;
read WUSERNAME

ACCESS_FILE=&quot;/etc/awstats/awstats.pwd&quot;
STAT_DIR=&quot;/home/httpd/$WUSERNAME/awstats&quot;

echo &quot;Enter the password:&quot;
read PASSWORD

echo &quot;Enter the main domain:&quot;
read DOMAIN

echo &quot;Enter aliases separated by space:&quot;
read ALIASES

# Create the statistics directory
if [ -d $STAT_DIR ]; then
    echo &quot;Statistics dir already exist&quot;
else
    mkdir $STAT_DIR
fi

# Create the virtual host awstats.conf
cat /etc/awstats/awstats.model.conf | \
sed -e &quot;s/\\\$DOMAIN/$DOMAIN/g&quot; | \
sed -e &quot;s/\\\$USERNAME/$WUSERNAME/g&quot; | \
sed -e &quot;s/\\\$ALIASES/$ALIASES/g&quot; &gt; \
&quot;/etc/awstats/awstats.$DOMAIN.conf&quot;

# Add user/password to password file
if [ -e $ACCESS_FILE ]; then
    /usr/bin/htpasswd -bm $ACCESS_FILE $WUSERNAME $PASSWORD
else
    /usr/bin/htpasswd -bm -c $ACCESS_FILE $WUSERNAME $PASSWORD
fi
</pre>
<p>The &quot;username&quot; requested is the name found in the <tt class="docutils literal"><span class="pre">/home/httpd</span></tt> directory for which you want to create the site.  This will also be the username needed to login (via Apache authentication) to view the stats.  The &quot;password&quot; then requested is for that same Apache authentication (will be stored in <tt class="docutils literal"><span class="pre">/etc/awstats/awstat.pwd</span></tt>).  The &quot;main domain&quot; is what people
use to access the site, (e.g., www.DOMAIN.com), but you&#8217;ll also then be asked to include any subdomains that log to the same Apache log file (at least if you want AWStats to process them).</p>
<p>After the setup is complete, you can check out your stats by going to: <a class="reference" href="http://www.DOMAIN.com/awstats/awstats.pl">http://www.DOMAIN.com/awstats/awstats.pl</a></p>
<p>AWStats knows which config file (automatically generated) it needs by reading the domain from the URL, but you can also view other domains by appending &quot;?config=www.whatever.com&quot; to the URL.  That config file is left in <tt class="docutils literal"><span class="pre">/etc/awstats</span></tt>, and the individual AWStats DB file that results from processing the logs is left in each user&#8217;s directory in <tt class="docutils literal"><span class="pre">/home/httpd/DOMAIN/awstats</span></tt></p>
<p>While each user will be able to HTTP-authenticate against any other user&#8217;s domain, the values in the <tt class="docutils literal"><span class="pre">AllowAccessToWebToFollowingUsers</span></tt> variable will prevent users from being able to view one another&#8217;s stats.</p>
<p>Finally, note that your AWStats installation may have included a cron task to update the AWStats data in <tt class="docutils literal"><span class="pre">/etc/cron/hourly</span></tt> or other.  In any case, you&#8217;ll want AWStats to automatically process your logs on an at least daily basis via the included script <tt class="docutils literal"><span class="pre">/usr/share/awstats/tools/awstats_updateall.pl</span></tt>.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.mattdorn.com/content/automating-awstats-configuration-for-multiple-domains/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Gnapsack 0.1.0 released</title>
		<link>http://www.mattdorn.com/content/gnapsack-010-released/</link>
		<comments>http://www.mattdorn.com/content/gnapsack-010-released/#comments</comments>
		<pubDate>Fri, 28 Apr 2006 18:51:29 +0000</pubDate>
		<dc:creator>mdorn</dc:creator>
		
		<category><![CDATA[open source]]></category>

		<category><![CDATA[software]]></category>

		<category><![CDATA[technology]]></category>

		<category><![CDATA[web services]]></category>

		<guid isPermaLink="false">http://67.207.132.145/wordpress/?p=33</guid>
		<description><![CDATA[


I have just released Gnapsack, a desktop client for Linux that uses the Backpack API.  Check out the site for info, screenshots, etc.  This is an open source (GPL) project.
While it only runs on Linux currently, I&#8217;m hoping to get someone to help me out with a Windows port.  It uses the [...]]]></description>
			<content:encoded><![CDATA[
<div class="document">
<!-- -*- mode: rst -*- -->
<p>I have just released <a class="reference" href="http://www.mattdorn.com/open/gnapsack">Gnapsack</a>, a desktop client for Linux that uses the Backpack API.  Check out the site for info, screenshots, etc.  This is an open source (GPL) project.</p>
<p>While it only runs on Linux currently, I&#8217;m hoping to get someone to help me out with a Windows port.  It uses the Python bindings to the GTK widget set.  A good example of a PyGTK app that has been ported to Windows is the <a class="reference" href="http://griffith.vasconunes.net/">Griffith</a> film collection manager.</p>
<p>I may unwittingly be using some non-standard Python libraries&#8211;if any Linux users can give it a try and let me know if I should add items to the dependencies list, I&#8217;d appreciate it.</p>
<p>Anyone interesting in contributing to this project in general, please let me know, and I&#8217;ll get you oriented.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.mattdorn.com/content/gnapsack-010-released/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
