diff --git a/organize/browser/service.py b/organize/browser/service.py
index 8197976..0b9757a 100644
--- a/organize/browser/service.py
+++ b/organize/browser/service.py
@@ -22,12 +22,16 @@ Basic browser view classes for composer.schema.
$Id$
"""
+from datetime import datetime
+import time
from zope import component
from zope.cachedescriptors.property import Lazy
from cybertools.organize.interfaces import IClientRegistrations, IRegistrationTemplate
+from cybertools.organize.interfaces import serviceCategories
from cybertools.composer.schema.browser.common import BaseView as SchemaBaseView
from cybertools.composer.schema.interfaces import IClientFactory
+from cybertools.util.format import formatDate
class BaseView(object):
@@ -44,6 +48,25 @@ class BaseView(object):
from zope.traversing.browser import absoluteURL
return absoluteURL(obj, self.request)
+ def getLanguage(self):
+ # TODO: take from request or whatever...
+ return 'en'
+
+ def getFormattedDate(self, date=None, type='date', variant='medium'):
+ date = time.localtime(date)[:6]
+ date = datetime(*date)
+ return formatDate(date, type=type, variant=variant, lang=self.getLanguage())
+
+ def getFromTo(self, service=None):
+ if service is None:
+ service = self.context
+ if service.start and service.end:
+ return ('%s - %s' %
+ (self.getFormattedDate(service.start, type='dateTime', variant='short'),
+ self.getFormattedDate(service.end, type='time', variant='short')))
+ else:
+ return '-'
+
class ServiceManagerView(BaseView):
@@ -63,11 +86,15 @@ class ServiceManagerView(BaseView):
category = None
maxLevel = 0
svcs = sorted(self.context.getServices(),
- key=lambda x: (x.getCategory(), x.getClassification()))
+ key=lambda x: (x.getCategory(),
+ x.getClassification(),
+ x.title))
for svc in svcs:
cat = svc.getCategory()
if cat != category:
- result.append(dict(isHeadline=True, title=cat, level=0))
+ term = serviceCategories.getTermByToken(cat)
+ result.append(dict(isHeadline=True, level=0, title=term.title,
+ object=None))
category = cat
classific = []
clsf = svc.getClassification()
@@ -75,13 +102,15 @@ class ServiceManagerView(BaseView):
level = idx + 1
if (len(classific) <= idx or
classific[idx].name != element.name):
- result.append(dict(isHeadline=True, title=element.title,
- level=level))
+ result.append(dict(isHeadline=True, level=level,
+ title=element.title,
+ object=element.object))
classific = clsf
if level > maxLevel:
maxLevel = level
result.append(dict(isHeadline=False, level=maxLevel+1,
title=svc.title or svc.getName(),
+ fromTo=self.getFromTo(svc),
object=svc))
return result
diff --git a/organize/interfaces.py b/organize/interfaces.py
index 5654a40..387af8d 100644
--- a/organize/interfaces.py
+++ b/organize/interfaces.py
@@ -22,10 +22,13 @@ Interfaces for organizational stuff like persons, addresses, tasks, services...
$Id$
"""
-from zope.interface import Interface, Attribute
from zope import schema
+from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
+from zope.interface import Interface, Attribute
from zope.i18nmessageid import MessageFactory
+from cybertools.util.jeep import Jeep, Term
+
_ = MessageFactory('zope')
@@ -126,6 +129,15 @@ class IServiceManager(Interface):
""" A manager or container for a set of services.
"""
+ start = schema.Date(
+ title=_(u'Start date/time'),
+ description=_(u'The start date/time for providing services.'),
+ required=False,)
+ end = schema.Date(
+ title=_(u'End date/time'),
+ description=_(u'The end date/time for providing services.'),
+ required=False,)
+
services = Attribute('A collection of services managed by this object.')
@@ -137,6 +149,11 @@ class IServiceGroup(Interface):
services = Attribute('A collection of services belonging to this object.')
+serviceCategories = SimpleVocabulary((
+ SimpleTerm('event', 'event', u'Event'),
+ SimpleTerm('transport', 'transport', u'Transport'),
+))
+
class IService(Interface):
""" A service that clients may register with.
"""
@@ -147,10 +164,12 @@ class IService(Interface):
title=_(u'Description'),
description=_(u'A brief description of the item.'),
required=False,)
- category = schema.TextLine(
+ category = schema.Choice(
title=_(u'Category'),
- description=_(u'A tokenized term characterizing the type of '
+ description=_(u'The type of '
'this service, e.g. an event or a transport.'),
+ vocabulary=serviceCategories,
+ default='event',
required=False,)
capacity = schema.Int(
title=_(u'Capacity'),
@@ -193,10 +212,12 @@ class IScheduledService(IService):
title=_(u'Start date/time'),
description=_(u'The date/time when the service starts'),
required=False,)
+ start.default_method = 'getStartFromManager'
end = schema.Date(
title=_(u'End date/time'),
description=_(u'The date/time when the service ends'),
required=False,)
+ end.default_method = 'getEndFromManager'
duration = Attribute('Time delta between start and end date/time.')
diff --git a/organize/service.py b/organize/service.py
index b0cbfab..48d27ef 100644
--- a/organize/service.py
+++ b/organize/service.py
@@ -149,6 +149,13 @@ class ScheduledService(Service):
implements(IScheduledService)
+ start = end = None
+
+ def getStartFromManager(self):
+ return getattr(self.getManager(), 'start', None)
+ def getEndFromManager(self):
+ return getattr(self.getManager(), 'end', None)
+
# registration
diff --git a/util/format.py b/util/format.py
new file mode 100644
index 0000000..9bd984a
--- /dev/null
+++ b/util/format.py
@@ -0,0 +1,50 @@
+#
+# Copyright (c) 2007 Helmut Merz helmutm@cy55.de
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""
+Some simple standard formatting routines.
+
+$Id$
+"""
+
+from zope.i18n.locales import locales
+from datetime import datetime
+
+
+def nl2br(text):
+ if not text: return text
+ if '\n' in text: # Unix or DOS line endings
+ return '
\n'.join(x.replace('\r', '') for x in text.split('\n'))
+ else: # gracefully handle Mac line endigns
+ return '
\n'.join(text.split('\r'))
+
+
+def formatDate(dt=None, type='date', variant='medium', lang='de'):
+ """ type: date, time, dateTime;
+ variant: full, long, medium, short.
+ """
+ loc = locales.getLocale(lang)
+ fmt = loc.dates.getFormatter(type, variant)
+ return fmt.format(dt or datetime.now())
+
+
+def formatNumber(num, type='decimal', lang='de'):
+ loc = locales.getLocale(lang)
+ fmt = de.numbers.getFormatter(type)
+ return fmt.format(num)
+
diff --git a/util/format.txt b/util/format.txt
new file mode 100644
index 0000000..3bb7fb2
--- /dev/null
+++ b/util/format.txt
@@ -0,0 +1,17 @@
+==========================
+Basic Formatting Functions
+==========================
+
+$Id$
+
+ >>> from cybertools.util import format
+ >>> from datetime import datetime
+
+ >>> time = datetime(2006, 8, 21, 17, 37, 13)
+
+ >>> format.formatDate(time, type='time', variant='medium')
+ u'17:37:13'
+
+ >>> format.formatDate(time, type='dateTime', variant='medium')
+ u'21.08.2006 17:37:13'
+
diff --git a/util/jeep.py b/util/jeep.py
index 9d90166..d1e8b61 100644
--- a/util/jeep.py
+++ b/util/jeep.py
@@ -32,9 +32,13 @@ class Jeep(object):
def __init__(self, seq=[]):
sequence = self._sequence = []
- for attr, value in seq:
- sequence.append(attr)
- object.__setattr__(self, attr, value)
+ for item in seq:
+ if isinstance(item, (list, tuple)) and len(item) == 2:
+ attr, value = item
+ sequence.append(attr)
+ object.__setattr__(self, attr, value)
+ else:
+ self.append(item)
def __len__(self):
return len(self._sequence)
@@ -129,8 +133,11 @@ class Term(object):
"""
def __init__(self, name, title, **kw):
- self.name = self.__name__ = name
+ self.name = self.__name__ = self.value = self.token = name
self.title = title
for k, v in kw.items():
setattr(self, k, v)
+ def __str__(self):
+ return self.title
+
diff --git a/util/tests.py b/util/tests.py
index 621a6cc..8a42664 100755
--- a/util/tests.py
+++ b/util/tests.py
@@ -20,6 +20,7 @@ def test_suite():
#doctest.DocTestSuite(cybertools.util.property, optionflags=flags),
doctest.DocFileSuite('adapter.txt', optionflags=flags),
doctest.DocFileSuite('defer.txt', optionflags=flags),
+ doctest.DocFileSuite('format.txt', optionflags=flags),
doctest.DocFileSuite('property.txt', optionflags=flags),
doctest.DocFileSuite('jeep.txt', optionflags=flags),
doctest.DocFileSuite('randomname.txt', optionflags=flags),