*************************************************************************
itools 0.20.0
*************************************************************************

The current upgrade notes are no complete, most notably for the
"itools.handlers" and "itools.web" packages.  Thanks to report any
problem you find.

Imports
=======

The package "itools.xhtml" has been merged into "itools.html", and there
have been many naming normalizations.  Non exhaustive list follows:

  Before (alphabetical order)    Now
  ----------------------------   ---------------------------
  csv.CSV                        csv.CSVFile
  datatypes.InternetDateTime     datatypes.HTTPDate
  gettext.MO                     gettext.MOFile
  gettext.PO                     gettext.POFile
  handlers.Bzip2                 handlers.Bzip2File
  handlers.Config                handlers.ConfigFile
  handlers.escape_data           csv.escape_data
  handlers.fold_line             csv.fold_line
  handlers.Gzip                  handlers.GzipFile
  handlers.parse_table           csv.parse_table
  handlers.Property              csv.Property
  handlers.Record                csv.Record
  handlers.Table                 csv.Table
  handlers.TarArchive            handlers.TARFile
  handlers.Text                  handlers.TextFile
  handlers.ZipArchive            handlers.ZIPFile
  html.Document                  html.HTMLFile
  html.Parser                    html.HTMLParser
  odf.ODP                        odf.ODPFile
  odf.ODS                        odf.ODSFile
  odf.ODT                        odf.ODTFile
  odf.OOCalc                     odf.SXCFile
  odf.OOImpress                  odf.SXIFile
  odf.OOWriter                   odf.SXWFile
  pdf.PDF                        pdf.PDFFile
  rest.checkid                   handlers.checkid
  xhtml.Document                 html.XHTMLFile
  xhtml.elements_schema          html.elements_schema
  xhtml.sanitize_str             html.sanitize_str
  xhtml.sanitize_stream          html.sanitize_stream
  xhtml.stream_to_str_as_html    html.stream_to_str_as_html
  xhtml.stream_to_str_as_xhtml   html.stream_to_str_as_xhtml
  xhtml.xhtml_uri                html.xhtml_uri
  xml.Document                   xml.XMLFile
  xml.Parser                     xml.XMLParser

The "itools.schemas" package has been drop, use instead explicit schemas,
or the XML namespaces (depends on what you want to do, ask to the mailing
list for advice).


Packaging
=========

The "setup.conf" options have changed a little, rename the "description"
field to "title":

  # Before
  description = "The itools library"

  # Now
  title = "The itools library"


itools.catalog
==============

The abort method has been renamed to abort_changes:

  Catalog.abort()           # Before
  Catalog.abort_changes()   # Now

Before the fields to index (or store) were defined once and for all at
creation time with the "make_catalog" function.  Now they are defined
on a per object basis.  Also, the "get_catalog_indexes" method has been
renamed to "get_catalog_values".

  # Before
  make_catalog(path, TextField('title'), TextField('body'))

  class Document(CatalogAware):
      def get_catalog_indexes(self):
          return {'title': ..., 'body': ...}

  # Now
  make_catalog(path)

  class Document(CatalogAware):
      def get_catalog_fields(self):
          return [TextField('title'), TextField('body')]

      def get_catalog_values(self):
          return {'title': ..., 'body': ...}


itools.csv
==========

The "Row.set_value" method has been removed, use instead the new method
"CSVFile.update_row".

  # Before
  row = csv.get_row(index)
  csv.set_changed()
  row.set_value(name1, value1)
  row.set_value(name2, value2)

  # Now
  csv.update_row(index, name1=value1, name2=value2)

The new method, "update_row", takes care to set the csv file as dirty,
and updates the reverse indexes needed to search.

The advanced feature "IntegerKey" has been removed (if you need advanced
features, consider using the "Table" handler, which is, from a functional
point of view, a CSV on steroids).


itools.datatypes
================

The "InternetDateTime" class has been renamed to "HTTPDate", and includes
a semantic difference.  Before it returned "aware" datetime objects, this
is to say, objects with a timezone (always in UTC).

Now it returns "naive" datetime objects, this is to say, objects without
a timezone (always in local time).


