#!/usr/princeton/bin/python
# -*-python-*-
# Change the top line to reflect the path of your Python executable.
#
# debate-online-registration (dor) an web-based tournament registration system
#
# Copyright (C) 2001 Joe Barillari
#
# From the GPL:
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# debate-online-registration: By Joe Barillari (jbarilla@princeton.edu)
# July 23, 2001
# http://www.princeton.edu/~jbarilla
# US mail: 7458 Ashburton Circle NW, North Canton, OH 44720
#
# Released under the terms of the GNU General Public License Version 2
# See <http://www.gnu.org/copyleft/gpl.html> for details
#
# INSTRUCTIONS:
# (1) Get access to a CGI server and determine the URL that the script will have. It should be something like
#     http://school-site.edu/stuff-between-here-and-there/cgi-bin/debate.py
#
# (2) Change the top line of this document to reflect the location of your Python executable
#
# (3) Change the value for the tour director's password:
# make sure the script has permissions set to 701,
# otherwise it's insecure (moreso).
td_password = 'udoiwrjn' #this has GOTTA go somewhere else
#
# (4) Change the 1 to 0 if you don't want to have directory lookups (see #5)
use_directory = 1
#
# (5) If you want users to be able to click on names and get directory
#     entries, find the appropriate URL on your campus and enter it below.
directory_lookup_string = 'http://www.princeton.edu/cgi-bin/Phone/phonecg.pl?Qname=' 
#
# (6) Enter the name of your debate team
team_name = 'Princeton Debate Panel'
#
# (7) Enter the name and email address of the administrator (probably whoever's reading this)
administrator_name="<a href=\"mailto:jbarilla@princeton.edu\">Joe Barillari</a>"
#
# (8) Enter the name of the document. This is probably "debate.py."
script_url = "debate.py"
#
# (9) Enter your team's website's URL
team_url = 'http://www.princeton.edu/~debate'
#
# (10) Create a directory in your cgi-bin directory (ask your site
# administrator for details on where this is) to hold the script and its files.
# You should have a seprate directory for this script -- it creates lots
# of files.
#
# (11) Copy this script to that directory with the executable-for-other bit set.
#     To keep your password safe, unset the read bit.
#		chmod 701 debate.py
#		cp debate.py /path-to/cgi-bin
#
# That's it! You can connect to the URL now and try it out!
#
# TODO:
# 
# add ipstamping?
#
# clean up the HTML -- dump it all into the validator somehow -- cat
# the functions?
#
#
# fix potential exploits (whatever they may be -- fallacious weeks,
# for example, by comparing them to the req'd data). 
# Right now, they'll probably just cause errors,
# but it may be possible to submit bogus data that can only be
# deleted from the shell prompt.

import cPickle
import string
import cgi
import os 
import sys
import time
import traceback

# global variables (constants, actually)
# thanks to this page for telling me how to do something like that:
# http://mail.python.org/pipermail/python-list/2000-January/021755.html

list_of_weeks = 'listofweeks'
version = '$Revision: 1.1.1.1 $ on $Date: 2001/12/25 06:51:55 $ GMT (first beta)'

def print_header(title="Online Registration System"): # dumps the HTML header
	"Print the HTML header"
	print "Content-type: text/html"	
	print
	print
	print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\""
        print "\"http://www.w3.org/TR/html4/strict.dtd\">"
	print "<!--Doctype line supplied by http://www.w3.org/TR/html4/strict-->"
	print "<html><head>"
	#thanks to robotstxt.org, w3.org
	print "<meta name=\"robots\" content=\"none\">"
	if len(title) == 0:
		print "<title>" + team_name + ":: Internal Registration System</title>"
	else:
		print "<title>" + team_name + ":: Internal Registration System :: " + title + "</title>"
	print "<LINK href=\"standard.css\" title=\"compact\" rel=\"stylesheet\" type=\"text/css\">"
	print "</head><body>"
	if len(title) == 0:
		print "<h1>Online Tournament Registration</h1>"
	else:
		print "<h1>" + title + "</h1>"

def print_footer():	#closes the page
	"closes the page"
	print "<hr>"
	show_standard_buttons()
	print "<hr>"
	print "<p><a href=\"" + team_url + "\">" + team_name + "</a> Online Registration System. Uses debate-online-registration " + version + ". Access to and use of this area is restricted to members of the " + team_name + ". Report debate-related problems to the team officers and problems with this script to " + administrator_name + ". This page is powered by <a href=\"http://www.gnu.org/philosophy/free-sw.html\">free software</a>. Visit <a href=\"http://www.princeton.edu/~jbarilla/software.html\">this page</a> to download it.</p>"
	print "</body></html>"


