<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>More is Different</title>
  <link href="http://morediff.infoindex.xml" rel="self" />
  <link href="http://morediff.info"/>
  <updated>2012-12-09T20:00:19Z</updated>
  <id>http://morediff.infoindex.xml</id>
  <entry><title type="html">FormEncode: (2) Compound Validation</title><author><name>nil</name></author><link href="http://morediff.info/posts/2013/02/05_formencode-2-compound-validation.html"/><updated>2013-02-05T14:15:00Z</updated><published>2013-02-05T14:15:00Z</published><id>posts/2013/02/05_formencode-2-compound-validation.html</id><category scheme="/tags/formencode.html" term="formencode" label="formencode"/><category scheme="/tags/python.html" term="python" label="python"/><content type="html">&lt;p&gt;
Suppose we have a form in which two inputs need to be the same, i.e.: email
matching or password matching.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #bc8383; font-weight: bold;"&gt;import&lt;/span&gt; formencode
&lt;span style="color: #bc8383; font-weight: bold;"&gt;from&lt;/span&gt; formencode &lt;span style="color: #bc8383; font-weight: bold;"&gt;import&lt;/span&gt; validators &lt;span style="color: #bc8383; font-weight: bold;"&gt;as&lt;/span&gt; v


&lt;span style="color: #bc8383; font-weight: bold;"&gt;class&lt;/span&gt; &lt;span style="color: #94bff3;"&gt;Registration&lt;/span&gt;(formencode.Schema):
    &lt;span style="color: #f0dfaf;"&gt;email_input&lt;/span&gt; = v.Email(strip=&lt;span style="color: #9fc59f;"&gt;True&lt;/span&gt;, resolve_domain=&lt;span style="color: #9fc59f;"&gt;True&lt;/span&gt;)
    &lt;span style="color: #f0dfaf;"&gt;email_input_confirm&lt;/span&gt; = v.Email(strip=&lt;span style="color: #9fc59f;"&gt;True&lt;/span&gt;, resolve_domain=&lt;span style="color: #9fc59f;"&gt;True&lt;/span&gt;)
    &lt;span style="color: #f0dfaf;"&gt;chained_validators&lt;/span&gt; = [v.FieldsMatch(&lt;span style="color: #6ca0a3;"&gt;"email_input"&lt;/span&gt;,
                                        &lt;span style="color: #6ca0a3;"&gt;"email_input_confirm"&lt;/span&gt;)]
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
&lt;code&gt;chained_validators&lt;/code&gt; runs after all other validators inside of
&lt;code&gt;Registration&lt;/code&gt; is done. &lt;code&gt;v.FieldsMatch&lt;/code&gt; will verify that the two given
fields match with each other.
&lt;/p&gt;

&lt;p&gt;
If we have a input field which expect a user input a integer in
between 0 and 99. When we get the input in the backend, it's always a
string. Before we need to validate using &lt;code&gt;OneOf&lt;/code&gt;, we need to convert
the input from &lt;code&gt;string&lt;/code&gt; to &lt;code&gt;int&lt;/code&gt; via &lt;code&gt;Int&lt;/code&gt;.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #bc8383; font-weight: bold;"&gt;import&lt;/span&gt; formencode
&lt;span style="color: #bc8383; font-weight: bold;"&gt;from&lt;/span&gt; formencode &lt;span style="color: #bc8383; font-weight: bold;"&gt;import&lt;/span&gt; compound &lt;span style="color: #bc8383; font-weight: bold;"&gt;as&lt;/span&gt; c
&lt;span style="color: #bc8383; font-weight: bold;"&gt;from&lt;/span&gt; formencode &lt;span style="color: #bc8383; font-weight: bold;"&gt;import&lt;/span&gt; validators &lt;span style="color: #bc8383; font-weight: bold;"&gt;as&lt;/span&gt; v


&lt;span style="color: #bc8383; font-weight: bold;"&gt;class&lt;/span&gt; &lt;span style="color: #94bff3;"&gt;Calculator&lt;/span&gt;(formencode.Schema):
    &lt;span style="color: #9fc59f;"&gt;# &lt;/span&gt;&lt;span style="color: #7f9f7f; font-style: italic;"&gt;All validates backwards&lt;/span&gt;
    &lt;span style="color: #f0dfaf;"&gt;numerator&lt;/span&gt; = c.All(v.OneOf(&lt;span style="color: #8cd0d3;"&gt;range&lt;/span&gt;(100)), v.Int())
    &lt;span style="color: #9fc59f;"&gt;# &lt;/span&gt;&lt;span style="color: #7f9f7f; font-style: italic;"&gt;Pipe validates forwards&lt;/span&gt;
    &lt;span style="color: #9fc59f;"&gt;# &lt;/span&gt;&lt;span style="color: #7f9f7f; font-style: italic;"&gt;numerator = c.Pipe(v.Int(), v.OneOf(range(100)))&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
