1#!/neo/opt/bin/python
2
3import neo_cgi
4import sys, os, string
5import time
6from log import *
7
8# errors thrown...
9NoPageName = "NoPageName"
10NoDisplayMethod = "NoDisplayMethod"
11
12# errors signaled back to here
13Redirected = "Redirected"
14DisplayDone = "DisplayDone"
15DisplayError = "DisplayError"
16
17class Context:
18    def __init__ (self):
19        self.argv = sys.argv
20        self.stdin = sys.stdin
21        self.stdout = sys.stdout
22        self.stderr = sys.stderr
23        self.environ = os.environ
24
25class CSPage:
26    def __init__(self, context, pagename=0,readDefaultHDF=1,israwpage=0,**parms):
27        if pagename == 0:
28            raise NoPageName, "missing pagename"
29        self.pagename = pagename
30        self.readDefaultHDF = readDefaultHDF
31        self._israwpage = israwpage
32        self.context = context
33        self._pageparms = parms
34
35        self._error_template = None
36
37        self.page_start_time = time.time()
38        neo_cgi.cgiWrap(context.stdin, context.stdout, context.environ)
39        neo_cgi.IgnoreEmptyFormVars(1)
40        self.ncgi = neo_cgi.CGI()
41        self.ncgi.parse()
42        self._path_num = 0
43        domain = self.ncgi.hdf.getValue("CGI.ServerName","")
44        domain = self.ncgi.hdf.getValue("HTTP.Host", domain)
45        self.domain = domain
46        self.subclassinit()
47        self.setPaths([self.ncgi.hdf.getValue("CGI.DocumentRoot","")])
48
49    def subclassinit(self):
50        pass
51
52    def setPaths(self, paths):
53        for path in paths:
54            self.ncgi.hdf.setValue("hdf.loadpaths.%d" % self._path_num, path)
55            self._path_num = self._path_num + 1
56
57    def redirectUri(self,redirectTo):
58        ncgi = self.ncgi
59        if ncgi.hdf.getIntValue("Cookie.debug",0) == 1:
60            ncgi.hdf.setValue("CGI.REDIRECT_TO",redirectTo)
61            ncgi.display("dbg/redirect.cs")
62            print "<PRE>"
63            print neo_cgi.htmlEscape(ncgi.hdf.dump())
64            print "</PRE>"
65            raise DisplayDone
66
67        self.ncgi.redirectUri(redirectTo)
68        raise Redirected, "redirected To: %s" % redirectTo
69
70    ## ----------------------------------
71    ## methods to be overridden in subclass when necessary:
72
73    def setup(self):
74        pass
75
76    def display(self):
77        raise NoDisplayMethod, "no display method present in %s" % repr(self)
78
79    def main(self):
80        self.setup()
81        self.handle_actions()
82        self.display()
83
84    ## ----------------------------------
85
86    def handle_actions(self):
87        hdf = self.ncgi.hdf
88        hdfobj = hdf.getObj("Query.Action")
89        if hdfobj:
90            firstchild = hdfobj.child()
91            if firstchild:
92                action = firstchild.name()
93                if firstchild.next():
94                    raise "multiple actions present!!!"
95
96                method_name = "Action_%s" % action
97                method = getattr(self,method_name)
98                apply(method,[])
99
100    def start(self):
101        SHOULD_DISPLAY = 1
102        if self._israwpage:
103            SHOULD_DISPLAY = 0
104
105        ncgi = self.ncgi
106
107        if self.readDefaultHDF:
108            try:
109                if not self.pagename is None:
110                    ncgi.hdf.readFile("%s.hdf" % self.pagename)
111            except:
112                log("Error reading HDF file: %s.hdf" % (self.pagename))
113
114        DISPLAY_ERROR = 0
115        ERROR_MESSAGE = ""
116        # call page main function!
117        try:
118            self.main()
119        except DisplayDone:
120            SHOULD_DISPLAY = 0
121        except Redirected:
122            # catch redirect exceptions
123            SHOULD_DISPLAY = 0
124        except DisplayError, num:
125            ncgi.hdf.setValue("Query.error", str(num))
126            if self._error_template:
127                ncgi.hdf.setValue("Content", self._error_template)
128            else:
129                DISPLAY_ERROR = 1
130        except:
131            SHOULD_DISPLAY = 0
132            DISPLAY_ERROR = 1
133
134            import handle_error
135            handle_error.handleException("Display Failed!")
136            ERROR_MESSAGE = handle_error.exceptionString()
137
138        if DISPLAY_ERROR:
139            print "Content-Type: text/html\n\n"
140
141            # print the page
142
143            print "<H1> Error in Page </H1>"
144            print "A copy of this error report has been submitted to the developers. "
145            print "The details of the error report are below."
146
147
148            print "<PRE>"
149            print neo_cgi.htmlEscape(ERROR_MESSAGE)
150            print "</PRE>\n"
151            # print debug info always on page error...
152            print "<HR>\n"
153            print "<PRE>"
154            print neo_cgi.htmlEscape(ncgi.hdf.dump())
155            print "</PRE>"
156
157
158        etime = time.time() - self.page_start_time
159        ncgi.hdf.setValue("CGI.debug.execute_time","%f" % (etime))
160
161        if SHOULD_DISPLAY and self.pagename:
162            debug_output = ncgi.hdf.getIntValue("page.debug",ncgi.hdf.getIntValue("Cookie.debug",0))
163
164            # hijack the built-in debug output method...
165            if ncgi.hdf.getValue("Query.debug","") == ncgi.hdf.getValue("Config.DebugPassword","1"):
166                ncgi.hdf.setValue("Config.DebugPassword","CSPage.py DEBUG hijack (%s)" %
167                    ncgi.hdf.getValue("Config.DebugPassword",""))
168                debug_output = 1
169
170            if not debug_output:
171              ncgi.hdf.setValue("Config.CompressionEnabled","1")
172
173            # default display
174            template_name = ncgi.hdf.getValue("Content","%s.cs" % self.pagename)
175            # ncgi.hdf.setValue ("cgiout.charset", "utf-8");
176
177            try:
178                ncgi.display(template_name)
179            except:
180                print "Content-Type: text/html\n\n"
181                print "CSPage: Error occured"
182                import handle_error
183                print "<pre>" + handle_error.exceptionString() + "</pre>"
184                debug_output = 1
185
186
187            # debug output
188            if debug_output:
189                print "<HR>\n"
190                print "CSPage Debug, Execution Time: %5.3f<BR><HR>" % (etime)
191                print "<PRE>"
192                print neo_cgi.htmlEscape(ncgi.hdf.dump())
193                print "</PRE>"
194                # ncgi.hdf.setValue("hdf.DEBUG",ncgi.hdf.dump())
195                # ncgi.display("debug.cs")
196
197        script_name = ncgi.hdf.getValue("CGI.ScriptName","")
198        if script_name:
199            script_name = string.split(script_name,"/")[-1]
200
201        log ("[%s] etime/dtime: %5.3f/%5.3f %s (%s)" % (self.domain, etime, time.time() - etime - self.page_start_time,  script_name, self.pagename))
202
203    # a protected output function to catch the output errors that occur when
204    # the server is either restarted or the user pushes the stop button on the
205    # browser
206    def output(self, str):
207        try:
208            self.context.stdout.write(str)
209        except IOError, reason:
210            log("IOError: %s" % (repr(reason)))
211            raise DisplayDone
212
213
214    def allQuery (self, s):
215        l = []
216        if self.ncgi.hdf.getValue ("Query.%s.0" % s, ""):
217          obj = self.ncgi.hdf.getChild ("Query.%s" % s)
218          while obj:
219            l.append(obj.value())
220            obj = obj.next()
221        else:
222          t = self.ncgi.hdf.getValue ("Query.%s" % s, "")
223          if t: l.append(t)
224        return l
225