Restarting Apache with Python

It doesn't happen a lot but when it does it is frustrating. Since the server that runs this site is modest in every means I sometimes will check out how things are going and find out that the Apache2 web server has stopped running on the server. The last time this happened I did a quick search to see what others were doing to manage the problem. There were a few packages that will monitor the server for you and then restart it if needed but every one of them took a lot more work to manage and install than I really wanted to do. So I wrote a quick Python script that combined with cron do the job very nicely.

#!/usr/bin/env python

from os import system, path

pidFile = '/var/run/apache2.pid'
startCmd = 'apache2 -k start'

if not path.exists(pidFile):
    system(startCmd)

The basic idea is that most *nix services use a pid file to store the ID number of the process that was assigned to the service when the service was started. If the service is running then there will be a pid file for that service and no pid file if the service is not running.

To start out, test to see whether the pid file exists. It is located at /var/run/apache2.pid on my server. Your setup may vary so check your setup before proceeding. I also created a symlink to /usr/bin for Apache at /usr/bin/apache2 -> /etc/init.d/apache2 which allows me to type just 'Apache2' at the prompt instead of the entire path to Apache. If the pid file does not exist that means Apache isn't running so go ahead and send a start command to the server via 'apache2 –k start'

I saved this code as a file in my home directory and created a cron job to run the file once each minute.

Announcing Bracketizer.com

My new site is now officially up and running. Come check out how your team compares to the rest of Division 1. You can find it here Bracketizer.com

New features will also be released soon.

Valid XHTML 1.1 and JavaScript

When dynamically building HTML with inline JavaScript you HAVE to escape your JavaScript code with HTML comments in order to get it to validate as XHTML1.1 like the example below or else the HTML elements will cause the Validator to choke.

<script type="text/javascript">
<--
...
/* code goes here */
...
//-->
</script>

Modulo In Django Templates

Ever find yourself wishing for the modulo operator (%) in Django templates? I did. Its easy enough to create your own custom filter so why not do it?

Caveat: I couldn't figure out how to get the filter to accept two arguments to do the modulo test against so I defaulted the test value to zero. If there is a way to add a second argument I would love to add that to the code.

In the templatetags directory of your Django install, add a file named 'mod.py'. In that file add the following code:

from django import template
register = template.Library()

def mod(value, arg):
    if value % arg == 0:
        return True
    else:
        return False

register.filter('mod', mod)

In your template use the mod filter like this:

...
{% load mod %}
...
<tr bgcolor="{% if forloop.counter|mod:2 %}#cccccc{% else %}#ffffff">
...

This will alternate every other row's background color between gray and white.

JavaScript Number Formatting

I don't know why this function is not more well known or why it never comes up when I do a search for "javascript round method", but I have always had a terrible time coming up with a reliable floating-point rounding function for JavaScript that holds a definite number of places. Usually the search comes back with somebody's custom method for rounding to a specific number of digits that has flaws of some sort. The built-in toFixed() method fixes all of this. It is a built in method of all JavaScript Numeric types. For example:

Var myFloat = 0.12345;
Alert(myFloat.toFixed(4)); // displays 0.1235

myFloat = 1.23;
alert(myFloat.toFixed(4)); // displays 1.2300

DateFormat with Python

My early background in programming is in ColdFusion. Since I found python I do not really use ColdFusion for much any more but it is still one of my favorite languages. One of the features I missed most about ColdFusion is the DateFormat() built-in function. Python's default date formatting syntax is arcane in my opinion and very difficult to remember at best. I always find myself going back to the documentation to figure it out. Worry no more. Introducing ... DateFormat() for python based on the ColdFusion DateFormat() function. It is not a terribly unique name by any means but it takes all the guess work out of remembering how to format a date by using a string mask to show how you want the date to appear. The following values can be used in the mask:

  • d: Day of the month as digits; no leading zero for single-digit days.
  • dd: Day of the month as digits; leading zero for single-digit days.
  • ddd: Day of the week as a three-letter abbreviation.
  • dddd: Day of the week as its full name.
  • m: Month as digits; no leading zero for single-digit months.
  • mm: Month as digits; leading zero for single-digit months.
  • mmm: Month as a three-letter abbreviation.
  • mmmm: Month as its full name.
  • yy: Year as last two digits; leading zero for years less than 10.
  • yyyy: Year represented by four digits.

The following masks tell how to format the full date and cannot be combined with other masks:

  • short: equivalent to m/d/yy.
  • medium: equivalent to mmm d, yyyy.
  • long: equivalent to mmmm d, yyyy.
  • full: equivalent to dddd, mmmm d, yyyy.

Example usage is:

>>>import datetime
>>>today = datetime.datetime.today()
>>> DateFormat(today, 'mm-dd-yyyy')
'09-20-2007'
>>>DateFormat(today, 'ddd, mmm d, yyyy')
'Thu, Sep 20, 2007'
>>>DateFormat(today, 'm/d/yy')
'9/20/07'
>>>DateFormat(today, 'full')
'Thursday, September 20, 2007'

Download it here

Surplus Computer Auction

