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

📄 webpage.py

📁 python web programming 部分
💻 PY
字号:
#
# Base WebPage object
#
# $Revision: 15 $
# $Date: 8/03/01 12:59p $
#
import os
import dtuple
import cgi
import mx.DateTime
import cachequery

class dbsource:
    def __init__(self, source, type='mx'):
        self.source = source
        if type == 'mx':
            import mx.ODBC.Windows as odbc
            self.conn = odbc.connect(source, "promuser", "promuser")
        elif type == 'odbc':
            import odbc
            self.conn = odbc.odbc(source)
        elif type == 'gf':
            import gadfly
            self.conn = gadfly.gadfly(source, "gadfly")
        else:
            raise ValueError, "Illegal data source type %s" % type
        self.cursor = self.conn.cursor()

    def close(self):
        self.cursor.close()
        self.conn.close()

class FormsMixin:
        
    def DropDown(self, tbl, valcol, descol, name="pulldown",
                default="Please make a selection", selected=None, ordercol=None, autosubmit=None):

        """Create a dropdown selector from two columns of a database table.

        Note that column aliasing is used to give fixed attribute names to
        the columns retrieved, so this algorithm works with two different
        database columns or the same one for both value and description."""

        td = dtuple.TupleDescriptor([("ValCol",), ("DesCol",)])
        if autosubmit:
            auto = """OnChange="submit(this.parent)"""
        else:
            auto = ""
        result = ["""<SELECT NAME="%s" %s ">""" % (name, auto)]
        result.append(self.Option("", default))
        stmt = "SELECT %s, %s FROM %s" % (valcol, descol, tbl)
        if ordercol:
            stmt += " ORDER BY %s" % ordercol
        # print stmt
        self.cursor.execute(stmt)
        rows = self.cursor.fetchall()
        for row in rows:
            row = dtuple.DatabaseTuple(td, row)
            result.append(self.Option(row.ValCol, row.DesCol))
        result.append("</SELECT>\n")
        return "\n".join(result)

    def Option(self, val, dsc):
        return """<OPTION VALUE="%s">%s""" % (val, dsc)

class Page:
    """Object to implement common behavior. No actual look-and-feel here."""

    def __init__(self, dbsource, op, path, query):
        """Build the main page content."""
        self.dbsource = dbsource
        self.cursor = dbsource.cursor
        self.op = op
        self.path = path
        self.query = query

    def Title(self):
        return "Page requires Title() method"

    def NavBar(self):
        return "Page requires NavBar() method"
    
    def Content(self):
        return "Page requires Content() method"

    def Generate(self):
        return \
"""HTTP/1.0 200 OK Response Follows
Content-Type: text/html
Cache-Control: no-cache

<HTML>
<HEAD>
    <TITLE>%s</TITLE>
</HEAD>
<BODY>
<TABLE>
  <tr>
    <td VALIGN="TOP"><IMG SRC="/Image/py.gif"></td><td VALIGN="TOP"><H3><font color="red">Web/Database Technology Demonstrator</font></H3></td>
  </tr>
  <tr><td colspan="2"><hr></td></tr>
  <tr>
    <td valign="TOP" width="80">%s</td>
    <td valign="TOP" width="250">%s</td>
  </tr>
</TABLE>
</BODY>
""" % (self.Title(), self.NavBar(), self.Content())

#
# Global queries to optimize database access
#
q = cachequery.CacheQuery
conn = dbsource("prom2000").conn
qDepts = q("department", "DptCode DptName".split(), (), conn, ORDER=("DptName",), refresh=30)

class Home(Page):

    def Title(self):
        return "Welcome to the Database Mini-Web!"

    def NavBar(self):
        """Generate nav bar for any department page."""
        result = ["""<FONT size="-2">"""]
        for DptCode, DptName in qDepts(debug=1):
            result.append("""<A HREF="/DeptHome/%s">%s</A><BR><BR>""" % (DptCode, DptName))
        result.append("""</FONT>""")
        return "\n".join(result)

    def Content(self):
        if self.op.upper() == "GET":
            text = """<H1 color="red">There's a Database Behind this Site!</H1>
                <H3>Data source is %s</H3>
                <P>Please select a department</P>""" % self.dbsource.source
        else:
            text = "Sorry. The operation you requested is invalid."
        return text


