<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.kunxi.org/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.kunxi.org/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Refactor the Life</title>
	
	<link>http://kunxi.org</link>
	<description>Yet another code monkey blog.</description>
	<pubDate>Tue, 18 Nov 2008 06:59:54 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.1</generator>
	<language>en</language>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.kunxi.org/rtl" type="application/rss+xml" /><feedburner:emailServiceId>191470</feedburner:emailServiceId><feedburner:feedburnerHostname>http://www.feedburner.com</feedburner:feedburnerHostname><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><item>
		<title>Poor man’s NAS</title>
		<link>http://feeds.kunxi.org/~r/rtl/~3/456860956/</link>
		<comments>http://kunxi.org/archives/2008/11/poor-mans-nas/#comments</comments>
		<pubDate>Sat, 15 Nov 2008 02:42:26 +0000</pubDate>
		<dc:creator>bookstack</dc:creator>
		
		<category><![CDATA[Gentoo]]></category>

		<category><![CDATA[linux]]></category>

		<category><![CDATA[mybook]]></category>

		<category><![CDATA[samba]]></category>

		<guid isPermaLink="false">http://kunxi.org/?p=315</guid>
		<description><![CDATA[A Network Attached Storage(NAS) has been in my wanted list for quite a long time, thanks to Live Search Cashback program to make it happen: a Western Digital MyBook World Edition(500GB). More information about the hardware specification:

ARM926EJ-Sid(wb) [41069265] revision 5 (ARMv5TEJ) 99.73 MHz
Memory: 32M
VIA Networking Velocity Family Gigabit Ethernet 
WD5000AAVS-0 500G HD

I believe 100MHz ARM [...]<p><a href="http://sharethis.com/item?&#038;wp=2.6.1&#38;publisher=&#38;title=Poor+man%26%238217%3Bs+NAS&#38;url=http%3A%2F%2Fkunxi.org%2Farchives%2F2008%2F11%2Fpoor-mans-nas%2F">ShareThis</a></p>]]></description>
			<content:encoded><![CDATA[<p>A Network Attached Storage(NAS) has been in my wanted list for quite a long time, thanks to <a href="http://search.live.com/cashback/">Live Search Cashback</a> program to make it happen: a Western Digital MyBook World Edition(500GB). More information about the hardware specification:</p>
<ul>
<li>ARM926EJ-Sid(wb) [41069265] revision 5 (ARMv5TEJ) 99.73 MHz</li>
<li>Memory: 32M</li>
<li>VIA Networking Velocity Family Gigabit Ethernet </li>
<li>WD5000AAVS-0 500G HD</li>
</ul>
<p>I believe 100MHz ARM CPU is powerful enough to drive this tiny box, but the limited capacity of memory cripples it as a lame duck. The sustainable file write(85G using lftp mirror) rate is approximately 3.8MB/s. It hardly qualifies any service beyond file server. Now, it is time to hack.</p>
<h1>Jailbreak and SSH</h1>
<p>The first thing to do is to create a user in the web interface of MyBook as root with null password is banned for security reason. Log on with <em>admin</em> and <em>123456</em>, create a user <em>JOE</em> and setup the password for later use.</p>
<p>Run the script discussed in the <a href="http://mybookworld.wikidot.com/first-steps-with-mbwe#toc0">wiki</a>, and ssh with JOE. Now you can su to root with blank password, 0wned!</p>
<h1>User management</h1>
<p>MyBook takes a very intricate way to manage users:</p>
<p>All Samba users are granted shell access, but <em>unix password sync = yes</em> is not set, the <em>/etc/shadow</em> and <em>/var/private/smbpasswd</em> are updated individually by a Perl script via the web interface. The only reasonable explanation is the minimized Samba lacks PAM support.</p>
<p>All user names are capitalized. I assume this is a brutal force approach to address the difference between Samba and Linux native accounts: Windows user name is case insensitive, while Linux is case-sensitive.</p>
<p>As the password scrambled in <em>/etc/shadow</em>, it is easier to add/delete/update users via the web interface, then fine-tune the corresponding files. The user administration executives are hidden in <em>/usr/www/nbin</em>.</p>
<h1>Share with Samba</h1>
<p>The default exported directory is <em>/share/internal/PUBLIC</em>, the permission of the directory is set as <em>rwsr-sr-x</em>, and the owner is <em>www-data</em>, YMMV. So any file/directory created will be owned by www-data. If you are unhappy with the name, you may add a user, e.g joe as discussed before, then add joe to www-data group:</p>
<div class="codesnip-container" ># /etc/group, YMMV<br />
www-data:x:33:share</div>
<p>remember to change the default mask in /etc/smb.conf:</p>
<div class="codesnip-container" >create mask = 0775<br />
directory mask = 0775</div>
<h1>Package management</h1>
<p>Though I am a big fan of Gentoo, it is a little bit paranoid to build everything from scratch. A precompiled package management, like <a href="http://www.nslu2-linux.org/wiki/Optware/Packages?from=Unslung.Packages">Optware</a> makes more sense. Check out <a href="http://mybookworld.wikidot.com/optware ">this tutorial</a> for bootstrapping.</p>
<p>The essential packages for daily administration imho are screen, lftp.</p>
<h1>Feature requests</h1>
<p>There are some itchy miss features, if you happen to know a solution or hint, please drop me a message in the comment:</p>
<p><strong>Access Anywhere</strong>  No mionet, just SSH. If you are a perfectionist, consider to port <a href="http://www.thecodecave.com/article337">this Delphi application</a> to MyBook to host MyBook in your preferred domain.</p>
<p><strong>Download Manager</strong>  A web front-end to listen to download requests from Firefox/IE plugins, then delegate it to wget backend with cookie support. A more aggressive approach may support megaupload happy hour.</p>
<div class="feedflare">
<a href="http://feeds.kunxi.org/~f/rtl?a=vKu4N"><img src="http://feeds.kunxi.org/~f/rtl?i=vKu4N" border="0"></img></a> <a href="http://feeds.kunxi.org/~f/rtl?a=cTWnn"><img src="http://feeds.kunxi.org/~f/rtl?i=cTWnn" border="0"></img></a>
</div><img src="http://feeds.kunxi.org/~r/rtl/~4/456860956" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://kunxi.org/archives/2008/11/poor-mans-nas/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=rtl&amp;itemurl=http%3A%2F%2Fkunxi.org%2Farchives%2F2008%2F11%2Fpoor-mans-nas%2F</feedburner:awareness><feedburner:origLink>http://kunxi.org/archives/2008/11/poor-mans-nas/</feedburner:origLink></item>
		<item>
		<title>Rewrite WordPress and ZenPhoto for Nginx</title>
		<link>http://feeds.kunxi.org/~r/rtl/~3/449633469/</link>
		<comments>http://kunxi.org/archives/2008/10/rewrite-wordpress-and-zenphoto-for-nginx/#comments</comments>
		<pubDate>Wed, 15 Oct 2008 15:08:47 +0000</pubDate>
		<dc:creator>bookstack</dc:creator>
		
		<category><![CDATA[Web]]></category>

		<category><![CDATA[mod_rewrite]]></category>

		<category><![CDATA[nginx]]></category>

		<category><![CDATA[wordpress]]></category>

		<category><![CDATA[zenphoto]]></category>

		<guid isPermaLink="false">http://kunxi.org/?p=300</guid>
		<description><![CDATA[Nginx also supports URL rewrite, not compatible to Apache&#8217;s mod_rewrite, but more intuitive and more powerful imho. The only problem is most applications, WordPress and ZenPhoto for this specific case do include the mod_rewrite code snippet and/or may update the .htaccess for your convenience.
Thanks to the Slicehost community, the port of mod_rewrite rules perfectly covers [...]<p><a href="http://sharethis.com/item?&#038;wp=2.6.1&#38;publisher=&#38;title=Rewrite+WordPress+and+ZenPhoto+for+Nginx&#38;url=http%3A%2F%2Fkunxi.org%2Farchives%2F2008%2F10%2Frewrite-wordpress-and-zenphoto-for-nginx%2F">ShareThis</a></p>]]></description>
			<content:encoded><![CDATA[<p>Nginx also supports URL rewrite, not compatible to Apache&#8217;s mod_rewrite, but more intuitive and more powerful imho. The only problem is most applications, WordPress and ZenPhoto for this specific case do include the mod_rewrite code snippet and/or may update the .htaccess for your convenience.</p>
<p>Thanks to the <a href="http://forum.slicehost.com/comments.php?DiscussionID=2087">Slicehost community</a>, the port of mod_rewrite rules perfectly covers WordPress and SuperCache. Here are some minor modification to craft for more general usage:</p>
<div class="codesnip-container" ># the blog dir, aka where index.php is<br />
            set $blog_dir &#8221;;<br />
            # the wordpress dir where all wp-* stays<br />
            set $wordpress_dir &#8216;/wordpress&#8217;;<br />
            include wordpress.rewrite;</div>
<p>In nginx.conf, define wordpress_dir and blog_dir, these two variables are equivalent to WordPress address (URL) and Blog address (URL) stripped off the host information. Then we can replace the hard-coded /blog path by using $wordpress_dir or $blog_dir:</p>
<div class="codesnip-container" >2d1<br />
<<br />
26c25<br />
< set $supercache_file /blog/wp-content/cache/supercache/$http_host/$1index.html;<br />
---<br />
>     set $supercache_file $wordpress_dir/wp-content/cache/supercache/$http_host/$1index.html;<br />
36c35<br />
< rewrite . /blog/index.php last;<br />
---<br />
>     rewrite ^(.*)$ $blog_dir/index.php?q=$1 last;</div>
<p>Here is my <a href="http://static.kunxi.org/rewrite-wordpress-and-zenphoto-for-nginx/zenphoto.rewrite">zenphoto.rewrite</a>, it seems <a href="http://cdn.sivel.net/z/e/zenphoto_nginx_rewrites.txt">sivel&#8217;s</a> more concise. Either of these should work.</p>
<div class="feedflare">
<a href="http://feeds.kunxi.org/~f/rtl?a=sbWlN"><img src="http://feeds.kunxi.org/~f/rtl?i=sbWlN" border="0"></img></a> <a href="http://feeds.kunxi.org/~f/rtl?a=wMqXn"><img src="http://feeds.kunxi.org/~f/rtl?i=wMqXn" border="0"></img></a>
</div><img src="http://feeds.kunxi.org/~r/rtl/~4/449633469" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://kunxi.org/archives/2008/10/rewrite-wordpress-and-zenphoto-for-nginx/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=rtl&amp;itemurl=http%3A%2F%2Fkunxi.org%2Farchives%2F2008%2F10%2Frewrite-wordpress-and-zenphoto-for-nginx%2F</feedburner:awareness><feedburner:origLink>http://kunxi.org/archives/2008/10/rewrite-wordpress-and-zenphoto-for-nginx/</feedburner:origLink></item>
		<item>
		<title>Parse HTML file with BeautifulSoup</title>
		<link>http://feeds.kunxi.org/~r/rtl/~3/419237797/</link>
		<comments>http://kunxi.org/archives/2008/10/parse-html-file-with-beautifulsoup/#comments</comments>
		<pubDate>Mon, 13 Oct 2008 06:20:35 +0000</pubDate>
		<dc:creator>bookstack</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://kunxi.org/?p=307</guid>
		<description><![CDATA[In the last post, regular expression is used to fetch the specific information. To access the structured information,  BeautifulSoap BeautifulSoup is preferred for its simplicity and convenient API:

You may override the fromEncoding in the constructor, this is very useful for non-roman, non-standard web pages.
Versatile find/findAll on tag, attributes.
Developer-friendly syntactic sugar, the Tag implements the [...]<p><a href="http://sharethis.com/item?&#038;wp=2.6.1&#38;publisher=&#38;title=Parse+HTML+file+with+BeautifulSoup&#38;url=http%3A%2F%2Fkunxi.org%2Farchives%2F2008%2F10%2Fparse-html-file-with-beautifulsoup%2F">ShareThis</a></p>]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://kunxi.org/archives/2008/10/wys-is-not-always-wyg-in-pythonre/">last post</a>, regular expression is used to fetch the specific information. To access the structured information,  <del datetime="2008-10-13T02:28:37+00:00">BeautifulSoap</del> <a href="http://www.crummy.com/software/BeautifulSoup/">BeautifulSoup</a> is preferred for its simplicity and convenient API:</p>
<ul>
<li>You may override the <em>fromEncoding</em> in the constructor, this is very useful for non-roman, non-standard web pages.</li>
<li>Versatile find/findAll on tag, attributes.</li>
<li>Developer-friendly syntactic sugar, the Tag implements the interface of string, list, dict and callable function, so there are many ways to access the data as you wish. The drawback of this approach is the typo is only caught in the run time instead of compilation time.</li>
<li>Easy to deploy, only one BeautifulSoup.py file.</li>
</ul>
<p>Something I don&#8217;t like:</p>
<ul>
<li>No XPath support, more efforts are needed to port from JavaScript.</li>
<li>The API does not support stream, or file object. Laziness is always cherished for pipelining.</li>
<li>Why BeautifulSoup? I have made typo as <em>soap</em> more than ten times.</li>
</ul>
<p>Here is the home-brewed script to wage through the <a href="http://www.dvbbs.net/">Dvbbs</a> thread to find the corresponding messages： <a href="http://static.kunxi.org/parse-html-file-with-beautifulsoup/elevator.py">elevator.py</a></p>
<div class="feedflare">
<a href="http://feeds.kunxi.org/~f/rtl?a=WXGoM"><img src="http://feeds.kunxi.org/~f/rtl?i=WXGoM" border="0"></img></a> <a href="http://feeds.kunxi.org/~f/rtl?a=TGxqm"><img src="http://feeds.kunxi.org/~f/rtl?i=TGxqm" border="0"></img></a>
</div><img src="http://feeds.kunxi.org/~r/rtl/~4/419237797" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://kunxi.org/archives/2008/10/parse-html-file-with-beautifulsoup/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=rtl&amp;itemurl=http%3A%2F%2Fkunxi.org%2Farchives%2F2008%2F10%2Fparse-html-file-with-beautifulsoup%2F</feedburner:awareness><feedburner:origLink>http://kunxi.org/archives/2008/10/parse-html-file-with-beautifulsoup/</feedburner:origLink></item>
		<item>
		<title>WYS is not always WYG in python.re</title>
		<link>http://feeds.kunxi.org/~r/rtl/~3/419169128/</link>
		<comments>http://kunxi.org/archives/2008/10/wys-is-not-always-wyg-in-pythonre/#comments</comments>
		<pubDate>Fri, 03 Oct 2008 06:22:36 +0000</pubDate>
		<dc:creator>bookstack</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[python]]></category>

		<category><![CDATA[unicode]]></category>

		<guid isPermaLink="false">http://kunxi.org/?p=301</guid>
		<description><![CDATA[After almost two month hard work, I finally check-in the feature, and tonight I decided to relax on some leisure python programming:
This side project is quite trivial, fetch the HTML content, search the keywords in the thread, and build links table of contents for navigation. The only intrigue highlight that make this post worthy your [...]<p><a href="http://sharethis.com/item?&#038;wp=2.6.1&#38;publisher=&#38;title=WYS+is+not+always+WYG+in+python.re&#38;url=http%3A%2F%2Fkunxi.org%2Farchives%2F2008%2F10%2Fwys-is-not-always-wyg-in-pythonre%2F">ShareThis</a></p>]]></description>
			<content:encoded><![CDATA[<p>After almost two month hard work, I finally check-in the feature, and tonight I decided to relax on some leisure python programming:</p>
<p>This side project is quite trivial, fetch the HTML content, search the keywords in the thread, and build links table of contents for navigation. The only intrigue highlight that make this post worthy your 5 minute is that the language of the page is Chinese, and it is encoded in GB2312.</p>
<p>Long story short, I am trying to search the total number of posts in the thread using this regular expression:</p>
<div class="codesnip-container" >
<div class="codesnip">pattern = <span class="kw3">re</span>.<span class="kw2">compile</span><span class="br0">&#40;</span><span class="st0">&#8216;(?&lt;=&lt;b class=&quot;page&quot;&gt;总数 )(?P&lt;total&gt;<span class="es0">\d</span>+)&#8217;</span><span class="br0">&#41;</span></div>
</div>
<p>The first catch is I have to declare the code page used for the source code, as python interpreter complains:</p>
<blockquote><p>SyntaxError: Non-ASCII character &#8216;\xe6&#8242; in file ./elevator.py on line 17, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
</p></blockquote>
<p>OK, I will stick to UTF-8, so add this declaration in the second line:<br />
<em># -*- coding: utf-8 -*-</em></p>
<p>It does not work. And the dumped content of the page is totally messy. Oops, we forget to decode the content to Unicode, use <em>codec</em> to wrap the <em>urlopen</em>ed handle:</p>
<div class="codesnip-container" >
<div class="codesnip">gb = <span class="kw3">codecs</span>.<span class="me1">lookup</span><span class="br0">&#40;</span><span class="st0">&#8216;gb2312&#8242;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="co1"># load the page</span><br />
&nbsp; &nbsp; content = gb.<span class="me1">streamreader</span><span class="br0">&#40;</span><span class="kw3">urllib</span>.<span class="me1">urlopen</span><span class="br0">&#40;</span>url<span class="br0">&#41;</span><span class="br0">&#41;</span>.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</div>
<p>And don&#8217;t forget to add either Unicode prefix or re.Unicode flag to the pattern.</p>
<div class="codesnip-container" >
<div class="codesnip">pattern = <span class="kw3">re</span>.<span class="kw2">compile</span><span class="br0">&#40;</span><span class="st0">&#8216;(?&lt;=&lt;b class=&quot;page&quot;&gt;总数 )(?P&lt;total&gt;<span class="es0">\d</span>+)&#8217;</span>, <span class="kw3">re</span>.<span class="kw2">UNICODE</span><span class="br0">&#41;</span></div>
</div>
<p>Still no luck, but it works in the python console with the same pattern, faked data, and also works if we change a little bit:</p>
<div class="codesnip-container" >
<div class="codesnip">pattern = <span class="kw3">re</span>.<span class="kw2">compile</span><span class="br0">&#40;</span><span class="st0">&#8216;(?&lt;=&lt;b class=&quot;page&quot;&gt;.{2} )(?P&lt;total&gt;<span class="es0">\d</span>+)&#8217;</span>, <span class="kw3">re</span>.<span class="kw2">UNICODE</span><span class="br0">&#41;</span></div>
</div>
<p>Looks like the trouble maker is the non-Latin characters: 总数. Let&#8217;s play a little bit in the pdb console:</p>
<div class="codesnip-container" >
<div class="codesnip"><span class="br0">&#40;</span><span class="kw3">Pdb</span><span class="br0">&#41;</span> <span class="st0">&#8216;总数&#8217;</span><br />
<span class="st0">&#8216;<span class="es0">\x</span>e6<span class="es0">\x</span>80<span class="es0">\x</span>bb<span class="es0">\x</span>e6<span class="es0">\x</span>95<span class="es0">\x</span>b0&#8242;</span><br />
<span class="br0">&#40;</span><span class="kw3">Pdb</span><span class="br0">&#41;</span> <span class="st0">&#8216;总数&#8217;</span>.<span class="me1">decode</span><span class="br0">&#40;</span><span class="st0">&#8216;utf8&#8242;</span><span class="br0">&#41;</span><br />
u<span class="st0">&#8216;<span class="es0">\u</span>603b<span class="es0">\u</span>6570&#8242;</span></div>
</div>
<p>And it works finally with the hard-coded Unicode character:</p>
<div class="codesnip-container" >
<div class="codesnip">pattern = <span class="kw3">re</span>.<span class="kw2">compile</span><span class="br0">&#40;</span><span class="st0">&#8216;(?&lt;=&lt;b class=&quot;page&quot;&gt;<span class="es0">\u</span>603b<span class="es0">\u</span>6570 )(?P&lt;total&gt;<span class="es0">\d</span>+)&#8217;</span>, <span class="kw3">re</span>.<span class="kw2">UNICODE</span><span class="br0">&#41;</span></div>
</div>
<p>We can use the decode method to avoid the ugly Unicode string for better readability:</p>
<div class="codesnip-container" >
<div class="codesnip">pattern = <span class="kw3">re</span>.<span class="kw2">compile</span><span class="br0">&#40;</span><span class="st0">&#8216;(?&lt;=&lt;b class=&quot;page&quot;&gt;总数 )(?P&lt;total&gt;<span class="es0">\d</span>+)&#8217;</span>decode<span class="br0">&#40;</span><span class="st0">&#8216;utf-8&#8242;</span><span class="br0">&#41;</span>, <span class="kw3">re</span>.<span class="kw2">UNICODE</span><span class="br0">&#41;</span></div>
</div>
<p>And a note is recorded that the decoded codec <strong>MUST</strong> be consistent to the code page declaration.</p>
<p>Some speculations based upon the observation:</p>
<ul>
<li>re.UNICODE does not enforce the Unicode mode, it just redefine the escaped characters like: \b, \w etc. </li>
<li>The pattern and string in Unicode implicitly invokes the Unicode mode. That explains why some pattern works in Python console only. Both of them are encoded in UTF-8, so re really runs in 8bit!</li>
<li>Python interpreter will not translate the literal string even though the code page is specified.</li>
</ul>
<p>Please leave your insight in the comments. Thanks</p>
<p><strong>UPDATE:</strong><br />
Thanks for all the comments first. Seems that I have a typo when testing the pattern with Unicode prefix. Here are the test cases:</p>
<div class="codesnip-container" >
<div class="codesnip">patterns = <span class="br0">&#91;</span><br />
&nbsp; &nbsp; <span class="kw3">re</span>.<span class="kw2">compile</span><span class="br0">&#40;</span><span class="st0">&#8216;(?&lt;=&lt;b class=&quot;page&quot;&gt;总数 )(?P&lt;total&gt;<span class="es0">\d</span>+)&lt;/b&gt;&#8217;</span>.<span class="me1">decode</span><span class="br0">&#40;</span><span class="st0">&#8216;utf8&#8242;</span><span class="br0">&#41;</span>, <span class="kw3">re</span>.<span class="kw2">UNICODE</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; <span class="kw3">re</span>.<span class="kw2">compile</span><span class="br0">&#40;</span>ur<span class="st0">&#8216;(?&lt;=&lt;b class=&quot;page&quot;&gt;总数 )(?P&lt;total&gt;<span class="es0">\d</span>+)&lt;/b&gt;&#8217;</span>, <span class="kw3">re</span>.<span class="kw2">UNICODE</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; <span class="kw3">re</span>.<span class="kw2">compile</span><span class="br0">&#40;</span>u<span class="st0">&#8216;(?&lt;=&lt;b class=&quot;page&quot;&gt;总数 )(?P&lt;total&gt;<span class="es0">\d</span>+)&lt;/b&gt;&#8217;</span>, <span class="kw3">re</span>.<span class="kw2">UNICODE</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; <span class="kw3">re</span>.<span class="kw2">compile</span><span class="br0">&#40;</span><span class="st0">&#8216;(?&lt;=&lt;b class=&quot;page&quot;&gt;总数 )(?P&lt;total&gt;<span class="es0">\d</span>+)&lt;/b&gt;&#8217;</span>, <span class="kw3">re</span>.<span class="kw2">UNICODE</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; <span class="br0">&#93;</span></p>
<p><span class="kw1">print</span> <span class="br0">&#91;</span> pattern.<span class="me1">search</span><span class="br0">&#40;</span>s<span class="br0">&#41;</span> <span class="kw1">for</span> pattern <span class="kw1">in</span> patterns <span class="br0">&#93;</span></div>
</div>
<p>The output is:</p>
<div class="codesnip-container" >
<div class="codesnip"><span class="br0">&#91;</span>&lt;_sre.<span class="me1">SRE_Match</span> <span class="kw2">object</span> at 0xb7c18260&gt;, &lt;_sre.<span class="me1">SRE_Match</span> <span class="kw2">object</span> at 0xb7c18360&gt;, &lt;_sre.<span class="me1">SRE_Match</span> <span class="kw2">object</span> at 0xb7c183a0&gt;, <span class="kw2">None</span><span class="br0">&#93;</span></div>
</div>
<p>Download <a href="http://static.kunxi.org/wyi-not-always-wyg-in-pythonr/test.py">test.py</a></p>
<div class="feedflare">
<a href="http://feeds.kunxi.org/~f/rtl?a=suZ5M"><img src="http://feeds.kunxi.org/~f/rtl?i=suZ5M" border="0"></img></a> <a href="http://feeds.kunxi.org/~f/rtl?a=DnEem"><img src="http://feeds.kunxi.org/~f/rtl?i=DnEem" border="0"></img></a>
</div><img src="http://feeds.kunxi.org/~r/rtl/~4/419169128" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://kunxi.org/archives/2008/10/wys-is-not-always-wyg-in-pythonre/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=rtl&amp;itemurl=http%3A%2F%2Fkunxi.org%2Farchives%2F2008%2F10%2Fwys-is-not-always-wyg-in-pythonre%2F</feedburner:awareness><feedburner:origLink>http://kunxi.org/archives/2008/10/wys-is-not-always-wyg-in-pythonre/</feedburner:origLink></item>
		<item>
		<title>HOWTO: Serve virtual host with Nginx</title>
		<link>http://feeds.kunxi.org/~r/rtl/~3/386117326/</link>
		<comments>http://kunxi.org/archives/2008/09/howto-server-virtual-host-with-nginx/#comments</comments>
		<pubDate>Sat, 06 Sep 2008 20:44:44 +0000</pubDate>
		<dc:creator>bookstack</dc:creator>
		
		<category><![CDATA[Web]]></category>

		<category><![CDATA[centos]]></category>

		<category><![CDATA[nginx]]></category>

		<category><![CDATA[vhost]]></category>

		<guid isPermaLink="false">http://kunxi.org/?p=290</guid>
		<description><![CDATA[As the limited memory budget, and I plan to host multiple website in the VPS, I decided to take a less versatile, but lightweight Apache alternative, the Nginx made by the polar bear.
There is no RPM in the repository I have enlisted, so let&#8217;s fallback the old-school way:

# remove the blocking glibc-dummy-centos-4 package, then get [...]<p><a href="http://sharethis.com/item?&#038;wp=2.6.1&#38;publisher=&#38;title=HOWTO%3A+Serve+virtual+host+with+Nginx&#38;url=http%3A%2F%2Fkunxi.org%2Farchives%2F2008%2F09%2Fhowto-server-virtual-host-with-nginx%2F">ShareThis</a></p>]]></description>
			<content:encoded><![CDATA[<p>As the limited memory budget, and I plan to host multiple website in the VPS, I decided to take a less versatile, but lightweight Apache alternative, the <a href="http://nginx.net/">Nginx</a> made by the polar bear.</p>
<p>There is no RPM in <a href="http://kunxi.org/archives/2008/09/vps-warm-up/">the repository I have enlisted</a>, so let&#8217;s fallback the old-school way:</p>
<div class="codesnip-container" >
<div class="codesnip"><span class="co1"># remove the blocking glibc-dummy-centos-4 package, then get the toolchain:</span><br />
yum remove glibc-dummy-centos-<span class="nu0">4</span><br />
yum -y install gcc openssl-devel<br />
<span class="co1"># Now it is time to build the nginx:</span><br />
./configure &#8211;<span class="re2">prefix=</span>/opt/nginx &#8211;with-http_ssl_module &#8211;with-http_stub_status_module<br />
make &amp;&amp; sudo make install</div>
</div>
<p>Then get the PHP with FastCGI support, and the lighttpd-fastcgi for the fastcgi loader.</p>
<div class="codesnip-container" >
<div class="codesnip">yum install php-cli php-mysql lighttpd-fastcgi</div>
</div>
<p>Here is the nginx.conf that server.</p>
<div class="codesnip-container" >user  nobody;<br />
worker_processes  2;<br />
pid  logs/nginx.pid;<br />
error_log  logs/error.log;</p>
<p>events {<br />
    worker_connections  2048;<br />
    use epoll;<br />
}</p>
<p>http {<br />
    include       mime.types;<br />
    include       fastcgi_params;<br />
    default_type  application/octet-stream;</p>
<p>    log_format  main  &#8216;$remote_addr - $remote_user [$time_local] $request &#8216;<br />
                      &#8216;&#8221;$status&#8221; $body_bytes_sent &#8220;$http_referer&#8221; &#8216;<br />
                      &#8216;&#8221;$http_user_agent&#8221; &#8220;$http_x_forwarded_for&#8221;&#8216;;</p>
<p>    access_log  logs/access.log  main;<br />
    client_header_timeout  3m;<br />
    client_body_timeout    3m;<br />
    send_timeout           3m;</p>
<p>    client_header_buffer_size    1k;<br />
    large_client_header_buffers  4 4k;</p>
<p>    gzip  on;<br />
    gzip_min_length  1100;<br />
    gzip_buffers     4 8k;<br />
    gzip_types       text/plain;<br />
    gzip_static on;</p>
<p>    output_buffers   1 32k;<br />
    postpone_output  1460;</p>
<p>    sendfile         on;<br />
    tcp_nopush       on;<br />
    tcp_nodelay      on;<br />
    keepalive_timeout  75 20;</p>
<p>    server {<br />
        #REVIEW: how to redirect https? using re?<br />
        server_name www.kunxi.org;<br />
        rewrite ^(.*) http://kunxi.org$1 permanent;<br />
    }</p>
<p>    server {<br />
        # kunxi&#8217;s gallery<br />
        listen       80;<br />
        server_name gallery.kunxi.org;<br />
        root /home/webadmin/$host;<br />
        access_log  logs/$host.log  main;</p>
<p>        location / {<br />
            root  /home/webadmin/$host;<br />
            index  index.html index.htm index.php;<br />
            include zenphoto.rewrite;<br />
        }</p>
<p>        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000<br />
        location ~ \.php$ {<br />
            fastcgi_pass   127.0.0.1:9000;<br />
            fastcgi_index  index.php;<br />
        }</p>
<p>        # deny access to .htaccess files.<br />
        location ~ /\.ht {<br />
            deny  all;<br />
        }<br />
    }</p>
<p>    server {<br />
        # kunxi&#8217;s sites<br />
        listen       80;<br />
        server_name kunxi.org *.kunxi.org;<br />
        root /home/webadmin/$host;</p>
<p>        error_page  404              $document_root/404.html;<br />
        error_page   500 502 503 504  $document_root/50x.html;<br />
        access_log  logs/$host.log  main;</p>
<p>        location / {<br />
            root  /home/webadmin/$host;<br />
            index  index.html index.htm index.php;</p>
<p>            # the blog dir, aka where index.php is<br />
            set $blog_dir &#8221;;<br />
            # the wordpress dir where all wp-* stays<br />
            set $wordpress_dir &#8216;/wordpress&#8217;;</p>
<p>            include wordpress.rewrite;<br />
        }</p>
<p>        # rewrite the /files/<br />
        #<br />
        location /files/ {<br />
            alias /home/webadmin/static.kunxi.org/;<br />
        }</p>
<p>        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000<br />
        #<br />
        location ~ \.php$ {<br />
            fastcgi_pass   127.0.0.1:9000;<br />
            fastcgi_index  index.php;<br />
        }</p>
<p>        # deny access to .htaccess files.<br />
        #<br />
        location ~ /\.ht {<br />
            deny  all;<br />
        }<br />
    }<br />
}</p></div>
<p>Some highlights of the configuration:<br />
Rewrite www.kunxi.org to kunxi.org, yes, we support <a href="http://no-www.org">no-www</a>!</p>
<div class="codesnip-container" >server {<br />
        #REVIEW: how to redirect https? using re?<br />
        server_name www.kunxi.org;<br />
        rewrite ^(.*) http://kunxi.org$1 permanent;<br />
    }</div>
<p>And this wildcards will cover all sub-domains powered by PHP:</p>
<div class="codesnip-container" >server_name kunxi.org *.kunxi.org;<br />
        root /home/webadmin/$host;<br />
        &#8230; &#8230;.</div>
<p>Home-brewed <a href="http://static.kunxi.org/howto-serve-virtual-host-with-nginx/nginx">nginx</a> and <a href="http://static.kunxi.org/howto-serve-virtual-host-with-nginx/fcgi-php">fastcgi</a> init scripts to make it works after the reboot:</p>
<div class="codesnip-container" >chkconfig &#8211;add nginx<br />
chkconfig &#8211;add fcgi-php<br />
service start nginx<br />
service start fcgi-php</div>
<p><strong>Tips and Traps:</strong><br />
Nginx supports 0 downtime upgrade, so if your nginx.conf is wrong, the server would ignore it and suck up the complain. Make sure stop the nginx service and start nginx during debugging rewrite rules.</p>
<p>fcgi-php seems to have problem to parse localhost, so I use 127.0.0.1 instead.</p>
<p>The rewrite rule for WordPress and ZenPhoto are explained here and here. (TODO).</p>
<div class="feedflare">
<a href="http://feeds.kunxi.org/~f/rtl?a=qh2FL"><img src="http://feeds.kunxi.org/~f/rtl?i=qh2FL" border="0"></img></a> <a href="http://feeds.kunxi.org/~f/rtl?a=FXNvl"><img src="http://feeds.kunxi.org/~f/rtl?i=FXNvl" border="0"></img></a>
</div><img src="http://feeds.kunxi.org/~r/rtl/~4/386117326" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://kunxi.org/archives/2008/09/howto-server-virtual-host-with-nginx/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=rtl&amp;itemurl=http%3A%2F%2Fkunxi.org%2Farchives%2F2008%2F09%2Fhowto-server-virtual-host-with-nginx%2F</feedburner:awareness><feedburner:origLink>http://kunxi.org/archives/2008/09/howto-server-virtual-host-with-nginx/</feedburner:origLink></item>
		<item>
		<title>Move to the new VPS, Yummy</title>
		<link>http://feeds.kunxi.org/~r/rtl/~3/385637426/</link>
		<comments>http://kunxi.org/archives/2008/09/vps-warm-up/#comments</comments>
		<pubDate>Thu, 04 Sep 2008 08:35:41 +0000</pubDate>
		<dc:creator>bookstack</dc:creator>
		
		<category><![CDATA[Web]]></category>

		<category><![CDATA[centos]]></category>

		<category><![CDATA[linux]]></category>

		<category><![CDATA[yum]]></category>

		<guid isPermaLink="false">http://www.kunxi.org/?p=284</guid>
		<description><![CDATA[I finally ride the trend of VPS, yes, I just bought Economy VPS COS4&#215;64 with 512M RAM, 200G HD and 350G bandwidth. The host is visualized via virtuozzo, and loaded with CentOS 4.4. 
The package management of RPM is quite lacking, so the first thing is to get YUM working:

rpm -Uvh http://mirror.centos.org/centos/4/os/x86_64/CentOS/RPMS/yum-2.4.3-4.el4.centos.noarch.rpm
rpm -Uvh http://mirror.centos.org/centos/4/os/x86_64/CentOS/RPMS/python-elementtree-1.2.6-5.el4.centos.x86_64.rpm
rpm -Uvh [...]<p><a href="http://sharethis.com/item?&#038;wp=2.6.1&#38;publisher=&#38;title=Move+to+the+new+VPS%2C+Yummy&#38;url=http%3A%2F%2Fkunxi.org%2Farchives%2F2008%2F09%2Fvps-warm-up%2F">ShareThis</a></p>]]></description>
			<content:encoded><![CDATA[<p>I finally ride the trend of VPS, yes, I just bought Economy VPS COS4&#215;64 with 512M RAM, 200G HD and 350G bandwidth. The host is visualized via virtuozzo, and loaded with CentOS 4.4. </p>
<p>The package management of RPM is quite lacking, so the first thing is to get <a href="http://linux.duke.edu/projects/yum/">YUM</a> working:</p>
<div class="codesnip-container" >
<div class="codesnip">rpm -Uvh http://mirror.centos.org/centos/<span class="nu0">4</span>/os/x86_<span class="nu0">64</span>/CentOS/RPMS/yum-<span class="nu0">2</span>.<span class="nu0">4</span>.<span class="nu0">3</span>-<span class="nu0">4</span>.el4.centos.noarch.rpm<br />
rpm -Uvh http://mirror.centos.org/centos/<span class="nu0">4</span>/os/x86_<span class="nu0">64</span>/CentOS/RPMS/python-elementtree-<span class="nu0">1</span>.<span class="nu0">2</span>.<span class="nu0">6</span>-<span class="nu0">5</span>.el4.centos.x86_<span class="nu0">64</span>.rpm<br />
rpm -Uvh http://mirror.centos.org/centos/<span class="nu0">4</span>/os/x86_<span class="nu0">64</span>/CentOS/RPMS/python-sqlite-<span class="nu0">1</span>.<span class="nu0">1</span>.<span class="nu0">7</span>-<span class="nu0">1</span>.<span class="nu0">2</span>.<span class="nu0">1</span>.x86_<span class="nu0">64</span>.rpm<br />
rpm -Uvh http://mirror.centos.org/centos/<span class="nu0">4</span>/os/x86_<span class="nu0">64</span>/CentOS/RPMS/sqlite-<span class="nu0">3</span>.<span class="nu0">3</span>.<span class="nu0">6</span>-<span class="nu0">2</span>.x86_<span class="nu0">64</span>.rpm<br />
rpm -Uvh http://mirror.centos.org/centos/<span class="nu0">4</span>/os/x86_<span class="nu0">64</span>/CentOS/RPMS/python-sqlite-<span class="nu0">1</span>.<span class="nu0">1</span>.<span class="nu0">7</span>-<span class="nu0">1</span>.<span class="nu0">2</span>.<span class="nu0">1</span>.x86_<span class="nu0">64</span>.rpm<br />
rpm -Uvh http://mirror.centos.org/centos/<span class="nu0">4</span>/os/x86_<span class="nu0">64</span>/CentOS/RPMS/python-urlgrabber-<span class="nu0">2</span>.<span class="nu0">9</span>.<span class="nu0">8</span>-<span class="nu0">2</span>.noarch.rpm<br />
rpm -Uvh http://mirror.centos.org/centos/<span class="nu0">4</span>/os/x86_<span class="nu0">64</span>/CentOS/RPMS/yum-metadata-parser-<span class="nu0">1</span>.<span class="nu0">0</span>-<span class="nu0">8</span>.el4.centos.x86_<span class="nu0">64</span>.rpm<br />
rpm -Uvh http://mirror.centos.org/centos/<span class="nu0">4</span>/os/x86_<span class="nu0">64</span>/CentOS/RPMS/yum-<span class="nu0">2</span>.<span class="nu0">4</span>.<span class="nu0">3</span>-<span class="nu0">4</span>.el4.centos.noarch.rpm<br />
yum update</div>
</div>
<p>Since I have been spoiled by Gentoo&#8217;s portage, the upgrade of CentOS makes little sense to me: wipe off the disk, then reinstall the OS. The upgrade from CentOS 4 to CentOS is quite <a href="http://www.tocpcs.com/yum-install-centos-5-upgrade-from-centos-44-to-centos-5/">hair-rising</a>, and I was scared off by the tech support. So I would stick to CentOS 4 right now.</p>
<p>The next step is to configure the repository:</p>
<div class="codesnip-container" >wget -P /etc/yum.repos.d http://jpackage.org/jpackage.repo<br />
wget -P /etc/yum.repos.d http://centos.karan.org/kbsingh-CentOS-Extras.repo<br />
wget -P /etc/yum.repos.d http://centos.karan.org/kbsingh-CentOS-Misc.repo<br />
wget -P /etc/yum.repos.d http://www.sipfoundry.org/pub/sipX/3.2/sipx-centos.repo<br />
wget -P /etc/yum.repos.d http://dev.centos.org/centos/4/CentOS-Testing.repo</div>
<p>And manually add the following repos as well</p>
<div class="codesnip-container" ># /etc/yum.repos.d/dag.repo<br />
[dag]<br />
name=Dag RPM Repository for Red Hat Enterprise Linux<br />
baseurl=http://apt.sw.be/redhat/el$releasever/en/$basearch/dag<br />
gpgcheck=1<br />
enabled=1</p>
<p># /etc/yum.repos.d/utterramblings.repo<br />
[utterramblings]<br />
name=Jason’s Utter Ramblings Repo<br />
baseurl=http://www.jasonlitka.com/media/EL$releasever/$basearch/<br />
enabled=1<br />
gpgcheck=1<br />
gpgkey=http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka</p>
<p>[dries]<br />
name=Extra Fedora rpms dries - $releasever - $basearch<br />
baseurl=http://ftp.belnet.be/packages/dries.ulyssis.org/redhat/el4/en/i386/dries/RPMS<br />
gpgcheck=1<br />
enabled=1</p>
<p>[atrpms]<br />
name=Fedora Core $releasever - $basearch - ATrpms<br />
baseurl=http://dl.atrpms.net/fc$releasever-$basearch/atrpms/stable<br />
gpgkey=http://ATrpms.net/RPM-GPG-KEY.atrpms<br />
gpgcheck=1enabled=1</p></div>
<p>Import the GPG keys as well:</p>
<div class="codesnip-container" >rpm &#8211;import http://centos.karan.org/RPM-GPG-KEY-karan.org.txt<br />
rpm &#8211;import http://dries.ulyssis.org/rpm/RPM-GPG-KEY.dries.txt<br />
rpm &#8211;import http://dag.wieers.com/packages/RPM-GPG-KEY.dag.txt<br />
rpm &#8211;import http://ATrpms.net/RPM-GPG-KEY.atrpms</div>
<p>And accelerate YUM by cache the meta data locally:</p>
<div class="codesnip-container" >yum makecache</div>
<p>With YUM, it is much easier to start the engine.</p>
<div class="feedflare">
<a href="http://feeds.kunxi.org/~f/rtl?a=PaZ7L"><img src="http://feeds.kunxi.org/~f/rtl?i=PaZ7L" border="0"></img></a> <a href="http://feeds.kunxi.org/~f/rtl?a=zThdl"><img src="http://feeds.kunxi.org/~f/rtl?i=zThdl" border="0"></img></a>
</div><img src="http://feeds.kunxi.org/~r/rtl/~4/385637426" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://kunxi.org/archives/2008/09/vps-warm-up/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=rtl&amp;itemurl=http%3A%2F%2Fkunxi.org%2Farchives%2F2008%2F09%2Fvps-warm-up%2F</feedburner:awareness><feedburner:origLink>http://kunxi.org/archives/2008/09/vps-warm-up/</feedburner:origLink></item>
		<item>
		<title>Reverse mashup</title>
		<link>http://feeds.kunxi.org/~r/rtl/~3/385272893/</link>
		<comments>http://kunxi.org/archives/2008/09/reverse-mashup/#comments</comments>
		<pubDate>Wed, 03 Sep 2008 08:40:11 +0000</pubDate>
		<dc:creator>bookstack</dc:creator>
		
		<category><![CDATA[Web]]></category>

		<category><![CDATA[django]]></category>

		<category><![CDATA[mashup]]></category>

		<category><![CDATA[restful]]></category>

		<guid isPermaLink="false">http://www.kunxi.org/?p=279</guid>
		<description><![CDATA[I barely remember when was the last time I updated Gelman. This project starts as an exercise to practice my Django + dojo skills, and also to manage my eBook collection, I were stuck in UI design which I suck and the authentication/registration which I takes little interest in.
What if we take a different approach [...]<p><a href="http://sharethis.com/item?&#038;wp=2.6.1&#38;publisher=&#38;title=Reverse+mashup&#38;url=http%3A%2F%2Fkunxi.org%2Farchives%2F2008%2F09%2Freverse-mashup%2F">ShareThis</a></p>]]></description>
			<content:encoded><![CDATA[<p>I barely remember when was the last time I updated Gelman. This project starts as an exercise to practice my Django + dojo skills, and also to manage my eBook collection, I were stuck in UI design which I suck and the authentication/registration which I takes little interest in.</p>
<p>What if we take a different approach to avoid the reinvention of the wheel? Let&#8217;s take an online eBook management Web2.0 application, for example <a href="http://www.librarything.com">LibraryThing</a>, to manage the Read, Reading, Wish to Read list, if an electronic copy is available, it will be inserted into the LibraryThing search/detail page, and we can add it to Reading list for quick access later. We just mashup our web service into LibraryThing!</p>
<p>This application can be decomposed to two parts:</p>
<ul>
<li>A Web service to CRUD eBook collection hosted in home-brew server</li>
<li>Firefox Add-on or GreaseMonkey user script for mashup</li>
<li>A web service client to automate importing books</li>
<li>Find your favorite app, then mash it up!</li>
</ul>
<p>A more portable solution to glue the pieces is to leave the mashup in the server side, using a proxy server to insert all the mashup data. </p>
<p>As all comments, tags, reading history has been hosted in the cloud, it is essential to do something against the raining day:</p>
<ul>
<li>Big name may endorse the availability. I would seriously consider <a href="http://www.shelfari.com">Shelfari</a> only after it is acquired by Amazon</li>
<li>Open API is the key. This is the trend, the web site could not lock on the user by closing itself, the users may cold feet in the first place. <a href="http://www.douban.com">Douban</a>, the leader in the Chinese market, did <a href="http://code.google.com/p/douban-api-examples/">an excellent job</a> to open its platform.</li>
</ul>
<p>I am working on an prototype of the RESTful web service using Django, stay in tune.</p>
<div class="feedflare">
<a href="http://feeds.kunxi.org/~f/rtl?a=1wduL"><img src="http://feeds.kunxi.org/~f/rtl?i=1wduL" border="0"></img></a> <a href="http://feeds.kunxi.org/~f/rtl?a=Czkml"><img src="http://feeds.kunxi.org/~f/rtl?i=Czkml" border="0"></img></a>
</div><img src="http://feeds.kunxi.org/~r/rtl/~4/385272893" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://kunxi.org/archives/2008/09/reverse-mashup/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=rtl&amp;itemurl=http%3A%2F%2Fkunxi.org%2Farchives%2F2008%2F09%2Freverse-mashup%2F</feedburner:awareness><feedburner:origLink>http://kunxi.org/archives/2008/09/reverse-mashup/</feedburner:origLink></item>
	<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetFeedData?uri=rtl</feedburner:awareness></channel>
</rss><!-- Dynamic Page Served (once) in 0.698 seconds --><!-- Cached page served by WP-Cache --><!-- Compression = gzip -->
