<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
      <title>python on Roy Tang</title>
      <link>https://mirror.roytang.net/tags/python/</link>
      <description>Recent content in python on Roy Tang</description>
      <generator>Hugo -- gohugo.io</generator>
      <language>en-us</language>
      <managingEditor>hello@roytang.net (Roy Tang)</managingEditor>
      <webMaster>hello@roytang.net (Roy Tang)</webMaster>
      <lastBuildDate>Fri, 24 Jan 2020 00:00:00 +0000</lastBuildDate>
      
          <atom:link href="https://mirror.roytang.net/tags/python/index.xml" rel="self" type="application/rss+xml" />
      
          
      
        <item>
            <title>Flask vs Django
</title>
            <link>https://mirror.roytang.net/2020/01/flask-vs-django/</link>
            <pubDate>Fri, 24 Jan 2020 00:00:00 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2020/01/flask-vs-django/</guid>
            <description>
            
            &lt;p&gt;In a bid to reduce the number of webapps actually running on my server (for resource consumption reasons), I decided to migrate a small Flask app I had and merge into this larger Django app where I have a lot of my personal data tracking stuff. The Flask app was small enough, mostly containing backend support for this blog (like search and comment submissions) and some Twitter things. The migration was straightforward, taking around half a day, most of that was wrangling with Twitter API rate limits.&lt;/p&gt;
&lt;p&gt;It got me thinking, why did I build this using Flask in the first place? And that led to the more general question: when do I prefer using Flask over Django?&lt;/p&gt;
&lt;p&gt;Personal experience: I&amp;rsquo;m much more familiar with Django than Flask, having started using it back in 2008. Professionally, I&amp;rsquo;ve also worked on more Django projects, compared to only one Flask project that actually made it to production.&lt;/p&gt;
&lt;p&gt;The usual quick comparison is that Flask is the more lightweight web framework, suitable to smaller apps like microservices perhaps; while Django is the big monolithic web framework with all the bells and whistles already available. In practice this means Django already provides a lot of functionalities out of the box, while with Flask you have to install and figure out extensions for even the most common tasks like database management. A negative for Flask, but partly due to my inexperience: if you were already well-versed in the use of those extensions, I imagine getting everything together and setting them up will be easier.&lt;/p&gt;
&lt;p&gt;If there is need for a traditional RDBMS, I will probably use Django. I&amp;rsquo;m not super familiar with SQLAlchemy, the usual recommended ORM for Flask, so that&amp;rsquo;s a big factor. That being said, if I needed to work with something like a NoSQL database or some other nontraditional backend, it might be better to consider Flask since Django isn&amp;rsquo;t super flexible in that record - most of the pluses are oriented towards RDBMS-backed models.&lt;/p&gt;
&lt;p&gt;Admin: The built-in Django admin is a big plus for me; it means that for things like simple record CRUD, if usability and presentation isn&amp;rsquo;t a big concern, I can just use the Django admin as my backend without needing to write maintenance screens. There is an equivalent &lt;a href=&#34;https://flask-admin.readthedocs.io/en/latest/&#34;&gt;Flask Admin plugin&lt;/a&gt;, but I&amp;rsquo;ve not tried that either.&lt;/p&gt;
&lt;p&gt;API building: I&amp;rsquo;m already familiar with the Django REST framework, I&amp;rsquo;m not sure if there&amp;rsquo;s an equivalent for Flask. The one Flask project we did, we rolled our own API backend.&lt;/p&gt;
&lt;p&gt;I find that I tend to favor Flask when building quick proof-of-concept apps that don&amp;rsquo;t need a database. An example that was part of the app I migrated recently would be this quick &lt;a href=&#34;https://apps.roytang.net/twitter/&#34;&gt;Twitter app I wrote about a year ago&lt;/a&gt;, to find intersections between follows/followers. It didn&amp;rsquo;t need a database, only twitter API calls. (I have since merged it into the Django app, so the current version is using Django now.)&lt;/p&gt;
&lt;p&gt;In general I prefer Django, but that is probably due to familiarity and experience. I would love to have a full-scale project that uses Flask though! Perhaps in the future, for now all my personal projects are running on Django.&lt;/p&gt;



&lt;img src=&#34;https://mirror.roytang.net/2020/01/flask-vs-django/code_hu9effae59deb16cf77937c315ce614999_79312_300x0_resize_box_2.png&#34; /&gt;



            </description>
        </item>
    
        <item>
            <title>Python: Markov Chains
</title>
            <link>https://mirror.roytang.net/2019/08/python-markov-chains/</link>
            <pubDate>Wed, 28 Aug 2019 00:00:00 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2019/08/python-markov-chains/</guid>
            <description>
            
            &lt;p&gt;Back when I was still learning Python in 2008, one of the first &amp;ldquo;fun&amp;rdquo; scripts I wrote was a text generator using &lt;a href=&#34;https://en.wikipedia.org/wiki/Markov_chain&#34;&gt;Markov chains&lt;/a&gt;. I&amp;rsquo;d run it against all the chat logs I had with people at work and serve the results from a webserver on my computer. THe results were often amusing and sometimes hilarious.&lt;/p&gt;