def confirm_delete_debater(submission):
	print_header('Confirm deletion')
	print "<p>Are you sure you want to delete " + submission['name'] + " from registration for the week of " + submission['week'] + "?</p>"
	print "<p>Click \"Confirm Delete\" to delete, or any other navigation button to leave.</p>"
	print "<form method=\"post\" action=\"" + script_url + "\">"
	print "<LABEL for=\"password\">Password to delete: </label>"
        print "<INPUT type=\"password\" name=\"password\">"
	print "<input type=\"hidden\" name=\"name\" value=\"" + submission['name'] + "\">"
	print "<input type=\"hidden\" name=\"week\" value=\"" + submission['week'] + "\">"
	print "<label for=\"delete\">Delete this entry: </label>"
	print "<input type=\"submit\" name=\"submit\" value=\"Confirm Delete\"></form></p>"
	print_footer()

def delete_debater(name, week):
	"deletes a debater's entry."	
	if not os.path.exists(string.replace(week, '/', '%2F')):
		tell_user("You tried to delete a user from a non-existant week, which should be impossible. Email the site maintainer -- that's gotta be a bug.")
		return	
	thisweekfile = open(string.replace(week,'/','%2F'), 'r')
	userdb = cPickle.load(thisweekfile)
	thisweekfile.close()
	if not userdb.has_key(name):
		tell_user("You tried to delete a non-existant user, which should be impossible (unless someone deleted them after you got the confirmation question but before you confirmed). Email the site maintainer -- that's gotta be a bug.")
		return				
	del userdb[name]
	thisweekfile = open(string.replace(week,'/','%2F'), 'w')
	cPickle.dump(userdb, thisweekfile)
	thisweekfile.close()
	return

def show_week_menu(label='Week: ', readonly_status = ' ', select_week = ' '):
	#saw this "label" stuf on the w3 website, used it
	#also see http://www.ping.be/sabine-appelmans/home/python/. Quite useful!
	print "<LABEL for=\"week\">"+label+"</label>"
	print "<select " + readonly_status + " id=\"week\" name=\"week\">"
	for week in get_weeks():
		if week == select_week:
			print "<option selected>  " +  week  + " </option>"
		else:
			if not readonly_status == 'readonly':	
				print "<option> " +  week + " </option>"
	print "</select>"
	return

def show_tournament_menu(week, label='Tournament: ', readonly_status = ' ', select_tournament = ' '):
	print "<LABEL for=\"tournament\">" + label + "</label>"
	print "<select  id=\"tournament\" name=\"tournament\">"
	for tournament in get_tournaments(week):
		if tournament == select_tournament:
			print "<option selected>  " +  tournament  + " </option>"
		else:
			print "<option> " +  tournament + " </option>"
	print "</select>"
	return

def show_all_tournament_menus():
	print "<LABEL for=\"tournament\">" +'the tournament' + "</label>"
	print "<select  id=\"tournament\" name=\"tournament\">"
	#thanks to the W3c for all the cool commands and instructions on how to use them
	for week in get_weeks():
		print "<optigroup label \"" + week + "\">"
		for tournament in get_tournaments(week):
			print "<option> " +  tournament + " </option>"
		print "</optigroup>"
	print "</select>"
	return

def edit_page(submission):
	"wrapper for show_editing_page; finds the object it needs."
	show_form('Edit my registration', 'Update my registration', submission)

