⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 web.py

📁 python web programming 部分
💻 PY
字号:
#! python
#
# $Workfile: Web.py $ $Revision: 18 $
# $Date: 10/07/01 1:50p $ $Author: Sholden $
#
import os, base64
import cgi
import mx.DateTime as mxdt
import mx.DateTime.ARPA as arpa
import Cookie
import Params
from dtuple import TupleDescriptor, DatabaseTuple
from dbsource import dbsource
import pyforms
from cachequery import CacheQuery
from Error import Error

try:
    pageformat = open("index.htm", "r").read()
except:
    import sys
    sys.exit("Cannot read 'index.htm'")

conn = dbsource().conn
cursor = conn.cursor()
StdNames = ["StdEmail", "StdFirstName", "StdLastName", "StdPhone",
            "StdPasswd", "StdAddress", "StdCity", "StdState", "StdPostCode"]
qStud = CacheQuery("Student", StdNames, ("StdEmail", ), conn)


class Page:
    """Implement common page behavior, with basic look-and-feel.

    This is the ultimate ancestor class for all pages."""

    def __init__(self, op, path, query, session, headers,
                 oHeaders=None, Realm=None, Initpath=""):
        """Build the page to prepare for content generation."""
        self.op = op
        self.path = path
        self.query = query
        self.session = session
        self.headers = headers
        self.oheaders = oHeaders or  []
        self.realm = Realm
        self.initpath = Initpath or []
        self.message = "OK Content Follows"
        self.returncode = 200
        self.mimetype = "text/html"

    def Generate(self, Input=None):
        self.input = Input
        try:
            self.Authenticate()
            return self.HTTP(self.Content())
        except Error, error:
            self.returncode, self.message, self.realm, \
                self.oheaders, self.errmsg, self.errcontent = error()
            self.mimetype = "text/html"
            return self.HTTP(self.Content())

    def Authenticate(self):
        realm = self.Realm()
        if not realm:           # no authentication required
            return
        else:                   # verify authentication
            try:
                passwd = self.session._auth[realm]["password"]
                # Already authenticated for the realm
                return
            except KeyError:
                # Check authentication credentials in HTTP headers
                auth = self.headers.getheader("authorization")
                if auth:
                    auth = auth.split()
                    if auth[0].lower() == "basic": # username:password
                        auth = base64.decodestring(auth[1]).split(":")
                        self.session._auth[realm] = {"email": auth[0].lower()}
                        # Retrieve authentication data from realm table
                        a = Params.RealmAuth.get(realm, None)
                        if a: # Always fail if no data for the realm
                            stmt ="SELECT %s FROM %s WHERE %s = ?" % (a[2], a[0], a[1])
                            cursor.execute(stmt, (auth[0].lower(), ))
                            pw = cursor.fetchall()
                            if pw and pw[0][0].lower()  == auth[1].lower():
                                self.session._auth[realm]["password"] = pw[0][0]
                                # This realm is authenticated for the first time
                                if realm == "PythonTeach":
                                    self.session._udata = qStud(auth[0])[0]
                                return
            # No credential is present for this realm, so we require
            # authentication. If the browser stops trying, the content
            # we return instead of the page offers the password via
            # email. Email is only sent to users in the database!
            raise Error(401, "Authentication required", realm,
                        oheaders=['WWW-Authenticate: Basic realm="%s"' % realm],
                        errmsg="""Authentication Required<BR><BR>
                        Would you like an <BR>
                        <A HREF="/MailPass/%s/"> email password reminder</A>?<BR><BR>
                        Or do you want to <BR>
                        <A HREF="/NewAccount/%s/">open a new account</A>?
                        """ % (realm, realm))

    def Content(self):
        """Return content when authentication not required or known good.

        If error occurred, generate standard or abbreviated page depending
        on whether the error overrode the errcontent argument."""
        if self.returncode == 200:
            return pageformat % (self.Title(), self.session._id, self.NavBar(), self.Body())
        elif self.errcontent is None:
            return pageformat % (self.Title(), self.session._id, self.NavBar(), self.ErrMsg())
        else:
            return self.errcontent


    def HTTP(self, content):
        return \