Now suppose we have a form with a group of employees. Each employee
has his/her own first name, last name, email, and phone number. In the
frontend, a user can add a new employee or delete an existing
employee. In another word, we don't know how many employees ahead we
are going to validate. Thus, we can not use Brute-force validation
like we did before. &lt;a href="http://www.formencode.org/"&gt;Formencode&lt;/a&gt; provides a function called
&lt;code&gt;formencode.ForEach&lt;/code&gt; which helps us solve similar problems.
&lt;/p&gt;

&lt;p&gt;
Here is how our form looks like:
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-html"&gt;&amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;form&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;table&lt;/span&gt;&amp;gt;
        &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;tr&lt;/span&gt;&amp;gt;
            &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;input&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;type&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"text"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;name&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"employee-0.first_name"&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;
            &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;input&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;type&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"text"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;name&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"employee-0.last_name"&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;
            &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;input&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;type&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"text"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;name&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"employee-0.email"&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;
            &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;input&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;type&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"text"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;name&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"employee-0.phone"&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;
        &amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;tr&lt;/span&gt;&amp;gt;
        &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;tr&lt;/span&gt;&amp;gt;
            &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;input&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;type&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"text"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;name&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"employee-1.first_name"&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;
            &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;input&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;type&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"text"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;name&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"employee-1.last_name"&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;
            &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;input&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;type&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"text"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;name&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"employee-1.email"&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;
            &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;input&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;type&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"text"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;name&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"employee-1.phone"&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;
        &amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;tr&lt;/span&gt;&amp;gt;
        &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;tr&lt;/span&gt;&amp;gt;
            &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;input&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;type&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"text"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;name&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"employee-2.first_name"&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;
            &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;input&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;type&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"text"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;name&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"employee-2.last_name"&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;
            &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;input&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;type&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"text"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;name&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"employee-2.email"&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;
            &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;input&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;type&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"text"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;name&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"employee-2.phone"&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;
        &amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;tr&lt;/span&gt;&amp;gt;
        ...
    &amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;table&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;form&lt;/span&gt;&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
The validation class definition will be
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #bc8383; font-weight: bold;"&gt;import&lt;/span&gt; formencode
&lt;span style="color: #bc8383; font-weight: bold;"&gt;from&lt;/span&gt; formencode &lt;span style="color: #bc8383; font-weight: bold;"&gt;import&lt;/span&gt; validators &lt;span style="color: #bc8383; font-weight: bold;"&gt;as&lt;/span&gt; v
&lt;span style="color: #bc8383; font-weight: bold;"&gt;from&lt;/span&gt; formencode &lt;span style="color: #bc8383; font-weight: bold;"&gt;import&lt;/span&gt; national &lt;span style="color: #bc8383; font-weight: bold;"&gt;as&lt;/span&gt; n


&lt;span style="color: #bc8383; font-weight: bold;"&gt;class&lt;/span&gt; &lt;span style="color: #94bff3;"&gt;Employee&lt;/span&gt;(formencode.SchemaElement):
    &lt;span style="color: #f0dfaf;"&gt;first_name&lt;/span&gt; = v.String(strip=&lt;span style="color: #9fc59f;"&gt;True&lt;/span&gt;)
    &lt;span style="color: #f0dfaf;"&gt;last_name&lt;/span&gt; = v.String(strip=&lt;span style="color: #9fc59f;"&gt;True&lt;/span&gt;)
    &lt;span style="color: #f0dfaf;"&gt;email&lt;/span&gt; = v.String(strip=&lt;span style="color: #9fc59f;"&gt;True&lt;/span&gt;, resolve_domain=&lt;span style="color: #9fc59f;"&gt;True&lt;/span&gt;)
    &lt;span style="color: #f0dfaf;"&gt;phone&lt;/span&gt; = n.USPhoneNumber()


