*************************************************************************
itools 0.61.0
*************************************************************************

These upgrade notes may not be complete. Thanks to report any problem you
find.

New Dependencies
================

Now libsoup 2.28 or later is required for anything related to the web
(itools.http, itools.web).

This table summurizes the new and updated dependencies:

            0.60   0.61   Used by      Home
            ----   ----   ----------   ------------------------------
glib        2.16   2.20   itools.vfs   http://www.gtk.org/
pygobject   2.16   2.18   itools.vfs   http://www.pygtk.org/
libsoup            2.28   itools.soup  http://live.gnome.org/LibSoup


Imports
=======

See the table below for the imports to update.

  Before (alphabetical order)    Now
  ----------------------------   ---------------------------
  itools.vfs                     itools.fs.vfs (*)
  itools.vfs.cwd                 itools.fs.vfs (*)
  itools.vfs.Error               itools.fs.Error
  itools.vfs.FileName            itools.fs.FileName
  itools.vfs.APPEND              itools.fs.APPEND
  itools.vfs.READ                itools.fs.READ
  itools.vfs.READ_WRITE          itools.fs.READ_WRITE
  itools.vfs.WRITE               itools.fs.WRITE

(*) The package itools.vfs has been renamed to itools.fs, and imports have
changed a little:

  Before                         Now
  ----------------------------   --------------------------
  from itools import vfs         from itools.fs import vfs
  from itools.vfs import cwd     from itools.fs import vfs

All "vfs" functions are now "vfs" methods:

  # Before
  from itools.vfs import exists
  exists(uri)

  # Now
  from itools.fs import vfs
  vfs.exists(uri)

It is recommended to use 'lfs' instead of 'vfs' when you are sure only
local files are to be used:

  # Before
  from itools import vfs
  f = vfs.open(path)

  # Now
  from itools.fs import lfs
  f = lfs.open(path)


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

The class variables 'record_schema' and 'parameters_schema' have been
renamed, respectively, to 'record_properties' and 'record_parameters'.

  # Before
  class MyTable(Table):
      record_schema = {...}
      parameters_schema = {...}

  # Now
  class MyTable(Table):
      record_properties = {...}
      record_parameters = {...}


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

The obsolete functions 'is_datatype' and 'copy_datatype' have been
removed:

  # Before
  if is_datatype(datatype, Unicode):
      ...

  # Now
  if issubclass(datatype, Unicode):
      ...

And:

  # Before
  new_datatype = copy_datatype(datatype, a=5, b=3, ...)

  # Now
  new_datatype = datatype(a=5, b=3, ...)


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

(1) Now loading a handler can only be done through a database. For this
purpose, the built-in 'ro_database' database can be used:

  # Before
  h = MyHandlerClass('/tmp/toto.txt')

  # Now
  from itools.handlers import ro_database
  h = ro_database.get_handler('/tmp/toto.txt', MyHandlerClass)

This also means the 'get_handler' and 'get_handler_class' functions have
been removed:

  # Before
  from itools.handlers import get_handler
  h = get_handler('/tmp/toto.txt', MyHandlerClass)

  # Now
  from itools.handlers import ro_database
  h = ro_database.get_handler('/tmp/toto.txt', MyHandlerClass)

(2) The 'File.load_state_from' method has been renamed to the more explicit
'File.load_state_from_uri':

  # Before
  self.load_state_from(xxx)

  # Now
  self.load_state_from_uri(xxx)

(3) The "uri" attribute has been renamed to "key" as it could be anything
unique enough for a given handler database:

  Before        Now
  -----------   -----------
  handler.uri   handler.key

Check whether your handler classes do not already use the 'key' variable,
and if so rename this variable.

(4) Handlers may be attached to different filesystems (see itools.fs) so
don't call vfs directly:

  # Before
  vfs.get_mtime(self.uri)

  # After
  self.database.fs.get_mtime(self.key)

(5) Do not assume that handlers use URIs, it could be absolute paths or
anything else that makes sense to a handler database:

  # Before
  resolve_uri2(self.key, name)

  # After
  self.database.fs.resolve2(self.key, name)

(6) A database may use the new lfs module and provide faster operations when
you know you only need to access the filesystem. It is the default for
(RO)GitDatabase.

To use lfs on the RO- or RWDatabase, just pass it as the "fs" keyword to the
constructor:

  database = RODatabase(fs=lfs)


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

The HTTP server has been rewritten on top of the libsoup library, so now the
API is quite different.  Check the documentation to see how it works now.


itools.ical
===========

The class variable 'schema' has been removed. To override the schema
of an iCalendar file, redefine the 'record_properties' class variable.

  # Before
  class MyCalendar(iCalendar):
      schema = {
          'MYPROPERTY': String}

  # Now
  class MyCalendar(iCalendar):
      record_properties = merge_dicts(iCalendar.record_properties,
          MYPROPERTY=String)


itools.pkg
==========

These public functions, classes, etc. have been removed:

- ArchiveNotSupported
- Bundle
- download
- EXTENSIONS
- get_installed_info
- parse_package_name


itools.stl
==========

STL does not support 'gettattr' to traverse namespaces anymore.


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

(1) Obsolete method 'context.has_form_value' has been removed, use instead
'context.get_form_value':

  # Before
  if context.has_form_value(name):
      ...

  # Now
  value = context.get_form_value(name)
  if value is not None:
      ...

(2) Obsolete method 'context.get_form_values' has been removed, use instead
'context.get_form_value':

  # Before
  values = context.get_form_values(name)

  # Now
  values = context.get_form_value(name, String(multiple=True))

(3) Since the request and response objects have been removed, use instead
the API exposed by the context, for instance:

  # Before
  context.response.set_header(name, value)

  # Now
  context.set_header(name, value)

In particular, to set the content-type and content-disposition headers of
the response, use the new higher level API made for this purpose:

  # Before
  response = context.response
  response.set_header('Content-Type', content_type)
  response.set_header('Content-Disposition',
                      'inline; filename="%s"' % filename)

  # Now
  context.set_content_type(content_type)
  context.set_content_disposition('inline', filename)

(4) The method 'BaseForm.build_namespace' has become 'STLForm.get_namespace':

  # Before
  def get_namespace(self, resource, context):
      namespace = self.build_namespace(resource, context)

  # Now
  def get_namespace(self, resource, context):
      namespace = STLForm.get_namespace(self, resource, context)

(5) Use <button> to submit forms:

  # Before
  <input type="submit" value="Log in" />

  # Now
  <button type="submit">Log in</button>

And, for forms with multiple buttons (when there is an specific action
defined):

  # Before
  <input type="submit" name=";login' value="Log in" />

  # Now
  <button type="submit" name="action' value="login">Log in</button>

In the example above 'login' is a placeholder.

(6) To properly log any event (errors, warnings, etc.) use the new
itools.log package instead of the Python's standard logging package.


itools.xapian
=============

Remove obsolete method 'SearchResults.get_n_documents':

  # Before
  n = results.get_n_documents()

  # Now
  n = len(results)
