Simple JSON AJAX WSGI MVC App
Verfasst: Sonntag 19. März 2006, 17:43
Ich hab mal die BUZZ Hypes JSON AJAX WSGI MVC in einer Mini Anwendung exemplarisch zusammengebaut
. Das ganze baut auf dem Simple AJAX JSON Beispiel auf. Es wird eine Tabelle erzeugt und auf Knopfdruck via AJAX (JSON) neue RANDOM Tabellenwerte vom MVC System geholt. Mittels JavaScript und DOM wird die Tabelle dann aktualisiert.
Es sind zwei Dateien: ajaxSrv.py und ajax.html. Beide Dateien in einem Verzeichnis ablegen und ajaxSrv.py starten. Anschliessend sollte via http://localhost:8081 im Browser die Tabelle angezeigt werden.
Tabellar
edit: ist nun WSGI kompatibel + div. Änderungen
ajaxSrv.py
ajax.html

Es sind zwei Dateien: ajaxSrv.py und ajax.html. Beide Dateien in einem Verzeichnis ablegen und ajaxSrv.py starten. Anschliessend sollte via http://localhost:8081 im Browser die Tabelle angezeigt werden.
Tabellar
edit: ist nun WSGI kompatibel + div. Änderungen
ajaxSrv.py
Code: Alles auswählen
# -*- coding: utf-8 -*-
"""
Simple JSON-AJAX-WSGI-MVC Application
=====================================
Based on simple JSON-AJAX example from
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440637
StartUrl: http://localhost:8081
"""
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
import random
class AjaxApp(object):
def __init__(self,controller):
self.controller=controller
self.view=View(self)
def __call__(self,environ,start_response):
self.start=start_response
urlpath=environ['PATH_INFO'].strip('/')
if urlpath == "" :
return self.view.ajax_table()
elif urlpath == "update":
return self.view.ajax_table_update()
else:
return self.view.ajax_table()
class View(object):
def __init__(self,app):
self.app=app
def ajax_table(self):
status = "200 OK"
response_headers = [('Content-type','text/html')]
self.app.start(status, response_headers)
return self.app.controller.getAjaxTable()
def ajax_table_update(self):
status = "200 OK"
response_headers = [('Content-type','text/plain')]
self.app.start(status, response_headers)
return self.app.controller.getRandomTableData()
class Controller(object):
def __init__(self):
self.model=Model()
def getAjaxTable(self):
return self.model.getAjaxTable()
def getRandomTableData(self):
return self.model.getRandomTableData()
class Model(object):
def getAjaxTable(self):
file=open("ajax.html","r")
file_raw=file.read()
file.close()
return [file_raw]
def getRandomTableData(self):
jsondata =[{"one":'Hello world',"two":12345678L,"three":3.1415926},\
['to',"be","or",'not',"to",'be'],\
{'title':"that's the question",'random':random.randrange(0,1000000)}\
]
return [jsondata]
class WSGIHandler(BaseHTTPRequestHandler):
def do_GET(self):
"""
HTTP-GET-Anfragen
"""
self.process_request()
def do_POST(self):
"""
HTTP-POST-Anfragen
"""
def process_request(self):
environ = {'PATH_INFO': self.path}
headers_set = []
headers_sent = []
def write(data):
if not headers_set:
raise AssertionError("write() before start_response()")
elif not headers_sent:
# Before the first output, send the stored headers
status, response_headers = headers_sent[:] = headers_set
code, msg = status.split(' ',1)
self.send_response(int(code), msg)
for header in response_headers:
self.send_header(*header)
self.end_headers()
self.wfile.write(data)
def start_response(status,response_headers,exc_info=None):
if exc_info:
try:
if headers_sent:
# Re-raise original exception if headers sent
raise exc_info[0], exc_info[1], exc_info[2]
finally:
exc_info = None # avoid dangling circular ref
elif headers_set:
raise AssertionError("Headers already set!")
headers_set[:] = [status,response_headers]
return write
result = self.server.app(environ, start_response)
try:
for data in result:
if data: # don't send headers until body appears
write(data)
if not headers_sent:
write('') # send headers now if body was empty
finally:
if hasattr(result,'close'):
result.close()
class WSGIServer(HTTPServer):
def __init__(self, hostname='', port=8081,application=''):
HTTPServer.__init__(self, (hostname, port), WSGIHandler)
self.app = application
def run(self):
print "SIMPLE-WSGI-AJAX-MVC-APP..."
while True:
try:
self.handle_request()
except KeyboardInterrupt:
break
if __name__ == '__main__':
app=AjaxApp(Controller()) #Application instance
WSGIServer(application = app).run()
Code: Alles auswählen
<html>
<head>
<title>simple json-ajax-wsgi-mvc example</title>
<script language="JavaScript">
//json parser
//from json.org with small modification
var cur_str_chr;
function json_parse(text) {
var at = 0;
var ch = ' ';
function error(m) {
throw {
name: 'JSONError',
message: m,
at: at - 1,
text: text
};
}
function next() {
ch = text.charAt(at);
at += 1;
return ch;
}
function white() {
while (ch !== '' && ch <= ' ') {
next();
}
}
function str() {
var i, s = '', t, u;
if (ch == '\'' || ch == '"') { //change " to ' for python
cur_str_chr = ch;
outer: while (next()) {
if (ch == cur_str_chr) {
next();
return s;
} else if (ch == '\\') {
switch (next()) {
case 'b':
s += '\b';
break;
case 'f':
s += '\f';
break;
case 'n':
s += '\n';
break;
case 'r':
s += '\r';
break;
case 't':
s += '\t';
break;
case 'u':
u = 0;
for (i = 0; i < 4; i += 1) {
t = parseInt(next(), 16);
if (!isFinite(t)) {
break outer;
}
u = u * 16 + t;
}
s += String.fromCharCode(u);
break;
default:
s += ch;
}
} else {
s += ch;
}
}
}
error("Bad string");
}
function arr() {
var a = [];
if (ch == '[') {
next();
white();
if (ch == ']') {
next();
return a;
}
while (ch) {
a.push(val());
white();
if (ch == ']') {
next();
return a;
} else if (ch != ',') {
break;
}
next();
white();
}
}
error("Bad array");
}
function obj() {
var k, o = {};
if (ch == '{') {
next();
white();
if (ch == '}') {
next();
return o;
}
while (ch) {
k = str();
white();
if (ch != ':') {
break;
}
next();
o[k] = val();
white();
if (ch == '}') {
next();
return o;
} else if (ch != ',') {
break;
}
next();
white();
}
}
error("Bad object");
}
function num() {
var n = '', v;
if (ch == '-') {
n = '-';
next();
}
while (ch >= '0' && ch <= '9') {
n += ch;
next();
}
if (ch == '.') {
n += '.';
while (next() && ch >= '0' && ch <= '9') {
n += ch;
}
}
if (ch == 'e' || ch == 'E') {
n += 'e';
next();
if (ch == '-' || ch == '+') {
n += ch;
next();
}
while (ch >= '0' && ch <= '9') {
n += ch;
next();
}
}
if (ch == 'L')next();//for python long
v = +n;
if (!isFinite(v)) {
error("Bad number");
} else {
return v;
}
}
function word() {
switch (ch) {
case 't':
if (next() == 'r' && next() == 'u' && next() == 'e') {
next();
return true;
}
break;
case 'f':
if (next() == 'a' && next() == 'l' && next() == 's' &&
next() == 'e') {
next();
return false;
}
break;
case 'n':
if (next() == 'u' && next() == 'l' && next() == 'l') {
next();
return null;
}
break;
}
error("Syntax error");
}
function val() {
white();
switch (ch) {
case '{':
return obj();
case '[':
return arr();
case '\'':
case '"':
return str();
case '-':
return num();
default:
return ch >= '0' && ch <= '9' ? num() : word();
}
}
return val();
}
//end json parser
function loadurl(dest) {
xmlhttp = window.XMLHttpRequest?new XMLHttpRequest(): new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange = pop_table;
xmlhttp.open("GET", dest);
xmlhttp.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
xmlhttp.send(null);
}
function pop_table() {
if ((xmlhttp.readyState == 4) && (xmlhttp.status == 200)) {
var json_data = json_parse(xmlhttp.responseText);
var rows = document.getElementById("testtable").getElementsByTagName("tr");
rows[0].childNodes[0].innerHTML = json_data[0]['one']
rows[0].childNodes[1].innerHTML = json_data[0]['two']
rows[0].childNodes[2].innerHTML = json_data[0]['three']
for(i=0;i<rows[1].childNodes.length;i++)
rows[1].childNodes[i].innerHTML = json_data[1][i]
rows[2].childNodes[0].innerHTML = json_data[2]['title']
rows[2].childNodes[2].innerHTML = json_data[2]['random']
}
}
</script>
<style type="text/css">
div,td {
width: 10em;
font-family: sans-serif;
padding: 0.2em;
border: 1px solid #ccc;
margin: 0.5em;
background-color: #eee;
}
</style>
</head>
<body>
<table id="testtable" border=1>
<tr><td>11</td><td>12</td><td>13</td></tr>
<tr><td>21</td><td>22</td><td>23</td></tr>
<tr><td>31</td><td>32</td><td>33</td></tr>
</table>
<div id="clickhere" onclick="loadurl('http://localhost:8081/update')">click here</div>
</body>
</html>