&lt;span style="color: #bc8383; font-weight: bold;"&gt;class&lt;/span&gt; &lt;span style="color: #94bff3;"&gt;Employees&lt;/span&gt;(formencode.Schema):
    &lt;span style="color: #f0dfaf;"&gt;employee&lt;/span&gt; = formencode.ForEach(Employee())
&lt;/pre&gt;
&lt;/div&gt;
</content></entry><entry><title type="html">Send emails via marrow.mailer</title><author><name>nil</name></author><link href="http://morediff.info/posts/2013/01/29_send-emails-via-marrowmailer.html"/><updated>2013-01-29T21:58:00Z</updated><published>2013-01-29T21:58:00Z</published><id>posts/2013/01/29_send-emails-via-marrowmailer.html</id><category scheme="/tags/python.html" term="python" label="python"/><category scheme="/tags/email.html" term="email" label="email"/><category scheme="/tags/mailer.html" term="mailer" label="mailer"/><category scheme="/tags/postfix.html" term="postfix" label="postfix"/><content type="html">&lt;p&gt;
I have a web app where authorized users can log in to edit a
schedule. In order to remind the users mentioned in the schedule on a
weekly base, a mailer running inside of cron is
needed. &lt;a href="https://github.com/marrow/marrow.mailer"&gt;marrow.mailer&lt;/a&gt; is
a very handy framework to help achieve this goal.
&lt;/p&gt;

&lt;p&gt;
First, I retrieve all the calendar for this week from the database:
&lt;/p&gt;
&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #f0dfaf;"&gt;now&lt;/span&gt; = datetime.now()
&lt;span style="color: #f0dfaf;"&gt;nextweek&lt;/span&gt; = now + timedelta(days=7)
&lt;span style="color: #f0dfaf;"&gt;cal&lt;/span&gt; = (
    session.query(model.Calendar)
        .&lt;span style="color: #8cd0d3;"&gt;filter&lt;/span&gt;(between(model.Calendar.fake_date, now, nextweek))
).first()
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
Then, setup the mailer via marrow.mailer
&lt;/p&gt;
&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #9fc59f;"&gt;# &lt;/span&gt;&lt;span style="color: #7f9f7f; font-style: italic;"&gt;start the mailer daemon. I use postfix as my email agent so here I use&lt;/span&gt;
&lt;span style="color: #9fc59f;"&gt;# &lt;/span&gt;&lt;span style="color: #7f9f7f; font-style: italic;"&gt;localhost as host&lt;/span&gt;
&lt;span style="color: #f0dfaf;"&gt;mailer&lt;/span&gt; = Mailer(&lt;span style="color: #8cd0d3;"&gt;dict&lt;/span&gt;(
    transport = &lt;span style="color: #8cd0d3;"&gt;dict&lt;/span&gt;(
        use = &lt;span style="color: #6ca0a3;"&gt;"smtp"&lt;/span&gt;,
        host = &lt;span style="color: #6ca0a3;"&gt;"localhost"&lt;/span&gt;),
    manager = &lt;span style="color: #8cd0d3;"&gt;dict&lt;/span&gt;()))
mailer.start()

&lt;span style="color: #f0dfaf;"&gt;message&lt;/span&gt; = Message(author=&lt;span style="color: #6ca0a3;"&gt;"Foo Bar &lt;a href="mailto:foo%40bar.org"&gt;&amp;lt;foo@bar.org&amp;gt;&lt;/a&gt;"&lt;/span&gt;,
                  to=cal.email,
                  cc=[&lt;span style="color: #6ca0a3;"&gt;"woot@bar.org"&lt;/span&gt;,
                      &lt;span style="color: #6ca0a3;"&gt;"bar@bar.org"&lt;/span&gt;],
                  bcc=&lt;span style="color: #6ca0a3;"&gt;"zoo@bar.org"&lt;/span&gt;)
&lt;span style="color: #f0dfaf;"&gt;message.subject&lt;/span&gt; = subject
&lt;span style="color: #f0dfaf;"&gt;message.plain&lt;/span&gt; = body
mailer.send(message)

mailer.stop()
&lt;/pre&gt;
&lt;/div&gt;
</content></entry><entry><title type="html">FormEncode: (1) Introduction</title><author><name>nil</name></author><link href="http://morediff.info/posts/2012/12/15_formencode-1-introduction.html"/><updated>2012-12-15T02:51:00Z</updated><published>2012-12-15T02:51:00Z</published><id>posts/2012/12/15_formencode-1-introduction.html</id><category scheme="/tags/formencode.html" term="formencode" label="formencode"/><category scheme="/tags/python.html" term="python" label="python"/><content type="html">&lt;p&gt;
&lt;a href="https://github.com/bdoms/formencode"&gt;FormEncode&lt;/a&gt; is very helpful to validate forms data. Here is a very
simple example to show how to use it.
&lt;/p&gt;

