organize: Python3 fixes
This commit is contained in:
parent
52990d1df6
commit
8037ac38be
9 changed files with 97 additions and 150 deletions
|
@ -1,31 +1,12 @@
|
||||||
#
|
# cybertools.composer.message.instance
|
||||||
# Copyright (c) 2011 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
|
|
||||||
#
|
|
||||||
|
|
||||||
"""
|
""" Message instance and related classes.
|
||||||
Message instance and related classes.
|
|
||||||
|
|
||||||
$Id$
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from cgi import parse_qs
|
#from cgi import parse_qs
|
||||||
|
from urllib.parse import parse_qs
|
||||||
from string import Template
|
from string import Template
|
||||||
from zope import component
|
from zope import component
|
||||||
from zope.interface import implements
|
|
||||||
from zope.publisher.browser import TestRequest
|
from zope.publisher.browser import TestRequest
|
||||||
try:
|
try:
|
||||||
from zope.traversing.browser.absoluteurl import absoluteURL
|
from zope.traversing.browser.absoluteurl import absoluteURL
|
||||||
|
@ -149,7 +130,7 @@ class MessageInstance(Instance):
|
||||||
#path = aq_inner(self.client.manager).getPhysicalPath()
|
#path = aq_inner(self.client.manager).getPhysicalPath()
|
||||||
path = self.client.manager.getPhysicalPath()
|
path = self.client.manager.getPhysicalPath()
|
||||||
if len(path) >= 3 and path[-3] == 'sm_clients':
|
if len(path) >= 3 and path[-3] == 'sm_clients':
|
||||||
print '*** path correction:', path
|
print('*** path correction:', path)
|
||||||
# evil hack for aqcuisition-wrapped manager object
|
# evil hack for aqcuisition-wrapped manager object
|
||||||
path = path[:-3]
|
path = path[:-3]
|
||||||
url = request.physicalPathToURL(path)
|
url = request.physicalPathToURL(path)
|
||||||
|
|
|
@ -1,30 +1,10 @@
|
||||||
#
|
# cybertools.composer.rule.mail
|
||||||
# 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
|
|
||||||
#
|
|
||||||
|
|
||||||
"""
|
""" Action handler for sending emails.
|
||||||
Action handler for sending emails.
|
|
||||||
|
|
||||||
$Id$
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from email.MIMEText import MIMEText
|
from email.mime.text import MIMEText
|
||||||
from zope import component
|
from zope import component
|
||||||
from zope.interface import implements
|
|
||||||
|
|
||||||
from cybertools.composer.interfaces import IInstance
|
from cybertools.composer.interfaces import IInstance
|
||||||
from cybertools.composer.rule.interfaces import IActionHandler
|
from cybertools.composer.rule.interfaces import IActionHandler
|
||||||
|
@ -47,7 +27,7 @@ class MailActionHandler(ActionHandler):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def prepareMessage(self, subject, text, sender, recipient):
|
def prepareMessage(self, subject, text, sender, recipient):
|
||||||
text = text.encode('utf-8')
|
#text = text.encode('utf-8')
|
||||||
msg = MIMEText(text, 'plain', 'utf-8')
|
msg = MIMEText(text, 'plain', 'utf-8')
|
||||||
msg['Subject'] = subject
|
msg['Subject'] = subject
|
||||||
msg['From'] = sender
|
msg['From'] = sender
|
||||||
|
|
|
@ -1,28 +1,7 @@
|
||||||
#
|
# cybertools.composer.rule.message
|
||||||
# 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
|
|
||||||
#
|
|
||||||
|
|
||||||
|
""" Action handler for providing messages.
|
||||||
"""
|
"""
|
||||||
Action handler for providing messages.
|
|
||||||
|
|
||||||
$Id$
|
|
||||||
"""
|
|
||||||
|
|
||||||
from zope.interface import implements
|
|
||||||
|
|
||||||
from cybertools.composer.message.interfaces import IMessageManager
|
from cybertools.composer.message.interfaces import IMessageManager
|
||||||
from cybertools.composer.message.instance import MessageInstance
|
from cybertools.composer.message.instance import MessageInstance
|
||||||
|
|
|
@ -14,7 +14,7 @@ class TestMailer(object):
|
||||||
msg = message_from_string(message)
|
msg = message_from_string(message)
|
||||||
print('subject:', msg['Subject'])
|
print('subject:', msg['Subject'])
|
||||||
print('message:')
|
print('message:')
|
||||||
print(msg.get_payload(decode=True))
|
print(msg.get_payload(decode=True).decode('UTF-8'))
|
||||||
|
|
||||||
|
|
||||||
class Test(unittest.TestCase):
|
class Test(unittest.TestCase):
|
||||||
|
|
|
@ -13,11 +13,11 @@ Persons and Addresses
|
||||||
Let's start with a Person:
|
Let's start with a Person:
|
||||||
|
|
||||||
>>> from cybertools.organize.party import Person
|
>>> from cybertools.organize.party import Person
|
||||||
>>> john = Person(u'Smith')
|
>>> john = Person('Smith')
|
||||||
>>> john.lastName
|
>>> john.lastName
|
||||||
u'Smith'
|
'Smith'
|
||||||
>>> john.firstName
|
>>> john.firstName
|
||||||
u''
|
''
|
||||||
>>> john.birthDate is None
|
>>> john.birthDate is None
|
||||||
True
|
True
|
||||||
>>> john.addresses
|
>>> john.addresses
|
||||||
|
@ -35,9 +35,9 @@ A Person object knows the age of the person:
|
||||||
>>> john.age >= 26
|
>>> john.age >= 26
|
||||||
True
|
True
|
||||||
|
|
||||||
>>> john.firstName = u'John'
|
>>> john.firstName = 'John'
|
||||||
>>> john.firstName
|
>>> john.firstName
|
||||||
u'John'
|
'John'
|
||||||
|
|
||||||
Addresses
|
Addresses
|
||||||
---------
|
---------
|
||||||
|
@ -45,10 +45,10 @@ Addresses
|
||||||
Let's create an address and assign it to a person:
|
Let's create an address and assign it to a person:
|
||||||
|
|
||||||
>>> from cybertools.organize.party import Address
|
>>> from cybertools.organize.party import Address
|
||||||
>>> addr = Address(u'New York', u'Broadway 1')
|
>>> addr = Address('New York', 'Broadway 1')
|
||||||
>>> john.addresses['standard'] = addr
|
>>> john.addresses['standard'] = addr
|
||||||
>>> john.addresses['standard'].street
|
>>> john.addresses['standard'].street
|
||||||
u'Broadway 1'
|
'Broadway 1'
|
||||||
|
|
||||||
|
|
||||||
Tasks
|
Tasks
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import csv
|
import csv
|
||||||
from io import StringIO
|
from io import BytesIO, StringIO
|
||||||
import itertools
|
import itertools
|
||||||
from zope import component
|
from zope import component
|
||||||
from zope.cachedescriptors.property import Lazy
|
from zope.cachedescriptors.property import Lazy
|
||||||
|
@ -106,7 +106,7 @@ class RegistrationsExportCsv(BaseView):
|
||||||
#waiting.append(reg.numberWaiting)
|
#waiting.append(reg.numberWaiting)
|
||||||
if reg.number or reg.numberWaiting:
|
if reg.number or reg.numberWaiting:
|
||||||
hasRegs = True
|
hasRegs = True
|
||||||
if reg.timeStamp < timeStamp:
|
if timeStamp == '' or reg.timeStamp < timeStamp:
|
||||||
timeStamp = reg.timeStamp
|
timeStamp = reg.timeStamp
|
||||||
if not hasRegs:
|
if not hasRegs:
|
||||||
continue
|
continue
|
||||||
|
@ -134,6 +134,7 @@ class RegistrationsExportCsv(BaseView):
|
||||||
delimiter = ';'
|
delimiter = ';'
|
||||||
methodName = self.request.get('get_data_method', 'getAllDataInColumns')
|
methodName = self.request.get('get_data_method', 'getAllDataInColumns')
|
||||||
method = getattr(self, methodName, self.getData)
|
method = getattr(self, methodName, self.getData)
|
||||||
|
#output = BytesIO()
|
||||||
output = StringIO()
|
output = StringIO()
|
||||||
try:
|
try:
|
||||||
csv.writer(output, dialect='excel', delimiter=delimiter,
|
csv.writer(output, dialect='excel', delimiter=delimiter,
|
||||||
|
@ -153,6 +154,7 @@ class RegistrationsExportCsv(BaseView):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def encode(self, text):
|
def encode(self, text):
|
||||||
|
return text
|
||||||
if isinstance(text, str):
|
if isinstance(text, str):
|
||||||
result = []
|
result = []
|
||||||
for c in text:
|
for c in text:
|
||||||
|
|
|
@ -31,9 +31,9 @@ parts (events, lectures, ...).
|
||||||
>>> workshop.__name__ = 'workshop'
|
>>> workshop.__name__ = 'workshop'
|
||||||
|
|
||||||
>>> event1 = service.ScheduledService('event1', category='event', manager=workshop,
|
>>> event1 = service.ScheduledService('event1', category='event', manager=workshop,
|
||||||
... title=u'Event 1', capacity=5)
|
... title='Event 1', capacity=5)
|
||||||
>>> event2 = service.ScheduledService('event2', category='event', manager=workshop,
|
>>> event2 = service.ScheduledService('event2', category='event', manager=workshop,
|
||||||
... title=u'Event 2')
|
... title='Event 2')
|
||||||
>>> workshop.services.append(event1)
|
>>> workshop.services.append(event1)
|
||||||
>>> workshop.services.append(event2)
|
>>> workshop.services.append(event2)
|
||||||
|
|
||||||
|
@ -43,26 +43,26 @@ clients. This is done via to form descriptions (schemas), one for the
|
||||||
personal data (first name, last name), and one for the address.
|
personal data (first name, last name), and one for the address.
|
||||||
|
|
||||||
>>> workshop.clientSchemas.append(schema.Schema(
|
>>> workshop.clientSchemas.append(schema.Schema(
|
||||||
... schema.Field('lastName', u'Last Name', required=True,
|
... schema.Field('lastName', 'Last Name', required=True,
|
||||||
... standardFieldName='lastName'),
|
... standardFieldName='lastName'),
|
||||||
... schema.Field('firstName', u'First Name'),
|
... schema.Field('firstName', 'First Name'),
|
||||||
... schema.Field('email', u'Email Address', required=True,
|
... schema.Field('email', 'Email Address', required=True,
|
||||||
... fieldType='email', standardFieldName='email'),
|
... fieldType='email', standardFieldName='email'),
|
||||||
... schema.Field('age', u'Age', fieldType='number'),
|
... schema.Field('age', 'Age', fieldType='number'),
|
||||||
... schema.Field('addr', u'Personal Address', required=True,
|
... schema.Field('addr', 'Personal Address', required=True,
|
||||||
... fieldtype='radiobuttons',
|
... fieldtype='radiobuttons',
|
||||||
... vocabulary=u'Mrs\nMr'),
|
... vocabulary='Mrs\nMr'),
|
||||||
... schema.Field('acadTitles', u'Academic Titles',
|
... schema.Field('acadTitles', 'Academic Titles',
|
||||||
... fieldtype='checkboxes',
|
... fieldtype='checkboxes',
|
||||||
... vocabulary=u'Prof.\nDr.'),
|
... vocabulary='Prof.\nDr.'),
|
||||||
... name='person',
|
... name='person',
|
||||||
... manager=workshop,
|
... manager=workshop,
|
||||||
... ))
|
... ))
|
||||||
>>> workshop.clientSchemas.append(schema.Schema(
|
>>> workshop.clientSchemas.append(schema.Schema(
|
||||||
... schema.Field('street', u'Street'),
|
... schema.Field('street', 'Street'),
|
||||||
... schema.Field('city', u'City', required=True),
|
... schema.Field('city', 'City', required=True),
|
||||||
... schema.Field('country', u'Country', required=True,
|
... schema.Field('country', 'Country', required=True,
|
||||||
... fieldType='dropdown', vocabulary=u'USA\nGermany'),
|
... fieldType='dropdown', vocabulary='USA\nGermany'),
|
||||||
... name='address',
|
... name='address',
|
||||||
... manager=workshop,
|
... manager=workshop,
|
||||||
... ))
|
... ))
|
||||||
|
@ -76,7 +76,7 @@ So we are now ready to register participants.
|
||||||
>>> client1 = IClientFactory(workshop)()
|
>>> client1 = IClientFactory(workshop)()
|
||||||
>>> client1Name = workshop.addClient(client1)
|
>>> client1Name = workshop.addClient(client1)
|
||||||
|
|
||||||
>>> data = dict(addr=u'Mr', lastName=u'Skywalker', email='luke@skywalker.universe')
|
>>> data = dict(addr='Mr', lastName='Skywalker', email='luke@skywalker.universe')
|
||||||
>>> inst = component.getAdapter(client1, IInstance, name='editor')
|
>>> inst = component.getAdapter(client1, IInstance, name='editor')
|
||||||
>>> inst.template = workshop.clientSchemas['person']
|
>>> inst.template = workshop.clientSchemas['person']
|
||||||
>>> state = inst.applyTemplate(data=data)
|
>>> state = inst.applyTemplate(data=data)
|
||||||
|
@ -85,7 +85,7 @@ So we are now ready to register participants.
|
||||||
['schema.client.__standard__', 'schema.client.person']
|
['schema.client.__standard__', 'schema.client.person']
|
||||||
|
|
||||||
>>> client1.__schema_attributes__['schema.client.person']['lastName']
|
>>> client1.__schema_attributes__['schema.client.person']['lastName']
|
||||||
u'Skywalker'
|
'Skywalker'
|
||||||
|
|
||||||
Instead of directly peeking into the attributes we can also use a
|
Instead of directly peeking into the attributes we can also use a
|
||||||
suitable instance adapter.
|
suitable instance adapter.
|
||||||
|
@ -93,10 +93,12 @@ suitable instance adapter.
|
||||||
>>> inst = IInstance(client1)
|
>>> inst = IInstance(client1)
|
||||||
>>> inst.template = workshop.clientSchemas['person']
|
>>> inst.template = workshop.clientSchemas['person']
|
||||||
>>> inst.applyTemplate()
|
>>> inst.applyTemplate()
|
||||||
{'acadTitles': u'', 'standard.lastName': u'Skywalker', 'addr': u'Mr',
|
{..., 'lastName': 'Skywalker', ...}
|
||||||
'firstName': u'', 'lastName': u'Skywalker', 'age': '', '__name__': '...',
|
|
||||||
'email': u'luke@skywalker.universe',
|
{'acadTitles': '', 'standard.lastName': 'Skywalker', 'addr': 'Mr',
|
||||||
'standard.email': u'luke@skywalker.universe'}
|
'firstName': '', 'lastName': 'Skywalker', 'age': '', '__name__': '...',
|
||||||
|
'email': 'luke@skywalker.universe',
|
||||||
|
'standard.email': 'luke@skywalker.universe'}
|
||||||
|
|
||||||
Note that the ``standardFieldName`` setting for the ``lastName`` field
|
Note that the ``standardFieldName`` setting for the ``lastName`` field
|
||||||
results in a 'standard.lastName' entry; this technique may be used to
|
results in a 'standard.lastName' entry; this technique may be used to
|
||||||
|
@ -110,13 +112,13 @@ We need some additional setup for working with schema views - so we have to
|
||||||
supply some session handling stuff in order to work with client names.
|
supply some session handling stuff in order to work with client names.
|
||||||
|
|
||||||
>>> from zope.interface import implementer
|
>>> from zope.interface import implementer
|
||||||
|
>>> from zope.session.interfaces import IClientId
|
||||||
>>> from zope.session.interfaces import IClientIdManager, ISessionDataContainer
|
>>> from zope.session.interfaces import IClientIdManager, ISessionDataContainer
|
||||||
>>> from zope.session import session
|
>>> from zope.session import session
|
||||||
>>> component.provideAdapter(session.ClientId)
|
>>> component.provideAdapter(session.ClientId, provides=IClientId)
|
||||||
>>> component.provideAdapter(session.Session)
|
>>> component.provideAdapter(session.Session)
|
||||||
>>> component.provideUtility(session.RAMSessionDataContainer(), ISessionDataContainer)
|
>>> component.provideUtility(session.RAMSessionDataContainer(), ISessionDataContainer)
|
||||||
>>> class ClientIdManager(object):
|
>>> class ClientIdManager(object):
|
||||||
... implements(IClientIdManager)
|
|
||||||
... def getClientId(self, request): return 'dummy'
|
... def getClientId(self, request): return 'dummy'
|
||||||
>>> ClientIdManager = implementer(IClientIdManager)(ClientIdManager)
|
>>> ClientIdManager = implementer(IClientIdManager)(ClientIdManager)
|
||||||
>>> component.provideUtility(ClientIdManager())
|
>>> component.provideUtility(ClientIdManager())
|
||||||
|
@ -143,17 +145,19 @@ the corresponding client.
|
||||||
>>> request = TestRequest(form=input)
|
>>> request = TestRequest(form=input)
|
||||||
>>> view = SchemaView(schema, request)
|
>>> view = SchemaView(schema, request)
|
||||||
>>> view.data
|
>>> view.data
|
||||||
{'acadTitles': u'', 'standard.lastName': u'Skywalker', 'addr': u'Mr',
|
{..., 'lastName': 'Skywalker', ...}
|
||||||
'firstName': u'', 'lastName': u'Skywalker', 'age': '', '__name__': '...',
|
|
||||||
'email': u'luke@skywalker.universe',
|
{'acadTitles': '', 'standard.lastName': 'Skywalker', 'addr': 'Mr',
|
||||||
'standard.email': u'luke@skywalker.universe'}
|
'firstName': '', 'lastName': 'Skywalker', 'age': '', '__name__': '...',
|
||||||
|
'email': 'luke@skywalker.universe',
|
||||||
|
'standard.email': 'luke@skywalker.universe'}
|
||||||
|
|
||||||
When we provide data and an 'update' action a new client object will
|
When we provide data and an 'update' action a new client object will
|
||||||
be created - if we clear the client name in the session first via
|
be created - if we clear the client name in the session first via
|
||||||
``view.setClientName('')``.
|
``view.setClientName('')``.
|
||||||
|
|
||||||
>>> input = dict(lastName='Solo', firstName='Han', email='han.solo@space.net',
|
>>> input = dict(lastName='Solo', firstName='Han', email='han.solo@space.net',
|
||||||
... addr=u'Mr', action='update')
|
... addr='Mr', action='update')
|
||||||
>>> request = TestRequest(form=input)
|
>>> request = TestRequest(form=input)
|
||||||
>>> view = SchemaView(schema, request)
|
>>> view = SchemaView(schema, request)
|
||||||
>>> view.setClientName('')
|
>>> view.setClientName('')
|
||||||
|
@ -168,15 +172,17 @@ be created - if we clear the client name in the session first via
|
||||||
>>> request = TestRequest(form=input)
|
>>> request = TestRequest(form=input)
|
||||||
>>> view = SchemaView(schema, request)
|
>>> view = SchemaView(schema, request)
|
||||||
>>> view.data
|
>>> view.data
|
||||||
{'acadTitles': u'', 'standard.lastName': u'Solo', 'addr': u'Mr',
|
{..., 'lastName': 'Solo', ...}
|
||||||
'firstName': u'Han', 'lastName': u'Solo',
|
|
||||||
'age': '', '__name__': '...', 'email': u'han.solo@space.net',
|
{'acadTitles': '', 'standard.lastName': 'Solo', 'addr': 'Mr',
|
||||||
'standard.email': u'han.solo@space.net'}
|
'firstName': 'Han', 'lastName': 'Solo',
|
||||||
|
'age': '', '__name__': '...', 'email': 'han.solo@space.net',
|
||||||
|
'standard.email': 'han.solo@space.net'}
|
||||||
|
|
||||||
If we provide an id parameter we may also change an existing client.
|
If we provide an id parameter we may also change an existing client.
|
||||||
|
|
||||||
>>> input = dict(lastName=u'Skywalker', firstName=u'Luke', id=client1Name,
|
>>> input = dict(lastName='Skywalker', firstName='Luke', id=client1Name,
|
||||||
... email='luke@skywalker.universe', addr=u'Mr', action='update')
|
... email='luke@skywalker.universe', addr='Mr', action='update')
|
||||||
>>> request = TestRequest(form=input)
|
>>> request = TestRequest(form=input)
|
||||||
>>> view = SchemaView(schema, request)
|
>>> view = SchemaView(schema, request)
|
||||||
>>> view.update()
|
>>> view.update()
|
||||||
|
@ -186,15 +192,17 @@ If we provide an id parameter we may also change an existing client.
|
||||||
>>> request = TestRequest(form=input)
|
>>> request = TestRequest(form=input)
|
||||||
>>> view = SchemaView(schema, request)
|
>>> view = SchemaView(schema, request)
|
||||||
>>> view.data
|
>>> view.data
|
||||||
{'acadTitles': u'', 'standard.lastName': u'Skywalker', 'addr': u'Mr',
|
{..., 'lastName': 'Skywalker', ...}
|
||||||
'firstName': u'Luke', 'lastName': u'Skywalker', 'age': '', '__name__': '...',
|
|
||||||
'email': u'luke@skywalker.universe',
|
{'acadTitles': '', 'standard.lastName': 'Skywalker', 'addr': 'Mr',
|
||||||
'standard.email': u'luke@skywalker.universe'}
|
'firstName': 'Luke', 'lastName': 'Skywalker', 'age': '', '__name__': '...',
|
||||||
|
'email': 'luke@skywalker.universe',
|
||||||
|
'standard.email': 'luke@skywalker.universe'}
|
||||||
|
|
||||||
If we do not provide a value for a required attribute we get a validation
|
If we do not provide a value for a required attribute we get a validation
|
||||||
error and the form will be displayed again.
|
error and the form will be displayed again.
|
||||||
|
|
||||||
>>> input = dict(firstName=u'Anakin', action='update')
|
>>> input = dict(firstName='Anakin', action='update')
|
||||||
>>> request = TestRequest(form=input)
|
>>> request = TestRequest(form=input)
|
||||||
>>> view = SchemaView(schema, request)
|
>>> view = SchemaView(schema, request)
|
||||||
>>> view.update()
|
>>> view.update()
|
||||||
|
@ -203,7 +211,7 @@ error and the form will be displayed again.
|
||||||
The same happens if we provide a number field with a string that cannot
|
The same happens if we provide a number field with a string that cannot
|
||||||
be converted to an integer.
|
be converted to an integer.
|
||||||
|
|
||||||
>>> input = dict(firstName=u'Anakin', lastName=u'Skywalker', age='foo',
|
>>> input = dict(firstName='Anakin', lastName='Skywalker', age='foo',
|
||||||
... action='update')
|
... action='update')
|
||||||
>>> request = TestRequest(form=input)
|
>>> request = TestRequest(form=input)
|
||||||
>>> view = SchemaView(schema, request)
|
>>> view = SchemaView(schema, request)
|
||||||
|
@ -216,7 +224,7 @@ More on special field types
|
||||||
>>> schema2 = workshop.clientSchemas['address']
|
>>> schema2 = workshop.clientSchemas['address']
|
||||||
>>> countryField = schema2.fields.country
|
>>> countryField = schema2.fields.country
|
||||||
>>> countryField.getVocabularyItems()
|
>>> countryField.getVocabularyItems()
|
||||||
[{'token': u'USA', 'title': u'USA'}, {'token': u'Germany', 'title': u'Germany'}]
|
[{'token': 'USA', 'title': 'USA'}, {'token': 'Germany', 'title': 'Germany'}]
|
||||||
|
|
||||||
|
|
||||||
Registering for Services Using a Registration Template
|
Registering for Services Using a Registration Template
|
||||||
|
@ -437,7 +445,7 @@ We are now ready to trigger a registration checkout.
|
||||||
|
|
||||||
>>> result = ruleManager.handleEvent(Event(checkoutEvent, client1))
|
>>> result = ruleManager.handleEvent(Event(checkoutEvent, client1))
|
||||||
sender: manager@workshops.com
|
sender: manager@workshops.com
|
||||||
recipients: [u'luke@skywalker.universe']
|
recipients: ['luke@skywalker.universe']
|
||||||
subject: Workshop Registration
|
subject: Workshop Registration
|
||||||
message:
|
message:
|
||||||
Dear Luke Skywalker,
|
Dear Luke Skywalker,
|
||||||
|
@ -474,7 +482,7 @@ rendered message.
|
||||||
>>> input = dict(message='feedback_html')
|
>>> input = dict(message='feedback_html')
|
||||||
>>> view = MessageView(workshop, TestRequest(form=input))
|
>>> view = MessageView(workshop, TestRequest(form=input))
|
||||||
>>> view.getMessage()
|
>>> view.getMessage()
|
||||||
u'<p>Dear Luke Skywalker...'
|
'<p>Dear Luke Skywalker...'
|
||||||
|
|
||||||
|
|
||||||
Service Manager and Service Views
|
Service Manager and Service Views
|
||||||
|
@ -527,7 +535,7 @@ because the ``waitingList`` flag has not been set.)
|
||||||
>>> srvView.registeredTotalSubmitted
|
>>> srvView.registeredTotalSubmitted
|
||||||
0
|
0
|
||||||
>>> srvView.registeredTotalsSubmitted
|
>>> srvView.registeredTotalsSubmitted
|
||||||
{'numberWaiting': '', 'number': 0}
|
{'number': 0, 'numberWaiting': ''}
|
||||||
|
|
||||||
Checkout
|
Checkout
|
||||||
--------
|
--------
|
||||||
|
@ -545,7 +553,7 @@ her registrations.
|
||||||
>>> checkout.getRegistrationsInfo()
|
>>> checkout.getRegistrationsInfo()
|
||||||
[...]
|
[...]
|
||||||
>>> checkout.listRegistrationsText()
|
>>> checkout.listRegistrationsText()
|
||||||
u'Event 1\nDatum: -\nUhrzeit: -\n\n'
|
'Event 1\nDatum: -\nUhrzeit: -\n\n'
|
||||||
|
|
||||||
When the user clicks the "Confirm Registration" button the corresponding
|
When the user clicks the "Confirm Registration" button the corresponding
|
||||||
actions will be carried out.
|
actions will be carried out.
|
||||||
|
@ -556,7 +564,7 @@ actions will be carried out.
|
||||||
>>> checkout = CheckoutView(workshop, request)
|
>>> checkout = CheckoutView(workshop, request)
|
||||||
>>> checkout.update()
|
>>> checkout.update()
|
||||||
sender: unknown@sender.com
|
sender: unknown@sender.com
|
||||||
recipients: [u'luke@skywalker.universe']
|
recipients: ['luke@skywalker.universe']
|
||||||
subject: Workshop Registration
|
subject: Workshop Registration
|
||||||
message: ...
|
message: ...
|
||||||
False
|
False
|
||||||
|
@ -579,7 +587,7 @@ for security reasons.)
|
||||||
>>> checkout = CheckoutView(workshop, request)
|
>>> checkout = CheckoutView(workshop, request)
|
||||||
>>> checkout.update()
|
>>> checkout.update()
|
||||||
sender: unknown@sender.com
|
sender: unknown@sender.com
|
||||||
recipients: [u'luke@skywalker.universe']
|
recipients: ['luke@skywalker.universe']
|
||||||
subject: Workshop Registration
|
subject: Workshop Registration
|
||||||
message: ...
|
message: ...
|
||||||
False
|
False
|
||||||
|
@ -621,7 +629,7 @@ possible.
|
||||||
True
|
True
|
||||||
|
|
||||||
>>> input = dict(lastName='Walker', firstName='John', email='john@walker.tv',
|
>>> input = dict(lastName='Walker', firstName='John', email='john@walker.tv',
|
||||||
... addr=u'Mr', action='update')
|
... addr='Mr', action='update')
|
||||||
>>> request = TestRequest(form=input)
|
>>> request = TestRequest(form=input)
|
||||||
>>> schema = workshop.clientSchemas['person']
|
>>> schema = workshop.clientSchemas['person']
|
||||||
>>> view = SchemaView(schema, request)
|
>>> view = SchemaView(schema, request)
|
||||||
|
@ -755,7 +763,7 @@ conference that is organized in parallel tracks.
|
||||||
>>> conference.__name__ = 'conference'
|
>>> conference.__name__ = 'conference'
|
||||||
|
|
||||||
>>> main = service.Service('conf_main', manager=conference,
|
>>> main = service.Service('conf_main', manager=conference,
|
||||||
... title=u'Conference', capacity=5)
|
... title='Conference', capacity=5)
|
||||||
>>> conference.services.append(main)
|
>>> conference.services.append(main)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
Organizations: Persons, Institutions, Addresses, Work, ...
|
Organizations: Persons, Institutions, Addresses, Work, ...
|
||||||
==========================================================
|
==========================================================
|
||||||
|
|
||||||
($Id$)
|
|
||||||
|
|
||||||
>>> from zope import component
|
>>> from zope import component
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,7 +34,7 @@ so we do not have to set up real objects.
|
||||||
>>> wi01 = workItems.add('001', 'john')
|
>>> wi01 = workItems.add('001', 'john')
|
||||||
>>> wi01
|
>>> wi01
|
||||||
<WorkItem ['001', 1, 'john', '...', 'new']:
|
<WorkItem ['001', 1, 'john', '...', 'new']:
|
||||||
{'created': ..., 'creator': 'john'}>
|
{'creator': 'john', 'created': ...}>
|
||||||
|
|
||||||
Properties that have not been set explicitly have a default of None; properties
|
Properties that have not been set explicitly have a default of None; properties
|
||||||
not specified in the IWorkItem interface will lead to an AttributeError.
|
not specified in the IWorkItem interface will lead to an AttributeError.
|
||||||
|
@ -53,7 +51,7 @@ Properties may be set as long as the work item is in status "new".
|
||||||
>>> wi01.setData(start=1229955772, party='annie')
|
>>> wi01.setData(start=1229955772, party='annie')
|
||||||
>>> wi01
|
>>> wi01
|
||||||
<WorkItem ['001', 1, 'annie', '2008-12-22 15:22', 'new']:
|
<WorkItem ['001', 1, 'annie', '2008-12-22 15:22', 'new']:
|
||||||
{'start': 1229955772, 'created': ..., 'creator': 'john'}>
|
{'creator': 'john', 'created': ..., ...}>
|
||||||
|
|
||||||
The duration value is calculated automatically when start and end are set;
|
The duration value is calculated automatically when start and end are set;
|
||||||
the effort is taken from the duration if not set explicitly.
|
the effort is taken from the duration if not set explicitly.
|
||||||
|
@ -84,8 +82,7 @@ be excluded from queries.
|
||||||
'planned_x'
|
'planned_x'
|
||||||
>>> wi02
|
>>> wi02
|
||||||
<WorkItem ['001', 1, 'jim', '2008-12-22 15:22', 'accepted']:
|
<WorkItem ['001', 1, 'jim', '2008-12-22 15:22', 'accepted']:
|
||||||
{'duration': 700, 'start': 1229955772, 'created': ...,
|
{'creator': 'jim', 'created': ..., ...}>
|
||||||
'end': 1229956372, 'creator': 'jim'}>
|
|
||||||
|
|
||||||
It is not possible to change a value of a work item that is not in state "new".
|
It is not possible to change a value of a work item that is not in state "new".
|
||||||
|
|
||||||
|
@ -100,7 +97,7 @@ but may also be specified explicitly.
|
||||||
>>> wi03 = wi02.doAction('start', 'jim', start=1229958000)
|
>>> wi03 = wi02.doAction('start', 'jim', start=1229958000)
|
||||||
>>> wi03
|
>>> wi03
|
||||||
<WorkItem ['001', 1, 'jim', '2008-12-22 16:00', 'running']:
|
<WorkItem ['001', 1, 'jim', '2008-12-22 16:00', 'running']:
|
||||||
{'duration': 0, 'start': 1229958000, 'created': ..., 'creator': 'jim'}>
|
{'creator': 'jim', 'created': ..., ...}>
|
||||||
|
|
||||||
Stopping and finishing work
|
Stopping and finishing work
|
||||||
---------------------------
|
---------------------------
|
||||||
|
@ -113,10 +110,10 @@ as "running" will be replaced by a new one.
|
||||||
|
|
||||||
>>> wi03
|
>>> wi03
|
||||||
<WorkItem ['001', 1, 'jim', '2008-12-22 16:00', 'replaced']:
|
<WorkItem ['001', 1, 'jim', '2008-12-22 16:00', 'replaced']:
|
||||||
{'duration': 0, 'start': 1229958000, 'created': ..., 'creator': 'jim'}>
|
{'creator': 'jim', 'created': ..., ...}>
|
||||||
>>> wi04
|
>>> wi04
|
||||||
<WorkItem ['001', 1, 'jim', '2008-12-22 16:00', 'done']:
|
<WorkItem ['001', 1, 'jim', '2008-12-22 16:00', 'done']:
|
||||||
{'start': 1229958000, 'created': ..., 'end': 1229958300, 'creator': 'jim'}>
|
{'creator': 'jim', 'created': ..., ...}>
|
||||||
|
|
||||||
After another hour Jim works again on the task; he now finishes it within
|
After another hour Jim works again on the task; he now finishes it within
|
||||||
ten minutes and records this in one step.
|
ten minutes and records this in one step.
|
||||||
|
@ -124,7 +121,7 @@ ten minutes and records this in one step.
|
||||||
>>> wi05 = wi04.doAction('finish', 'jim', start=1229961600, end=1229962200)
|
>>> wi05 = wi04.doAction('finish', 'jim', start=1229961600, end=1229962200)
|
||||||
>>> wi05
|
>>> wi05
|
||||||
<WorkItem ['001', 1, 'jim', '2008-12-22 17:00', 'finished']:
|
<WorkItem ['001', 1, 'jim', '2008-12-22 17:00', 'finished']:
|
||||||
{'start': 1229961600, 'created': ..., 'end': 1229962200, 'creator': 'jim'}>
|
{'creator': 'jim', 'created': ..., ...}>
|
||||||
>>> wi05.duration, wi05.effort
|
>>> wi05.duration, wi05.effort
|
||||||
(600, 600)
|
(600, 600)
|
||||||
|
|
||||||
|
@ -137,7 +134,7 @@ As the work is now finished, the work item may be closed; the corresponding
|
||||||
>>> wi06 = wi05.doAction('close', 'john')
|
>>> wi06 = wi05.doAction('close', 'john')
|
||||||
>>> wi06
|
>>> wi06
|
||||||
<WorkItem ['001', 1, 'jim', '... ...', 'closed']:
|
<WorkItem ['001', 1, 'jim', '... ...', 'closed']:
|
||||||
{'start': ..., 'created': ..., 'end': ..., 'creator': 'john'}>
|
{'creator': 'john', 'created': ..., ...}>
|
||||||
|
|
||||||
Let's now check how many work items have been generated.
|
Let's now check how many work items have been generated.
|
||||||
|
|
||||||
|
@ -158,10 +155,10 @@ delegated so that it may be selected by queries.
|
||||||
|
|
||||||
>>> wi07
|
>>> wi07
|
||||||
<WorkItem ['001', 2, 'john', '2008-12-22 19:33', 'delegated']:
|
<WorkItem ['001', 2, 'john', '2008-12-22 19:33', 'delegated']:
|
||||||
{'start': 1229970800, 'created': ..., 'creator': 'john'}>
|
{'creator': 'john', 'created': ..., 'start': 1229970800, 'target': '0000008'}>
|
||||||
>>> wi08
|
>>> wi08
|
||||||
<WorkItem ['001', 3, 'annie', '2008-12-22 19:33', 'planned']:
|
<WorkItem ['001', 3, 'annie', '2008-12-22 19:33', 'planned']:
|
||||||
{'start': 1229970800, 'created': ..., 'source': '0000007', 'creator': 'john'}>
|
{'creator': 'john', 'created': ..., 'start': 1229970800, 'source': '0000007'}>
|
||||||
>>> len(list(workItems))
|
>>> len(list(workItems))
|
||||||
8
|
8
|
||||||
|
|
||||||
|
@ -180,10 +177,10 @@ Note that nevertheless only the last work item of a run may be modified.
|
||||||
|
|
||||||
>>> wi08
|
>>> wi08
|
||||||
<WorkItem ['001', 3, 'annie', '2008-12-22 19:33', 'replaced']:
|
<WorkItem ['001', 3, 'annie', '2008-12-22 19:33', 'replaced']:
|
||||||
{'start': 1229970800, 'created': ..., 'creator': 'john'}>
|
{'creator': 'john', 'created': ..., 'start': 1229970800, 'source': '0000007'}>
|
||||||
>>> wi09
|
>>> wi09
|
||||||
<WorkItem ['001', 3, 'annie', '2008-12-22 19:33', 'planned']:
|
<WorkItem ['001', 3, 'annie', '2008-12-22 19:33', 'planned']:
|
||||||
{'duration': 3600, 'start': 1229970800, 'created': ..., 'creator': 'annie'}>
|
{'creator': 'annie', 'created': ..., ...}>
|
||||||
|
|
||||||
|
|
||||||
Moving Work Items to Other Tasks
|
Moving Work Items to Other Tasks
|
||||||
|
@ -192,7 +189,7 @@ Moving Work Items to Other Tasks
|
||||||
>>> wi10 = wi07.doAction('move', 'john')
|
>>> wi10 = wi07.doAction('move', 'john')
|
||||||
>>> wi10
|
>>> wi10
|
||||||
<WorkItem ['001', 4, 'john', '2008-12-22 19:33', 'delegated']:
|
<WorkItem ['001', 4, 'john', '2008-12-22 19:33', 'delegated']:
|
||||||
{'start': 1229970800, 'created': ..., 'source': '0000010', 'creator': 'john'}>
|
{'creator': 'john', 'created': ..., 'start': 1229970800, 'source': '0000010'}>
|
||||||
|
|
||||||
|
|
||||||
Queries
|
Queries
|
||||||
|
@ -215,8 +212,8 @@ Close a run with some delegated items.
|
||||||
>>> wi07a = workItems.query(run=2)[-2]
|
>>> wi07a = workItems.query(run=2)[-2]
|
||||||
>>> wi07b = workItems.query(run=2)[-1]
|
>>> wi07b = workItems.query(run=2)[-1]
|
||||||
>>> wi07b
|
>>> wi07b
|
||||||
<WorkItem ['001', 2, 'john', '2008-12-22 19:33', 'moved']: {'start': 1229970800,
|
<WorkItem ['001', 2, 'john', '2008-12-22 19:33', 'moved']:
|
||||||
'created': ..., 'target': '0000011', 'creator': 'john'}>
|
{'creator': 'john', 'created': ..., 'start': 1229970800, 'target': '0000011'}>
|
||||||
|
|
||||||
>>> wi07c = wi07b.doAction('close', 'john')
|
>>> wi07c = wi07b.doAction('close', 'john')
|
||||||
|
|
||||||
|
|
|
@ -66,12 +66,12 @@ def toStr(value, encoding='UTF-8'):
|
||||||
|
|
||||||
def toUnicode(value, encoding='UTF-8', fallback='ISO8859-15'):
|
def toUnicode(value, encoding='UTF-8', fallback='ISO8859-15'):
|
||||||
# or: fallback='CP852'
|
# or: fallback='CP852'
|
||||||
if isinstance(value, unicode):
|
if isinstance(value, str):
|
||||||
return value
|
return value
|
||||||
elif isinstance(value, str):
|
elif isinstance(value, bytes):
|
||||||
try:
|
try:
|
||||||
return value.decode(encoding)
|
return value.decode(encoding)
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
return value.decode(fallback)
|
return value.decode(fallback)
|
||||||
else:
|
else:
|
||||||
return u''
|
return ''
|
||||||
|
|
Loading…
Add table
Reference in a new issue