mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
First pass at default landing page for WebRequestDispatcher
This commit is contained in:
parent
ed233ec891
commit
8c5a903620
86
direct/src/http/LandingPage.py
Executable file
86
direct/src/http/LandingPage.py
Executable file
@ -0,0 +1,86 @@
|
|||||||
|
import LandingPageHTML
|
||||||
|
|
||||||
|
class LandingPage:
|
||||||
|
def __init__(self):
|
||||||
|
self.headerTemplate = LandingPageHTML.header
|
||||||
|
self.footerTemplate = LandingPageHTML.footer
|
||||||
|
|
||||||
|
self.title = LandingPageHTML.title
|
||||||
|
self.contactInfo = LandingPageHTML.contactInfo
|
||||||
|
|
||||||
|
self.menu = {}
|
||||||
|
|
||||||
|
def addTab(self, title, uri):
|
||||||
|
self.menu[title] = uri
|
||||||
|
|
||||||
|
def getMenu(self, activeTab):
|
||||||
|
tabList = self.menu.keys()
|
||||||
|
if "Main" in tabList:
|
||||||
|
tabList.remove("Main")
|
||||||
|
|
||||||
|
tabList.sort()
|
||||||
|
if "Main" in self.menu.keys():
|
||||||
|
tabList.insert(0, "Main")
|
||||||
|
|
||||||
|
s = ""
|
||||||
|
tabNum = 0
|
||||||
|
|
||||||
|
for tab in tabList:
|
||||||
|
if tabNum == 0:
|
||||||
|
if tab == activeTab:
|
||||||
|
s += "<li id=\"active\" class=\"first\"><a href=\"%s\" id=\"current\">%s</a></li>\n" % \
|
||||||
|
(self.menu[tab], tab)
|
||||||
|
else:
|
||||||
|
s += "<li class=\"first\"><a href=\"%s\">%s</a></li>\n" % \
|
||||||
|
(self.menu[tab], tab)
|
||||||
|
else:
|
||||||
|
if tab == activeTab:
|
||||||
|
s += "<li id=\"active\"><a href=\"%s\" id=\"current\">%s</a></li>\n" % \
|
||||||
|
(self.menu[tab], tab)
|
||||||
|
else:
|
||||||
|
s += "<li><a href=\"%s\">%s</a></li>\n" % \
|
||||||
|
(self.menu[tab], tab)
|
||||||
|
tabNum += 1
|
||||||
|
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def getHeader(self, activeTab = "Main"):
|
||||||
|
s = self.headerTemplate % {'titlestring' : self.title,
|
||||||
|
'menustring' : self.getMenu(activeTab)}
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def getFooter(self):
|
||||||
|
return self.footerTemplate % {'contact' : self.contactInfo}
|
||||||
|
|
||||||
|
def listHandlerPage(self, uriToHandler):
|
||||||
|
output = self.getHeader("Services")
|
||||||
|
|
||||||
|
uriList = uriToHandler.keys()
|
||||||
|
uriList.sort()
|
||||||
|
|
||||||
|
output += "<table>\n<caption>Services</caption><thead><tr><th scope=col>URI</th><th scope=col>Handler</th></tr></thead>\n\n"
|
||||||
|
output += "<tbody>\n"
|
||||||
|
|
||||||
|
rowNum = 0
|
||||||
|
for uri in uriList:
|
||||||
|
rowNum += 1
|
||||||
|
handlerFunc = str(uriToHandler[uri][0]).split(" ")[2]
|
||||||
|
|
||||||
|
output += "<tr%s><td><a href=%s>%s</a></td><td>%s</td></tr>\n" % \
|
||||||
|
(LandingPageHTML.getRowClassString(rowNum),
|
||||||
|
uri,
|
||||||
|
uri,
|
||||||
|
handlerFunc)
|
||||||
|
#handlerFunc)
|
||||||
|
|
||||||
|
output += "</tbody></table>\n"
|
||||||
|
|
||||||
|
output = output + self.getFooter()
|
||||||
|
return output
|
||||||
|
|
||||||
|
def main(self):
|
||||||
|
output = self.getHeader("Main") + "<P>Welcome!</P>\n" + self.getFooter()
|
||||||
|
return output
|
||||||
|
|
291
direct/src/http/LandingPageHTML.py
Executable file
291
direct/src/http/LandingPageHTML.py
Executable file
@ -0,0 +1,291 @@
|
|||||||
|
# -- Text content for the landing page. You should change these for yours! --
|
||||||
|
|
||||||
|
title = "Landing Page"
|
||||||
|
contactInfo = "M. Ian Graham - ian.graham@dig.com - 818-623-3219"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# -- Begin fancy layout stuff, change at your own risk --
|
||||||
|
|
||||||
|
header = '''
|
||||||
|
<html><head>
|
||||||
|
<title>%(titlestring)s</title>
|
||||||
|
<style>
|
||||||
|
body
|
||||||
|
{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 90%%;
|
||||||
|
font-family: Verdana, sans-serif;
|
||||||
|
background-color: #fff;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
p
|
||||||
|
{
|
||||||
|
margin: 0;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2
|
||||||
|
{
|
||||||
|
font-size: 140%%;
|
||||||
|
color: #666;
|
||||||
|
background-color: #fff;
|
||||||
|
width: 22em;
|
||||||
|
margin-left: 150px;
|
||||||
|
margin-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3
|
||||||
|
{
|
||||||
|
padding-top: 10px;
|
||||||
|
margin-top: 0px;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre
|
||||||
|
{
|
||||||
|
margin-left: 20px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a
|
||||||
|
{
|
||||||
|
text-decoration: none;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover
|
||||||
|
{
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header
|
||||||
|
{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer
|
||||||
|
{
|
||||||
|
margin: 0;
|
||||||
|
padding: 3px;
|
||||||
|
text-align: right;
|
||||||
|
background-color: #fff;
|
||||||
|
border-top: 1px solid #778;
|
||||||
|
font: 10px Verdana, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
#contents
|
||||||
|
{
|
||||||
|
margin: 0;
|
||||||
|
padding: 25;
|
||||||
|
background-color: #eee;
|
||||||
|
min-height:600px;
|
||||||
|
height:auto !important;
|
||||||
|
height:600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
<!-- Tab menu -->
|
||||||
|
|
||||||
|
#navcontainer
|
||||||
|
{
|
||||||
|
margin:0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#navlist
|
||||||
|
{
|
||||||
|
padding: 3px 0;
|
||||||
|
margin-left: 0;
|
||||||
|
margin: 0;
|
||||||
|
border-bottom: 1px solid #778;
|
||||||
|
font: bold 12px Verdana, sans-serif;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#navlist li
|
||||||
|
{
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
#navlist li a
|
||||||
|
{
|
||||||
|
padding: 3px 0.5em;
|
||||||
|
margin-left: 3px;
|
||||||
|
border: 1px solid #778;
|
||||||
|
border-bottom: none;
|
||||||
|
background: #DDE;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#navlist li a:link { color: #448; }
|
||||||
|
#navlist li a:visited { color: #667; }
|
||||||
|
|
||||||
|
#navlist li a:hover
|
||||||
|
{
|
||||||
|
color: #000;
|
||||||
|
background: #AAE;
|
||||||
|
border-color: #227;
|
||||||
|
}
|
||||||
|
|
||||||
|
#navlist li a#current
|
||||||
|
{
|
||||||
|
background: #eee;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
#navlist li.first
|
||||||
|
{
|
||||||
|
margin-left: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
<!-- Table formatting -->
|
||||||
|
|
||||||
|
table
|
||||||
|
{
|
||||||
|
border-spacing:1px;
|
||||||
|
background:#E7E7E7;
|
||||||
|
color:#333;
|
||||||
|
}
|
||||||
|
|
||||||
|
caption
|
||||||
|
{
|
||||||
|
border: #666666;
|
||||||
|
border-bottom: 2px solid #666666;
|
||||||
|
margin-left: 2px;
|
||||||
|
margin-right: 2px;
|
||||||
|
padding: 10px;
|
||||||
|
background: #cfcfdf;
|
||||||
|
font: 15px 'Verdana', Arial, Helvetica, sans-serif;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
td, th
|
||||||
|
{
|
||||||
|
font:13px 'Courier New',monospace;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead th
|
||||||
|
{
|
||||||
|
text-align: center;
|
||||||
|
background: #dde;
|
||||||
|
color: #666666;
|
||||||
|
border: 1px solid #ffffff;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody th
|
||||||
|
{
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr
|
||||||
|
{
|
||||||
|
background: #efeffc;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr.odd
|
||||||
|
{
|
||||||
|
background: #ffffff;
|
||||||
|
border-top: 1px solid #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody th a:hover
|
||||||
|
{
|
||||||
|
color: #009900;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr td
|
||||||
|
{
|
||||||
|
text-align: left
|
||||||
|
height: 30px;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #ffffff;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr.odd td
|
||||||
|
{
|
||||||
|
background: #efeffc;
|
||||||
|
border-top: 1px solid #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr.dead td
|
||||||
|
{
|
||||||
|
background:#ff0000;
|
||||||
|
border-top: 1px solid #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td a:link, table td a:visited
|
||||||
|
{
|
||||||
|
display: block;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
width: 100%%;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
html>body #navcontainer li a { width: auto; }
|
||||||
|
|
||||||
|
table td a:hover
|
||||||
|
{
|
||||||
|
color: #000000;
|
||||||
|
background: #aae;
|
||||||
|
}
|
||||||
|
|
||||||
|
tfoot th, tfoot td
|
||||||
|
{
|
||||||
|
background: #dfdfdf;
|
||||||
|
padding: 3px;
|
||||||
|
text-align: center;
|
||||||
|
font: 14px 'Verdana', Arial, Helvetica, sans-serif;
|
||||||
|
font-weight: bold;
|
||||||
|
border-bottom: 1px solid #cccccc;
|
||||||
|
border-top: 1px solid #DFDFDF;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="header">
|
||||||
|
<h2>%(titlestring)s</h2>
|
||||||
|
<div id="navcontainer">
|
||||||
|
<ul id="navlist">
|
||||||
|
%(menustring)s
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="contents">
|
||||||
|
<center>
|
||||||
|
'''
|
||||||
|
|
||||||
|
mainMenu = '''
|
||||||
|
<p>Whee!</p>
|
||||||
|
'''
|
||||||
|
|
||||||
|
footer = '''
|
||||||
|
</center>
|
||||||
|
</div>
|
||||||
|
<div id="footer">
|
||||||
|
Contact: %(contact)s
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
\r\n'''
|
||||||
|
|
||||||
|
|
||||||
|
def getRowClassString(rowNum):
|
||||||
|
if rowNum % 2 == 0:
|
||||||
|
return ""
|
||||||
|
else:
|
||||||
|
return " class=\"odd\""
|
@ -3,6 +3,7 @@ from pandac.PandaModules import HttpRequest
|
|||||||
from direct.directnotify.DirectNotifyGlobal import directNotify
|
from direct.directnotify.DirectNotifyGlobal import directNotify
|
||||||
from direct.task.TaskManagerGlobal import taskMgr
|
from direct.task.TaskManagerGlobal import taskMgr
|
||||||
from direct.task import Task
|
from direct.task import Task
|
||||||
|
from LandingPage import LandingPage
|
||||||
|
|
||||||
notify = directNotify.newCategory('WebRequestDispatcher')
|
notify = directNotify.newCategory('WebRequestDispatcher')
|
||||||
|
|
||||||
@ -90,8 +91,8 @@ class WebRequestDispatcher(object):
|
|||||||
obj.__dict__ = self._shared_state
|
obj.__dict__ = self._shared_state
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, wantLandingPage = True, landingPageTitle = None):
|
||||||
pass
|
self.enableLandingPage(wantLandingPage, landingPageTitle)
|
||||||
|
|
||||||
def listenOnPort(self,listenPort):
|
def listenOnPort(self,listenPort):
|
||||||
"""
|
"""
|
||||||
@ -199,3 +200,28 @@ class WebRequestDispatcher(object):
|
|||||||
def stopCheckingIncomingHTTP(self):
|
def stopCheckingIncomingHTTP(self):
|
||||||
taskMgr.remove('pollHTTPTask')
|
taskMgr.remove('pollHTTPTask')
|
||||||
|
|
||||||
|
|
||||||
|
# -- Landing page convenience functions --
|
||||||
|
|
||||||
|
def enableLandingPage(self, enable, title):
|
||||||
|
if enable:
|
||||||
|
if not self.__dict__.has_key("landingPage"):
|
||||||
|
self.landingPage = LandingPage()
|
||||||
|
if title is None:
|
||||||
|
title = self.__class__.__name__
|
||||||
|
self.landingPage.title = title
|
||||||
|
self.registerGETHandler("/", self.landingPage.main, returnsResponse = True)
|
||||||
|
#self.registerGETHandler("/main", self.landingPage.main, returnsResponse = True)
|
||||||
|
self.registerGETHandler("/list", self._listHandlers, returnsResponse = True)
|
||||||
|
self.landingPage.addTab("Main", "/")
|
||||||
|
self.landingPage.addTab("Services", "/list")
|
||||||
|
else:
|
||||||
|
self.landingPage = None
|
||||||
|
self.unregisterGETHandler("/")
|
||||||
|
#self.unregisterGETHandler("/main")
|
||||||
|
self.unregisterGETHandler("/list")
|
||||||
|
|
||||||
|
|
||||||
|
def _listHandlers(self):
|
||||||
|
return self.landingPage.listHandlerPage(self.uriToHandler)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user