&lt;p&gt;
Suppose we have a form in our &lt;a href="http://www.makotemplates.org/"&gt;mako&lt;/a&gt; template as follows:
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-html"&gt;  &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;form&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;id&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"formExample"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;method&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"post"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;action&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"${c.url.to.action}"&lt;/span&gt;&amp;gt;
  &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;table&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;tr&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;input&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;type&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"text"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;id&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"firstID"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;name&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"number1"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;value&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;""&lt;/span&gt;/&amp;gt;&amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;input&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;type&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"text"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;id&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"secondID"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;name&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"int1"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;value&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;""&lt;/span&gt;/&amp;gt;&amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #8fb28f; font-weight: bold;"&gt;input&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;type&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"text"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;id&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"thirdID"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;name&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;"string1"&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;value&lt;/span&gt;=&lt;span style="color: #6ca0a3;"&gt;""&lt;/span&gt;/&amp;gt;&amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;td&lt;/span&gt;&amp;gt;
    &amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;tr&lt;/span&gt;&amp;gt;
  &amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;table&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span style="color: #8fb28f; font-weight: bold;"&gt;form&lt;/span&gt;&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
To validate these three input fields, we need to define a class like
this:
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #bc8383; font-weight: bold;"&gt;import&lt;/span&gt; formencode
&lt;span style="color: #bc8383; font-weight: bold;"&gt;from&lt;/span&gt; formencode &lt;span style="color: #bc8383; font-weight: bold;"&gt;import&lt;/span&gt; validators

&lt;span style="color: #bc8383; font-weight: bold;"&gt;class&lt;/span&gt; &lt;span style="color: #94bff3;"&gt;myFormValidation&lt;/span&gt;(formencode.Schema):
    &lt;span style="color: #f0dfaf;"&gt;number1&lt;/span&gt; = validators.Number(&lt;span style="color: #8cd0d3;"&gt;min&lt;/span&gt;=0, &lt;span style="color: #8cd0d3;"&gt;max&lt;/span&gt;=100, not_empty=&lt;span style="color: #9fc59f;"&gt;False&lt;/span&gt;)
    &lt;span style="color: #f0dfaf;"&gt;int1&lt;/span&gt; = validators.Int(&lt;span style="color: #8cd0d3;"&gt;min&lt;/span&gt;=30, &lt;span style="color: #8cd0d3;"&gt;max&lt;/span&gt;=100)
    &lt;span style="color: #f0dfaf;"&gt;string1&lt;/span&gt; = validators.String(&lt;span style="color: #8cd0d3;"&gt;max&lt;/span&gt;=128, strip=&lt;span style="color: #9fc59f;"&gt;True&lt;/span&gt;)
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
As we can see from the above example, formencode matches each input
via the name attribute within a tag. In the controller, we'll
validate all parameters from the above form.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #bc8383; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span style="color: #8fb28f; font-weight: bold;"&gt;example_action&lt;/span&gt;(&lt;span style="color: #bc8383; font-weight: bold;"&gt;self&lt;/span&gt;, **kwargs):
    &lt;span style="color: #8fb28f; font-style: italic;"&gt;"""Demo action to show how formencode works."""&lt;/span&gt;

    &lt;span style="color: #f0dfaf;"&gt;example_form&lt;/span&gt; = myFormValidation(request.params)
&lt;/pre&gt;
&lt;/div&gt;
</content></entry><entry><title type="html">Score My Mutt</title><author><name>nil</name></author><link href="http://morediff.info/posts/2012/12/15_score-my-mutt.html"/><updated>2012-12-15T02:21:00Z</updated><published>2012-12-15T02:21:00Z</published><id>posts/2012/12/15_score-my-mutt.html</id><category scheme="/tags/mutt.html" term="mutt" label="mutt"/><category scheme="/tags/email.html" term="email" label="email"/><category scheme="/tags/setup.html" term="setup" label="setup"/><content type="html">&lt;p&gt;
At work, I receive 200 emails on average per day, including all
Mercurial activities, EC2 instances activities, tickets from Jira,
etc. I do not care much about messages from EC2, and some testing
messages from our platform.  Worse, they flood my Inbox and buries
other important messages when I sort my Inbox by
last-date-received. Sorting by scores inside of threads will solve
this problem.
&lt;/p&gt;