def show_form(message, action, submission):
	"wrapper for the editing pages."
	if submission['submit'] == 'Register for a tournament this week':
		debater = Debater_entry('','','','','','','','','','')
		readonly = ''
	else:
		debater = get_debater_obj(submission['name'], submission['week'])
		readonly = 'readonly'	
	week = submission['week']
	usecar = usevan = isjudge = ' '
	if debater.car == 'Yes':
		usecar = "checked"
	if debater.judge == 'Yes':
		isjudge = "checked"
	if debater.van == 'Yes':
		usevan = "checked"		
	print_header(message)
	print "<p id=\"emphasizeme\">Starred fields are required.</p>"
	print "<FORM method=\"post\" action=\"" + script_url + "\">"
	print "<table summary=\"Form to create or edit a debater's entry\">"
	print "<tr> <th id=name>Description</th> <th id=choice>Choice</th></tr>"
	print "<tr><td>*Week (preselected):</td><td>"
	show_week_menu('', 'readonly', week) 
	print "</td></tr>"
	print "<tr><td>*Tournament:</td><td>"
	show_tournament_menu(week,'')
	print "</td></tr>"
	print "<tr><td><LABEL for=\"name\">* Your NetID: </label></td>"
	print "<td><INPUT " + readonly + " type=\"text\" name=\"name\" value=\"" + debater.name + "\"></tr></td>"
	print "</p><p>"
	if not debater.created == '': #must be an edit
		print "<tr><td colspan=2>"
		print "<p id=emphasizeme>To change the name or week of registration, you must delete the erroneous record and create a new one. <br>Same goes for the password.</p>"
		print "<input type=\"hidden\" name=\"created\" value=\"" + debater.created + "\">"
		print "</td></tr>"
	print "<tr><td><LABEL for=\"partner\">(Optional.) Your (preferred) partner's NetID, or name and school, if hybrid: </label>"
	print "<td><INPUT type=\"text\" name=\"partner\" value=\"" + debater.partner + "\"></td></tr>"
	print "</p><p>"

	# htmlhelp.org was helpful here...or it was, before I changed the page (again)

	print "<tr><td><LABEL for=\"car\">Got a car we can use?: </label></td><td>"
	print "<INPUT type=\"checkbox\" name=\"car\" value=\"Yes\"" + usecar + "></td></tr>"	

	print "<tr><td><LABEL for=\"van\">Van-certified?: </label></td><td>"
	print "<INPUT type=\"checkbox\" name=\"van\" value=\"Yes\" " + usevan + "></td></tr>"

	print "<tr><td><LABEL for=\"van\">Will you be judging/willing to judge?: </label></td><td>"
	print "<INPUT type=\"checkbox\" name=\"judge\" value=\"Yes\" " + isjudge + "></td></tr>"

	print "<tr><td><LABEL for=\"notes\">Anything else we should know?: </label><br></td><td>"
	print "<textarea name=\"notes\" rows=5 cols=40>" + debater.notes + "</textarea></td></tr>"

	print "<tr><td><LABEL for=\"password\">*Password: </label></td><td>"
	print "<INPUT type=\"password\" name=\"password\"></td></tr>"

	if debater.created == '': #new entry, needs verification	
		print "<tr><td><LABEL for=\"password\">*Password again, to verify: </label></td><td>"
		print "<INPUT type=\"password\" name=\"password2\"></td></tr>"
		print "<tr><td colspan=2>"
		print "<p id=emphasizeme>Your password is used to prevent changes to your registration by anyone except for you or the tour directors. It is tied to you by entry, so it can be different every week. DO NOT use an important password (like your CIT password). Storage of your password is NOT secure.</p></td></tr>"
	print "<tr><td>Submit:</td><td>"
	print "<INPUT type=\"submit\" name=\"submit\" value=\"" + action + "\"></td></tr>"
	print "</table>"
	print "</form>"
	print_footer()


def create_empty_week_file_if_none_exists(weekname): #exception -- b/c week is a dictionary, 
						     # we have to break convention of calling 
						     #like variables like names
	"sets up empty week files"
	if not os.path.exists(string.replace(weekname+'.info','/','%2F')):
		thisweekfile = open(string.replace(weekname+'.info','/','%2F'), 'w')
		week = {}
		cPickle.dump(week, thisweekfile)
		thisweekfile.close()
	if not os.path.exists(string.replace(weekname,'/','%2F')):
		thisweekfile = open(string.replace(weekname,'/','%2F'), 'w')
		userdb = {}			
		cPickle.dump(userdb, thisweekfile)
		thisweekfile.close()

def create_debater(submission): #now we do some data stuff....eeeeventually
	"dumps reg. data into the appropriate week's data file. most magical function here. Yay Python!"
	create_empty_week_file_if_none_exists(submission['week'])
	thisweekfile = open(string.replace(submission['week'],'/','%2F'), 'r')
	userdb = cPickle.load(thisweekfile)
	thisweekfile.close()
	if userdb.has_key(submission['name']) == 1:
		thisweekfile.close()
		tell_user('Username already registered for this week. To change an entry, delete the old entry and re-enter it.')
		return
		# awwright...apparently the cgi dictionary is IMMUTABLE, so I can't mess with it
		# so I go with this ugliness (maybe copying it to a new dictonary would help
		# but it's not the important thing -- it's disposable. The Debater object isn't.
		#really and truthfully, when doing reregistration,
		#I should work with the object, not with the input type=hidden
		#returned data. In the future.
	if submission.has_key('car'):
		car = submission['car']
	else:
		car = 'No'
	if submission.has_key('van'):
		van = submission['van']
	else:
		van = 'No'
	if submission.has_key('judge'):
		judge = submission['judge']
	else:
		judge = 'No'
	if submission.has_key('notes'):
		notes = submission['notes']
	else:
		notes = ' '
	if submission.has_key('partner'):
		partner = submission['partner']
	else:
		partner = ' '
	if submission.has_key('created'):
		creation_timestamp = submission['created']
	else:
		creation_timestamp = time.strftime("%b %d %Y %H:%M", time.localtime(time.time()))
	modification_timestamp = time.strftime("%b %d %Y %H:%M", time.localtime(time.time()))
	userdb[submission['name']] = Debater_entry(submission['name'],
partner, submission['tournament'], car, van, judge, notes, creation_timestamp,
modification_timestamp, submission['password'])
	thisweekfile = open(string.replace(submission['week'],'/','%2F'), 'w')
	cPickle.dump(userdb, thisweekfile)
	thisweekfile.close()
	if creation_timestamp == modification_timestamp: #kludge to detect new registration
		tell_user_with_table('Registered.', submission['week'])
	else:
		tell_user_with_table('Updated.', submission['week'])