I went to the county government surplus computer auction last night. It was the first time I have been to an auction and I was surprised at just how much I enjoyed it. There was the guy who just kept giving “the nod” every time he bid. There was the classic head shake to tell the auctioneer no more. The auctioneer himself was a classic old guy with suspenders, white beard and rapid fire speaking. It took a few items to go before I felt comfortable with what was going on before I started bidding. It was amusing because I could see some people getting caught up in the excitement of the auction and bidding on prices that they shouldn't. Like when a computer identical to the one I paid $15 went for $45 dollars just a few minutes later. Weren't they paying attention?

Some people got some good deals, but I don't really know if they got “smoking deals”. Some of the newer computers (P4, 80GB HD, 512MB RAM) went for $120-$165. There were some P4, 40GB HD, 512MB RAM with the smaller form factor that I really had my eye on but they all went for about $40 each. I ended up with two P4 computers with 256MB RAM and monitors, two 8mm backup tape drives and a UPS battery backup for $35. Not too bad I think. I probably could have gotten them for even less if I had been thinking right. When I bid on the UPS I opened the bidding at $1, a guy immediately went to $5 so I raised my card to bid again and the auctioneer upped the bid to $10 when he saw me. He did the right thing and asked me if I was okay going to $10 and after thinking for about a second I said sure. I should have said no and gone to $6 instead but I still got a deal I think so I'm not upset. The same thing probably could have happened with the $15 computer I got. In retrospect, I probably should have since some of the older PIII's went for just $1. With two or three of those I could have cobbled together a pretty decent computer. One guy there bid on everything and I think he must have walked away with 20-30 computers and other miscellaneous items.

At the beginning the auctioneer told us that everything had to be sold so for example, if the item in lot number 1 didn't sell it would be combined with the item in lot number 2 and so on until there was a winning bid. Some people got some decent deals that way. That is actually how I ended up with the tape drives.

The next time they have the auction I am definitely going. It would have been worth it just to see the people. Some of the things I learned were, get in on the bidding early. You never know just when something will go for a song. At the same time, exercise a little patience. If you know what you want wait for that item so you don't end up going over your budget before you get to the items that you actually wanted. Always have a budget and know what that budget is. This wasn't a problem for me, per se, but I could definitely tell when people weren't thinking about what they had to spend and they probably ended up with some computers that were overpriced and will be hard to resell.

Unzip Un-needed in Python?

I recently read a post that contends that an unzip function is unneeded in python. His argument is that you don't need unzip because of the following:

>>> t1 = (0,1,2,3)
>>> t2 = (7,6,5,4)
>>> [t1,t2] == zip(*zip(t1,t2))
True

Oh, of course! How intuitive! OK, no more sarcasm. To me that seems to be very un-pythonic. I never would have thought to use *zip() inside of zip() to get the unzipped version. I would however have expected to be able to write unzip() and get a result. I decided to see how easy it would be to create an unzip() of my own so I fired this off just to see.

def unzip(l):
    if len(l) < 1:
        return []
    
    itemCount = len(l[0])
    
    unzipped = []
    
    for i in range(itemCount):
        unzipped.append(tuple([j[i] for j in l]))
    
    return unzipped

if __name__ == '__main__':
    
    t1 = ("brian","becca","hyrum","david")
    t2 = (29,30,3,27)
    t3 = ("utah","utah","utah","arizona")
    
    zipped = zip(t1,t2,t3)
    unzipped = unzip(zipped)
    
    print zipped
    print unzipped

Starting BlueDragon with Python

I don't know about anybody else but the default startup script that installs with BlueDragon on linux never worked for me. It always failed to do anything. I descended into having to manually restart BlueDragon every time I restarted my server which is a real pain. I know a real sys admin would have solved this long ago. Well the pain goes on no longer. I finally realized that I can use python to start the service for me as system start time. Here is the code.

#!usr/bin/env python

import os

os.system('sh /usr/local/NewAtlanta/BlueDragon_Server_70/bin/StartBlueDragon.sh')

Stylesheet Issues

I apparently seem to be having some stylesheet issues with this site. I'll get that figured out tonight.

How many chickens can YOU have?

I was curious about how many animals I could have on my property so I made a quick call down the the city office as was told that there is a point system in place used to determine the limits. There is a 100 point baseline for a 1 acre lot. The points break down like this:

  • 20 pts - Houses
  • 50 pts - Pigs
  • 25 pts - Horses
  • 25 pts - Cows
  • 10 pts - Goats
  • 5 pts - Small Animals*

Using this formula, with a half acre lot, I start with 50 points for the lot and subtract 20 points for the house. Now I have 30 points to work with -- or in other words I can keep up to six chickens on my property. The combinations are nearly endless! I can even legally have 2 ½ houses! Search me to figure out what ½ a house looks like.

* Small animals are chickens, ducks, geese, pigeons, and rabbits. Dogs and cats are apparently "domestic" so they don't fall into the point system. I would be important to note that the county does requires a kennel license for over dogs yet there are no restrictions on the number of cats you can have.

More Entries