&lt;p&gt;
Mutt score at a glance.  According to Mutt manual &lt;sup&gt;&lt;a id="fnr.1" name="fnr.1" class="footref" href="#fn.1"&gt;1&lt;/a&gt;&lt;/sup&gt;, we can
use these patterns for scoring. But my Mutt (1.5.21) does not
recognize some of them, i.e.: &lt;b&gt;~h&lt;/b&gt;, &lt;b&gt;~b&lt;/b&gt;, &lt;b&gt;~B&lt;/b&gt;, etc.
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;
~A              all messages &lt;br/&gt;
~b EXPR         messages which contain EXPR in the message body &lt;br/&gt;
~B EXPR         messages which contain EXPR in the whole message &lt;br/&gt;
~c USER         messages carbon-copied to USER&lt;br/&gt;
~C EXPR         message is either to: or cc: EXPR&lt;br/&gt;
~D              deleted messages&lt;br/&gt;
~d [MIN]-[MAX]  messages with ``date-sent'' in a Date range&lt;br/&gt;
~E              expired messages&lt;br/&gt;
~e EXPR         message which contains EXPR in the ``Sender'' field&lt;br/&gt;
~F              flagged messages&lt;br/&gt;
~f USER         messages originating from USER&lt;br/&gt;
~g              PGP signed messages&lt;br/&gt;
~G              PGP encrypted messages&lt;br/&gt;
~h EXPR         messages which contain EXPR in the message header&lt;br/&gt;
~k              message contains PGP key material&lt;br/&gt;
~i ID           message which match ID in the ``Message-ID'' field&lt;br/&gt;
~L EXPR         message is either originated or received by EXPR&lt;br/&gt;
~l              message is addressed to a known mailing list&lt;br/&gt;
~m [MIN]-[MAX]  message in the range MIN to MAX *)&lt;br/&gt;
~n [MIN]-[MAX]  messages with a score in the range MIN to MAX *)&lt;br/&gt;
~N              new messages&lt;br/&gt;
~O              old messages&lt;br/&gt;
~p              message is addressed to you (consults $alternates)&lt;br/&gt;
~P              message is from you (consults $alternates)&lt;br/&gt;
~Q              messages which have been replied to&lt;br/&gt;
~R              read messages&lt;br/&gt;
~r [MIN]-[MAX]  messages with ``date-received'' in a Date range&lt;br/&gt;
~S              superseded messages&lt;br/&gt;
~s SUBJECT      messages having SUBJECT in the ``Subject'' field.&lt;br/&gt;
~T              tagged messages&lt;br/&gt;
~t USER         messages addressed to USER&lt;br/&gt;
~U              unread messages&lt;br/&gt;
~v              message is part of a collapsed thread.&lt;br/&gt;
~x EXPR         messages which contain EXPR in the `References' field&lt;br/&gt;
~y EXPR         messages which contain EXPR in the `X-Label' field&lt;br/&gt;
~z [MIN]-[MAX]  messages with a size in the range MIN to MAX *)&lt;br/&gt;
~=              duplicated messages (see $duplicate&lt;sub&gt;threads&lt;/sub&gt;)
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
The interesting ones are &lt;b&gt;~f&lt;/b&gt;, &lt;b&gt;~C&lt;/b&gt;, and &lt;b&gt;~s&lt;/b&gt;. They are pretty
straight-forward. One thing needs to mention about &lt;b&gt;~f&lt;/b&gt; is that it
only check sender's actual email address, instead of sender's
name. For example, if the sender is "hello world
&amp;lt;morediff@moreisdifferent.info&amp;gt;", it does not check the "hello
world" part, but the "morediff@moreisdifferent.info" part. As the
following configuration file shows, you can &lt;b&gt;AND&lt;/b&gt; multiple patterns
together.  &lt;span class="underline"&gt;score "patternOne patternTwo patternMore" scoreNum&lt;/span&gt;
means if a message satisfies all the
conditions &lt;b&gt;patternOne&lt;/b&gt;, &lt;b&gt;patternTwo&lt;/b&gt;, and &lt;b&gt;patternMore&lt;/b&gt;, then it
will be assigned the score &lt;b&gt;scoreNum&lt;/b&gt;. You can get a good idea of
how to configure it by understanding the following example.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-sh"&gt;&lt;span style="color: #9fc59f;"&gt;# &lt;/span&gt;&lt;span style="color: #7f9f7f; font-style: italic;"&gt;sorting method&lt;/span&gt;
&lt;span style="color: #8cd0d3;"&gt;set&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;sort&lt;/span&gt; = &lt;span style="color: #6ca0a3;"&gt;'threads'&lt;/span&gt;
&lt;span style="color: #8cd0d3;"&gt;set&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;sort_aux&lt;/span&gt; = &lt;span style="color: #6ca0a3;"&gt;'score'&lt;/span&gt;

