################################################################################ # index.py ################################################################################ import html_help import os import sys import time import Zcgi KEYS = 'description', 'start', 'end', 'sunday', 'monday', \ 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday' class soft_dict: def __init__(self, dictionary, format): self.__dictionary = dictionary self.__format = format def __getitem__(self, key): try: if self.__dictionary[key]: return self.__format % self.__dictionary[key] except: pass return '' class WeekError: def __init__(self, string): self.__string = string def __str__(self): return self.__string def main(): if Zcgi.dictionary is None: show_form() elif has_keys(Zcgi.dictionary, KEYS): show_table() else: show_form() def show_form(error=''): if error: error = '\t\t' + error + '\n' values = soft_dict(Zcgi.dictionary, ' value="%s"') Zcgi.print_html(''' \t \t\t \t\t\tSchedule Maker \t\t \t \t %s\t\t
\t\t\tDescription:
\t\t\t
\t\t\tStart Date:
\t\t\t
\t\t\tEnd Date:
\t\t\t
\t\t\tSunday:
\t\t\t
\t\t\tMonday:
\t\t\t
\t\t\tTuesday:
\t\t\t
\t\t\tWednesday:
\t\t\t
\t\t\tThursday:
\t\t\t
\t\t\tFriday:
\t\t\t
\t\t\tSaturday:
\t\t\t
\t\t\t \t\t
\t ''' % tuple([error, os.path.basename(sys.argv[0])] \ + unpack(values, KEYS))) def has_keys(dictionary, keys): for key in keys: if not dictionary.has_key(key): return False return True def show_table(): values = Zcgi.dictionary if not values['description']: show_form('You must enter a description.') try: start = time.strptime(values['start'], '%m/%d/%y') end = time.strptime(values['end'], '%m/%d/%y') except: show_form('Dates must be in the MM/DD/YY format.') try: assert time.mktime(end) > time.mktime(start) except: show_form('The end date must come after the start date.') try: check_week(values, KEYS[3:]) except WeekError, problem: show_form(str(problem)) html = create_html(values['description'], start, end, unpack(values, KEYS[3:])) Zcgi.print_html(html) def unpack(values, keys): unpacked = [] for key in keys: unpacked.append(values[key]) return unpacked def check_week(dictionary, keys): for key in keys: try: if not dictionary[key]: continue hm = dictionary[key].split('-') assert len(hm) == 2 first = time.strptime(hm[0].strip(), '%H:%M') second = time.strptime(hm[1].strip(), '%H:%M') dictionary[key] = hm[0].strip() + ' - ' + hm[1].strip() except: raise WeekError(key.capitalize() + ' should be in the HH:MM - HH:MM format.') try: assert second.tm_hour * 60 + second.tm_min > first.tm_hour * 60 + first.tm_min except: raise WeekError('Start time must come before end time on ' + key.capitalize() + '.') def create_html(description, start, end, week): html = ''' \t \t\t \t\t\tThe Schedule \t\t \t \t \t\t
''' start_month = start.tm_year * 12 + (start.tm_mon - 1) end_month = end.tm_year * 12 + (end.tm_mon - 1) for month in range(start_month, end_month + 1): html += html_help.html_table(1, 1, 3, '\t').mutate(0, 0, create_month_html(description, start, end, week, month)).html() + '\n' if month != end_month: html += '\t\t\t
\n' return html + '\t\t
\n\t\n' def create_month_html(description, start, end, week, month): start = time.mktime(start) - 43200 end = time.mktime(end) + 43200 now = time.strptime(str((month / 12) % 100).zfill(2) + ' ' + str(month % 12 + 1) + ' 01', '%y %m %d') html = '' + time.strftime('%B %Y', now) + '\n' html_month = html_help.html_month((month / 12) % 100, month % 12 + 1, 0, '\t') html_month.table_option('border="1" width="800"').row_option('valign="top"').column_option('width="14%"') now_month = now.tm_mon while now.tm_mon == now_month: mktime = time.mktime(now) if start <= mktime <= end: week_day = (now.tm_wday + 1) % 7 if week[week_day]: html_month.mutate(now.tm_mday, '' + description + '
\n' + week[week_day]) now = time.localtime(mktime + 86400) return html + html_month.html() if __name__ == '__main__': Zcgi.execute(main, 'cgi') ################################################################################ # html_help.py ################################################################################ import time import Zam class html_table: def __init__(self, rows, columns, indent, style): self.__matrix = Zam.matrix(rows, columns, '') self.__indent = indent self.__style = style self.__table_option = '' self.__row_option = '' self.__column_option = '' def mutate(self, row, column, text): assert type(text) is str self.__matrix[row][column] = text return self def access(self, row, column): return self.__matrix[row][column] def table_option(self, string): assert type(string) is str self.__table_option = string return self def row_option(self, string): assert type(string) is str self.__row_option = string return self def column_option(self, string): assert type(string) is str self.__column_option = string return self def html(self): html = self.__style * self.__indent + '\n' html += self.__style * (self.__indent + 1) + '\n' return html + self.__style * self.__indent + '' class html_month: def __init__(self, year, month, indent, style): matrix = self.__make_matrix(year, month) self.__table = html_table(len(matrix) + 1, 7, indent, style) for index, item in enumerate(('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday')): self.__table.mutate(0, index, '' + item + '') for row in range(len(matrix)): for column in range(7): if matrix[row][column]: self.__table.mutate(row + 1, column, '' + str(matrix[row][column]).zfill(2) + '\n
\n') def __make_matrix(self, year, month): rows = [Zam.array(7, 0)] row = 0 now = time.localtime(time.mktime(time.strptime(str(year).zfill(2) + ' ' + str(month).zfill(2) + ' 01', '%y %m %d')) + 14400) self.__first_day = (now.tm_wday + 1) % 7 once = False while now.tm_mon == month: if once: if now.tm_wday == 6: rows.append(Zam.array(7, 0)) row += 1 else: once = True rows[row][(now.tm_wday + 1) % 7] = now.tm_mday self.__days_in_month = now.tm_mday now = time.localtime(time.mktime(now) + 86400) return rows def mutate(self, day, text): row, column = self.__get_pos(day) self.__table.mutate(row, column, self.__table.access(row, column)[:15] + text) return self def access(self, day): row, column = self.__get_pos(day) return self.__table.access(row, column)[15:] def __get_pos(self, day): assert 1 <= day <= self.__days_in_month pos = self.__first_day - 1 + day return pos / 7 + 1, pos % 7 def table_option(self, string): self.__table.table_option(string) return self def row_option(self, string): self.__table.row_option(string) return self def column_option(self, string): self.__table.column_option(string) return self def html(self): return self.__table.html() ################################################################################ # Zam.py ################################################################################ # Name & Description # ================== '''Support module for array and matrix use. This module provides two classes that emulate one and two dimentional lists with fixed sizes but mutable internals.''' # Data & Imports # ============== __all__ = ['array', 'matrix'] __version__ = '1.1' import sys # Public Names # ============ class array(object): '''array(length) -> new array array(length, value) -> initialized from value''' def __init__(self, length, value=None): '''x.__init__(...) initializes x''' self.__data = range(length) for index in range(length): self.__data[index] = value def __repr__(self): '''x.__repr__() <==> repr(x)''' return repr(self.__data) def __len__(self): '''x.__len__() <==> len(x)''' return len(self.__data) def __getitem__(self, key): '''x.__getitem__(y) <==> x[y]''' return self.__data[key] def __setitem__(self, key, value): '''x.__setitem__(i, y) <==> x[i]=y''' self.__data[key] = value def __delitem__(self, key): '''x.__delitem__(y) <==> del x[y]''' self.__data[key] = None def __iter__(self): '''x.__iter__() <==> iter(x)''' return iter(self.__data) def __contains__(self, value): '''x.__contains__(y) <==> y in x''' return value in self.__data class matrix(object): '''matrix(rows, columns) -> new matrix matrix(rows, columns, value) -> initialized from value''' def __init__(self, rows, columns, value=None): '''x.__init__(...) initializes x''' self.__data = array(rows) for index in range(rows): self.__data[index] = array(columns, value) def __repr__(self): '''x.__repr__() <==> repr(x)''' return repr(self.__data) def __len__(self): '''x.__len__() <==> len(x)''' return len(self.__data) def __getitem__(self, key): '''x.__getitem__(y) <==> x[y]''' return self.__data[key] def __setitem__(self, key, value): '''x.__setitem__(i, y) <==> x[i]=y''' self.__data[key] = array(len(self.__data[key]), value) def __delitem__(self, key): '''x.__delitem__(y) <==> del x[y]''' self.__data[key] = array(len(self.__data[key])) def __iter__(self): '''x.__iter__() <==> iter(x)''' return iter(self.__data) def __contains__(self, value): '''x.__contains__(y) <==> y in x''' for item in self.__data: if value in item: return True return False # Private Names # ============= def main(): print 'Content-Type: text/plain' print print file(sys.argv[0]).read() # Execute Main # ============ if __name__ == '__main__': main() ################################################################################ # Zcgi.py ################################################################################ # Name & Description # ================== '''Support module for use by CGI scripts. This module provides several functions and variables that help with printing text and accessing form data.''' # Data & Imports # ============== __all__ = ['execute', 'print_html', 'print_plain', 'print_self', 'dictionary', 'string'] __version__ = '1.2' import os import sys import types # Public Names # ============ def execute(main, exception): '''execute(function main, str exception) Execute main unless exception.''' assert_type((types.FunctionType, main), (str, exception)) if exception == string: print_self() else: main() def print_html(text): '''print_html(str text) Print text as HTML.''' assert_type((str, text)) print 'Content-Type: text/html' print print text sys.exit(0) def print_plain(text): '''print_plain(str text) Print text as plain.''' assert_type((str, text)) print 'Content-Type: text/plain' print print text sys.exit(0) def print_self(): '''print_self() Print __main__ as plain.''' print 'Content-Type: text/plain' print print file(sys.argv[0]).read() sys.exit(0) # Private Names # ============= def export(): global dictionary, string dictionary = string = None try: string = os.environ['QUERY_STRING'] temp = string.replace('+', ' ').split('&') for index in range(len(temp)): temp[index] = temp[index].split('=') dictionary = dict() for parameter, value in temp: dictionary[decode(parameter)] = decode(value) except: pass def decode(string): assert_type((str, string)) index = string.find('%') while index != -1: string = string[:index] + chr(int(string[index+1:index+3], 16)) + string[index+3:] index = string.find('%', index + 1) return string def assert_type(*tuples): for types, objects in tuples: if type(objects) is not types: raise TypeError # Execute Conditional # =================== if __name__ == '__main__': print_self() else: export()