<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>Vuong Nguyen</title><link>http://vuongnguyen.com/</link><description>on technology, life and the urgency of learning</description><atom:link href="http://vuongnguyen.com/feeds/all.rss.xml" rel="self"></atom:link><lastBuildDate>Thu, 28 Mar 2013 00:00:00 -0400</lastBuildDate><item><title>Migrating to Django 1.5 and Custom User Model</title><link>http://vuongnguyen.com/migrate-django-1.5-custom-user-model.html</link><description>&lt;p&gt;With the recent Django 1.5 release, we now have the choice to create custom user model instead of the default user model that came with &lt;code&gt;django.contrib.auth&lt;/code&gt;.&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;Two important use cases this release resolved were the ability to easily extend user profile and fix &lt;code&gt;User.email&lt;/code&gt; field from having a hard coded value of &lt;code&gt;max_length=75&lt;/code&gt;.  This isn&amp;#8217;t in compliant with &lt;a href="http://tools.ietf.org/html/rfc5321#section-4.5.3" title="Simple Mail Transfer Protocol"&gt;&lt;span class="caps"&gt;RFC&lt;/span&gt; 5321&lt;/a&gt;, which establishes that an email can have &lt;code&gt;max_length=254&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here are a few quick steps to migrate your current users and profiles to take advantage of the new custom user model feature in Django 1.5&amp;nbsp;release.&lt;/p&gt;
&lt;h2&gt;Create a new Django&amp;nbsp;app&lt;/h2&gt;
&lt;p&gt;We&amp;#8217;ll call this app &lt;code&gt;accounts&lt;/code&gt; for the rest of this article.  You&amp;#8217;re definitely free to call it whatever you want. You can call it &lt;code&gt;humans&lt;/code&gt; for&amp;nbsp;instance.&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;django-admin.py startapp accounts
&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Duplicate old &lt;code&gt;User&lt;/code&gt; object&amp;nbsp;definitions&lt;/h2&gt;
&lt;p&gt;Copy &lt;code&gt;django.contrib.auth.models.User&lt;/code&gt; object into &lt;code&gt;accounts.models.User&lt;/code&gt;. Doing this would make our later migrations much simpler. You can definitely make additional changes after the transition away from old &lt;code&gt;User&lt;/code&gt; object&amp;nbsp;finalizes.&lt;/p&gt;
&lt;h2&gt;Move your profile model into &lt;code&gt;accounts&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;If you&amp;#8217;re like me, you probably had a &lt;code&gt;Profile&lt;/code&gt; or &lt;code&gt;UserProfile&lt;/code&gt; object to extend the legacy &lt;code&gt;User&lt;/code&gt; object. It made sense then because you didn&amp;#8217;t want to modify the &lt;code&gt;django.contrib.auth&lt;/code&gt; source&amp;nbsp;codes. &lt;/p&gt;
&lt;p&gt;With Django 1.5, this decision is a matter of preference.  However, I would recommend keeping a profile model to hold attributes not relating to basic &lt;code&gt;User&lt;/code&gt; object&amp;#8217;s goals of keeping authentication &lt;span class="amp"&gt;&amp;amp;&lt;/span&gt; essential&amp;nbsp;information. &lt;/p&gt;
&lt;h2&gt;Use &lt;code&gt;South&lt;/code&gt; to make initial&amp;nbsp;migration&lt;/h2&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;python manage.py schemamigration accounts --initial
&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Migrate &lt;code&gt;accounts&lt;/code&gt; models&lt;/h2&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;python manage.py migrate accounts
&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Remove and rename database&amp;nbsp;tables&lt;/h2&gt;
&lt;p&gt;Drop the newly migrated &lt;code&gt;accounts.models.User&lt;/code&gt; and relational objects and rename the old &lt;code&gt;django.contrib.auth.models.User&lt;/code&gt; to&amp;nbsp;it.&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="c1"&gt;# delete and rename the User object and its relational tables&lt;/span&gt;
&lt;span class="k"&gt;&lt;span class="caps"&gt;DROP&lt;/span&gt;&lt;/span&gt; &lt;span class="k"&gt;&lt;span class="caps"&gt;TABLE&lt;/span&gt;&lt;/span&gt; &lt;span class="n"&gt;accounts_users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;&lt;span class="caps"&gt;RENAME&lt;/span&gt;&lt;/span&gt; &lt;span class="k"&gt;&lt;span class="caps"&gt;TABLE&lt;/span&gt;&lt;/span&gt; &lt;span class="n"&gt;auth_user&lt;/span&gt; &lt;span class="k"&gt;&lt;span class="caps"&gt;TO&lt;/span&gt;&lt;/span&gt; &lt;span class="n"&gt;accounts_users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;&lt;span class="caps"&gt;DROP&lt;/span&gt;&lt;/span&gt; &lt;span class="k"&gt;&lt;span class="caps"&gt;TABLE&lt;/span&gt;&lt;/span&gt; &lt;span class="n"&gt;accounts_users_groups&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;&lt;span class="caps"&gt;RENAME&lt;/span&gt;&lt;/span&gt; &lt;span class="k"&gt;&lt;span class="caps"&gt;TABLE&lt;/span&gt;&lt;/span&gt; &lt;span class="n"&gt;auth_user_groups&lt;/span&gt; &lt;span class="k"&gt;&lt;span class="caps"&gt;TO&lt;/span&gt;&lt;/span&gt; &lt;span class="n"&gt;accounts_users_groups&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;&lt;span class="caps"&gt;DROP&lt;/span&gt;&lt;/span&gt; &lt;span class="k"&gt;&lt;span class="caps"&gt;TABLE&lt;/span&gt;&lt;/span&gt; &lt;span class="n"&gt;accounts_users_user_permissions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;&lt;span class="caps"&gt;RENAME&lt;/span&gt;&lt;/span&gt; &lt;span class="k"&gt;&lt;span class="caps"&gt;TABLE&lt;/span&gt;&lt;/span&gt; &lt;span class="n"&gt;auth_user_user_permissions&lt;/span&gt; &lt;span class="k"&gt;&lt;span class="caps"&gt;TO&lt;/span&gt;&lt;/span&gt; &lt;span class="n"&gt;accounts_users_user_permissions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;# delete and rename the profile tables&lt;/span&gt;
&lt;span class="k"&gt;&lt;span class="caps"&gt;DROP&lt;/span&gt;&lt;/span&gt; &lt;span class="k"&gt;&lt;span class="caps"&gt;TABLE&lt;/span&gt;&lt;/span&gt; &lt;span class="n"&gt;accounts_profiles&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;&lt;span class="caps"&gt;RENAME&lt;/span&gt;&lt;/span&gt; &lt;span class="k"&gt;&lt;span class="caps"&gt;TABLE&lt;/span&gt;&lt;/span&gt; &lt;span class="n"&gt;user_profiles&lt;/span&gt; &lt;span class="k"&gt;&lt;span class="caps"&gt;TO&lt;/span&gt;&lt;/span&gt; &lt;span class="n"&gt;accounts_profiles&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;# if you want to (or already) immediately changed email field from 75 to 255 characters&lt;/span&gt;
&lt;span class="k"&gt;&lt;span class="caps"&gt;ALTER&lt;/span&gt;&lt;/span&gt; &lt;span class="k"&gt;&lt;span class="caps"&gt;TABLE&lt;/span&gt;&lt;/span&gt; &lt;span class="n"&gt;accounts_users&lt;/span&gt; &lt;span class="n"&gt;&lt;span class="caps"&gt;MODIFY&lt;/span&gt;&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="kt"&gt;&lt;span class="caps"&gt;VARCHAR&lt;/span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;&lt;span class="caps"&gt;ALTER&lt;/span&gt;&lt;/span&gt; &lt;span class="k"&gt;&lt;span class="caps"&gt;TABLE&lt;/span&gt;&lt;/span&gt; &lt;span class="n"&gt;accounts_users&lt;/span&gt; &lt;span class="n"&gt;&lt;span class="caps"&gt;MODIFY&lt;/span&gt;&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="kt"&gt;&lt;span class="caps"&gt;VARCHAR&lt;/span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Fix references to old &lt;code&gt;User&lt;/code&gt; object&lt;/h2&gt;
&lt;p&gt;Replacing old imports with the correct reference to the new &lt;code&gt;User&lt;/code&gt; object with the &lt;code&gt;get_user_model&lt;/code&gt; utility&amp;nbsp;method.&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="c"&gt;# old&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.contrib.auth.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;