&lt;span style="color: #9fc59f;"&gt;# &lt;/span&gt;&lt;span style="color: #7f9f7f; font-style: italic;"&gt;score messages&lt;/span&gt;
&lt;span style="color: #8cd0d3;"&gt;set&lt;/span&gt; &lt;span style="color: #f0dfaf;"&gt;index_format&lt;/span&gt;= &lt;span style="color: #6ca0a3;"&gt;"%2N %Z %{%b %d} %-15.15F %s"&lt;/span&gt;
unscore *
&lt;span style="color: #9fc59f;"&gt;# &lt;/span&gt;&lt;span style="color: #7f9f7f; font-style: italic;"&gt;addressed to myself&lt;/span&gt;
score &lt;span style="color: #6ca0a3;"&gt;"~p"&lt;/span&gt; 7
score &lt;span style="color: #6ca0a3;"&gt;"!(~f trac@domain\.com) ~C name@domain\.com"&lt;/span&gt; 7
&lt;span style="color: #9fc59f;"&gt;# &lt;/span&gt;&lt;span style="color: #7f9f7f; font-style: italic;"&gt;replied to&lt;/span&gt;
score &lt;span style="color: #6ca0a3;"&gt;"~Q"&lt;/span&gt; 6
&lt;span style="color: #9fc59f;"&gt;# &lt;/span&gt;&lt;span style="color: #7f9f7f; font-style: italic;"&gt;company group email&lt;/span&gt;
score &lt;span style="color: #6ca0a3;"&gt;"~C yaname@domain\.com"&lt;/span&gt; 6
&lt;span style="color: #9fc59f;"&gt;# &lt;/span&gt;&lt;span style="color: #7f9f7f; font-style: italic;"&gt;ticket assignment&lt;/span&gt;
score &lt;span style="color: #6ca0a3;"&gt;"~f yaaname@domain\.com"&lt;/span&gt; 5
&lt;span style="color: #9fc59f;"&gt;# &lt;/span&gt;&lt;span style="color: #7f9f7f; font-style: italic;"&gt;from me&lt;/span&gt;
score &lt;span style="color: #6ca0a3;"&gt;"~P"&lt;/span&gt; 4
&lt;span style="color: #9fc59f;"&gt;# &lt;/span&gt;&lt;span style="color: #7f9f7f; font-style: italic;"&gt;mercurial push, commit&lt;/span&gt;
score &lt;span style="color: #6ca0a3;"&gt;"~f mercurial"&lt;/span&gt; 3
score &lt;span style="color: #6ca0a3;"&gt;"!(~s Informational) !(~s Warning) !(~s Error) !(~s Unknown) ~f dev"&lt;/span&gt; 3
score &lt;span style="color: #6ca0a3;"&gt;"~f monitoring"&lt;/span&gt; 3
&lt;span style="color: #9fc59f;"&gt;# &lt;/span&gt;&lt;span style="color: #7f9f7f; font-style: italic;"&gt;new messages&lt;/span&gt;
score &lt;span style="color: #6ca0a3;"&gt;"~N"&lt;/span&gt; 2
&lt;span style="color: #9fc59f;"&gt;# &lt;/span&gt;&lt;span style="color: #7f9f7f; font-style: italic;"&gt;flagged messages&lt;/span&gt;
score &lt;span style="color: #6ca0a3;"&gt;"~F"&lt;/span&gt; 1
&lt;/pre&gt;
&lt;/div&gt;

&lt;hr/&gt;
&lt;div id="footnotes"&gt;
&lt;h2 class="footnotes"&gt;Footnotes: &lt;/h2&gt;
&lt;div id="text-footnotes"&gt;

