<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text">Libcoffee.net</title>
  <id>http://www.libcoffee.net/blog/feeds/latest/</id>
  <updated>2009-10-24T17:18:40Z</updated>
  <link href="http://www.libcoffee.net/" />
  <link href="http://www.libcoffee.net/blog/feeds/latest/" rel="self" />
  <generator>Werkzeug</generator>
  <entry xml:base="http://www.libcoffee.net/blog/feeds/latest/">
    <title type="text">Libcoffee.net on Github</title>
    <id>http://www.libcoffee.net/blog/2009/10/21/libcoffeenet-github/</id>
    <updated>2009-10-24T17:18:40Z</updated>
    <published>2009-10-21T21:30:34Z</published>
    <link href="http://www.libcoffee.net/blog/2009/10/21/libcoffeenet-github/" />
    <author>
      <name>zanglang</name>
    </author>
    <content type="html">&lt;p&gt;Libcoffee.net's source code is now released at &lt;a class="reference external" href="http://github.com/zanglang/libcoffee"&gt;http://github.com/zanglang/libcoffee&lt;/a&gt; under the &lt;a class="reference external" href="http://creativecommons.org/licenses/by-sa/3.0/"&gt;Creative Commons Attribution-Share Alike&lt;/a&gt; license, with which the end result is what you are reading right now. ;) The codebase is by no means &lt;em&gt;complete&lt;/em&gt;, and by extension of that I'm pretty darn sure it's neither bugless, stable, nor razor efficient yet. However, it's being continuously updated so if by any chance you spot an error feel free to send a shout. So, to summarize:&lt;/p&gt;
