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!

My First Firefox Extension

Last November, a former co-worker and I began brainstorming for a particular site. This site was intended to give people a way to remember quotes that they heard/read/smelled/absorbed/etc without much effort. Soon thereafter, QuoteBoards.org was born.

The site has been pretty boring until recently, though it has been performing its purpose since its first launch. Up until a couple weeks ago, we only had one truly "faithful" member. This member, dirid51, added quotes to his QuoteBoard regularly. He held the site record of 52 quotes until one day another member (Puck) blew is 52 quotes out of the water with nearly 150 (genuine, I might add) quotes in one day.

I got in touch with Puck, and he shared some invaluable feedback with me concerning QuoteBoards.org. With this feedback, I was able to make several improvements that helped Puck along the way as he added his collection of quotes. Currently, he as 1,002 quotes. Most of these were added within a two or three day window. The reason he's stopped adding quotes is because he's tired of transcribing them from printed documents.

With that in mind, I decided it was finally time to begin working on the Firefox extension that I had originally planned to build for QuoteBoards.org when my co-worker and I were initially brainstorming. The purpose of this extension was to make adding quotes from the Web even easier. So, with a few minutes here and there between laundry and such, I was able to build my very first Firefox extension: Quote Grabber.

Right now, the extension is marked as "experimental" and requires people to log into the Mozilla Add-ons site in order to install and use it. However, if you're feeling adventurous, you can bypass that requirement by installing it directly from QuoteBoards.org. There are also directions for using it there.

I hope that those of you who are reading this find the extension to be beneficial and useful. I had a good time developing it nonetheless.

Andy Rutledge: Don't Walk; Run

This morning I've been doing some research for work, and I stumbled upon an article that is very helpful for freelancers like me (relatively new to the freelance arena) and people looking for freelancers/design agencies.

Given the recent freelance opportunities that I have been involved with, I found this article to be particularly beneficial. There are many pieces of advice that, taken into consideration, really do distinguish the good freelancers/design agencies from the bad ones.

If the agency has any clue at all, your company will basically have to "interview for the job" in order to be accepted as a client. Agencies that know what they're doing work hard to take on only those projects and those clients that are a good fit for their skill set, even their personality. They'll want to get to know you a bit and they'll want to learn much about your project, its scope, and your specific expectations before they agree to work with you. If you find that they immediately suggest you work with them and start talking about sending you a contract, you're probably talking to the wrong agency. Hang up the phone.

I know that I am guilty of such behavior. In the past, I have quickly jumped at any opportunity to make some extra cash as a freelancer. It usually doesn't take a long time before I begin regretting my hasty acceptance of a job. This is extremely sound advice.

If anyone other than the designer who did the work presents the designs to you, something's amiss and there is likely more yet to go astray. It is an unfortunate habit among some agencies to ever get between the client and the designer. This is a terrible mistake and a clear sign that the agency, large or small, is not well run. As a result, the work produced by the agency is likely to be flawed for the voids in understanding and effectiveness that result. In short, if your project's design phase does not begin and end with direct contact between yourself and the designer, you're getting short shrift. Find another agency.

I'd like to twist this one around a little. I completely agree with what Andy has said here, but I have also been on the receiving end of this particular type of situation. On one recent project, I was receiving instructions from a person who apparently didn't have the same goals as the "real" client. The end result was a product the "real" client didn't really want. Working directly with the client/agency is critical to a successful project.

There are several other important points in Andy's article, and I wholeheartedly recommend that you read it if you find yourself in such a situation. It will only help. In conclusion, I just want to share another quote from Andy's article:

And if you do notice too many of these telltale signs of incompetence in your current agency — don't walk; run.

Project Release: django-tracking 0.1

I'm proud to announce the official release of yet another one of my side projects. I call it django-tracking, and it is a simple project capable of telling you how many users are currently on your site. If you look at the bottom of any page on codekoala.com, you will see a demonstration of what this project can be used for.

django-tracking also offers basic blacklisting capabilities. I had a chap who apparently setup a script to spam my blog with rubbish comments every 11 minutes recently. I devised a way to stop the comments from being posted, but I noticed from my logs that the script was still hitting my website consistently over the following days. As a result, I implemented the "Banned IP" feature in django-tracking, and any visitor (or script) accessing my site from that IP address receives an error page. Yay!