itools.gettext
==============

The obsolete method "PO.get_translation" has been removed:

  # Before
  po.get_translation(msgid)

  # Now
  po.gettext(msgid)

The "Domain" class has been drop from the public API, use always the
registry:

  # Before
  domain = Domain(path)

  # Now
  register_domain(name, path)
  domain = get_domain(name)


itools.handlers
===============

The changes to the handlers package are too many to describe all of them
here, check the documentation to know how things work now.  However, some
patterns have a direct translation.

Do not define the "__slots__" variable class anymore when implementing
your own handler classes.

The "guess_encoding" method is not a (static) method anymore, but a
function:

  # Before
  from itools.handlers import Text
  Text.guess_encoding('...')

  # Now
  from itools.handlers import guess_encoding
  guess_encoding('...')


itools.html
===========

Now the HTML parser behaves more like the XML parser, when a parsing
error happens the "XMLError" exception is raised:

  # Before
  from HTMLParser import HTMLParseError
  from itools.html import Parser
  try:
      Parser(...)
  except (HTMLParserError, ValueError):
      ...

  # Now
  from itools.xml import XMLError
  from itools.html import HTMLParser
  try:
      HTMLParser(...)
  except XMLError:
      ...


itools.http
===========

Now the "Request.get_parameter" method does not automatically try to
figure out the datatype from the field name:

  # Before
  value = request.get_parameter('dc:title')

  # Now
  value = request.get_parameter('dc:title', type=Unicode)


itools.rss
==========

The changes to the rss package are too many to describe all of them here,
check the documentation to know how things work now.


itools.vfs
==========

The modes to open a file have changed, this table summarizes the changes:

  Before           Now             Posix
  ---------------  --------------  -----
  READ             READ (default)  rb
                   WRITE           wb
  WRITE (default)  READ_WRITE      r+b
  APPEND           APPEND          ab

Follow the patterns that must be updated:

  Before                 Now
  ---------------------  -------------------------
  vfs.open(uri)          vfs.open(uri, READ_WRITE)
  vfs.open(uri, WRITE)   vfs.open(uri, READ_WRITE)


itools.web
==========

The changes to the web package are too many to describe all of them
here, check the documentation to know how things work now.  However,
some patterns that have a direct translation.

Renames in the context API include:

  Before (alphabetical order)     Now
  ------------------------------  -----------------------
  context.handler                 context.object
  context.get_accept_language()   context.accept_language

(1) Now the "context.get_form_value" method does not automatically try
to figure out the datatype from the field name:

  # Before
  value = context.get_form_value('dc:title')

  # Now
  value = context.get_form_value('dc:title', type=Unicode)

(2) The "context.check_form_input" method has changed.  Before it just
tested whether the input data was valid or not, and returned an error
message if it was not.

Now if everything is ok it will return a dictionary with the deserialized
values.  If there was an error it will raise an exception describing the
fields that are missing or invalid.

  # Before
  schema = [('name', True, Unicode)]
  error = context.check_form_input(schema)
  if error is not None:
      return ...
  value = context.get_form_value('name', type=Unicode)

  # Now
  schema = {'name': Unicode(mandatory=True)}
  try:
      values = context.check_form_input(schema)
  except FormError, error:
      return ...
  value = values['name']

(3) Now the "context.build_form_namespace" method requires the fields
parameter to explicitly define the datatype:

  # Before
  fields = [(name, True)]
  context.build_form_namespace(fields)

  # Now
  fields = [(name, True, String)]
  context.build_form_namespace(fields)

(4) The traversal API has changed.

  # Before
  def _get_handler(self, segment, uri):
      ...
      return handler_class(uri)

  # Now
  def _get_object(self, name):
      metadata = self.handler.get_handler('%s.metadata' % name)
      ...
      return object_class(metadata)


  Before                      Now
  -------------------------   ------------------
  _get_handler_names          ?
  _get_virtual_handler        _get_object
  get_real_handler            get_real_object
  get_physical_path           get_canonical_path


(5) The methods "get_abspath" and "get_canonical_path" return Path instances,
so that you need to str() their return value for use in catalog searches.
