Archive for the ‘PHP’ Category

WordPress Rocks at Updates

Tuesday, July 15th, 2008

I feel I owe it to my friends who put up with my senseless Python fanboying to admit WordPress is not only a great blog engine, but rocks at updates.

I just upgraded from 2.5 to 2.6 by doing a simple svn switch http://... and then logging into the web admin interface. It took about 30 seconds to complete.

Now compare that to my last experience upgrading Trac from 0.10 to 0.11… ugh.

I love you Trac. Python just lacks an easy and efficient web app deployment method.

Simple WordPress Upgrade Using Subversion

Sunday, October 28th, 2007

I’ve been using subversion to update WordPress for a few minor revisions now. I simply followed the 2.2 branch and ran…

svn up

…to update my code.

Today I ran…

svn switch http://svn.automattic.com/wordpress/branches/2.3

…followed by visiting the upgrade script page and everything worked beautifully!

Anyone not using subversion to update WordPress is doing way too much work! Time to play with tags…

Now if I was really cool I’d use bzr to maintain my local code changes and plugins in my own repository… maybe later.

IRC After a 10 Year Hiatus

Friday, September 21st, 2007

Its probably been 10+ years since I’ve touched IRC. In the early days of the public Internet, IRC was IM + MySpace + Filesharing, only a lot geekier. :)

Then came ICQ and soon after a flood of IM clients that rendered IRC clumsy and antiquated for casual chatting. When I went from High School to College in 2000, I left IRC behind…

Now its 2007, I’m an old man and returning to my old ways. I’m back on IRC except instead of chatting with friends using pIRCh* on Windows 98, I’m lurking in technical channels using irsii centrally located on a Debian Etch server.

If you want to track me down I go by the nick schmichael** and am currently lurking in the following channels.

  • #cherrypy on irc.oftc.net
  • #linode on irc.oftc.net
  • #python-genshi on irc.freenode.net
  • #drupal-ecommerce on irc.freenode.net

I also pop in and out of #gnome on gimpnet and #drupal-support on irc.freenode.net.

To experienced free and open source software community members the fact that IRC is new or strange to anyone is probably a bit hard to grasp. As far as I can tell, IRC is simply the de facto method for communicating about FOSS projects. Mailing lists may be more popular for some projects, but I find the instance gratification of IRC much more appealing.

* I remember liking its scripting better then mIRC or some such nonsense… I’ve never been known to use the most popular software available…

** A very unimaginative combination of my first and last names given to me by some friends in college. It works.

New WordPress Plugins and Updates

Saturday, September 1st, 2007
WordPress Screenshot

I just added the Subscribe to Comments WordPress plugin. You should now be able to get e-mail notifications when new comments are posted. This should make flamewars and trolling much easier. ;)

For what its worth I also installed the Google Sitemap Generator plugin which seems to work alright. My main gripe is that the author uses a blog post dated June 5, 2005 as the home page for the plugin! I actually passed it up and kept looking the first time I hit the page because I assumed the plugin was old.

I have to admit, sites that use a blog like a full-fledged CMS usually annoy me. Of course tons of sites probably do it without me noticing, so I suppose if its done well, I don’t mind. :)

A while ago I installed the WP-Syntax plugin. Here’s a snippet of Python to test it out since I haven’t gotten around to posting any code lately:

d = {'test1': 'hello world'}
d.setdefault('test1', 'goodbye world')
d.setdefault('foo', 'bar')
print d['test1']
print d['foo']

This prints:

hello world
bar

becase setdefault() only changes the value of a dictionary key if the key has no value. Very handy.

My final bit of WordPress hacking has been to switch to using Subversion to update WordPress. Juggling files to do updates is just annoying. With Subversion I just checked out http://svn.automattic.com/wordpress/branches/2.2 and run svn up whenever an update is released.

I suppose I could just schedule running svn up with a cron job. It would even automatically e-mail what files it updates because cron e-mails stdout by default. But considering how much I love automatic updates on Windows, I think I’ll hold off on that… ;)

Update: Grrr… Now if only I could convince WordPress not to convert my <div> tags to <p> tags when editing posts and messing up my whitespace when saving!

Deploying CherryPy on Apache 2 using mod_proxy

Thursday, August 16th, 2007

Background

I’ve been trying to move away from PHP to Python for web applications. I tried Django and TurboGears, but I settled upon the more basic CherryPy framework. It helped that my friend Christian is active in the CherryPy community and promised to answer all of my stupid questions (thanks Christian!).

Regardless of which framework I had chosen though, they all have a significant architectural difference from PHP:

  • PHP is a scripting language.
  • Django, TurboGears, CherryPy, etc. are application servers.

Technically Python is a scripting language and PHP+Apache could be called an application server, so I should explain:

  • PHP web applications are executed from start to finish for each web request.
  • The Python frameworks all run as a daemon and requests are processed based on object and method mappings.

Still probably a gross oversimplification, but for the sake of brevity lets move on!

The reason I mention these fundamental differences is because they completely change how you deploy your web applications. PHP scripts can be FTPed (via SSH/SSL/TLS of course!) to a web accessible directory and instantly accessed. Python web applications must be started and somehow integrated with your existing web server (Apache 2 in my case).

The Problem

So how do you deploy CherryPy applications and have them play nice with Apache 2?

One Solution: Using mod_proxy

Warning: These instructions are for Debian Etch, but the principles should be fairly universal.