class DeptPage(Page):

    def __init__(self, *args, **kw):
        # print "args:", args
        # print "kw:", kw
        Page.__init__(self, *args, **kw)
        DptNames = ["Code", "Name", "Welcome", "Links", "LnksTxt"]
        DptDtuple = dtuple.TupleDescriptor([ [colname, ] for colname in DptNames]) # local, could factor out?
        if len(self.path) == 0 or self.path[0] == "None":
            # XXX this is rather unsatisfactory, and needs changing
            self.DptCode = None
            self.dpt = dtuple.DatabaseTuple(DptDtuple, [ None for name in DptNames])
        else:
            #
            # XXX Because every subtype also does all this work we are
            # XXX definitely reapeating code that should not be repeated
            #
            self.DptCode = self.path[0]
            self.path = self.path[1:]   # XXX Need _shftpth() method!
            stmt = "SELECT %s FROM department WHERE DptCode=?" % ", ".join(["Dpt"+name for name in DptNames])
            # print "SQL:", stmt
            self.cursor.execute(stmt, (self.DptCode, ))
            r = self.cursor.fetchall()
            assert len(r) == 1
            self.dpt = dtuple.DatabaseTuple(DptDtuple, r[0])
            now = mx.DateTime.today()
            stmt = """SELECT DptCode, newsitem.NwsNum, NwsHead FROM newsitem, deptnews
                        WHERE DptCode=?
                        AND deptnews.NwsNum=newsitem.NwsNum
                        AND ? BETWEEN NewsItem.NwsStart AND NewsItem.NwsEnd"""
            self.cursor.execute(stmt, (self.dpt.Code, now))
            self.Nws = self.cursor.fetchall()
            stmt = """SELECT LnkURL, LnkText FROM links WHERE DptCode=?"""
            self.cursor.execute(stmt, (self.dpt.Code, ))
            self.Lnk = self.cursor.fetchall()
            stmt = """SELECT QodHook, QodQuestion, QodAlist, QodAnswer
                        FROM Qod WHERE ? BETWEEN QodDate AND QodDate+1
                        AND DptCode = ?
                        AND QodShow"""
            self.cursor.execute(stmt, (now, self.dpt.Code))
            self.Qod = self.cursor.fetchall()
        
    def Title(self):
        return "Department %s" % self.dpt.Name

    def NavBar(self):
        """Generate nav bar for any department page."""
        result = ["""<FONT size="-2">"""]
        result.append("""<A HREF="/">HOME</A><BR><BR>""")
        result.append("""<A HREF="/DeptHome/%s">Dept Home</A><BR><BR>""" % self.DptCode)
        if len(self.Nws):
            # XXX Departmental news
            result.append("""<A HREF="/DeptNews/%s">News</A><BR><BR>""" % self.dpt.Code)
        if self.dpt.LnksTxt:
            result.append("%s<BR><BR>" % self.dpt.LnksTxt)
        if len(self.Lnk):
            # XXX Departmental links page link
            result.append("""<A HREF="/DeptLinks/%s">More Links</A><BR><BR>""" % self.dpt.Code)
        if len(self.Qod):
            # Departmental question of the day
            result.append("""<B>Today's question:</B><BR><BR>
            <A HREF="/DeptQod/%s">%s ...</A><BR><BR>""" % (self.dpt.Code, self.Qod[0][0]))
        result.append("""</FONT>""")
        return "\n".join(result)

    def DeptHeader(self):
        return "<P><B>%s</B></BR><HR>" % self.dpt.Name

class DeptHome(DeptPage):

    def Content(self):
        if self.op.upper() == "GET":
            text = self.DeptHeader() + self.dpt.Welcome
        else:
            text = "Sorry. The operation you requested is invalid."
        return text


class DeptLinks(DeptPage):

    def Links(self):
        result = ["""<BR><P><FONT SIZE="-1">"""]
        for row in self.Lnk:
            result.append("""<A HREF="http://%s">%s</A><HR>""" % row)
        result.append("""</FONT></P>""")
        return "\n".join(result)

    def Content(self):
        if self.op.upper() == "GET":
            text = "%s<B>%s</B></P>%s" % (self.DeptHeader(), "Additional Links", self.Links())
        else:
            text = "Sorry. The operation you requested is invalid."
        return text


class DeptNews(DeptPage):

    def News(self):
        result = ["""<BR><P>"""]
        for row in self.Nws:
            result.append("""<A HREF="/DeptNewsItem/%s/%s">%s</A><BR><BR>""" % row)
        result.append("""<FONT></P>""")
        return "\n".join(result)

    def Content(self):
        if self.op.upper() == "GET":
            text = self.DeptHeader()+"<B>%s</B><BR>%s" % ("News", self.News())
        else:
            text = "Sorry. The operation you requested is invalid."
        return text