&lt;p&gt;&lt;cite&gt;Libcoffee.net&lt;/cite&gt; is the name of the blogging engine &lt;a class="footnote-reference" href="#id4" id="id1"&gt;[1]&lt;/a&gt; hosting this site. It's written using the &lt;a class="reference external" href="http://www.djangoproject.com"&gt;Django&lt;/a&gt; framework, and is intended to be run on a &lt;a class="reference external" href="http://code.google.com/appengine/"&gt;Google App Engine&lt;/a&gt; account. Some of its features:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Basic blog authoring and publishing with plain URLs e.g. &lt;cite&gt;'blog/2009/12/31/slug'&lt;/cite&gt;&lt;/li&gt;
&lt;li&gt;Comments with Google, OpenID and Facebook identities&lt;/li&gt;
&lt;li&gt;Content markup with &lt;a class="reference external" href="http://docutils.sourceforge.net/rst.html"&gt;reStructuredText&lt;/a&gt;, &lt;a class="reference external" href="http://daringfireball.net/projects/markdown/"&gt;Markdown&lt;/a&gt; and &lt;a class="reference external" href="http://textile.thresholdstate.com/"&gt;Textile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;XMPP and email notifications for new comments&lt;/li&gt;
&lt;li&gt;Clean default template with &lt;a class="reference external" href="http://www.blueprintcss.org/"&gt;Blueprint CSS&lt;/a&gt; framework, &lt;a class="reference external" href="http://microformats.org/wiki/hatom"&gt;hAtom&lt;/a&gt; and &lt;a class="reference external" href="http://microformats.org/wiki/hcard"&gt;hCard&lt;/a&gt; microformats&lt;/li&gt;
&lt;li&gt;Code block syntax highlighting&lt;/li&gt;
&lt;li&gt;Trackbacks and pingbacks&lt;/li&gt;
&lt;li&gt;Automated datastore backup via email&lt;/li&gt;
&lt;li&gt;And of course, other miscellaneous benefits brought by running on Google's distributed computing platform.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There's a fair bunch of library dependencies used, so refer to &lt;a class="reference external" href="http://github.com/zanglang/libcoffee/tree/master/README.rst"&gt;READEME.rst&lt;/a&gt; for a list, as well as installation instructions. (So, uh, why yet &lt;strong&gt;another&lt;/strong&gt; Django blog engine &lt;a class="footnote-reference" href="#id5" id="id2"&gt;[2]&lt;/a&gt;? Answer: because it's not cool if you don't write one while learning Django. Amirite? ^^) All in all, fun experience. Lessons learned from this mini project:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Resource management on a distributed computing environment is very &lt;em&gt;textbook&lt;/em&gt;. Disk space and CPU is cheap. Cloud computing, a buzzword it may be, could very well be the future of software. Memory is a lot cheaper than disk read/writes too, so it pays to &lt;a class="reference external" href="http://code.google.com/appengine/docs/python/memcache/overview.html"&gt;cache the hell out of everything&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;I have mixed feelings about running Django on App Engine, via &lt;a class="reference external" href="http://code.google.com/p/app-engine-patch/"&gt;app-engine-patch&lt;/a&gt;. Django itself is great, but &lt;a class="reference external" href="http://labs.google.com/papers/bigtable.html"&gt;BigTable&lt;/a&gt; imposes so many restrictions that half of Django doesn't work the same anymore, not to mention there's a massive requent-response latency when the app has to cold start &lt;a class="footnote-reference" href="#id6" id="id3"&gt;[3]&lt;/a&gt;, and then load the 3mb Django zip file, then crawl along as compiled Python bytecode is not allowed. In the first week, I was seeing ridiculously high response times averaging at 25 seconds each, but that seems to be have improved by now.&lt;/li&gt;
&lt;li&gt;I clearly have not reached the point where I require the benefits of BigTable yet, so I frequently suspect if it would have been much less trouble if I just coughed up the money for a Python web hosting account... :P&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And stuff on the to-do list:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Rewrite the comments/feedback modules. They were originally ported from Django apps, but a lot of unused cruft is still left over. I still don't know if trackback/pingbacks work properly, for instance.&lt;/li&gt;
&lt;li&gt;Content caching is still very inconsistent. As it is, memcache keys are pretty much generated adhoc without a proper consistent namespace policy, and purged en masse every time a post is created so it's pretty wasteful. Need to get ideas from &lt;a class="reference external" href="http://blog.notdot.net/"&gt;Nick Johnson&lt;/a&gt; recent posts on implementing a static content generator.&lt;/li&gt;
&lt;li&gt;Use more of those leftover App Engine quota. I guess that requires me to blog more. :)&lt;/li&gt;
&lt;li&gt;I really need to look at how to further cut down response times too. Perhaps it'll be yet another fun project - replace bits and pieces with newer and more interesting bits and pieces.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Related Links:&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Libcoffee.net project page: &lt;a class="reference external" href="http://github.com/zanglang/libcoffee"&gt;http://github.com/zanglang/libcoffee&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Django: &lt;a class="reference external" href="http://www.djangoproject.com/"&gt;http://www.djangoproject.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Google App Engine: &lt;a class="reference external" href="http://code.google.com/appengine/"&gt;http://code.google.com/appengine/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;app-engine-patch: &lt;a class="reference external" href="http://code.google.com/p/app-engine-patch/"&gt;http://code.google.com/p/app-engine-patch/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;table class="docutils footnote" frame="void" id="id4" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;I've originally wanted to call it &lt;cite&gt;Nii&lt;/cite&gt;, as it's a &lt;a class="reference external" href="http://typosphere.org"&gt;*typo*&lt;/a&gt;  of Ni, which was an utterance of &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Knights_who_say_Ni"&gt;the Knights from Monty Python&lt;/a&gt;, which inspired Python, which I would be using to write it with - uh, it was all supposed to be all connected and &lt;em&gt;funny&lt;/em&gt;, okay?&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id5" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id2"&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;In fact, there's probably already a whole rainbow spectrum of blogs named &lt;strong&gt;Yet another Django blog&lt;/strong&gt; in a dozen alphabetical variants, too.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id6" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id3"&gt;[3]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;A proper analogy would be: after a period of inactivity an App Engine app goes &lt;em&gt;cold&lt;/em&gt; (deactivated?), until the next request is received, where Google picks a new CPU slice for us to run on again. A popular app will propably stay &lt;em&gt;warm&lt;/em&gt; quite well.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content>
  </entry>
  <entry xml:base="http://www.libcoffee.net/blog/feeds/latest/">
    <title type="text">Fetching Twitter by App Engine Cron</title>
    <id>http://www.libcoffee.net/blog/2009/10/21/fetching-twitter-app-engine-cron/</id>
    <updated>2009-10-24T07:20:18Z</updated>
    <published>2009-10-21T01:18:45Z</published>
    <link href="http://www.libcoffee.net/blog/2009/10/21/fetching-twitter-app-engine-cron/" />
    <author>
      <name>zanglang</name>
    </author>
    <content type="html">&lt;p&gt;Snippet for fetching a Twitter feed to monitor for updates on AppEngine/Django.&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;feedparser&lt;/span&gt; &lt;span class="c"&gt;# (http://www.feedparser.org/)&lt;/span&gt;

