diff --git a/VERSION b/VERSION index 6d0bcfe0..002e289d 100644 --- a/VERSION +++ b/VERSION @@ -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 diff --git a/certificates/web2py.com/new-digitss.csr b/certificates/web2py.com/new-digitss.csr deleted file mode 100644 index fdca57bf..00000000 --- a/certificates/web2py.com/new-digitss.csr +++ /dev/null @@ -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----- diff --git a/certificates/web2py.com/new-digitss.key b/certificates/web2py.com/new-digitss.key deleted file mode 100644 index 6244f2b7..00000000 --- a/certificates/web2py.com/new-digitss.key +++ /dev/null @@ -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----- diff --git a/dist/web2py-2.1.1.tar.gz b/dist/web2py-2.1.1.tar.gz deleted file mode 100644 index 8ca6f521..00000000 Binary files a/dist/web2py-2.1.1.tar.gz and /dev/null differ diff --git a/temps/asynwsgi.py b/temps/asynwsgi.py deleted file mode 100644 index edac590f..00000000 --- a/temps/asynwsgi.py +++ /dev/null @@ -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 ["

Hello World!


%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() diff --git a/temps/asynwsgi2.py b/temps/asynwsgi2.py deleted file mode 100644 index 91040265..00000000 --- a/temps/asynwsgi2.py +++ /dev/null @@ -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 ["

Hello World!

", "
%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() diff --git a/temps/benchmark.py b/temps/benchmark.py deleted file mode 100644 index 5936886f..00000000 --- a/temps/benchmark.py +++ /dev/null @@ -1,4 +0,0 @@ -import time - -t0 = time.time() - diff --git a/temps/bm_split.py b/temps/bm_split.py deleted file mode 100644 index 9dd1660e..00000000 --- a/temps/bm_split.py +++ /dev/null @@ -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 diff --git a/temps/bm_urandom.py b/temps/bm_urandom.py deleted file mode 100644 index c7998870..00000000 --- a/temps/bm_urandom.py +++ /dev/null @@ -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 diff --git a/temps/case.py b/temps/case.py deleted file mode 100644 index b7952077..00000000 --- a/temps/case.py +++ /dev/null @@ -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'))) diff --git a/temps/check.py b/temps/check.py deleted file mode 100644 index 2377a0e9..00000000 --- a/temps/check.py +++ /dev/null @@ -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 - - - diff --git a/temps/compile_rotator.py b/temps/compile_rotator.py deleted file mode 100644 index a41c49ae..00000000 --- a/temps/compile_rotator.py +++ /dev/null @@ -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 - diff --git a/temps/cookies.py b/temps/cookies.py deleted file mode 100644 index 73b91306..00000000 --- a/temps/cookies.py +++ /dev/null @@ -1,78 +0,0 @@ -import re -import urllib -import urllib2 - -class W2POpener(object): - regex = re.compile('\\') - - 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() - diff --git a/temps/daemon.py b/temps/daemon.py deleted file mode 100644 index 65317569..00000000 --- a/temps/daemon.py +++ /dev/null @@ -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() diff --git a/temps/db.py b/temps/db.py deleted file mode 100644 index e6776cee..00000000 --- a/temps/db.py +++ /dev/null @@ -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() diff --git a/temps/fofo.py b/temps/fofo.py deleted file mode 100644 index 0d32f44b..00000000 --- a/temps/fofo.py +++ /dev/null @@ -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') diff --git a/temps/fofo.py.old b/temps/fofo.py.old deleted file mode 100644 index ba59ea37..00000000 --- a/temps/fofo.py.old +++ /dev/null @@ -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 ) - diff --git a/temps/looping.py b/temps/looping.py deleted file mode 100644 index 623c92ee..00000000 --- a/temps/looping.py +++ /dev/null @@ -1,4 +0,0 @@ -import time -for t in range(1000): - print t - time.sleep(5) diff --git a/temps/mmpy b/temps/mmpy deleted file mode 100644 index 81ede4a3..00000000 --- a/temps/mmpy +++ /dev/null @@ -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() diff --git a/temps/out_fifo b/temps/out_fifo deleted file mode 100644 index d450450e..00000000 --- a/temps/out_fifo +++ /dev/null @@ -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 diff --git a/temps/p.py b/temps/p.py deleted file mode 100644 index 1edfaad6..00000000 --- a/temps/p.py +++ /dev/null @@ -1,3 +0,0 @@ -from gluon.contrib.populate import populate -populate(db.auth_user,10) -print db(db.auth_user).select() diff --git a/temps/path.py b/temps/path.py deleted file mode 100644 index 03b9fb09..00000000 --- a/temps/path.py +++ /dev/null @@ -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 diff --git a/temps/pg.py b/temps/pg.py deleted file mode 100644 index ce4af336..00000000 --- a/temps/pg.py +++ /dev/null @@ -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() diff --git a/temps/pi.py b/temps/pi.py deleted file mode 100644 index aa8238a1..00000000 --- a/temps/pi.py +++ /dev/null @@ -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() diff --git a/temps/process.py b/temps/process.py deleted file mode 100644 index 864e08d1..00000000 --- a/temps/process.py +++ /dev/null @@ -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() diff --git a/temps/read.py b/temps/read.py deleted file mode 100644 index 6356bf2e..00000000 --- a/temps/read.py +++ /dev/null @@ -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 diff --git a/temps/runcmd.log b/temps/runcmd.log deleted file mode 100644 index cc63a1f7..00000000 --- a/temps/runcmd.log +++ /dev/null @@ -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! diff --git a/temps/server.py b/temps/server.py deleted file mode 100644 index 6c2db90a..00000000 --- a/temps/server.py +++ /dev/null @@ -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() diff --git a/temps/singleton.py b/temps/singleton.py deleted file mode 100644 index c1f28244..00000000 --- a/temps/singleton.py +++ /dev/null @@ -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') diff --git a/temps/static.py b/temps/static.py deleted file mode 100644 index c9ac6566..00000000 --- a/temps/static.py +++ /dev/null @@ -1,42 +0,0 @@ -import re - -regex_url = re.compile(r''' - (^( # (/a/c/f.e/s) - /(?P [\w\s+]+ ) # /a=app - ( # (/c.f.e/s) - /(?P [\w\s+]+ ) # /a/c=controller - ( # (/f.e/s) - /(?P [\w\s+]+ ) # /a/c/f=function - ( # (.e) - \.(?P [\w\s+]+ ) # /a/c/f.e=extension - )? - ( # (/s) - /(?P # /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 diff --git a/temps/test1.py b/temps/test1.py deleted file mode 100644 index 77aabd99..00000000 --- a/temps/test1.py +++ /dev/null @@ -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 - diff --git a/temps/test2.py b/temps/test2.py deleted file mode 100644 index 62063fd0..00000000 --- a/temps/test2.py +++ /dev/null @@ -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) diff --git a/temps/test3.py b/temps/test3.py deleted file mode 100644 index 902ddf2f..00000000 --- a/temps/test3.py +++ /dev/null @@ -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) -""" - diff --git a/temps/test7.py b/temps/test7.py deleted file mode 100644 index 55a50302..00000000 --- a/temps/test7.py +++ /dev/null @@ -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 diff --git a/temps/test8.py b/temps/test8.py deleted file mode 100644 index 96d7309b..00000000 --- a/temps/test8.py +++ /dev/null @@ -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) diff --git a/temps/test9.py b/temps/test9.py deleted file mode 100644 index 1814f766..00000000 --- a/temps/test9.py +++ /dev/null @@ -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 diff --git a/temps/test_1.py b/temps/test_1.py deleted file mode 100644 index ce8e701b..00000000 --- a/temps/test_1.py +++ /dev/null @@ -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 diff --git a/temps/test_bruno.py b/temps/test_bruno.py deleted file mode 100644 index 0fdbcc9e..00000000 --- a/temps/test_bruno.py +++ /dev/null @@ -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 diff --git a/temps/test_cache.py b/temps/test_cache.py deleted file mode 100644 index b8437b3d..00000000 --- a/temps/test_cache.py +++ /dev/null @@ -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 diff --git a/temps/test_dominc.py b/temps/test_dominc.py deleted file mode 100644 index 883e4f95..00000000 --- a/temps/test_dominc.py +++ /dev/null @@ -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') diff --git a/temps/test_jim.py b/temps/test_jim.py deleted file mode 100644 index 147279f1..00000000 --- a/temps/test_jim.py +++ /dev/null @@ -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') diff --git a/temps/test_session.py b/temps/test_session.py deleted file mode 100644 index e167db2d..00000000 --- a/temps/test_session.py +++ /dev/null @@ -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)) - - - - diff --git a/temps/types.py b/temps/types.py deleted file mode 100644 index 4b548a8f..00000000 --- a/temps/types.py +++ /dev/null @@ -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()) diff --git a/temps/zombie.py b/temps/zombie.py deleted file mode 100644 index 0a79524e..00000000 --- a/temps/zombie.py +++ /dev/null @@ -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 diff --git a/web2py.egg-info/PKG-INFO b/web2py.egg-info/PKG-INFO deleted file mode 100644 index b65d93af..00000000 --- a/web2py.egg-info/PKG-INFO +++ /dev/null @@ -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 diff --git a/web2py.egg-info/SOURCES.txt b/web2py.egg-info/SOURCES.txt deleted file mode 100644 index 8fc5186c..00000000 --- a/web2py.egg-info/SOURCES.txt +++ /dev/null @@ -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 \ No newline at end of file diff --git a/web2py.egg-info/dependency_links.txt b/web2py.egg-info/dependency_links.txt deleted file mode 100644 index 8b137891..00000000 --- a/web2py.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/web2py.egg-info/top_level.txt b/web2py.egg-info/top_level.txt deleted file mode 100644 index 3621de16..00000000 --- a/web2py.egg-info/top_level.txt +++ /dev/null @@ -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 diff --git a/web2py_src.zip b/web2py_src.zip index 9899f1cb..c6d0cd6c 100644 Binary files a/web2py_src.zip and b/web2py_src.zip differ diff --git a/web2py_src_old.zip b/web2py_src_old.zip index f8af1b40..9899f1cb 100644 Binary files a/web2py_src_old.zip and b/web2py_src_old.zip differ