Example domain: www.example.com
Example CherryPy URL: http://www.example.com/webapp/
Example CherryPy Root Object: WebApp()
Example CherryPy Configuration File: webapp.config

  1. Install Apache 2 (if you don’t use PHP, feel free to choose a MPM other than prefork) and Python
  2. Install python-setuptools if you haven’t already:
    sudo apt-get install python-setuptools
  3. Install CherryPy via easy_install to get the latest stable version:
    sudo easy_install cherrypy
  4. Edit your CherryPy applications’ config file (webapp.config in this example) to include the following lines:
    server.socket_port = 6464
    server.socket_host = "127.0.0.1"
  5. To start your web application you should have a line similar to:
    cherrypy.quickstart(WebApp(), '/webapp', 'webapp.config')
  6. Start your application as a background process. I usually use a command like this:
    python start-webapp.py > stdout.log &
  7. If you have lynx or links installed you can test your web application:
    lynx http://127.0.01:6464/webapp/
  8. Enable mod_proxy for Apache 2:
    sudo a2enmod proxy_http
  9. Add the following to the Apache virtual host configuration for www.example.com (for example: /etc/apache2/sites-enabled/000-default or /etc/apache2/sites-enabled/www.example.com):
    ProxyPreserveHost on
    <Proxy *>
      Order allow,deny
      Allow from all
    </Proxy>
    ProxyPass /webapp/ http://127.0.0.1:6464/webapp/
    ProxyPassReverse /webapp/ http://127.0.0.1:6464/webapp/
  10. Restart Apache 2 using the following command:
    sudo /etc/init.d/apache2 force-reload

Go to http://www.example.com/webapp to see if it works!

Caveats and Tips

  • Be careful using absolute URLs (especially in redirects!) in your web application.
  • To make sure your web application always starts at boot, add this line to your crontab:
    @reboot /usr/bin/python /path/to/start-webapp.py > /path/to/stdout.log &

Other Solutions

Using mod_proxy is neither the only way to deploy CherryPy web applications nor the best for all deployment scenarios. Once I have a bit more experience I’d love to post a side-by-side comparison, but for now your probably best off reading CherryPy’s wiki article on the subject.

Drupal Database Maintenance Script

Friday, August 3rd, 2007

I love Drupal, but its insistence on saving every session its ever created causes the sessions table to become massive. So I usually end up creating a shell script like the following:

drupal-db-maint.sh (I posted a copy to pastebin since WordPress makes the code impossible to read.)

#!/bin/sh
echo `date` - Starting Drupal database maintenance
MYSQL_USERNAME=’insert your MySQL username here
MYSQL_PASSWORD=’insert your MySQL password here
MYSQL_DATABASE=’insert your database name here

# Note: 2592000 = sessions over 30 days old.
# Adjust the timespan as desired.
CLEAN_SESSIONS_SQL=’DELETE FROM `sessions` WHERE `timestamp` < (UNIX_TIMESTAMP() - 2592000)’
OPTIMIZE_CACHES_SQL=’OPTIMIZE TABLE `cache` , `cache_filter` , `cache_menu` , `cache_page` , `cache_views` , `sessions`’

# Note: I have tons of modules installed.
# I tried cleaning out their table names before posting, but you’ll want to double check this SQL.
OPTIMIZE_REST_SQL=’OPTIMIZE TABLE `access` , `accesslog` , `aggregator_category` , `aggregator_category_feed` , `aggregator_category_item` , `aggregator_feed` , `aggregator_item` , `authmap` , `blocks` , `blocks_roles` , `boxes` , `client` , `client_system` , `comments` , `contact` , `files` , `file_revisions` , `filters` , `filter_formats` , `flood` , `history` , `invite` , `menu` , `node` , `node_access` , `node_comment_statistics` , `node_counter` , `node_revisions` , `node_type` , `permission` , `profile_fields` , `profile_values` , `role` , `search_dataset` , `search_index` , `search_total` , `sequences` , `system` , `term_data` , `term_hierarchy` , `term_node` , `term_relation` , `term_synonym` , `url_alias` , `users` , `users_roles` , `variable` , `vocabulary` , `vocabulary_node_types` , `watchdog`’

# Note: I run this script on a Linode which has limited IO.
# Adding a short wait between commands lessens the load on the server.
SLEEP_TIME=5

echo $CLEAN_SESSIONS_SQL | mysql -u $MYSQL_USERNAME -p$MYSQL_PASSWORD $MYSQL_DATABASE
sleep $SLEEP_TIME

echo $OPTIMIZE_CACHES_SQL | mysql -u $MYSQL_USERNAME -p$MYSQL_PASSWORD $MYSQL_DATABASE > /dev/null
sleep $SLEEP_TIME

echo $OPTIMIZE_REST_SQL | mysql -u $MYSQL_USERNAME -p$MYSQL_PASSWORD $MYSQL_DATABASE > /dev/null

echo `date` - Done with Drupal database maintenance

Then just run crontab -e to edit your crontab and add a line similar to:
46 4 * * * /path/to/drupal-db-maint.sh

That will optimize your database nightly at 4:46 AM server time (usually UTC).

If you don’t like my solution, there are plenty of more elegant session cleaning solutions out there. I’m just more comfortable writing shell scripts and crontabs than Drupal modules that use hook_cron.

Posting code in WordPress so that its readable is pretty much impossible. Any suggestions?