If you have "Big Brother"-like tendencies when it comes to your visitors, there is also a way for you to have a "live feed" of active users on your site. Works pretty well, if I do say so myself :)

For more information, hop on over to django-tracking's homepage. There you will also find installation instructions and details for configuration and usage.

Have fun!

Using Django to Design Your Database Schema

Last night I had a buddy of mine ask me how I would approach a particular database design problem. I get similar questions quite often from my peers--suggests there is something important lacking from the database classes out there. Instead of answering him directly, I decided to come up with this tutorial for using Django to design your database schema.

For those of you new to Django, this article might seem a bit advanced. In time I will have more introductory-level Django tutorials, but I hope this one is easy enough.

Create a Django Project

The first step is to create a Django project. If you already have a project that you can play with, you can skip this step. To create a project, go to a place where you want to keep your code (like C:\projects or /home/me/projects) in a command prompt/terminal and run the following command:

django-admin.py startproject myproject

This will create a new directory in your current location called myproject (you can replace myproject with whatever you'd like so long as you're consistent). This new directory will contain a few files:

  • __init__.py
  • manage.py
  • settings.py
  • urls.py

If you get an error message when running the above command, you might not have Django installed properly. See Step-by-Step: Installing Django for details on installing Django.

Create An Application

Once you have a Django project setup, you should create a new application.

Note: If you're using Windows, you will probably need to omit the ./ on the ./manage.py commands. I will include them here for everyone else who's using Linux or a Mac.

cd myproject
./manage.py startapp specialapp

This will create a new directory in your myproject directory. This new directory will contain three files: __init__.py, models.py, and views.py. We are only concerned with the models.py file in this article.

Create Your Models

Models are usually a direct representation of what your database will be. Django makes creating these models extremely easy, and Python's syntax makes them quite readable. The Django framework asks for models to be defined in the models.py file that was created in the last step. Here's an example (for my buddy who prompted the creation of this article):

from django.db import models

class Component(models.Model):
    item_number = models.CharField(max_length=20)
    name = models.CharField(max_length=50)
    size = models.CharField(max_length=10)
    quantity = models.IntegerField(default=1)
    price = models.DecimalField(max_digits=8, decimal_places=2)

class Project(models.Model):
    name = models.CharField(max_length=50)
    components = models.ManyToManyField(Component)
    instructions = models.TextField()

(for more information about models, see the Django Model API Reference)

I don't know about you, but that code seems pretty straightforward to me. I'll spare you all the details about what's going on (that can be a future article).

Install Your New Application

Once you have your models setup, we need to add our specialapp to our list of INSTALLED_APPS in order for Django to register these models. To do that, open up settings.py in your myproject directory, go to the bottom of the file, until you see something like

1
2
3
4
5
6
INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
)

When you find that, add your specialapp to the list

1
2
3
4
5
6
7
INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'specialapp'
)

Setup Your Database

Now you need to let Django know what kind of database you're using. Django currently supports MySQL, SQLite3, PostgreSQL, and Oracle natively, but you can get third-party tools that allow you to use other database (like SQL Server).

Still in your settings.py, go to the top until you see DATABASE_ENGINE and DATABASE_NAME. Set that to whatever type of database you are using:

DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = 'myproject.db'

Save your settings.py and go back to your command prompt/terminal.

Get Django's Opinion For Your Schema

Make sure you're in your myproject directory and run the following command:

./manage.py sqlall specialapp

This command will examine the models that we created previously and will generate the appropriate SQL to create the tables for your particular database. For SQLite, we get something like this for output:

BEGIN;
CREATE TABLE "specialapp_component" (
      "id" integer NOT NULL PRIMARY KEY,
      "item_number" varchar(20) NOT NULL,
      "name" varchar(50) NOT NULL,
      "size" varchar(10) NOT NULL,
      "quantity" integer NOT NULL,
      "price" decimal NOT NULL
)
;
CREATE TABLE "specialapp_project" (
      "id" integer NOT NULL PRIMARY KEY,
      "name" varchar(50) NOT NULL,
      "instructions" text NOT NULL
)
;
CREATE TABLE "specialapp_project_components" (
      "id" integer NOT NULL PRIMARY KEY,
      "project_id" integer NOT NULL REFERENCES "specialapp_project" ("id"),
      "component_id" integer NOT NULL REFERENCES "specialapp_component" ("id"),
      UNIQUE ("project_id", "component_id")
)
;
COMMIT;

