CSPage.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 import neo_cgi, neo_cs
4 import sys, os, string
5 import time
6 from log import *
7 
8 # errors thrown...
9 class NoPageName(Exception):
10  pass
11 class NoDisplayMethod(Exception):
12  pass
13 
14 # errors signaled back to here
15 class Redirected(Exception):
16  pass
17 class DisplayDone(Exception):
18  pass
19 class DisplayError(Exception):
20  pass
21 class MultipleActionsError(Exception):
22  pass
23 
24 class Context:
25  def __init__ (self):
26  self.argv = sys.argv
27  self.stdin = sys.stdin
28  self.stdout = sys.stdout
29  self.stderr = sys.stderr
30  self.environ = os.environ
31 
32  def setStatus(self, request, status):
33  if request:
34  request['status'] = str(status)
35 
36 
37 class CSPage:
38  _pagename = None
39 
40  def __init__(self, context, pagename=None,readDefaultHDF=1,israwpage=0,
41  parseCGI=1, makePUT=0, **parms):
42  if pagename is None: pagename = self._pagename
43  if not pagename: raise NoPageName("missing pagename")
44  self.pagename = pagename
45  self.readDefaultHDF = readDefaultHDF
46  self._israwpage = israwpage
47  self.context = context
48  self._pageparms = parms
49 
50  self._error_template = None
51 
52  self.page_start_time = time.time()
53 
54  if makePUT:
55  context.environ['REQUEST_METHOD'] = 'PUT'
56 
57  neo_cgi.cgiWrap(context.stdin, context.stdout, context.environ)
58  neo_cgi.IgnoreEmptyFormVars(1)
59  self.ncgi = neo_cgi.CGI()
60 
61  if parseCGI:
62  self.ncgi.parse()
63 
64  self._path_num = 0
65  domain = self.ncgi.hdf.getValue("CGI.ServerName","")
66  domain = self.ncgi.hdf.getValue("HTTP.Host", domain)
67  self.domain = domain
68 
69  self.setPaths([self.ncgi.hdf.getValue("CGI.DocumentRoot","")])
70 
71  self._sent_headers = 0
72  self._reply_headers = {}
73  self._reply_code = 200
74 
75  if self.ncgi.hdf.getValue("CGI.HTTPS", ""):
76  self.http = "https://"
77  else:
78  self.http = "http://"
79 
80  try:
81  self.subclassinit()
82  except:
83  SHOULD_DISPLAY = 0
84  DISPLAY_ERROR = 1
85 
86  import handle_error
87  handle_error.handleException("Display Failed!")
88  ERROR_MESSAGE = handle_error.exceptionString()
89  return
90 
91  def __setitem__(self, key, value):
92  self._reply_headers[string.lower(key)] = value
93  self.ncgi.hdf.setValue("cgiout.other.%s" % key, "%s: %s" % (key, value))
94 
95  def __getitem__(self, key):
96  return self._reply_headers[string.lower(key)]
97 
98  def has_key(self, key):
99  return self._reply_headers.has_key(string.lower(key))
100 
101  def subclassinit(self):
102  pass
103 
104  def clearPaths(self):
105  self.ncgi.hdf.removeTree("hdf.loadpaths")
106 
107  def setPaths(self, paths):
108  for path in paths:
109  self.ncgi.hdf.setValue("hdf.loadpaths.%d" % self._path_num, path)
110  self._path_num = self._path_num + 1
111 
112  def redirectUri(self,redirectTo):
113  ncgi = self.ncgi
114  if ncgi.hdf.getIntValue("Cookie.debug",0) == 1:
115  ncgi.hdf.setValue("CGI.REDIRECT_TO",redirectTo)
116 # ncgi.display("dbg/redirect.cs")
117 
118  cs = neo_cs.CS(ncgi.hdf)
119  self['Content-Type'] = "text/html"
120  template = """
121 Redirect
122 <br><br>
123 <a href="<?cs var:CGI.REDIRECT_TO ?>"><?cs var:CGI.REDIRECT_TO ?></a>
124 """
125  cs.parseStr(template)
126  page = cs.render()
127 
128  self.push(page)
129 
130  self.push("<PRE>\n")
131  self.push(neo_cgi.htmlEscape(ncgi.hdf.dump()) + "\n")
132  self.push("</PRE>\n")
133  raise DisplayDone()
134 
135  self.context.setStatus(self, 302)
136  self.ncgi.redirectUri(redirectTo)
137  raise Redirected("redirected To: %s" % redirectTo)
138 
139  ## ----------------------------------
140  ## methods to be overridden in subclass when necessary:
141 
142  def setup(self):
143  pass
144 
145  def display(self):
146  raise NoDisplayMethod("no display method present in %s" % repr(self))
147 
148  def main(self):
149  hdf = self.ncgi.hdf
150 
151  def __call(method):
152  if method.im_func.func_code.co_argcount == 2:
153  method(hdf)
154  else:
155  method()
156 
157  __call(self.setup)
158 
159  self.handle_actions()
160 
161  __call(self.display)
162 
163  ## ----------------------------------
164 
165  def handle_actions(self):
166  hdf = self.ncgi.hdf
167  #warn(hdf.writeString())
168  hdfobj = hdf.getObj("Query.Action")
169  if hdfobj:
170  firstchild = hdfobj.child()
171  if firstchild:
172  action = firstchild.name()
173  if firstchild.next():
174  raise MultipleActionsError("multiple actions present!!!")
175 
176  method_name = "Action_%s" % action
177  method = getattr(self,method_name)
178  if method.im_func.func_code.co_argcount == 2:
179  apply(method,[hdf])
180  else:
181  apply(method,[])
182 
183  def start(self):
184  SHOULD_DISPLAY = 1
185  if self._israwpage:
186  SHOULD_DISPLAY = 0
187 
188  ncgi = self.ncgi
189 
190  if self.readDefaultHDF:
191  try:
192  if not self.pagename is None:
193  ncgi.hdf.readFile("%s.hdf" % self.pagename)
194  except:
195  debug("Error reading HDF file: %s.hdf" % (self.pagename))
196 
197  DISPLAY_ERROR = 0
198  ERROR_MESSAGE = ""
199  # call page main function!
200  try:
201  self.main()
202  except DisplayDone:
203  SHOULD_DISPLAY = 0
204  except Redirected:
205  # catch redirect exceptions
206  SHOULD_DISPLAY = 0
207  except DisplayError, num:
208  ncgi.hdf.setValue("Query.error", str(num))
209  if self._error_template:
210  ncgi.hdf.setValue("Content", self._error_template)
211  else:
212  DISPLAY_ERROR = 1
213  except:
214  SHOULD_DISPLAY = 0
215  DISPLAY_ERROR = 1
216 
217  import handle_error
218  handle_error.handleException("Display Failed!")
219  ERROR_MESSAGE = handle_error.exceptionString()
220 
221  if DISPLAY_ERROR:
222  #print "Content-Type: text/html\n\n"
223 
224  # print the page
225 
226  self['Content-Type'] = "text/html"
227 
228  # print the page
229  self.push("<head>")
230  self.push('''
231 <script type="text/javascript">
232 function toggleDebugInfo() {
233  var tb = document.getElementById('%s');
234  if (tb == null) return;
235  tb.style.display = tb.style.display ? '' : 'none';
236 }
237 </script>
238 <style type="text/css">
239 .cgitb {background: #E6EAF0; border: 1px solid #4D6180; direction: ltr;}
240 .cgitb p {margin: 0.5em 0; padding: 5px 10px; text-align: left;}
241 .cgitb ol {margin: 0}
242 .cgitb li {margin: 0.25em 0;}
243 .cgitb h1, .cgitb h2, .cgitb h3 {padding: 5px 10px; margin: 0; background: #4D6180; color: white;}
244 .cgitb h1 {font-size: 1.3em;}
245 .cgitb h2 {font-size: 1em; margin-top: 1em;}
246 .cgitb h3 {font-size: 1em;}
247 .cgitb .frames {margin: 0; padding: 0; color: #606060}
248 .cgitb .frames li {display: block;}
249 .cgitb .call {padding: 5px 10px; background: #A3B4CC; color: black}
250 .cgitb .context {padding: 0; font-family: monospace; }
251 .cgitb .context li {display: block; white-space: pre;}
252 .cgitb .context li.highlight {background: #C0D3F0; color: black}
253 .cgitb .variables {padding: 5px 10px; font-family: monospace;}
254 .cgitb .variables li {display: inline;}
255 .cgitb .variables li:after {content: ", ";}
256 .cgitb .variables li:last-child:after {content: "";}
257 .cgitb .exception {border: 1px solid #4D6180; margin: 10px}
258 .cgitb .exception h3 {background: #4D6180; color: white;}
259 .cgitb .exception p {color: black;}
260 .cgitb .exception ul {padding: 0 10px; font-family: monospace;}
261 .cgitb .exception li {display: block;}
262 
263 .cgitb .buttons {margin: 0.5em 0; padding: 5px 10px;}
264 .cgitb .buttons li {display: inline; margin: 0; padding: 0 0.25em;}
265 </style>
266 ''')
267 
268  self.push("</head>")
269 
270  self.push("<H1> Error in Page </H1>\n")
271  self.push("A copy of this error report has been submitted to the developers. ")
272  self.push("The details of the error report are below.")
273 
274  self.push(handle_error.exceptionString())
275 
276  # print debug info always on page error...
277  self.push("<HR>\n")
278  self.push("<PRE>")
279  self.push(neo_cgi.htmlEscape(ncgi.hdf.dump()))
280  self.push("</PRE>")
281 
282 
283  etime = time.time() - self.page_start_time
284  ncgi.hdf.setValue("CGI.debug.execute_time","%f" % (etime))
285  #warn("excute_time", etime)
286 
287  if SHOULD_DISPLAY and self.pagename:
288  debug_output = ncgi.hdf.getIntValue("page.debug",ncgi.hdf.getIntValue("Cookie.debug",0))
289 
290  # hijack the built-in debug output method...
291  if ncgi.hdf.getValue("Query.debug","") == ncgi.hdf.getValue("Config.DebugPassword","1"):
292  ncgi.hdf.setValue("Config.DebugPassword","CSPage.py DEBUG hijack (%s)" %
293  ncgi.hdf.getValue("Config.DebugPassword",""))
294  debug_output = 1
295 
296  if not debug_output:
297  ncgi.hdf.setValue("Config.CompressionEnabled","1")
298  else:
299  ncgi.hdf.setValue("Config.CompressionEnabled","0")
300 
301  # default display
302  template_name = ncgi.hdf.getValue("Content","%s.cs" % self.pagename)
303  # ncgi.hdf.setValue ("cgiout.charset", "utf-8");
304 
305  try:
306  self.context.setStatus(self, 200)
307  ncgi.display(template_name)
308  self._sent_headers = 1
309  except:
310  self['Content-Type'] = 'text/html'
311  self.push("CSPage: Error occured\n")
312  import handle_error
313  self.push("<pre>" + handle_error.exceptionString() + "</pre>")
314  debug_output = 1
315 
316 
317  # debug output
318  if debug_output:
319  self.push("<HR>\n")
320  self.push("Execution Time: %5.3f<BR><HR>" % (etime))
321  self.push("<PRE>")
322  self.push(neo_cgi.htmlEscape(ncgi.hdf.dump()))
323  self.push("</PRE>")
324  # ncgi.hdf.setValue("hdf.DEBUG",ncgi.hdf.dump())
325  # ncgi.display("debug.cs")
326 
327  script_name = ncgi.hdf.getValue("CGI.ScriptName","")
328  if script_name:
329  script_name = string.split(script_name,"/")[-1]
330 
331  log ("[%s] etime/dtime: %5.3f/%5.3f %s (%s)" % (self.domain, etime, time.time() - etime - self.page_start_time, script_name, self.pagename))
332  return self._reply_code
333 
334  # a protected output function to catch the output errors that occur when
335  # the server is either restarted or the user pushes the stop button on the
336  # browser
337  def output(self, str):
338  try:
339  if len(str) > 8196:
340  import cStringIO
341  fp = cStringIO.StringIO(str)
342  while 1:
343  data = fp.read(8196*8)
344  if not data: break
345  self.context.stdout.write(data)
346  else:
347  self.context.stdout.write(str)
348  except IOError, reason:
349  log("IOError: %s" % (repr(reason)))
350  raise DisplayDone()
351 
352  def done(self):
353  if not self._sent_headers: self.error(500)
354  self._sent_headers = 0
355 
356  raise DisplayDone()
357 
358  def push(self, data):
359  if not self._sent_headers:
360  headerdata = self.send_headers(dont_send=1)
361  self.output(headerdata + data)
362  else:
363  self.output(data)
364 
365 
366  def send_headers(self, dont_send=0):
367  self._sent_headers = 1
368 
369  message = gHTTPResponses[self._reply_code]
370 
371  if self._reply_code != 200:
372  #self['status'] = "%s %s" % (self._reply_code, message)
373  #self.context.setStatus(self, self._reply_code)
374  pass
375  self.context.setStatus(self, self._reply_code)
376  self['connection'] = 'close'
377 
378  headers = []
379  #headers.append(self.response(self._reply_code))
380  for (key, value) in self._reply_headers.items():
381  headers.append('%s: %s' % (key, value))
382  headers.append('\r\n')
383 
384  if dont_send == 0:
385  self.push(string.join(headers, '\r\n'))
386  else:
387  return string.join(headers, '\r\n')
388 
389 
390  def allQuery (self, s):
391  l = []
392  if self.ncgi.hdf.getValue ("Query.%s.0" % s, ""):
393  obj = self.ncgi.hdf.getChild ("Query.%s" % s)
394  while obj:
395  l.append(obj.value())
396  obj = obj.next()
397  else:
398  t = self.ncgi.hdf.getValue ("Query.%s" % s, "")
399  if t: l.append(t)
400  return l
401 
402 
403  def error(self, code, reason=None):
404  self._reply_code = code
405  message = gHTTPResponses[code]
406  s = DEFAULT_ERROR_MESSAGE % {
407  'code': code, 'message': message, 'reason': reason
408  }
409 
410 # self['Content-Length'] = len(s)
411 # self['Content-Type'] = 'text/html'
412 
413 # self.push(s)
414  self.context.stdout.write("Content-Type: text/html\n")
415  self.context.setStatus(self, code)
416  self.context.stdout.write("Status: %s\n" % code)
417  self.context.stdout.write(s)
418 # self.done()
419 
420  raise DisplayDone()
421 
422 
423 
424 gHTTPResponses = {
425  100: "Continue",
426  101: "Switching Protocols",
427  200: "OK",
428  201: "Created",
429  202: "Accepted",
430  203: "Non-Authoritative Information",
431  204: "No Content",
432  205: "Reset Content",
433  206: "Partial Content",
434  300: "Multiple Choices",
435  301: "Moved Permanently",
436  302: "Moved Temporarily",
437  303: "See Other",
438  304: "Not Modified",
439  305: "Use Proxy",
440  400: "Bad Request",
441  401: "Unauthorized",
442  402: "Payment Required",
443  403: "Forbidden",
444  404: "Not Found",
445  405: "Method Not Allowed",
446  406: "Not Acceptable",
447  407: "Proxy Authentication Required",
448  408: "Request Time-out",
449  409: "Conflict",
450  410: "Gone",
451  411: "Length Required",
452  412: "Precondition Failed",
453  413: "Request Entity Too Large",
454  414: "Request-URI Too Large",
455  415: "Unsupported Media Type",
456  500: "Internal Server Error",
457  501: "Not Implemented",
458  502: "Bad Gateway",
459  503: "Service Unavailable",
460  504: "Gateway Time-out",
461  505: "HTTP Version not supported"
462  }
463 
464 # Default error message
465 DEFAULT_ERROR_MESSAGE = string.join(
466  ['',
467  '<head>',
468  '<title>%(code)d %(message)s</title>',
469  '</head>',
470  '<body>',
471  '<h1>%(message)s</h1>',
472  '<p>Error code %(code)d.',
473  '<p>Message: %(message)s.',
474  '<p>Reason:\n <pre>%(reason)s</pre>',
475  '</body>',
476  ''
477  ],
478  '\r\n'
479  )
def __setitem__(self, key, value)
Definition: CSPage.py:91
def send_headers(self, dont_send=0)
Definition: CSPage.py:366
def error(self, code, reason=None)
Definition: CSPage.py:403
def __getitem__(self, key)
Definition: CSPage.py:95
def redirectUri(self, redirectTo)
Definition: CSPage.py:112
def push(self, data)
Definition: CSPage.py:358
def log(args)
Definition: log.py:107
def setup(self)
methods to be overridden in subclass when necessary:
Definition: CSPage.py:142
def setPaths(self, paths)
Definition: CSPage.py:107
def handle_actions(self)
Definition: CSPage.py:165
def allQuery(self, s)
Definition: CSPage.py:390
def __init__(self, context, pagename=None, readDefaultHDF=1, israwpage=0, parseCGI=1, makePUT=0, parms)
Definition: CSPage.py:41
def has_key(self, key)
Definition: CSPage.py:98
def setStatus(self, request, status)
Definition: CSPage.py:32
def output(self, str)
Definition: CSPage.py:337
def debug(args)
Definition: log.py:116


pyclearsilver
Author(s): Scott Noob Hassan
autogenerated on Mon Jun 10 2019 15:51:13