<?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>klenwell press</title>
	<atom:link href="http://www.klenwell.com/press/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.klenwell.com/press</link>
	<description>A Developer's Broadsheet</description>
	<lastBuildDate>Tue, 09 Feb 2010 04:08:21 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>ReCaptcha Plugin Added</title>
		<link>http://www.klenwell.com/press/2010/02/recaptcha-added/</link>
		<comments>http://www.klenwell.com/press/2010/02/recaptcha-added/#comments</comments>
		<pubDate>Tue, 09 Feb 2010 03:28:54 +0000</pubDate>
		<dc:creator>klenwell</dc:creator>
				<category><![CDATA[Miscellany]]></category>
		<category><![CDATA[wp]]></category>

		<guid isPermaLink="false">http://www.klenwell.com/press/?p=156</guid>
		<description><![CDATA[First off, let me apologize to all those who have commented in the recent weeks and had their comments held up in moderation limbo.  With all the spam I was getting, I got bad about procrasting on moderating comments.  Now with this new plugin, hopefully I can relax the moderation and, when moderation, [...]]]></description>
			<content:encoded><![CDATA[<p>First off, let me apologize to all those who have commented in the recent weeks and had their comments held up in moderation limbo.  With all the spam I was getting, I got bad about procrasting on moderating comments.  Now with this new plugin, hopefully I can relax the moderation and, when moderation, get to approving comments more quickly.</p>
<p>Next, this plugin should come standard issue with WordPress.  I know the keys are a bit of a hassle.  But WordPress should offer something out or the box, because the amount of spam I get through the comment forms on this site is demoralizing.</p>
<p>Anyway, easy to install and well worth the effort, I hope.  Find reCAPTCHA installation notes here:</p>
<p><a href="http://wordpress.org/extend/plugins/wp-recaptcha/installation/">http://wordpress.org/extend/plugins/wp-recaptcha/installation/</a></p>
<p>Now, let&#8217;s see if this thing works.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.klenwell.com/press/2010/02/recaptcha-added/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CakePHP Query Method Does Support Bind Parameters</title>
		<link>http://www.klenwell.com/press/2009/10/cakephp-query-bind-parameters/</link>
		<comments>http://www.klenwell.com/press/2009/10/cakephp-query-bind-parameters/#comments</comments>
		<pubDate>Mon, 26 Oct 2009 22:13:02 +0000</pubDate>
		<dc:creator>klenwell</dc:creator>
				<category><![CDATA[Failsafety]]></category>
		<category><![CDATA[cakephp]]></category>

		<guid isPermaLink="false">http://www.klenwell.com/press/?p=153</guid>
		<description><![CDATA[Just came across a post from a few months ago where I stated that CakePhp doesn&#8217;t support bind parameters.  I have learned since then that this is not true.  Happily, it does support bind parameters.  An example I have used successfully:

    function query_bottom_count($bottom_value, $start_uts, $end_uts)
    {
 [...]]]></description>
			<content:encoded><![CDATA[<p>Just came across <a href="http://www.klenwell.com/press/2009/01/cakephp-custom-pagination/">a post from a few months ago</a> where I stated that CakePhp doesn&#8217;t support bind parameters.  I have learned since then that this is not true.  Happily, it does support bind parameters.  An example I have used successfully:</p>
<pre class="syntax-highlight:php">
    function query_bottom_count($bottom_value, $start_uts, $end_uts)
    {
        $sql = &lt;&lt;&lt;XSQL
SELECT
    REPLACE( SUBSTRING_INDEX( SUBSTRING_INDEX( last_result_url,
        &#039;://&#039;, -1 ) , &#039;/&#039;, 1 ) , &#039;www.&#039;, &#039;&#039; ) AS domain,
    COUNT( REPLACE( SUBSTRING_INDEX( SUBSTRING_INDEX( last_result_url, &#039;://&#039;, -1 ) ,
        &#039;/&#039;, 1 ) , &#039;www.&#039;, &#039;&#039; ) ) AS hits
FROM queries as Query
WHERE insert_uts &gt;= ?
AND insert_uts &lt; ?
GROUP BY domain HAVING hits = ?;
XSQL;

        $ParamList = array($start_uts, $end_uts, $bottom_value);
        $Data = $this-&gt;query($sql, $ParamList);
        if ( !$Data ) return 0;
        return count($Data);
    }
</pre>
<p>Just setting the record straight.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.klenwell.com/press/2009/10/cakephp-query-bind-parameters/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Advance Model Testing in CakePhp</title>
		<link>http://www.klenwell.com/press/2009/09/model-testing-cakephp/</link>
		<comments>http://www.klenwell.com/press/2009/09/model-testing-cakephp/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 05:23:50 +0000</pubDate>
		<dc:creator>klenwell</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[cakephp]]></category>

		<guid isPermaLink="false">http://www.klenwell.com/press/?p=145</guid>
		<description><![CDATA[One of the most challenging issues I&#8217;ve found in developing with CakePhp is unit testing.  Testing models, with its dependence on fixtures, is especially touchy.  The documentation, while constantly improving, still seems at crucial points incomplete or inconsistent.  In this post, I&#8217;d like to draw attention to a few pitfalls that I [...]]]></description>
			<content:encoded><![CDATA[<p>One of the most challenging issues I&#8217;ve found in developing with CakePhp is unit testing.  Testing models, with its dependence on fixtures, is especially touchy.  The documentation, while constantly improving, still seems at crucial points incomplete or inconsistent.  In this post, I&#8217;d like to draw attention to a few pitfalls that I burned a few brain cycles in overcoming and offer some tips for unit testing models with fixtures.</p>
<h4>Cake Core Bugs</h4>
<p>There are a couple documented bugs that still outstanding as of release 1.2.4.8284.  If you are doing anything more than basic testing, one of these could bite you eventually:</p>
<p><a onclick="window.open(this.href,'_blank');return false;" href="https://trac.cakephp.org/ticket/6205">https://trac.cakephp.org/ticket/6205</a><br />
<a onclick="window.open(this.href,'_blank');return false;" href="https://trac.cakephp.org/ticket/6468">https://trac.cakephp.org/ticket/6468</a></p>
<p>Here is a patch file that fixes them:</p>
<pre class="syntax-highlight:php">
# Fix issues with CakePhp model unit tests
# Tom at klenwell@gmail.com
# CakePhp Version: 1.2.4.8284

diff -r ead5d3b62da7 -r df04a99fec1b cake/libs/model/datasources/dbo_source.php
--- a/cake/libs/model/datasources/dbo_source.php	Mon Aug 10 21:16:09 2009 -0700
+++ b/cake/libs/model/datasources/dbo_source.php	Mon Sep 14 21:08:12 2009 -0700
@@ -2355,6 +2355,15 @@ class DboSource extends DataSource {
 			$column[&#039;default&#039;] = null;
 		}

+                // solves fixture problem
+                // see https://trac.cakephp.org/ticket/6205
+                if (($column[&#039;type&#039;] == &#039;datetime&#039; || $column[&#039;type&#039;] == &#039;timestamp&#039; ) &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; isset($column[&#039;default&#039;]) &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; $column[&#039;default&#039;] === &#039;&#039;) {
+                    $column[&#039;default&#039;] = null;
+                }
+                if ( $column[&#039;type&#039;] == &#039;timestamp&#039; &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; $column[&#039;default&#039;] === &#039;CURRENT_TIMESTAMP&#039; )
+                    #pr($column);
+                    $column[&#039;default&#039;] = null;
+
 		if (isset($column[&#039;key&#039;]) &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; $column[&#039;key&#039;] == &#039;primary&#039; &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; $type == &#039;integer&#039;) {
 			$out .= &#039; &#039; . $this-&amp;amp;amp;gt;columns[&#039;primary_key&#039;][&#039;name&#039;];
 		} elseif (isset($column[&#039;key&#039;]) &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; $column[&#039;key&#039;] == &#039;primary&#039;) {
@@ -2455,4 +2464,4 @@ class DboSource extends DataSource {
 		return &#039;string&#039;;
 	}
 }
-?&amp;amp;amp;gt;
\ No newline at end of file
+?&amp;amp;amp;gt;

diff -r ead5d3b62da7 -r df04a99fec1b cake/tests/lib/cake_test_fixture.php
--- a/cake/tests/lib/cake_test_fixture.php	Mon Aug 10 21:16:09 2009 -0700
+++ b/cake/tests/lib/cake_test_fixture.php	Mon Sep 14 21:08:12 2009 -0700
@@ -114,7 +114,12 @@ class CakeTestFixture extends Object {
 			}
 		}

-		if (!isset($this-&amp;amp;amp;gt;table)) {
+                // solves HABTM problem
+                // see https://trac.cakephp.org/ticket/6468
+                if (isset($model-&amp;amp;amp;gt;table)) {
+                        $this-&amp;amp;amp;gt;table = $model-&amp;amp;amp;gt;table;
+                }
+                elseif (!isset($this-&amp;amp;amp;gt;table)) {
 			$this-&amp;amp;amp;gt;table = Inflector::underscore(Inflector::pluralize($this-&amp;amp;amp;gt;name));
 		}

@@ -190,4 +195,4 @@ class CakeTestFixture extends Object {
 		return $return;
 	}
 }
-?&amp;amp;amp;gt;
\ No newline at end of file
+?&amp;amp;amp;gt;
</pre>
<h4>Fixtures</h4>
<p>The design and usage of fixtures still seems fickle.  For instance, the CakePhp docs and packaged test examples promote the explicit declaration of fields in fixtures.  I find this tedious.  Happily, it is also unnecessary, thanks to the import property.</p>
<p>To avoid this nuisance, use the import &#8216;model&#8217; or &#8216;table&#8217; setting to automatically load the table schema from the existing database.  See the example here:</p>
<p><a onclick="window.open(this.href,'_blank');return false;" href="http://code.google.com/p/cakewell/source/browse/app/tests/fixtures/simple_record_fixture.php">simple_record_fixture.php</a></p>
<p>A couple other tips for using fixtures:</p>
<p>1. Import all fixtures associated with a model in the unit test for that model<br />
2. If unit testing a plugin, the value in the fixtures property takes this format: <tt>plugin.$plugin_name.$model_name</tt><br />
3. Don&#8217;t forget to set up an empty database and include a test_suite setting in your database configuration file.</p>
<p>See these links for additional insight:<br />
<a onclick="window.open(this.href,'_blank');return false;" href="http://code.google.com/p/cakewell/source/browse/app/config/database.php.default">Cakewell Database Config File</a><br />
<a href="http://code.google.com/p/cakewell/source/browse/app/plugins/authwell/tests/cases/models/authwell_user.test.php" onclick="window.open(this.href,'_blank');return false;">Model Test with Fixtures</a><br />
<a onclick="window.open(this.href,'_blank');return false;" href="https://trac.cakephp.org/browser/trunk/cake/1.2.x.x/cake/tests/lib/cake_test_fixture.php">CakePhp cake_test_fixture.php</a></p>
<h4>HABTM Relationships</h4>
<p>To test models that have HABTM relationships with other models, it is necessary to create fixtures for both models having the HABTM relationship <em>and</em> a fixture to build the join table.  See these files from the Cakewell project for examples:</p>
<p><a onclick="window.open(this.href,'_blank');return false;" href="http://code.google.com/p/cakewell/source/browse/app/plugins/authwell/tests/fixtures/authwell_user_authwell_role_fixture.php">Authwell User-Role HABTM Fixture</a><br />
<a onclick="window.open(this.href,'_blank');return false;" href="http://code.google.com/p/cakewell/source/browse/app/plugins/authwell/tests/fixtures/authwell_role_authwell_privilege_fixture.php">Authwell Role-Privilege HABTM Fixture</a></p>
<p>The Cakewell Authwell plugin include a good example of a complex model unit test that is successfully configured.  It includes tests within the plugin directory that autoload a clean test database and successfully test models with HABTM associations.  The source can be found here:</p>
<p><a onclick="window.open(this.href,'_blank');return false;" href="http://code.google.com/p/cakewell/source/browse/#hg/app/plugins/authwell/tests">Authwell Plugin Test Directory</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.klenwell.com/press/2009/09/model-testing-cakephp/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Wordpress Upgrade</title>
		<link>http://www.klenwell.com/press/2009/09/wordpress-upgrade/</link>
		<comments>http://www.klenwell.com/press/2009/09/wordpress-upgrade/#comments</comments>
		<pubDate>Sun, 06 Sep 2009 17:44:19 +0000</pubDate>
		<dc:creator>klenwell</dc:creator>
				<category><![CDATA[Failsafety]]></category>
		<category><![CDATA[wp]]></category>

		<guid isPermaLink="false">http://www.klenwell.com/press/?p=142</guid>
		<description><![CDATA[After reading this alarming post on slashdot, and coming across similar reports on reddit and elsewhere, I decided it was time to bite the bullet and upgrade.  I did it the long, manual way.  Not as tough as helping your sister move.  But it still took about an hour to complete.
This post [...]]]></description>
			<content:encoded><![CDATA[<p>After reading <a href="http://developers.slashdot.org/story/09/09/05/2210237/Wordpressorg-Warns-of-Active-Worm-Hacking-Blogs" onclick="window.open(this.href,'_blank');return false;">this alarming post on slashdot</a>, and coming across similar reports on reddit and elsewhere, I decided it was time to bite the bullet and upgrade.  I did it <a href="http://codex.wordpress.org/Upgrading_WordPress_Extended" onclick="window.open(this.href,'_blank');return false;">the long, manual way</a>.  Not as tough as helping your sister move.  But it still took about an hour to complete.</p>
<p>This post is mainly just to insure that everything is working correctly.  More sporadic posting to follow.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.klenwell.com/press/2009/09/wordpress-upgrade/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Project Cakewell</title>
		<link>http://www.klenwell.com/press/2009/08/project-cakewell/</link>
		<comments>http://www.klenwell.com/press/2009/08/project-cakewell/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 03:21:33 +0000</pubDate>
		<dc:creator>klenwell</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[cakephp]]></category>

		<guid isPermaLink="false">http://www.klenwell.com/press/?p=137</guid>
		<description><![CDATA[Project Cakewell is a CakePhp prototype application.  Its main purpose is to document and demonstrate useful concepts and features of a web application built with the CakePhp framework.  These include things like unit testing a component, creating a working fixture , and configuring your application to automatically detect the server environment and set [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://cakewell.klenwell.com/" onclick="window.open(this.href,'_blank');return false;">Project Cakewell</a> is a <a href="http://cakephp.org/" onclick="window.open(this.href,'_blank');return false;">CakePhp</a> prototype application.  Its main purpose is to document and demonstrate useful concepts and features of a web application built with <a href="http://book.cakephp.org/view/13/Basic-Principles-of-CakePHP" onclick="window.open(this.href,'_blank');return false;">the CakePhp framework</a>.  These include things like unit testing a component, creating a working fixture , and configuring your application to automatically detect the server environment and set the debug level accordingly.</p>
<p>The code is open source and available at the Cakewell Google Code site at:</p>
<p><a href="http://code.google.com/p/cakewell/" onclick="window.open(this.href,'_blank');return false;">http://code.google.com/p/cakewell/</a></p>
<p>The live demo can be found at:</p>
<p><a href="http://cakewell.klenwell.com/ onclick="window.open(this.href,'_blank');return false;"">http://cakewell.klenwell.com/</a></p>
<p>I&#8217;ll add updates here as I progress.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.klenwell.com/press/2009/08/project-cakewell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Greqo 4 Released</title>
		<link>http://www.klenwell.com/press/2009/06/greqo-4-released/</link>
		<comments>http://www.klenwell.com/press/2009/06/greqo-4-released/#comments</comments>
		<pubDate>Sat, 13 Jun 2009 20:10:52 +0000</pubDate>
		<dc:creator>klenwell</dc:creator>
				<category><![CDATA[Miscellany]]></category>

		<guid isPermaLink="false">http://www.klenwell.com/press/?p=135</guid>
		<description><![CDATA[Greqo is a PHP project I started a couple years back for Google&#8217;s services.  It was an extension of a Blogger API I had written in PHP.  I extended it to include Gmail and Google Analytics.  I took some time this year to clean it up and recently released Greqo 4.  [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://code.google.com/p/greqo/">Greqo</a> is a PHP project I started a couple years back for Google&#8217;s services.  It was an extension of a Blogger API I had written in PHP.  I extended it to include Gmail and Google Analytics.  I took some time this year to clean it up and recently released <a href="http://code.google.com/p/greqo/downloads/list">Greqo 4</a>.  It&#8217;s not really the 4th version.  More like the 2nd.  The 4 signifies full compatability with PHP 4.</p>
<p>For more information on usage, I recommend the <a href="http://greqo.googlecode.com/svn/tags/v4.0/test/">unit and acceptance tests<a href="http://phpmailer.codeworxtech.com/"></a> that come packaged with the source code.</p>
<p>There are probably better PHP libraries for Google&#8217;s Data APIs (e.g. <a href="http://framework.zend.com/manual/en/zend.gdata.html">the Zend Framework</a>.)  </a>PHPMailer, upon which my Gmail library was built, <a href="http://phpmailer.codeworxtech.com/index.php?pg=examplebgmail">now supports Gmail</a> natively.  <a href="http://code.google.com/apis/analytics/">Google Analytics</a> now has an <a href="http://code.google.com/apis/analytics/docs/gdata/gdataDeveloperGuide.html">export API</a>.  And PHP 4, of course, has reached the <a href="http://developers.slashdot.org/article.pl?sid=07/07/14/0646216">end of its life</a>.</p>
<p>But Greqo 4 runs on PHP 5.  And if you need a PHP 4 implementation of these Google APIs, well then here you are:</p>
<p><a href="http://code.google.com/p/greqo/downloads/detail?name=greqo-lib-v4.0.zip&#038;can=2">Download: Greqo 4 Release for Google Mail, Blogger, and Analytics</a></p>
<p>Going forward, the Greqo library will abandon complete PHP 4 compatibility and focus on PHP 5 and, eventually, PHP 6.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.klenwell.com/press/2009/06/greqo-4-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FormEncode (Pylons): What Is State?</title>
		<link>http://www.klenwell.com/press/2009/04/formencode-state/</link>
		<comments>http://www.klenwell.com/press/2009/04/formencode-state/#comments</comments>
		<pubDate>Sat, 11 Apr 2009 18:43:45 +0000</pubDate>
		<dc:creator>klenwell</dc:creator>
				<category><![CDATA[Code Case]]></category>
		<category><![CDATA[pylons]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.klenwell.com/press/?p=131</guid>
		<description><![CDATA[If you're using <a href="http://pylonshq.com/">Pylons</a>, the Python framework, you're probably using <a href="http://formencode.org/">FormEncode</a>.  And if you're using FormEncode, you've probably have noticed, and blithely ignored, the state argument that's the last argument to a number of the validator class methods.

So what is state and why would you want to use it?]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re using <a href="http://pylonshq.com/">Pylons</a>, the Python framework, you&#8217;re probably using <a href="http://formencode.org/">FormEncode</a>.  And if you&#8217;re using FormEncode, you&#8217;ve probably have noticed, and blithely ignored, the state argument that&#8217;s the last argument to a number of the validator class methods.</p>
<p>This is the official FormEncode explanation of state:</p>
<blockquote><p>All the validators receive a magic, somewhat meaningless state argument (which defaults to None). It&#8217;s used for very little in the validation system as distributed, but is primarily intended to be an object you can use to hook your validator into the context of the larger system.</p>
<p>For instance, imagine a validator that checks that a user is permitted access to some resource. How will the validator know which user is logged in? State! Imagine you are localizing it, how will the validator know the locale? State! Whatever else you need to pass in, just put it in the state object as an attribute, then look for that attribute in your validator.</p></blockquote>
<p>Hmmm.  Maybe an example would help.  Here&#8217;s the best example of its usage I could find on <a href="http://wiki.pylonshq.com/display/pylonscookbook/The+other+FormEncode+manual+%28UNFINISHED%29">the Pylons site</a>:</p>
<pre class="syntax-highlight:python">
  this_schema = TheAppropriateSchema()
  try:
    state = dict() # this won&#039;t actually work. you&#039;ll need an object that formencode can hang things on.
    state[&quot;useful_state_information&quot;] = something_useful
    form_result = this_schema.to_python(postvars, state)

    # validation is successful - form_result contains good data for you to consume

    redirect_to(&quot;somewhere&quot;)

  except Invalid, e:
    defaults = request.params
    errors = e.error_dict
    unfilled_html = a_function_that_draws_your_form_page_html()
    filled_html = htmlfill.render(unfilled_html, defaults, errors)
    return filled_html
</pre>
<p>Notice the comment: <strong># this won&#8217;t actually work.</strong>  Thanks for the warning.</p>
<p>So what is state and why would you want to use it?</p>
<p>Let&#8217;s answer the second question first, because at work, where we&#8217;re using the Pylons framework, I came up with an excellent situation which helped me figure out what it is and why I would want to use it.</p>
<p>The situation, briefly: our application has two separate forms.  One is a form where a user can add new records in a multi-row table form.  Each row is an individual record.  The second is a review form, which looks just like the new record form, but is filled in from data uploaded in csv file (from another form).</p>
<p>Since DRY is a guiding principle of development in my office, the goal is to use the same underlying code for the form, controller, validation, etc.  But the problem is that data originate in two different formats: one is as POST data from the add form, the second as the contents of a csv file.  So how can we normalize these two data formats so that we can use the same underlying code? All together now: <strong>State!</strong>  Now you&#8217;re talking!</p>
<p>If we could just tell our FormEncode validator where the data was coming from, then we could create two separate normalization methods in our validation class that would transform the data into a form that the validator and template could deal with.  Anyway, enough verbiage.  Find below a representative generalized version of the FormEncode validator I created and the controller it&#8217;s used in.</p>
<p>One more note before I finish.  Notice the FormencodeState object comment. That explains why the example from the Pylons wiki does not work (in most cases).  My first impulse would be to use a dict, too, as the state object.  But the internals of the FormEncode validator class require an object.  This is what gets passed in the validator method state argument and it is what passes info from the general framework environment to the validator.</p>
<h4>Pylons Controller Code (with State Object)</h4>
<pre class="syntax-highlight:python">
class FormencodeState(object):
    &quot;&quot;&quot;
    State class for formencode
    Although NOT well documented, to use the state argument in the to_python
    method in the context of schema that does complex, multistep validation,
    the state argument must be an object that formencode can hang additional
    attributes from, else you get errors like:
    Module formencode.schema:114 in _to_python
    &gt;&gt;  state.full_dict = value_dict
    &lt;type &#039;exceptions.AttributeError&#039;&gt;: &#039;dict&#039; object has no attribute &#039;full_dict&#039;
    &quot;&quot;&quot;
    pass

# ... within actual Controller class method
Validator = SourceDataPreValidator()
ControllerState = FormencodeState()
ControllerState.source = &#039;csv&#039;
Validator.to_python(DataValue, ControllerState)     # &lt;- state object in action!
</pre>
<h4>FormEncode Validator Code</h4>
<pre class="syntax-highlight:python">
class SourceDataPreValidator(formencode.validators.FormValidator):
    &quot;&quot;&quot;normalize data from either a form submission or a csv file upload and validate&quot;&quot;&quot;
    validate_partial_form = True
    def _to_python(self, value, state):
        &quot;&quot;&quot;normalize csv input&quot;&quot;&quot;
        if state.source == &#039;csv&#039;:
            value[&#039;normal_data&#039;] = self._normalize_csv_data(value.get(&#039;csv_import_file&#039;), state)
        elif state.source == &#039;form&#039;:
            pass
        return value

    def _normalize_import_data(self, csv_file_string, state):
        NormalDataList = []
        ImportedLines = csv_file_string.split(&#039;\n&#039;)
        for i in range(len(ImportedLines)):
            ColValues = ImportedLines[i].split(&#039;,&#039;)
            fpre = &#039;csv_import-&#039; + str(i)
            NormalDataList.append((fpre + &#039;.id&#039;, str(ColValues[1])))
            NormalDataList.append((fpre + &#039;.amount&#039;, str(ColValues[2])))
            NormalDataList.append((fpre + &#039;.date&#039;,
                self._importdate_to_python_date(ColValues[4])))
        return NormalDataList

    def _importdate_to_python_date(self, datestr):
        &quot;&quot;&quot;some code to convert a date string to object&quot;&quot;&quot;
        pass
</pre>
<p>I hope that sheds a little light on this powerful mystery.  Questions or comments welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.klenwell.com/press/2009/04/formencode-state/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Comparing Big Numbers in PHP</title>
		<link>http://www.klenwell.com/press/2009/03/comparing-big-numbers-in-php/</link>
		<comments>http://www.klenwell.com/press/2009/03/comparing-big-numbers-in-php/#comments</comments>
		<pubDate>Sat, 14 Mar 2009 17:49:53 +0000</pubDate>
		<dc:creator>klenwell</dc:creator>
				<category><![CDATA[Code Case]]></category>

		<guid isPermaLink="false">http://www.klenwell.com/press/?p=122</guid>
		<description><![CDATA[Problem
What if I need to compare really big numbers in PHP?  Like comparing 2^66 &#62; 3^53?
Overview
This will work:

print (int) (pow(2,66) &#62; pow(3,53));

PHP will convert the integers to scientific notation.  But this script illustrates the limitation of normal operational syntax (i.e.: pow(2,66) &#62; pow(3,53) vs. bccomp(bcpow(2,66), bcpow(3,53),1) &#62; 0):

$max = 1000;
foreach ( range(1,$max) as [...]]]></description>
			<content:encoded><![CDATA[<h4>Problem</h4>
<p>What if I need to compare really big numbers in PHP?  Like comparing 2^66 &gt; 3^53?</p>
<h4>Overview</h4>
<p>This will work:</p>
<pre class="syntax-highlight:php">
print (int) (pow(2,66) &gt; pow(3,53));
</pre>
<p>PHP will convert the integers to scientific notation.  But this script illustrates the limitation of normal operational syntax (i.e.: <tt>pow(2,66) &gt; pow(3,53)</tt> vs. <tt>bccomp(bcpow(2,66), bcpow(3,53),1) &gt; 0</tt>):</p>
<pre class="syntax-highlight:php">
$max = 1000;
foreach ( range(1,$max) as $x )
{
    if (
        ! ( pow(2,$x)+1 &gt; pow(2,$x) ) ||
        ! ( pow(2,$x)-1 &lt; pow(2,$x) ) ||
        ! ( pow(2,$x-1)*2 == pow(2,$x) )
    ) break;
}

$maxpow = $x-1;
$maxint = bcpow(2, $maxpow);
$Result[&#039;op&#039;] = &quot;max supported int: 2^$maxpow or $maxint\n&quot;;

foreach ( range(1,$max) as $x )
{
    if (
        ! ( bccomp(bcadd(bcpow(2,$x),1), bcpow(2,$x)) == 1 ) ||
        ! ( bccomp(bcsub(bcpow(2,$x),1), bcpow(2,$x)) == -1 ) ||
        ! ( bccomp(bcmul(bcpow(2,$x-1),2), bcpow(2,$x)) == 0 )
    ) break;
}

$maxpow = $x-1;
$maxint = bcpow(2, $maxpow);
$Result[&#039;bc&#039;] = &quot;max supported int &gt;= 2^$maxpow or $maxint\n&quot;;

printf(&quot;&lt;pre&gt;%s&lt;/pre&gt;&quot;, print_r($Result,1));
</pre>
<h4>Solution</h4>
<p>Use bccomp.  The script above can be found on the klenwell code site:</p>
<p><a href="http://code.google.com/p/klenwell/source/browse/trunk/pastebin/bc_demo.php">http://code.google.com/p/klenwell/source/browse/trunk/pastebin/bc_demo.php</a></p>
<p>Results will vary depending on the processing capacity of the system.  Here&#8217;s the results on my machine:</p>
<div class="code">
Array<br />
(<br />
	[op] => max supported int: 2^52 or 4503599627370496</p>
<p>	[bc] => max supported int >= 2^999 or 5357543035931336604742125245300009052807024058527668037218751941851755255624680612465991894078479290637973364587765734125935726428461570217992288787349287401967283887412115492710537302531185570938977091076523237491790970633699383779582771973038531457285598238843271083830214915826312193418602834034688<br />
)
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.klenwell.com/press/2009/03/comparing-big-numbers-in-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Command Line Email on Ubuntu (mailx version)</title>
		<link>http://www.klenwell.com/press/2009/03/ubuntu-email-with-mailx/</link>
		<comments>http://www.klenwell.com/press/2009/03/ubuntu-email-with-mailx/#comments</comments>
		<pubDate>Wed, 04 Mar 2009 04:53:15 +0000</pubDate>
		<dc:creator>klenwell</dc:creator>
				<category><![CDATA[Miscellany]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.klenwell.com/press/?p=114</guid>
		<description><![CDATA[This guide explains how to configure Ubuntu so that you can send email from the command line using mailx with your Gmail account for delivery.  This updates a guide I originally posted on the ubuntu forums for mailx, which is part of the current Ubuntu repositories (versions 7 and 8).  To use nail, [...]]]></description>
			<content:encoded><![CDATA[<p>This guide explains how to configure Ubuntu so that you can send email from the command line using mailx with your Gmail account for delivery.  This updates a guide I originally posted on the <a href="http://ubuntuforums.org/showthread.php?t=780509">ubuntu forums</a> for mailx, which is part of the current Ubuntu repositories (versions 7 and 8).  To use nail, for which this guide was originally drawn up, see <a href="http://www.klenwell.com/press/2009/03/ubuntu-email-with-nail/">this post</a>.</p>
<h4>In 5 Fairly Easy Steps</h4>
<p><strong>1. Install the needed programs</strong></p>
<div class="code">$ sudo apt-get install msmtp<br />
$ sudo apt-get install mailx</div>
<p><strong>2. Install Thawte certificates for Gmail</strong></p>
<p><strong>EDIT: verisign.com apparently no longer issues certs at the address below.  So the &#8216;wget&#8217; step will not work.</strong> adkein, in a comment below (<a href="#comment-146">click here</a>), links to another page when you can apparently get the needed cert.  I cannot vouch for this as my cert still works.  But you might try downloading that and putting it your ~/etc/.certs directory if you&#8217;re having issues finding the cert.</p>
<p>This is necessary for Gmail. (Thanks to <a href="http://laurentbois.com/2007/10/20/activemailer-using-msmtp-and-gmail/">laurentbois.com</a>.)</p>
<div class="code">$ mkdir -p ~/etc/.certs<br />
$ chmod 0700 ~/etc/.certs<br />
$ cd ~/etc/.certs<br />
$ wget https://www.verisign.com/support/thawte-roots.zip &#8211;no-check-certificate<br />
$ unzip thawte-roots.zip<br />
$ cp &#8216;Thawte Server Roots/ThawtePremiumServerCA_b64.txt&#8217; ThawtePremiumServerCA.crt</div>
<p><strong>3. Configure msmtp</strong><br />
This will open up a new msmtp configuration file</p>
<div class="code">$ gedit ~/.msmtprc</div>
<p>Copy the following lines. Replace UPPERCASE text with your personal settings:</p>
<pre class="syntax-highlight:bash">
# config options: http://msmtp.sourceforge.net/doc/msmtp.html#A-user-configuration-file
defaults
logfile /tmp/msmtp.log

# gmail account
#account gmail
auth on
host smtp.gmail.com
port 587
user YOURNAME@gmail.com
password YOURPASSWORD
from YOURNAME@gmail.com
tls on
tls_trust_file /home/USER/etc/.certs/ThawtePremiumServerCA.crt

# set default account to use (not necessary with single account)
#account default : gmail
</pre>
<p>Change permission on this file or msmtp will complain:</p>
<div class="code">$ chmod 600 ~/.msmtprc</div>
<p><strong>4. Configure mailx</strong></p>
<div class="code">$ gedit ~/.mailrc</div>
<p>Copy the following lines and replace UPPERCASE text with your personal settings:</p>
<pre class="syntax-highlight:bash">
# set smtp for nail
# ref: http://ubuntuforums.org/showpost.php?p=4531994&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;postcount=6

# gmail account (default)
# $ mailx -s &quot;subject line&quot; -a /path/file recipient@email.com &lt; /path/body.txt
set from=&quot;YOURNAME@gmail.com (YOURNAME)&quot;
set sendmail=&quot;/usr/bin/msmtp&quot;
set message-sendmail-extra-arguments=&quot;-a gmail&quot;
</pre>
<p><strong>5. Run a test</strong><br />
Send a test message to <a href="https://gmail.google.com/gmail">your gmail account</a>:</p>
<div class="code">$ echo -e &#8220;testing email from the command line&#8221; &gt; /tmp/test_email<br />
$ mailx -s &#8220;nail gmail test&#8221; YOURNAME@gmail.com &lt; /tmp/test_email</div>
<p>Check your gmail account and you should have a message from yourself.  You can also check your log:</p>
<div class="code">$ gedit /tmp/msmtp.log</div>
<p>I personally prefer <a href="http://www.klenwell.com/press/2009/03/ubuntu-email-with-nail/">nail</a> because it more easily accommodates multiple accounts.  But if you don&#8217;t have a deliberate need to use multiple accounts and are using a later version of Ubuntu, use this.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.klenwell.com/press/2009/03/ubuntu-email-with-mailx/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Command Line Email on Ubuntu (nail version)</title>
		<link>http://www.klenwell.com/press/2009/03/ubuntu-email-with-nail/</link>
		<comments>http://www.klenwell.com/press/2009/03/ubuntu-email-with-nail/#comments</comments>
		<pubDate>Tue, 03 Mar 2009 05:39:54 +0000</pubDate>
		<dc:creator>klenwell</dc:creator>
				<category><![CDATA[Miscellany]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.klenwell.com/press/?p=110</guid>
		<description><![CDATA[This will be the first of two posts showing you how to configure the more recent versions of Ubuntu to send email from the command line as simply as humanly possible using your Gmail account for delivery.  These instructions were originally posted on my old blog and on the Ubuntu forums site.
This guide covers [...]]]></description>
			<content:encoded><![CDATA[<p>This will be the first of two posts showing you how to configure the more recent versions of Ubuntu to send email from the command line as simply as humanly possible using your Gmail account for delivery.  These instructions were originally posted on <a href="http://phosphorusandlime.blogspot.com/2008/05/ubuntu-command-line-email.html">my old blog</a> and on the <a href="http://ubuntuforums.org/showthread.php?t=780509">Ubuntu forums site</a>.</p>
<p>This guide covers using the nail program, which is my client of choice but is no longer in the main repositories.  Find a guide for using mailx, which is part of the current Ubuntu repositories, <a href="http://www.klenwell.com/press/2009/03/ubuntu-email-with-mailx/">here</a>.</p>
<h4>In 6 Fairly Easy Steps</h4>
<p><strong>1. Add the breezy repositories containing nail to your source file</strong><br />
Edit your sources list</p>
<div class="code">$ sudo gedit /etc/apt/sources.list</div>
<p>Add the following lines at bottom.  These will enable you to apt-get nail</p>
<pre class="syntax-highlight:bash"># breezy repositories (added to install nail)
# see http://old-releases.ubuntu.com/releases/ for more info
deb http://old-releases.ubuntu.com/ubuntu/ breezy universe</pre>
<p>Don&#8217;t forget to update</p>
<div class="code">$ sudo apt-get update</div>
<p><strong>2. Install the needed programs</strong></p>
<div class="code">$ sudo apt-get install msmtp<br />
$ sudo apt-get install nail</div>
<p><strong>3. Install Thawte certificates for Gmail</strong></p>
<p><strong>EDIT: verisign.com apparently no longer issues certs at the address below.  So the &#8216;wget&#8217; step will not work.</strong> According to <a href="http://www.klenwell.com/press/2009/03/ubuntu-email-with-mailx/#comment-146">this comment</a>, you can downloaded the needed cert from <a href="http://www.cs.utexas.edu/~suriya/UT-wireless/ThawtePremiumServerCA_b64.txt">http://www.cs.utexas.edu/~suriya/UT-wireless/ThawtePremiumServerCA_b64.txt</a>.  I cannot vouch for this as my cert still works.  But you might try downloading that and putting it your ~/etc/.certs directory if you&#8217;re having issues finding the cert.</p>
<p>This is necessary for Gmail. (Thanks to <a href="http://laurentbois.com/2007/10/20/activemailer-using-msmtp-and-gmail/">laurentbois.com</a>.)</p>
<div class="code">$ mkdir -p ~/etc/.certs<br />
$ chmod 0700 ~/etc/.certs<br />
$ cd ~/etc/.certs<br />
$ wget https://www.verisign.com/support/thawte-roots.zip &#8211;no-check-certificate<br />
$ unzip thawte-roots.zip<br />
$ cp Thawte Server Roots/ThawtePremiumServerCA_b64.txt ThawtePremiumServerCA.crt</div>
<p><strong>4. Configure msmtp</strong><br />
This will open up a new msmtp configuration file</p>
<div class="code">$ gedit ~/.msmtprc</div>
<p>Copy the following lines. Replace UPPERCASE text with your personal settings:</p>
<pre class="syntax-highlight:bash">
# config options: http://msmtp.sourceforge.net/doc/msmtp.html#A-user-configuration-file
defaults
logfile /tmp/msmtp.log

# isp account
account isp
auth login
host SMTP.YOURISP.COM
port 25
user YOURNAME@ISP.COM
from YOURNAME@ISP.COM
password YOURPASSWORD

# gmail account
account gmail
auth on
host smtp.gmail.com
port 587
user YOURNAME@gmail.com
password YOURPASSWORD
from YOURNAME@gmail.com
tls on
tls_trust_file /home/USER/etc/.certs/ThawtePremiumServerCA.crt

# set default account to use (from above)
account default : gmail
</pre>
<p>Change permission on this file or msmtp will complain:</p>
<div class="code">$ chmod 600 ~/.msmtprc</div>
<p><strong>5. Configure nail</strong></p>
<div class="code">$ gedit ~/.mailrc</div>
<p>Copy the following lines and replace UPPERCASE text with your personal settings:</p>
<pre class="syntax-highlight:bash">
# set smtp for nail
# ref: http://ubuntuforums.org/showpost.php?p=4531994&amp;amp;amp;amp;amp;amp;postcount=6

# gmail account (default)
# $ nail -s &quot;subject line&quot; -a /path/file recipient@email.com &lt; /path/body.txt
set from=&quot;YOURNAME@gmail.com (YOURNAME)&quot;
set sendmail=&quot;/usr/bin/msmtp&quot;
set message-sendmail-extra-arguments=&quot;-a gmail&quot;

# isp account (add -A option to command line)
# $ nail -A isp -s &quot;subject line&quot; -a /path/file recipient@email.com &lt; /path/body.txt
account isp {
set from=&quot;YOURNAME@ISP.COM&quot;
set sendmail=&quot;/usr/bin/msmtp&quot;
set message-sendmail-extra-arguments=&quot;-a isp&quot;
}
</pre>
<p><strong>6. Run a test</strong><br />
Send a test message to <a href="https://gmail.google.com/gmail">your gmail account</a>:</p>
<div class="code">$ echo -e &#8220;testing email from the command line&#8221; &gt; /tmp/test_email<br />
$ nail -s &#8220;nail gmail test&#8221; YOURNAME@gmail.com &lt; /tmp/test_email</div>
<p>Check your gmail account and you should have a message from yourself.  You can also check your log:</p>
<div class="code">$ gedit /tmp/msmtp.log</div>
<p>That&#8217;s it.  You should now be ready to incorporate email into your bash scripts, which is great for making backups.  I did successfully test this on an old laptop had installed Ubuntu 8.04 this weekend.</p>
<p>If you have any problems or questions, I&#8217;d recommend posting to the <a href="http://ubuntuforums.org/showthread.php?t=780509">ubuntu forums thread</a> as you&#8217;ll probably get a quicker response there.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.klenwell.com/press/2009/03/ubuntu-email-with-nail/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
