CHANGE SUMMARY:

Version 1.2:
2013-06-10

Use ImageMagick tools for converting pdf pages to png files if sips is not
present.

Return an empty list from genlib.node_get_text_data_list in the case of an
exception.

Add the capability for temporary password expiration for qp Users.
The default is 24 hours.

Implement session-level affinity in the dispatcher:

 - We peek at the headers and use the cookie value to distinguish users.
   This should allow a group of users coming from a single IP address
   (such as when NAT is used) to utilize multiple worker processes.

Add digest computation method to StoredFile.

Add support for gradients in the svg module.

Add module level functions for table, paragraphs, spans, and header elements to
the html module.

If a path is not provided when formatting menus, use a default value based on 
get_path().

In the stored_file UI, when downloading a stored file, if no disposition is
specified, and the mime_type is text/html, use disposition = 'attachment',
not 'inline'.  The intent is to avoid the inline display of the possibly
dangerous html in the browser.

Attempt to get QPY xml_empty initialized correctly in Python >= 3.3.

Add methods to Pager class so that a subclass can maintain a page size
preference.

Add redecode(), and add a redecode= keyword to Widget that can be used
by Widgets to recover multiply-encoded form values. This special handling is
implemented for TextWidget, where the errors seem to be most common.

In _q_traverse(), remove requirement that the export has exactly 4 components.

Add note about list_validation_errors() to qpcensus.py.

Use the timeout feature that was added to httplib in Python 2.6 to ensure the
Pusher does not hang during a connection attempt. This bumps the minimum Python
required for DurusWorks to 2.6.

Add a new menu module for carrying the various information we need to build
menus.

Add a Page class for containing header/body/footer/menu information about 
rendering a single page.

Add Pusher, a class for constructing POST request bodies.
These can be used for testing forms or for actually transmitting
to a server.

Add Upload.move(), which moves the Upload's fp to a new location.
Use the new method in stored_file.new_stored_file(). This approach allows
requests with Uploads to successfully replay after WriteConflictErrors.

Change qpcensus.py to avoid having two Connection instances.

Add new_form() to qp.pub.common. This makes it easier for sites to use
site-specific Form classes.

Provide separate access to the spec and doc of a Specification.

Add 'classes' keyword to htmltag. If provided, the argument is expected to be
a list of css class names. Because htmltag is used in href(), img() and other
templates, they also get support for the 'classes' keyword.

Change request input processing. Instead of parsing form requests first, and 
then processing the request, wait for the page handling code to call 
get_fields(). This allows for the possibility of other form parsing methods,
including forms handled by by cgi programs.

Add a 'log_errors' keyword to Form which is False by default. If log_errors is
True, then any form errors are printed to standard output, as well as the 
fields of the form.k

Remove dispatcher-level commands.

Add support to run https directly with QP when using Python 2.6 or above.

Modified qpy as needed to work with python 3.3.

Extended qp.html package to include html element formatting functions.
Added stored_file and svg modules.

Version 1.1:
2011-08-17

This release fixes a long-standing undetected bug in the Durus incremental
packing algorithm.  Thanks to David Hess for finding and solving this issue.

We were raising a KeyError in FileStorage.load_state()

Version 1.0:

This is the initial DurusWorks release.