Skip to content

Commit

Permalink
javascript examples
Browse files Browse the repository at this point in the history
  • Loading branch information
ctb committed Apr 12, 2012
1 parent 213c16c commit 307ae50
Show file tree
Hide file tree
Showing 26 changed files with 902 additions and 0 deletions.
130 changes: 130 additions & 0 deletions jquery-examples/chat/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import os
import os.path
import mimetypes
import traceback
import random
import time
import cgi

class Message(object):
def __init__(self, timestamp, user, message):
self.timestamp = timestamp
self.user = user
self.message = message

class ChatApp(object):
def __init__(self, files_path):
self.file_server = FileServer(files_path)
self.messages = []

def get_messages_since(self, timestamp):
"""Retrieve any messages received since the given timestamp."""
x = []
for m in self.messages:
if m.timestamp > timestamp:
x.append(m)

return x

def format_response(self, new_messages, timestamp):
x = []
for m in new_messages:
x.append("""\
<message>
<author>%s</author>
<text>%s</text>
</message>
""" % (m.user, m.message))

if x: # new messages received?
# yes
status = 1
else:
status = 2 # no new messages

xml = """
<?xml version="1.0"?>
<response>
<status>%d</status>
<time>%f</time>
%s
</response>
""" % (status, timestamp, "".join(x))

return xml

def __call__(self, environ, start_response):
url = environ['PATH_INFO']
if url == '/get_messages':
# last_time
form = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ)
last_time = float(form['last_time'].value)

new_messages = self.get_messages_since(last_time)
xml = self.format_response(new_messages, time.time())

# done; return whatever we've got.
start_response("200 OK", [('Content-type', 'text/html')])

print xml
return [xml]
elif url == '/post_message':
form = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ)

# retrieve submitted data
last_time = float(form['last_time'].value)
author = form['user'].value
message = form['message'].value

# create and add new message:
timestamp = time.time()
m = Message(timestamp, author, message)
self.messages.append(m)

# return any new messages:
new_messages = self.get_messages_since(last_time)
xml = self.format_response(new_messages, timestamp)

# done; return whatever we've got.
start_response("200 OK", [('Content-type', 'text/html')])

print xml
return [xml]

# by default, just return a file
return self.file_server(environ, start_response)

class FileServer(object):
def __init__(self,path):
self.path = os.path.abspath(path)

def __call__(self, environ, start_response):
url = environ['PATH_INFO']

print 'url:' + url
if url.endswith('/'):
url += 'index.html'

fullpath = self.path + url
fullpath = os.path.abspath(fullpath)
assert fullpath.startswith(self.path)

extension=mimetypes.guess_type(fullpath)
extension=extension[0]

if extension is None:
extension = 'text/plain'

status = '200 OK'
headers = [('Content-type', extension )]

try:
fp = open(fullpath)
contents = fp.read()
start_response(status, headers)
return [contents]
except:
status = '404 Not Found'
headers = [('Content-type', 'text/html')]
start_response(status, headers)
return ['404 Not Found']
10 changes: 10 additions & 0 deletions jquery-examples/chat/chat-server
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import sys
from webserve import Server

port = sys.argv[1]
port = int(port)

from apps import ChatApp
chat_app = ChatApp('./html')

Server(port, chat_app).serve_forever()
99 changes: 99 additions & 0 deletions jquery-examples/chat/html/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<!-- chat server, from http://www.sitepoint.com/article/ajax-jquery/ -->

<head>

<style type="text/css">
#messagewindow {
height: 250px;
border: 1px solid;
padding: 5px;
overflow: auto;
}
#wrapper {
margin: auto;
width: 438px;
}
</style>

<script src="jquery-1.3.2.min.js"></script>

<script type="text/javascript">

$(document).ready(function() {
timestamp = 0;

function add_messages(xml) {
// retrieve 'status' from the XML; if nothing changed, exit.
if($("status", xml).text() == "2") return;

// update timestamp value from XML
timestamp = $("time", xml).text();

// for each 'message' block in the XML, retrieve author & content, then
// post.

$("message", xml).each( function(id) {
message = $("message", xml).get(id);

author = $("author", message).text();
content = $("text", message).text();

$("#messagewindow").prepend("<b>" + author + "</b>:" + content
+ "<br>");
});
};

// when the 'submit' button is pushed on the chatform,
$("form#chatform").submit(function() {

// send the message data to the URL 'post_message'
$.post("post_message",
{ message : $("#message").val(),
user : $("#author").val(),
last_time : timestamp,
},
// apply 'add_messages' to update page with returned data
function(xml) {
add_messages(xml)
}
);

// blank out the 'message' field in the form
$("#message").val("");

return false;
});

//
// execute below on load:
//

// blank out the 'loading' message
$("#loading").remove();

// get the current set of messages with timestamp 0
$.post("get_messages",
{ last_time : timestamp },
function(xml) { add_messages(xml) }
);

});