"""HTTP/1.0 %d %s
Content-Type: %s
Content-Length: %d
Date: %s
%s
%s
%s""" % (self.ReturnCode(), self.Message(), self.MIMEtype(), len(content),
            arpa.str(mxdt.now()),  self.Cookie(), self.Headers(), content)

    def ErrMsg(self):
        return """<FONT SIZE="+1" COLOR="RED"><B>Error Response<BR></FONT>
                    <FONT SIZE="+1" COLOR="RED">%d <I>%s</I></B></FONT>""" % \
                                (self.ReturnCode(), self.errmsg)

    def Body(self):
        return "Error: Web.Page subclass %s requires Body() method" % str(self.__class__)

    def Cookie(self):
        cookie = Cookie.SimpleCookie()
        cookie["session"] = "%s:%d" % (self.session._id, id(self.session))
        cookie["session"]["path"] = "/"
        #cookie["session"]["expires"] = "31 Dec 2002" # Seems to make it permanent
        return str(cookie)

    def Message(self):
        return self.message

    def MIMEtype(self):
        return self.mimetype

    def NavBar(self, Home=0):
        try:
            name = "%s %s<BR>" % (self.session._udata.StdFirstName,
                                    self.session._udata.StdLastName)
        except AttributeError:
            name = ""
        if self.session._bookings:
            checkout = """<A HREF="/CourseViewCart/">Shopping Cart</A><BR>"""
        else:
            checkout = ""
        return """
                <table border="0" cellpadding="0" cellspacing="0" width="158">
                  <tr>
                    <td width="10" valign="top">
                    <img src="/images/spacer.gif" width="10" height="5" border="0"></td>
                    <td class="navtext" width="148">
                    <img src="/images/spacer.gif" width="5" height="5" border="0"><br>
<b>%s%s</b></td>
                  </tr>
                </table>
%s
%s
%s
%s
""" % (name, checkout, self.NavSection("/", "home"),
        self.NavSection("/DeptStart/", "departments", self.DeptNav()),
        self.NavSection("/CourseStart/", "courses", self.CourseNav()),
        self.NavSection("/Auth/Usrs/", "PythonTeach", self.PTNav()))

    def NavLink(self, p):
        return """
		<a href="%s">%s</a><br>
		<img alt="" src="/images/spacer.gif" width="5" height="2" border="0"><br>""" % p

    def NavSection(self, link, graphic, extra=""):
        return """
    <a href="%s"><img src="/images/%s.gif" width="158" height="22" border="0"></a><br>
    <table border="0" cellpadding="0" cellspacing="0" width="158">
      <tr>
        <td width="10" valign="top">
        <img src="/images/spacer.gif" width="10" height="10" border="0"></td>
        <td class="navtext" width="148">
        %s<img src="/images/spacer.gif" width="5" height="5" border="0"><br>
</td>
     </tr>
    </table>
""" % (link, graphic, extra)

    def DeptNav(self):
        return ""

    def CourseNav(self):
        return ""

    def PTNav(self):
        return ""

    def Headers(self):
        if self.oheaders:
            return "\n".join(self.oheaders)+"\n"
        else:
            return "\n"

    def Realm(self):
        """Return the authentication realm, if any."""
        return self.realm

    def ReturnCode(self):
        return self.returncode

    def Title(self):
        return "Error: Web.Page subclass %s requires Title() method" % str(self.__class__)

    def ChkReqd(self, FD, udata):
        """Return list of errors concerning required fields."""
        errors = []
        # Verify that required fields are present
        for field in FD:
            field = DatabaseTuple(pyforms.Descriptor(), field)
            if "R" in field.Options:
                if not udata[field.FieldName]:
                    errors.append("%s is required" % field.Description)
        # Verify that passwords in the form agree
        if udata.StdPasswd != self.input["StdPasswd+"]:
            errors.append("Passwords did not agree")
        return errors

    def getValidForm(self):
        try:
            FD = self.session._fd
            if not FD:
                raise AttributeError    # session timeout?
            if self.session._secureform:
                # raise AttributeError if FD is not same as form._Flist_
                if str(id(FD)) != self.input["_Flist_"]:
                    # print "Form ID mismatch!!!!!"
                    raise AttributeError
                self.session._fd = None # can only ask this question once!
        except (AttributeError, KeyError):
            raise Error(400, "Bad Request",
                        errmsg="""Non-matching form ID<BR>
                        <FONT SIZE="-1">
                        Form identity not recognized.
                        </FONT><BR>We log all potential
                        abuse to safeguard member privacy.
                        """)
        return FD

def test():
    import rfc822, StringIO, Session
    h = rfc822.Message(StringIO.StringIO(""))
    s = Session.Session(1)
    p = Page("GET", ["one", "two"], {}, s, h, Realm="staff")
    print ":::::401 Error:::::\n", p.Generate(), "=================================="
    p = Page("GET", ["one", "two"], {}, s, h, Realm=None)
    print ":::::200 Page:::::\n", p.Generate(), "=================================="
    ha = rfc822.Message(StringIO.StringIO("Authorization: Basic c3RldmU6ZGFwcGxl\n\n"))
    p = Page("GET", ["one", "two"], {}, s, ha, Realm="Staff")
    print ":::::Good authentication:::::\n", p.Generate(), "=================================="
    
if __name__ == "__main__":
    import rfc822, StringIO, Session
    h = rfc822.Message(StringIO.StringIO(""))
    s = Session.Session(1)
    p = Page("GET", ["one", "two"], {}, s, h, Realm="staff")
    print p.NavBar()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -