Mercurial > hg > rlgallery-misc
comparison web/archive.cgi @ 0:5ba2123d2c20
Put this project under version control, finally.
Scripts for rlgallery.org, using a PostgreSQL backend. The recorder
system is in py/, CGI scripts are in web/.
author | John "Elwin" Edwards <elwin@sdf.org> |
---|---|
date | Wed, 25 Jul 2012 21:59:42 -0700 |
parents | |
children | 8f49df4074d7 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:5ba2123d2c20 |
---|---|
1 #!/usr/bin/python | |
2 | |
3 import cgi | |
4 import os | |
5 import sys | |
6 import re | |
7 import time | |
8 import calendar | |
9 import rlgalldb as rlgall | |
10 import cgitb | |
11 | |
12 cgitb.enable() | |
13 | |
14 infop = """<p>Looking for ttyrec files? Don't like digging through Web directory listings, converting time zones in your head, or guessing how many files | |
15 the game was spread across? The Archivist can find them all for you.</p> | |
16 """ | |
17 | |
18 ttyrecbase = "/var/dgl/dgldir/ttyrec/" | |
19 recre = r"(\d{4,4})-(\d{2,2})-(\d{2,2})\.(\d{2,2}):(\d{2,2}):(\d{2,2})\.ttyrec" | |
20 recrec = re.compile(recre) | |
21 | |
22 def name_in_time(filename, timerange): | |
23 "Checks whether filename is a ttyrec with time between Unix times \ | |
24 timerange[0] and timerange[1]." | |
25 nmatch = recrec.match(filename) | |
26 if not nmatch: | |
27 return False | |
28 ntime = calendar.timegm([int(val) for val in nmatch.groups()]) | |
29 if ntime > timerange[0] and ntime <= timerange[1]: | |
30 return True | |
31 else: | |
32 return False | |
33 | |
34 def input_game(outf, selected=None): | |
35 "Prints the form components for selecting a game." | |
36 selstr = '<option label="{0}" value="{1}" selected="selected">{0}</option>\n' | |
37 unselstr = '<option label="{0}" value="{1}">{0}</option>\n' | |
38 outf.write('<div>Dungeon name: <select name="game">\n') | |
39 for game in rlgall.gamelist: | |
40 # This will cause trouble if someone puts games with identical names | |
41 # into rlgall. | |
42 if selected and selected == game.uname: | |
43 outf.write(selstr.format(game.name, game.uname)) | |
44 else: | |
45 outf.write(unselstr.format(game.name, game.uname)) | |
46 outf.write('</select></div>\n') | |
47 return | |
48 | |
49 def input_name(outf, defaultval=None): | |
50 defstr = '<div>Adventurer\'s name: <input type="text" name="name" value="{0}"></div>\n' | |
51 if defaultval: | |
52 outf.write(defstr.format(defaultval)) | |
53 else: | |
54 outf.write('<div>Adventurer\'s Name: <input type="text" name="name"></div>\n') | |
55 return | |
56 | |
57 def input_time(outf, defaultval=None): | |
58 defstr = '<div>Time: <input type="text" name="time" value="{0}"></div>\n' | |
59 if defaultval: | |
60 outf.write(defstr.format(defaultval)) | |
61 else: | |
62 outf.write('<div>Time: <input type="text" name="time"></div>\n') | |
63 return | |
64 | |
65 def input_datetime(outf, dvals=[None, None, None, None, None, None]): | |
66 optstr = '<option value="{0}" label="{1}">{1}</option>\n' | |
67 soptstr = '<option value="{0}" label="{1}" selected="selected">{1}</option>\n' | |
68 tf = '<input type="text" size="2" maxlength="2" name="{0}" value="{1:02}">' | |
69 emptf = '<input type="text" size="2" maxlength="2" name="{0}">' | |
70 sstr = '<div>Date: <select name="year">\n' | |
71 # Default to today | |
72 now = time.gmtime() | |
73 for dindex in range(3): | |
74 if not dvals[dindex]: | |
75 dvals[dindex] = now[dindex] | |
76 for year in range(2010, now[0] + 1): | |
77 if year == dvals[0]: | |
78 sstr += soptstr.format(year, year) | |
79 else: | |
80 sstr += optstr.format(year, year) | |
81 sstr += '</select>\n' | |
82 outf.write(sstr) | |
83 sstr = '<select name="month">\n' | |
84 for month in range(1, 13): | |
85 if month == dvals[1]: | |
86 sstr += soptstr.format(month, calendar.month_name[month]) | |
87 else: | |
88 sstr += optstr.format(month, calendar.month_name[month]) | |
89 sstr += '</select>\n' | |
90 outf.write(sstr) | |
91 sstr = '<select name="day">\n' | |
92 for day in range(1, 32): | |
93 if day == dvals[2]: | |
94 sstr += soptstr.format(day, day) | |
95 else: | |
96 sstr += optstr.format(day, day) | |
97 sstr += '</select></div>\n' | |
98 outf.write(sstr) | |
99 sstr = '<div>Approximate time: ' | |
100 if dvals[3] != None: | |
101 sstr += tf.format("hour", dvals[3]) | |
102 else: | |
103 sstr += emptf.format("hour") | |
104 sstr += " : " | |
105 if dvals[4] != None: | |
106 sstr += tf.format("minute", dvals[4]) | |
107 else: | |
108 sstr += emptf.format("minute") | |
109 sstr += " : " | |
110 if dvals[5] != None: | |
111 sstr += tf.format("second", dvals[5]) | |
112 else: | |
113 sstr += emptf.format("second") | |
114 sstr += ' (optional)</div>\n' | |
115 outf.write(sstr) | |
116 return | |
117 | |
118 def checkempty(cgidata): | |
119 exkeys = set(cgidata.keys()) | |
120 wanted = set(["name", "game", "time", "year", "month", "day", "hour", | |
121 "minute", "second"]) | |
122 return wanted.isdisjoint(exkeys) | |
123 | |
124 def processname(fdata, errlist): | |
125 "Takes a CGI data object, extracts the player name, checks its validity, \ | |
126 and returns it. If errors are encountered, they are appended to errlist." | |
127 cantfind = "I have no record of an adventurer called {0}." | |
128 if "name" not in fdata: | |
129 errlist.append("You didn\'t tell me the adventurer\'s name.") | |
130 return None | |
131 # Just in case someone supplies something nasty, make sure they can't go | |
132 # digging all over the filesystem. | |
133 formname = fdata.getfirst("name").rpartition("/")[2] | |
134 try: | |
135 os.stat(ttyrecbase + formname) | |
136 except OSError: | |
137 errlist.append(cantfind.format(cgi.escape(formname))) | |
138 return None | |
139 return formname | |
140 | |
141 def processgame(fdata, errlist): | |
142 "Takes a CGI data object and returns the game from rlgall.gamelist that \ | |
143 it asks for. Errors appended to errlist." | |
144 cantfind = "I've never heard of a dungeon called {0}." | |
145 if "game" not in fdata: | |
146 errlist.append('You didn\'t choose a dungeon.') | |
147 return None | |
148 formgame = fdata.getfirst("game") | |
149 for agame in rlgall.gamelist: | |
150 if agame.uname == formgame: | |
151 return agame | |
152 errlist.append(cantfind.format(cgi.escape(formgame))) | |
153 return None | |
154 | |
155 def processtime(fdata, errlist, hlist): | |
156 "Takes a CGI data object and converts to a Unix timestamp by finding fields \ | |
157 called year, month, etc. Any errors get appended to errlist. hlist \ | |
158 should contain 6 components, for ymd-hms fields." | |
159 | |
160 # Timestamp overrides human-readable, even if it's invalid. | |
161 badtime = 'The time field is for Unix clocks, which never say anything \ | |
162 like {0}. Try the form instead.' | |
163 utime = None | |
164 formtime = fdata.getfirst("time") | |
165 if formtime: | |
166 try: | |
167 utime = int(formtime) | |
168 except ValueError: | |
169 errlist.append(badtime.format(cgi.escape(formtime))) | |
170 return None | |
171 else: | |
172 if utime < 0: | |
173 utime = 0 | |
174 if utime != None: | |
175 chtime = time.gmtime(utime) | |
176 for i in range(6): | |
177 hlist[i] = chtime[i] | |
178 return utime | |
179 | |
180 # Now try to get a human-readable specification. | |
181 lerrors = [] | |
182 year = month = day = hour = minute = second = None | |
183 fyear = fdata.getfirst("year") | |
184 if not fyear: | |
185 lerrors.append("No year was provided.") | |