</script>
</head>

<body>

<div id="wrapper">
<p id="messagewindow"><span id="loading">Loading...</span></p>
<form id="chatform">

Name: <input type="text" id="author" />
Message: <input type="text" id="message" />

<input type="submit" value="ok" /><br />

</form>
</div>

</body>
19 changes: 19 additions & 0 deletions jquery-examples/chat/html/jquery-1.3.2.min.js

Large diffs are not rendered by default.

121 changes: 121 additions & 0 deletions jquery-examples/chat/webserve.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import socket
from cStringIO import StringIO
import urlparse

class StartResponse(object):
def __call__(self, status, headers):
self.status = status
self.headers = headers

class Server(object):
def __init__(self, port, wsgi_app):
self.port = port
self.wsgi_app = wsgi_app

def request_is_complete(self, data):
"""
Evaluate data -- is this a complete (GET or POST) request?
"""
if '\r\n\r\n' not in data:
return False

head, rest = data.split('\r\n\r\n', 1)
request_line, head = head.split('\r\n', 1)
reqtype, url, protocol = request_line.split(' ')

parsed_url = urlparse.urlparse(url)
path = parsed_url.path

# process headers
headers = head.splitlines()
headers = [ x.split(': ', 1) for x in headers ]

if reqtype != 'POST':
contentsize = 0
else:
contentsize = None
for k, v in headers:
if k.lower() == 'content-length':
contentsize = int(v)

if len(rest) == contentsize:
return True

return False

def parse_request(self, data):
if '\r\n\r\n' not in data:
return False

head, rest = data.split('\r\n\r\n', 1)
request_line, head = head.split('\r\n', 1)
request_type, url, protocol = request_line.split(' ')

parsed_url = urlparse.urlparse(url)
path = parsed_url.path
query = parsed_url.query

# process headers
headers = head.splitlines()
headers = [ x.split(': ', 1) for x in headers ]

environ = {}
environ['REQUEST_METHOD'] = request_type
environ['SCRIPT_NAME'] = ''
environ['PATH_INFO'] = path
environ['SERVER_PROTOCOL'] = protocol
environ['QUERY_STRING'] = query
environ['wsgi.input'] = StringIO(rest)

start_response = StartResponse()

data = list(self.wsgi_app(environ, start_response))
data = "".join(data)

status = start_response.status
headers = start_response.headers

headers = "\r\n".join([ ": ".join(x) for x in headers ])

return "HTTP/1.0 %s\r\n%s\r\n\r\n%s" % (status, headers, data)

def handle_connection(self, sockobj, data_so_far=None):
if data_so_far is None: # initialize
data_so_far = ''

try:
data = sockobj.recv(4096)
except socket.error:
return False, data_so_far

data_so_far += data
if self.request_is_complete(data_so_far): # complete request?
response = self.parse_request(data_so_far)
try:
sockobj.sendall(response)
sockobj.close()
except socket.error:
pass

return True, None

# not done yet; keep gathering information
return False, data_so_far

def serve_forever(self):
print "binding '%s', port %d" % ('', self.port)
sock = socket.socket()
sock.bind( ('', self.port) )
sock.listen(5)

while 1:
client_sock, client_addr = sock.accept()
print '----'
print 'connection:', client_addr

close_flag, data = self.handle_connection(client_sock)
while not close_flag:
close_flag, data = self.handle_connection(client_sock, data)
client_sock.close()

print 'done with', client_addr
27 changes: 27 additions & 0 deletions jquery-examples/ex1.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!-- basic jquery; CSS-style selectors -->

<head>
<script src='jquery-1.3.2.min.js'></script>
</head>

<body>

<div class='foo'>
Pre-existing text.

<div class='parks'>
foo bar baz
</div>

</div>

<script type='text/javascript'>

$("div.foo").append("Hello World!");
$("div.foo").css("color","red");
$("div.parks").css("color","blue");

</script>


</body>
Loading

0 comments on commit 307ae50

Please sign in to comment.