diff --git a/cybertools/composer/message/instance.py b/cybertools/composer/message/instance.py index b6f01f8..8f8a89d 100644 --- a/cybertools/composer/message/instance.py +++ b/cybertools/composer/message/instance.py @@ -1,31 +1,12 @@ -# -# 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 -# +# cybertools.composer.message.instance -""" -Message instance and related classes. - -$Id$ +""" Message instance and related classes. """ -from cgi import parse_qs +#from cgi import parse_qs +from urllib.parse import parse_qs from string import Template from zope import component -from zope.interface import implements from zope.publisher.browser import TestRequest try: from zope.traversing.browser.absoluteurl import absoluteURL @@ -149,7 +130,7 @@ class MessageInstance(Instance): #path = aq_inner(self.client.manager).getPhysicalPath() path = self.client.manager.getPhysicalPath() if len(path) >= 3 and path[-3] == 'sm_clients': - print '*** path correction:', path + print('*** path correction:', path) # evil hack for aqcuisition-wrapped manager object path = path[:-3] url = request.physicalPathToURL(path) diff --git a/cybertools/composer/rule/mail.py b/cybertools/composer/rule/mail.py index af89463..028e0c1 100644 --- a/cybertools/composer/rule/mail.py +++ b/cybertools/composer/rule/mail.py @@ -1,30 +1,10 @@ -# -# 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 -# +# cybertools.composer.rule.mail -""" -Action handler for sending emails. - -$Id$ +""" Action handler for sending emails. """ -from email.MIMEText import MIMEText +from email.mime.text import MIMEText from zope import component -from zope.interface import implements from cybertools.composer.interfaces import IInstance from cybertools.composer.rule.interfaces import IActionHandler @@ -47,7 +27,7 @@ class MailActionHandler(ActionHandler): return data def prepareMessage(self, subject, text, sender, recipient): - text = text.encode('utf-8') + #text = text.encode('utf-8') msg = MIMEText(text, 'plain', 'utf-8') msg['Subject'] = subject msg['From'] = sender diff --git a/cybertools/composer/rule/message.py b/cybertools/composer/rule/message.py index 6926aee..5a8cb46 100644 --- a/cybertools/composer/rule/message.py +++ b/cybertools/composer/rule/message.py @@ -1,28 +1,7 @@ -# -# 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 -# +# cybertools.composer.rule.message +""" 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.instance import MessageInstance diff --git a/cybertools/composer/rule/tests.py b/cybertools/composer/rule/tests.py index 280e09e..a515f98 100755 --- a/cybertools/composer/rule/tests.py +++ b/cybertools/composer/rule/tests.py @@ -14,7 +14,7 @@ class TestMailer(object): msg = message_from_string(message) print('subject:', msg['Subject']) print('message:') - print(msg.get_payload(decode=True)) + print(msg.get_payload(decode=True).decode('UTF-8')) class Test(unittest.TestCase): diff --git a/cybertools/organize/README.txt b/cybertools/organize/README.txt index e272251..f6c6665 100644 --- a/cybertools/organize/README.txt +++ b/cybertools/organize/README.txt @@ -13,11 +13,11 @@ Persons and Addresses Let's start with a Person: >>> from cybertools.organize.party import Person - >>> john = Person(u'Smith') + >>> john = Person('Smith') >>> john.lastName - u'Smith' + 'Smith' >>> john.firstName - u'' + '' >>> john.birthDate is None True >>> john.addresses @@ -35,9 +35,9 @@ A Person object knows the age of the person: >>> john.age >= 26 True - >>> john.firstName = u'John' + >>> john.firstName = 'John' >>> john.firstName - u'John' + 'John' Addresses --------- @@ -45,10 +45,10 @@ Addresses Let's create an address and assign it to a person: >>> 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'].street - u'Broadway 1' + 'Broadway 1' Tasks diff --git a/cybertools/organize/browser/report.py b/cybertools/organize/browser/report.py index 128f1fa..b4386eb 100644 --- a/cybertools/organize/browser/report.py +++ b/cybertools/organize/browser/report.py @@ -4,7 +4,7 @@ """ import csv -from io import StringIO +from io import BytesIO, StringIO import itertools from zope import component from zope.cachedescriptors.property import Lazy @@ -106,7 +106,7 @@ class RegistrationsExportCsv(BaseView): #waiting.append(reg.numberWaiting) if reg.number or reg.numberWaiting: hasRegs = True - if reg.timeStamp < timeStamp: + if timeStamp == '' or reg.timeStamp < timeStamp: timeStamp = reg.timeStamp if not hasRegs: continue @@ -134,6 +134,7 @@ class RegistrationsExportCsv(BaseView): delimiter = ';' methodName = self.request.get('get_data_method', 'getAllDataInColumns') method = getattr(self, methodName, self.getData) + #output = BytesIO() output = StringIO() try: csv.writer(output, dialect='excel', delimiter=delimiter, @@ -153,6 +154,7 @@ class RegistrationsExportCsv(BaseView): return result def encode(self, text): + return text if isinstance(text, str): result = [] for c in text: diff --git a/cybertools/organize/servicemanager.txt b/cybertools/organize/servicemanager.txt index b538c5b..82cb2bb 100644 --- a/cybertools/organize/servicemanager.txt +++ b/cybertools/organize/servicemanager.txt @@ -31,9 +31,9 @@ parts (events, lectures, ...). >>> workshop.__name__ = '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, - ... title=u'Event 2') + ... title='Event 2') >>> workshop.services.append(event1) >>> 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. >>> workshop.clientSchemas.append(schema.Schema( - ... schema.Field('lastName', u'Last Name', required=True, + ... schema.Field('lastName', 'Last Name', required=True, ... standardFieldName='lastName'), - ... schema.Field('firstName', u'First Name'), - ... schema.Field('email', u'Email Address', required=True, + ... schema.Field('firstName', 'First Name'), + ... schema.Field('email', 'Email Address', required=True, ... fieldType='email', standardFieldName='email'), - ... schema.Field('age', u'Age', fieldType='number'), - ... schema.Field('addr', u'Personal Address', required=True, + ... schema.Field('age', 'Age', fieldType='number'), + ... schema.Field('addr', 'Personal Address', required=True, ... fieldtype='radiobuttons', - ... vocabulary=u'Mrs\nMr'), - ... schema.Field('acadTitles', u'Academic Titles', + ... vocabulary='Mrs\nMr'), + ... schema.Field('acadTitles', 'Academic Titles', ... fieldtype='checkboxes', - ... vocabulary=u'Prof.\nDr.'), + ... vocabulary='Prof.\nDr.'), ... name='person', ... manager=workshop, ... )) >>> workshop.clientSchemas.append(schema.Schema( - ... schema.Field('street', u'Street'), - ... schema.Field('city', u'City', required=True), - ... schema.Field('country', u'Country', required=True, - ... fieldType='dropdown', vocabulary=u'USA\nGermany'), + ... schema.Field('street', 'Street'), + ... schema.Field('city', 'City', required=True), + ... schema.Field('country', 'Country', required=True, + ... fieldType='dropdown', vocabulary='USA\nGermany'), ... name='address', ... manager=workshop, ... )) @@ -76,7 +76,7 @@ So we are now ready to register participants. >>> client1 = IClientFactory(workshop)() >>> 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.template = workshop.clientSchemas['person'] >>> state = inst.applyTemplate(data=data) @@ -85,7 +85,7 @@ So we are now ready to register participants. ['schema.client.__standard__', 'schema.client.person'] >>> client1.__schema_attributes__['schema.client.person']['lastName'] - u'Skywalker' + 'Skywalker' Instead of directly peeking into the attributes we can also use a suitable instance adapter. @@ -93,10 +93,12 @@ suitable instance adapter. >>> inst = IInstance(client1) >>> inst.template = workshop.clientSchemas['person'] >>> inst.applyTemplate() - {'acadTitles': u'', 'standard.lastName': u'Skywalker', 'addr': u'Mr', - 'firstName': u'', 'lastName': u'Skywalker', 'age': '', '__name__': '...', - 'email': u'luke@skywalker.universe', - 'standard.email': u'luke@skywalker.universe'} + {..., 'lastName': 'Skywalker', ...} + +{'acadTitles': '', 'standard.lastName': 'Skywalker', 'addr': 'Mr', + 'firstName': '', 'lastName': 'Skywalker', 'age': '', '__name__': '...', + 'email': 'luke@skywalker.universe', + 'standard.email': 'luke@skywalker.universe'} Note that the ``standardFieldName`` setting for the ``lastName`` field 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. >>> from zope.interface import implementer + >>> from zope.session.interfaces import IClientId >>> from zope.session.interfaces import IClientIdManager, ISessionDataContainer >>> from zope.session import session - >>> component.provideAdapter(session.ClientId) + >>> component.provideAdapter(session.ClientId, provides=IClientId) >>> component.provideAdapter(session.Session) >>> component.provideUtility(session.RAMSessionDataContainer(), ISessionDataContainer) >>> class ClientIdManager(object): - ... implements(IClientIdManager) ... def getClientId(self, request): return 'dummy' >>> ClientIdManager = implementer(IClientIdManager)(ClientIdManager) >>> component.provideUtility(ClientIdManager()) @@ -143,17 +145,19 @@ the corresponding client. >>> request = TestRequest(form=input) >>> view = SchemaView(schema, request) >>> view.data - {'acadTitles': u'', 'standard.lastName': u'Skywalker', 'addr': u'Mr', - 'firstName': u'', 'lastName': u'Skywalker', 'age': '', '__name__': '...', - 'email': u'luke@skywalker.universe', - 'standard.email': u'luke@skywalker.universe'} + {..., 'lastName': 'Skywalker', ...} + +{'acadTitles': '', 'standard.lastName': 'Skywalker', 'addr': 'Mr', + '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 be created - if we clear the client name in the session first via ``view.setClientName('')``. >>> input = dict(lastName='Solo', firstName='Han', email='han.solo@space.net', - ... addr=u'Mr', action='update') + ... addr='Mr', action='update') >>> request = TestRequest(form=input) >>> view = SchemaView(schema, request) >>> view.setClientName('') @@ -168,15 +172,17 @@ be created - if we clear the client name in the session first via >>> request = TestRequest(form=input) >>> view = SchemaView(schema, request) >>> view.data - {'acadTitles': u'', 'standard.lastName': u'Solo', 'addr': u'Mr', - 'firstName': u'Han', 'lastName': u'Solo', - 'age': '', '__name__': '...', 'email': u'han.solo@space.net', - 'standard.email': u'han.solo@space.net'} + {..., 'lastName': 'Solo', ...} + +{'acadTitles': '', 'standard.lastName': 'Solo', 'addr': 'Mr', + '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. - >>> input = dict(lastName=u'Skywalker', firstName=u'Luke', id=client1Name, - ... email='luke@skywalker.universe', addr=u'Mr', action='update') + >>> input = dict(lastName='Skywalker', firstName='Luke', id=client1Name, + ... email='luke@skywalker.universe', addr='Mr', action='update') >>> request = TestRequest(form=input) >>> view = SchemaView(schema, request) >>> view.update() @@ -186,15 +192,17 @@ If we provide an id parameter we may also change an existing client. >>> request = TestRequest(form=input) >>> view = SchemaView(schema, request) >>> view.data - {'acadTitles': u'', 'standard.lastName': u'Skywalker', 'addr': u'Mr', - 'firstName': u'Luke', 'lastName': u'Skywalker', 'age': '', '__name__': '...', - 'email': u'luke@skywalker.universe', - 'standard.email': u'luke@skywalker.universe'} + {..., 'lastName': 'Skywalker', ...} + +{'acadTitles': '', 'standard.lastName': 'Skywalker', 'addr': 'Mr', + '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 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) >>> view = SchemaView(schema, request) >>> 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 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') >>> request = TestRequest(form=input) >>> view = SchemaView(schema, request) @@ -216,7 +224,7 @@ More on special field types >>> schema2 = workshop.clientSchemas['address'] >>> countryField = schema2.fields.country >>> 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 @@ -437,7 +445,7 @@ We are now ready to trigger a registration checkout. >>> result = ruleManager.handleEvent(Event(checkoutEvent, client1)) sender: manager@workshops.com - recipients: [u'luke@skywalker.universe'] + recipients: ['luke@skywalker.universe'] subject: Workshop Registration message: Dear Luke Skywalker, @@ -474,7 +482,7 @@ rendered message. >>> input = dict(message='feedback_html') >>> view = MessageView(workshop, TestRequest(form=input)) >>> view.getMessage() - u'
Dear Luke Skywalker...' + '
Dear Luke Skywalker...'
Service Manager and Service Views
@@ -527,7 +535,7 @@ because the ``waitingList`` flag has not been set.)
>>> srvView.registeredTotalSubmitted
0
>>> srvView.registeredTotalsSubmitted
- {'numberWaiting': '', 'number': 0}
+ {'number': 0, 'numberWaiting': ''}
Checkout
--------
@@ -545,7 +553,7 @@ her registrations.
>>> checkout.getRegistrationsInfo()
[...]
>>> 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
actions will be carried out.
@@ -556,7 +564,7 @@ actions will be carried out.
>>> checkout = CheckoutView(workshop, request)
>>> checkout.update()
sender: unknown@sender.com
- recipients: [u'luke@skywalker.universe']
+ recipients: ['luke@skywalker.universe']
subject: Workshop Registration
message: ...
False
@@ -579,7 +587,7 @@ for security reasons.)
>>> checkout = CheckoutView(workshop, request)
>>> checkout.update()
sender: unknown@sender.com
- recipients: [u'luke@skywalker.universe']
+ recipients: ['luke@skywalker.universe']
subject: Workshop Registration
message: ...
False
@@ -621,7 +629,7 @@ possible.
True
>>> input = dict(lastName='Walker', firstName='John', email='john@walker.tv',
- ... addr=u'Mr', action='update')
+ ... addr='Mr', action='update')
>>> request = TestRequest(form=input)
>>> schema = workshop.clientSchemas['person']
>>> view = SchemaView(schema, request)
@@ -755,7 +763,7 @@ conference that is organized in parallel tracks.
>>> conference.__name__ = 'conference'
>>> main = service.Service('conf_main', manager=conference,
- ... title=u'Conference', capacity=5)
+ ... title='Conference', capacity=5)
>>> conference.services.append(main)
diff --git a/cybertools/organize/work.txt b/cybertools/organize/work.txt
index c276fc1..a7848e9 100644
--- a/cybertools/organize/work.txt
+++ b/cybertools/organize/work.txt
@@ -2,8 +2,6 @@
Organizations: Persons, Institutions, Addresses, Work, ...
==========================================================
- ($Id$)
-
>>> from zope import component
@@ -36,7 +34,7 @@ so we do not have to set up real objects.
>>> wi01 = workItems.add('001', 'john')
>>> wi01