Announcing Pythug, Idaho's Python Users Group

I've decided something. I love Python. A lot. It's, like, the best programming language in the world. It's such a pleasure to use and program. It works on basically anything. And it's pretty.

Living in Idaho, there aren't quite as many passionate programmers as you might find in many other places of the world (even in a university setting). A while back, I started looking around for a possible Python Users Group (PUG) in my area so I could bask in Python goodness with others. I was very surprised to learn that there wasn't one nearby.

As a result, I took it upon myself to begin to create one, mainly for southeastern Idaho. Since I started using Python about a year and a half ago, I've spread the good word amongst many of my colleagues. Many have started to like Python, others have decided it's not their cup of tea. For the time being, it appears that the PUG will be comprised primarily of my colleagues and myself. However, I would like the group to be a place where beginners and experts alike can come together to learn and instruct each other. I have plans. Devious plans.

The problem I have is a lack of time. That shouldn't surprise anyone, because we all seem to be in the same boat when it comes to time. Anyway, there are still some details that need to be addressed. This will take time. I don't anticipate things being "ready" until April, around the time that my semester ends.

For any of you who are interested in joining such a community, I would encourage you to visit its brand spankin' new Web site to sign up for progress updates. Those who sign up for updates will be counted on the "unofficial" membership roster, but there is no obligation to really become a member when all is said and done. It's merely a way for me to update everyone at the same time a couple times a month.

If you live in Idaho and are interested in joining Pythug, or know someone who might be interested, please get the information in the form. Remember... there are plans. :D

Miscellaneous Site Updates

I figured I should probably post something since I haven't done so yet this year. I've been making several changes to the site lately. Most of them are pretty subtle, but I hope they're useful to you. Updates include

  • You can now send an article to some friends by clicking on the "envelope" icon in the top-right corner of each article. It's a pretty simple mechanism.

  • You can save any of my articles to your hard drive for later consumption in the form of a PDF. Just click the "save" button in the top right corner of any article, and you will be able to view/save the latest revision of the respective article as a PDF. One thing to note on this, though, is that the program I use to generate the PDFs does not support the line numbers in code blocks. Sorry folks.

    For those of you who are interested, I'm using rst2pdf to generate the PDFs from my reStructuredText-based articles.

  • I've removed the calendar from the sidebar and replaced it with my newest useless side project: django-bibliophile. It allows me to share my reading progress with my visitors, because I know you all care that much. I plan on officially releasing the project in the near future.

  • Pagination has been implemented in parts of the article archive.

  • I've added an "article distribution" chart when looking at a year's blog articles.

  • Other random improvements.

django-watermark 0.1.5-pre1

I've been making several updates to django-watermark during my more boring classes the past couple days. I have just released a new version for your pleasure.

Changes include:

  • A lot of code refactoring. There was a lot of logic in the watermark filter itself. I decided this logic should be placed elsewhere so as to make the utils.watermark function easier to use outside the realm of the watermark filter.
  • Removed the "parameter precedence" that used to exist between the positioning, tiling, and scaling parameters. Previously, if scale was defined, any values for position and tile were ignored. Similarly, if any value was given for tile, any value for position was ignored. Now you can use all three parameters simultaneously.
  • Added a couple of goodies for positioning and scaling.

I think this is quite a stable release. Please notify me if you find any problems with it!!

django-watermark 0.1.2-pre1

I've added a few updates to django-watermark and figured it was time to announce another release. Updates include:

  • the ability to place watermarks randomly on the target image
  • updated the way relative positioning works. Now, position=50%x50% will center the watermark image on the target image. Previously django-watermark placed the top-left corner of the watermark image in the center of the target image.
  • the ability to convert the watermark image to a transparent greyscale image before applying it to the target image
  • the ability to rotate the watermark image using either a specific number of degrees or usign a random rotation value

Both Google Code and PyPI have been updated with these changes.

django-pendulum news

I've made several fun improvements to my Pendulum Django application. Perhaps the most noteworthy for most people is the addition of a default jQuery-powered date picker for adding and updating entries. I was hesitant to make anything like this be required because some people might prefer controls other than the one I chose. However, I tried to make it easy to override this default date picker if you so desire. Hopefully someone will report on how easy/difficult it is.

Also, I've added django-pendulum to the PyPI, which is Python's little package repository. You can think of it as an apt-get repository for those of you familiar with Debian/Ubuntu Linux or derivatives. There is a utility called easy_install, which obviously makes it easy to install packages that are found in the PyPI. The command to install django-pendulum with easy_install is easy_install django-pendulum. Good stuff!