&lt;p&gt;Since I&amp;rsquo;ve been going through my old scripts lately, I thought I&amp;rsquo;d update that script to Python 3 (read: add parentheses around print params and use &lt;a href=&#34;https://mirror.roytang.net/2019/08/devnotes-python-pathlib/&#34;&gt;pathlib&lt;/a&gt;) and run it against all the posts on this here site. I added the script to my deploy script for this site (thus further worsening my build times), so it should generate a new page every hour or so. I also added the generated markdown file to gitignore so it never gets saved to the repo. Every output of this script will be fleeting and ephemeral!&lt;/p&gt;
&lt;p&gt;You can view the output &lt;a href=&#34;https://mirror.roytang.net/demos/markov&#34;&gt;here&lt;/a&gt;. You can view the script source &lt;a href=&#34;https://github.com/roytang/blog/blob/master/utils/markov.py&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>Devnotes: Python Pathlib
</title>
            <link>https://mirror.roytang.net/2019/08/devnotes-python-pathlib/</link>
            <pubDate>Tue, 27 Aug 2019 00:00:00 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2019/08/devnotes-python-pathlib/</guid>
            <description>
            
            &lt;p&gt;Ever since I started learning Python back in 2008ish, I&amp;rsquo;ve been using it as my primary scripting language for various tasks such as processing log files, organizing my own file system, processing stuff on this blog, and so on. A lot of it is basically moving files around. In the days of Python 2, that involved a lot of imports of different libraries like &lt;code&gt;os&lt;/code&gt;, &lt;code&gt;shutil&lt;/code&gt; and &lt;code&gt;glob&lt;/code&gt;. It can become a bit messy with so many imports, and I often can&amp;rsquo;t remember which import I need for a particular case and end up having to search for the documentation (or stackoverflow, let&amp;rsquo;s not kid ourselves here).&lt;/p&gt;
&lt;p&gt;With Python 3, a new cleaner option is available to replace all of the above libraries: &lt;a href=&#34;https://docs.python.org/3/library/pathlib.html&#34;&gt;Pathlib&lt;/a&gt;, introduced in Python 3.4, provides an object-oriented way of doing file operations, replacing many of the most common uses I had for the libraries above. Some sample usage:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; pathlib &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; path

&lt;span style=&#34;color:#75715e&#34;&gt;# Declaring a path object is just passing the path string&lt;/span&gt;
p &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Path(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/home/roytang/stuff&amp;#34;&lt;/span&gt;)

&lt;span style=&#34;color:#75715e&#34;&gt;# Other paths can be derived using the / operator&lt;/span&gt;
subdir &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; p &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;favorites&amp;#34;&lt;/span&gt;

&lt;span style=&#34;color:#75715e&#34;&gt;# p.glob replaces stuff like os.walk and glob.glob&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; mdfile &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;glob(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;**/*.md&amp;#34;&lt;/span&gt;):
    &lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt;(str(mdfile))

    &lt;span style=&#34;color:#75715e&#34;&gt;# path objects have properties for individual path elements&lt;/span&gt;
    filename &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; mdfile&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;name
    stem &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; mdfile&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;stem &lt;span style=&#34;color:#75715e&#34;&gt;# filename without extension&lt;/span&gt;

    &lt;span style=&#34;color:#75715e&#34;&gt;# path.exists() replaces os.exists()&lt;/span&gt;
    newdir &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; subdir &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt; stem 
    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; newdir&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;exists():
        &lt;span style=&#34;color:#75715e&#34;&gt;# path.mkdir replaces os.makedirs&lt;/span&gt;
        newdir&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;mkdir(parents&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;True)

    newfile &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; newdir &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt; newfile &lt;span style=&#34;color:#75715e&#34;&gt;# path objects can be either files or dirs&lt;/span&gt;
    &lt;span style=&#34;color:#75715e&#34;&gt;# for file copying, you still need shutil!&lt;/span&gt;
    &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; shutil
    shutil&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;copy(str(mdfile), str(newfile))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For me it&amp;rsquo;s much cleaner to use than the old methods and require less imports (most of the time). I eventually hope to migrate all my older scripts to use Pathlib (the same way I migrated them away from Python 2 a while back), and moving forward I plan to use it primarily for filesystem operations.&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>TriviaStorm: Text and Answer parsing
</title>
            <link>https://mirror.roytang.net/2019/02/triviastorm-text-and-answer-parsing/</link>
            <pubDate>Sun, 03 Feb 2019 05:56:56 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2019/02/triviastorm-text-and-answer-parsing/</guid>
            <description>
            
            &lt;p&gt;A while back I started a &lt;a href=&#34;https://mirror.roytang.net/2017/02/weekend-project-twitter-trivia-bot/&#34;&gt;Twitter trivia bot as a weekend project&lt;/a&gt;. That bot is still &lt;a href=&#34;https://twitter.com/triviastorm&#34;&gt;up and running on Twitter&lt;/a&gt;, you can check it out there!&lt;/p&gt;
&lt;p&gt;But today, I thought I&amp;rsquo;d write about the answer-checking mechanism used by the bot. It was a bit interesting to me because it was the first nontrivial use I had for &lt;a href=&#34;https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/unit-tests/&#34;&gt;Django&amp;rsquo;s unit testing framework&lt;/a&gt;. I&amp;rsquo;m not too keen on unit testing web functionality (something I still have to learn), but this seemed an appropriate first use of a unit test framework for several reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the bot had to be able to handle a wide variety of answers&lt;/li&gt;
&lt;li&gt;there were a lot of test cases to check and a single checking function handling everything - I couldn&amp;rsquo;t risk breaking previous working tests&lt;/li&gt;
&lt;li&gt;inputs were discrete and outputs were easily checkable&lt;/li&gt;
&lt;li&gt;I needed to be able to add new test scenarios all the time as more problematic answers were provided&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The project currently isn&amp;rsquo;t open source, but I did make a gist of the &lt;code&gt;tests.py&lt;/code&gt; I used &lt;a href=&#34;https://gist.github.com/roytang/9199962097bdf3ca2aa8ec9c43bd7ef8&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;check&lt;/code&gt; function basically accepts three parameters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a checking mode (currently only supports EXACT and ALL_ANYORDER)&lt;/li&gt;
&lt;li&gt;the answer phrase provided by the player&lt;/li&gt;
&lt;li&gt;a set of valid answers accepted for the question&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There&amp;rsquo;s a number of test cases already handled:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;checking should be case-insensitive&lt;/li&gt;
&lt;li&gt;articles should be ignored if they&amp;rsquo;re at the start of the answer phrase&lt;/li&gt;
&lt;li&gt;numbers should be acceptable for the spelled-out versions i.e. &amp;ldquo;7&amp;rdquo; should be accepted for &amp;ldquo;seven&amp;rdquo;, and vice versa&lt;/li&gt;
&lt;li&gt;some minor soundex (phonetic matching) support (via &lt;a href=&#34;https://github.com/jamesturk/jellyfish&#34;&gt;Python Jellyfish&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;handling of questions that support multiple answers. This is what ALL_ANYORDER is for - it means that all the given answers must be provided, but they can be in any order. i.e. if the valid answer set is &lt;code&gt;&amp;quot;Huey&amp;quot;&lt;/code&gt;, &lt;code&gt;&amp;quot;Dewey&amp;quot;&lt;/code&gt; and &lt;code&gt;&amp;quot;Louie&amp;quot;&lt;/code&gt;, then &lt;code&gt;&amp;quot;Louie Huey Dewey&amp;quot;&lt;/code&gt; should be accepted as an answer&lt;/li&gt;
&lt;li&gt;nonalphanumeric characters should be treated as whitespace, except in some special cases&lt;/li&gt;
&lt;li&gt;special case: abbreviations like &lt;code&gt;&amp;quot;don&#39;t&amp;quot;&lt;/code&gt; or &lt;code&gt;&amp;quot;can&#39;t&amp;quot;&lt;/code&gt; should be treated as if they were a single term like &lt;code&gt;&amp;quot;dont&amp;quot;&lt;/code&gt; or &lt;code&gt;&amp;quot;cant&amp;quot;&lt;/code&gt; instead of &lt;code&gt;&amp;quot;don t&amp;quot;&lt;/code&gt; or &lt;code&gt;&amp;quot;can t&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The answer checking definitely still isn&amp;rsquo;t perfect, but I&amp;rsquo;m pretty happy with where it&amp;rsquo;s at right now. There is also definitely an element of subjectivity as to which answers should be accepted. One time a player complained that his answer &lt;code&gt;&amp;quot;Batman vs Superman Dawn of Justice&amp;quot;&lt;/code&gt; should count for &lt;code&gt;&amp;quot;Batman v Superman: Dawn of Justice&amp;quot;&lt;/code&gt;, but for this particular question I had chosen not to allow &amp;ldquo;vs&amp;rdquo; for &amp;ldquo;v&amp;rdquo; because that was the actual movie title, which might be unreasonable now that I think about it!&lt;/p&gt;
&lt;p&gt;I do know that I need to implement a better &amp;ldquo;synonym&amp;rdquo; handling, i.e. mapping of &lt;code&gt;&amp;quot;v&amp;quot;&amp;lt;-&amp;gt;&amp;quot;vs&amp;quot;&lt;/code&gt; and other terms like &lt;code&gt;&amp;quot;mr&amp;quot;&amp;lt;-&amp;gt;&amp;quot;mister&amp;quot;&lt;/code&gt; or &lt;code&gt;&amp;quot;natl&amp;quot;&amp;lt;-&amp;gt;&amp;quot;national&amp;quot;&lt;/code&gt;. The problem with handling things like that is that is the possible combinations of phrases expands when multiple such terms are found in the same answer, so it can&amp;rsquo;t scale too well. I suppose I need to normalize the answer sets at the time the question is defined. What do you know, I figured out how to do something just by writing a blog post!&lt;/p&gt;
&lt;p&gt;I do have a bunch of other enhancements planned for the trivia bot, including support for slack and discord, and a longer time frame roadmap, but I&amp;rsquo;m not sure when I can commit more time to it. Still, it&amp;rsquo;s turned out to be a pretty fun endeavor, I&amp;rsquo;m hoping it leads to something cool!&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>Django Blog Application
</title>
            <link>https://mirror.roytang.net/2018/10/django-blog-application/</link>
            <pubDate>Sun, 28 Oct 2018 05:02:37 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2018/10/django-blog-application/</guid>
            <description>
            
            &lt;p&gt;Ten years ago this month, I started studying &lt;a href=&#34;https://www.djangoproject.com/&#34;&gt;Django&lt;/a&gt; by trying to build my own blog application. I found the code lying around while I was going through some backups lately. It&amp;rsquo;s way out of date, it uses an early version of django. I thought of bringing it up to speed, but that didn&amp;rsquo;t seem practical. Instead, for archival purposes, I cleaned it up a bit and &lt;a href=&#34;https://github.com/roytang/django-blog&#34;&gt;uploaded the code to a github repo&lt;/a&gt;. (Helpful github immediately warned me that having a very old version of Django was a security risk lol). There&amp;rsquo;s a lot more information in the README.md of that repo. I actually used this as my main blog engine for a while before I decided the maintenance effort wasn&amp;rsquo;t worth it and switched to WordPress.&lt;/p&gt;
&lt;p&gt;Tangent: I&amp;rsquo;m not actually 100% happy with WordPress, and when I found this old code I was tempted to maybe trying building Yet Another Blog Application (TM), except maybe using the opportunity to learn some other framework. My 2018 personal to-do list is already way too long though.&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>Running Python 2.x and 3.x on Windows
</title>
            <link>https://mirror.roytang.net/2017/03/running-python-2-x-and-3-x-on-windows/</link>
            <pubDate>Thu, 02 Mar 2017 01:30:38 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2017/03/running-python-2-x-and-3-x-on-windows/</guid>
            <description>
            
            &lt;p&gt;I&amp;rsquo;ve been hesitant to try Python 3.x because it&amp;rsquo;s not backward compatible with Python 2.x which I&amp;rsquo;ve been using for scripting since forever. But recently I found out that since Python 3.3, they&amp;rsquo;ve included a launcher in the Windows version that supports having both versions installed.&lt;/p&gt;
&lt;p&gt;You can use the launcher to specify the Python version to use at the command line (it defaults to whichever version was installed first):&lt;/p&gt;











&lt;a href=&#34;#245f649da64bdf242059b3bc2b8467dd-lightbox&#34;&gt;
    &lt;figure&gt;
      &lt;img src=&#34;https://mirror.roytang.net/2017/03/running-python-2-x-and-3-x-on-windows/py_hu39b80b4493d6a22d9e54b62321f525d1_13537_300x0_resize_box_2.png&#34; alt=&#34;&#34; title=&#34;&#34; class=&#34;tn&#34; /&gt;
      &lt;figcaption&gt; (Click to view full-size)&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;/a&gt;
&lt;div class=&#34;lightbox&#34; id=&#34;245f649da64bdf242059b3bc2b8467dd-lightbox&#34; style=&#34;display: none;&#34;&gt;
  &lt;a href=&#34;#_&#34;&gt;
    &lt;img src=&#34;https://mirror.roytang.net/2017/03/running-python-2-x-and-3-x-on-windows/py.png&#34; /&gt;
  &lt;/a&gt;
  &lt;div class=&#34;lightbox_overlay&#34;&gt;
    &lt;p&gt;&lt;/p&gt;
    &lt;time class=&#34;dt-published&#34; datetime=&#34;2 Mar 2017 1:30am&#34;&gt;2 Mar 2017 1:30am&lt;/time&gt;&lt;a href=&#34;#_&#34;&gt;Close&lt;/a&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Even better, the launcher will recognize a header in your .py files that can specify which version of python to use:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;#!/usr/bin/env python3&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If the launcher sees this header, it will automatically launch the appropriate python version. Handy!&lt;/p&gt;



&lt;img src=&#34;https://mirror.roytang.net/2017/03/running-python-2-x-and-3-x-on-windows/py_hu39b80b4493d6a22d9e54b62321f525d1_13537_300x0_resize_box_2.png&#34; /&gt;



            </description>
        </item>
    
        <item>
            <title>Weekend Project: Twitter Trivia Bot
</title>
            <link>https://mirror.roytang.net/2017/02/weekend-project-twitter-trivia-bot/</link>
            <pubDate>Thu, 23 Feb 2017 01:30:00 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2017/02/weekend-project-twitter-trivia-bot/</guid>
            <description>
            
            &lt;p&gt;I had been meaning to try writing a Twitter bot for a while now. I figured a trivia bot would be pretty easy to implement, so I spent some time a couple of weekends to rig one together.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s (mostly) working now, the bot is active as &lt;a href=&#34;https://twitter.com/triviastorm/&#34;&gt;triviastorm on Twitter&lt;/a&gt;, with a supporting webapp deployed on &lt;a href=&#34;https://triviastorm.net/&#34;&gt;https://triviastorm.net/&lt;/a&gt;. The bot tweets out a trivia question once every hour. It will then award points to the first five people who gave the correct answer. The bot will only recognize answers given as a direct reply to the tweet with the question, and only those submitted within the one hour period.&lt;/p&gt;
&lt;p&gt;Some technical details:&lt;/p&gt;
&lt;p&gt;My scripting language of choice for the past few years has been Python 2.7. I&amp;rsquo;m using &lt;a href=&#34;http://www.tweepy.org/&#34;&gt;Tweepy&lt;/a&gt; to interact with the Twitter API, &lt;a href=&#34;https://github.com/PyMySQL/PyMySQL&#34;&gt;PyMySQL&lt;/a&gt; to connect to the database, and &lt;a href=&#34;http://flask.pocoo.org/&#34;&gt;Flask&lt;/a&gt; to run the webapp. I haven&amp;rsquo;t used Flask in some time, but it&amp;rsquo;s still very straightforward. I actually had a harder time configuring the webapp with mod_wsgi on my host.&lt;/p&gt;
&lt;p&gt;The main problem with a trivia system is that you need a large and high-quality set of questions. Right now the bot is using a small trivia set &amp;ndash;around a thousand questions I got from a variety of sources. If I want to leave this bot running for a while, I&amp;rsquo;m going to need a much larger trivia set. However, reviewing and collating the questions is a nontrivial task. Hopefully I can add new questions every so often.&lt;/p&gt;
&lt;p&gt;Feel free to follow the bot and help test it out. I&amp;rsquo;d be grateful!&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>The Simplest Code That Can Do The Job
</title>
            <link>https://mirror.roytang.net/2017/01/the-simplest-code-that-can-do-the-job/</link>
            <pubDate>Wed, 11 Jan 2017 01:30:06 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2017/01/the-simplest-code-that-can-do-the-job/</guid>
            <description>
            
            &lt;p&gt;So the other day I was reworking a Python script that I had been using for years on my home PC to manage and categorize some downloaded files for me. This time I wanted to add some smarter behavior to make it more able to figure out when to group files into folders without constantly needing manual intervention from me. To do this, I needed to persist some data between runs &amp;ndash; so that the script remembers how it categorized previous files and is able to group similar files together.&lt;/p&gt;
&lt;p&gt;Now since my software development career has largely been as an enterprise-y kind of developer, my first thought was to just use a database to store the data. I already had a MySql installation on my machine so that was fine, I just needed Python to interface with it. After looking up how to do it, I balked at having to install a new Python library just to connect to MySql and reconsidered.&lt;/p&gt;
&lt;p&gt;As programmers, we have a tendency sometimes to over-engineer solutions because that&amp;rsquo;s what we&amp;rsquo;re used to doing. Did I really need a database for this? The data won&amp;rsquo;t be very big, and I won&amp;rsquo;t need to do any sort of maintenance on it, so maybe a simpler solution was in order.&lt;/p&gt;
&lt;p&gt;I ended up just using pickle, which was already built-in to Python:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;load_db&lt;/span&gt;():
	all_series &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {}
	&lt;span style=&#34;color:#66d9ef&#34;&gt;with&lt;/span&gt; open(DATABASE_FILE, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;rb&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; handle:
		all_series &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; pickle&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;load(handle)
	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; all_series

&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;save_db&lt;/span&gt;(all_series):
	&lt;span style=&#34;color:#66d9ef&#34;&gt;with&lt;/span&gt; open(DATABASE_FILE, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;wb&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; handle:
		pickle&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;dump(all_series, handle, protocol&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;pickle&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;HIGHEST_PROTOCOL)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(Above code &lt;em&gt;probably&lt;/em&gt; gives you an idea what kind of files I&amp;rsquo;m sorting&amp;hellip; )&lt;/p&gt;
&lt;p&gt;As an added benefit, I didn&amp;rsquo;t need to design any database schemas or tables or whatnot, pickle just lets me serialize the map as-is and reload it later from disk without any hassle.&lt;/p&gt;
&lt;p&gt;I guess my lesson here was: don&amp;rsquo;t over-complicate things when something simple will work fine. Write the simplest code that can do the job.&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>Reply to &#39;I&#39;ll be your python slave. Looking a py project to work at to become better.&#39; on /r/Python at https://reddit.com/r/Python/comments/jw5lx/ill_be_your_python_slave_looking_a_py_project_to/:
</title>
            <link>https://mirror.roytang.net/2011/08/c2flc8v/</link>
            <pubDate>Sat, 27 Aug 2011 00:00:00 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2011/08/c2flc8v/</guid>
            <description>
            Reply to &amp;#39;I&amp;#39;ll be your python slave. Looking a py project to work at to become better.&amp;#39; on /r/Python at https://reddit.com/r/Python/comments/jw5lx/ill_be_your_python_slave_looking_a_py_project_to/:

            &lt;p&gt;Earlier today i was thinking of writing a python script to detect duplicate mp3s, you might want to try that. There are existing programs to do it, but they all seem terrible!&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>New note
</title>
            <link>https://mirror.roytang.net/2010/10/3951840/</link>
            <pubDate>Sun, 17 Oct 2010 03:01:52 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2010/10/3951840/</guid>
            <description>
            

            &lt;p&gt;In Python, say I have a string that contains the name of a class function that I know a particular object will have, how can I invoke it?&lt;/p&gt;
&lt;p&gt;That is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;obj = MyClass() # this class has a method doStuff()
func = &amp;quot;doStuff&amp;quot;
# how to call obj.doStuff() using the func variable?&lt;/code&gt;&lt;/pre&gt;



            </description>
        </item>
    
        <item>
            <title>Reply to &#39;Python execution speed: laptop vs desktop&#39; on stackoverflow at https://stackoverflow.com/questions/3939912/python-execution-speed-laptop-vs-desktop:
</title>
            <link>https://mirror.roytang.net/2010/10/3939957/</link>
            <pubDate>Fri, 15 Oct 2010 06:27:52 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2010/10/3939957/</guid>
            <description>
            Reply to &amp;#39;Python execution speed: laptop vs desktop&amp;#39; on stackoverflow at https://stackoverflow.com/questions/3939912/python-execution-speed-laptop-vs-desktop:

            &lt;p&gt;Split your processing into multiple threads. Your particular i7 should be able to support up to 8 threads in parallel.&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>Ask HN: How will it impact my webapp if it is written in Python instead of PHP.
</title>
            <link>https://mirror.roytang.net/2010/07/ask-hn-how-will-it-impact-my-webapp-if-it-is-written-in-python-instead-of-php/</link>
            <pubDate>Tue, 06 Jul 2010 12:19:00 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2010/07/ask-hn-how-will-it-impact-my-webapp-if-it-is-written-in-python-instead-of-php/</guid>
            <description>
            Shared via delicious:
    &lt;a href=&#34;http://news.ycombinator.com/item?id=1490142&#34;&gt;Ask HN: How will it impact my webapp if it is written in Python instead of PHP.&lt;/a&gt;

            &lt;p&gt;One of the responses has a nice discussion on the state of python web frameworks.&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>New note
</title>
            <link>https://mirror.roytang.net/2010/06/3051295/</link>
            <pubDate>Wed, 16 Jun 2010 07:12:12 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2010/06/3051295/</guid>
            <description>
            

            &lt;p&gt;Is there any Python library that allows me to parse an HTML document similar to what jQuery does?&lt;/p&gt;
&lt;p&gt;i.e. I&amp;rsquo;d like to be able to use CSS selector syntax to grab an arbitrary set of nodes from the document, read their content/attributes, etc.&lt;/p&gt;
&lt;p&gt;The only Python HTML parsing lib I&amp;rsquo;ve used before was BeautifulSoup, and even though it&amp;rsquo;s fine I keep thinking it would be faster to do my parsing if I had jQuery syntax available. :D&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>Anyone care to share neat python tricks? : programming
</title>
            <link>https://mirror.roytang.net/2010/01/anyone-care-to-share-neat-python-tricks-programming/</link>
            <pubDate>Wed, 13 Jan 2010 00:46:28 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2010/01/anyone-care-to-share-neat-python-tricks-programming/</guid>
            <description>
            Shared via delicious:
    &lt;a href=&#34;http://www.reddit.com/r/programming/comments/akdpr/anyone_care_to_share_neat_python_tricks/&#34;&gt;Anyone care to share neat python tricks? : programming&lt;/a&gt;

            


            </description>
        </item>
    
        <item>
            <title>Reply to &#39;ValueError in Django&#39; on stackoverflow at https://stackoverflow.com/questions/2032360/valueerror-in-django:
</title>
            <link>https://mirror.roytang.net/2010/01/2032378/</link>
            <pubDate>Sat, 09 Jan 2010 04:47:32 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2010/01/2032378/</guid>
            <description>
            Reply to &amp;#39;ValueError in Django&amp;#39; on stackoverflow at https://stackoverflow.com/questions/2032360/valueerror-in-django:

            &lt;pre&gt;&lt;code&gt;urlpatterns = patterns(&#39;&#39;,     
    (r&#39;^salaries/employee/$&#39;, list_detail.object_list, &#39;employee_info&#39;),
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The third item in the tuple needs to be a dictionary, not a string. Try removing the single quotes around employee_info:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;urlpatterns = patterns(&#39;&#39;,     
    (r&#39;^salaries/employee/$&#39;, list_detail.object_list, employee_info),
)&lt;/code&gt;&lt;/pre&gt;



            </description>
        </item>
    
        <item>
            <title>Reply to &#39;How to create a .py file for Google App Engine?&#39; on stackoverflow at https://stackoverflow.com/questions/1866147/how-to-create-a-py-file-for-google-app-engine:
</title>
            <link>https://mirror.roytang.net/2009/12/1866186/</link>
            <pubDate>Tue, 08 Dec 2009 10:52:08 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2009/12/1866186/</guid>
            <description>
            Reply to &amp;#39;How to create a .py file for Google App Engine?&amp;#39; on stackoverflow at https://stackoverflow.com/questions/1866147/how-to-create-a-py-file-for-google-app-engine:

            &lt;p&gt;You will need a better editor than Notepad. With Notepad, use Save As&amp;hellip;, and type &amp;ldquo;helloworld.py&amp;rdquo; in the dialog, &lt;strong&gt;including&lt;/strong&gt; quotes so that the file extension is .py instead of .txt&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>Reply to &#39;Is there a tuple data structure in Python&#39; on stackoverflow at https://stackoverflow.com/questions/1831218/is-there-a-tuple-data-structure-in-python:
</title>
            <link>https://mirror.roytang.net/2009/12/1831230/</link>
            <pubDate>Wed, 02 Dec 2009 07:37:51 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2009/12/1831230/</guid>
            <description>
            Reply to &amp;#39;Is there a tuple data structure in Python&amp;#39; on stackoverflow at https://stackoverflow.com/questions/1831218/is-there-a-tuple-data-structure-in-python:

            &lt;p&gt;You can have an array of 3-item tuples.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;arr = [ (1,2,3), (4,5,6), (7,8,9)]
for (k, v, x) in arr:
  # do stuff&lt;/code&gt;&lt;/pre&gt;



            </description>
        </item>
    
        <item>
            <title>Andy McKay&#39;s blog
</title>
            <link>https://mirror.roytang.net/2009/09/andy-mckay-s-blog/</link>
            <pubDate>Sun, 06 Sep 2009 04:53:07 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2009/09/andy-mckay-s-blog/</guid>
            <description>
            Shared via delicious:
    &lt;a href=&#34;http://www.agmweb.ca/blog/andy/2222/&#34;&gt;Andy McKay&amp;#39;s blog&lt;/a&gt;

            


            </description>
        </item>
    
        <item>
            <title>Django snippets: Facebook shell
</title>
            <link>https://mirror.roytang.net/2009/09/django-snippets-facebook-shell/</link>
            <pubDate>Sun, 06 Sep 2009 04:52:51 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2009/09/django-snippets-facebook-shell/</guid>
            <description>
            Shared via delicious:
    &lt;a href=&#34;http://www.djangosnippets.org/snippets/1716/&#34;&gt;Django snippets: Facebook shell&lt;/a&gt;

            


            </description>
        </item>
    
        <item>
            <title>Getting Started - wxPyWiki
</title>
            <link>https://mirror.roytang.net/2009/04/getting-started-wxpywiki/</link>
            <pubDate>Mon, 13 Apr 2009 15:04:33 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2009/04/getting-started-wxpywiki/</guid>
            <description>
            Shared via delicious:
    &lt;a href=&#34;http://wiki.wxpython.org/Getting%20Started&#34;&gt;Getting Started - wxPyWiki&lt;/a&gt;

            


            </description>
        </item>
    
        <item>
            <title>Stylesheet Switcher using Django
</title>
            <link>https://mirror.roytang.net/2009/02/stylesheet-switcher-using-django/</link>
            <pubDate>Sat, 14 Feb 2009 14:17:32 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2009/02/stylesheet-switcher-using-django/</guid>
            <description>
            
            &lt;p&gt;You may have noticed the new color scheme and new &amp;ldquo;Theme Switcher&amp;rdquo; widget in the sidebar. I had done some CSS work during the past month in the office and it made me want to tweak the stylesheets on this site a bit. I figured I might as well make it easy to switch stylesheets, so I wrote a small Theme Switcher django app. (Well, it&amp;rsquo;s more of a stylesheet switcher I guess)&lt;/p&gt;
&lt;p&gt;The model is simple:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Theme&lt;/span&gt;(models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Model):
    slug &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;SlugField()
    title &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CharField(max_length&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;250&lt;/span&gt;)
    css_path &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;CharField(max_length&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;500&lt;/span&gt;)

    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; __str__(self):
        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;title
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I only needed one view &amp;ndash; to switch the current theme.&lt;/p&gt;
&lt;p&gt;Added the ff to urls.py:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;^theme/([a-zA-Z0-9\-]+)/&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;themer.views.switch&amp;#39;&lt;/span&gt;),
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The view code simply stores the selected theme as a cookie:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;switch&lt;/span&gt;(request, theme_slug):
  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34; Sets a cookie to specify the new theme, then redirects to the referer or root url &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
  theme &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; get_object_or_404(Theme, slug&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;theme_slug)
  referer &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;HTTP_REFERER&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; request&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;META:
    referer &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; request&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;META[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;HTTP_REFERER&amp;#34;&lt;/span&gt;]
  resp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; HttpResponseRedirect(referer)
  resp&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;set_cookie(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;theme&amp;#34;&lt;/span&gt;, theme_slug, &lt;span style=&#34;color:#ae81ff&#34;&gt;100000&lt;/span&gt;)
  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; resp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To load the stylesheet, I set up a &lt;a href=&#34;http://www.b-list.org/weblog/2006/jun/14/django-tips-template-context-processors/&#34; title=&#34;Django tips: Template context processors by James Bennet&#34;&gt;context processor&lt;/a&gt; to pass both the current theme and the list of themes to the context. I wanted to do this using template tags, but I couldn&amp;rsquo;t figure out how to extract a cookie from within a template tag.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; themer.models &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; Theme
&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;context_processor&lt;/span&gt;(request):
    theme_list &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Theme&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;objects&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;all()
    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;theme&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; request&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;COOKIES:
        slug &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; request&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;COOKIES[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;theme&amp;#34;&lt;/span&gt;]
        &lt;span style=&#34;color:#66d9ef&#34;&gt;try&lt;/span&gt;:
            theme &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Theme&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;objects&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(slug&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;slug)
        &lt;span style=&#34;color:#66d9ef&#34;&gt;except&lt;/span&gt; Theme&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;DoesNotExist:
            theme &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; None
    &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; theme_list&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;count() &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;:
            theme &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; theme_list[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]
        &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
            theme &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; None
    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;current_theme&amp;#34;&lt;/span&gt; : theme, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;theme_list&amp;#34;&lt;/span&gt; : theme_list}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then in my base template file, I add the following to the head section:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;link&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;rel&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;stylesheet&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;href&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{{ current_theme.css_path }}&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;text/css&amp;#34;&lt;/span&gt; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And add the list of themes into the sidebar.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;h2&lt;/span&gt;&amp;gt;Theme Switcher&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;h2&lt;/span&gt;&amp;gt;
&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt;&amp;gt;
            {% for theme in theme_list %}
            &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;li&lt;/span&gt;&amp;gt;
            {% ifequal theme.slug current_theme.slug %}
            {{ theme.title }} &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;note&amp;#34;&lt;/span&gt;&amp;gt;(current)&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;span&lt;/span&gt;&amp;gt;
            {% else %}
            &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;href&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{% url themer.views.switch theme.slug %}&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;title&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Switch to {{ theme.title }} theme&amp;#34;&lt;/span&gt;&amp;gt;{{ theme.title }}&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt;&amp;gt;
            {% endifequal %}
            &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;li&lt;/span&gt;&amp;gt;
            {% endfor %}
            &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And we&amp;rsquo;re done!&lt;/p&gt;
&lt;p&gt;Of course, I&amp;rsquo;m still not particularly strong in web design, so the two current &amp;ldquo;themes&amp;rdquo; really just switch around the color scheme. The light blue theme is named Azorius, while the old black and green theme is named Golgari, both named after the respective color guilds in Magic: The Gathering&amp;rsquo;s Ravnica block.&lt;/p&gt;
&lt;p&gt;Hopefully this gives me a chance to whip up more interesting themes and polish the old CSS skills some more. Enjoy!&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>Using Django Pingback
</title>
            <link>https://mirror.roytang.net/2009/01/using-django-pingback/</link>
            <pubDate>Sun, 04 Jan 2009 07:22:20 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2009/01/using-django-pingback/</guid>
            <description>
            
            &lt;p&gt;I actually had some trouble using &lt;a href=&#34;http://code.google.com/p/django-pingback/&#34;&gt;django-pingback&lt;/a&gt; on my custom blog engine; the &lt;a href=&#34;http://hg.piranha.org.ua/django-pingback/file/6ca8eadcd22d/README.md#l1&#34;&gt;django-pingback documentation&lt;/a&gt; is mostly fine, but there were some caveats that I had to discover myself through a bit of debugging:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The URL specified for the XML-RPC endpoint in the HTML head needs to be a full absolute url including domain, i.e. &lt;a href=&#34;http://roytang.net/xmlrpc/,&#34;&gt;http://roytang.net/xmlrpc/,&lt;/a&gt; which gave me trouble when I was trying to test using localhost pinging to an online server. I eventually just decided to set it up, deploy on webfaction and test it online before I redirected the domain name.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The documentation mentioned that the pingback handler needs to have the same arguments as the detail view for the post, so I wrote it as follows:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# exactly same arguments as &amp;#39;details&amp;#39; view.&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;pingback_blog_handler&lt;/span&gt;(catslug, year, month, slug, &lt;span style=&#34;color:#f92672&#34;&gt;**&lt;/span&gt;kwargs):
    cat &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Category&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;objects&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(slug&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;catslug)
    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; Post&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;pub_objects&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(date__year&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;year, date__month&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;month, slug&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;slug, category&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;cat, published&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;True)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But it wasn&amp;rsquo;t exactly working for me, for some reason the function wasn&amp;rsquo;t being called. After some debugging I found that I needed to use named parameters for catslug, year, month, slug in the URLConf for the post permalink in order for this to work. I&amp;rsquo;m not sure if this was because I was doing it wrong or it&amp;rsquo;s some sort of undocumented requirement.&lt;/li&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The pingback client was throwing a KeyError whenever a post I made would have anchor tags without an href attribute. Granted that there isn&amp;rsquo;t much point in having an &lt;a&gt;anchor tag without the href&lt;/a&gt;, but the code shouldn&amp;rsquo;t just choke on it. I modified the following line in client.py:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;  links &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [a[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;href&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; a &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; soup&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;findAll(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; is_external(a[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;href&amp;#39;&lt;/span&gt;], url)]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Adding the check for the href attribute:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;  links &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [a[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;href&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; a &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; soup&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;findAll(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; a&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;has_key(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;href&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;and&lt;/span&gt; is_external(a[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;href&amp;#39;&lt;/span&gt;], url)]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Those are all the changes I made to get pingbacks working. I hope they&amp;rsquo;re still working now, as I haven&amp;rsquo;t received any pingbacks since the django version of this blog went live &amp;gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;



            </description>
        </item>
    
        <item>
            <title>Colophon 2008
</title>
            <link>https://mirror.roytang.net/2008/12/colophon-2008/</link>
            <pubDate>Sat, 27 Dec 2008 02:08:22 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2008/12/colophon-2008/</guid>
            <description>
            
            &lt;p&gt;&lt;strong&gt;Frontend&lt;/strong&gt;: All page templates are valid (X)HTML. However, I choose not to claim valid XHTML (and no doc type declaration) since I can&amp;rsquo;t guarantee that blog posts I write are compliant! The site uses standard CSS and uses the &lt;a href=&#34;http://blueprintcss.org&#34; title=&#34;Blueprint CSS Framework&#34;&gt;Blueprint CSS Framework&lt;/a&gt; for the grid layout of the page. The site design is entirely original (if not simple and bland &amp;ndash; I&amp;rsquo;m not very good with website design yet!). The site has minor usage of &lt;a href=&#34;http://jquery.com/,&#34; title=&#34;JQuery&#34;&gt;JQuery Javascript library&lt;/a&gt; in some parts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Backend&lt;/strong&gt;: The server side uses &lt;a href=&#34;http://python.org&#34;&gt;Python&lt;/a&gt; and &lt;a href=&#34;http://djangoproject.com&#34;&gt;Django&lt;/a&gt; behind mod_python on Apache, with a MySQL database. The following Django apps and Python libraries are used:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;custom made blog application by myself&lt;/li&gt;
&lt;li&gt;built-in (contrib) apps: admin, comments, sitemaps, flatpages&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://code.google.com/p/django-tagging/&#34;&gt;django-tagging&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://launchpad.net/django-xmlrpc&#34;&gt;django-xmlrpc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://code.google.com/p/django-comment-utils/&#34;&gt;comment_utils&lt;/a&gt; for advanced comment moderation features&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://code.google.com/p/django-template-utils/&#34;&gt;template_utils&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://code.google.com/p/django-pingback/&#34;&gt;django-pingback&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.crummy.com/software/BeautifulSoup/&#34;&gt;Beautiful Soup&lt;/a&gt; for XML/HTML parsing&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://pygments.org/&#34;&gt;Pygments&lt;/a&gt; for syntax highlighting. See the &lt;a href=&#34;https://mirror.roytang.net/pygments/&#34;&gt;Pygments Demo!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.feedparser.org/&#34;&gt;Feedparser&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://code.google.com/p/python-markdown2/&#34;&gt;Markdown2&lt;/a&gt; so that I can post using Markdown.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As is typical for hobbyist software development, I started working on this site with only a minimal set of features considered, but as I kept working I kept wanting to add more stuff. Some notable custom-made features:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;XMLRPC server, supporting &lt;a href=&#34;http://www.xmlrpc.com/metaWeblogApi&#34;&gt;Metaweblog API&lt;/a&gt; and Pingbacks. I actually only added the metaweblog support so I could post from &lt;a href=&#34;http://www.flock.com/&#34;&gt;Flock&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Autocard support (same as &lt;a href=&#34;https://mirror.roytang.net/2008/02/mtg-autocard-wordpress-plugin/&#34;&gt;my previous Autocard plugin for WP&lt;/a&gt;) and syntax highlighting of code.&lt;/li&gt;
&lt;li&gt;Automatic extraction of twitter and delicious entries into the sidebar&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://gravatar.com&#34;&gt;Gravatar&lt;/a&gt; support for comments&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All entries from the previous &amp;ldquo;roytang / weblog&amp;rdquo;, &amp;ldquo;Roy on Magic&amp;rdquo; and &amp;ldquo;Roy on Django&amp;rdquo; have been imported using a custom data conversion script, but nothing is perfect so some of the older posts may be badly formatted. (Comment on those posts!)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hosting&lt;/strong&gt;: Provided by &lt;a href=&#34;http://www.webfaction.com/?affiliate=roytang&#34;&gt;Webfaction&lt;/a&gt;.&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>Fixing up the comments
</title>
            <link>https://mirror.roytang.net/2008/12/fixing-up-the-comments/</link>
            <pubDate>Mon, 01 Dec 2008 04:58:00 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2008/12/fixing-up-the-comments/</guid>
            <description>
            
            &lt;p&gt;I played around with the built-in comments app today, trying to clean it up.&lt;/p&gt;
&lt;p&gt;Some findings:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Some of the moderation views, such as flagging a post or deleting a post, accept a next parameter that determines where the view will redirect to after the operation. However, the way the url&amp;rsquo;s are set up, there&amp;rsquo;s no easy way to pass this parameter normally, even through query strings. This lovely bug is documented in &lt;a href=&#34;http://code.djangoproject.com/ticket/8968&#34;&gt;http://code.djangoproject.com/ticket/8968&lt;/a&gt;. I wasn&amp;rsquo;t confident enough to try patching it, so as a temporary workaround, I overrode the flag and delete templates and placed the following inside the form:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;next&amp;quot; value=&amp;quot;{{ comment.get\_content\_object_url }}&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Edit: Wow that was stupid. Blogger didn&amp;rsquo;t want to render the HTML code above!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I also replaced the URL in the &amp;ldquo;cancel&amp;rdquo; links for both pages. For some reason, {{ comment.permalink }} wasn&amp;rsquo;t giving me anything useful.&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;
&lt;p&gt;Took me a bit of work to figure out how the moderation part works. Apparently I have to hook on some of the signals to add my moderation logic. I&amp;rsquo;m not sure yet how to handle this, or whether I should try customizing the comment form with something like a captcha to prevent comment spam.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I have a pending problem now that submitting comments from the preview or error page does not redirect to the correct place. (i.e. the post page). I tried adding the next parameter to the form, but apparently comment.get_content_object_url returns an empty string here because the comment has not yet been saved to the database. I think the content object should be provided in the context for the preview page. This would be handled by &lt;a href=&#34;http://code.djangoproject.com/ticket/9268&#34;&gt;http://code.djangoproject.com/ticket/9268&lt;/a&gt;, except apparently no one&amp;rsquo;s paying attention to it yet.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Some random features I added: Gravatar support (the Gravatar for the email address used to post the comment will be shown), and Markdown support in the comment body. Easy stuff.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cleaned up an refactored the templates that render the comments, separating them from the parts that render the blog posts. This makes it easier if I want to have comments for other non-Blog post objects later.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Non-comment related:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Added simple search!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The script to import from WordPress has some problems. Since I&amp;rsquo;m storing the post body in markdown format, I use &lt;a href=&#34;http://www.aaronsw.com/2002/html2text/&#34;&gt;html2text&lt;/a&gt; to convert the HTML body from old posts into markdown, but nice stuff like image alignments and tables are lost. I think I have to make do with editing straight HTML for old posts imported from WordPress, and just clean them up later as needed.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;My code is rather messy now (especially from the HTML side). I should clean it up sometime soon.&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>Django Update -- WordPress Import and More
</title>
            <link>https://mirror.roytang.net/2008/11/django-update-wordpress-import-and-more/</link>
            <pubDate>Sun, 23 Nov 2008 00:04:00 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2008/11/django-update-wordpress-import-and-more/</guid>
            <description>
            
            &lt;p&gt;I&amp;rsquo;ve been busy at work so fell a bit behind with Django. Last night I worked on a WordPress importer, so that I could migrate posts from my current blog(s) into the Django-powered blog that I&amp;rsquo;m coding. I&amp;rsquo;m using BeautifulSoup to parse the WordPress export file and insert them as Django objects.&lt;/p&gt;
&lt;p&gt;Since I was running the script repeatedly, I had to figure out how to easily run it from the command line, without having to run it from inside manage.py shell. After some searching, I found that what I needed to do was set an environment variable DJANGO_SETTINGS_FILE to point to my settings file. After that, the importer script could be run repeatedly.&lt;/p&gt;
&lt;p&gt;Also made a few tweaks to my dev copy:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Modified URL mapping to follow the permalinks of the old blog (so that people linking to me don&amp;rsquo;t suddenly have broken links)&lt;/li&gt;
&lt;li&gt;Added a tag cloud (Still using django-tagging)&lt;/li&gt;
&lt;li&gt;Added markdown support to the admin maintenance screen. I used to think I would need to code my own form for posting, but I think I can live with just using the admin-provided one (initially at least)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I plan to migrate my main blog over once I take my Christmas break (hopefully 2nd week of December)&lt;/p&gt;
&lt;p&gt;Stuff to do:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use clean, non-hardcoded urls (url template tag and reverse())&lt;/li&gt;
&lt;li&gt;Customize the admin screen for posting&lt;/li&gt;
&lt;li&gt;Clean up the layout and templates&lt;/li&gt;
&lt;/ul&gt;



            </description>
        </item>
    
        <item>
            <title>django-tagging
</title>
            <link>https://mirror.roytang.net/2008/10/django-tagging/</link>
            <pubDate>Sun, 26 Oct 2008 04:22:00 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2008/10/django-tagging/</guid>
            <description>
            
            &lt;p&gt;I wanted to add some basic tagging to my blog app so I tried out &lt;a href=&#34;http://code.google.com/p/django-tagging/&#34;&gt;django-tagging&lt;/a&gt;. Unfortunately, the featured downloads on the Google Code site are quite out-of-date and would not work with Django 1.0, so I did a subversion checkout instead. If you&amp;rsquo;re getting an error like &amp;ldquo;ImportError: cannot import name parse_lookup&amp;rdquo;, then you need to get the source code from SVN.&lt;/p&gt;
&lt;p&gt;Adding the tagging to the blog was pretty easy:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the tagging app to settings.py&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add a tagging.fields.TagField to the Post model&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add a &amp;ldquo;tags&amp;rdquo; text field to the post form used.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Modify templates to display the tags.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I used something like &amp;ldquo;/tag/&amp;rdquo; url mapping to get all posts associated with a tag. Then you just need to write a wrapper around the object_list generic view:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;from tagging.models import Tag, TaggedItem&lt;/p&gt;
&lt;p&gt;from django.views.generic.list_detail import object_list&lt;/p&gt;
&lt;p&gt;def posts_by_tag(request, tag):&lt;/p&gt;
&lt;p&gt;o_tag = Tag.objects.get(name=tag)&lt;/p&gt;
&lt;p&gt;queryset = TaggedItem.objects.get_by_model(Post, o_tag)&lt;/p&gt;
&lt;p&gt;return object_list(request, queryset)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This view will use the same template used to list out posts normally.&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>I left it for a while
</title>
            <link>https://mirror.roytang.net/2008/10/i-left-it-for-a-while/</link>
            <pubDate>Fri, 24 Oct 2008 06:54:00 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2008/10/i-left-it-for-a-while/</guid>
            <description>
            
            &lt;p&gt;&amp;hellip; and now it works!&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.randomencounters.bells-n-whistles.net/blog/&#34;&gt;http://www.randomencounters.bells-n-whistles.net/blog/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I think the apache service needed to restart mod_python or something&amp;hellip; (I don&amp;rsquo;t have SSH access so&amp;hellip; )&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>Deployment Problems
</title>
            <link>https://mirror.roytang.net/2008/10/deployment-problems/</link>
            <pubDate>Tue, 21 Oct 2008 06:52:00 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2008/10/deployment-problems/</guid>
            <description>
            
            &lt;p&gt;So I got a basic blog app up and running.&lt;/p&gt;
&lt;p&gt;Posting, paged archives, etc.&lt;/p&gt;
&lt;p&gt;Comments implemented using the django.contrib.comments. No problems here, the only caveat being most of the current documentation found by Google searches refer to the pre-1.0 version. Need to peruse the official docs for 1.0 stuff.&lt;/p&gt;
&lt;p&gt;RSS feeds implemented using django.contrib.syndication, this one seems fine.&lt;/p&gt;
&lt;p&gt;I tested it and it&amp;rsquo;s running fine on localhost. I also have a free django hosting account at &lt;a href=&#34;http://bells-n-whistles.net&#34;&gt;http://bells-n-whistles.net&lt;/a&gt;, so I try to upload it there. However, when I access the website there (&lt;a href=&#34;http://www.randomencounters.bells-n-whistles.net/blog/&#34;&gt;http://www.randomencounters.bells-n-whistles.net/blog/&lt;/a&gt;), I get the following error:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&#39;comments&#39; is not a valid tag library: Could not load template library from django.templatetags.comments, No module named comments&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I think the settings.py is not being reloaded - I tried to set Debug = False and I&amp;rsquo;m still getting the stacktraces.&lt;/p&gt;
&lt;p&gt;Bah, I&amp;rsquo;ll figure it out tomorrow.&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>Playing with Generic Views and URLs
</title>
            <link>https://mirror.roytang.net/2008/10/playing-with-generic-views-and-urls/</link>
            <pubDate>Mon, 20 Oct 2008 13:44:00 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2008/10/playing-with-generic-views-and-urls/</guid>
            <description>
            
            &lt;p&gt;&amp;ldquo;when redirecting, how can I make the redirect URL decoupled from the urls.py of the parent app?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;-&amp;gt; It turns out that HttpResponseRedirect supports relative paths, so this was fine.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;return HttpResponseRedirect(&amp;quot;../&amp;quot; + str(post.id) + &amp;quot;/&amp;quot;)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I got the basic posting structure up.&lt;/p&gt;
&lt;p&gt;/post/new/ -&amp;gt; To make new posts&lt;/p&gt;
&lt;p&gt;/post// -&amp;gt; To view a single post&lt;/p&gt;
&lt;p&gt;/post/all/ -&amp;gt; To view all posts&lt;/p&gt;
&lt;p&gt;I should probably start thinking of a better url scheme. Ideally, I&amp;rsquo;d want the @login_required views to be indicated as such in the urls. Something like &amp;ldquo;/admin/post/&amp;rdquo; for new posts &amp;ldquo;/admin/manage/&amp;rdquo; for a screen to manage posts to differentiate it from a screen just to list them out.&lt;/p&gt;
&lt;p&gt;Next I think I&amp;rsquo;ll try to CSS-ify the blog; I&amp;rsquo;ll probably just reuse stuff from one of the blogger templates as I&amp;rsquo;m still not very good with the HTML/CSS.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll also look into using some of the date-based generic views to get an archive view. I&amp;rsquo;ll need more data though. Will consider importing from the WordPress blog.&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>Starting out
</title>
            <link>https://mirror.roytang.net/2008/10/starting-out/</link>
            <pubDate>Sun, 19 Oct 2008 07:33:00 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2008/10/starting-out/</guid>
            <description>
            
            &lt;p&gt;The quintessential app to learn from is of course a blog.&lt;/p&gt;
&lt;p&gt;Started using a simple Post model. Added the new post form and view. Can now successfully insert posts into the DB.&lt;/p&gt;
&lt;p&gt;Next:&lt;/p&gt;
&lt;p&gt;&amp;ndash; create the detail page that will show the post after saving&lt;/p&gt;
&lt;p&gt;Figure out:&lt;/p&gt;
&lt;p&gt;&amp;ndash; when redirecting, how can I make the redirect URL decoupled from the urls.py of the parent app?&lt;/p&gt;
&lt;p&gt;i.e. if the parent app has the following mapping:&lt;/p&gt;
&lt;p&gt;‘^blog/&amp;rsquo; -&amp;gt; pass to blog.urls.urlpatterns&lt;/p&gt;
&lt;p&gt;the blog app has mappings for&lt;/p&gt;
&lt;p&gt;‘^post/new/&amp;rsquo; -&amp;gt; new post&lt;/p&gt;
&lt;p&gt;‘^post/([A-Za-z-])/&amp;rsquo; -&amp;gt; post detail&lt;/p&gt;
&lt;p&gt;inside the view, I want to redirect to &amp;ldquo;post/&amp;rdquo;, but with respect to the app, it should be &amp;ldquo;blog/post/&amp;rdquo;&lt;/p&gt;
&lt;p&gt;I should subscribe to one of the Django mailing lists to ask stuff like this.&lt;/p&gt;



            </description>
        </item>
    
        <item>
            <title>Write Facebook apps using Google AppEngine -- Patrick Crosby
</title>
            <link>https://mirror.roytang.net/2008/07/write-facebook-apps-using-google-appengine-patrick-crosby/</link>
            <pubDate>Sun, 06 Jul 2008 15:21:24 +0000</pubDate>
            <author>hello@roytang.net (Roy Tang)</author>
            <guid>https://mirror.roytang.net/2008/07/write-facebook-apps-using-google-appengine-patrick-crosby/</guid>
            <description>
            Shared via delicious:
    &lt;a href=&#34;http://blog.patrickcrosby.com/posts/35-Write-Facebook-apps-using-Google-AppEngine&#34;&gt;Write Facebook apps using Google AppEngine -- Patrick Crosby&lt;/a&gt;

            


            </description>
        </item>
    
    </channel>
  </rss>