&lt;span class="c"&gt;# cron job function&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;update_twitter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;TWITTER_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;http://twitter.com/statuses/user_timeline/&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;.rss&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; \
                            &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TWITTER_USERNAME&lt;/span&gt; &lt;span class="c"&gt;# my username&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;feedparser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TWITTER_URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;has_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;bozo_exception&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;OK&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^http://twitter.com/.*?/statuses/(\d+)$&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;tweets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;dict&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;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;entries&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;tweets&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;
    &lt;span class="c"&gt;# there&amp;#39;s a &amp;#39;Tweet&amp;#39; model for previously saved tweets&lt;/span&gt;
    &lt;span class="n"&gt;tweeted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;guid&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;Tweet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;guid IN&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tweets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;())]&lt;/span&gt;
    &lt;span class="n"&gt;not_tweeted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tweets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tweeted&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c"&gt;# there we go.&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;not_tweeted&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Nothing to save&amp;#39;&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;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;not_tweeted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="c"&gt;# save t&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;OK&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And schedule it in cron.yaml:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Download&lt;/span&gt; &lt;span class="n"&gt;twitter&lt;/span&gt;
  &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lifestream&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;update_twitter&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
  &lt;span class="n"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;every&lt;/span&gt; 10 &lt;span class="n"&gt;minutes&lt;/span&gt;`
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Have I ever said I love Python's libraries? I love Python's libraries.&lt;/p&gt;
&lt;p&gt;Seems that Twitter's RSS feed doesn't always generate successfully either (not unimaginable I guess, considering their concurrent hits), so it's important to catch errors... although they're not always very helpful (I've got several very generic &lt;code&gt;'Application Error: 2'&lt;/code&gt; so far, what on earth does that mean?). I suspect I'm not doing it very efficiently either, with 3 for loops and a dictionary, but not too many choices as I've only want to hit the AppEngine Datastore &lt;em&gt;once&lt;/em&gt; for the entire query.&lt;/p&gt;
&lt;p&gt;P.S - just noticed Markdown + syntax highlighting is still fairly dodgy with detecting whitespaces / code block boundaries. On to the TODO list it goes.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Edit:&lt;/em&gt; Attached a more complete code snippet. May have been a bad idea to blog at 1am.&lt;/p&gt;</content>
  </entry>
  <entry xml:base="http://www.libcoffee.net/blog/feeds/latest/">
    <title type="text">Reopening</title>
    <id>http://www.libcoffee.net/blog/2009/10/16/reopening/</id>
    <updated>2009-10-16T15:44:38Z</updated>
    <published>2009-10-16T23:44:16Z</published>
    <link href="http://www.libcoffee.net/blog/2009/10/16/reopening/" />
    <author>
      <name>zanglang</name>
    </author>
    <content type="html">&lt;p&gt;Well, it certainly has been a while... The last post dates back to &lt;em&gt;2 years&lt;/em&gt; ago, which in internet time is A Very Long Time (tm) indeed. Can't remember why did my blog go on an almost indefinite hiatus - perhaps studying for my honours year exams (which I am glad to report went brilliantly well) as well as last minute hacking on my thesis (which was relatively underwhelming - I like my Advanced Security Project report a lot more due to topical interests... but I digress), and after that a fairly long period of &lt;a href="http://www.worldofwarcraft.com"&gt;WoW&lt;/a&gt;. Anyway, this post is not to reminisce about the past, but as a quick memory jog for myself... Meanwhile, I'll try not to &lt;a href="http://en.wikipedia.org/wiki/The_Catcher_in_the_Rye"&gt;Catcher-in-the-Rye&lt;/a&gt; -esque stream of consciousness rant too much. :P&lt;/p&gt;
&lt;p&gt;So, for a very long time I've wanted to sit down, dump my Ruby on Rails blog (using &lt;a href="http://typosphere.org/"&gt;Typo&lt;/a&gt;), and rewrite it with &lt;em&gt;something&lt;/em&gt;. (I admit that my knowledge of Ruby/Rails only very barely skims the surface, so hosting one without understanding what it does was quite a peculiar experience which I suspect most true hackers would not endorse :P) I was severely tempted to just get a vanilla Wordpress install too, but that wouldn't have been a cool thing to do, of course. During April this year I've also no longer had my own server, which also meant Libcoffee.net went down for several months...&lt;/p&gt;
&lt;p&gt;About a month ago on a Friday night with a very free weekend ahead, I decided to rewrite the site with &lt;a href="http://www.djangoproject.com/"&gt;Django&lt;/a&gt; until it matches functionalities, and then chuck it on &lt;a href="http://appengine.google.com/"&gt;Google App Engine&lt;/a&gt; for free hosting, so over the next 4 weeks of accumulated after-work hacking, I did. :) Technical details and source code will have to wait, but I'll chuck it on &lt;a href="http://github.com/zanglang"&gt;Github&lt;/a&gt; along with a detailed writeup later. (I promise.)&lt;/p&gt;
&lt;p&gt;So, hi again blog. ただいま～！&lt;/p&gt;</content>
  </entry>
  <entry xml:base="http://www.libcoffee.net/blog/feeds/latest/">
    <title type="text">Test post</title>
    <id>http://www.libcoffee.net/blog/2009/10/10/test-post/</id>
    <updated>2009-10-24T07:30:00Z</updated>
    <published>2009-10-10T22:44:02Z</published>
    <link href="http://www.libcoffee.net/blog/2009/10/10/test-post/" />
    <author>
      <name>zanglang</name>
    </author>
    <content type="html">&lt;p&gt;Test post, 1 2 3. &lt;em&gt;Ping&lt;/em&gt;, &lt;strong&gt;pong&lt;/strong&gt;!&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;    &lt;span class="c"&gt;# testing code syntax highlighting&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;lorem ipsum&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;This is a list&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry>
  <entry xml:base="http://www.libcoffee.net/blog/feeds/latest/">
    <title type="text">Backlog July 2nd</title>
    <id>http://www.libcoffee.net/blog/2009/7/3/backlog-july-2nd/</id>
    <updated>2009-10-16T15:57:52Z</updated>
    <published>2009-07-03T00:00:00Z</published>
    <link href="http://www.libcoffee.net/blog/2009/7/3/backlog-july-2nd/" />
    <author>
      <name>zanglang</name>
    </author>
    <content type="html">&lt;p&gt;Reposted from &lt;a href="http://projects.gnome.org/tomboy/"&gt;Tomboy Notes&lt;/a&gt; on 16 October 2009.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Long discussion with Chee Hong about version control, and the mess that is Panton's design and code organization. Curiously, he's quite eager to learn, but I can't vouch for the rest of the company. May have to write proposal and jump through hoops to convince them to properly version control to save themselves, but then, I'm not supposed to be Code Jesus am I?&lt;/li&gt;
&lt;li&gt;Playing around with the new &lt;a href="http://do.davebsd.com"&gt;Gnome Do&lt;/a&gt; 0.8.2. Docks are still rather pointless without a 22" screen. Sorry &lt;a href="http://projects.gnome.org/deskbar-applet/"&gt;Deskbar&lt;/a&gt;, but I'm removing you for the new kid on the block.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Going down to JB on Friday, so probably have to use Conboy for writing.&lt;/p&gt;</content>
  </entry>
</feed>