def sanity_check(submission, whattodo):
	"makes sure people aren't stupid"
	if whattodo.has_key('stdcheck'):
		for key in submission.keys():
			if (len(submission[key]) > 1) == 0:
				if not ( key == 'notes' or key == 'partner' ):
					if whattodo.has_key('explainwhy'):
						tell_user("Your submission for \"" + key + "\" of \"" + submission[key] + "\" was invalid (too short). Please try again.")
						return 0
		if not submission.has_key('tournament') or not submission.has_key('name'): # replace this with something better
			if whattodo.has_key('explainwhy'):
				tell_user("Your submission had no data in a required field. Please hit back and fill in the required fields.")
				
			return 0
	if whattodo.has_key('dualpasswordcheck'):
		if not submission.has_key('password2') or not submission.has_key('password'): 
			if whattodo.has_key('explainwhy'):
				tell_user("Supply BOTH passwords. Please press back and try again.")
			return 0
		elif not submission['password2'] == submission['password']:
			if whattodo.has_key('explainwhy'):			
				tell_user("Passwords didn't match. Please press back and try again.")
			return 0
	if whattodo.has_key('passwordcheck'):
		if not submission.has_key('password'): 
			if whattodo.has_key('explainwhy'):
				tell_user("Supply a password. Please press back and try again.")
			return 0
	return 1

def get_weeks(): #read the weeks from a file
	"get the list of weeks (i.e., tournaments)!"
	#this is the first and only place we check for the file's existance. Mainly b/c if you manage to go somewhere else
	#that it is referenced, it must exist for you to get there
	safename = string.replace(list_of_weeks,'/','%2F') #safe, b/c it's been checked for slashes!
	if not os.path.exists(safename):
 		blankweeklist = []
		blankweekfile = open(safename, 'w')
		cPickle.dump(blankweeklist, blankweekfile)
		blankweekfile.close()
	file = open(safename, 'r')
	weeklist = cPickle.load(file)
	file.close()
	return weeklist

def get_tournaments(week): 
	"get the list of tournaments!"
	safename = string.replace(week+'.info','/','%2F')
	file=open(safename,'r')
	week = cPickle.load(file)
	file.close()
	return week.keys()

	
class Debater_entry:
	"A debater on any given week"
	def __init__(self, nname, npartner, ntournament, ncar, nvan, njudge, nnotes, ncreated, nmodified, npassword):      #thanks to the tutorial
		self.name = nname
		self.partner = npartner
		self.tournament = ntournament
		self.car = ncar
		self.van = nvan
		self.judge = njudge
		self.notes = nnotes
		self.created = ncreated
		self.modified = nmodified
		self.password = npassword

class Tournament: #"I can't make a struct, so this is the result!"
	"A tournament"
	def __init__(self, nname = '', nloc = '', ntime = '', ntds = [], nnotes = ''): 
		self.name = nname
		self.location = nloc
		self.time = ntime
		self.tds = ntds
		self.notes = nnotes

def create_week(weekname):
	"creates a new week"
	weeklist = get_weeks()
	safename = string.replace(weekname,'/','%2F')
	if os.path.exists(safename) or os.path.exists(safename+'.info') or weekname in weeklist:
		tell_user('Error. Week or old files belonging to it still exist.')
		return 0
	create_empty_week_file_if_none_exists(weekname)
	weeklist = weeklist + [weekname]
	weekfile=open(string.replace(list_of_weeks,'/','%2F'), 'w')
	weeklist = cPickle.dump(weeklist, weekfile)
	weekfile.close()
	tell_user('Week created.') 