&lt;div class="footdef"&gt;&lt;sup&gt;&lt;a id="fn.1" name="fn.1" class="footnum" href="#fnr.1"&gt;1&lt;/a&gt;&lt;/sup&gt; &lt;p class="footpara"&gt;
. &lt;a href="http://www.mutt.org/doc/manual/manual-4.html#patterns"&gt;http://www.mutt.org/doc/manual/manual-4.html#patterns&lt;/a&gt;
&lt;/p&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;/div&gt;</content></entry><entry><title type="html">Blog Setup</title><author><name>nil</name></author><link href="http://morediff.info/posts/2012/12/14_blog-setup.html"/><updated>2012-12-14T16:53:00Z</updated><published>2012-12-14T16:53:00Z</published><id>posts/2012/12/14_blog-setup.html</id><category scheme="/tags/setup.html" term="setup" label="setup"/><content type="html">&lt;p&gt;
This blog is powered by &lt;a href="https://github.com/renard/o-blog"&gt;o-blog&lt;/a&gt;, which converts &lt;a href="http://orgmode.org"&gt;Org&lt;/a&gt; files into
static html pages. As an &lt;a href="http://www.gnu.org/software/emacs/"&gt;Emacs&lt;/a&gt; + &lt;a href="http://orgmode.org"&gt;Org&lt;/a&gt; user, &lt;a href="https://github.com/renard/o-blog"&gt;o-blog&lt;/a&gt; is the best blog
tool so far to myself. It allows me to use the all the features from
&lt;a href="http://orgmode.org"&gt;Org&lt;/a&gt;, at the same time provides a lot of cool &lt;a href="http://renard.github.com/o-blog/features.html"&gt;features&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Setting up the basic page is relatively straight forward. Let's starts
from our "Hello World!" example.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-org"&gt;&lt;span style="color: #b3b3b3;"&gt;#+TITLE:&lt;/span&gt; &lt;span style="color: #afeeee; font-weight: bold;"&gt;Hello World Blog&lt;/span&gt;
&lt;span style="color: #7f9f7f; font-style: italic;"&gt;#+DESCRIPTION: How to create a basic blog using o-blog&lt;/span&gt;

&lt;span style="color: #7f9f7f; font-style: italic;"&gt;#+STARTUP: logdone&lt;/span&gt;

&lt;span style="color: #7f9f7f; font-style: italic;"&gt;#+TEMPLATE_DIR: templates&lt;/span&gt;
&lt;span style="color: #7f9f7f; font-style: italic;"&gt;#+URL: &lt;a href="http://helloworld.blog"&gt;http://helloworld.blog&lt;/a&gt;&lt;/span&gt;

&lt;span style="color: #7f9f7f; font-style: italic;"&gt;#+DISQUS: hello-world-demo&lt;/span&gt;
&lt;span style="color: #7f9f7f; font-style: italic;"&gt;#+FILENAME_SANITIZER: ob-sanitize-string&lt;/span&gt;
&lt;span style="color: #7f9f7f; font-style: italic;"&gt;#+POST_SORTER: ob-sort-posts-by-date&lt;/span&gt;

&lt;span style="color: #DFAF8F;"&gt;* Home Page&lt;/span&gt;
,  :PROPERTIES:
,  :PAGE: index.html
,  :TEMPLATE: blog_static_no_title.html
,  :END:

#+begin_o_blog_row 8

#+begin_o_blog_hero_unit
#+HTML: &amp;lt;h1&amp;gt;&amp;lt;lisp&amp;gt;(ob:blog-title BLOG)&amp;lt;/lisp&amp;gt;&amp;lt;/h1&amp;gt;
#+end_o_blog_hero_unit

#+o_blog_row_column 4

#+HTML: &amp;lt;div class="hero-unit" style="font-size: 100%;"&amp;gt;

,&lt;span style="color: #D0BF8F; text-decoration: underline;"&gt;&lt;a href="https://github.com"&gt;/icon-github-sign icon-white/ github&lt;/a&gt;&lt;/span&gt;

#+HTML: &amp;lt;/div&amp;gt;

#+end_o_blog_row

#+begin_o_blog_row 5
&lt;span style="color: #BFEBBF;"&gt;** Hello World&lt;/span&gt;
,    Welcome to our &lt;span style="color: #b3b3b3;"&gt;=Hello World=&lt;/span&gt; demo site.

#+end_o_blog_row

&lt;span style="color: #DFAF8F;"&gt;* Blog Details&lt;/span&gt;
&lt;span style="color: #BFEBBF;"&gt;** Copyright&lt;/span&gt;
,   :PROPERTIES:
,   :SNIPPET: t
,   :END:

&lt;span style="color: #BFEBBF;"&gt;** About&lt;/span&gt;
,  :PROPERTIES:
,  :SNIPPET: t
,  :END:

,   &lt;span style="color: #b3b3b3;"&gt;=Hello World=&lt;/span&gt; demo site using o-blog

&lt;span style="color: #BFEBBF;"&gt;** Navigation&lt;/span&gt;
,  :PROPERTIES:
,  :SNIPPET: t
,  :END:

&lt;span style="color: #BFEBBF;"&gt;** Navigation Footer&lt;/span&gt;
,  :PROPERTIES:
,  :SNIPPET:t
,  :END:

&lt;span style="color: #BFEBBF;"&gt;** Articles by tags&lt;/span&gt;
,   :PROPERTIES:
,   :PAGE: tags.html
,   :TEMPLATE: blog_post-by-tags.html
,   :END:

&lt;span style="color: #DFAF8F;"&gt;* Posts&lt;/span&gt;
&lt;span style="color: #BFEBBF;"&gt;** &lt;/span&gt;&lt;span style="color: #AFD8AF; font-weight: bold;"&gt;DONE&lt;/span&gt;&lt;span style="color: #BFEBBF;"&gt; Hello World                         &lt;/span&gt;&lt;span style="color: #BFEBBF; font-weight: bold;"&gt;:demo:hello_world:&lt;/span&gt;
,   &lt;span style="color: #656555;"&gt;CLOSED:&lt;/span&gt; &lt;span style="color: #8CD0D3; text-decoration: underline;"&gt;[2012-12-15 Sat 15:35]&lt;/span&gt;
,   :PROPERTIES:
,   :END:

,   This is our &lt;span style="color: #b3b3b3;"&gt;=Hello World=&lt;/span&gt; example by using &lt;span style="color: #DC8CC3; background-color: #3F3F3F;"&gt;&lt;a href="http://renard.github.com/o-blog/index.html"&gt;o-blog&lt;/a&gt;.&lt;/span&gt;
,   It's required to insert an empty line between &lt;span style="color: #b3b3b3;"&gt;=:END:=&lt;/span&gt; and the content
,   of the post. A post only get published when it's state cycle changed
,   from &lt;span style="color: #b3b3b3;"&gt;=TODO=&lt;/span&gt; to &lt;span style="color: #b3b3b3;"&gt;=DONE=&lt;/span&gt;  which is a great feature which allows us to
,   keep our in-progress post private until it's done.
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
After this, you can just type &lt;code&gt;M-x org-publish-blog&lt;/code&gt; to generate the
static htmls. All outputs will be in &lt;code&gt;out&lt;/code&gt; directory. You can just copy
this directory to wherever you host your website, i.e. &lt;code&gt;S3&lt;/code&gt;, &lt;code&gt;EC2&lt;/code&gt;, or
&lt;code&gt;Github Pages&lt;/code&gt;. For &lt;code&gt;S3&lt;/code&gt;, you can use a great set of tools from
&lt;code&gt;s3cmd&lt;/code&gt;, including &lt;code&gt;s3cmd put&lt;/code&gt;, &lt;code&gt;s3cmd sync&lt;/code&gt;, or &lt;code&gt;s3cmd setacl&lt;/code&gt;. I
use &lt;code&gt;EC2&lt;/code&gt; as my host. What I did at the beginning was setting up a
&lt;code&gt;Mercurial&lt;/code&gt; repository on my server. Every time I generate new htmls,
I push to my server. Since I also want to host a mirror site via
&lt;a href="http://pages.github.com/"&gt;Github Page&lt;/a&gt;, I switched to use &lt;a href="https://github.com/wujiang/wujiang.github.com"&gt;Github&lt;/a&gt; as my repository. On my &lt;code&gt;EC2&lt;/code&gt;
server, I created a cron job which will &lt;code&gt;git pull&lt;/code&gt; every minute.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-sh"&gt;deploy workflow

  +--------------+           +------------------+           +--------------+
  |              |           |                  |           |              |
  |              |           |                  | (crontab) |              |
  |    Laptop    | git push  |     Github       | git pull  | EC2 Server   |
  |              |---------&amp;gt; |wujiang.github.com|---------&amp;gt; |morediff.info |
  |              |           |                  |           |              |
  |              |           |                  |           |              |
  +--------------+           +------------------+           +--------------+
&lt;/pre&gt;
&lt;/div&gt;
</content></entry>
</feed>
