.
[HamExam.git] / interface.py
blobc2cee33a7ae6d0a2b680625debf6bbc40d1f3463
1 #!/usr/bin/python
2 import string,cgi,time
3 from os import curdir, sep
4 from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
5 import posixpath, urllib, os
7 import questions, statistic
9 class MyHandler(BaseHTTPRequestHandler):
10 def do_GET(self):
11 if self.path.endswith(".afu"):
12 self.Good()
13 else:
14 f = self.send_head()
15 if f:
16 self.copyfile(f, self.wfile)
17 f.close()
19 def do_HEAD(self):
20 """Serve a HEAD request."""
21 f = self.send_head()
22 if f:
23 f.close()
25 def send_head(self):
26 """Common code for GET and HEAD commands.
28 This sends the response code and MIME headers.
30 Return value is either a file object (which has to be copied
31 to the outputfile by the caller unless the command was HEAD,
32 and must be closed by the caller under all circumstances), or
33 None, in which case the caller has nothing further to do.
35 """
36 path = self.translate_path(self.path)
37 if os.path.isdir(path):
38 self.send_error(403, "Directory listing not supported")
39 return None
40 try:
41 f = open(path, 'rb')
42 except IOError:
43 self.send_error(404, "File not found")
44 return None
45 self.send_response(200)
46 self.send_header("Content-type", self.guess_type(path))
47 self.end_headers()
48 return f
50 def translate_path(self, path):
51 """Translate a /-separated PATH to the local filename syntax.
53 Components that mean special things to the local file system
54 (e.g. drive or directory names) are ignored. (XXX They should
55 probably be diagnosed.)
57 """
58 path = posixpath.normpath(urllib.unquote(path))
59 words = string.splitfields(path, '/')
60 words = filter(None, words)
61 path = os.getcwd()
62 for word in words:
63 drive, word = os.path.splitdrive(word)
64 head, word = os.path.split(word)
65 if word in (os.curdir, os.pardir): continue
66 path = os.path.join(path, word)
67 return path
69 def copyfile(self, source, outputfile):
70 """Copy all data between two file objects.
72 The SOURCE argument is a file object open for reading
73 (or anything with a read() method) and the DESTINATION
74 argument is a file object open for writing (or
75 anything with a write() method).
77 The only reason for overriding this would be to change
78 the block size or perhaps to replace newlines by CRLF
79 -- note however that this the default server uses this
80 to copy binary data as well.
82 """
84 BLOCKSIZE = 8192
85 while 1:
86 data = source.read(BLOCKSIZE)
87 if not data: break
88 outputfile.write(data)
90 def guess_type(self, path):
91 """Guess the type of a file.
93 Argument is a PATH (a filename).
95 Return value is a string of the form type/subtype,
96 usable for a MIME Content-type header.
98 The default implementation looks the file's extension
99 up in the table self.extensions_map, using text/plain
100 as a default; however it would be permissible (if
101 slow) to look inside the data to make a better guess.
105 base, ext = posixpath.splitext(path)
106 if self.extensions_map.has_key(ext):
107 return self.extensions_map[ext]
108 ext = string.lower(ext)
109 if self.extensions_map.has_key(ext):
110 return self.extensions_map[ext]
111 else:
112 return self.extensions_map['']
114 extensions_map = {
115 '': 'text/plain', # Default, *must* be present
116 '.html': 'text/html',
117 '.htm': 'text/html',
118 '.gif': 'image/gif',
119 '.jpg': 'image/jpeg',
120 '.jpeg': 'image/jpeg',
125 def Good(self):
126 self.send_response(200)
127 self.send_header('Content-type', 'text/html')
128 self.end_headers()
129 self.wfile.write("<html><head><base href=\"http://127.0.0.1:8080/Questions/\"></head><body>")
131 q.AskQuestion("TB305")
133 self.wfile.write("<div class=question>")
134 self.wfile.write(q.question)
135 self.wfile.write("</div>")
137 self.wfile.write("<form name=abc action=\"http://127.0.0.1:8080\" method=get><div class=answer><input type=hidden name=ANSWER/>")
138 self.wfile.write("<a href=\"javascript:document.gtd.ACTION.value='a';document.gtd.submit();\" class=button>A</a>"+q.answera+"<br>")
139 self.wfile.write("<a href=\"javascript:document.gtd.ACTION.value='b';document.gtd.submit();\" class=button>B</a>"+q.answerb+"<br>")
140 self.wfile.write("<a href=\"javascript:document.gtd.ACTION.value='c';document.gtd.submit();\" class=button>C</a>"+q.answerc+"<br>")
141 self.wfile.write("<a href=\"javascript:document.gtd.ACTION.value='d';document.gtd.submit();\" class=button>D</a>"+q.answerd+"<br>")
142 self.wfile.write("</div></form>")
144 self.wfile.write("</body></html>")
148 def do_POST(self):
149 global rootnode
150 ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
151 if ctype == 'multipart/form-data':
152 query=cgi.parse_multipart(self.rfile, pdict)
153 self.send_response(301)
155 self.end_headers()
156 upfilecontent = query.get('upfile')
157 print "filecontent", upfilecontent[0]
158 self.wfile.write("<HTML>POST OK.<BR><BR>");
159 self.wfile.write(upfilecontent[0]);
161 def main():
162 try:
163 global q
164 q = questions.Questions()
165 server = HTTPServer(('', 8080), MyHandler)
166 print 'started httpserver...'
167 server.serve_forever()
168 except KeyboardInterrupt:
169 print '^C received, shutting down server'
170 server.socket.close()
172 if __name__ == '__main__':
173 main()