def confirm_delete_week(submission):
	print_header('Confirm week deletion')
	print "<p>Are you sure you want to delete the week of " + submission['week'] + "? This action will not erase the week's record files, but will render the week inaccessable.</p>"
	print "<p>Click \"Confirm Delete Week\" to delete, or any other navigation button to leave.</p>"
	print "<form method=\"post\" action=\"" + script_url + "\">"
	print "<LABEL for=\"password\">TD Password to delete: </label>"
        print "<INPUT type=\"password\" name=\"password\">"
	print "<input type=\"hidden\" name=\"week\" value=\"" + submission['week'] + "\">"
	print "<label for=\"delete\">Delete this entry: </label>"
	print "<input type=\"submit\" name=\"submit\" value=\"Confirm Delete Week\"></form></p>"
	print_footer()

def delete_week(weekname):
	"deletes a week"
	weeklist = get_weeks()
	safename = string.replace(weekname,'/','%2F')
	del weeklist[weeklist.index(weekname)]
	weekfile=open(string.replace(list_of_weeks,'/','%2F'), 'w')
	weeklist = cPickle.dump(weeklist, weekfile)
	weekfile.close()
	tell_user('Week deleted.') 

def show_tournament_form(submission):
	if submission['submit'] == 'New tournament':
		show_tournament_form_inner('Create a new tournament', 'Create this tournament', submission['week'])
	else:
		safename = string.replace(submission['week']+'.info','/','%2F')
		thisweekfile = open(safename, 'r')
		week = cPickle.load(thisweekfile)
		thisweekfile.close()
		if not week.has_key(submission['name']):
			tell_user("Error. Tournament doesn't exist.")
			return
		show_tournament_form_inner('Edit a tournament entry', 'Update this tournament', submission['week'], 'readonly', week[submission['name']])

def show_tournament_form_inner(header, button, week, readonly = '', tournament = Tournament()):
	print_header(header)
	print "<FORM method=\"post\" action=\"" + script_url + "\">"
	print "<p>"
	print "<table summary=\"Form to create or edit a tournament\">"
	print "<tr> <th id=name>Description</th> <th id=choice>Choice</th></tr>"
	print "<tr> <td>*Week of tournament (preselected)</td><td>"
	show_week_menu('', 'readonly', week) 
	print "</td>"
	print "<tr><td><LABEL for=\"name\">* The tournament's name: </label></td>"
	print "<td><INPUT type=\"text\"" +  readonly + " size=50 name=\"name\" value=\"" + tournament.name + "\"></td></tr>"
	print "<tr><td><LABEL for=\"location\">* Location: </label></td>"
	print "<td><INPUT type=\"text\" size=50 name=\"location\" value=\"" + tournament.location + "\"></td></tr>"
	print "<tr><td><LABEL for=\"tds\">TDs\' NetIDs, separated by spaces</label></td>"
	print "<td><INPUT type=\"text\" size=50 name=\"tds\" value=\""
	for td in tournament.tds:
		print td + ' '
	print "\"></tr>"
	print "<tr><td><LABEL for=\"time\">Time/day of departure (e.g., 14 a.m. on October 32):</label></td>"
	print "<td><INPUT type=\"text\" name=\"time\" size=50 value=\"" + tournament.time + "\"></td></tr>"
	print "<tr><td><LABEL for=\"notes\">Info (nature of tournament, helpful hints): </label></td>"
	print "<td><textarea name=\"notes\" rows=5 cols=50>" + tournament.notes + "</textarea></td></tr>"
	print "<tr><td><LABEL for=\"password\">* Tour director password: </label></td>"
	print "<td><INPUT type=\"password\" name=\"password\"></td></tr>"
	print "<tr><td>Submit this entry:</td>"
	print "<td><INPUT type=\"submit\" name=\"submit\" value=\"" + button + "\"></td></tr></table>"
	print "</form>"
	print_footer()

def show_week_form():
	print_header('Create a new week:')
	print "<FORM method=\"post\" action=\"" + script_url + "\">"
	print "<p>"
	print "<LABEL for=\"name\">* The week's name (the date it starts, usually -- e.g., Sun, July 1, 2001): </label>"
	print "<INPUT type=\"text\" name=\"name\">"
	print "</p>"
	print "<p>"
	print "<LABEL for=\"password\">* Tour director password: </label>"
	print "<INPUT type=\"password\" name=\"password\">"
	print "</p>"
	print "<p><INPUT type=\"submit\" name=\"submit\" value=\"Create this week\">"
	print "</p>"
	print "</form>"
	print_footer()

def create_tournament(submission, be_quiet = 'no'):
	if not submission.has_key('notes'):
		notes = ''	
	else:
		notes = submission['notes']
	tds = string.splitfields(submission['tds'])
	tournament = Tournament(submission['name'], submission['location'], submission['time'], tds, notes)
	create_empty_week_file_if_none_exists(submission['week'])
	safename = string.replace(submission['week']+'.info','/','%2F')
	thisweekfile = open(safename, 'r')
	week = cPickle.load(thisweekfile)
	thisweekfile.close()
	if week.has_key(submission['name']):
		tell_user("Error. Tournament exists. If you were creating a tournament, this shouldn't happen. If you were editing a tournament, this means that the old tournament wasn't deleted properly. In either case, contact the administrator.")
	week[submission['name']] = tournament
	thisweekfile = open(safename, 'w')
	cPickle.dump(week, thisweekfile)
	thisweekfile.close()
	if be_quiet == 'no':
		tell_user('Tournament added.')		