Notice how Django does all sorts of nifty things, like wrapping the table creation queries in a transaction, setting up indexes, unique keys, and defining relationships between tables. The output also offers a solution to the original problem my buddy had: an intermediate table that just keeps track of relationships between projects and components (the specialapp_project_components table).

Notice that the SQL above may not work with database servers other than SQLite.

Enhancing The Intermediate Table

After my buddy reviewed this article, he asked a very interesting and valid question: What if a project needs 3 of one component? In response, I offer the following models (this requires a modern version of Django--it doesn't work on Django 0.96.1 or earlier):

from django.db import models

class Component(models.Model):
    item_number = models.CharField(max_length=20)
    name = models.CharField(max_length=50)
    size = models.CharField(max_length=10)
    quantity = models.IntegerField(default=1)
    price = models.DecimalField(max_digits=8, decimal_places=2)

class Project(models.Model):
    name = models.CharField(max_length=50)
    components = models.ManyToManyField(Component, through='ProjectComponent')
    instructions = models.TextField()

class ProjectComponent(models.Model):
    project = models.ForeignKey(Project)
    component = models.ForeignKey(Component)
    quantity = models.PositiveIntegerField()

    class Meta:
        unique_together = ['project', 'component']

Running ./manage.py sqlall specialapp now generates the following SQL:

BEGIN;
CREATE TABLE "specialapp_component" (
    "id" integer NOT NULL PRIMARY KEY,
    "item_number" varchar(20) NOT NULL,
    "name" varchar(50) NOT NULL,
    "size" varchar(10) NOT NULL,
    "quantity" integer NOT NULL,
    "price" decimal NOT NULL
)
;
CREATE TABLE "specialapp_project" (
    "id" integer NOT NULL PRIMARY KEY,
    "name" varchar(50) NOT NULL,
    "instructions" text NOT NULL
)
;
CREATE TABLE "specialapp_projectcomponent" (
    "id" integer NOT NULL PRIMARY KEY,
    "project_id" integer NOT NULL REFERENCES "specialapp_project" ("id"),
    "component_id" integer NOT NULL REFERENCES "specialapp_component" ("id"),
    "quantity" integer unsigned NOT NULL,
    UNIQUE ("project_id", "component_id")
)
;
CREATE INDEX "specialapp_projectcomponent_project_id" ON "specialapp_projectcomponent" ("project_id");
CREATE INDEX "specialapp_projectcomponent_component_id" ON "specialapp_projectcomponent" ("component_id");
COMMIT;

As you can see, most of the SQL is the same. The main difference is that the specialapp_project_components table has become specialapp_projectcomponent and it now has a quantity column. This can be used to keep track of the quantity of each component that a project requires. You can add however many fields you want to this new intermediate table's model.

Using This SQL

There are several ways you can use the SQL generated by Django. If you want to make your life really easy, you can have Django create the tables for you directly. Assuming that you have specified all of the appropriate database information in your settings.py file, you can simply run the following command:

./manage.py syncdb

This will execute the queries generated earlier directly on your database, creating the tables (if they don't already exist). Please note that this command currently will not update your schema if the table exists but is missing a column or two. You must either do that manually or drop the table in question and then execute the syncdb command.

Another option, if you want to keep your DDL(Data Definition Language) in a separate script (maybe if you want to keep it in some sort of version control) is something like:

./manage.py sqlall specialapp > specialapp-ddl-080813.sql

This just puts the output of the sqlall command into a file called specialapp-ddl-080813.sql for later use.

Benefits of Using Django To Create Your Schema

  • Simple: I personally find the syntax of Django models to be very simple and direct. There is a comprehensive API that explains and demonstrates what Django models are capable of.
  • Fast: Being that the syntax is so simple, I find that it makes designing and defining your schema much faster than trying to do it with raw SQL or using a database administration GUI.
  • Understandable: Looking at the model code in Django is not nearly as intimidating as similar solutions in other frameworks (think about Java Persistence API models).
  • Intelligent: Using the same model code, Django can generate proper Data Definition Language SQL for several popular database servers. It handles indexes, keys, relationships, transactions, etc. and can tell the difference between server types.

Downfalls of Using Django To Create Your Schema

  • The Table Prefix: Notice how all of the tables in the SQL above were prefixed with specialapp_. That's Django's safe way of making sure models from different applications in the same Django project do not interfere with each other. However, if you don't plan on using Django for your end project, the prefix could be a major annoyance. There are a couple solutions:
    • A simple "search and replace" before executing the SQL in your database
    • Define the db_table option in your models
  • Another Technology: Django (or even Python) may or may not be in your organization's current development stack. If it's not, using the methods described in this article would just become one more thing to support.

Other Thoughts

I first thought about doing the things mentioned in this application when I was working on a personal Java application. I like to use JPA when developing database-backed applications in Java because it abstracts away a lot of the database operations. However, I don't like coming up with the model classes directly, so I usually reverse engineer them from existing database tables.

Before thinking about the things discussed in this article, I created the tables by hand, making several modifications to the schema before I was satisfied with my JPA models. This proved to be quite bothersome and time-consuming.

After using Django to develop my tables, the JPA models turned out to be a lot more reliable, and they were usually designed properly from the get-go. I haven't created tables manually ever since.

If you find yourself designing database schemas often, and you find that you have to make several changes to your tables before you/the project requirements are satisfied, you might consider using Django to do the grunt work. It's worked for me, and I'm sure it will work for you too.

Good luck!

Sad Day for Religious Nerds

I recently decided it would be prudent for me to request permission from the Church of Jesus Christ of Latter-day Saints to redistribute a copy of the scriptures with the PyScriptures program that I have been working on recently. I didn't want to be held liable for any copyright infringement or other legal violations. So I decided to contact them a couple of weeks ago. Here is my message requesting permission:

To whom it may concern:

I would like to request permission to redistribute and use a database which contains the LDS standard works (scriptures only, not the bible dictionary, topical guide, or even footnotes). One of my personal projects relies upon a local copy of the scriptures in order to be useful at all, and I would like people to be able to use this program without fear of any sort of copyright infringement charges to any party. The goal of the program is to offer users of platforms other than Microsoft Windows a way to peruse and study the scriptures without requiring an Internet connection. I have tested it on Windows XP, Linux, and MacOS X and it works great. There are still some parts that need some work, and things could probably be optimized a bit, but works well enough considering that I've only been working on it for about a week and a half.

To learn more about this project, please go to http://code.google.com/p/pyscriptures/ where you can even browse the Python source code for my application (though you might want to do so on an empty stomach). The database is called 'scriptures.db' (http://code.google.com/p/pyscriptures/source/browse/trunk/pyscriptures/scriptures.db) and was created using SQLite in case you are interested in examining and verifying its contents. One of my main reasons for creating this database is that I noticed the database that The Mormon Documentation Project offers is missing some things, particularly all of the answers in Section 77 of the Doctrine and Covenants. I didn't want to find out what else was missing or modified. Perhaps the reason those answers are missing is because that's part of the conditions of redistributing the scriptures?

Please notify me as soon as possible if there are any objections to the use and redistribution of this database. If that is the case, I will delete this project immediately. However, if I may be granted permission to redistribute the database containing the unmodified scriptures, I would greatly appreciate a response which states what my rights are in this matter.

Thank you for your time! Have a wonderful day.

Sincerely,

Josh VanderLinden

Developer

I got my reply today:

Dear Josh VanderLinden:

Thank you for your email dated 9 June 2008 requesting permission to use a database containing the LDS Standard works to redistribute.

After reviewing your request we have determined that we must deny your request for the use of this material. Church policy does not allow its intellectual properties to be used as you are requesting.

We appreciate your intentions, but trust you will understand and support the decision of the Church in this matter.

Thank you for checking with us.

Bobbie Reynolds, Paralegal

Intellectual Property Office

Somehow I could see this coming. I was curious, however, to determine if there was a way I could avoid litigation by modifying the way the program operates. So I responded with this message:

Hello Bobbie,

Thank you for your reply. I'm sorry that the verdict was not in my favor, but I do understand completely. Otherwise, I wouldn't have asked in the first place. Before I remove the project from the Internet, I would like to ask one more question. Is there a way I could somehow make the program legal? I've noticed that other some programs for the scriptures don't exactly redistribute the scriptures with the program itself. Instead they seem to download the scriptures from scriptures.lds.org (or elsewhere?) on an individual level, and the individual who runs the program has to specifically tell the program to do so. Would that be a more appropriate route for my project to take? Or would that also violate the rules?

Thanks again,

Josh VanderLinden

After only a few hours, I received the following reply:

If I understand you correctly, this also sounds like a reformatting project, which is restricted. Thank you for requesting further clarification and for your compliance to Church policy.

Bobbie

So it looks like I will have to discontinue this project, or at least not allow other people to use my work and keep it all to myself. In compliance with the message communicated to me by the legal representatives of the Church, I have removed the project from Google Code, and it shall remain a project for my own purposes. My apologies go out to everyone who actually found this program useful and promising. I can't blame the Church for being strict in its policies--neither should you.

Windows XP: command != cmd

So I was trying to help one of my good friends get started with Django today. He managed to get Python and the development version of Django installed, but once he tried to actually start working on a project he ran into some strange problems. In the command prompt, he changed to the directory where he wanted to create his Django projects and tried to run the appropriate command to actually create one. It came back telling him it was and invalid command and all that. We checked the paths and whatnot, and everything seemed perfectly fine.

After a little bit of further tinkering, we agreed to let me use LogMeIn to try to figure out what the problem was. When I got into his computer, he had his command prompt open. Everything was a bit fishy--no tab-completion, 8-character file and directory names, all upper-case names, etc. At first I just assumed that he was using an older version of Windows XP. I was personally not aware that XP shipped with such outdated capabilities, so it was a big surprise for me.

Eventually, I decided to open another command prompt, and I noticed that the file names were all long and properly-cased. Tab completion also worked. Turns out that my buddy opened the command prompt using Start > Run: command.com, while I used cmd.exe. Strange that the legacy command prompt is still included in XP.

So if anyone else runs into similar problems, check which method you're using to open the command prompt.

Finally!

So this semester is finally over and done with. I only have two more courses to take before I am done with my major, but I still have quite a few classes before I complete my minor (I chose one very late). I will still be in school for another year or so.

This has been a particularly frustrating and busy semester for me, so I think it will be nice to only take one class over the summer and work/play the rest of the time. I have a lot of really fun projects that I want to work on this summer, so hopefully my site will be a bit more active that it has been for the past month. We'll see how that goes.

How to Upgrade a NetBeans Project to JDK 6

NOTE: I am currently using NetBeans 5.5.

Here are the simple steps:

  1. Download and install JDK 6 if you haven't already
  2. Add the JDK 6 platform to NetBeans
    1. Tools > Java Platform Manager
    2. Add Platform
    3. Navigate to JDK 6's installation root directory. It will probably have a fancy overlay icon over it.
    4. Click Next
    5. Give the platform a name and continue onward
  3. Open a project in NetBeans
  4. Right-click on the project and open its properties
  5. Open the Libraries item on the left
  6. Change the Java Platform to your new 1.6
  7. Open the Sources item on the left
  8. Change the source level at the bottom to 1.6
  9. Enjoy!

There really are quite a few nice features in this release. So far I've found time to play with the built-in JTable sorting methods and the system tray icon stuff. It's so much easier than it used to be!!

Installing SuSE Linux Enterprise Desktop 10

This will be the second time for me putting SLED 10 on my laptop, but I've also put SLES 10, SuSE Linux 10.1, and various others on this laptop several times before. It _has_ been a few months since I last installed Linux on this laptop, so we'll see how well I remember how to do it. I will be installing the 64-bit DVD version, so as to take better advantage of the 64-bit capabilities of my processor. This shouldn't have a drastic effect on the overall procedure, compared to that of installing the 32-bit CD/DVD version.

Here are some specs of my laptop:

  • Make/Model: HP Pavilion dv8000
  • CPU: AMD Turion 64 ML-40 (2.2Ghz)
  • RAM: 1.25GB PC2700 DDR333 SODIMM
  • HDD: 5400RPM 80GB
  • Video: ATI Radeon Xpress 200M (128MB dedicated RAM, up to an additional 128MB shared RAM)

Note: I make a few assumptions in the writing of this article. One is that you are on a machine running Windows XP. If your computer can't handle Windows XP, you probably don't want to be running SLED 10. Another assumption is that you don't yet have your hard drive partitioned into more than one partition. I also assume that you already have the installation media in good working condition. For those of you in the BYU-I Linux Users Group (LUG), I am willing to make copies of the discs if you provide the media or discuss some sort of compensation if you want me to provide the media.

BACKUP ALL IMPORTANT DATA BEFORE PROCEEDING

We all hate losing the projects that we've slaved over for weeks and months. Take the proper precautions to backup anything you wouldn't like to lose before installing any flavor of Linux. That's not to say that you will lose everything, but it's not unheard of to wipe out all data from your drive while attempting to install Linux. With that warning out of the way, let's get started!!!

Defragment Your Hard Drive

If you have a secondary drive which you plan to dedicate to Linux, this step is not necessary. However, if you plan to install Linux on the same drive as your Windows installation, I would suggest defragmenting your drive prior to repartitioning your drive. In order to defragment your hard drive in Windows XP, open your Start menu and open the Control Panel. Once here, descend into Administrative Tools and run Computer Management. This utility is quite handy. On the left side of the Computer Management window, you should see a tree of options. Under Storage you will see the Disk Defragmenter. Simply click the Defragment button, and the program will begin optimizing your files. Defragmenting your hard drive basically puts each of your files into one piece instead of scattered across the drive (as they tend to be written). Defragmentation is a good process to run on a regular basis. Once again, this step is not necessary to the installation of Linux, but it is a good practice.

Begin The Installation

Once you're done backing up your files and defragmenting your hard drive, insert the first SuSE Linux Enterprise Desktop 10 CD/DVD into your CD/DVD drive and reboot your computer. You should be presented with a fancy blue welcome screen, but if you see the Windows boot screen, you'll have to change the settings in your BIOS to enable you to boot from your CD/DVD drive. That process will vary from machine to machine, so I won't even try to explain how to do it. Once you see the welcome screen, you are presented with several boot options:

  • Boot from Hard Disk
  • Installation
  • Installation--ACPI Disabled
  • Installation--Local APIC Disabled
  • Installation--Safe Settings
  • Rescue System
  • Memory Test

We're going to go with the first Installation option. In my experience, starting with SuSE Linux 10.1, I haven't had any issues at all getting Linux installed. Most people shouldn't have problems booting into the installation program, but if you do, try the other Installation options. Once we begin the installation process, the bootloader will load the Linux kernel into memory and begin booting the SuSE Linux Enterprise Desktop installation utility. It will probe several devices to make the installation usable, after which you are presented with a language selection menu. Choose the language of your preference. Next you will be asked to accept the License Agreement, which I would recommend reading (with any product, not just SLED). If you accept, check the "Yes, I Agree to the License Agreement" option box and hit "Next." If you don't accept the agreement, this is the end of the road--your installation process will end.

Once we accept the License Agreement, a few more devices are probed and we're asked what kind of installation we'll be doing. With the assumptions I've made for this tutorial, we will proceed with a New Installation. If you have the "extras" CD, you can check the "Include Add-On Products from Separate Media" checkbox. You'll then be asked to insert the disc so that a catalog of available applications can be made. However, I'll assume that we all just have the required media. Click "Next" to create a catalog of the software available.

Now we're presented with a Clock and Time Zone screen. Choose the appropriate options for your situation and click next.

Installation Settings

Once we have set our clock and time zone, we are shown an overview of the current installation settings. I personally prefer to see all of the details, so I am going to click on the Expert tab. I don't like the predefined partitioning scheme, so I am going to change that.

Partition Your Drive

Partitioning a hard drive basically allows you to split up that brand new 500GB SATA-II drive you bought into smaller "virtual hard drives." I like to partition my hard drive because it allows me to manage my files easier, and I don't have to worry about losing ALL of my data if one of the partitions needs to be reformatted. Each partition can have a different file system on it, which allows us to run a Windows file system (NTFS) and a linux file system (ext2/3 and reiserfs are the two main ones, at least for workstations) on the same physical hard drive.

This is the first time I will entrust all of the data on my hard drive to a Linux installation partitioning utility in a very long time. We're talking about 7 years... However, for the sake of others, I am willing to put it to the test to see if SuSE will not wipe my drive when I try to resize the Windows partition. I usually use a utility such as Partition Magic to resize and create new partitions.

To change my partitioning scheme, I click on the "Partitioning" subtitle on the Expert tab in the Installation Settings section. I want to base my partition setup on the default proposal, so I select the second option "Base Partition Setup on This Proposal" and hit next. This part could be a bit hairy if you've never partitioned a drive before. I want to be able to share files between Windows and Linux, so I am going to create a small ~20GB partition which I will format to be FAT32, a format readable and writable in both Windows and Linux.

First, I must resize my Linux partitions. I don't need my home partition to be 22GB, so I'm going to resize that one to be 5GB. To do that, I select the partition with /home listed as it's Mount point and click the "Resize" button at the bottom of the screen. The window that appears shows a graphical representation of the changes we make. All I need do is enter "5" into the "Space Free (GB)" box or move the slider to the right spot and click "OK". Now I'm left with 17GB to share between Windows and Linux. To create this new partition, I click on the "Create" button at the bottom.

The new partition window asks me what type of format I wish to have on the new partition--I want to select FAT. I want to have this partition listed in a place that makes sense to me, so I'm going to change the "Mount Point" field to /windows/share and click OK. I think I'm now satisfied with the partitioning scheme, so I click "Finish" to return back to the Installation Settings screen.

Partitioning Pointers

Let me share some pointers for partitioning schemes. Traditional Linux installations would ask for a partition twice as big as the amount of RAM you have in your machine. This is for the swap, which is synonymous with virtual memory in Windows lingo. That means that if you have 512MB of RAM, your swap partition should be at least 1024MB (1GB). Likewise, if you have 1GB of RAM, your swap partition should be at least 2048MB (2GB). In my opinion, the average Linux desktop does not require more than 512MB for a swap partition. I may be mistaken, but I think the "double your RAM" rule became somewhat obsolete for desktop workstations with the advent of 2Ghz+ processors with 1GB+ of RAM. It could just be me, but I've never even filled 256MB of swap. Just something to consider while partitioning your drive.

If you plan on experimenting with several distros of Linux without wiping other installations of Linux, I would recommend a partition dedicated to your /home folder. This way, you are able to keep your personal settings across most if not all distros. I've found it useful on countless occasions.

Software Selection

One thing I really like about SLED is the ease of package selection. Their default package selection will suit most people just fine. However, I have developed my own tastes for how I like my Linux, so I am going to customize the package selection a bit. To do that, I click on the "Software" heading in the Expert tab of Installation Settings.

I personally prefer KDE to GNOME as my window manager. So I am going to deselect GNOME from the Desktops category, but not so the "Do Not Enter" symbol shows up where there once was a check. I want to click the checkbox until I see a white box (no checkmark). I'm not sure if this is required, but usually different environments will require libraries from other environments in order for certain programs to run. I suspect that the Do Not Enter sign means that nothing for GNOME will be installed, but this is not fact--it's simply a notion of mine. Now I want to put a check in the checkbox next to KDE. Being a nerd, I want to have my compilers around, so I will also select that option.

According to the disk usage graphs in the bottom right of the screen, I'm only going to be installing about 1.9GB of software. That's interesting because I downloaded a whole DVD... If anyone wants to see what other software is available, you can click the Details button below the software category list. This might scare a few off, but it's all quite simple. If you want to see more categories to choose from, select "Package Groups" from the Filter list in the top left. This is where you can explore all of your software options available on your installation media. I am going to leave that sort of customization until after I'm all installed and running.

Once you're done selecting the packages you wish to have installed, click Accept from the bottom right. You will probably encounter a few more license agreements at this point. These are for non-open-source applications (Adobe Acrobat Reader, Macromedia Flash plug-in, etc) included with SLED. I recommend reading and accepting each license agreement. Now I am presented with the same Expert tab in the Installation Settings stage. Now we're ready to proceed, so click Accept in the bottom right again. We're asked to confirm that we want to install Linux, with a warning that certain parts of your hard drive will be formatted, thus erasing any data that were there before. If you're ready, click Install, sit back, and enjoy.

Installing Everything

At this point your partitions will be resized/formatted and the appropriate files will be installed. This process can take anywhere from 20 minutes to 2 hours or more, depending on the packages you selected and the speed of your system. You might be interested in seeing what exactly is being installed on your system at this point. If so, you can click the Details tab and see each package being installed. Apparently I chose some other packages along the way or something, because now it says that I'm installing about 2.5GB of software and that this segment should take about 30 minutes.

Once all of the files are copied, the installation settings will be saved to the hard drive and your system will reboot for the first time in your brand new SLED. At this point, you shouldn't remove your installation media, as it is required in the following steps.

The Initial Boot And Final Settings

When we boot up our SLED for the first time after installation, we are asked to provide a hostname to identify our machine on the network. When you have set the hostname and domain name as you want them, click next. Now we're asked to set the root password. Make sure this password is one that you'll not forget, but at the same time make sure that it's not easy to guess. If someone gets root access to your machine, there's no end to what they can do.

Network Configuration

This is another section that is mostly correct, but a few settings are not the way I would like them to be. For example, my ssh port is listed as disabled under the Firewall heading. To enable it, just click the word "blocked"--it will change to "open". The rest of the settings look fine for now. If you have any customizations to be made, go ahead and make them. I'll wait.

When we're ready to move on, click next. At this point, our network configuration is saved. Next we're asked if we wish to try out our Internet connection. Do as you please. I usually skip this step, but for your sake, I will try out my connection. When we test, it tries to download the latest changelogs. If your connection works, you will see "Success" in the Result field. Click next.

User Authentication Method

Most home users won't have their own LDAP server or Windows Domain setup, so I won't go into how these are to be set up. Let's just go with Local authentication for now, the default option. Click next.

New Local User

This is when we create our very own user account. This set is essential. DO NOT EVER RUN EVERYDAY APPLICATIONS AS ROOT. There are serious security implications involved if you choose to login and perform your daily tasks as the root, or all-powerful administrator, user in Linux. It's much easier to just create an "unprivileged" user and do your regular business with that account. Only login as root when you need to perform system maintenance or install something. When you're done with those tasks, logout of the root environment immediately. Trust me.

Anyway, back to our installation. Go ahead and create your user. You may or may not want to check the checkbox to receive system mail. System mail includes certain security breaches on most distributions. If you don't wish to have to enter your password in order to use your computer, click the automatic login checkbox. If you wish to add more than one user at this time, you can click on the User Management button. The process is pretty much the same as it is to add the first unprivileged user. Click next when you're ready to proceed.

Now our system configuration is saved again (this seems to happen all the time in SuSE... it gets rather annoying in my opinion). After our settings are saved, we are presented with the release notes (which may have been more useful had they been displayed during the file copy process, but whatever). Read them if you wish. Click next when you're ready to proceed.

Hardware Configuration

Now this is one of the selling points for me with SuSE. I have a 17" widescreen (1680x1050 max resolution) for my laptop. There weren't many distros for a while that could handle the resolution out of the box. Fedora Core 5 was the first that I tried that handled it without any manual configuration, and SuSE was the second. I'm pretty happy with the configuration listed here, so click next when you are too. Once again, the settings will be saved (seems like saving settings in SuSE is as bad as rebooting in Windows...).

If you have several similar machines, you can save your installation configuration by checking the "Clone This System for Autoyast" checkbox. If you choose this, the system will determine what settings exactly were used for installation and create a file somewhere that you can use in later installations. When this is done, or when you click finish if you don't want to clone, a login screen will appear.

First Login

When you see this login screen, enter the username and password that you created for the unprivileged user. You'll see a fancy loading screen while your profile is being created for the first time.

Now, you may or may not have noticed, but I wrote this article as I installed SLED. I want to watch a movie now, so subsequent configuration (wireless, 3D acceleration, etc) will take place later. I hope this is good enough for the time being.