&lt;span class="c"&gt;# new&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.contrib.auth&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_user_model&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_user_model&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;em&gt;&lt;span class="caps"&gt;WARNING&lt;/span&gt;: You probably should run &lt;code&gt;South&lt;/code&gt; migration on all apps to make sure other models are aware of the new &lt;code&gt;User&lt;/code&gt; object.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;You can now make any further changes to your new &lt;code&gt;User&lt;/code&gt; object.  Good&amp;nbsp;luck!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Vuong Nguyen</dc:creator><pubDate>Thu, 28 Mar 2013 00:00:00 -0400</pubDate><guid>tag:vuongnguyen.com,2013-03-28:migrate-django-1.5-custom-user-model.html</guid><category>technology</category><category>python</category><category>django</category><category>south</category><category>mysql</category></item><item><title>Personal and Business Cloud Security</title><link>http://vuongnguyen.com/personal-business-cloud-security.html</link><description>&lt;p&gt;These days, it seems that businesses are finally starting to be more comfortable with the &lt;a href="http://en.wikipedia.org/wiki/Bring_your_own_device" title="Bring Your Own Device"&gt;Bring Your Own Device (&lt;span class="caps"&gt;BYOD&lt;/span&gt;)&lt;/a&gt; policy which allows employees to use their personal devices to access privileged corporate&amp;nbsp;information.&lt;/p&gt;
&lt;p&gt;Device manufacturers have also started to push their own flavor of cloud storage service such as Apple with iCloud, Google with Google Drive and Microsoft with SkyDrive.  Although to be fair, Google and Microsoft aren&amp;#8217;t really hardware manufacturers, but they do have their hands in the hardware products.&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;Stand-alone cloud storage providers such as Dropbox, SugarSync, Box etc. catering to personal and business users are also growing at a viral&amp;nbsp;rate.&lt;/p&gt;
&lt;p&gt;Current outlook indicates our personal and business files will eventually be on one or more cloud storage providers.  Like all data storage facilities, it&amp;#8217;s only a matter of time before the question of security becomes front and center not only to &lt;span class="caps"&gt;IT&lt;/span&gt; professionals but regular&amp;nbsp;consumers.&lt;/p&gt;
&lt;h2&gt;Is Cloud Security a Real&amp;nbsp;Problem?&lt;/h2&gt;
&lt;p&gt;The quick answer is: &lt;span class="caps"&gt;YES&lt;/span&gt;! One would only need to perform a quick search for &amp;#8220;cloud security issues&amp;#8221; or &amp;#8220;dropbox security breaches&amp;#8221; to find top headlines such as: &lt;a href="http://www.zdnet.com/dropbox-gets-hacked-again-7000001928/" title="Dropbox got hacked ... again"&gt;Dropbox got hacked &amp;#8230; again&lt;/a&gt;, &lt;a href="http://www.forbes.com/sites/karstenstrauss/2012/07/19/dropbox-security-breach-security-in-the-cloud/" title="Dropbox Security Breach: Who's Guarding Your Secrets In The Cloud?"&gt;Dropbox Security Breach: Who&amp;#8217;s Guarding Your Secrets In The Cloud?&lt;/a&gt;, &lt;a href="http://www.csoonline.com/article/717307/5-more-key-cloud-security-issues" title="5 (more) key cloud security issues"&gt;5 (more) key cloud security issues&lt;/a&gt; or &lt;a href="https://www.eff.org/deeplinks/2012/10/governments-attack-cloud-computing," title="Megaupload and the Government's Attack on Cloud Computing"&gt;Megaupload and the Government&amp;#8217;s Attack on Cloud Computing&lt;/a&gt;&amp;nbsp;etc.&lt;/p&gt;
&lt;p&gt;The sad truth is, we&amp;#8217;re no longer surprised to read news of &amp;#8220;Law Firm X&amp;#8221; had some sensitive case documents leaked from one of the cloud storages or &amp;#8220;Company Y&amp;#8221; had some trade secret stolen by employees using Dropbox as a data storage facility.&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;As I write this article, &lt;a href="http://evernote.com" title="Evernote"&gt;Evernote&lt;/a&gt; is still trying to contain its recent &lt;a href="http://blog.evernote.com/blog/2013/03/02/security-notice-service-wide-password-reset/" title="Security Notice: Service-wide Password Reset"&gt;security breach&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;re not surprised because those aware of security issues already self-censor the data going into the clouds and those who are not &amp;#8230; well, probably aren&amp;#8217;t reading these news to begin with!  When was the last time you put your tax return or a copy of your passport into Dropbox or&amp;nbsp;SugarSync?&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s the kicker, how many of us, so-called &amp;#8220;security-aware&amp;#8221; or &amp;#8220;tech savy&amp;#8221;, wouldn&amp;#8217;t think twice about sending a copy of driver license, passport or even &lt;span class="caps"&gt;SSN&lt;/span&gt; card via email to our life or auto insurance agents?  How are those information handled by these parties?  Is it one agent, a team of agents, the whole company or worse, another third party vendor they&amp;nbsp;use?&lt;/p&gt;
&lt;h2&gt;The Promise of&amp;nbsp;Security&lt;/h2&gt;
&lt;p&gt;When it comes down to it, our data is only as secured as the person we share with.  You can be the most security-conscious person, but if you&amp;#8217;re sending sensitive documents to someone with terrible security hygiene, then your data is most definitely at&amp;nbsp;risk.&lt;/p&gt;
&lt;p&gt;In this instance, an email is a terrible way to share files because when it gets to the receiver, you would have lost all control of these files.&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;All we can do then is to rely on a &amp;#8220;promise&amp;#8221; that whoever has our data will secure it appropriately.  At best, it&amp;#8217;s well-intended, at worst, it&amp;#8217;s dishonesty.  Why?  Those aforementioned articles say: whether you like it or not, security breaches&amp;nbsp;happen.&lt;/p&gt;
&lt;h2&gt;The Problem with Cloud&amp;nbsp;Security&lt;/h2&gt;
&lt;p&gt;If cloud storage providers allow us to put data in a virtual &amp;#8220;lockbox&amp;#8221; with username &lt;span class="amp"&gt;&amp;amp;&lt;/span&gt; password as the key to open this box, then like any storage facility owner, they also have access to this data.  Just imagine, your data is only as safe as the time it takes for an obsucre disgruntled employee to go&amp;nbsp;rouge.&lt;/p&gt;
&lt;p&gt;Remember the &amp;#8220;promise of security&amp;#8221; above?  Here are a few excerps from Dropbox&amp;#8217;s Privacy&amp;nbsp;Policy:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Changing or Deleting Your Information:&lt;/em&gt; &amp;#8230;  In some cases we may retain copies of your information if required by&amp;nbsp;law&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Data Retention:&lt;/em&gt; &amp;#8230; We may retain and use your information as necessary to comply with our legal obligations, resolve disputes, and enforce our agreements. Consistent with these requirements, we will try to delete your information quickly upon request. Please note, however, that there might be latency in deleting information from our servers and backed-up versions might exist after deletion. In addition, we do not delete from our servers files that you have in common with other&amp;nbsp;users.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Not exactly the most comforting information to learn from your cloud storage&amp;nbsp;provider.&lt;/p&gt;
&lt;h2&gt;Cloud Security&amp;nbsp;Solutions&lt;/h2&gt;
&lt;p&gt;The concept is quite simple: storage providers holding your data shouldn&amp;#8217;t be able to open it.  This is why whatever security solution cloud storage providers propose, it would most likely fail this very litmus&amp;nbsp;test.&lt;/p&gt;
&lt;p&gt;Then how do we solve this?  Secure or lock your data up &lt;em&gt;before&lt;/em&gt; it goes into the &amp;#8220;cloud&amp;#8221;.&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;You can easily do this right now by creating a zip archive with a password of your data using tools like &lt;a href="http://www.7-zip.org/" title="7-zip"&gt;7-zip&lt;/a&gt;, which provides &amp;#8220;strong &lt;span class="caps"&gt;AES&lt;/span&gt;-256 encryption in 7z and &lt;span class="caps"&gt;ZIP&lt;/span&gt; formats&amp;#8221;.&lt;br /&gt;
&lt;/p&gt;
&lt;h2&gt;Credential Management System in Cloud&amp;nbsp;Security&lt;/h2&gt;
&lt;p&gt;One of the pitfalls of manual password management is the level of password uniqueness.  People usually have one or a few passwords they like to use for all purposes.  The chance of someone breaking one of those passwords and using it to open other files is very&amp;nbsp;possible.&lt;/p&gt;
&lt;p&gt;However, attempting to remember multiple passwords, repetition of extraction &lt;span class="amp"&gt;&amp;amp;&lt;/span&gt; compression every time you need to work on your files will definitely drive you insane!&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;What we really need is a practical credential management system for these secured data.  Here, &amp;#8220;practical&amp;#8221; means something regular folks can actually use without sacrificing&amp;nbsp;security.&lt;/p&gt;
&lt;h2&gt;Secure Collaboration and Sharing in the&amp;nbsp;Cloud&lt;/h2&gt;
&lt;p&gt;Most of cloud storage providers currently have a way for users to share data with others.  Sharing a secured file, however, is a more complicated problem.&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;Again, it still boils down to: how do we manage credentials for secured files in the collaboration use case?  Surely sending the credentials via email isn&amp;#8217;t the best solution; especially if the collaboration happens with a large group of&amp;nbsp;people.&lt;/p&gt;
&lt;h2&gt;Seamless Credential Management&amp;nbsp;System&lt;/h2&gt;
&lt;p&gt;For a credential management system to be viable for both consumer and enterprise, it needs to be able&amp;nbsp;to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Generate unique passwords for each&amp;nbsp;file &lt;/li&gt;
&lt;li&gt;Have mechanism to share or revoke access to file with others in collaborative&amp;nbsp;workflows&lt;/li&gt;
&lt;li&gt;Have a foolproof way to recover file for owners in case of forgetting credentials (because we&amp;#8217;re only humans and humans often&amp;nbsp;forget!)&lt;/li&gt;
&lt;li&gt;Use open and standard technologies that won&amp;#8217;t make files useless when the company goes out of&amp;nbsp;business&lt;/li&gt;
&lt;li&gt;Abstract 1-4 and shield users from the all complexities and what&amp;#8217;s going on under the&amp;nbsp;hood&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So far, there have been quite a few attempts at solving the cloud security &lt;span class="amp"&gt;&amp;amp;&lt;/span&gt; privacy problem.  However, no one has emerged to be the clear winner and more are quickly joining the race.&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;One thing is clear, all players must first convince consumers that there&amp;#8217;s a problem before they can go about peddling their&amp;nbsp;solutions.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Vuong Nguyen</dc:creator><pubDate>Tue, 26 Mar 2013 00:00:00 -0400</pubDate><guid>tag:vuongnguyen.com,2013-03-26:personal-business-cloud-security.html</guid><category>technology</category><category>cloud</category><category>security</category><category>encryption</category><category>cloud storage providers</category><category>dropbox</category><category>google drive</category><category>skydrive</category><category>icloud</category></item><item><title>Installing M2Crypto on CentOS, RedHat or Fedora</title><link>http://vuongnguyen.com/installing-python-m2crypto-on-centos-redhat-fedora.html</link><description>&lt;p&gt;Installing &lt;a href="http://pypi.python.org/pypi/M2Crypto/" title="M2Crypto"&gt;M2Crypto&lt;/a&gt;, a feature-rich &lt;a href="http://www.python.org/" title="Python"&gt;Python&lt;/a&gt; wrapper for &lt;a href="http://www.openssl.org/" title="OpenSSL"&gt;OpenSSL&lt;/a&gt;, should be a simple matter of running &lt;code&gt;pip install M2Crypto&lt;/code&gt;.  However, it seems that on CentOS, RedHat or other Fedora Core-based distributions, especially 32-bit operating system running on 64-bit hardware, it is a bit&amp;nbsp;tricky.&lt;/p&gt;
&lt;p&gt;Here are the requirements for the current version (0.21.1) taken from M2Crypto &lt;a href="http://chandlerproject.org/Projects/MeTooCrypto" title="MeTooCrypto"&gt;home page&lt;/a&gt;: Python 2.3+, OpenSSL 0.9.7+, &lt;span class="caps"&gt;SWIG&lt;/span&gt; 1.3.28+.  Skimming through the &lt;span class="caps"&gt;INSTALL&lt;/span&gt; notes, we stumble on &amp;#8220;Note about Fedora Core -based&amp;nbsp;Distributions&amp;#8221;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;Fedora Core (and RedHat, CentOS etc.) have made changes to OpenSSL configuration compared to many other Linux distributions. If you can not build M2Crypto normally, try the fedora_setup.sh script included with M2Crypto&amp;nbsp;sources.&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Error with &lt;code&gt;pip install M2Crypto&lt;/code&gt; on CentOS, RedHat or&amp;nbsp;Fedora:&lt;/h2&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;...
/usr/include/openssl/opensslconf.h:31: Error: CPP &lt;span class="c"&gt;#error &amp;quot;&amp;quot;This openssl-devel package does not work your architecture?&amp;quot;&amp;quot;. Use the -cpperraswarn option to continue swig processing.&lt;/span&gt;

error: &lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;swig&amp;#39;&lt;/span&gt; failed with &lt;span class="nb"&gt;exit &lt;/span&gt;status 1
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Okay, so it didn&amp;#8217;t build normally.  Let&amp;#8217;s see if we can build it manually using &lt;code&gt;fedora_setup.sh&lt;/code&gt; as recommened in the &lt;span class="caps"&gt;INSTALL&lt;/span&gt;&amp;nbsp;notes. &lt;/p&gt;
&lt;p&gt;With your &lt;code&gt;virtualenv&lt;/code&gt; environment activated, the failed &lt;code&gt;pip install M2Crypto&lt;/code&gt; above would have left behind the downloaded files in &lt;code&gt;&amp;lt;your-virtualenv-path&amp;gt;/build/M2Crypto&lt;/code&gt;.  If you don&amp;#8217;t use &lt;code&gt;virtualenv&lt;/code&gt; (you should!), you can download a copy of &lt;a href="http://pypi.python.org/packages/source/M/M2Crypto/" title="Download M2Crypto on Pypi"&gt;M2Crypto on Pypi&lt;/a&gt;.&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;Normally, going into this directory and run &lt;code&gt;./fedora_setup.sh build&lt;/code&gt; and then &lt;code&gt;./fedora_setup.sh install&lt;/code&gt; work fine and you&amp;#8217;re done.  However, if you run into the &lt;code&gt;Unable to find 'openssl/opensslconf-i686.h'&lt;/code&gt; error as shown below, then you have 32-bit operating system running on 64-bit&amp;nbsp;hardware.&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="c"&gt;# don&amp;#39;t forget to give yourself permission to execute the script&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;chmod u+x fedora_setup.sh
&lt;span class="nv"&gt;$ &lt;/span&gt;./fedora_setup.sh build
running build
running build_py
running build_ext
building &lt;span class="s1"&gt;&amp;#39;M2Crypto.__m2crypto&amp;#39;&lt;/span&gt; extension
swigging &lt;span class="caps"&gt;SWIG&lt;/span&gt;/_m2crypto.i to &lt;span class="caps"&gt;SWIG&lt;/span&gt;/_m2crypto_wrap.c
swig -python -I/usr/include/python2.6 -I/usr/include -includeall -o &lt;span class="caps"&gt;SWIG&lt;/span&gt;/_m2crypto_wrap.c &lt;span class="caps"&gt;SWIG&lt;/span&gt;/_m2crypto.i
&lt;span class="caps"&gt;SWIG&lt;/span&gt;/_evp.i:12: Error: Unable to find &lt;span class="s1"&gt;&amp;#39;openssl/opensslconf-i686.h&amp;#39;&lt;/span&gt;
&lt;span class="caps"&gt;SWIG&lt;/span&gt;/_ec.i:7: Error: Unable to find &lt;span class="s1"&gt;&amp;#39;openssl/opensslconf-i686.h&amp;#39;&lt;/span&gt;
error: &lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;swig&amp;#39;&lt;/span&gt; failed with &lt;span class="nb"&gt;exit &lt;/span&gt;status 1
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Taking a look at &lt;code&gt;fedora_setup.sh&lt;/code&gt;, we see &lt;code&gt;arch =&lt;/code&gt;&amp;acute;&lt;code&gt;uname -m&lt;/code&gt;&amp;acute; which yields &lt;code&gt;i686&lt;/code&gt; but you&amp;#8217;re really running &lt;code&gt;i386&lt;/code&gt; operating system.  The simplest thing to do here is to just create a symbolic link of the file &lt;code&gt;openssl/opensslconf-i386.h&lt;/code&gt; to &lt;code&gt;openssl/opensslconf-i686.h&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Finally, installing M2Crypto for 32-bit CentOS, RedHat and Fedora running on 64-bit&amp;nbsp;harware:&lt;/h2&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="c"&gt;# just to make sure our file name database is up-to-date&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;sudo updatedb

&lt;span class="c"&gt;# locate opensslconf-* file&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;locate openssl|grep &lt;span class="s1"&gt;&amp;#39;opensslconf-&amp;#39;&lt;/span&gt;
/usr/include/openssl/opensslconf-i386.h

&lt;span class="c"&gt;# create a symbolic link&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;sudo ln -s /usr/include/openssl/opensslconf-i386.h /usr/include/openssl/opensslconf-i686.h

&lt;span class="c"&gt;# just build &lt;span class="amp"&gt;&amp;amp;&lt;/span&gt; install and you&amp;#39;re all set!&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;./fedora_setup.sh build
&lt;span class="nv"&gt;$ &lt;/span&gt;./fedora_setup.sh install
&lt;/pre&gt;&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Vuong Nguyen</dc:creator><pubDate>Tue, 05 Feb 2013 00:00:00 -0500</pubDate><guid>tag:vuongnguyen.com,2013-02-05:installing-python-m2crypto-on-centos-redhat-fedora.html</guid><category>pip</category><category>python</category><category>m2crypto</category><category>centos</category><category>redhat</category><category>fedora</category><category>linux</category><category>i386</category><category>i686</category></item><item><title>My List of Commonly-Used Git Commands</title><link>http://vuongnguyen.com/common-useful-git-commands.html</link><description>&lt;p&gt;One of the tools I use on a daily basis is &lt;a href="http://git-scm.com/" title="Git"&gt;Git&lt;/a&gt;, a &lt;a href="http://en.wikipedia.org/wiki/Distributed_revision_control" title="Distributed Version Control System"&gt;Distributed Version Control System&lt;/a&gt; (&lt;span class="caps"&gt;DVCS&lt;/span&gt;). Other than the usual &lt;code&gt;git checkout -b branch&lt;/code&gt;, &lt;code&gt;git tag -a&lt;/code&gt; and &lt;code&gt;git merge/push/pull&lt;/code&gt;, the Git workflow generally demands very little of me to keep the repository under control.&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;If not for a few &amp;#8220;human errors&amp;#8221; that happen once in a while (or a couple of times every week), there&amp;#8217;s not much to write home about.  In those instances, I have to admit that relying on the search engine to answer specific questions usually gets things done faster than parsing the man/help page or going through the docs. Lazy.  I&amp;nbsp;know!&lt;/p&gt;
&lt;p&gt;After repeating the same process a few times and finding answers on different sites, I decided to just compile a list as I go along rather than trying to remember the search terms I used to get the answer last time.  In any case, here is the list of my commonly-used as well as &amp;#8220;almost&amp;#8221; commonly-used Git&amp;nbsp;commands. &lt;/p&gt;
&lt;h2&gt;Branching with&amp;nbsp;Git&lt;/h2&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="c"&gt;#list all branches&lt;/span&gt;
git branch -l

&lt;span class="c"&gt;# create and immediately checkout a new branch&lt;/span&gt;
git checkout -b &lt;span class="o"&gt;[&lt;/span&gt;branchname&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="c"&gt;# create a new branch&lt;/span&gt;
git branch &lt;span class="o"&gt;[&lt;/span&gt;branchname&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="c"&gt;# delete branch&lt;/span&gt;
git branch -d &lt;span class="o"&gt;[&lt;/span&gt;branchname&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="c"&gt;# all local branches up to remote repository&lt;/span&gt;
git push &lt;span class="o"&gt;[&lt;/span&gt;remotename&lt;span class="o"&gt;]&lt;/span&gt; --all

&lt;span class="c"&gt;# delete remote branch&lt;/span&gt;
git push &lt;span class="o"&gt;[&lt;/span&gt;remotename&lt;span class="o"&gt;]&lt;/span&gt; :&lt;span class="o"&gt;[&lt;/span&gt;branch name&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="c"&gt;# track a remote repository&lt;/span&gt;
git branch --track &lt;span class="o"&gt;[&lt;/span&gt;branchname&lt;span class="o"&gt;]&lt;/span&gt; origin/&lt;span class="o"&gt;[&lt;/span&gt;branchname&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Tagging with&amp;nbsp;Git&lt;/h2&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="c"&gt;# list all available tags&lt;/span&gt;
git tag -l

&lt;span class="c"&gt;# create an annotated tag&lt;/span&gt;
git tag -a &lt;span class="o"&gt;[&lt;/span&gt;tagname&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="c"&gt;# delete tag&lt;/span&gt;
git tag -d &lt;span class="o"&gt;[&lt;/span&gt;tagname&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="c"&gt;# remove remote tag&lt;/span&gt;
git push &lt;span class="o"&gt;[&lt;/span&gt;remotename&lt;span class="o"&gt;]&lt;/span&gt; :refs/tags/&lt;span class="o"&gt;[&lt;/span&gt;tagname&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="c"&gt;# push all local tags to remote&lt;/span&gt;
git push &lt;span class="o"&gt;[&lt;/span&gt;remotename&lt;span class="o"&gt;]&lt;/span&gt; --tags

&lt;span class="c"&gt;# fetch all remote tags&lt;/span&gt;
git fetch --tags

&lt;span class="c"&gt;# show verbose view of the tag&lt;/span&gt;
git show &lt;span class="o"&gt;[&lt;/span&gt;tagname&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Remote Repository Management with&amp;nbsp;Git&lt;/h2&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="c"&gt;# view existing remote urls&lt;/span&gt;
git remote -v

&lt;span class="c"&gt;# change origin remote&amp;#39;s &lt;span class="caps"&gt;URL&lt;/span&gt;&lt;/span&gt;
git remote &lt;span class="nb"&gt;set&lt;/span&gt;-url origin &lt;span class="o"&gt;[&lt;/span&gt;path to new repository&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="c"&gt;# add remote&lt;/span&gt;
git remote add &lt;span class="o"&gt;[&lt;/span&gt;remote-name&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;path to remote repository&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="c"&gt;# pull changes from remote&lt;/span&gt;
get fetch &lt;span class="o"&gt;[&lt;/span&gt;remote-name&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Other Commonly-used git&amp;nbsp;Commands&lt;/h2&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="c"&gt;# merge codes with another branch&lt;/span&gt;
git merge &lt;span class="o"&gt;[&lt;/span&gt;branchname&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="c"&gt;# neater way to view git log that I actually created an alias called &amp;quot;git_pretty&amp;quot;&lt;/span&gt;
git log --pretty&lt;span class="o"&gt;=&lt;/span&gt;oneline --max-count&lt;span class="o"&gt;=[&lt;/span&gt;no. of lines&lt;span class="o"&gt;]&lt;/span&gt; --abbrev-commit
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I plan to update this list every time I have to search for the same thing twice!  So what are some of your commonly used git&amp;nbsp;commands?&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Vuong Nguyen</dc:creator><pubDate>Mon, 28 Jan 2013 00:00:00 -0500</pubDate><guid>tag:vuongnguyen.com,2013-01-28:common-useful-git-commands.html</guid><category>technology</category><category>git</category><category>github</category><category>subversion</category><category>svn</category><category>tips</category><category>programming</category><category>distributed version control system</category><category>dvcs</category></item><item><title>Inline Read More Link in Python Using lxml</title><link>http://vuongnguyen.com/creating-inline-read-more-link-python-pelican-lxml.html</link><description>&lt;p&gt;When dealing with displaying large html content, we need a way to generate its summary and a &amp;#8220;read more&amp;#8221; or &amp;#8220;continue&amp;#8221; link to the full article.&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;This is a simple matter of truncating the html content at a defined maximum word count and adding the convenient ellipsis&amp;nbsp;(&amp;#8230;).&lt;/p&gt;
&lt;p&gt;For&amp;nbsp;instance:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;Full html:
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;paragraph 1&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&lt;/span&gt;paragraph 2&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&lt;/span&gt;paragraph 3&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&lt;/span&gt;paragraph 4&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

Truncated html:
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;paragraph 1&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&lt;/span&gt;paragraph 2...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The problem is: most of the time trying to add a &amp;#8220;read more&amp;#8221; link to &lt;code&gt;&amp;lt;p&amp;gt;paragraph 1&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;paragraph 2...&amp;lt;/p&amp;gt;&lt;/code&gt; would put the link outside of the html content.  This results in a really frustrating line break since &lt;code&gt;&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;/code&gt; is a block element.  In my opinion, the line break is disruptive and not as aesthetically&amp;nbsp;pleasing.&lt;/p&gt;
&lt;p&gt;What we really&amp;nbsp;want:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;Instead of:
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;paragraph 1&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&lt;/span&gt;paragraph 2...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/read-more/&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;read more&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;

We want:
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;paragraph 1&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&lt;/span&gt;paragraph 2...&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/read-more/&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;read more&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I ran into this pet peeve a while back when I was trying to add an inline &amp;#8220;answer&amp;#8221; link to my question &lt;span class="amp"&gt;&amp;amp;&lt;/span&gt; answer joke for &lt;a href="http://officecheese.com/joke/truck-unfortunate-teenager/" title="OfficeCheese - Calcium for office funny bones"&gt;officecheese.com&lt;/a&gt;.  Here are the python codes I wrote to address&amp;nbsp;this:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;insert_into_last_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;lxml.html&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;fragment_fromstring&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fragments_fromstring&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tostring&lt;/span&gt;
        &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;lxml.etree&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ParserError&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;ImportError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Unable to find lxml&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fragment_fromstring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;ParserError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ne"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fragment_fromstring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fragments_fromstring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tostring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;ParserError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ne"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Seeing that the same need exists in &lt;code&gt;Pelican&lt;/code&gt;, I added the functionality to my fork, which is located &lt;a href="https://github.com/VuongN/pelican/commit/31c984e39363c4c1d0e89f9d1fd98a3d9fec1272" title=" Inline Read More Link in Pelican"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I hope this is useful to you and if anyone has suggestions for improvement, please don&amp;#8217;t hesitate to let me&amp;nbsp;know.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Vuong Nguyen</dc:creator><pubDate>Sun, 06 Jan 2013 00:00:00 -0500</pubDate><guid>tag:vuongnguyen.com,2013-01-06:creating-inline-read-more-link-python-pelican-lxml.html</guid><category>technology</category><category>python</category><category>pelican</category><category>lxml</category><category>programming</category></item><item><title>Creating Mid-Autumn Festival Lantern for Mây Sơn</title><link>http://vuongnguyen.com/creating-mid-autumn-festival-lantern.html</link><description>&lt;p&gt;Growing up in Việt Nam as a kid, when the lights of electricity had yet to pollute the world and the night sky was truly black, a lantern had mysterious power over my&amp;nbsp;childhood. &lt;/p&gt;
&lt;p&gt;How can it not be?  Imagine sitting under a sky of a million stars listening to the songs of nature: leaves singing, cricket chirping, earth turning and even the sounds of silence in brief moments.  And when that lantern shined as it swayed to the rhythm of the autumn winds, it was as if you had your own little&amp;nbsp;star.&lt;/p&gt;
&lt;p&gt;With a culture of &amp;#8220;sweets&amp;#8221; and &amp;#8220;lights&amp;#8221;, Tết Trung Thu or Mid-Autumn Festival was indeed the &amp;#8220;Children&amp;#8217;s New Year&amp;#8221;.  Even for an adult, it remains a wonderful reminiscence of how simple life used to&amp;nbsp;be.&lt;/p&gt;
&lt;p&gt;This will be our little daughter Mây Sơn&amp;#8217;s first Tết Trung Thu.  Being only four months old, I don&amp;#8217;t think she understands the significance of this tết yet.  Still, she loves colors and lights; so I set out to learn and create a lantern in time for her own little&amp;nbsp;&amp;#8220;festival&amp;#8221;.&lt;/p&gt;
&lt;h2&gt;Design&lt;/h2&gt;
&lt;p&gt;Mây Sơn was born in the year of the dragon and is nicknamed &amp;#8220;Rồng Con&amp;#8221; or &amp;#8220;Baby Dragon&amp;#8221; by my family.  I wanted to design a lantern just for her.  After some thinking, I decided on a lantern with the intent and spirit of: an &lt;strong&gt;egg cracking to give birth to a little baby dragon&lt;/strong&gt;.&lt;br /&gt;
&lt;/p&gt;
&lt;h2&gt;Materials&lt;/h2&gt;
&lt;p&gt;Raw bamboo, multicolor Cellophane sheets, thick paper (for the dragon cutout), metal wires, glue, clear tape, needle and&amp;nbsp;thread.&lt;/p&gt;
&lt;div id="trung-thu-lantern" class="carousel slide" data-interval="false"&gt;
    &lt;div class="carousel-inner"&gt;
        &lt;div class="item active"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/design.jpg" atl="Lantern Design"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;I made a simple sketch of the lantern and details of certain parts.  I was excited to see how this will turn&amp;nbsp;out.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/1.jpg" atl="Bamboo"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Trying to be authentic to my childhood, I had hoped to use raw bamboo; however, getting raw and green bamboo in the &lt;span class="caps"&gt;U.S.&lt;/span&gt; was challenging due to the shipping cost.  After a few phone calls to a bamboo farm in Mississippi, I decided to go with the dried decorative bamboo found in the local art supplies&amp;nbsp;store.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/2.jpg" atl="Splitting Bamboo"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Since these dried bamboo sticks have a lot of knots, splitting them was very difficult at first. I ended up using a combination of my mother&amp;#8217;s big kitchen knife, an axe and a hammer to get the job&amp;nbsp;done.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/3.jpg" atl="Main Rings for Drum"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Even in the dried state, I was very surprised at how flexible and strong the bamboo was.  Although just to be on the safe side, I ran them under hot water&amp;nbsp;anyway.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/4.jpg" atl="Wire Binding Details"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Growing up in Việt Nam, I often used rubber band to bind bamboo.  It&amp;#8217;s quick and strong but didn&amp;#8217;t last very long.  Here, I used metal wires as a superior replacement for binding the bamboo sticks&amp;nbsp;together.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/5.jpg" atl="Wire Binding Details 2"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Another close-up of the wire&amp;nbsp;bindings.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/6.jpg" atl="Drum Frame Complete"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;The drum frame and the two main egg rings&amp;nbsp;complete.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/7.jpg" atl="Egg Frames Complete"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Egg frames&amp;nbsp;complete!&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/8.jpg" atl="Fixing Cracked Bamboo"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Oops. I discovered a small crack in one of the drum frame rings. I really didn&amp;#8217;t want to undo all the wire bindings so I slabbed on a supporting bamboo piece and bound them together with&amp;nbsp;wires.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/9.jpg" atl="Sawing Thick Bamboo"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Since I was working with dried bamboo, I needed to use a saw to cut the main bar for the drum.  This bar will act as the base for the spinning&amp;nbsp;dragon.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/10.jpg" atl="Center Bar Complete"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Center bar successfully attached to the drum with a hole in the center.  This is where I plan to place the&amp;nbsp;spinner.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/11.jpg" atl="Smoothing and Drilling Bamboo"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Started working on the spinner&amp;#8217;s base. I used sand papers to smooth out the bamboo in hope that it will be smooth for&amp;nbsp;spinning.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/12.jpg" atl="Drilling Bamboo"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Drilling bamboo is surprisingly stressful as it can crack very easily.  Here, I started with the smaller drill head and slowly moved up until I widened the hole.  I was planning to insert a thinner stick of bamboo to hold up the spinning&amp;nbsp;dragon.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/13.jpg" atl="Cracked Bamboo"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Cracked!  Well, that didn&amp;#8217;t work.  When I was trying to &amp;#8220;tighten&amp;#8221; up the joined bamboo, the nicely-sanded piece cracked.  I would have to suspend the dragon from the top rather than holding it up from the&amp;nbsp;bottom.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/14.jpg" atl="Cellophane Test"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;At the end of the first night, the drum and egg frames were complete.  Here, I was testing to see how the Cellophane sheets would look on the drum.  Not&amp;nbsp;bad!&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/15.jpg" atl="Egg Frame with Cellophane"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Using a glue stick, I was able to attache the Cellophane sheets to the drum.  However, I noticed that the glue stick was a bit waxy and left dirty residues on the bamboo and&amp;nbsp;plastic.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/16.jpg" atl="Sewing Cellophane to Bamboo"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;My wife suggested that I use needle and threads to bind the Cellophane with the bamboo.  Sewing was fun, but definitely much more&amp;nbsp;time-consuming.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/17.jpg" atl="Colorful Cellophane on Bamboo"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;All done with attaching the Cellophane to the bamboo frames.  I cheated a bit here and used clear tapes where ever sewing was a much more difficult option.  Look at all those vibrant colors on the egg&amp;nbsp;shells!&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/18.jpg" atl="Bamboo Frames Bounded"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Here, the two egg shells and the drum were now bound together with&amp;nbsp;wires.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/19.jpg" atl="Paper Cutout of Dragon"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Started working on the paper cutout of the dragon to create the silhouette for the&amp;nbsp;drum.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/20.jpg" atl="Cutting Eye for the Dragon"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Opening up the dragon&amp;#8217;s&amp;nbsp;eyes.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/21.jpg" atl="Final Rush Before Nightfall"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;This was me rushing to the finish line before&amp;nbsp;nightfall.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/22.jpg" atl="All Done"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;All done.  Added the &lt;span class="caps"&gt;LED&lt;/span&gt; candles to the bottom of the egg&amp;nbsp;shells.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/23.jpg" atl="Dragon Chasing Heart"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Close-up of the dragon chasing a&amp;nbsp;heart.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/24.jpg" atl="Dragon Silhouette"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Dragon&amp;nbsp;silhouette.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/25.jpg" atl="Dragon Silhouette"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Another dragon&amp;nbsp;silhouette.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/26.jpg" atl="Drum Close-up"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Drum&amp;nbsp;close-up&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/27.jpg" atl="Dragon in Drum Close-up"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Dragon-in-drum close-up.  Notice the bow at the dragon&amp;#8217;s tail?  Yes, it&amp;#8217;s a girl&amp;nbsp;dragon.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="item"&gt;
            &lt;img src="/static/img/articles/trung-thu-2012/28.jpg" atl="Dragon Seen Through Egg Shell"&gt;
            &lt;div class="carousel-caption"&gt;
                &lt;p&gt;Dragon silhouette seen through egg&amp;nbsp;shells.&lt;/p&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;a class="left carousel-control" href="#trung-thu-lantern" data-slide="prev"&gt;&amp;lsaquo;&lt;/a&gt;
    &lt;a class="right carousel-control" href="#trung-thu-lantern" data-slide="next"&gt;&amp;rsaquo;&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;This was the first time I created a Trung Thu lantern from scratch in the &lt;span class="caps"&gt;U.S.&lt;/span&gt; After gathering the raw materials, it came down to trial and error and ultimately problem solving the&amp;nbsp;design.&lt;/p&gt;
&lt;p&gt;It was a great feeling to work with raw bamboo like a kid; but the greatest joy was knowing that I was creating something from scratch for my&amp;nbsp;daughter.&lt;/p&gt;
&lt;p&gt;After dinner, we turned off all the lights in the house.&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;Carried by grandma, followed by mommy singing a popular Tết Trung Thu tune, led by daddy holding the lantern, Mây Sơn had her traditional &amp;#8220;rước đèn&amp;#8221; or lantern and moon welcoming procession around the house.  She smiled sweetly at the lantern but was perhaps more curiously amused at the&amp;nbsp;commotion.&lt;/p&gt;
&lt;p&gt;Holding Mây Sơn&amp;#8217;s hand as she was falling asleep later that evening, I realized she grew so much in the past few months.  She is so much bigger in body and spirit.  In a new world, where everything is a new learning opportunity for her, she also gives my family and I many opportunities to learn.  Love remains a perpetual&amp;nbsp;lesson.&lt;/p&gt;
&lt;p&gt;Happy first Tết Trung Thu, little Mây Sơn.  Don&amp;#8217;t grow up too fast, con gái; we&amp;#8217;re still trying to catch our&amp;nbsp;breath.&lt;/p&gt;
&lt;script src="/static/js/jquery-1.7.2.min.js"&gt;&lt;/script&gt;

&lt;script src="/theme/bootstrap/js/bootstrap.min.js"&gt;&lt;/script&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Vuong Nguyen</dc:creator><pubDate>Sun, 30 Sep 2012 00:00:00 -0400</pubDate><guid>tag:vuongnguyen.com,2012-09-30:creating-mid-autumn-festival-lantern.html</guid><category>arts &amp; crafts</category><category>tết trung thu</category><category>mid-autumn festival</category><category>harvest</category><category>moon</category></item><item><title>jQuery-Fakecrop: Cropping Images with jQuery</title><link>http://vuongnguyen.com/fake-cropping-images-with-jquery.html</link><description>&lt;p&gt;Once in a while, you just want to display a collection (or more) of images with different dimensions.  The problem &lt;em&gt;seems&lt;/em&gt; easy&amp;nbsp;enough.&lt;/p&gt;
&lt;p&gt;The task of manually creating thumbnail for each image is quite tedious and it&amp;#8217;s definitely not worth the trouble to write a script to generate the thumbnails either.  Let&amp;#8217;s face it, this starts to feel&amp;#8230;&amp;nbsp;annoying.&lt;/p&gt;
&lt;p&gt;Now, being a problem solver and a big proponent of &lt;a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself/" title="Don't Repeat Yourself"&gt;&lt;span class="caps"&gt;DRY&lt;/span&gt;&lt;/a&gt;, I created &lt;code&gt;jQuery-Fakecrop&lt;/code&gt;, a &lt;a href="http://jquery.com/" title="jQuery - write ess, do more"&gt;&lt;code&gt;jQuery&lt;/code&gt;&lt;/a&gt;&amp;nbsp;plugin. &lt;/p&gt;
&lt;p&gt;&lt;code&gt;jQuery-Fakecrop&lt;/code&gt; takes a collection of images and automatically scale them to fit a custom-defined bounding box.  This creates a &amp;#8220;fake&amp;#8221; cropping effect on those images; which produces convincing&amp;nbsp;thumbnails.&lt;/p&gt;
&lt;p&gt;Below is the demo as well as the links to download &lt;span class="amp"&gt;&amp;amp;&lt;/span&gt; fork this&amp;nbsp;plugin.&lt;/p&gt;
&lt;div class="download-fork"&gt;
    &lt;a class="btn btn-large btn-success" href="https://github.com/VuongN/jQuery-Fakecrop/zipball/master/" title="Click to download jQuery-Fakecrop" target="_blank"&gt;Download &lt;i class="icon-download icon-white"&gt;&lt;/i&gt;&lt;/a&gt;
    &lt;a class="btn btn-large btn-success" href="https://github.com/VuongN/jQuery-Fakecrop/" title="Click to fork jQuery-Fakecrop on github" target="_blank"&gt;Fork on GitHub &lt;i class="icon-share-alt icon-white"&gt;&lt;/i&gt;&lt;/a&gt;
&lt;/div&gt;

&lt;h2&gt;Quick&amp;nbsp;Start&lt;/h2&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/path/to/jquery-library.js&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/path/to/jquery.fakecrop.js&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// for a filled square thumbnail&lt;/span&gt;
        &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;img&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;fakecrop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// for a fixed width/height&lt;/span&gt;
        &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;img&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;fakecrop&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Normal&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;&lt;span class="caps"&gt;NOTE&lt;/span&gt;: Since every image in this collection has extremely different dimensions, I restricted the height of the images to 100 pixel in &lt;span class="caps"&gt;CSS&lt;/span&gt; so this part of the page doesn&amp;#8217;t look so&amp;#8230;&amp;nbsp;terrible.&lt;/em&gt;&lt;/p&gt;
&lt;div id="fakecrop-normal" class="section"&gt;
    &lt;script&gt;
        // This function just write 10 images to the document where ever executed
        // since we don't want to repeat ourselves
        function makeImages(amount) {
            var i = 1, src = '';
            for (var i=1;i&lt;amount+1;i++) {
                src = 'static/img/demo/' + i + '.jpg';
                document.write('&lt;a href="' + src + '"&gt;&lt;img src="' + src + '" alt="Image ' + i + '" /&gt;&lt;/a&gt;' );
            }   
        }
        makeImages(10);
    &lt;/script&gt;
&lt;/div&gt;

&lt;h2&gt;With Fakecrop&amp;nbsp;(default)&lt;/h2&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;#fakecrop-fill img&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;fakecrop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;div id="fakecrop-fill" class="section"&gt;&lt;script&gt;makeImages(10);&lt;/script&gt;&lt;/div&gt;

&lt;h2&gt;With Fakecrop &lt;code&gt;{fill : false}&lt;/code&gt;&lt;/h2&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;#fakecrop img&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;fakecrop&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;div id="fakecrop-nonfill" class="section"&gt;&lt;script&gt;makeImages(10);&lt;/script&gt;&lt;/div&gt;

&lt;p&gt;Public domain photographs courtesy of &lt;a href="http://www.ars.usda.gov/is/graphics/photos/" title="United State Department of Agriculture"&gt;United State Department of&amp;nbsp;Agriculture&lt;/a&gt;&lt;/p&gt;
&lt;script src="/static/js/jquery-1.7.2.min.js"&gt;&lt;/script&gt;

&lt;script src="/static/js/plugins/jquery.fakecrop.js"&gt;&lt;/script&gt;

&lt;script&gt;
$(document).ready(function () {
    $('#fakecrop-fill img').fakecrop();
    $('#fakecrop-nonfill img').fakecrop({ fill : false });
});
&lt;/script&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Vuong Nguyen</dc:creator><pubDate>Wed, 13 Jun 2012 00:00:00 -0400</pubDate><guid>tag:vuongnguyen.com,2012-06-13:fake-cropping-images-with-jquery.html</guid><category>javascript</category><category>jquery</category><category>plugin</category><category>open source</category><category>web</category><category>front-end</category></item><item><title>Setting Menu Active State Using HTML and CSS</title><link>http://vuongnguyen.com/menu-active-state-using-html-css.html</link><description>&lt;p&gt;Setting menu active state should be simple in any programming languages or frameworks.  Checking whether a &lt;code&gt;page_id&lt;/code&gt; or an &lt;code&gt;Object&lt;/code&gt; is the same as the current page in context is usually all that&amp;#8217;s&amp;nbsp;required.&lt;/p&gt;
&lt;p&gt;When using a template engine, such as &lt;a href="http://jinja.pocoo.org/" title="Jinja template engine"&gt;&lt;code&gt;jinja&lt;/code&gt;&lt;/a&gt; in &lt;a href="https://www.djangoproject.com/" title="The Web framework for perfectionists (with deadlines)"&gt;&lt;code&gt;Django&lt;/code&gt;&lt;/a&gt; or &lt;a href="http://pelican.notmyidea.org" title="Python Pelican"&gt;&lt;code&gt;python pelican&lt;/code&gt;&lt;/a&gt;, I sometime skip the extra logic in the templates and just bring it to the &lt;span class="caps"&gt;HTML&lt;/span&gt;/&lt;span class="caps"&gt;CSS&lt;/span&gt; layer especially if I have to insert the &lt;code&gt;page_id&lt;/code&gt; at the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag for one reason or another&amp;nbsp;anyway.&lt;/p&gt;
&lt;h2&gt;Before:&lt;/h2&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="n"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/about/&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;page_id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;about-page&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;active&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;endif&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;About&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;/**&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="n"&gt;styles&lt;/span&gt; &lt;span class="o"&gt;**/&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;After:&lt;/h2&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="n"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;{{ page_id }}&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;...&lt;/span&gt;
&lt;span class="o"&gt;...&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;about-menu-item&amp;quot;&lt;/span&gt; &lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/about/&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;About&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;...&lt;/span&gt;

&lt;span class="n"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="c"&gt;#about-page #about-menu-item, .active { /** active state styles **/ }&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I like to have &lt;code&gt;{% block body_tag %}&amp;lt;body&amp;gt;{% endblock %}&lt;/code&gt; in my base template file.  That way, in other children templates like the &lt;code&gt;archives.html&lt;/code&gt; of my &lt;code&gt;pelican&lt;/code&gt; theme, I can have &lt;code&gt;{% block body_tag %}&amp;lt;body id="archive-page"&amp;gt;{% endblock %}&lt;/code&gt; without the need to set the &lt;code&gt;page_id&lt;/code&gt; in the backend&amp;nbsp;codes.&lt;/p&gt;
&lt;p&gt;Like all things, when used in moderation and for the right situations, this technique can be a great addition to your bag of tricks as a front-end web&amp;nbsp;developer.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Vuong Nguyen</dc:creator><pubDate>Mon, 11 Jun 2012 00:00:00 -0400</pubDate><guid>tag:vuongnguyen.com,2012-06-11:menu-active-state-using-html-css.html</guid><category>html</category><category>css</category><category>django</category><category>pelican</category><category>jinja</category><category>front-end</category><category>web</category><category>development</category></item><item><title>Eating Striped Bass Organs and Innards</title><link>http://vuongnguyen.com/eating-striped-bass-organs-innards.html</link><description>&lt;p&gt;&lt;img class="img-right img-rounded img-polaroid pull-right" src="/static/img/articles/striped-bass.jpg" alt="A Striped Bass" title="A Striped Bass" /&gt;Other than our short temper, my brother and I share little in common.  Our hobbies and activities are also completely different.  While I love arts and technology, he is an accountant, a true &amp;#8220;foodie&amp;#8221; and an avid&amp;nbsp;fisherman.&lt;/p&gt;
&lt;p&gt;Having said that, I love my brother dearly and would find any opportunity to spend time with him.  Since the thought of him joining me in a brotherly hackathon is a little absurd, one of the most joyful activities we do together happens to be&amp;nbsp;fishing.&lt;/p&gt;
&lt;p&gt;Whenever I find myself sitting in the middle of the dark ocean with the frigid winds howling and the &amp;#8220;pup-pup&amp;#8221; sounds of the waves hitting the sides of the fiberglass boat, it&amp;#8217;s often dawn on me how foreign this experience is to me.  It&amp;#8217;s definitely &lt;em&gt;nothing&lt;/em&gt; like programming at all as the joy of reeling in a striped bass is&amp;nbsp;indescribable!&lt;/p&gt;
&lt;p&gt;Striped bass is difficult to catch, especially for amateur like myself.  On a boat of four or five people, it would be a good night to go ashore with one per person.  Still, someone always catch one and that&amp;#8217;s the beauty and hope of the hobbyist&amp;nbsp;fisherman.&lt;/p&gt;
&lt;p&gt;When the stars are aligned in form of big catch and no work the following day, nothing is better than a celebratory impromptu get-together.  At these Vietnamese drinking bash or &amp;#8220;nhậu&amp;#8221;, the striped bass is usually cooked into a few courses: fish rice porridge (with the head), seared fillet and the most unique of all, sautéed organs and innards.  Like the efforts on the sea, no part of the fish is to be&amp;nbsp;wasted.&lt;/p&gt;
&lt;p&gt;Usually, the fish is gutted first to keep the precious innards and organs including the gills as fresh as possible.  While waiting for a pot of water, the innards are cleaned under salted water.  The washed innards are then quickly dipped into the boiled water before some more scrubbing with a sharp spoon, especially the&amp;nbsp;intestines. &lt;/p&gt;
&lt;p&gt;&lt;img class="img-left img-rounded img-polaroid pull-left" src="/static/img/articles/eating-striped-bass-organs-innards.jpg" alt="Eating Striped Bass Organs and Innards" title="Eating Striped Bass Organs and Innards" /&gt;After a nice cleaning, all innards are washed again with water and marinated with crushed black peppers, fish sauce, sugar and turmeric powder.  The whole thing is then allowed to sit for a short time while a few onions is thickly sliced. When everything is done, there would be a bowl of the marinated innards and another bowl of sliced&amp;nbsp;onions.&lt;/p&gt;
&lt;p&gt;Only the innards are thrown onto a hot pan with a little bit of olive oil and stir for a few minutes.  As the pan is turning into a nice golden color from the turmeric powder, the onions are then tossed in to join the medley.  If the group is up for it, a red-hot chilly pepper is thrown to spice it up.  A few more minutes of stirring and you get the most amazing drinking food: striped bass organs and innards with sautéed onion and turmeric powder.  A small bowl of soy sauce and with chilly pepper and if available, a plate of fresh herbal vegetables would be the best &amp;#8220;Amen&amp;#8221; to a heavenly&amp;nbsp;meal.&lt;/p&gt;
&lt;p&gt;As I write this article, I think some fisherman or fisherwoman is out there without the deserving credit of inventing this unique and tasty dish.  To whoever you are, thank&amp;nbsp;you!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Vuong Nguyen</dc:creator><pubDate>Fri, 08 Jun 2012 00:00:00 -0400</pubDate><guid>tag:vuongnguyen.com,2012-06-08:eating-striped-bass-organs-innards.html</guid><category>food</category><category>fishing</category><category>striped bass</category><category>innards</category><category>organs</category></item><item><title>Creating a Blog with Python Pelican</title><link>http://vuongnguyen.com/creating-blog-python-virtualenv-pelican.html</link><description>&lt;p&gt;Let&amp;#8217;s move beyond the &lt;strong&gt;when&lt;/strong&gt; and &lt;strong&gt;why&lt;/strong&gt; of a personal blog of a web developer and discuss the &lt;strong&gt;what&lt;/strong&gt; and &lt;strong&gt;how&lt;/strong&gt;.  The current trend seems to favor the static site generation route and I agree whole-heartedly.  Static pages are easier and faster to host and less vulnerable to security issues of other database-driven tools such as &lt;a href="http://wordpress.org" title="Wordpress"&gt;Wordpress&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One of the more popular tools for static site generation is &lt;a href="http://octopress.org/" title="Octopress"&gt;Octopress&lt;/a&gt;, dubbing itself &amp;#8220;A blogging framework for hackers.&amp;#8221;  While I think &lt;code&gt;Octopress&lt;/code&gt; looks great, I am not a Ruby guy.  Thus, my search for a python equivalent ended with &lt;a href="http://pelican.notmyidea.org" title="Python Pelican"&gt;python pelican&lt;/a&gt;.  We&amp;#8217;ll dive right in and create a virtual environment to keep &lt;code&gt;pelican&lt;/code&gt; and its dependencies&amp;nbsp;isolated:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;virtualenv /path/to/pelican_env
&lt;span class="nb"&gt;source&lt;/span&gt; /path/to/pelican_env/bin/activate
pip install pelican markdown
pelican-quickstart
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;code&gt;pelican&lt;/code&gt; is now installed.  Note that I am using &lt;code&gt;markdown&lt;/code&gt; (&lt;code&gt;pelican&lt;/code&gt; gives you the choice between &lt;code&gt;markdown&lt;/code&gt; or &lt;code&gt;reStructuredText&lt;/code&gt; or both).  Go through all the guided steps following the command &lt;code&gt;pelican-quickstart&lt;/code&gt;.  This should give you a basic structure&amp;nbsp;of:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;output/     src/    pelican.conf.py
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;You may also add a few more&amp;nbsp;directories:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="c"&gt;# all .md files in the markdown/ directory will be used to generated articles&lt;/span&gt;
markdown/
&lt;span class="c"&gt;# all .md files in the pages/ directory will be used to generate pages&lt;/span&gt;
pages/
&lt;span class="c"&gt;# a few static directories to be copied into output/static/ (more on STATIC_PATHS setting below)&lt;/span&gt;
img/    css/    js/
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;At this point, running the command &amp;#8220;&lt;code&gt;pelican -s pelican.conf.py .&lt;/code&gt;&amp;#8221; in the directory would generate all static files for the blog using the default theme &lt;code&gt;notmyidea&lt;/code&gt; into the &lt;code&gt;output/&lt;/code&gt; directory.  Just serve this directory as you would any other static &lt;code&gt;html&lt;/code&gt; files.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re like me, you&amp;#8217;re probably interested in creating your own theme.  If this is the case, you can create your own theme from one of the default themes, I suggest &lt;a href="https://github.com/getpelican/pelican/tree/master/pelican/themes/simple" title="GitHub Pelican Repository"&gt;simple&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I am creating a directory and calling it &lt;code&gt;theme&lt;/code&gt; and copy &lt;code&gt;pelican/themes/simple/templates&lt;/code&gt; into &lt;code&gt;theme&lt;/code&gt;.  In your settings file &lt;code&gt;pelican.conf.py&lt;/code&gt; add the following&amp;nbsp;line:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="n"&gt;&lt;span class="caps"&gt;THEME&lt;/span&gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;theme&amp;#39;&lt;/span&gt; &lt;span class="c"&gt;#or whatever name you chose for your theme&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;(&lt;span class="caps"&gt;NOTE&lt;/span&gt;: you could also simply create a &lt;code&gt;templates&lt;/code&gt; directory in your &lt;code&gt;theme&lt;/code&gt; directory with the following files: &lt;code&gt;index.html&lt;/code&gt;, &lt;code&gt;article.html&lt;/code&gt;, &lt;code&gt;page.html&lt;/code&gt;, &lt;code&gt;category.html&lt;/code&gt;, &lt;code&gt;tag.html&lt;/code&gt; and a &lt;code&gt;base.html&lt;/code&gt; for your common&amp;nbsp;layout)&lt;/p&gt;
&lt;p&gt;Here are a few more useful&amp;nbsp;settings:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="c"&gt;# static files to copy into root, very useful for robots.txt&lt;/span&gt;
&lt;span class="n"&gt;FILES_TO_COPY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;extra/robots.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;robots.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;extra/humans.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;humans.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;# directories to be copied into output/static/&lt;/span&gt;
&lt;span class="n"&gt;STATIC_PATHS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;img&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;css&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;js&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c"&gt;# very useful for debugging purposes&lt;/span&gt;
&lt;span class="n"&gt;DELETE_OUTPUT_DIRECTORY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The basic idea is that &lt;code&gt;pelican&lt;/code&gt; will be using the template files in your &lt;code&gt;theme/templates/&lt;/code&gt; directory to generate all static &lt;code&gt;html&lt;/code&gt; files.  &lt;code&gt;pelican&lt;/code&gt; uses &lt;a href="http://jinja.pocoo.org/docs/" title="Jinja"&gt;Jinja&lt;/a&gt; for is templating language, which should be quite familiar for &lt;a href="http://djangoproject.com" title="Django Web Framework"&gt;&lt;code&gt;Django&lt;/code&gt;&lt;/a&gt; developers. In these templates, you should have access to all variables from &lt;code&gt;pelican.conf.py&lt;/code&gt; as well as template-specific variables (please refer to the &amp;#8220;Template and Variables&amp;#8221; section of the documents for more&amp;nbsp;information). &lt;/p&gt;
&lt;p&gt;Make appropriate edits to the template files and run &amp;#8220;&lt;code&gt;pelican -s pelican.conf.py .&lt;/code&gt;&amp;#8221; again.  You should now see your changes in the &lt;code&gt;html&lt;/code&gt; files generated in &lt;code&gt;output/&lt;/code&gt; directory.&lt;/p&gt;
&lt;p&gt;Hopefully this post motivated any developers or engineers still on the fence about starting a personal blog to finally make it happen.  Good luck and have fun&amp;nbsp;blogging!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Vuong Nguyen</dc:creator><pubDate>Wed, 06 Jun 2012 00:00:00 -0400</pubDate><guid>tag:vuongnguyen.com,2012-06-06:creating-blog-python-virtualenv-pelican.html</guid><category>technology</category><category>python</category><category>pelican</category><category>virtualenv</category><category>blogging</category><category>octopress</category><category>jinja</category><category>markdown</category><category>django</category></item><item><title>Rice Paddy and Crabs in Viet Nam</title><link>http://vuongnguyen.com/rice-paddy-crabs-vietnam.html</link><description>&lt;p&gt;&lt;em&gt;I visited Viet Nam in the summer of 2008 and jotted down some memories.  This was written on June 4th,&amp;nbsp;2008&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img class="img-left img-rounded img-polaroid pull-left" src="/static/img/articles/rice-paddies-mountains.jpg" alt="Rice Paddies and Mountains" /&gt;I felt the smooth and squishy earth between my toes.  That was last week.  Standing in a flooded rice paddy with water just above my ankles, it felt like my childhood has woken up after a long slumber.  The air and cold breezes carrying the fragrance of live mud together with the biting sunrays on my face placed me in a rather poetic&amp;nbsp;setting.&lt;/p&gt;
&lt;p&gt;Perhaps rice was recently harvested here and the paddies are left nude for the dry season.  Then again, I&amp;#8217;m only guessing.  But this much I know: surrounding me is a vast and seemingly infinite flat land of water-filled rice paddies shimmering with a million&amp;nbsp;suns.&lt;/p&gt;
&lt;p&gt;Breezes seemed to only come from one direction.  I was sure of this because all the grasses were leaning only one way or at least around where I was standing&amp;nbsp;anyway.&lt;/p&gt;
&lt;p&gt;My cousin, who was out herding his family pack of goats, accompanied me to the field.  As the joke went, I was there to milk the goats.  There was no milking of course and I found out later that they were all male&amp;nbsp;goats.&lt;/p&gt;
&lt;p&gt;Much younger than I am, the cousin was an excited one.  He was rushing me everywhere on the field whenever he saw small caves believed to be crabs&amp;#8217;&amp;nbsp;dwellings.&lt;/p&gt;
&lt;p&gt;Still new to the old feelings, my bare feet inched slowly forward.  I looked nervously as the clear water became muddy following each step.  The first cave was a small underwater opening located at the rice paddy&amp;#8217;s&amp;nbsp;floor.&lt;/p&gt;
&lt;p&gt;The cousin motioned me to push my hand in to find the crab.  I did this kind of things quite a few times when I was growing up here, so my actions were fluid.  But my hand is bigger than thirteen years ago.  The cramp feeling, as if my hand can be sucked in or stuck any moment, made the first contact with the dweller a bit chilly.&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;&lt;img class="img-right img-rounded img-polaroid pull-right" src="/static/img/articles/cousin-catching-rice-paddy-crabs.jpg" alt="Cousin Catching Rice Paddy Crabs" /&gt;The sharp needle-like legs and big curvy claws were less than comfortable in soft mud.  I quickly pushed my hands below the crab and performed a scoop-up action.  In my hand, there was now a layer of mud and above it, my victim struggling hopelessly.  As my hand, which was buried up to the elbow, inches out of what felt like a tube of mud, I could feel the sharp crab legs pinching my hand through the layer of mud.  It was tingly.  I only wish there weren&amp;#8217;t any pebbles on the way out.  But there were, and they did a number on&amp;nbsp;knuckles.&lt;/p&gt;
&lt;p&gt;As my hand and the crab closes to the opening, my cousin cheered in excitement: &amp;#8220;Slowly! Slowly! Don&amp;#8217;t let it get away!&amp;#8221;  Finally, it was out.  Water rushes the mud out of my palm to show a male crab with its two claws snapping at my fingers.  I quickly dropped it into the bucket with a bit of water to join a few my cousins had caught moments ago.  For about another thirty minutes, the excitements happened a few more times.  Each time was a different personality of crab and each time left a new mark on my&amp;nbsp;hand.&lt;/p&gt;
&lt;p&gt;By the end of the adventure, we got over twenty rice paddy crabs.  Most were only as big as the size of lime.  We left them in a bucket with hope that there would be more the next day&amp;mdash;perhaps enough for a pot of &amp;#8220;bún riêu&amp;#8221;, a Vietnamese vermicelli soup with crabmeat as the key&amp;nbsp;ingredient.&lt;/p&gt;
&lt;p&gt;&lt;img class="img-left img-rounded img-polaroid pull-left" src="/static/img/articles/water-clovers-lucky-field.jpg" alt="Water Clovers Lucky Field" /&gt;One thing I forgot to mention was the &amp;#8220;lucky field&amp;#8221; I discovered in one rice paddy.  I found big patches of clovers floating in water, all with four leaves.  They were clovers, if not, a type of vegetation very close to the clovers&amp;#8217; family.  I told myself that I would take a photograph the next time I come&amp;nbsp;back.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Vuong Nguyen</dc:creator><pubDate>Fri, 01 Jun 2012 00:00:00 -0400</pubDate><guid>tag:vuongnguyen.com,2012-06-01:rice-paddy-crabs-vietnam.html</guid><category>vietnam</category><category>travel</category><category>memories</category><category>reflection</category><category>crab</category><category>writing</category></item><item><title>Hello (Learning) World</title><link>http://vuongnguyen.com/hello-learning-world.html</link><description>&lt;p&gt;Starting a personal blog is something I have wanted to do for a very long time.  However, my priority list tends to favor non-personal action&amp;nbsp;items.&lt;/p&gt;
&lt;p&gt;As a web developer, technology consultant and &lt;em&gt;especially&lt;/em&gt; as a bootstrap startup enthusiast, it makes sense to produce work that has a fixed or potential monetary&amp;nbsp;value.&lt;/p&gt;
&lt;p&gt;As a growing and developing person, though, I remain curious and constantly thrive to maintain an obsession of learning.  With a finite memory, it is increasingly important that I archive new lessons and&amp;nbsp;reflections.&lt;/p&gt;
&lt;p&gt;Thus, with much humility, I started this blog in hope to record and share a few of my personal thoughts.  If by chance, someone other than myself find my writings helpful in their quest of learning, then I am&amp;nbsp;satisfied.&lt;/p&gt;
&lt;p&gt;&lt;span class="caps"&gt;NOTE&lt;/span&gt;: In producing this blog, I have strengthened my python knowledge, used &lt;code&gt;virtualenv&lt;/code&gt;, &lt;code&gt;markdown&lt;/code&gt; and learned how to use &lt;a href="http://pelican.notmyidea.org"&gt;python pelican&lt;/a&gt;.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Vuong Nguyen</dc:creator><pubDate>Mon, 28 May 2012 00:00:00 -0400</pubDate><guid>tag:vuongnguyen.com,2012-05-28:hello-learning-world.html</guid><category>hello</category><category>learning</category><category>news</category><category>pelican</category><category>python</category><category>blog</category></item></channel></rss>