def delete_tournament(submission, be_quiet = 'no'):
	safename = string.replace(submission['week']+'.info','/','%2F')
	thisweekfile = open(safename, 'r')
	week = cPickle.load(thisweekfile)
	thisweekfile.close()
	del week[submission['name']]
	thisweekfile = open(safename, 'w')
	cPickle.dump(week, thisweekfile)
	thisweekfile.close()
	if be_quiet == 'no':
		tell_user('Tournament deleted.')		

def confirm_delete_tournament(submission):
	print_header('Confirm tournament deletion')
	print "<form method=\"post\" action=\"" + script_url + "\">"
	print "<p>Are you sure you want to delete "
	show_all_tournament_menus() 
	print "? This action will not erase the tournament's entreants, but will delete the tournament's background information and render it unselectable. The behavior of debaters registered in a deleted tournament is undefined. To be safe, unregister all entreants from a tournament before deleting it.</p>"
	print "<p>Click \"Confirm Delete Tournament\" to delete, or any other navigation button to leave.</p>"
	print "<LABEL for=\"password\">TD Password to delete: </label>"
        print "<INPUT type=\"password\" name=\"password\">"
	print "<input type=\"hidden\" name=\"week\" value=\"" + submission['week'] + "\">"
	print "<label for=\"submit\">Delete this entry: </label>"
	print "<input type=\"submit\" name=\"submit\" value=\"Confirm Delete Tournament\"></form></p>"
	print_footer()


def show_tournament_info(weekname): 
	"get the list of tournaments!"
	safename = string.replace(weekname+'.info','/','%2F')
	file=open(safename,'r')
	week_dict = cPickle.load(file)
	if len(week_dict.keys()) == 0:
		print "<p id=emphasizeme>No tournaments have been associated with this week.</p>"
		return
	for tournament in week_dict.keys():
		print "<h3>" + week_dict[tournament].name + "</h3>"
		print "<p><strong>Location:</strong> " + week_dict[tournament].location + "</p><p>  <strong>Time of Departure:</strong> " + week_dict[tournament].time + "</p>"
		print "<p><strong>Tour Directors:</strong> "
		for td in week_dict[tournament].tds:
						print "<a href=\"" + directory_lookup_string +  td  + "\">" + td + "</a> "
		print "<p>"
		print "<p> <strong>Notes:</strong> " + week_dict[tournament].notes + "</p>"
		print "<FORM method=\"post\" action=\"" + script_url + "\">"
		print "<p> Tour director controls:"
		print "<INPUT type=\"submit\" name=\"submit\" value=\"Edit tournament\">"
		print "<input type=\"hidden\" name=\"week\" value=\"" + weekname + "\">"
		print "<input type=\"hidden\" name=\"name\" value=\"" + week_dict[tournament].name + "\">"
		print "<INPUT type=\"submit\" name=\"submit\" value=\"Delete tournament\">"
		print "</p>"
		print "</form>"
	file.close()

def show_standard_buttons():
	"standard button bar."
	print "<FORM method=\"get\" action=\"" + script_url + "\">"
	print "<p>"
	show_week_menu('Select a week:')
	print "</p>"
	print "<p> User Controls:"
	print "<INPUT type=\"submit\" name=\"submit\" value=\"View this week\">"
	print "<INPUT type=\"submit\" name=\"submit\" value=\"Register for a tournament this week\">"
	print "</p><p> Tour Director controls:"
	show_td_buttons_inner()
	print "</p>"
	print "</form>"



def show_td_buttons():
	"Puts buttons on the page to make a new tournament/week"
	print "<FORM method=\"post\" action=\"" + script_url + "\">"
	print "<p> TD Controls:"
	show_td_buttons_inner()
	print "</p>"
	print "</form>"

def show_td_buttons_inner():
	"Puts buttons on the page to make a new tournament/week"
	print "<INPUT type=\"submit\" name=\"submit\" value=\"New week\">"
	print "<INPUT type=\"submit\" name=\"submit\" value=\"Delete week\">"
	print "<INPUT type=\"submit\" name=\"submit\" value=\"New tournament\">"