class DeptNewsItem(DeptPage):

    def Content(self):
        stmt = "SELECT NwsHead, NwsCopy from newsitem WHERE NwsNum=?"
        self.cursor.execute(stmt, (self.path[0], ))
        rows = self.cursor.fetchall()
        assert len(rows) == 1
        NwsHead, NwsCopy = rows[0]
        return self.DeptHeader()+"<B><I>%s</I></B><br>%s" % (NwsHead, NwsCopy)


class DeptQod(DeptPage):

    def Content(self):
        result = [self.DeptHeader(),
                    """<B><I>Question of the Day</I></B><BR><BR>%s<BR><BR>%s<BR><BR>""" %
                     self.Qod[0][1:3]]
        result.append("""<A HREF="/DeptQodAns/%s">Click for the answer</A>""" % self.dpt.Code)
        return "\n".join(result)


class DeptQodAns(DeptPage):

    def Content(self):
        return """%s<B><I>Answer of the Day</I></B><BR><BR>%s<BR><BR>""" % \
                    (self.DeptHeader(), self.Qod[0][3])


class DeptPgPage(DeptPage):

    def Content(self):
        
        self.PgpSetName = self.path[0] # XXX need insurance against short path!
        self.PtxSetNum = self.path[1]
        self.path = self.path[2:]   # XXX Need _shftpth() method?
        stmt = """SELECT PtxLinkText, PtxSetNum, PtxLink FROM PageText
                    WHERE PgpSetName=?
                    ORDER BY PtxSetNum"""
        self.cursor.execute(stmt, (self.PgpSetName, ))
        linkdata = self.cursor.fetchall()
        stmt = """SELECT PtxTitle, PtxContent FROM PageText
                    WHERE PgpSetName=?
                    AND PtxSetNum=?"""
        # print "SQL:", stmt
        self.cursor.execute(stmt, (self.PgpSetName, self.PtxSetNum))
        self.PtxTitle, self.PtxContent = self.cursor.fetchall()[0]
        # XXX should check that the page group+number actually exists
        result = [self.DeptHeader(), '<font size="-2"><center>']
        links = []
        for PtxLinkText, PtxSetNum, PtxLink in linkdata:
            if not PtxLink:
                PtxLink = "DeptPgPage"
            if PtxSetNum != self.PtxSetNum:
                links.append('<A HREF="/%s/%s/%s/%s">%s</A>' % (PtxLink, self.DptCode, self.PgpSetName, PtxSetNum, PtxLinkText))
            else:
                links.append(PtxLinkText)
        result.append(" | ".join(links)) # XXX need sensible multiline behavior here
        result.append('</center></font>')
        result.append("<BR><HR>%s" % (self.PtxContent))
        return "\n".join(result)


imgtype = {
    ".jpg": "image/jpeg",
    ".gif": "image/gif",
    ".png": "image/png"
}


class Image(Page):

#
# Note that image inherits NavBar(), etc., methods, but its
# Generate() never calls them. __init__() is all that is needed!
#
    def Generate(self):
        if self.op.upper() != "GET":
            return \
            """HTTP/1.0 405 You can't post to an image\r\n\r\n"""
        else:
            fname = self.path[-1]
            ext = os.path.splitext(fname)[1]
            if imgtype.has_key(ext):
                mimetype = imgtype[ext]
            else:
                return \
                """HTTP/1.0 415 Do not support this image type\r\n\r\n"""
            try:
                f = open(os.sep.join(["images"] + self.path), "rb")
                img = f.read()
                return \
"""HTTP/1.0 200 OK Image per request
Content-Type: %s
Content-Length: %s

%s""" % (mimetype, len(img), img)
            except IOError:
                return \
                """HTTP/1.0 404 Not found\r\n\r\n"""
            
class ErrorPage(Page):

    def Title(self):
        return "Program Error"

    def NavBar(self):
        return "LINK TO REPORT ERRORS?"

    def Content(self):
        return "<H2>Program Error:</H2><BR>%s" % self.Message()

    def Message(self):
        return "Unspecified problem"


class ErrorPageIllegalPageType(ErrorPage):

    def Message(self):
        return "Illegal page type"



#################################################################

if __name__ == "__main__":

    page = Page(dbpages.dbsource("departments", "mx"), "GET", "this/is/the/path?with=query")
    print page.DropDown("newsitem", "NwsNum", "NwsHead", name="MyDropDown")
    print page.Content("GET", ["one", "two", "three"], "Well, hello")


⌨️ 快捷键说明

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