removed errors in previous commit

This commit is contained in:
mdipierro
2012-12-24 13:55:00 -06:00
parent 3710d43cfc
commit 5d4ef568a1
50 changed files with 1 additions and 2664 deletions
+1 -1
View File
@@ -1 +1 @@
Version 2.4.1-alpha.1+timestamp.2012.12.24.13.48.18
Version 2.4.1-alpha.1+timestamp.2012.12.24.13.54.21
-18
View File
@@ -1,18 +0,0 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICzjCCAbYCAQAwgYgxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhJbGxpbm9pczER
MA8GA1UEBxMIT2FrIFBhcmsxDzANBgNVBAoTBndlYjJweTEXMBUGA1UEAxMOd3d3
LndlYjJweS5jb20xKTAnBgkqhkiG9w0BCQEWGm1hc3NpbW8uZGlwaWVycm9AZ21h
aWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6AX4oTjdBThw
xdGEDtb+XhvyW58gC9il2z5ewp/AVwYUst1MYPF1jPLv23yn4jkN4c6OExlhgsVi
YxsWq8fEg55SEBr3gpH608FOtwicEeIHwufP7OhHiOB1rhUa5B54xIIoh5AMKwIH
qvPlLn8Pi8DJGdAoDwUTUsFLWJdt0/XQgjHQOeIrgXRvrGPLWQglQ3/8AqWZ2TLp
raBZv9RgXJ8IlArwfEzfdQnfkrmAMOjsBRaf7krQMAF7n+R1SqNWQeFfw//FccC9
seHvRkbawjyHL0VezmR/eAUGw8nYZuEjhUEZnrGpD4fRWSxfZuk7nx2EXKh4qOJL
kVQHu5/ZOQIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBANjuO4viE6MpTVyMDJNv
Cx60q4fq5ej9QU+KDb9A5wTHl6/KRJNd7EPJl07OP1Mm0D2Krp+GfLh7vVLKvxl1
G1f4sDkXeAD1OhcqcUEBdS4CzLCYP0RdW9T77lQ5i43C+XBJH3RGzdgofjS41JNY
mswCv66mSMb28PoRPYiGLfW/RKO27g+viYrVoJBikntjR86x7hwBUWjpOv+jBk3a
jtE39KDj1ID/3eYrkdz3Hz65VvK4rFSY/TwTYzRrTO/4SZjwCZfgcy1BdFRn5aSK
pB2fxDLEg/bydBdI78PtxocFBX7qZfm9VWpj8UfN0D+SAFUyesxEuQDPIKO5FHMm
Otk=
-----END CERTIFICATE REQUEST-----
-27
View File
@@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpgIBAAKCAQEA6AX4oTjdBThwxdGEDtb+XhvyW58gC9il2z5ewp/AVwYUst1M
YPF1jPLv23yn4jkN4c6OExlhgsViYxsWq8fEg55SEBr3gpH608FOtwicEeIHwufP
7OhHiOB1rhUa5B54xIIoh5AMKwIHqvPlLn8Pi8DJGdAoDwUTUsFLWJdt0/XQgjHQ
OeIrgXRvrGPLWQglQ3/8AqWZ2TLpraBZv9RgXJ8IlArwfEzfdQnfkrmAMOjsBRaf
7krQMAF7n+R1SqNWQeFfw//FccC9seHvRkbawjyHL0VezmR/eAUGw8nYZuEjhUEZ
nrGpD4fRWSxfZuk7nx2EXKh4qOJLkVQHu5/ZOQIDAQABAoIBAQCAyI+wLPfApgsy
QZCjDAI0Ch8Da9dFvAKTJpNCQ5lmtCFZBiwWwu8UROONWCt3DWP/Kb8CKtxM0XJC
wA5dWoxg4cd62Pz4pD4suucOAOFfq63TKQfn3yWVe8DV1zEN3Tv7FqOYWwPl+0J2
SNm0bSIb1+3HPhp9+7s1+8PucF6tfnyRMtZAXN0MURsMLHhxepi1hd1nxEhFt2gg
F57CQVTMFnGZd9swSgJhFbMbQeBjBd/KSE8Jf+Gr3jMbpyQoqAsJrmikmz1ONvYA
+FlIDxNFJZWXYTXld3amXXjPyDgc4VbmrtTTYHpZHjwecEf/Sj1J7MAGCXJoAwuF
7LeByp1hAoGBAPoLl1VFyC0p3Iu2wViW1CxT2inb5eH7IuosPxG41vFKG/wom+Ww
bT8BUwGwGXJv/PIMbAKbJ8z7SZtSkY4I+hL51r+rplwwnxW7AfuRB2wK3KEoBtUN
EdmNlVW2DNIIJitv2Cszx7z1myRhaOj9xNz6cI5FhkGAMmE+rr8Q1e6LAoGBAO2M
gjfu1/iI7QWXG9tS3/TE3n7JVXpt222iJh4Df6oYAa93snU0OAAV3DiURpDmbi43
qpryiDgaM5ONCmOgYs3wM7Vpc5PdKtwZdIOcMP78Vk7hwaAsFn1k+WjIXlPcRWLi
3iAAzjz+juXa6BGxBcQf2PmPuEEOwBrnVaLfIjPLAoGBAI6Boqs3zSFoVUjPTJxX
we7Nj24B5J+JiNmbhApupRn5mb95yXf7uBeLgqpYmfgtuSSeTcSidumNYeMDCO/B
T/0WpPyyMGskTtaMsVGV03wRKLM0Y8hy3XR3C+BAlEfz2wUwhiwBI9oexF/UoH0B
fHxQw2tiVmToUk438lH0n2iHAoGBAN5iIPIN9j+kqAgIu7pqbmDuAME+6HfR6o9L
MlX8voJVMRa8fuO8PATQcjbBkQJLxrAbyup9zMqAtPIYIra7ymOy0CWwD9RIQ7yD
VBF1omTDhGUacbLqMy+23MqccboeRxLZAkuBlZGCWfKTKZiOWbCOhAi15C97iJpn
IUN1ksZbAoGBANY7zwfUFPeKoChU92Jsub0daLGFBX8IRkRmDGPUvSHtMG2LRUdX
s12Y2wCVX9nDwVHvVo1E+Xnc1UeXJZI6r9P0GnJqhTf/4Z9XULCb4E/nJdrd1zcq
VYnb6p0ECh1N6syJ+YeBLG6aWKU0sLfri8LNxTFRza2lVP6aRLt+iE6M
-----END RSA PRIVATE KEY-----
BIN
View File
Binary file not shown.
-640
View File
@@ -1,640 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
docstring
"""
__author__ = "Gu Yingbo (tensiongyb@gmail.com)"
import os
import re
import sys
import time
import base64
import asyncore
import asynchat
import rfc822
import socket
import thread
import signal
import collections
from traceback import format_exc
from urllib import unquote, splitquery
from urlparse import urlparse
try:
import cStringIO as StringIO
except ImportError:
import StringIO
RN = '\r\n'
RNRN = '\r\n\r\n'
QUOTED_SLASH = re.compile("(?i)%2F")
COMMA_SEPARATED_HEADERS = ['ACCEPT', 'ACCEPT-CHARSET', 'ACCEPT-ENCODING',
'ACCEPT-LANGUAGE', 'ACCEPT-RANGES', 'ALLOW', 'CACHE-CONTROL',
'CONNECTION', 'CONTENT-ENCODING', 'CONTENT-LANGUAGE', 'EXPECT',
'IF-MATCH', 'IF-NONE-MATCH', 'PRAGMA', 'PROXY-AUTHENTICATE', 'TE',
'TRAILER', 'TRANSFER-ENCODING', 'UPGRADE', 'VARY', 'VIA', 'WARNING',
'WWW-AUTHENTICATE']
class FIFO(list):
def is_empty(self):
return len(self)==0
def push(self,data):
self.append(data)
def first(self):
return self[0] if len(self) else None
class RequestHandler(asynchat.async_chat):
def __init__(self, sock, server):
asynchat.async_chat.__init__(self, sock)
self.server = server
self.reset()
def reset(self):
self.ac_in_buffer = ''
self.ac_out_buffer = ''
self.producer_fifo.clear() # = collections.deque()
self.set_terminator(RNRN)
self.process = "reading headers"
self.started_response = False
self.status = ""
self.outheaders = []
self.sent_headers = False
self.close_connection = False
self.chunked_write = False
self.rfile = StringIO.StringIO()
self.environ = {
"wsgi.version": (1, 0),
"wsgi.url_scheme": "http",
"wsgi.multithread": False,
"wsgi.multiprocess": False,
"wsgi.run_once": False,
"wsgi.errors": sys.stderr,
}
def collect_incoming_data(self, data):
"""Buffer the data"""
if self.process == "reading chunked":
self.line_buffer += data
else:
self.rfile.write(data)
def found_terminator(self):
if self.process == "reading headers":
self.rfile.write(RNRN)
self.rfile.seek(0)
try:
self.parse_request()
except:
self.simple_response("500 Internal Server Error", format_exc())
return
if not self.read_chunked:
if self.environ["REQUEST_METHOD"].upper() == "POST":
cl = int(self.environ["CONTENT_LENGTH"])
self.rfile = StringIO.StringIO()
self.environ["wsgi.input"] = self.rfile
self.process = "dealing post"
self.set_terminator(cl)
else:
return self.wsgi_response()
else:
self.rfile = StringIO.StringIO()
self.environ["wsgi.input"] = self.rfile
self.process = "reading chunked"
self.set_terminator(RN)
self.line_buffer = ""
self.cl = 0
elif self.process == "dealing post":
self.rfile.seek(0)
return self.wsgi_response()
elif self.process == "reading chunked":
line = self.line_buffer.split(";", 1)
chunk_size = int(line.pop(0), 16)
if chunk_size <= 0:
self.process = "reading tail headers"
self.set_terminator(RNRN)
else:
self.cl += chunk_size
self.process = "get chunked"
self.set_terminator(self.cl+2) # browsers sometimes over-send
elif self.process == "get chunked":
crlf = self.rfile.getvalue()[-2:]
if not crlf != RN:
self.simple_response("400 Bad Request",
"Bad chunked transfer coding "
"(expected '\\r\\n', got %r)" % crlf)
return
else:
self.process = "reading chunked"
self.set_terminator(RN)
self.rfile.seek(-2, 2)
self.rfile.truncate()
elif self.process == "reading tail headers":
self.read_headers()
self.rfile.seek(0)
self.environ["CONTENT_LENGTH"] = str(self.cl) or ""
return self.wsgi_response()
def reset_when_done(self):
self.producer_fifo.append('\0')
def refill_buffer (self):
while 1:
if len(self.producer_fifo):
p = self.producer_fifo.first()
# a 'None' in the producer fifo is a sentinel,
# telling us to close the channel.
if p == 0:
if not self.ac_out_buffer:
self.producer_fifo.pop()
self.reset()
return
elif p is None:
if not self.ac_out_buffer:
self.producer_fifo.pop()
self.close()
return
elif isinstance(p, str):
self.producer_fifo.pop()
self.ac_out_buffer = self.ac_out_buffer + p
return
data = p.more()
if data:
self.ac_out_buffer = self.ac_out_buffer + data
return
else:
self.producer_fifo.pop()
else:
return
def wsgi_response(self):
try:
self.respond()
except:
self.simple_response("500 Internal Server Error", format_exc())
else:
if self.close_connection or ( not self.server.keep_going ):
self.close_when_done()
else:
self.reset_when_done()
def readable(self):
return self.server.keep_going and not self.writable() and \
asynchat.async_chat.readable(self)
def handle_expt(self):
asynchat.async_chat.handle_expt(self)
self.close()
def handle_error(self):
asynchat.async_chat.handle_error(self)
self.close()
def parse_request(self):
"""
Parse the next HTTP request start-line and message-headers.
HTTP/1.1 connections are persistent by default. If a client
requests a page, then idles (leaves the connection open),
then rfile.readline() will raise socket.error("timed out").
Note that it does this based on the value given to settimeout(),
and doesn't need the client to request or acknowledge the close
(although your TCP stack might suffer for it: cf Apache's history
with FIN_WAIT_2).
"""
request_line = self.rfile.readline()
if not request_line:
# Force self.ready = False so the connection will close.
self.ready = False
return
if request_line == RN:
# RFC 2616 sec 4.1: "...if the server is reading the protocol
# stream at the beginning of a message and receives a CRLF
# first, it should ignore the CRLF."
# But only ignore one leading line! else we enable a DoS.
request_line = self.rfile.readline()
if not request_line:
self.ready = False
return
server = self.server
environ = self.environ
environ["SERVER_SOFTWARE"] = "%s WSGI Server" % server.version
method, path, req_protocol = request_line.strip().split(" ", 2)
environ["REQUEST_METHOD"] = method
# path may be an abs_path (including "http://host.domain.tld");
scheme, location, path, params, qs, frag = urlparse(path)
if frag:
self.simple_response("400 Bad Request",
"Illegal #fragment in Request-URI.")
return
if scheme:
environ["wsgi.url_scheme"] = scheme
if params:
path = path + ";" + params
# Unquote the path+params (e.g. "/this%20path" -> "this path").
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2
#
# But note that "...a URI must be separated into its components
# before the escaped characters within those components can be
# safely decoded." http://www.ietf.org/rfc/rfc2396.txt, sec 2.4.2
atoms = [unquote(x) for x in QUOTED_SLASH.split(path)]
path = "%2F".join(atoms)
environ["SCRIPT_NAME"] = ""
environ["PATH_INFO"] = path
##if path == "*":
## # This means, of course, that the last wsgi_app (shortest path)
## # will always handle a URI of "*".
## environ["SCRIPT_NAME"] = ""
## environ["PATH_INFO"] = "*"
## self.wsgi_app = server.mount_points[-1][1]
##else:
## for mount_point, wsgi_app in server.mount_points:
## # The mount_points list should be sorted by length, descending.
## if path.startswith(mount_point + "/") or path == mount_point:
## environ["SCRIPT_NAME"] = mount_point
## environ["PATH_INFO"] = path[len(mount_point):]
## self.wsgi_app = wsgi_app
## break
## else:
## self.simple_response("404 Not Found")
## return
# Note that, like wsgiref and most other WSGI servers,
# we unquote the path but not the query string.
environ["QUERY_STRING"] = qs
# Compare request and server HTTP protocol versions, in case our
# server does not support the requested protocol. Limit our output
# to min(req, server). We want the following output:
# request server actual written supported response
# protocol protocol response protocol feature set
# a 1.0 1.0 1.0 1.0
# b 1.0 1.1 1.1 1.0
# c 1.1 1.0 1.0 1.0
# d 1.1 1.1 1.1 1.1
# Notice that, in (b), the response will be "HTTP/1.1" even though
# the client only understands 1.0. RFC 2616 10.5.6 says we should
# only return 505 if the _major_ version is different.
rp = int(req_protocol[5]), int(req_protocol[7])
sp = int(server.protocol[5]), int(server.protocol[7])
if sp[0] != rp[0]:
self.simple_response("505 HTTP Version Not Supported")
return
# Bah. "SERVER_PROTOCOL" is actually the REQUEST protocol.
environ["SERVER_PROTOCOL"] = req_protocol
# set a non-standard environ entry so the WSGI app can know what
# the *real* server protocol is (and what features to support).
# See http://www.faqs.org/rfcs/rfc2145.html.
environ["ACTUAL_SERVER_PROTOCOL"] = server.protocol
self.response_protocol = "HTTP/%s.%s" % min(rp, sp)
# If the Request-URI was an absoluteURI, use its location atom.
if location:
environ["SERVER_NAME"] = location
# then all the http headers
try:
self.read_headers()
except ValueError, ex:
self.simple_response("400 Bad Request", repr(ex.args))
return
creds = environ.get("HTTP_AUTHORIZATION", "").split(" ", 1)
environ["AUTH_TYPE"] = creds[0]
if creds[0].lower() == 'basic':
user, pw = base64.decodestring(creds[1]).split(":", 1)
environ["REMOTE_USER"] = user
# Persistent connection support
if self.response_protocol == "HTTP/1.1":
if environ.get("HTTP_CONNECTION", "") == "close":
self.close_connection = True
else:
# HTTP/1.0
if environ.get("HTTP_CONNECTION", "") != "Keep-Alive":
self.close_connection = True
# Transfer-Encoding support
te = None
if self.response_protocol == "HTTP/1.1":
te = environ.get("HTTP_TRANSFER_ENCODING")
if te:
te = [x.strip().lower() for x in te.split(",") if x.strip()]
read_chunked = False
if te:
for enc in te:
if enc == "chunked":
read_chunked = True
else:
# Note that, even if we see "chunked", we must reject
# if there is an extension we don't recognize.
self.simple_response("501 Unimplemented")
self.close_connection = True
return
self.read_chunked = read_chunked
return
if read_chunked:
if not self.decode_chunked():
return
# From PEP 333:
# "Servers and gateways that implement HTTP 1.1 must provide
# transparent support for HTTP 1.1's "expect/continue" mechanism.
# This may be done in any of several ways:
# 1. Respond to requests containing an Expect: 100-continue request
# with an immediate "100 Continue" response, and proceed normally.
# 2. Proceed with the request normally, but provide the application
# with a wsgi.input stream that will send the "100 Continue"
# response if/when the application first attempts to read from
# the input stream. The read request must then remain blocked
# until the client responds.
# 3. Wait until the client decides that the server does not support
# expect/continue, and sends the request body on its own.
# (This is suboptimal, and is not recommended.)
#
# We used to do 3, but are now doing 1. Maybe we'll do 2 someday,
# but it seems like it would be a big slowdown for such a rare case.
if environ.get("HTTP_EXPECT", "") == "100-continue":
self.simple_response(100)
self.ready = True
def new_header(self,k,v):
if k:
environ = self.environ
envname = 'HTTP_'+k
if k in COMMA_SEPARATED_HEADERS:
existing = environ.get(envname)
if existing:
v = ", ".join((existing, v))
environ[envname] = v
def read_headers(self):
"""Read header lines from the incoming stream."""
k = v = None
while True:
line = self.rfile.readline()
if not line or '\0' in line:
# No more data--illegal end of headers
raise ValueError("Illegal headers")
elif line == RN:
# Normal end of headers
self.new_header(k,v)
break
elif line[0] in ' \t':
v += line.strip()
else:
self.new_header(k,v)
k, v = line.split(":", 1)
k, v = k.strip().upper(), v.strip()
environ = self.environ
ct = environ.pop("HTTP_CONTENT_TYPE", None)
if ct:
environ["CONTENT_TYPE"] = ct
cl = environ.pop("HTTP_CONTENT_LENGTH", None)
if cl:
environ["CONTENT_LENGTH"] = cl
def decode_chunked(self):
"""Decode the 'chunked' transfer coding."""
cl = 0
data = StringIO.StringIO()
while True:
line = self.rfile.readline().strip().split(";", 1)
chunk_size = int(line.pop(0), 16)
if chunk_size <= 0:
break
## if line: chunk_extension = line[0]
cl += chunk_size
data.write(self.rfile.read(chunk_size))
crlf = self.rfile.read(2)
if crlf != RN:
self.simple_response("400 Bad Request",
"Bad chunked transfer coding "
"(expected '\\r\\n', got %r)" % crlf)
return
# Grab any trailer headers
self.read_headers()
data.seek(0)
self.environ["wsgi.input"] = data
self.environ["CONTENT_LENGTH"] = str(cl) or ""
return True
def respond(self):
"""
Call the appropriate WSGI app and write its iterable output.
"""
response = self.server.wsgi_app(self.environ, self.start_response)
try:
for chunk in response:
# "The start_response callable must not actually transmit
# the response headers. Instead, it must store them for the
# server or gateway to transmit only after the first
# iteration of the application return value that yields
# a NON-EMPTY string, or upon the application's first
# invocation of the write() callable." (PEP 333)
if chunk:
print 'sending',chunk
self.write(chunk)
print 'sent!'
finally:
if hasattr(response, "close"):
response.close()
if not self.sent_headers:
self.send_headers()
if self.chunked_write:
self.push("0\r\n")
def simple_response(self, status, msg=""):
"""Write a simple response back to the client."""
status = str(status)
buf = ["%s %s\r\n" % (self.server.protocol, status),
"Content-Length: %s\r\n" % len(msg)]
if status[:3] == "413" and self.response_protocol == 'HTTP/1.1':
# Request Entity Too Large
self.close_connection = True
buf.append("Connection: close\r\n")
buf.append(RN)
if msg:
buf.append(msg)
self.push(''.join(buf))
if self.close_connection or ( not self.server.keep_going ):
self.close_when_done()
else:
self.reset_when_done()
def start_response(self, status, headers, exc_info = None):
"""WSGI callable to begin the HTTP response."""
if self.started_response:
if not exc_info:
raise AssertionError("WSGI start_response called a second "
"time with no exc_info.")
else:
try:
raise exc_info[0], exc_info[1], exc_info[2]
finally:
exc_info = None
self.started_response = True
self.status = status
self.outheaders.extend(headers)
return self.write
def write(self, chunk):
"""
WSGI callable to write unbuffered data to the client.
This method is also used internally by start_response (to write
data from the iterable returned by the WSGI application).
"""
if not self.started_response:
raise AssertionError("WSGI write called before start_response.")
if not self.sent_headers:
self.send_headers()
if self.chunked_write and chunk:
buf = [hex(len(chunk))[2:], RN, chunk, RN]
self.push(''.join(buf))
else:
self.push(chunk)
def send_headers(self):
"""
Assert, process, and send the HTTP response message-headers.
"""
self.sent_headers = True
hkeys = [key.lower() for key, value in self.outheaders]
status = int(self.status[:3])
if status == 413:
# Request Entity Too Large. Close conn to avoid garbage.
self.close_connection = True
elif "content-length" not in hkeys:
# "All 1xx (informational), 204 (no content),
# and 304 (not modified) responses MUST NOT
# include a message-body." So no point chunking.
if status < 200 or status in (204, 205, 304):
pass
else:
if self.response_protocol == 'HTTP/1.1':
# Use the chunked transfer-coding
self.chunked_write = True
self.outheaders.append(("Transfer-Encoding", "chunked"))
else:
# Closing the conn is the only way to determine len.
self.close_connection = True
if "connection" not in hkeys:
if self.response_protocol == 'HTTP/1.1':
if self.close_connection:
self.outheaders.append(("Connection", "close"))
else:
if not self.close_connection:
self.outheaders.append(("Connection", "Keep-Alive"))
if "date" not in hkeys:
self.outheaders.append(("Date", rfc822.formatdate()))
server = self.server
if "server" not in hkeys:
self.outheaders.append(("Server", server.version))
buf = [server.protocol, " ", self.status, RN]
try:
buf += [k + ": " + v + RN for k, v in self.outheaders]
except TypeError:
if not isinstance(k, str):
raise TypeError("WSGI response header key %r is not a string.")
if not isinstance(v, str):
raise TypeError("WSGI response header value %r is not a string.")
else:
raise
buf.append(RN)
self.push(''.join(buf))
class WSGIServer(asyncore.dispatcher):
version = "Asynwsgi Server/1.0 alpha"
protocol = "HTTP/1.1"
def __init__(self, bind_addr, wsgi_app, server_name=None):
asyncore.dispatcher.__init__ (self)
self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind(bind_addr)
self.listen(1024)
self.keep_going = True
self.wsgi_app = wsgi_app
if not server_name:
server_name = socket.gethostname()
self.server_name = server_name
def writable(self):
return False
def readable(self):
return self.accepting
def handle_accept(self):
try:
conn, addr = self.accept()
except:
return
RequestHandler(conn, self)
def reload(self, signum, frame):
print 'reloading...'
self.keep_going = False
self.close()
def stop(self, signum, frame):
asyncore.close_all()
def start(self):
signal.signal(signal.SIGTERM, self.stop)
signal.signal(signal.SIGINT, self.stop)
asyncore.loop(timeout=0.1, use_poll=False)
def demo_app(environ, start_response):
write = start_response('200 OK', [('content-type', 'text/html')])
return ["<html><body><h1>Hello World!</h1><br />%s</body></html>"%time.ctime()]
def test_client(address='127.0.0.1:8000'):
time.sleep(3)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip,port = address.split(':',1)
server.connect((ip,int(port)))
server.send('GET /\r\n\r\n')
while True:
sys.stdout.write(server.recv(1))
sys.stdout.write('CLOSE\n')
if __name__ == "__main__":
#thread.start_new_thread(test_client,())
#thread.start_new_thread(test_client,())
#thread.start_new_thread(test_client,())
WSGIServer(('127.0.0.1', 8000), demo_app).start()
-630
View File
@@ -1,630 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
docstring
"""
__author__ = "Gu Yingbo (tensiongyb@gmail.com)"
import os
import re
import sys
import time
import base64
import asyncore
import asynchat
import rfc822
import socket
import thread
import signal
from traceback import format_exc
from urllib import unquote, splitquery
from urlparse import urlparse
try:
import cStringIO as StringIO
except ImportError:
import StringIO
RN = '\r\n'
RNRN = '\r\n\r\n'
QUOTED_SLASH = re.compile("(?i)%2F")
COMMA_SEPARATED_HEADERS = ['ACCEPT', 'ACCEPT-CHARSET', 'ACCEPT-ENCODING',
'ACCEPT-LANGUAGE', 'ACCEPT-RANGES', 'ALLOW', 'CACHE-CONTROL',
'CONNECTION', 'CONTENT-ENCODING', 'CONTENT-LANGUAGE', 'EXPECT',
'IF-MATCH', 'IF-NONE-MATCH', 'PRAGMA', 'PROXY-AUTHENTICATE', 'TE',
'TRAILER', 'TRANSFER-ENCODING', 'UPGRADE', 'VARY', 'VIA', 'WARNING',
'WWW-AUTHENTICATE']
class RequestHandler(asynchat.async_chat):
def __init__(self, sock, server):
asynchat.async_chat.__init__(self, sock)
self.server = server
self.reset()
def reset(self):
self.ac_in_buffer = ''
self.ac_out_buffer = ''
self.producer_fifo = asynchat.fifo()
self.set_terminator(RNRN)
self.process = "reading headers"
self.started_response = False
self.status = ""
self.outheaders = []
self.sent_headers = False
self.close_connection = False
self.chunked_write = False
self.rfile = StringIO.StringIO()
self.environ = {
"wsgi.version": (1, 0),
"wsgi.url_scheme": "http",
"wsgi.multithread": False,
"wsgi.multiprocess": False,
"wsgi.run_once": False,
"wsgi.errors": sys.stderr,
}
def collect_incoming_data(self, data):
"""Buffer the data"""
if self.process == "reading chunked":
self.line_buffer += data
else:
self.rfile.write(data)
def found_terminator(self):
if self.process == "reading headers":
self.rfile.write(RNRN)
self.rfile.seek(0)
try:
self.parse_request()
except:
self.simple_response("500 Internal Server Error", format_exc())
return
if not self.read_chunked:
if self.environ["REQUEST_METHOD"].upper() == "POST":
cl = int(self.environ["CONTENT_LENGTH"])
self.rfile = StringIO.StringIO()
self.environ["wsgi.input"] = self.rfile
self.process = "dealing post"
self.set_terminator(cl)
else:
return self.wsgi_response()
else:
self.rfile = StringIO.StringIO()
self.environ["wsgi.input"] = self.rfile
self.process = "reading chunked"
self.set_terminator(RN)
self.line_buffer = ""
self.cl = 0
elif self.process == "dealing post":
self.rfile.seek(0)
return self.wsgi_response()
elif self.process == "reading chunked":
line = self.line_buffer.split(";", 1)
chunk_size = int(line.pop(0), 16)
if chunk_size <= 0:
self.process = "reading tail headers"
self.set_terminator(RNRN)
else:
self.cl += chunk_size
self.process = "get chunked"
self.set_terminator(self.cl+2) # browsers sometimes over-send
elif self.process == "get chunked":
crlf = self.rfile.getvalue()[-2:]
if not crlf != RN:
self.simple_response("400 Bad Request",
"Bad chunked transfer coding "
"(expected '\\r\\n', got %r)" % crlf)
return
else:
self.process = "reading chunked"
self.set_terminator(RN)
self.rfile.seek(-2, 2)
self.rfile.truncate()
elif self.process == "reading tail headers":
self.read_headers()
self.rfile.seek(0)
self.environ["CONTENT_LENGTH"] = str(self.cl) or ""
return self.wsgi_response()
def reset_when_done(self):
self.producer_fifo.push(0)
def refill_buffer (self):
while 1:
if len(self.producer_fifo):
p = self.producer_fifo.first()
# a 'None' in the producer fifo is a sentinel,
# telling us to close the channel.
if p == 0:
if not self.ac_out_buffer:
self.producer_fifo.pop()
self.reset()
return
elif p is None:
if not self.ac_out_buffer:
self.producer_fifo.pop()
self.close()
return
elif isinstance(p, str):
self.producer_fifo.pop()
self.ac_out_buffer = self.ac_out_buffer + p
return
data = p.more()
if data:
self.ac_out_buffer = self.ac_out_buffer + data
return
else:
self.producer_fifo.pop()
else:
return
def wsgi_response(self):
try:
self.respond()
except:
self.simple_response("500 Internal Server Error", format_exc())
else:
if self.close_connection or ( not self.server.keep_going ):
self.close_when_done()
else:
self.reset_when_done()
def readable(self):
return self.server.keep_going and not self.writable() and \
asynchat.async_chat.readable(self)
def handle_expt(self):
asynchat.async_chat.handle_expt(self)
self.close()
def handle_error(self):
asynchat.async_chat.handle_error(self)
self.close()
def parse_request(self):
"""
Parse the next HTTP request start-line and message-headers.
HTTP/1.1 connections are persistent by default. If a client
requests a page, then idles (leaves the connection open),
then rfile.readline() will raise socket.error("timed out").
Note that it does this based on the value given to settimeout(),
and doesn't need the client to request or acknowledge the close
(although your TCP stack might suffer for it: cf Apache's history
with FIN_WAIT_2).
"""
request_line = self.rfile.readline()
if not request_line:
# Force self.ready = False so the connection will close.
self.ready = False
return
if request_line == RN:
# RFC 2616 sec 4.1: "...if the server is reading the protocol
# stream at the beginning of a message and receives a CRLF
# first, it should ignore the CRLF."
# But only ignore one leading line! else we enable a DoS.
request_line = self.rfile.readline()
if not request_line:
self.ready = False
return
server = self.server
environ = self.environ
environ["SERVER_SOFTWARE"] = "%s WSGI Server" % server.version
method, path, req_protocol = request_line.strip().split(" ", 2)
environ["REQUEST_METHOD"] = method
# path may be an abs_path (including "http://host.domain.tld");
scheme, location, path, params, qs, frag = urlparse(path)
if frag:
self.simple_response("400 Bad Request",
"Illegal #fragment in Request-URI.")
return
if scheme:
environ["wsgi.url_scheme"] = scheme
if params:
path = path + ";" + params
# Unquote the path+params (e.g. "/this%20path" -> "this path").
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2
#
# But note that "...a URI must be separated into its components
# before the escaped characters within those components can be
# safely decoded." http://www.ietf.org/rfc/rfc2396.txt, sec 2.4.2
atoms = [unquote(x) for x in QUOTED_SLASH.split(path)]
path = "%2F".join(atoms)
environ["SCRIPT_NAME"] = ""
environ["PATH_INFO"] = path
##if path == "*":
## # This means, of course, that the last wsgi_app (shortest path)
## # will always handle a URI of "*".
## environ["SCRIPT_NAME"] = ""
## environ["PATH_INFO"] = "*"
## self.wsgi_app = server.mount_points[-1][1]
##else:
## for mount_point, wsgi_app in server.mount_points:
## # The mount_points list should be sorted by length, descending.
## if path.startswith(mount_point + "/") or path == mount_point:
## environ["SCRIPT_NAME"] = mount_point
## environ["PATH_INFO"] = path[len(mount_point):]
## self.wsgi_app = wsgi_app
## break
## else:
## self.simple_response("404 Not Found")
## return
# Note that, like wsgiref and most other WSGI servers,
# we unquote the path but not the query string.
environ["QUERY_STRING"] = qs
# Compare request and server HTTP protocol versions, in case our
# server does not support the requested protocol. Limit our output
# to min(req, server). We want the following output:
# request server actual written supported response
# protocol protocol response protocol feature set
# a 1.0 1.0 1.0 1.0
# b 1.0 1.1 1.1 1.0
# c 1.1 1.0 1.0 1.0
# d 1.1 1.1 1.1 1.1
# Notice that, in (b), the response will be "HTTP/1.1" even though
# the client only understands 1.0. RFC 2616 10.5.6 says we should
# only return 505 if the _major_ version is different.
rp = int(req_protocol[5]), int(req_protocol[7])
sp = int(server.protocol[5]), int(server.protocol[7])
if sp[0] != rp[0]:
self.simple_response("505 HTTP Version Not Supported")
return
# Bah. "SERVER_PROTOCOL" is actually the REQUEST protocol.
environ["SERVER_PROTOCOL"] = req_protocol
# set a non-standard environ entry so the WSGI app can know what
# the *real* server protocol is (and what features to support).
# See http://www.faqs.org/rfcs/rfc2145.html.
environ["ACTUAL_SERVER_PROTOCOL"] = server.protocol
self.response_protocol = "HTTP/%s.%s" % min(rp, sp)
# If the Request-URI was an absoluteURI, use its location atom.
if location:
environ["SERVER_NAME"] = location
# then all the http headers
try:
self.read_headers()
except ValueError, ex:
self.simple_response("400 Bad Request", repr(ex.args))
return
creds = environ.get("HTTP_AUTHORIZATION", "").split(" ", 1)
environ["AUTH_TYPE"] = creds[0]
if creds[0].lower() == 'basic':
user, pw = base64.decodestring(creds[1]).split(":", 1)
environ["REMOTE_USER"] = user
# Persistent connection support
if self.response_protocol == "HTTP/1.1":
if environ.get("HTTP_CONNECTION", "") == "close":
self.close_connection = True
else:
# HTTP/1.0
if environ.get("HTTP_CONNECTION", "") != "Keep-Alive":
self.close_connection = True
# Transfer-Encoding support
te = None
if self.response_protocol == "HTTP/1.1":
te = environ.get("HTTP_TRANSFER_ENCODING")
if te:
te = [x.strip().lower() for x in te.split(",") if x.strip()]
read_chunked = False
if te:
for enc in te:
if enc == "chunked":
read_chunked = True
else:
# Note that, even if we see "chunked", we must reject
# if there is an extension we don't recognize.
self.simple_response("501 Unimplemented")
self.close_connection = True
return
self.read_chunked = read_chunked
return
if read_chunked:
if not self.decode_chunked():
return
# From PEP 333:
# "Servers and gateways that implement HTTP 1.1 must provide
# transparent support for HTTP 1.1's "expect/continue" mechanism.
# This may be done in any of several ways:
# 1. Respond to requests containing an Expect: 100-continue request
# with an immediate "100 Continue" response, and proceed normally.
# 2. Proceed with the request normally, but provide the application
# with a wsgi.input stream that will send the "100 Continue"
# response if/when the application first attempts to read from
# the input stream. The read request must then remain blocked
# until the client responds.
# 3. Wait until the client decides that the server does not support
# expect/continue, and sends the request body on its own.
# (This is suboptimal, and is not recommended.)
#
# We used to do 3, but are now doing 1. Maybe we'll do 2 someday,
# but it seems like it would be a big slowdown for such a rare case.
if environ.get("HTTP_EXPECT", "") == "100-continue":
self.simple_response(100)
self.ready = True
def new_header(self,k,v):
if k:
environ = self.environ
envname = 'HTTP_'+k
if k in COMMA_SEPARATED_HEADERS:
existing = environ.get(envname)
if existing:
v = ", ".join((existing, v))
environ[envname] = v
def read_headers(self):
"""Read header lines from the incoming stream."""
k = v = None
while True:
line = self.rfile.readline()
if not line or '\0' in line:
# No more data--illegal end of headers
raise ValueError("Illegal headers")
elif line == RN:
# Normal end of headers
self.new_header(k,v)
break
elif line[0] in ' \t':
v += line.strip()
else:
self.new_header(k,v)
k, v = line.split(":", 1)
k, v = k.strip().upper(), v.strip()
environ = self.environ
ct = environ.pop("HTTP_CONTENT_TYPE", None)
if ct:
environ["CONTENT_TYPE"] = ct
cl = environ.pop("HTTP_CONTENT_LENGTH", None)
if cl:
environ["CONTENT_LENGTH"] = cl
def decode_chunked(self):
"""Decode the 'chunked' transfer coding."""
cl = 0
data = StringIO.StringIO()
while True:
line = self.rfile.readline().strip().split(";", 1)
chunk_size = int(line.pop(0), 16)
if chunk_size <= 0:
break
## if line: chunk_extension = line[0]
cl += chunk_size
data.write(self.rfile.read(chunk_size))
crlf = self.rfile.read(2)
if crlf != RN:
self.simple_response("400 Bad Request",
"Bad chunked transfer coding "
"(expected '\\r\\n', got %r)" % crlf)
return
# Grab any trailer headers
self.read_headers()
data.seek(0)
self.environ["wsgi.input"] = data
self.environ["CONTENT_LENGTH"] = str(cl) or ""
return True
def respond(self):
"""
Call the appropriate WSGI app and write its iterable output.
"""
response = self.server.wsgi_app(self.environ, self.start_response)
try:
for chunk in response:
# "The start_response callable must not actually transmit
# the response headers. Instead, it must store them for the
# server or gateway to transmit only after the first
# iteration of the application return value that yields
# a NON-EMPTY string, or upon the application's first
# invocation of the write() callable." (PEP 333)
if chunk:
self.write(chunk)
finally:
if hasattr(response, "close"):
response.close()
if not self.sent_headers:
self.send_headers()
if self.chunked_write:
self.push("0\r\n")
def simple_response(self, status, msg=""):
"""Write a simple response back to the client."""
status = str(status)
buf = ["%s %s\r\n" % (self.server.protocol, status),
"Content-Length: %s\r\n" % len(msg)]
if status[:3] == "413" and self.response_protocol == 'HTTP/1.1':
# Request Entity Too Large
self.close_connection = True
buf.append("Connection: close\r\n")
buf.append(RN)
if msg:
buf.append(msg)
self.push(''.join(buf))
if self.close_connection or ( not self.server.keep_going ):
self.close_when_done()
else:
self.reset_when_done()
def start_response(self, status, headers, exc_info = None):
"""WSGI callable to begin the HTTP response."""
if self.started_response:
if not exc_info:
raise AssertionError("WSGI start_response called a second "
"time with no exc_info.")
else:
try:
raise exc_info[0], exc_info[1], exc_info[2]
finally:
exc_info = None
self.started_response = True
self.status = status
self.outheaders.extend(headers)
return self.write
def write(self, chunk):
"""
WSGI callable to write unbuffered data to the client.
This method is also used internally by start_response (to write
data from the iterable returned by the WSGI application).
"""
if not self.started_response:
raise AssertionError("WSGI write called before start_response.")
if not self.sent_headers:
self.send_headers()
if self.chunked_write and chunk:
buf = [hex(len(chunk))[2:], RN, chunk, RN]
self.push(''.join(buf))
else:
self.push(chunk)
def send_headers(self):
"""
Assert, process, and send the HTTP response message-headers.
"""
self.sent_headers = True
hkeys = [key.lower() for key, value in self.outheaders]
status = int(self.status[:3])
if status == 413:
# Request Entity Too Large. Close conn to avoid garbage.
self.close_connection = True
elif "content-length" not in hkeys:
# "All 1xx (informational), 204 (no content),
# and 304 (not modified) responses MUST NOT
# include a message-body." So no point chunking.
if status < 200 or status in (204, 205, 304):
pass
else:
if self.response_protocol == 'HTTP/1.1':
# Use the chunked transfer-coding
self.chunked_write = True
self.outheaders.append(("Transfer-Encoding", "chunked"))
else:
# Closing the conn is the only way to determine len.
self.close_connection = True
if "connection" not in hkeys:
if self.response_protocol == 'HTTP/1.1':
if self.close_connection:
self.outheaders.append(("Connection", "close"))
else:
if not self.close_connection:
self.outheaders.append(("Connection", "Keep-Alive"))
if "date" not in hkeys:
self.outheaders.append(("Date", rfc822.formatdate()))
server = self.server
if "server" not in hkeys:
self.outheaders.append(("Server", server.version))
buf = [server.protocol, " ", self.status, RN]
try:
buf += [k + ": " + v + RN for k, v in self.outheaders]
except TypeError:
if not isinstance(k, str):
raise TypeError("WSGI response header key %r is not a string.")
if not isinstance(v, str):
raise TypeError("WSGI response header value %r is not a string.")
else:
raise
buf.append(RN)
self.push(''.join(buf))
class WSGIServer(asyncore.dispatcher):
version = "Asynwsgi Server/1.0 alpha"
protocol = "HTTP/1.1"
def __init__(self, bind_addr, wsgi_app, server_name=None):
asyncore.dispatcher.__init__ (self)
self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind(bind_addr)
self.listen(1024)
self.keep_going = True
self.wsgi_app = wsgi_app
if not server_name:
server_name = socket.gethostname()
self.server_name = server_name
def writable(self):
return False
def readable(self):
return self.accepting
def handle_accept(self):
try:
conn, addr = self.accept()
except:
return
RequestHandler(conn, self)
def reload(self, signum, frame):
print 'reloading...'
self.keep_going = False
self.close()
def stop(self, signum, frame):
asyncore.close_all()
def start(self):
signal.signal(signal.SIGTERM, self.stop)
signal.signal(signal.SIGINT, self.stop)
asyncore.loop(timeout=0.1, use_poll=False)
def demo_app(environ, start_response):
write = start_response('200 OK', [('content-type', 'text/html')])
return ["<h1>Hello World!</h1>", "<br />%s"%time.ctime()]
def test_client(address='127.0.0.1:8000'):
time.sleep(3)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip,port = address.split(':',1)
server.connect((ip,int(port)))
server.send('GET /\r\n\r\n')
while True:
sys.stdout.write(server.recv(1))
sys.stdout.write('CLOSE\n')
if __name__ == "__main__":
#thread.start_new_thread(test_client,())
#thread.start_new_thread(test_client,())
#thread.start_new_thread(test_client,())
WSGIServer(('127.0.0.1', 8000), demo_app).start()
-4
View File
@@ -1,4 +0,0 @@
import time
t0 = time.time()
-22
View File
@@ -1,22 +0,0 @@
import os
import time
import re
N = 100000
r = re.compile('^(\S+)\s*\:\s*(.*?)\s*$')
a = "hello : world\r\n"
t0 = time.time()
for k in xrange(N):
items = a.split(':',1)
x,y = items[0].strip(),items[1].strip()
print (time.time()-t0)/N
from gluon.utils import fast_urandom16
t0 = time.time()
for k in xrange(N):
x,y = a.split(':',1)
x,y = x.strip(), y.strip()
print (time.time()-t0)/N
print x,y
-15
View File
@@ -1,15 +0,0 @@
import os
import time
N = 100000
t0 = time.time()
for k in xrange(N):
os.urandom(16)
print (time.time()-t0)/N
from gluon.utils import fast_urandom16
t0 = time.time()
for k in xrange(N):
fast_urandom16()
print (time.time()-t0)/N
-19
View File
@@ -1,19 +0,0 @@
db =DAL()
db.define_table('person',Field('name'))
from gluon.dal import Expression
def IF(a,b,c,t=None):
db,f = a.db, a.db._adapter.expand
def r(x,represent=db._adapter.represent):
if x is None: return 'NULL'
elif isinstance(x,Expression): return str(x)
types = {type(True): 'boolean',
type(0): 'integer',
type(1.0): 'double'}
return represent(x,types.get(type(x),'string'))
return Expression(db,'CASE WHEN %s THEN %s ELSE %s END' % (f(a),r(b),r(c)))
db.person.insert(name='x')
db.person.insert(name='y')
db.person.insert(name='z')
print db().select(db.person.ALL, (db.person.name=='x').case('A',(db.person.name=='y').case('B','C')))
-16
View File
@@ -1,16 +0,0 @@
import re, sys
regex = re.compile('\w+\.\w+')
for line in open(sys.argv[1]).read().split(' def '):
function = line.split('(',1)[0]
links = regex.findall(line)
m = {}
for link in links: m[link]=m.get(link,0)+1
print function
for link, count in sorted([(v,k) for v,k in m.iteritems()]):
if count>1:
print ' ',link, count
-11
View File
@@ -1,11 +0,0 @@
import re
CACHED_REGEXES = {}
def re_compile(regex):
try:
return CACHED_REGEXES[regex]
except KeyError:
compiled_regex = CACHED_REGEXES[regex] = re.compile(regex)
return compiled_regex
-78
View File
@@ -1,78 +0,0 @@
import re
import urllib
import urllib2
class W2POpener(object):
regex = re.compile('\<input name\="_formkey" type\="hidden" value\="(?P<formkey>.+?)" \/\>\<input name\="_formname" type\="hidden" value\="(?P<formname>.+?)" \/\>')
def __init__(self,app=''):
self.app = app
self.cookies = {}
def get(self,url,cookies=None,headers=None,auth=None):
return self.post(url,data=None,cookies=cookies,headers=headers)
def post(self,url,data=None,cookies=None,headers=None,auth=None):
self.url = self.app+url
if cookies is None: cookies = self.cookies
if auth:
auth_handler = urllib2.HTTPBasicAuthHandler()
auth_handler.add_password(**auth)
opener = urllib2.build_opener(auth_handler)
else:
opener = urllib2.build_opener()
headers_list = []
for key,value in (headers or {}).iteritems():
if isinstance(value,(list,tuple)):
for v in value: headers_list.append((key,v))
else:
headers_list.append((key,value))
for key,value in (cookies or {}).iteritems():
headers_list.append(('Cookie','%s=%s' % (key,value)))
for key,value in headers_list:
opener.addheaders.append((key,str(value)))
if data is not None:
# if there is only one form, set _formname automatically
if not '_formname' in data and len(self.forms)==1:
data['_formname'] = self.forms.keys()[0]
# if there is no formkey but it is known, set it
if '_formname' in data and not '_formkey' in data and \
data['_formname'] in self.forms:
data['_formkey'] = self.forms[data['_formname']]
data = urllib.urlencode(data)
self.request = opener.open(self.url,data)
else:
self.request = opener.open(self.url)
self.status = self.request.getcode()
self.text = self.request.read()
self.headers = dict(self.request.headers)
self.cookies = dict(item[:item.find(';')].split('=') for item in \
self.headers.get('set-cookie','').split(','))
self.forms = {}
for match in W2POpener.regex.finditer(self.text):
self.forms[match.group('formname')] = match.group('formkey')
def test_registration_and_login():
session = W2POpener('http://127.0.0.1:8000/welcome/default/')
session.get('user/register')
data = dict(first_name = 'Homer',
last_name = 'Simpson',
email = 'homer@web2py.com',
password = 'test',
password_two = 'test',
_formname = 'register')
session.post('user/register',data = data)
session.get('user/login')
data = dict(email='homer@web2py.com',
password='test',
_formname = 'login')
session.post('user/login',data = data)
session.get('index')
assert 'Welcome Homer' in session.text
if __name__ == '__main__':
test_registration_and_login()
-165
View File
@@ -1,165 +0,0 @@
#!/usr/bin/env python
import sys, os, time, atexit, signal, subprocess
class Daemon:
"""
A generic daemon class.
Usage: subclass the Daemon class and override the run() method
From: http://bit.ly/TnPxwp
Developed by Sander Marechal
Minor modifications by Massimo Di Pierro
"""
def __init__(self,
pidfile,
stdin='/dev/null',
stdout='/dev/null',
stderr=None):
self.stdin = stdin
self.stdout = stdout
self.stderr = stderr
self.pidfile = pidfile
def daemonize(self):
"""
do the UNIX double-fork magic, see Stevens
"Advanced Programming in the UNIX Environment"
for details (ISBN 0201563177)
http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
"""
try:
pid = os.fork()
if pid > 0:
# exit first parent
sys.exit(0)
except OSError, e:
sys.stderr.write("fork #1 failed: %d (%s)\n" % (
e.errno, e.strerror))
sys.exit(1)
# decouple from parent environment
os.chdir("/")
os.setsid()
os.umask(0)
# do second fork
try:
pid = os.fork()
if pid > 0:
# exit from second parent
sys.exit(0)
except OSError, e:
sys.stderr.write("fork #2 failed: %d (%s)\n" % (
e.errno, e.strerror))
sys.exit(1)
# redirect standard file descriptors
sys.stdout.flush()
sys.stderr.flush()
if self.stdin != '/dev/null':
os.mkfifo(self.stdin)
si = open(self.stdin, 'r')
if self.stdout != '/dev/null':
os.mkfifo(self.stdout)
so = open(self.stdout, 'a+')
if self.stderr is None:
se = so
else:
if self.stderr != '/dev/null':
os.mkfifo(self.stderr)
se = open(self.stderr, 'a+', 0)
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
# write pidfile
# atexit.register(self.delpid)
pid = str(os.getpid())
open(self.pidfile,'w+').write("%s\n" % pid)
def delpid(self):
os.remove(self.pidfile)
def start(self):
"""
Start the daemon
"""
# Check for a pidfile to see if the daemon already runs
try:
pf = open(self.pidfile,'r')
pid = int(pf.read().strip())
pf.close()
except IOError:
pid = None
if pid:
message = "pidfile %s already exist. Daemon already running?\n"
sys.stderr.write(message % self.pidfile)
sys.exit(1)
# Start the daemon
self.daemonize()
self.run()
def stop(self):
"""
Stop the daemon
"""
# Get the pid from the pidfile
try:
pf = open(self.pidfile,'r')
pid = int(pf.read().strip())
pf.close()
except IOError:
pid = None
if not pid:
message = "pidfile %s does not exist. Daemon not running?\n"
sys.stderr.write(message % self.pidfile)
return # not an error in a restart
# Try killing the daemon process
try:
while 1:
os.kill(pid, signal.SIGTERM)
time.sleep(0.1)
except OSError, err:
err = str(err)
if err.find("No such process") > 0:
if os.path.exists(self.pidfile):
os.remove(self.pidfile)
else:
print str(err)
sys.exit(1)
def restart(self):
"""
Restart the daemon
"""
self.stop()
self.start()
def run(self):
"""
You should override this method when you subclass Daemon.
It will be called after the process has been
daemonized by start() or restart().
"""
if hasattr(self,'args'):
subprocess.call(self.args,
stdin=sys.stdin,
stdout=sys.stdout,
stderr=sys.stderr,
shell=True)
os.system('rm t1/*')
d = Daemon(
pidfile = '/Users/massimodipierro/Dropbox/web2py/temps/t1/process.pid',
stdin = '/Users/massimodipierro/Dropbox/web2py/temps/t1/fifo.in',
stdout = '/Users/massimodipierro/Dropbox/web2py/temps/t1/fifo.out',
stderr = None)
d.args = ['python looping.py']
d.start()
-14
View File
@@ -1,14 +0,0 @@
import sys
sys.path.append('/Users/massimodipierro/Dropbox/web2py/')
import pickle
from gluon import *
db = DAL()
print db
s = pickle.dumps(db)
db.close()
del db
a = pickle.loads(s)
print repr(a)
print str(a)
print BEAUTIFY(a).xml()
-76
View File
@@ -1,76 +0,0 @@
#!/usr/bin/env python
import sys, os
import subprocess
import threading
import socket
import tempfile
def daemonize():
sys.stdout.flush()
sys.stderr.flush()
pid = os.fork()
if pid<0:
raise RuntimeError, "cannot fork"
elif pid>0:
(pid,status) = os.wait()
sys.exit(status)
os.chdir("/")
os.setsid()
os.umask(0)
pid = os.fork()
if pid<0:
raise RuntimeError, "cannot fork"
elif pid>0:
sys.exit(0)
os.dup2(os.open('/dev/null',os.O_RDONLY),sys.stdin.fileno())
os.dup2(os.open('/dev/null',os.O_WRONLY),sys.stdout.fileno())
os.dup2(os.open('/dev/null',os.O_WRONLY),sys.stderr.fileno())
class SmokingDaemon(threading.Thread):
def __init__(self,
cmd,
path,
tempdir = None):
self.cmd = cmd
self.path = path
self.tempdir = tempdir or tempfile.mkdtemp()
self.fifo_in_name = os.path.join(self.tempdir,'in.fifo')
self.fifo_out_name = os.path.join(self.tempdir,'out.fifo')
self.fifo_err_name = os.path.join(self.tempdir,'err.fifo')
daemonize(path)
threading.Thread.__init__(self)
def run(self):
try: os.unlink(self.fifo_in_name)
except: pass
try: os.unlink(self.fifo_out_name)
except: pass
os.mkfifo(self.fifo_in_name)
os.mkfifo(self.fifo_out_name)
fifo_in_read = os.fdopen(
os.open(self.fifo_in_name,os.O_RDONLY|os.O_NONBLOCK))
self.output = os.fdopen(
os.open(self.fifo_out_name,os.O_RDONLY|os.O_NONBLOCK))
self.input = open(self.fifo_in_name,'a+')
fifo_out_write = open(self.fifo_out_name,'a+')
process = subprocess.call(self.cmd,
shell=True,
stdin=fifo_in_read,
stdout=fifo_out_write,
stderr=fifo_out_write)
sd = SmokingDaemon('ls -l','fifo.in','fifo.out')
sd.start()
sd.server()
sd.join()
open(sd.output.read()
sd = SmokingDaemon(id)
sd.start(command)
sd.stop()
sd.kill()
sd.seek()
sd.read(bytes)
sd.readline()
sd.write('hello world')
-73
View File
@@ -1,73 +0,0 @@
#!/usr/bin/env python
import sys, os
import subprocess
def runCmd( cmd, fifo ):
try:
os.unlink(fifo)
except:
pass
os.mkfifo( "out_fifo" )
try:
fifo = os.fdopen( os.open( "out_fifo",
os.O_RDONLY | os.O_NONBLOCK ) )
newcmd = "( %s ) 1>out_fifo 2>&1"%( cmd, )
process = subprocess.Popen( newcmd, shell = True,
stdout = subprocess.PIPE,
stderr = subprocess.STDOUT )
_localLog.debug( "Running: %s"%( cmd, ) )
while process.returncode == None:
# None means process is still running
# need to poll the process once so the returncode
# gets set (see docs)
process.poll()
try:
line = fifo.readline().strip()
except:
continue
if line:
log.info( line )
remaining = fifo.read()
if remaining:
for line in [ line
for line in remaining.split( "\n" )
if line.strip() ]:
log.info( line.strip() )
if process.returncode:
_localLog.critical( "Return Value: %s"%( process.returncode, ) )
else:
_localLog.debug( "Return Value: %s"%( process.returncode, ) )
finally:
os.unlink( "out_fifo" )
mainlog.debug( os.getcwd() )
print
runCmd( "echo 'bye'", mainlog )
print
runCmd( "/usr/bin/false", mainlog )
print
runCmd( "ls -l; sleep 5; echo 'hi!'; sleep 5; ls -l", mainlog )
print
runCmd( "this_should_not_exists", mainlog )
-4
View File
@@ -1,4 +0,0 @@
import time
for t in range(1000):
print t
time.sleep(5)
-5
View File
@@ -1,5 +0,0 @@
text = """
[[https://groups.google.com/forum/?fromgroups#!forum/web2py/ https://groups.google.com/forum/?fromgroups#!forum/web2py/]]
"""
print MARKMIN(text).xml()
-27
View File
@@ -1,27 +0,0 @@
total 184
-rw-r--r-- 1 massimodipierro staff 31 Aug 26 22:53 benchmark.py
-rw-r--r-- 1 massimodipierro staff 379 Aug 28 17:31 check.py
-rw-r--r-- 1 massimodipierro staff 220 Sep 2 12:08 compile_rotator.py
-rw-r--r-- 1 massimodipierro staff 3135 Aug 29 17:20 cookies.py
-rw-r--r-- 1 massimodipierro staff 4759 Sep 6 16:05 daemon.py
prw-r--r-- 1 massimodipierro staff 0 Sep 7 15:43 fifo.1
-rw-r--r-- 1 massimodipierro staff 671 Sep 7 15:43 fofo.py
-rw-r--r-- 1 massimodipierro staff 1612 Sep 7 15:39 fofo.py.old
-rw-r--r-- 1 massimodipierro staff 663 Sep 7 15:42 fofo.py~
-rw-r--r-- 1 massimodipierro staff 64 Sep 6 15:11 looping.py
-rw-r--r-- 1 massimodipierro staff 0 Sep 7 15:43 out_fifo
-rw-r--r-- 1 massimodipierro staff 1218 Sep 6 15:11 process.py
-rw-r--r-- 1 massimodipierro staff 475 Sep 6 09:32 read.py
-rw-r--r-- 1 massimodipierro staff 3487 Sep 7 15:02 runcmd.log
drwxr-xr-x 3 massimodipierro staff 102 Sep 6 16:04 t1
-rw-r--r-- 1 massimodipierro staff 170 Aug 26 09:45 test1.py
-rw-r--r-- 1 massimodipierro staff 270 Aug 26 10:43 test2.py
-rw-r--r-- 1 massimodipierro staff 1434 Aug 28 18:51 test3.py
-rw-r--r-- 1 massimodipierro staff 649 Aug 30 15:16 test7.py
-rw-r--r-- 1 massimodipierro staff 507 Sep 2 16:41 test8.py
-rw-r--r-- 1 massimodipierro staff 118 Aug 28 14:52 test_1.py
-rw-r--r-- 1 massimodipierro staff 595 Aug 28 10:42 test_bruno.py
-rw-r--r-- 1 massimodipierro staff 515 Aug 28 09:54 test_cache.py
-rw-r--r-- 1 massimodipierro staff 304 Aug 28 14:19 test_dominc.py
-rw-r--r-- 1 massimodipierro staff 2859 Aug 31 10:17 test_jim.py
prw-r--r-- 1 massimodipierro staff 0 Sep 7 13:30 tmp.1
-3
View File
@@ -1,3 +0,0 @@
from gluon.contrib.populate import populate
populate(db.auth_user,10)
print db(db.auth_user).select()
-37
View File
@@ -1,37 +0,0 @@
import os
class Path(object):
def __init__(self,s='/',sep=os.path.sep):
self.sep = sep
self.s = s.split(sep)
def __str__(self):
return self.sep.join(self.s)
def __add__(self,other):
if other[0]=='':
return Path(other)
else:
return Path(str(self)+os.sep+str(other))
def __getitem__(self,i):
return self.s[i]
def __setitem__(self,i,v):
self.s[i] = v
def append(self,v):
self.s.append(v)
@property
def filename(self):
return self.s[-1]
@property
def folder(self):
return Path(self.sep.join(self.s[:-1]))
>>> path = Path('/this/is/an/example.png')
>>> print path[-1]
example.png
>>> print path.filename
example.png
>>> print path.folder
/this/is/an
>>> path[1]='that'
/that/is/an/example.png
>>> print path.folder + 'this'
/that/is/an/this
-6
View File
@@ -1,6 +0,0 @@
from gluon.dal import PostgreSQLAdapter
db = DAL()
db.define_table('test',Field('name'))
db._adapter.close()
db._adapter = PostgreSQLAdapter(db,'postgres://a:b@example.com/demo',do_connect=False)
print db(db.test)._select()
-24
View File
@@ -1,24 +0,0 @@
import pickle
db=DAL()
db.define_table('person',Field('name'))
db.define_table('thing',Field('name'),Field('owner','reference person'))
id = db.person.insert(name='Tim')
db.thing.insert(name='chair',owner=id)
rows = db(db.person).select()
a = pickle.dumps(rows[0])
b = pickle.loads(a)
print b
print type(b)
print b.name
a = pickle.dumps(rows)
b = pickle.loads(a)
print b
print type(b)
print b.db == db
print b[0]['name']
print b.first().name
b.first().update_record(name='Max')
print b.first().thing.select()
-32
View File
@@ -1,32 +0,0 @@
import os
import subprocess
import pickle
class Process(object):
def __init__(self,path):
self.path = path
self.fifo_in_filename = os.path.join(self.path,'fifo.in')
self.fifo_out_filename = os.path.join(self.path,'fifo.out')
self.process_filename = os.path.join(self.path,'process.pickle')
if not os.path.exists(path):
os.mkdir(path)
def run(self,command):
if os.path.exists(self.fifo_in_filename):
os.unlink(self.fifo_in_filename)
if os.path.exists(self.fifo_out_filename):
os.unlink(self.fifo_out_filename)
fifo_in = os.mkfifo(self.fifo_in_filename)
fifo_out = os.mkfifo(self.fifo_out_filename)
s = subprocess.Popen(command, shell=True,
stdin=fifo_in,
stdout=fifo_out,
stderr=fifo_out,
close_fds=True)
pickle.dump(s,open(self.process_filename,'wb'))
def interact(self):
fifo_out = open(self.fifo_out_filename,'rb')
while True:
print 'x',fifo_out.read(1)
p = Process('t1').run('python looping.py')
q = Process('t1').interact()
-12
View File
@@ -1,12 +0,0 @@
import re
import urllib
import urllib2
from BeautifulSoup import BeautifulSoup
page = urllib2.urlopen('http://www.telegraph.co.uk/technology/internet/9524681/Sir-Tim-Berners-Lee-accuses-government-of-draconian-internet-snooping.html')
soup = BeautifulSoup(page)
items = soup.findAll(['h1','h2','h3','h4','h5','h6','p'])
text = '\n'.join(''.join(item.findAll(text=True)) for item in items).encode('utf8')
text = re.sub('\s*\n\s*','\n',re.sub('[ \t]+',' ',text))
print text
-34
View File
@@ -1,34 +0,0 @@
INFO : 2012-09-07 15:02:00,230 : foo : test
DEBUG : 2012-09-07 15:02:00,231 : main : /Users/massimodipierro/Dropbox/web2py/temps
DEBUG : 2012-09-07 15:02:00,237 : runCmd : Running: echo 'bye'
INFO : 2012-09-07 15:02:00,242 : main : bye
DEBUG : 2012-09-07 15:02:00,244 : runCmd : Return Value: 0
DEBUG : 2012-09-07 15:02:00,251 : runCmd : Running: /usr/bin/false
CRITICAL : 2012-09-07 15:02:00,278 : runCmd : Return Value: 1
DEBUG : 2012-09-07 15:02:00,290 : runCmd : Running: ls -l; sleep 5; echo 'hi!'; sleep 5; ls -l
INFO : 2012-09-07 15:02:00,398 : main : total 176
INFO : 2012-09-07 15:02:00,401 : main : -rw-r--r-- 1 massimodipierro staff 31 Aug 26 22:53 benchmark.py
INFO : 2012-09-07 15:02:00,402 : main : -rw-r--r-- 1 massimodipierro staff 379 Aug 28 17:31 check.py
INFO : 2012-09-07 15:02:00,403 : main : -rw-r--r-- 1 massimodipierro staff 220 Sep 2 12:08 compile_rotator.py
INFO : 2012-09-07 15:02:00,403 : main : -rw-r--r-- 1 massimodipierro staff 3135 Aug 29 17:20 cookies.py
INFO : 2012-09-07 15:02:00,404 : main : -rw-r--r-- 1 massimodipierro staff 4759 Sep 6 16:05 daemon.py
INFO : 2012-09-07 15:02:00,404 : main : -rw-r--r-- 1 massimodipierro staff 2759 Sep 7 15:01 fofo.py
INFO : 2012-09-07 15:02:00,405 : main : -rw-r--r-- 1 massimodipierro staff 723 Sep 7 13:43 fofo.py~
INFO : 2012-09-07 15:02:00,405 : main : -rw-r--r-- 1 massimodipierro staff 64 Sep 6 15:11 looping.py
INFO : 2012-09-07 15:02:00,406 : main : prw-r--r-- 1 massimodipierro staff 0 Sep 7 15:02 out_fifo
INFO : 2012-09-07 15:02:00,408 : main : -rw-r--r-- 1 massimodipierro staff 1218 Sep 6 15:11 process.py
INFO : 2012-09-07 15:02:00,409 : main : -rw-r--r-- 1 massimodipierro staff 475 Sep 6 09:32 read.py
INFO : 2012-09-07 15:02:00,410 : main : -rw-r--r-- 1 massimodipierro staff 581 Sep 7 15:02 runcmd.log
INFO : 2012-09-07 15:02:00,410 : main : drwxr-xr-x 3 massimodipierro staff 102 Sep 6 16:04 t1
INFO : 2012-09-07 15:02:00,411 : main : -rw-r--r-- 1 massimodipierro staff 170 Aug 26 09:45 test1.py
INFO : 2012-09-07 15:02:00,412 : main : -rw-r--r-- 1 massimodipierro staff 270 Aug 26 10:43 test2.py
INFO : 2012-09-07 15:02:00,412 : main : -rw-r--r-- 1 massimodipierro staff 1434 Aug 28 18:51 test3.py
INFO : 2012-09-07 15:02:00,413 : main : -rw-r--r-- 1 massimodipierro staff 649 Aug 30 15:16 test7.py
INFO : 2012-09-07 15:02:00,413 : main : -rw-r--r-- 1 massimodipierro staff 507 Sep 2 16:41 test8.py
INFO : 2012-09-07 15:02:00,414 : main : -rw-r--r-- 1 massimodipierro staff 118 Aug 28 14:52 test_1.py
INFO : 2012-09-07 15:02:00,414 : main : -rw-r--r-- 1 massimodipierro staff 595 Aug 28 10:42 test_bruno.py
INFO : 2012-09-07 15:02:00,415 : main : -rw-r--r-- 1 massimodipierro staff 515 Aug 28 09:54 test_cache.py
INFO : 2012-09-07 15:02:00,415 : main : -rw-r--r-- 1 massimodipierro staff 304 Aug 28 14:19 test_dominc.py
INFO : 2012-09-07 15:02:00,416 : main : -rw-r--r-- 1 massimodipierro staff 2859 Aug 31 10:17 test_jim.py
INFO : 2012-09-07 15:02:00,416 : main : prw-r--r-- 1 massimodipierro staff 0 Sep 7 13:30 tmp.1
INFO : 2012-09-07 15:02:05,411 : main : hi!
-109
View File
@@ -1,109 +0,0 @@
import asyncore
import asynchat
import socket
import time
import sys
import thread
import string
RN = '\r\n'
STATUS_READING_HEADERS = 0
STATUS_READING_BODY = 1
STATUS_SENDING_RESPONSE = 2
class http_request_handler(asynchat.async_chat):
def __init__(self, sock, addr, sessions, log):
asynchat.async_chat.__init__(self, sock=sock)
self.addr = addr
self.sessions = sessions
self.ibuffer = []
self.obuffer = ""
self.set_terminator(RN+RN)
self.reading_headers = True
self.handling = False
self.cgi_data = None
self.log = log
self.status = STATUS_READING_HEADERS
def collect_incoming_data(self, data):
"""Buffer the data"""
self.ibuffer.append(data)
def parse_headers(self,data):
if '\0' in data:
first_line, headers = data.split(RM,1)
self.op, self.path_info = first_line.split(' ',1)
lines = headers.replace(RN+' ',' ').replace(RN+'\t',' ').split(RN)
items = [line.split(':',1) for line in lines.split(RN) if ':' in line]
self.headers = dict((item[0].upper(),item[1]) for item in items)
self.close()
def found_terminator(self):
if self.status==STATUS_READING_HEADERS:
self.parse_headers(string.join(self.ibuffer,'')+'\r\n')
self.ibuffer = []
if self.op.upper() == "POST":
clen = self.headers.getheader("content-length")
self.set_terminator(int(clen))
self.status=STATUS_READ_BODY
else:
self.status=STATUS_SEND_RESPONSE
elif self.status==STATUS_READ_BODY:
self.ibuffer
self.set_terminator(None)
for data in self.run_app():
self.push(data)
time.sleep(1)
self.close()
elif not self.handling:
self.set_terminator(None) # browsers sometimes over-send
self.cgi_data = parse(self.headers, "".join(self.ibuffer))
self.handling = True
self.ibuffer = []
self.handle_request()
def handle_write(self):
print 'handle_write', self.buffer
self.send(self.buffer)
self.buffer = ''
def run_app(self):
return ['200 OK\r\n\r\n','Hello\n','World\n','%s\n' % time.ctime()]
class HTTPServer(asyncore.dispatcher):
def __init__(self, host, port, app):
asyncore.dispatcher.__init__(self)
self.host = host
self.port = port
self.app = app
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind((host, port))
self.listen(20)
def handle_accept(self):
pair = self.accept()
if not pair is None:
sock, addr = pair
print 'Incoming connection from %s' % repr(addr)
handler = http_request_handler(sock, addr, SESSIONS, None)
handler.server = self
def test_client(address='127.0.0.1:8000'):
time.sleep(3)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip,port = address.split(':',1)
server.connect((ip,int(port)))
server.send('GET /\r\n\r\nthis the body')
while True:
sys.stdout.write(server.recv(1))
sys.stdout.write('CLOSE\n')
thread.start_new_thread(test_client,())
thread.start_new_thread(test_client,())
thread.start_new_thread(test_client,())
server = HTTPServer('localhost', 8000, lambda e,r: ['data'])
asyncore.loop()
-31
View File
@@ -1,31 +0,0 @@
import threading
class SingletonPool(object):
thread_local = threading.local
locker = threadling.RLock()
pool = dict()
def __new__(cls, uri, *args, **kwargs):
print 'in new'
if not hasattr(thread_local,'db_instances'):
thread_local.db_instances = {}
try:
instance = thread_local.db_instances[uri]
print 'found existing instance'
except KeyError:
instance = super(DAL, cls).__new__(cls, uri, *args, **kwargs)
thread_local.db_instances[uri] = instance
return instance
def __init__(self,uri,*args, **kwargs):
print "INIT"
try:
self.uri
print 'have self.uri',self.uri
except:
self.uri = uri
db=DAL('test')
print 'here'
db=DAL('test')
-42
View File
@@ -1,42 +0,0 @@
import re
regex_url = re.compile(r'''
(^( # (/a/c/f.e/s)
/(?P<a> [\w\s+]+ ) # /a=app
( # (/c.f.e/s)
/(?P<c> [\w\s+]+ ) # /a/c=controller
( # (/f.e/s)
/(?P<f> [\w\s+]+ ) # /a/c/f=function
( # (.e)
\.(?P<e> [\w\s+]+ ) # /a/c/f.e=extension
)?
( # (/s)
/(?P<r> # /a/c/f.e/r=raw_args
.*
)
)?
)?
)?
)?
/?$)
''', re.X)
import time
n=100000
path = '/app/static/f.e/filename'
t0=time.time()
for k in range(n):
m = regex_url.match(path)
m.group('a')
m.group('c')
m.group('f')
print (time.time()-t0)/n
t0=time.time()
for k in range(n):
m = path.split('/')
lm = len(m)
if lm==0: m.append('a')
if lm==1: m.append('c')
if lm==2: m.append('f')
print (time.time()-t0)/n
-11
View File
@@ -1,11 +0,0 @@
from gluon.storage import Storage as Storage
n=10000
import time
s = Storage()
t0 = time.time()
for k in range(n):
s.x = 1
y = s.x
print (time.time()-t0)/n
-12
View File
@@ -1,12 +0,0 @@
db=DAL()
db.define_table('person',Field('name'))
db.person.insert(name="max")
db.person.insert(name="max")
db.person.insert(name="max")
print db(db.person).select().xml(strict=True)
import pickle
print db.person[1]
s = pickle.dumps(db.person[1])
print pickle.loads(s)
-54
View File
@@ -1,54 +0,0 @@
# run with web2py.py -S welcome -N -R thisfile.py
import time
db=DAL()
db.define_table('test',Field('one'))
db(db.test).delete()
for k in range(1000):
db.test.insert(one='one')
db.commit()
n = 100
t0 = time.time()
for k in range(n):
y = db.test.one
print 'time to access field obj',(time.time()-t0)/n
t0 = time.time()
for k in range(n):
rows = db(db.test).select(cacheable=False) # (*)
print 'time to select 1000 recods',(time.time()-t0)/n/1000
row = db(db.test).select().first()
t0 = time.time()
for k in range(n):
y = row.id
y = row.one
print 'time to access field values',(time.time()-t0)/n
"""
Results:
web2py 1.99.7
time to access field obj 5.068 (microseconds)
time to select 1000 recods 38.441 (microseconds)
time to access field values 7.710 (microseconds)
total time to access one field for each of 1000 records: 7748 (microseconds)
web2py 2.0
time to access field obj 0.579 (microseconds)
time to select 1000 recods 33.820 (microseconds)
time to access field values 0.338 (microseconds)
total time to access one field for each of 1000 records: 371 (microseconds)
web2py 2.0 w cacheable = True (*)
time to access field obj 0.579 (microseconds)
time to select 1000 recods 24.741 (microseconds)
time to access field values 0.300 (microseconds)
total time to access one field for each of 1000 records: 324 (microseconds)
(benhcmarks with SQLite on Mac Air and python 2.7)
"""
-17
View File
@@ -1,17 +0,0 @@
db=DAL()
db.define_table('Meet',Field('name'))
db.define_table('Team',Field('name'))
db.define_table('Participant_team',
Field('Meet',db.Meet),
Field('Team',db.Team))
a=db.Meet.insert(name='here')
b=db.Team.insert(name='snakes')
db.Participant_team.insert(Meet=a,Team=b)
teamStaff = db(db.Meet.id == a).select(
db.Meet.ALL, db.Team.ALL,
join = db.Team.on(
(db.Participant_team.Meet == db.Meet.id) &
(db.Participant_team.Team == db.Team.id)))
print teamStaff
-9
View File
@@ -1,9 +0,0 @@
db=DAL()
db.define_table('t',Field('a'))
db.t.insert(a='xxx')
rows = db(db.t).select()
import pickle
print pickle.loads(pickle.dumps(rows))
rows = db(db.t).select(cacheable=True)
s= pickle.dumps(rows)
print pickle.loads(s)
-17
View File
@@ -1,17 +0,0 @@
db = DAL(lazy_tables = True)
db.define_table('x',
Field('name', 'string')
)
db.define_table('y',
Field('x', 'reference x'),
Field('age', 'integer', default = 30)
)
x_id = db.x.insert(name = 'barry')
db.y.insert(x = x_id, age = 99)
x = db(db.x.id > 0).select().first()
for y in x.y.select():
print y
-5
View File
@@ -1,5 +0,0 @@
db=DAL()
db.define_table('test',Field('myid','id'),Field('name'))
db.test.insert(name='max')
row=db.test[1]
print row
-21
View File
@@ -1,21 +0,0 @@
db=DAL()
db.define_table("article",
Field("title"),
Field("slug"),
Field("number_of_views", "integer", default=0)
)
def printer(row):
print row
return True
db.article.slug.compute = lambda row: printer(row) and IS_SLUG()(row.title)[0]
article_id = db.article.insert(title='This is a Test')
row = db.article[article_id]
print 'xxx1'
print row.update_record(number_of_views=row.number_of_views + 1)
print row.update_record(number_of_views=row.number_of_views + 1)
print row.update_record(number_of_views=row.number_of_views + 1)
print 'xxx2'
print row
-16
View File
@@ -1,16 +0,0 @@
import sys, time
sys.path.append('/Users/massimodipierro/Dropbox/web2py')
from gluon.cache import CacheOnDisk
from gluon.storage import Storage
request = Storage()
request.folder = '/Users/massimodipierro/Dropbox/web2py/applications/welcome'
c = CacheOnDisk(request)
hello = c('key',lambda:'hello',0)
print hello
hello = c('key',lambda:'world',None)
print hello
hello = c('key',lambda:'world',1)
print hello
time.sleep(2)
hello = c('key',lambda:'world',1)
print hello
-8
View File
@@ -1,8 +0,0 @@
db=DAL()
db.define_table('person',Field('name'))
id = db.person.insert(name="max")
assert(id.name=='max')
db.define_table('dog',Field('name'),Field('owner','reference person'))
db.dog.insert(name='skipper',owner=1)
row = db(db.person.id==db.dog.owner).select().first()
assert(row[db.person.name]=='max')
-71
View File
@@ -1,71 +0,0 @@
import datetime
import os
db = DAL()
from gluon.tools import Auth
auth = Auth(db) # authentication/authorization
auth_user = db.define_table(
auth.settings.table_user_name,
Field('first_name', length=128, default='', required=True),
Field('last_name', length=128, default='', required=True),
Field('email', length=128, unique=True, required=True),
Field('password', 'password', length=512,
readable=True, writable=True, label='Password'),
Field('registration_key', length=512,
writable=False, readable=False, default=''),
Field('reset_password_key', length=512,
writable=False, readable=False, default=''),
Field('registration_id', length=512,
writable=False, readable=False, default=''),
Field('brillLogon', length=10, default='', label='Brill Logon'),
Field('technician', 'boolean', default=False),
Field('dispatcher', 'boolean', default=False),
Field('lastFirst', compute=lambda u: '%s, %s' % (u['last_name'], u['first_name']), label='Name'),
Field('firstLast', compute=lambda u: '%s %s' % (u['first_name'], u['last_name']), label='Name'),
format='%(last_name)s, %(first_name)s')
auth_user.first_name.requires = IS_NOT_EMPTY(error_message=auth.messages.is_empty)
auth_user.last_name.requires = IS_NOT_EMPTY(error_message=auth.messages.is_empty)
auth_user.password.requires = [CRYPT()]
auth_user.email.requires = [IS_EMAIL(error_message=auth.messages.invalid_email),
IS_NOT_IN_DB(db, auth_user.email),
IS_NOT_EMPTY(error_message=auth.messages.is_empty)]
auth_user.id.readable = False
auth_user._plural = 'Users'
auth.settings.table_user = auth_user
auth.define_tables() # creates all needed tables
warehouse = db.define_table('warehouse',
Field('warehouseId', 'id'),
Field('warehouseNumber', 'integer', required=True, unique=True, label='Warehouse #'),
Field('name', length=50, required=True, unique=True),
Field('allowPricesToFall', 'boolean', default=False,
label='Allow Prices to Fall'),
Field('hin', length=10),
Field('active', 'boolean', default=True),
format='%(warehouseNumber)s - %(name)s')
warehouse.warehouseNumber.requires = [IS_NOT_EMPTY(error_message=auth.messages.is_empty),
IS_NOT_IN_DB(db, warehouse.warehouseNumber)]
warehouse.name.requires = [IS_NOT_IN_DB(db, warehouse.name),
IS_NOT_EMPTY(error_message=auth.messages.is_empty)]
warehouse._plural = 'Warehouses'
link = db.define_table('link',
Field('linkId', 'id', readable=False),
Field('name', length=50, required=True, unique=True),
Field('parentLinkId', 'reference link', required=True,
label='Parent Link'),
Field('controller', length=512, required=True),
Field('method', length=512, required=True),
Field('picture', length=512, required=False),
Field('permissionId', db.auth_permission, label='Rqd Permission'),
Field('groupId', db.auth_group, label='Rqd Group'),
Field('description', 'text', required=True),
format='%(name)s')
-16
View File
@@ -1,16 +0,0 @@
import os, time
from gluon.contrib.webclient import WebClient
s = WebClient('http://127.0.0.1:8000/test2/test/')
s.get('index')
print s.sessions
id = s.sessions['test2']
time.sleep(1)
#print os.path.getmtime(os.path.join('applications','test2','sessions',id))
s.get('index')
id = s.sessions['test2']
#print os.path.getmtime(os.path.join('applications','test2','sessions',id))
-11
View File
@@ -1,11 +0,0 @@
import copy
db =DAL()
db._adapter.types = copy.copy(db._adapter.types)
db._adapter.types['boolean']='INTEGER'
db._adapter.TRUE = 1
db._adapter.FALSE = 0
db.define_table('test',Field('b', 'boolean'))
db.test.insert(b=True)
db.test.insert(b=False)
rows = db(db.test).select()
print db.executesql(db(db.test)._select())
-18
View File
@@ -1,18 +0,0 @@
import sys
sys.path.append('../')
from gluon.dal import DAL, THREAD_LOCAL
import pickle
db =DAL()
s = pickle.dumps(db)
db.close()
a = pickle.loads(s)
print THREAD_LOCAL.db_instances, THREAD_LOCAL.db_instances_zombie
db =DAL()
print a is db
print THREAD_LOCAL.db_instances, THREAD_LOCAL.db_instances_zombie
b = pickle.loads(s)
print THREAD_LOCAL.db_instances, THREAD_LOCAL.db_instances_zombie
print a is b
c = DAL()
print a is c
-29
View File
@@ -1,29 +0,0 @@
Metadata-Version: 1.0
Name: web2py
Version: 2.1.1
Summary: full-stack framework for rapid development and prototyping
of secure database-driven web-based applications, written and
programmable in Python.
Home-page: http://web2py.com
Author: Massimo Di Pierro
Author-email: mdipierro@cs.depaul.edu
License: http://web2py.com/examples/default/license
Description:
Everything in one package with no dependencies. Development, deployment,
debugging, testing, database administration and maintenance of applications can
be done via the provided web interface. web2py has no configuration files,
requires no installation, can run off a USB drive. web2py uses Python for the
Model, the Views and the Controllers, has a built-in ticketing system to manage
errors, an internationalization engine, works with SQLite, PostgreSQL, MySQL,
MSSQL, FireBird, Oracle, IBM DB2, Informix, Ingres, sybase and Google App Engine via a
Database Abstraction Layer. web2py includes libraries to handle
HTML/XML, RSS, ATOM, CSV, RTF, JSON, AJAX, XMLRPC, WIKI markup. Production
ready, capable of upload/download streaming of very large files, and always
backward compatible.
Platform: Windows
Platform: Linux
Platform: Mac
Platform: Unix
Platform: Windows Mobile
Classifier: Development Status :: 5 - Production/Stable
-160
View File
@@ -1,160 +0,0 @@
LICENSE
MANIFEST.in
README
VERSION
setup.py
w2p_apps
w2p_clone
w2p_run
gluon/__init__.py
gluon/admin.py
gluon/cache.py
gluon/cfs.py
gluon/compileapp.py
gluon/contenttype.py
gluon/custom_import.py
gluon/dal.py
gluon/debug.py
gluon/decoder.py
gluon/fileutils.py
gluon/globals.py
gluon/highlight.py
gluon/html.py
gluon/http.py
gluon/import_all.py
gluon/languages.py
gluon/main.py
gluon/messageboxhandler.py
gluon/myregex.py
gluon/newcron.py
gluon/portalocker.py
gluon/reserved_sql_keywords.py
gluon/restricted.py
gluon/rewrite.py
gluon/rocket.py
gluon/sanitizer.py
gluon/scheduler.py
gluon/serializers.py
gluon/settings.py
gluon/shell.py
gluon/sql.py
gluon/sqlhtml.py
gluon/storage.py
gluon/streamer.py
gluon/template.py
gluon/tools.py
gluon/utf8.py
gluon/utils.py
gluon/validators.py
gluon/widget.py
gluon/winservice.py
gluon/xmlrpc.py
gluon/contrib/AuthorizeNet.py
gluon/contrib/DowCommerce.py
gluon/contrib/__init__.py
gluon/contrib/aes.py
gluon/contrib/autolinks.py
gluon/contrib/feedparser.py
gluon/contrib/gae_memcache.py
gluon/contrib/gae_retry.py
gluon/contrib/generics.py
gluon/contrib/google_wallet.py
gluon/contrib/gql.py
gluon/contrib/imageutils.py
gluon/contrib/memdb.py
gluon/contrib/pam.py
gluon/contrib/pbkdf2.py
gluon/contrib/populate.py
gluon/contrib/pyfpdf.py
gluon/contrib/qdb.py
gluon/contrib/redis_cache.py
gluon/contrib/redis_session.py
gluon/contrib/rss2.py
gluon/contrib/shell.py
gluon/contrib/simplejsonrpc.py
gluon/contrib/sms_utils.py
gluon/contrib/spreadsheet.py
gluon/contrib/stripe.py
gluon/contrib/taskbar_widget.py
gluon/contrib/timecollect.py
gluon/contrib/user_agent_parser.py
gluon/contrib/webclient.py
gluon/contrib/websocket_messaging.py
gluon/contrib/fpdf/__init__.py
gluon/contrib/fpdf/fonts.py
gluon/contrib/fpdf/fpdf.py
gluon/contrib/fpdf/html.py
gluon/contrib/fpdf/php.py
gluon/contrib/fpdf/template.py
gluon/contrib/fpdf/ttfonts.py
gluon/contrib/gateways/__init__.py
gluon/contrib/gateways/fcgi.py
gluon/contrib/login_methods/__init__.py
gluon/contrib/login_methods/basic_auth.py
gluon/contrib/login_methods/browserid_account.py
gluon/contrib/login_methods/cas_auth.py
gluon/contrib/login_methods/dropbox_account.py
gluon/contrib/login_methods/email_auth.py
gluon/contrib/login_methods/extended_login_form.py
gluon/contrib/login_methods/gae_google_account.py
gluon/contrib/login_methods/ldap_auth.py
gluon/contrib/login_methods/linkedin_account.py
gluon/contrib/login_methods/loginza.py
gluon/contrib/login_methods/motp_auth.py
gluon/contrib/login_methods/oauth10a_account.py
gluon/contrib/login_methods/oauth20_account.py
gluon/contrib/login_methods/openid_auth.py
gluon/contrib/login_methods/pam_auth.py
gluon/contrib/login_methods/rpx_account.py
gluon/contrib/login_methods/x509_auth.py
gluon/contrib/markdown/__init__.py
gluon/contrib/markdown/markdown2.py
gluon/contrib/markmin/__init__.py
gluon/contrib/markmin/markmin2html.py
gluon/contrib/markmin/markmin2latex.py
gluon/contrib/markmin/markmin2pdf.py
gluon/contrib/memcache/__init__.py
gluon/contrib/memcache/memcache.py
gluon/contrib/pymysql/__init__.py
gluon/contrib/pymysql/charset.py
gluon/contrib/pymysql/connections.py
gluon/contrib/pymysql/converters.py
gluon/contrib/pymysql/cursors.py
gluon/contrib/pymysql/err.py
gluon/contrib/pymysql/times.py
gluon/contrib/pymysql/util.py
gluon/contrib/pyrtf/Constants.py
gluon/contrib/pyrtf/Elements.py
gluon/contrib/pyrtf/PropertySets.py
gluon/contrib/pyrtf/Renderer.py
gluon/contrib/pyrtf/Styles.py
gluon/contrib/pyrtf/__init__.py
gluon/contrib/pysimplesoap/__init__.py
gluon/contrib/pysimplesoap/client.py
gluon/contrib/pysimplesoap/server.py
gluon/contrib/pysimplesoap/simplexml.py
gluon/contrib/pysimplesoap/transport.py
gluon/contrib/simplejson/__init__.py
gluon/contrib/simplejson/decoder.py
gluon/contrib/simplejson/encoder.py
gluon/contrib/simplejson/ordered_dict.py
gluon/contrib/simplejson/scanner.py
gluon/contrib/simplejson/tool.py
gluon/tests/__init__.py
gluon/tests/test_cache.py
gluon/tests/test_contribs.py
gluon/tests/test_dal.py
gluon/tests/test_html.py
gluon/tests/test_is_url.py
gluon/tests/test_languages.py
gluon/tests/test_markmin.py
gluon/tests/test_router.py
gluon/tests/test_routes.py
gluon/tests/test_storage.py
gluon/tests/test_template.py
gluon/tests/test_utils.py
gluon/tests/test_web.py
web2py.egg-info/PKG-INFO
web2py.egg-info/SOURCES.txt
web2py.egg-info/dependency_links.txt
web2py.egg-info/top_level.txt
-1
View File
@@ -1 +0,0 @@
-13
View File
@@ -1,13 +0,0 @@
gluon/contrib/gateways
gluon/contrib/markmin
gluon/contrib/markdown
gluon/contrib/pyrtf
gluon/contrib/pymysql
gluon/contrib/fpdf
gluon
gluon/contrib
gluon/tests
gluon/contrib/login_methods
gluon/contrib/pysimplesoap
gluon/contrib/simplejson
gluon/contrib/memcache
BIN
View File
Binary file not shown.
Binary file not shown.