def get_debater_obj(name, week):
	"fetches the object of a given debater on a given week"
	safefilename = string.replace(week, '/', '%2F')
 	if not os.path.exists(safefilename):
		tell_user("Can't find the file \"" + safefilename + "\" . Something's seriously wrong. Contact the administrator.")
	thisweekfile = open(safefilename, 'r')
	userdb = cPickle.load(thisweekfile)
	thisweekfile.close()
	if not userdb.has_key(name):
		tell_user("Can't find the name \"" + name + "\" in the file \"" + safefilename + "\" . Something's seriously wrong. Contact the administrator.")
	return userdb[name]

def auth_check(submission, type='normal'):
	"determine if user is authorized"
	if not submission.has_key('password'):
		tell_user("invalid password")
		return 0
	if not len(submission['password']) > 1:
		tell_user("invalid password")
		return 0
	if type == 'normal':
		debater_obj = get_debater_obj(submission['name'], submission['week'])
		if debater_obj.password == submission['password']:
			return 1
		#check to see if they're a TD, and therefore authorized
		if td_password == submission['password']: #we GOTTA put this somewhere else...I'll have to make some week-object classfiles
			return 1
	if type == 'td':
		if td_password == submission['password']:
			return 1
	tell_user('Authentication failed: password incorrect.')
	return 0
	



def show_page_for_week(week): #wrapper
	print_header('Registration: week of ' + week)
	print "<h2>Registration</h2>"
	show_table_for_week(week)
	print "<hr><h2>Tournament Information</h2>"
	show_tournament_info(week)
	print_footer()
	

def show_table_for_week(week):
	"shows the page for the appropriate week"
	#sanity-check changed: now instead of complaining, the
	# computer silently creates a functional (empty)
	create_empty_week_file_if_none_exists(week)		
	weekfile = open(string.replace(week, '/', '%2F'), 'r') #eliminate madness of slashes in filenames
	weekdata = cPickle.load(weekfile)
	weekfile.close()
	print "<table summary=\"List of debaters signed up for the week of" + week + "\">"
#	print "<colgroup><col span=5><col id=\"notes_column\" width = 40px><col span=2></colgroup>"
#	print "<colgroup><col span=10></colgroup>"
	print "<tr> <th id=name>Name</th> <th id=partner>Partner</th> <th id=tournament>Tournament</th> <th id=car>Car avail?</th> <th id=van>Van cert?</th> <th id=judge>Judging?</th><th id=notes>Notes</th> <th id=created>Created</th><th id=modified>Last changed</th><th id=delete>Delete</th> <th id=edit>Edit</th></tr>"
	if weekdata == {}:
		print "<p id=emphasizeme>No one is registered for this week.</p>"
	for key in weekdata.keys():
		if use_directory == 1:
			print "<tr><td headers=name><a href=\"" + directory_lookup_string +  key + "\">" + key + "</a></td>"
			print "<td headers=partner><a href=\"" + directory_lookup_string +  weekdata[key].partner + "\">" + weekdata[key].partner + "</a>"

		else:	
			print "<tr id=\"list\"><td headers=name>" + key
			print "</td><td headers=partner>" + weekdata[key].partner
		print "</td><td headers=tournament>" + weekdata[key].tournament 
		print "</td><td headers=car>" + weekdata[key].car
		print "</td><td headers=van>" + weekdata[key].van 
		print "</td><td headers=judge>" + weekdata[key].judge
		print "</td><td headers=notes>" + weekdata[key].notes
		print "</td><td headers=created>" + weekdata[key].created
		print "</td><td headers=created>" + weekdata[key].modified
		print "</td><td headers=delete>"
		print "<form method=\"post\" action=\"" + script_url + "\">"
		print "<input type=\"hidden\" name=\"name\" value=\"" + key + "\">"
		print "<input type=\"hidden\" name=\"week\" value=\"" + week + "\">"
		print "<input type=\"submit\" name=\"submit\" value=\"Delete\"></form></td>"

		print "<td headers=edit>"
#FIXME:spaces, commas		print "<a href=\"" + script_url + "?name=" + key + "&week" + week + "&submit=Edit>"
		print "<form method=\"post\" action=\"" + script_url + "\">"
		print "<input type=\"hidden\" name=\"name\" value=\"" + key + "\">"
		print "<input type=\"hidden\" name=\"week\" value=\"" + week + "\">"
		print "<input type=\"submit\" name=\"submit\" value=\"Edit\"></form></td> </tr>"
	print "</table>"	


def tell_user(string, id = 'emphasizeme'):
	"tell the user something"
	print_header('Message from the server:')
	print "<p id=\"" + id + "\">" + string + "</p>"
	print_footer()

