Introduction
============

The ``horae.core`` package provides several core functionality used by the
``horae.*`` packages which there are:

* Formatters for:
  
  * Prices
  * Sizes
  * Dates and times
  * Hours
  
* Global configuration defining:
  
  * Title and description of the application
  * Work days
  * The currency
  
* Generic interfaces for objects having a textual or integer ID
* Utility managing integer IDs
* Utility creating textual IDs
* Base implementation of a container holding objects having a textual
  or integer ID

Usage
=====

Formatters
----------

Prices
''''''

The price formatter formats the given value using the current locale and adds
the configured currency. The formatter is registered as an adapter implementing
``horae.core.interfaces.ICurrencyFormatter`` and adapting any ``context`` and
the ``request``. The following example shows the usage of the formatter in a
view::

    import grok
    from zope.component import getMultiAdapter
    
    from horae.core import interfaces
    
    class SampleView(grok.View):
        
        def currency_formatted_price(self):
            formatter = getMultiAdapter((self.context, self.request),
                                        interface=interfaces.ICurrencyFormatter)
            return formatter.format(1050.25)

Sizes
'''''

The size formatter formats the given value (in bytes) as a number appending the
appropriate unit (B, KB, MB, GB). The formatter is registered as an adapter
implementing ``horae.core.interfaces.ISizeFormatter`` and adapting the ``request``.
The following example shows the usage of the formatter in a view::

    class SampleView(grok.View):
        
        def size_formatted_price(self):
            return interfaces.ISizeFormatter(self.request).format(2048)

Dates and times
'''''''''''''''

The date and time formatters are simple functions part of the ``horae.core.utils``
module. There are two functions available:

``formatDateTime(value, request, format=('dateTime', 'short'), html=True)``
  Formats the datetime ``value`` using the locale provided by the ``request``
  and the ``format`` provided. HTML output may be disabled by the ``html``
  argument.
``formatDateTimeRange(start, end, request, format=('dateTime', 'short'), html=True)``
  Formats the datetime range (``start``, ``end``) using the locale provided
  by the ``request`` and the ``format`` provided. HTML output may be disabled
  by the ``html`` argument.

Hours
'''''

As with the date and time formatters the hours formatter is a simple function of the
``horae.core.utils`` module:

``formatHours(value, request)``
  Formats the ``value`` as a decimal using the locale provided by the ``request``.

IDs and base container implementation
-------------------------------------

``horae.core`` defines two interfaces for objects having an ID:

``horae.core.interfaces.ITextId``
  An object having a text ID
``horae.core.interfaces.IIntId``
  An object having an integer ID

Text IDs may be generated by the text ID manager which is a global utility implementing
``horae.core.interfaces.ITextIdManager``. The utility has two methods:

``normalize(name)``
  Returns a normalized string usable in URLs based on the ``name`` provided
``idFromName(container, name)``
  Returns a valid ID for a new object to be added to the ``container`` from the ``name``
  provided

Integer IDs are managed by the int ID manager which is a local utility implementing
``horae.core.interfaces.IIntIdManager``. The utility provides a method to get the next
ID for a given key:

``nextId(self, key)``
  Returns the next ID for the given ``key``

Container
'''''''''

The base container implementation resides in the ``horae.core.container`` module and
consists of a ``Container`` class implementing ``horae.core.interfaces.IContainer``.
The container is mainly there to simplify the process of adding new objects implementing
one of the aforementioned ID interfaces. The ``add_object(obj)`` method checks if the
given object has an attribute named ``id`` and whether it is ``None``. If no ID is available
one is generated. If the object implements ``horae.core.interfaces.ITextId`` the ID is
generated by using the text ID manager otherwise by the int ID manager. A simple usage
would look like this::

    import grok
    
    from horae.core import interfaces, container
    
    class SampleContainer(container):
        
        def id_key(self):
            return 'sample_key'
    
    class SampleIntIdContent(grok.Model):
        grok.implements(interfaces.IIntId)
    
    class SampleTextIdContent(grok.Model):
        grok.implements(interfaces.ITextId)

An example usage of the above sample classes would look like this::

    >>> container = SampleContainer()
    >>> intcontent1 = SampleIntIdContent()
    >>> container.add_object(intcontent1)
    1
    >>> intcontent1.id
    1
    >>> intcontent2 = SampleIntIdContent()
    >>> container.add_object(intcontent2)
    2
    >>> intcontent2.id
    2
    >>> textcontent1 = SampleTextContent()
    >>> textcontent1.name = u'Test name of the content'
    >>> container.add_object(textcontent1)
    'test_name_of_the_content'
    >>> textcontent1.id
    'test_name_of_the_content'
    >>> textcontent2 = SampleTextContent()
    >>> textcontent2.name = u'Test name of the content'
    >>> container.add_object(textcontent2)
    'test_name_of_the_content-2'
    >>> textcontent2.id
    'test_name_of_the_content-2'

Dependencies
============

Horae
-----

* `horae.cache <http://pypi.python.org/pypi/horae.cache>`_

Third party
-----------

* `grok <http://pypi.python.org/pypi/grok>`_
* `zope.app.locales <http://pypi.python.org/pypi/zope.app.locales>`_
* `z3c.taskqueue <http://pypi.python.org/pypi/z3c.taskqueue>`_
