2.4 (2005-12-14) r27719: * Fix cimport bug (caused None to be bound to an imported name that did not exist). * Add Publisher.process(), which is like process_request() except that the caller provides an input stream and an environment instead of an HTTPRequest instance. Modify the included drivers to use process() instead of process_request(). * Update widgets.txt doc file (from Titus Brown). 2.3 (2005-10-18) r27556: * Remove some typechecking asserts from sendmail module to allow for unicode. * Make the generated http response header for content length be a str instead of an int. 2.2 (2005-9-27) r27459: * Remove check_session_addr from Config.config_var_list. * Remove Config.dump(). * When the PATH_INFO does not start with a '/' (or is empty), return a redirect instead of raising AssertionError. * Change htmltextObject_Check() to allow subtypes. * Improve unicode/charset handling. Add quixote.DEFAULT_CHARSET and use this as needed to encode log output, email bodies, and response bodies. When the response body is a str, let it pass through without re-encoding. When the response charset is None, omit the charset parameter from the content-type header. Use the default charset for decoding multipart requests. * Replace relative import in ptl_import.py. * Introduce a unicode-wrapper helper class to be used by htmltext formatting. It's purpose is to work around a PyString_Format bug that exists in all current versions of Python. Thanks go to Alexander J. Kozlovsky for the idea and for various other minor fixes. 2.1 (2005-8-9) r27151: * Make htmltag work better with unicode attribute values. * Modify publisher's exception handler to let SystemExit through. * Modify simple server so that SystemExit exceptions that make it to the server's error handler really are terminal. * Make encoding declarations work in ptl files. * Add HEAD request support to the simple server. * Modify simple server to avoid duplicate Date headers. * Add include_body keyword to response write(). 2.0 (2005-4-12) r26537: * Remove SessionError: just make a new session when the cookie does not identify an existing one. Remove CHECK_SESSION_ADDR configuration variable. * Gather ptl-related code into a sub-package: quixote.ptl. Add quixote.ptl.install: importing this module installs the ptl import hooks. Add quixote.ptl.ptlrun.py, a script for running ptl files from the command line. Gather the quixote.html and support files for htmltext into a sub-package. These changes should be compatible with current code, except that quixote.ptl_import is now in quixote.ptl.ptl_import, quixote.qx_distutils is now in quixote.ptl.qx_distutils, quixote._py_htmltext is now quixote.html._py_htmltext, and quixote._c_htmltext is now quixote.html._c_htmltext. * Insert REMOTE_USER environment value. * Change name: html_url() -> url_with_query() * Have StaticFile set the Expires header for 304 responses. * Add --https option to simple server to support https through stunnel. * Allow the label for the 'Add row' button to be specified for WidgetDict. * Add Session.get_user(). * Add Daniele Varrazzo's patch to _c_htmltext.c that makes it work on win32 with the mingw compiler. * Use private_msg when Directory raises TraversalError. * Allow setting of request's DEFAULT_CHARSET. 2.0a5 (2005-3-7) r26297: * SessionPublisher merged into Publisher. * Publisher 'session_mgr' keyword changed to 'session_manager'. * Form 'action_url' keyword and attribute changed to 'action.' * Make sure that HTTPResponse charset attribute is a str. * Don't require the traversed-into-object to be a Directory. * Make redirect() call str() on the location, so that calls from ptl templates don't need to. * Add an html_url() function that assembles a quoted url with a query. * Don't remove double-slashes from the path. * Make it easier to customize form error messages. * Make Form and Widget new-style classes so that properties can be used on them. * Call maintain_session on "interrupted" requests, too. * Add class variables with default values for content_type and charset. * Add HTTPRequest.get_fields(). * Add HTTPRequest.get_cookies(). * Remove name keyword from Form constructor. 2.0a4 (2005-1-19) r25893: * Remove support for $-substition. If you changed existing templates to work with 2.0a2 or 2.0a3 by escaping $'s, then you should change them back. * Change simple_server so that the PATH_INFO value is unquoted. * Add HTTPResponse.get_content_type(). * Update mod_python_handler.py to Quixote 2. 2.0a3 (2004-12-09) r25738: * Update most of the doc files. Add q1 -> q2 upgrade notes. Put notes at the start of the remaining doc files so that the reader knows that they have not been updated. * Make the simple_server provide remaining HTTP_* headers. * Generate a valid HTML document when listing static directories. Also, use get_path() instead of REQUEST_URI. * Work file upload into the basic forms demo. * Remove old session demo. The altdemo.py serves this purpose. * Add mini_demo. * Use the Twisted addCookie() method. It allows multiple Set-Cookie headers to end up in the response. * Fix a string formatting but that affected the htmltext type. 2.0a2 (2004-11-23) r25669: * Refactor the Publisher object. The new design gives "namespaces" more control over traversal. Packages are no longer imported automatically. By default, namespaces must be 'Directory' instances. The _q_access hook is gone. The 'namespace_stack' attribute is also gone. * Provide a Publisher object that works more like Quixote 1 (available in the 'publish1' module). Also, restore the original form framework with the name 'form1'. * Stop passing HTTPRequest to exported functions and _q_lookup(). You will need to use get_request() to access it. Also, require that _q_index be explicitly exported. * Remove the HTTPRequest.redirect() method. * Split error log and access log functionality into a separate class. Try to simplify site configuration. Configuration options can now be passed as keyword args to the Publisher class. The setup_logs() and shutdown_logs() methods are gone. Logs are now opened when the publisher is initialized. * Support $-substitution in templates, as in Python 2.4's string.Template class. $-substitution is applied to every '$'-containing literal in a template. Templates written before this change, if they contain literals containing '$', *must* be converted by replacing each '$' with '$$'. * Remove support for old style templates and support for versions of Python older than 2.3. * Use a common pattern for interfacing with HTTP servers. Simplify and cleanup the Medusa and Twisted code. Add a SCGI server module (it makes more sense to be part of Quixote rather than in the "scgi" package). * Rename HTTPRequest.get_form_var() to get_field(). That matches the terminology used by RFCs. * Add HTTPResponse.set_expires() method. * Add HTTPRequest.get_query() method. Use it instead of the QUERY_STRING environment variable. Add HTTPRequest.get_status_code(). * Compile .ptl files to .pyc files. Also, remove 'htmltext' and 'TemplateIO' from the globals of .ptl modules. * Move page compression functionality to http_response module. * Add a 'content_type' attribute to HTTPResponse. Refactor response to make it harder to screw up the character set of the response. * Add quixote.util.get_directory_path() for obtaining the list of _q_traversed() Directories (essentially a replacement for 'namespace_stack') * Move missing trailing slash detection and action to Directory.__call__() and remove FIX_TRAILING_SLASH configuration option. * Remove RUN_ONCE configuration variable and 'exit_now' attribute of publisher. * Stop generating 'Status' header for servers that don't need it. Add 'include_status' keyword to HTTPResponse.write(). * Overhaul the demo. 2.0a1 (2004-10-14) r25357: * Remove form1 library and rename form2 to form. * Remove HTTPRequest.dump_html() method and add dump_request to 'util' module. Remove obsolete functions from 'html' module (html_quote(), value_quote(), link() and render_tag()). * Use bool objects where appropriate. Prefer using builtin types over using the 'types' module. * Add support for unicode. The HTTPResponse object now has a set_charset() method. Also, the htmltext and TemplateIO types can contain unicode strings. * Add support to HTTPRequest for multipart/form-data type requests. Enhance MIME parsing so that it doesn't read huge lines into memory. Also implement parsing of application/x-www-form-urlencoded data rather than using the standard cgi.py module. Remove UPLOAD_DIR and UPLOAD_DIR_MODE config options. Uploaded files are now created using the tempfile module. * Remove the DEBUG_LOG configuration option. Debugging output now always goes to the error log. * Rewrite http_request.parse_cookie() and rename it to parse_cookies(). When generating cookies, escape quote characters that appear in cookie values. 1.2 (2004-10-06) r25277: * Fix Medusa server bug introduced in 1.1. HTTP headers must have "HTTP_" prepended to them. 1.1 (2004-10-05) r25259: * Fix example Apache directive for SCGI demo. * On Windows, put both stdin and stdout in binary mode. * Add 'buffered' flag to HTTPResponse (defaulting to True). * Support for the Python 2.4 'compiler' package. * Add HTTPRequest.get_scheme() method. * Use os.urandom() if it is available. Move randbytes() function to quixote.util module. * Convert tests to Sancho's utest framework. * Add 'index_filenames' keyword option to StaticDirectory. Medusa server: * Unquote the PATH_INFO environment variable. * Simplify propagation of HTTP headers. Form2 library: * Don't parse empty POSTs. * Fix a subtle bug in the multiple select widget. If nothing is selected then the value should be None, not [None]. * Add Widget.set_title(). 1.0 (2004-07-01) r24581: * No changes from 1.0c1. 1.0c1 (2004-06-15) r24468: * Fix some bugs in form2 library and improve the default look. * Add a 'content_type' attribute to Upload instances. 1.0b2 (2004-05-20) r24301: * Pass along more request headers when using twisted_http.py. * Add filter_output() hook (as suggested by Thomas Guettler). * Use plain text for the content of redirections. It's extremely unlikely that they will be seen anyhow. Use a modern DOCTYPE declaration for other pages that Quixote itself generates. * Fix code in upload.py that handles filename collisions. * Use a twisted producer for twisted_server.py (allows Stream responses to be efficient). Use twisted reactor instead of Application. Thanks to Jason Sibre. Form2 library changes: * Change how form2 widgets render themselves. The new approach makes it easier to build composite widgets and also provides more freedom to control the layout using CSS. Unfortunately, the forms will not look nice unless some CSS rules are provided. * Add recursive .has_error() and .clear_error() to widgets. * Ensure that has_errors() completely parse all the widgets. * Fix .clear_errors() for form2 Form. Errors can only be reliably cleared after the widget has parsed * Fix OptionSelect to always return a value from the options list. * Fix some bugs in WidgetList. * Check form token validity if tokens are enabled. 1.0b1 (2004-04-12) r23961: * Remove an underscore from the Session attributes __remote_address, __creation_time, and __access_time. Note that if you have pickled Session objects you will need to upgrade them somehow. * Use a simpler version of ptl_compile.parse() if using Python >= 2.3. Unfortunately, the hacks are still needed for older versions. * Change the behavior of session cookies if SESSION_COOKIE_PATH is unset. The old behavior was to not set the 'path' attribute of the session cookie. The new behavior is to use SCRIPT_NAME. Also, set the 'path' attribute when revoking the session cookie. Some browsers treat it as a separate cookie if it has a different path. * Don't try to compress stream responses. * Refactor PublishError exception handling. Requests will now be logged even if they raise an exception. This also allows some simplification to the Medusa and Twisted server code. * Make HTTPRequest.get_server() return HTTP_HOST if it is available rather than using SERVER_NAME and SERVER_PORT. * If "Host" header is present, use it to set SERVER_NAME and SERVER_PORT. * Make HTTPRequest.get_url() escape unsafe characters in the path part of the URL. * Use a simple counter instead of using the 'random' module when trying to generate unique names for uploaded files. * Allow arbitrary mapping objects to be used as the right hand operand when formating htmltext objects (i.e. as an argument to the htmltext.__mod__ method). The _c_htmltext implemention used to only allow 'dict' instances. Change _c_htmltext to allow any mapping. Also, instead of accessing every item in the mapping, use PyObject_GetItem() (aka __getitem__) to retrieve the values as they are required. That matches the behavior of PyString_Format(). * Don't set DEBUG_LOG in demo.conf. Extra logs files are confusing when people are starting out. * Significant form2 package changes. Remove FormComponent and related machinery. Allow widgets to control how they are rendered within forms (by overriding the form_render() method. Reorganize rendering code in the form module so that it is easier to subclass form and provide a different look. Change the parsing behavior of widgets. They no longer parse themselves when __init__ is called. Instead, each widget has a parse() method that calls _parse(), if it hasn't been called already, and returns the widgets value. Allow Widget._parse() to raise WidgetValueError in order to signal a parsing error. Add a CompositeWidget class. Remove Widget.get_value() since parse() seems to be sufficient. * Add HTTPS header when running under twisted_http.py. * Add cimport as a standard Quixote extension. * Disable FIX_TRAILING_SLASH in demo.conf. It can be confusing when trying to get the demo running. * Allow _q_exports to contain mappings of external names to internal names. * Twisted does not unquote the path so make twisted_http.py do it. * Implement error logging for mod_python handler. 0.7a3 (2003-12-03) r23260: * Improve init for ListWidget. The value of added_elements_widget needs to be set in the request if the list widget was added to the form after the first form submission. * Rename Form.WIDGET_ROW_CLASS to COMPONENT_CLASS, since that's what it really is. Make it an instance attribute as well as a class attribute, so it can be overridden at form construction time. * Remove 'allowed_values' and 'descriptions' from RadiobuttonsWidget.__init__. * Make htmltag() more efficient by avoiding repeated string concatenation. * Establish a pattern for way to specify html attributes for form2 widget constructors. The attributes may be provided in a dictionary using the 'attr' keyword. An html attribute 'foo' may also be specified in the widget constructor using using keyword 'foo' or 'foo_'. 0.7a2 (2003-11-11) r23130: * Implement publish_fcgi(). Don't use fcgi module for publish_cgi() since it's not completely portable. If you want to use FastCGI, you need to call publish_fcgi() instead of publish_cgi(). Don't import fcgi unless it's needed (since it does stuff at import time). * Allow StaticFile class to be overridden. Also, make it easier to subclass StaticDirectory. * When loading a PTL module, check if it exists in sys.modules. If it does, exec the code in that namespace rather than creating a new module. This is necessary to make reload() work. * Move HTTPUploadRequest import out of .create_request(). * Make HTTPRequest.guess_browser_version() more robust. * Remove 'allowed_values' and 'description' parameters from form2 SelectWidget. * Remove unused 'request' parameter from render() method of form2 RadiobuttonsWidget and OptionSelectWidget. * Improve form2 WidgetRow docstring. Don't use apply(). * Fix 'required' check in form2 WidgetRow. * Set the nb_inplace_add slot of TemplateIO types instead of sq_inplace_concat. nb_inplace_add takes precedence over __radd__ on instance types while sq_inplace_concat does not. * Fix typo in repr of _c_htmltext TemplateIO. * Use the quixote.sendmail module to send traceback email rather than calling /usr/sbin/sendmail. * Allow negative values to be passed to HTTPRequest.get_path(). * Add WidgetRow to form2.__init__. * Implement add_button() and add_reset() methods for form2.Form and rename Form._render_submit_buttons() to _render_button_widgets(). 0.7a1 (2003-10-09) r22720: * By default, don't build _c_htmltext on Win32. * In medusa_http.py, propagate 'GATEWAY_INTERFACE', 'SCRIPT_FILENAME', and HTTP headers. * Add HTTPRequest.get_method(). * Add support for keyword attributes on string widget. * Add a CollapsibleListWidget. * Allow HTTPResponse.body to be a Stream object as well as a string. Stream objects are useful if the body of the response is very large. * Change StaticFile to return Stream objects. Also, fix a minor bug in StaticDirectory (_q_lookup should return a namespace). * Improve installation instructions. * Add 'Redirector' helper class. * In publish.py, call _q_lookup(request, "") if _q_index does not exist and _q_lookup does exist. * In medusa_http.py, strip fragments from URLs (some versions of MSIE incorrectly send them at certain times; for example, a redirect includes them). Also, make REQUEST_URI contain the URI, not just the path. * In ptl_import, explicitly close the .ptlc file. This fixes a bug where a subsequent import may go for this .ptlc file and find it incomplete. * Add css_class keyword to htmltag so that class attributes can be specified easily. * Implement next generation form framework (currently called 'form2'). 0.6.1 (2003-07-14) r22004: * Make Form.add_widget() return the widget. * Allow the "Expires" header to be suppressed by setting the 'cache' attribute of HTTPResponse to None. * Use title case for header names added by HTTPResponse.set_headers(). Clients are not supposed to care about case but it's better to be conservative. * Catch IOError exceptions raised when writing the response and log a message (rather than exiting with a traceback). * Fix bug regarding _q_exception_handler. namespace_stack needs to be updated while the traversal is occuring. Thanks to Jason Sibre for spotting it and for the fix. * Add If-Modified-Since support for StaticFile objects. Also, don't set the Expires header by default. Instead, set the Last-Modified header based on the modification time of the file. The Expires header can be enabled by providing a value for the 'cache_time' argument. 0.6 final (2003-04-30) r21480: * Add a 'pass' to setup.py to make it easier to comment out the C extension. * Simplify 'From:' header in traceback e-mails. 0.6b6 (2003-04-15): * Rename _q_getname() to _q_lookup(). The name '_q_getname' is still supported, but will log a warning whenever it's encountered. This change will require users to modify their applications. * quixote.form.form has been translated from PTL to Python, meaning that you can now use the form framework without enabling PTL. (Original suggestion by Jim Dukarm, who also provided a patch that underwent considerable tweaking.) * Fix generation of temporary filenames in upload.py: filename collisions should be impossible now. * In medusa_http.py, convert HTTP headers into title case before passing them to Medusa, fixing duplicate Content-length headers. (Fix by Graham Fawcett.) * Added quixote.server.twisted_http, which serves a Quixote application using the Twisted event-driven framework (www.twistedmatrix.com). Contributed by Graham Fawcett. We don't use this code ourselves, but patches and bug fixes from Twisted users will be gratefully accepted. 0.6b5 (2003-03-13): * Fix incorrect parameter name for _traverse_url() 0.6b4 (2003-03-13): * The C version of the htmltext type is now compiled by default; you can edit setup.py manually to disable it. * StaticDirectory's list_folder argument renamed to list_directory. * StaticFile now supports the HTTP encoding for files. (Absence of this feature noted by Jim Dukarm.) * If Quixote looks for _q_index() in a namespace and doesn't find it, it raises AccessError (resulting in an HTTP 403 Forbidden error) rather than failing with an ImportError. A minor side effect of this change: Quixote will never attempt to import a module named '_q_index', nor will it pass '_q_index' to any _q_resolve() function. We don't expect this to be a backward compatibility problem . * Factored out the traverse_url() and get_component() method from the Publisher class. * Documented _q_exception_handler(). 0.6b3 (2003-03-07): * Fixed errors in demo_scgi.py. (David M. Cooke) * Avoid using True/False and enable nested scopes in _py_htmltext.py for Python 2.1 compatibility. (Noted by Jeff Bauer) Note that this means HTML templates will not work with Python 2.0 unless you compile the C extension. * Added StaticFile and StaticDirectory classes to quixote.util. Consult doc/static-files.txt for examples. (Contributed and documented by Hamish Lawson.) 0.6b2 (2003-01-27): * Added a new hook, _q_resolve(), that can be used to delay importing modules until they're actually accessed. Consult doc/programming.txt for an explanation. (Original suggestion and patch by Jon Corbet. In the process of adding it, Publisher.get_component() was rearranged to clarify the logic.) * Fixed the Medusa HTTP server to work with HTML templates (David M. Cooke) and to call finish_failed_request (pointed out by Graham Fawcett). * Added HTTP_USER_AGENT and ACCEPT_ENCODING to Medusa HTTP server. (Graham Fawcett) * Fixed _c_htmltext.c to compile on Windows. (Graham Fawcett) * Fixed two bugs in _c_htmltext.c found by code review, and one bug in _py_htmltext.py found by Nicola Larosa. (Neil Schemenauer) * Added a page to the demo that dumps the contents of the HTTPRequest. * Made upload.py write out HTTP upload data in binary mode, so binary content-types work correctly on Windows. (Graham Fawcett) * Added classifiers for use with Python 2.3's "register" command. 0.6b1 (2003-01-09): * Merged form/form.py and form/form_templates.ptl into form/form.ptl. (This means that you should completely remove (or rename) your old Quixote installation directory *before* installing 0.6, or the old form/form.py will shadow the new form.ptl.) * A new and preferred syntax for declaring PTL templates has been added. Instead of 'template func(): ...', the new form is 'def func [plain] ()'. This uses a notation that's been suggested for adding type information to Python functions. The Emacs Python mode already handles this properly, and it may be more compatible with future versions of Python. The 'template' keyword is still supported, but we encourage you to switch to the new syntax when you get a chance. * Quixote now supports a new kind of template that automatically performs HTML escaping. Here's an example. (Notice that the '[plain]' annotation is changed to '[html]' to enable this feature.) def header [html] (title): "