def tell_user_with_table(string, week):
	"tell the user something, usually that an operation worked"
	print_header('Registration: week of ' + week)
	print "<p id=\"emphasizeme\">" + string + "</p>"
	show_table_for_week(week)
	print_footer()



def dump_submission(submission):
	"debugging routine. Dump the text of the CGI submission to a webpage."
	fields = submission.keys()
	print_header('Error')
	print "I don't understand this submission. submission.keys():", fields
	print "len(fields):", len(fields)
	print "list of fields:"
	for i in fields:
		print "{"
		print i, submission[i]
		print "}"
	print_footer()

def show_front_page():
	"show the front page"
	print_header(team_name)
	print "<p>Welcome to Online Registration.</p>"
	print_footer()


def main():
	#I'd like to thank the ping.be site here
	"main event loop (remember FutureBasic!?) --- but it's not a loop"
	submission = cgi.SvFormContentDict() 
	#submission = cgi.FieldStorage() 

	if len (submission.keys()) == 0:  #visitor just hit the site
		show_front_page()
		return
	#otherwise, pick from the following submissions
	elif submission.has_key('submit'):
		if submission['submit'] == 'Edit':
				edit_page(submission)
		elif submission['submit'] == 'Delete':
			confirm_delete_debater(submission)
		elif submission['submit'] == 'Confirm Delete':
                        if sanity_check(submission, {"passwordcheck":1}):
				if auth_check(submission) == 1: #make this an input == hidden
					delete_debater(submission['name'], submission['week'])
					tell_user_with_table('Entry deleted.', submission['week'])
					return
				else:
					tell_user('Authentication failed.')
					return		
		elif submission['submit'] == 'Register me':
			if sanity_check(submission, {"stdcheck":1, "dualpasswordcheck":1}) == 1:
				if 1: #if auth_check(submission) == 1: we can't auth these, can we.
					create_debater(submission)	
				else:
					return
				return
			else:
				sanity_check(submission, {"stdcheck":1, "dualpasswordcheck":1, "explainwhy":1})
				return
		elif submission['submit'] == 'Update my registration':
			if sanity_check(submission, {"stdcheck":1, "passwordcheck":1}) == 1:
				if auth_check(submission) == 1:
					delete_debater(submission['name'], submission['week'])
					create_debater(submission)	
					return
				else:
					return
			else:
				sanity_check(submission, {"stdcheck":1, "passwordcheck":1, "explainwhy":1})
				return
		elif submission['submit'] == 'View this week':
			show_page_for_week(submission['week'])
			return
		elif submission['submit'] == 'Create this week':
			if auth_check(submission, 'td') and submission.has_key('name'):
				if len(submission['name']) > 2:
					create_week(submission['name'])
					return
			tell_user("Bad password or invalid week name.")
			return
		elif submission['submit'] == 'Create this tournament':
			if auth_check(submission, 'td') and submission.has_key('name'):
				if not len(submission['name']) < 2:
					create_tournament(submission)
					return
			tell_user("Bad password or invalid tournament name.")
			return
		elif submission['submit'] == 'New tournament' or submission['submit'] == 'Edit tournament':
			show_tournament_form(submission)
		elif submission['submit'] == 'New week':
			show_week_form()
		elif submission['submit'] == 'Delete week':
				confirm_delete_week(submission)
		elif submission['submit'] == 'Delete tournament':
				confirm_delete_tournament(submission)
		elif submission['submit'] == 'Confirm Delete Week':
			if auth_check(submission, 'td') and submission.has_key('week'):
				delete_week(submission['week'])
			else:
				tell_user('Bad password or invalid week selection.')
		elif submission['submit'] == 'Confirm Delete Tournament':
			if auth_check(submission, 'td'):
				delete_tournament(submission)
			else:
				tell_user('Bad password or invalid tournament selection.')
		elif submission['submit'] == 'Update this tournament':
			if auth_check(submission, 'td'):
				delete_tournament(submission, 'be quiet')
				create_tournament(submission, 'be quiet')
				tell_user("Tournament updated.")
			else:
				tell_user('Bad password or invalid submission.')
		elif submission['submit'] == 'Register for a tournament this week':
			if get_tournaments(submission['week']) == []:
				tell_user("No tournaments have been associated with this week.")
				return
			show_form('Registration form', 'Register me', submission)
	else:
		dump_submission(submission)
		return

#thanks to the ref. manual
sys.stderr = sys.stdout
try: main()
except:
	print_header('Major error!')
	print "An unexpected error has occured. Contact " + administrator_name + "and copy the text of this page into your message. Thanks."	
	print "<p>*** Begin error information"
	print
	print "<PRE>"
	traceback.print_exc()
	print "</PRE>"
	print
	print "*** End error information</p>"
	print
	print_footer()
	raise
















