Project Release: django-pendulum 0.1

For those of us who like to know how much time we spend on various projects, I've released a little project to help you out. Pendulum is a small Django application that I've been using to keep track of the time I work on my various personal projects. It's very easy to use, and it's been working great for me for several months.

This weekend I took the time to make several improvements that I deemed necessary before I could make the project publicly accessible. While I've done some testing on my own, I'm fairly certain that I haven't tried all combinations of situations, so there might be some problems that you find as you use it.

To learn more, head on over to http://code.google.com/p/django-pendulum/. There you can learn how to download and install it and what you need to do to configure it.

Enjoy!

django-clevercss v0.1

Today I launched another little side project. I call it django-clevercss. Really it's just a simple way to use CleverCSS-formatted stylesheets in Django sites.

At first glance, CleverCSS might not seem like the most useful thing ever, but I personally think it has potential. It is a more concise way to write CSS, and it also allows the use of variables (so you don't have to change 50 of the same hex color codes each time someone wants something a different shade of blue) and simple calculations within the stylesheet. You can also have a sort of "hierarchy" of elements so you don't have to repeat the same element name 30 times for simple styling.

Anyway, since I thought CleverCSS was so clever, I decided that I would make an effort to make the project more accessible for Django developers who agree with me.

This project gives you a way to create CleverCSS stylesheets in your database using the Django administration utility. Then you use a simple template tag to bring the CSS file into your Django templates. Put something like {% get_clever_css "Testing" %} in the href of a regular link tag and that's about it!

Assuming that you have a CleverCSS stylesheet in your database with the title "Testing", the project will do several things. First, it will see if the stylesheet has been parsed and saved to the filesystem. If it has, it will compare the last time the stylesheet on the filesystem was modified with the last modification time of the stylesheet in the database. If the stylesheet in the database is newer than the one on the filesystem, or the stylesheet has not yet been saved to the filesystem, the project will parse the CleverCSS into real, valid CSS and store it in a file on the filesystem. Then you end up with something like this in your template after Django is done with it:

<link rel="stylesheet" type="text/css" media="all" href="/media/clevercss/testing.css" />

For more information and installation instructions, check out the project homepage. Have fun!

Code Koala is now on Django 1.0 Alpha

For the last little while I've been working toward upgrading all of my sites to work with the newforms-admin changes that have been merged into Django's trunk in an effort to release Django 1.0 in a few weeks. However, one of my sites, QuoteBoards.org, was throwing a fit for one reason or another. The fit was enough to stop me from upgrading immediately.

However, I recently got QuoteBoards to a point where I feel it is stable enough on the newforms-admin. I just finished updating everything on my server to Django 1.0 Alpha, and I'm very excited to see what else makes it into the 1.0 final release. If you notice any problems with my site(s), please let me know!

Another Semester Gone

This summer semester, I took a single class--managerial accounting. It was a good class, and I learned a lot, but it took a lot of time. When I began reviewing everything for the final exam, I was surprised at how much I had _forgotten_ over the course of the semester. The more I studied, the more nervous I became.

Anyway, at some point this morning I decided I was comfortable with my understanding of the course material and decided to stop studying. Not too long after that I found myself in the testing center staring blankly at the exam questions. Most of the questions were relatively familiar, but all of the recent studying just confused me so I wasn't sure if I was doing anything right.

It took me just over an hour to finish less than 50 questions, but by that time I had had enough and just wanted to get out. Usually I will spend a few minutes reviewing my answers to the questions, but not this time. I just stood up, stuffed my pencil into my pocket, cleared my desk, and turned in the exam.

I looked at the monitor just outside the testing center, both excited and dreadful of learning how I had performed. I have to say that I'm quite satisfied with my score--89%. I can't ask for much more than that!!

After I finished that, Mindy and I drove straight over to the "black market" of university bookstores--you know, the little car at the end of the parking lots with big signs that say, "WE BUY TEXTBOOKS" in big print. Yeah, those guys. Anyway, Mindy and I decided that we wouldn't be using any of our textbooks from this semester (and several from previous semesters) ever again, so we decided to get some money back. We brought in $81 off of 9 textbooks! Not too bad considering that we probably wouldn't get that much from the university bookstore if they would accept our books back in the first place.

And now I'm free. Relatively.

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!

Linux Basics

Filesystem

  • /bin - This is where basic Linux commands reside (ls, du, dd, cp, etc).
  • /boot - Your boot images are stored here.
  • /dev - Links to access your machine's devices.
  • /etc - Configuration files and boot scripts.
  • /home - User directories, equivalent to "Documents and Settings" in Windows XP.
  • /lib - System libraries, codecs, etc.. similar to Windows/System and Windows/System32.
  • /mnt, /media - Mount points. A mount point is a directory that the contents of your hard drives, cd/dvd drives, floppy drives, or jump drives will be accessible.
  • /opt - Optional packages and programs. Could be thought of as a "Program Files" directory.
  • /proc - Special dynamic information about your system.
  • /root - System administrator home. Could be thought of as a "Documents and Settings/Administrator" directory.
  • /sbin - Super-user binaries. These programs need super-user (root) privileges to execute.
  • /tmp - Temporary files. Every user usually has read, write, and execute permissions here.
  • /usr - The main place for programs to be installed. Most like "Program Files" in Windows.
  • /var - System logs, mail spools, default web server directory, databases, etc...

Basic Commands

  • cd - Change Directory: moves to a different directory.

    Usage: cd directory, cd .., cd /directory

  • cp - CoPy: Copy a file or directory. If you wish to copy recursively and retain all attributes associated with the file or directory, use the -a option.

    Usage: cp original original.backup, cp -a /home/user/directory /home/user/backup

  • df - Disk usage on Filesystem: Display an overall summary of disk usage on mounted mountpoints. If you want human-readable sizes, use the -h option.

    Usage: df, df -h, df /mnt/mountpoint

  • du - Disk Usage: Display the disk usage of each file (recursively, by default) in the current directory. If you want human-readable sizes (1024 bytes = 1Kb, 1024Kb = 1Mb, etc), use the -h option. If you want a summary of the total disk usage by a directory and everything inside, use the -s option.

    Usage: du, du -s, du -h, du -sh, du -s /directory

  • ln - LiNk: Create a link, or shortcut, to a file or directory. I prefer to do symlinks by using the -s option.

    Usage: ln original link, ln original /directory, ln original /directory/link, ln -s original /directory/link

  • ls - LiSt: lists the contents of a directory.

    Usage: ls, ls .., ls /directory/subdirectory

  • man - View the MANual page for a program or other file. Probably the most useful program ever.

    Usage: man program, man xorg.conf

  • mkdir - MaKe DIRectory: create a new directory/folder.

    Usage: mkdir dirname, mkdir /directory/newdirname

  • mv - MoVe: Move a file or directory to a new location, or rename a file or directory.

    Usage: mv file /directory/newhome, mv file newfilename

  • pwd - Print Working Directory: returns the full path of the directory in which you are working.

    Usage: pwd

  • rm - ReMove: Remove a file or directory. If you want to get rid of a directory and all of its contents, use rm -R or rm -Rf for recursive deletion.

    Usage: rm filename, rm /directory/filename, rm -Rf /directory/dirname

  • rmdir - ReMove DIRectory: remove a directory. The directory must be empty.

    Usage: rmdir dirname, rmdir /directory/dirname

  • whereis - Determine where a certain file exists (if it's in your path)

    Usage: whereis filename

  • whoami - Detemine which user you are currently logged in as

    Usage: whoami

Linux Permissions

Linux has a great permission scheme. Since its inception, three basic levels of security have existed: user, group, and everyone. A simple way to change the permissions on a file or directory is to use the chmod, or CHange MODe, command. Changes to the permissions can be either a symbolic representation or an octal number representing the bit pattern for the new permissions. I prefer the symbolic method, myself, but many others prefer to see the octal pattern.

When working with permissions in Linux, always remember the following orders: User, Group, All; Read, Write, Execute. Those are the orders you will put the permissions in. Let's say that we want to make a file readable and writable only to the owner, while no one else will even be able to read the file. Here are some examples:

NOTE: Commands that begin with $ are executed as a regular user. Commands that begin with # are executed by a superuser (root). These two symbols (when they are the very first character in the command) are not entered by the user.

Symbolic:

$ echo "Hi" >> testing
$ chmod a-rwx,u+rw testing

Octal:

$ echo "Hi" >> testing
$ chmod 600 testing

Let's now examine the commands individually.

$ echo "Hi" >> testing

This command will append "Hi" (without the quotes) to the end of the file called testing. The file will be created if it does not already exist, assuming that the user has write permissions in the current directory. If you didn't want to append, you could overwrite anything that may be in the file by using a single > rather than >>.

$ chmod a-rwx,u+rw testing

This command removes (the - in a-rwx) read (the r in a-rwx), write (the w in a-rwx), and execute (the x in a-rwx) permissions from all (the a in a-rwx) users on the file called testing. Next we add (the + in u+rw) permissions for the owner (the u in u+rw) of the file: read (the r in u+rw) and write (the w in u+rw) on the file called testing.

$ chmod 600 testing

This command sets the permissions for everyone in one shot. I think of the digits in binary:

  • 1 = execute only;
  • 2 = write only;
  • 3 = write and execute, but no read;
  • 4 = read, but no write or execute;
  • 5 = read and execute, but no write;
  • 6 = read and write, but no execute;
  • 7 = read, write, and execute.

A digit is required for each level of permissions (user, group, and all). It is also possible to put another digit before the 3 levels of permissions, but to be honest, I don't know what significance it has. A little bit of testing has shown that it puts either an S or T in place of the execute permissions (depending on the digit).

A couple more things about chmod: Directories must also be executable in order to list the contents. chmod is very powerful. Finally, you can recursively apply permissions to directories and everything underneath with the -R option.

$ chmod -R a+rx /home/user/share

A couple of commands closely associated with chmod are chgrp (CHange GRouP) and chown (CHange OWNer).

chown will change the user ownership of files or directories. This can be done recursively with the -R option. It also has the capability to change the group ownership built into it. The syntax is: chown [options] user[:group] file1 [file...]

chgrp will change the group ownership of files or directories. You can do this recursively with the -R option. The syntax is: chgrp [options] groupname file1 [file...]

Cronjobs

Cronjobs are similar to scheduled tasks in the Windows world. Schedule tasks or cronjobs are simply programs that you want to run regularly, without having to type in the command every time you want it to run. Most distributions come with a cron daemon of some sort installed by default. Generally speaking, you can edit your cronjobs by typing crontab -e. This will bring up an editor like vi (it usually is vi by default) in which you edit your cronjob file. Each user can have their own cronjobs (unless it's been disabled by the administrator, I would assume). Here is an example of a cronjob entry:

47 * * * * /usr/bin/run-parts /etc/cron.hourly 1> /dev/null

You'll notice the 47 with four *'s after it. This is how the daemon knows when to execute a job. This is what each of the stars represent in their order:

  1. Minute: 0-59
  2. Hour: 0-23 (0 = midnight)
  3. Day of month: 1-31
  4. Month: 1-12
  5. Day of week: 0-6 (0 = Sunday)

So the example above will run after 47 minutes every hour of every day of the month of every month. You can also do some fancy things like having a job run every 5 minutes, after 15 and 45 minutes, etc. Let's say that we want to grab our mail every 5 minutes. The cronjob entry would look something like:

*/5 * * * * /usr/bin/fetchmail

If we wanted to grab our mail every 2 hours but only on Mondays, we would use the following:

0 */2 * * 1 /usr/bin/fetchmail

To have a job run after 15 and 45 minutes, we could do this:

15,45 * * * * /usr/bin/fetchmail

Pretty nifty, eh?

Make

This fancy utility is usually the means used for compiling programs from source. The usual sequence of commands for compiling and installing a program from the source in Linux is as follows:

$ ./configure
$ make
# make install

Most packages will follow this convention, but some require special procedures. Sometimes you can even get away with skipping the make and jump straight from ./configure to make install. It is always a good idea to read the README and INSTALL files included in source packages. They will generally tell you about anything out of the ordinary when compiling the source. Obviously, there is a lot more to this utility, but I'm not the person to explain it to you.

Package Management

There are several different types of package managers. The most popular these days are .rpm (RedHat Package Manager) and .deb (Debian). There are some other kinds of packages, but they aren't as popular as RPM and DEB. Slackware uses a straight .tgz (gzipped tarball) as its package system. Frugalware uses .fpm, which are bzipped tarballs. In the end, packages are almost always gzipped or bzipped tarballs.

Each package system has its ups and downs. I've personally found RPM-based distributions to be overly slow, especially with the package management. DEB-based distributions seem to be a lot more speedy when put up against RPM-based distros. However, I have found Slackware's TGZ-based system the most efficient and the fastest. Both RPM's and DEB's have dependency checking. In other words, the package manager will attempt to locate all entities upon which a program may depend in order to function properly before installing or upgrading that program.

A lot of people claim that .tgz packages are inferior to RPM and DEB because of the lack of dependency checking. By default, Slackware does not have dependency checking, but if you know what you're doing, you can get your dependencies a lot easier than you can with RPM or DEB (in my opinion).

RPM packages usually seem quite large compared to other package systems like DEB and TGZ. As far as I have seen, TGZ packages are smaller than both RPM and DEB packages. Here are a few options to help you use the RPM and TGZ package managers. I am not sure on Debian packages, so I won't attempt that one:

  • RPM:
    • rpm -q or rpm --query: look for a package on your system
    • rpm -i or rpm --install: install a new package on your system
    • rpm -U or rpm --upgrade: upgrade a package which is already installed on your system
    • rpm -e or rpm --erase: remove a package from your system
  • TGZ:
    • pkgtool: a text-based package manager
    • installpkg: install a package onto your system
    • upgradepkg: upgrade a package which is currently installed on your system
    • removepkg: remove a package from your system

You can also get some other programs that are VERY useful for package management. I think the latest craze for RPM's is YUM. I have not had great luck with this utility, but a lot of people really like it. Debian packages have used apt-get for ages now. My favorite add-on for Slackware packages is called swaret. Other distributions use the pacman utility, which is very efficient. Each one of these applications has several options and operation procedures.

Secure Shell and Secure Copy

One of my favorite aspects of Linux and other UNIX-derived systems is their secure shell capability (which is usually installed by default). Secure shell, or SSH, is a way for users to log into a remote computer and work on the remote computer as though it were right in front of them. Granted, it's all text-based unless you have X11 forwarding setup properly on both machines. But the command line interface (CLI) is extremely powerful--you should not be afraid to learn and use it. If you need to SSH from a Windows machine, you can use PuTTY.

In order to ssh into another computer, you simply type:

$ ssh hostname

or use the computer's IP address:

$ ssh xxx.xxx.xxx.xxx

By default, ssh on Linux machines will use the username of the account that you are running ssh from. Sometimes you need to login as a different user than the one you're currently using. To do that, you use the -l (lowercase L) or make it look like an e-mail address:

$ ssh hostname -l differentuser
$ ssh differentuser@hostname

Once your ssh session begins with the remote host, you will be asked to enter the password associated with the account with which you are attempting to login. If you do a lot of ssh'ing between machines, typing in your password several times is not only annoying but it could also pose a security risk--some wandering eyes might be watching you each time you enter your password. A great way to get around this is to generate a public and private key for your account. Once you do this, you can use the private key file on the machine you're ssh'ing out of and the public key on the remote machine.

To generate a public/private key, you can use ssh-keygen:

$ ssh-keygen -t rsa

You will be asked to enter and verify a passphrase for your private key. If you were aiming to get around not typing in your password, just hit enter twice for this part. It's still not secure, but it is a lot less hassle if you're only working on machines that no one else has "access" to. Usually your keys will be stored in ~/.ssh/ (or your /home/username/.ssh/ directory: ~ refers to your /home/yourusername).

The next step is to create your identification:

$ cd ~/.ssh
$ echo "IdKey private_key_file" > identification

Now you have to copy your public key (usually the one that ends in .pub) to the remote host:

$ scp public_key_file.pub username@xxx.xxx.xxx.xxx:/home/username/.ssh

And finally you should add your public key to the list of authorized users on the remote host by adding a line like the following to the ~/.ssh/authorization file:

Key public_key_file.pub

At this point you should be able to log into your remote host without your password (assuming you skipped the passphrase part of the key generation above).

As for the secure copy utility, you can get an idea of how to use it from the scp command above. This program uses the SSH system to securely copy files between two computers. This is how I use the scp command:

$ scp [-r] user@remote:/path/to/remote/file /local/destination/path/
$ scp [-r] /path/to/local/file user@remote:/remote/destination/path/

If you have setup public key authorization, you will not have to enter your password each time you use scp. Otherwise, you are asked for a password each time you run scp.

Archiving and Backup

There are many different kinds of compression and archiving tools in Linux. The most common types are tarballs, gzipped, and bzipped files. Below is a list of purposes for each of the three and some of the options:

  • tar - multiple files, little or no compression
    • c, --create - create a tarball
    • f, --file - specify the tarball's filename
    • x, --extract, --get - extract the contents of a tarball
    • j, --bzip2 - use bzip2 compression/decompression
    • v, --verbose - show verbose output
    • z, --gzip, --ungzip - use gzip compression/decompression
    • to create a tarball called filename.tar which contains all of the files in /dir/to/archive: $ tar cf filename.tar /dir/to/archive
    • to create a tarball called filename.tar.gz which contains all of the files in /dir/to/archive and gzip it: $ tar zcf filename.tar.gz /dir/to/archive
    • to create a tarball called filename.tar.bz2 which contains all of the files in /dir/to/archive and bzip it: $ tar jcf filename.tar.bz2 /dir/to/archive
    • to extract the contents of a tarball called filename.tar.gz to the current directory: $ tar zxf filename.tar.gz
    • to extract the contents of a tarball called filename.tar.bz2 to the current directory: $ tar jxf filename.tar.bz2
  • gzip - single file compression
    • To gzip a file called filename to make it filename.gz: $ gzip filename
    • To gunzip a file called filename.gz to make it filename: $ gunzip filename.gz
  • bzip2 - single file compression
    • To bzip a file called filename to make it filename.bz2: $ bzip2 filename
    • To bunzip a file called filename.bz2 to make it filename: $ bunzip2 filename.bz2