There have been various other changes to the code, and I have some more changes planned. We'll see how long it takes me to get around to making these changes...

Installing Django on Shared Hosting (Site5)

This article is a related to my previously posted article about installing Django, an advanced Web framework for perfectionists, on your own computer. Now we will learn how to install Django on a shared hosting account, using Site5 and fastcgi as an example. Depending on your host, you may or may not have to request additional privileges from the support team in order to execute some of these commands.

Note: Django requires at least Python 2.3. Newer versions of Python are preferred.

Note: This HOWTO assumes familiarity with the UNIX/Linux command line.

Note: If the wget command doesn't work for you (as in you don't have permission to run it), you might try curl [url] -O instead. That's a -O as in upper-case o.

Install Python

Site5 (and many other shared hosting providers that offer SSH access) already has Python installed, but you will want to have your own copy so you can install various tools without affecting other users. So go ahead and download virtual python:

mkdir ~/downloads
cd ~/downloads
wget http://peak.telecommunity.com/dist/virtual-python.py

Virtual Python will make a local copy of the installed Python in your home directory. Now you want to make sure you execute this next command with the newest version of Python available on your host. For example, Site5 offers both Python 2.3.4 and Python 2.4.3. We want to use Python 2.4.3. To verify the version of your Python, execute the following command:

python -V

If that displays Python 2.3.x or anything earlier, try using python2.4 -V or python2.5 -V instead. Whichever command renders the most recent version of Python is the one you should use in place of python in the next command. Since python -V currently displays Python 2.4.3 on my Site5 sandbox, I will execute the following command:

python ~/downloads/virtual-python.py

Again, this is just making a local copy of the Python installation that you used to run the virtual-python.py script. Your local installation is likely in ~/lib/python2.4/ (version could vary).

Make Your Local Python Be Default

To reduce confusion and hassle, let's give our new local installation of Python precedence over the system-wide Python. To do that, open up your ~/.bashrc and make sure it contains a line similar to this:

export PATH=$HOME/bin:$PATH

If you're unfamiliar with UNIX-based text editors such as vi, here is what you would type to use vi to make the appropriate changes:

  • vi ~/.bashrc to edit the file
  • go to the end of the file by using the down arrow key or the j key
  • hit o (the letter) to tell vi you want to start typing stuff on the next line
  • type export PATH=$HOME/bin:$PATH
  • hit the escape key
  • type :x to save the changes and quit. Don't forget the : at the beginning. Alternatively, you can type :wq, which works exactly the same as :x.

Once you've made the appropriate changes to ~/.bashrc, you need to make those changes take effect in your current SSH session:

source ~/.bashrc

Now we should verify that our changes actually took place. Type the following command:

which python

If they output of that command is not something like ~/bin/python or /home/[your username]/bin/python, something probably didn't work. If that's the case, you can try again, or simply remember to use ~/bin/python instead of python throughout the rest of this HOWTO.

Install Python's setuptools

Now we should install Python's setuptools to make our lives easier down the road.

cd ~/downloads
wget http://peak.telecommunity.com/dist/ez_setup.py
python ez_setup.py

This gives us access to a script called easy_install, which makes it easy to install many useful Python tools. We will use this a bit later.

Download Django

Let's now download the most recent development version of Django. SSH into your account and execute the following commands (all commands shall be executed on your host).

svn co http://code.djangoproject.com/svn/django/trunk ~/downloads/django-trunk

Now we should make a symlink (or shortcut) to Django and put it somewhere on the Python Path. A sure-fire place is your ~/lib/python2.4/site-packages/ directory (again, that location could vary from host to host):

ln -s ~/downloads/django-trunk/django ~/lib/python2.4/site-packages
ln -s ~/downloads/django-trunk/django/bin/django-admin.py ~/bin

Now verify that Django is installed and working by executing the following command:

python -c "import django; print django.get_version()"

That command should return something like 1.0-final-SVN-8964. If you got something like that, you're good to move onto the next section. If, however, you get something more along the lines of...

Traceback (most recent call last):
    File "<string>", line 1, in ?
ImportError: No module named django

...then your Django installation didn't work. If this is the case, make sure that you have a ~/downloads/django-trunk/django directory, and also verify that ~/lib/python2.4/site-packages actually exists.

Installing Dependencies

In order for your Django projects to become useful, we need to install some other packages: PIL (Python Imaging Library, required if you want to use Django's ImageField), MySQL-python (a MySQL database driver for Python), and flup (a utility for fastcgi-powered sites).

easy_install -f http://www.pythonware.com/products/pil/ Imaging
easy_install mysql-python
easy_install flup

Sometimes, using easy_install to install PIL doesn't go over too well because of your (lack of) permissions. To circumvent this situation, you can always download the actual PIL source code and install it manually.

cd ~/downloads
wget http://effbot.org/downloads/Imaging-1.1.6.tar.gz
tar zxf Imaging-1.1.6.tar.gz
cd Imaging-1.1.6
ln -s ~/downloads/Imaging-1.1.6/PIL ~/lib/python2.4/site-packages

And to verify, you can try this command:

python -c "import PIL"

If that doesn't return anything, you're good to go. If it says something about "ImportError: No module named PIL", it didn't work. In that case, you have to come up with some other way of installing PIL.

Setting Up A Django Project

Let's attempt to setup a sample Django project.

mkdir -p ~/projects/django
cd ~/projects/django
django-admin.py startproject mysite
cd mysite
mkdir media templates

If that works, then you should be good to do the rest of your Django development on your server. If not, make sure that ~/downloads/django-trunk/django/bin/django-admin.py exists and that it has a functioning symlink (shortcut) in ~/bin. If not, you'll have to make adjustments according to your setup. Your directory structure should look something like:

  • projects
    • django
      • mysite
        • media
        • templates
        • __init__.py
        • manage.py
        • settings.py
        • urls.py

Making A Django Project Live

Now we need to make your Django project accessible from the Web. On Site5, I generally use either a subdomain or a brand new domain when setting up a Django project. If you plan on having other projects accessible on the same hosting account, I recommend you do the same. Let's assume you setup a subdomain such as mysite.mydomain.com. On Site5, you would go to ~/public_html/mysite for the next few commands. This could differ from host to host, so I won't go into much more detail than that.

Once you're in the proper place, you need to setup a few things: two symlinks, a django.fcgi, and a custom .htaccess file. Let's begin with the symlinks.

ln -s ~/projects/django/mysite/media ~/public_html/mysite/static
ln -s ~/lib/python2.4/site-packages/django/contrib/admin/media ~/public_html/mysite/media

This just makes it so you can have your media files (CSS, images, javascripts, etc) in a different location than in your public_html.

Now for the django.fcgi. This file is what tells the webserver to execute your Django project.

#!/home/[your username]/bin/python
import sys, os

# Add a custom Python path.
sys.path.insert(0, "/home/[your username]/projects/django")

# Switch to the directory of your project. (Optional.)
os.chdir("/home/[your username]/projects/django/mysite")

# Set the DJANGO_SETTINGS_MODULE environment variable.
os.environ['DJANGO_SETTINGS_MODULE'] = "mysite.settings"

from django.core.servers.fastcgi import runfastcgi
runfastcgi(method="threaded", daemonize="false")

And finally, the .htaccess file:

1
2
3
4
5
6
RewriteEngine On
RewriteBase /
RewriteRule ^(media/.*)$ - [L]
RewriteRule ^(static/.*)$ - [L]
RewriteCond %{REQUEST_URI} !(django.fcgi)
RewriteRule ^(.*)$ django.fcgi/$1 [L]

The .htaccess file makes it so that requests to http://mysite.mydomain.com/ are properly directed to your Django project. So, now you should have a directory structure that something that looks like this:

  • public_html
    • mysite
      • media
      • static
      • .htaccess
      • django.fcgi

If that looks good, go ahead and make the django.fcgi executable and non-writable by others:

chmod 755 ~/public_html/mysite/django.fcgi

After that, head over to http://mysite.mydomain.com/ (obviously, replace the mydomain accordingly). If you see a page that says you've successfully setup your Django site, you're good to go!

Afterthoughts

I've noticed that I need to "restart" my Django sites on Site5 any time I change the .py files. There are a couple methods of doing this. One includes killing off all of your python processes (killall ~/bin/python) and the other simply updates the timestamp on your django.fcgi (touch ~/public_html/mysite/django.fcgi). I find the former to be more destructive and unreliable than the latter. So, my advice is to use the touch method unless it doesn't work, in which case you can try the killall method.

Good luck!

First Impressions: openSUSE 11.0

Those of you who have ever held any sort of conversation with me have probably heard or have personal experience with my bigotry concerning Linux. I absolutely love Linux, and I make all sorts of excuses for the things it doesn't to as well as Windows and Mac OS to convince people to use Linux. It's just the way I am.

I've been using Linux as my main operating system ever since about 2000, though I did dabble with it a few times before that. I started out with RedHat Linux way back when, and then moved on to Mandrake (now Mandriva) Linux. As time passed, I found out about this particular distribution called "SuSE Linux," which claimed to be able to detect hardware even better than the others I had tried. It even looked really pretty. I began to really want to use this distribution. It got to the point where I almost spent $80 on it, just so I could play around.

Eventually, I got my hands on a free copy by downloading all of the packages from their FTP server or something. I managed to get this installed, and I was even more impressed than I had anticipated. SuSE Linux was amazing. But by this time, I had already become addicted to downloading and trying out any distribution I could get my hands on. That meant that SuSE spent a few days or weeks on my computer before I replaced it with something else.

As I tried more and more distributions of Linux, I began to form opinions about them. I observed what certain distributions did well, and made hard mental notes about what each distribution didn't do so well. It wasn't long before I noticed that basically all of the RPM-based distributions I had tried suffered from two major problems: bloated installation packages and severe system slow-downs as time went on. It seemed that RPM-based distributions always slowed down just as bad as Windows machines. Other types of Linux, such as Slackware, Gentoo, and Debian, didn't seem to suffer from this nearly as bad.

With these opinions in mind, I carefully chose which distributions I elected to actually install with plans for keeping around a long time. It seemed like I would always download the RPM-based distributions, but I would do it "just in case" someone else wanted the CD or DVD. Sometimes I would download the distributions and never even bother to burn the CD image to disc. I would just stuff the image away for future reference.

However, despite my opinions of RPM-based distributions, I did end up installing SUSE Enterprise Linux Desktop/Server and openSUSE a few years ago. Part of it was for a class I had; another part was to find a distribution that would suit the needs of one of my buddies. I noticed several improvements in the distributions as the years passed, but those lingering problems with bloated packages and system slow-downs still plagued each distribution.

Last week, openSUSE 11.0 was finally released. Just like always, I downloaded the CD and DVD images with no plans of actually installing openSUSE anywhere. As the downloads were going, I read some reviews posted by other people. It sounded like this particular release of openSUSE actually addressed the issues of bloat and system slow-downs (finally!!), so that made me happy, but I still didn't quite consider installing it on any of my computers. I did use one of the live CD's at work for a day, though, and it treated me well.

This morning I got the itch to change the distribution I had installed on my main computer. I was going through the list of recent downloads that I had, and it occurred to me that the most recent version I had was openSUSE 11.0. It also occurred to me that it had been at least two years since I had seriously considered installing openSUSE or SLED/SLES on my computer. So I decided that maybe everything I had read was worth looking into on my own and possibly revisiting my biased opinion of RPM-based distributions.

I started the installation early this morning while I took notes and worked from another machine. The installation went very smoothly. Everything was logical and clean. It really was a good experience. The packages really did seem to install considerably faster than any release in the past, so I had high hopes for how the system would perform after installation. After everything was said and done, my computer rebooted into the freshly installed KDE 4.0 desktop of openSUSE 11.0. It looked nice, and it was actually functional--which I cannot honestly say about any other distributions that have a KDE 4.0 remix.

Since up to this morning I hadn't been able to use KDE 4 long enough to figure out what's changed, that's where I started. I explored the new menu, which I have to admit is quite funky, but I guess that's how the industry likes things nowadays. I played around with some of the personal settings that it offers. Things seemed logical enough, but it is quite a change from KDE 3.5, which I've been using for quite a while.

After a couple minutes of tinkering, I noticed a little bubble in the corner that said something about installing some system updates. I clicked it and ran through some sort of wizard, but I guess there were no updates to install. Or maybe I just have super-slow Internet and it was taking forever to download the changes. Whatever the case, I kept on tinkering with some settings while the updater did its thing.

Next thing I know, my screen goes black and flashes a few times. Then all I can see is a white mouse on a black background. That's it. Nothing else. I'm really not sure what the problem was. The settings I was playing with seemed fairly innocent, as I modify those sorts of settings all the time on KDE 3.5. After a few minutes of white-mouse-on-black-screen fun, I decided a reboot might solve the problem.

A couple minutes later, I was presented with my loading screen, followed by the black screen and white mouse. That's it. Nothing else.

Needless to say, despite all of the improvements that I did notice in this release of openSUSE, it left a rather bitter taste in my mouth in other areas. openSUSE is no longer on my computer--it's long been replaced with yet another distribution.

Maybe it's user error. Maybe it's my computer's hardware. Or maybe openSUSE really does suck. Whatever the case, it wouldn't surprise me if I wait another year or two to try out another RPM-based distribution.

Opera Debian Repositories

Being a web developer, I have an obligation to ensure that the sites I build work on the wides range of popular web browsers as possible. Because of this, I often find myself installing the wonderful Opera web browser on my Linux systems. Now, I could just download it directly from http://www.opera.com/ each time there's an upgrade, but it is much easier to handle when running a Debian-based distribution thanks to the apt-get infrastructure. This article will explain how to set your Debian system up to be capable of automatically updating Opera any time there is a new release.

  1. Install the keyring. A keyring is simply a way to verify the identity of the repository. It kinda makes sure that you are installing from the server you want to be installing from, instead of a different server that has unauthorized packages. To install the keyring, run the following command as root (or with root privileges using sudo):

    wget -O - http://deb.opera.com/archive.key | apt-key add -

    Note: Copying and pasting the above command does not seem to play well. The dash immediately before the http://... is translated improperly on this webpage. It should just be a regular dash.

  2. Install the repositories. This part usually depends upon your particular flavor of Debian. I am running Debian Sid, so I install the Opera repository using the following line:

    deb http://deb.opera.com/opera/ sid non-free

    or if I am feeling brave, I can install the "unstable" testing version of opera with

    deb http://deb.opera.com/opera-beta/ sid non-free

    If you are running Debian “etch”, you would change sid to etch and likewise for other flavors of Debian. This line typically goes in the /etc/apt/sources.list file. Just put it on its own line. Some newer Debian systems prefer that you put this line in /etc/apt/sources.list.d/[repository].list (where [repository] would likely be opera in this case).

  3. Run apt-get update as root to make sure the repositories are working properly. If they are, you should see no errors or warnings pertaining to opera.com. If you see any such messages, try updating again.

  4. Install Opera. Run the following command as root:

    apt-get install opera

Once that completes, you should be able to launch Opera without a hitch!

How To Create A Subversion Repository

In this tutorial, I assume that you have access to a Linux machine on which you plan to create the repository. I have never tried to create a repository on Windows or Mac, but perhaps in the future I will. I am doing this on a Slackware 10.2 machine with subversion 1.3.2. Version differences shouldn't have a great effect on the validity of the steps outlined here.

Install Subversion

If you haven't already installed subversion, you can download it from http://subversion.tigris.org/. You can download the svn package for a variety of platforms. If you download the source package, you should simply have to do the following as root:

  • unpack the archive and enter that folder
  • configure the application for your system by typing ./configure on the command line
  • compile the source code by typing make
  • install the package by typing make install

Note: these are the general steps for installing a package from the source; they may be slightly different with svn.

Choose A Home For The Repository

Next, choose a place for your server to keep track of all of the changes to your project. Try a place like /var/svn or /home/[your_username]/svn. I would recommend creating a folder specifically for the repository.

Create The Repository

Once you're in the directory in which you wish for your svn repository to reside, type the command svnadmin create repo or you can type the full path to be certain svnadmin create /var/svn/repo. This will create the repository.

Import Your Project

I do most of my development on my local area network, so I haven't created a repository that can be used over the Internet. I would imagine that it's pretty similar to what we do to create a repository for your LAN. Choose a project to import into your repository and navigate to the folder that the project is in. For example, if I have a project called Foo in /var/www/htdocs/foo, I would go to /var/www/htdocs. Next, use the command svn import to pull your project into the repository. For our Foo project, we would use the command svn import foo svn://localhost/var/svn/repo/foo -m "Initial Import". This will create a new folder in our repository at /var/svn/repo called foo (/var/svn/repo/foo). Our project files will put crammed into that directory for tracking.

Checkout Your Project

In order to be able to save your changes to our repository, we have to checkout the project again from the server. This is a pretty simple step, but it is critical. Even though we imported our project already, that folder remains untouched. SVN will not know how to handle the updates unless we checkout the project from the svn server. So, we proceed to checkout by removing or renaming /var/www/htdocs/foo and typing svn checkout svn://localhost/var/svn/repo/foo /var/www/htdocs/foo. This will place some hidden folders in each of the directories in your project. These hidden folders keep track of your local changes so that svn will know how to merge your changes with those of other developers.

Update The Repository

When you've made some changes that you want to save, you can send them out by typing svn commit /var/www/htdocs/foo. This command knows how to get to the server to save the changes, since the project was checked out from the repository.

Update Your Files

Sometimes you'll need to get changes that other developers have made, or revert back to a version of your project that didn't have as many problems. You can do this using the svn update command. If you're already in /var/www/htdocs/foo, you can type svn update and it will update files that have been changed in the repository since you last updated. If you're looking to get an older version of your project, you can type svn update -r PREV or a revision number in place of PREV.

Remember, these are just the basics of using SVN. You can do many amazing things with this utility. I actually did all of this as I was writing this article, so I'm sure that it works.