source: main/waeup.sirp/trunk/src/waeup/sirp/interfaces.py @ 6916

Last change on this file since 6916 was 6916, checked in by Henrik Bettermann, 14 years ago

Implement SessionConfiguration?, SessionConfigurationAddFormPage?, SessionConfigurationFactory? (work in progress).

  • Property svn:eol-style set to native
File size: 15.1 KB
Line 
1##
2## interfaces.py
3import os
4from datetime import datetime
5from hurry.workflow.interfaces import IWorkflow, IWorkflowInfo
6from zc.sourcefactory.basic import BasicSourceFactory
7from zope import schema
8from zope.component import getUtility
9from zope.component.interfaces import IObjectEvent
10from zope.interface import Interface, Attribute, implements
11from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
12
13default_frontpage = u'' + open(os.path.join(
14        os.path.dirname(__file__), 'frontpage.rst'), 'rb').read()
15
16def SimpleWAeUPVocabulary(*terms):
17    """A well-buildt vocabulary provides terms with a value, token and
18       title for each term
19    """
20    return SimpleVocabulary([
21            SimpleTerm(value, value, title) for title, value in terms])
22
23def year_range():
24    curr_year = datetime.now().year
25    return range(curr_year - 2, curr_year + 5)
26
27def academic_sessions():
28    curr_year = datetime.now().year
29    year_range = range(curr_year - 10, curr_year + 2)
30    return [('%s/%s' % (year,year+1), year) for year in year_range]
31
32academic_sessions_vocab = SimpleWAeUPVocabulary(*academic_sessions())
33
34class FatalCSVError(Exception):
35    """Some row could not be processed.
36    """
37    pass
38
39class DuplicationError(Exception):
40    """An exception that can be raised when duplicates are found.
41
42    When raising :exc:`DuplicationError` you can, beside the usual
43    message, specify a list of objects which are duplicates. These
44    values can be used by catching code to print something helpful or
45    similar.
46    """
47    def __init__(self, msg, entries=[]):
48        self.msg = msg
49        self.entries = entries
50
51    def __str__(self):
52        return '%r' % self.msg
53
54class RoleSource(BasicSourceFactory):
55    """A source for global roles.
56    """
57    def getValues(self):
58        # late import: in interfaces we should not import local modules
59        from waeup.sirp.permissions import getWAeUPRoleNames
60        return getWAeUPRoleNames()
61
62    def getTitle(self, value):
63        # late import: in interfaces we should not import local modules
64        from waeup.sirp.permissions import getRoles
65        roles = dict(getRoles())
66        if value in roles.keys():
67            title = roles[value].title
68            if '.' in title:
69                title = title.split('.', 2)[1]
70        return title
71
72class IWAeUPObject(Interface):
73    """A WAeUP object.
74
75    This is merely a marker interface.
76    """
77
78class IUniversity(IWAeUPObject):
79    """Representation of a university.
80    """
81
82
83class IWAeUPContainer(IWAeUPObject):
84    """A container for WAeUP objects.
85    """
86
87class IWAeUPContained(IWAeUPObject):
88    """An item contained in an IWAeUPContainer.
89    """
90
91class IWAeUPExporter(Interface):
92    """An exporter for objects.
93    """
94    def export(obj, filepath=None):
95        """Export by pickling.
96
97        Returns a file-like object containing a representation of `obj`.
98
99        This is done using `pickle`. If `filepath` is ``None``, a
100        `cStringIO` object is returned, that contains the saved data.
101        """
102
103class IWAeUPXMLExporter(Interface):
104    """An XML exporter for objects.
105    """
106    def export(obj, filepath=None):
107        """Export as XML.
108
109        Returns an XML representation of `obj`.
110
111        If `filepath` is ``None``, a StringIO` object is returned,
112        that contains the transformed data.
113        """
114
115class IWAeUPXMLImporter(Interface):
116    """An XML import for objects.
117    """
118    def doImport(filepath):
119        """Create Python object from XML.
120
121        Returns a Python object.
122        """
123
124class IBatchProcessor(Interface):
125    """A batch processor that handles mass-operations.
126    """
127    name = schema.TextLine(
128        title = u'Importer name'
129        )
130
131    mode = schema.Choice(
132        title = u'Import mode',
133        values = ['create', 'update', 'remove']
134        )
135
136    def doImport(path, headerfields, mode='create', user='Unknown',
137                 logger=None):
138        """Read data from ``path`` and update connected object.
139
140        `headerfields` is a list of headerfields as read from the file
141        to import.
142
143        `mode` gives the import mode to use (``'create'``,
144        ``'update'``, or ``'remove'``.
145
146        `user` is a string describing the user performing the
147        import. Normally fetched from current principal.
148
149        `logger` is the logger to use during import.
150        """
151
152class IUserAccount(IWAeUPObject):
153    """A user account.
154    """
155    name = schema.TextLine(
156        title = u'User ID',
157        description = u'Login name of user',
158        required = True,)
159    title = schema.TextLine(
160        title = u'Name',
161        description = u'Real name of user',
162        required = False,)
163    description = schema.TextLine(
164        title = u'Description',
165        required = False,)
166    password = schema.Password(
167        title = u'Password',
168        required = True,)
169    roles = schema.List(
170        title = u'Global roles',
171        value_type = schema.Choice(source=RoleSource()))
172
173
174class IUserContainer(IWAeUPObject):
175    """A container for users (principals).
176
177    These users are used for authentication purposes.
178    """
179
180    def addUser(name, password, title=None, description=None):
181        """Add a user.
182        """
183
184    def delUser(name):
185        """Delete a user if it exists.
186        """
187
188class ILocalRolesAssignable(Interface):
189    """The local roles assignable to an object.
190    """
191    def __call__():
192        """Returns a list of dicts.
193
194        Each dict contains a ``name`` referring to the role assignable
195        for the specified object and a `title` to describe the range
196        of users to which this role can be assigned.
197        """
198
199class IConfigurationContainer(IWAeUPObject):
200    """A container for session configuration objects.
201    """
202
203    name = schema.TextLine(
204        title = u'Name of University',
205        default = u'Sample University',
206        required = True,
207        )
208
209    title = schema.TextLine(
210        title = u'Title of frontpage',
211        default = u'Welcome to the Student Information and Registration ' +
212                  u'Portal of Sample University',
213        required = False,
214        )
215
216    skin = schema.Choice(
217        title = u'Skin',
218        default = u'gray waeup theme',
219        vocabulary = 'waeup.sirp.browser.theming.ThemesVocabulary',
220        required = True,
221        )
222
223    frontpage = schema.Text(
224        title = u'Content in reST format',
225        required = False,
226        default = default_frontpage,
227        )
228
229class ISessionConfiguration(IWAeUPObject):
230    """A session configuration object.
231    """
232
233    academic_session = schema.Choice(
234        title = u'Academic Session',
235        source = academic_sessions_vocab,
236        default = None,
237        required = True,
238        readonly = True,
239        )
240
241    fee_1 = schema.Int(
242        title = u'School Fee',
243        default = 0,
244        )
245
246    fee_2 = schema.Int(
247        title = u'Surcharge',
248        default = 0,
249        )
250
251class ISessionConfigurationAdd(ISessionConfiguration):
252    """A session configuration object in add mode.
253    """
254
255    academic_session = schema.Choice(
256        title = u'Academic Session',
257        source = academic_sessions_vocab,
258        default = None,
259        required = True,
260        readonly = False,
261        )
262
263ISessionConfigurationAdd['academic_session'].order =  ISessionConfiguration[
264    'academic_session'].order
265
266class IDataCenter(IWAeUPObject):
267    """A data center.
268
269    TODO : declare methods, at least those needed by pages.
270    """
271    pass
272
273class IDataCenterFile(Interface):
274    """A data center file.
275    """
276
277    name = schema.TextLine(
278        title = u'Filename')
279
280    size = schema.TextLine(
281        title = u'Human readable file size')
282
283    uploaddate = schema.TextLine(
284        title = u'Human readable upload datetime')
285
286    lines = schema.Int(
287        title = u'Number of lines in file')
288
289    def getDate():
290        """Get creation timestamp from file in human readable form.
291        """
292
293    def getSize():
294        """Get human readable size of file.
295        """
296
297    def getLinesNumber():
298        """Get number of lines of file.
299        """
300
301class IDataCenterStorageMovedEvent(IObjectEvent):
302    """Emitted, when the storage of a datacenter changes.
303    """
304
305class IObjectUpgradeEvent(IObjectEvent):
306    """Can be fired, when an object shall be upgraded.
307    """
308
309class ILocalRoleSetEvent(IObjectEvent):
310    """A local role was granted/revoked for a principal on an object.
311    """
312    role_id = Attribute(
313        "The role id that was set.")
314    principal_id = Attribute(
315        "The principal id for which the role was granted/revoked.")
316    granted = Attribute(
317        "Boolean. If false, then the role was revoked.")
318
319class IQueryResultItem(Interface):
320    """An item in a search result.
321    """
322    url = schema.TextLine(
323        title = u'URL that links to the found item')
324    title = schema.TextLine(
325        title = u'Title displayed in search results.')
326    description = schema.Text(
327        title = u'Longer description of the item found.')
328
329class IWAeUPSIRPPluggable(Interface):
330    """A component that might be plugged into a WAeUP SIRP app.
331
332    Components implementing this interface are referred to as
333    'plugins'. They are normally called when a new
334    :class:`waeup.sirp.app.University` instance is created.
335
336    Plugins can setup and update parts of the central site without the
337    site object (normally a :class:`waeup.sirp.app.University` object)
338    needing to know about that parts. The site simply collects all
339    available plugins, calls them and the plugins care for their
340    respective subarea like the applicants area or the datacenter
341    area.
342
343    Currently we have no mechanism to define an order of plugins. A
344    plugin should therefore make no assumptions about the state of the
345    site or other plugins being run before and instead do appropriate
346    checks if necessary.
347
348    Updates can be triggered for instance by the respective form in
349    the site configuration. You normally do updates when the
350    underlying software changed.
351    """
352    def setup(site, name, logger):
353        """Create an instance of the plugin.
354
355        The method is meant to be called by the central app (site)
356        when it is created.
357
358        `site`:
359           The site that requests a setup.
360
361        `name`:
362           The name under which the plugin was registered (utility name).
363
364        `logger`:
365           A standard Python logger for the plugins use.
366        """
367
368    def update(site, name, logger):
369        """Method to update an already existing plugin.
370
371        This might be called by a site when something serious
372        changes. It is a poor-man replacement for Zope generations
373        (but probably more comprehensive and better understandable).
374
375        `site`:
376           The site that requests an update.
377
378        `name`:
379           The name under which the plugin was registered (utility name).
380
381        `logger`:
382           A standard Python logger for the plugins use.
383        """
384
385class IAuthPluginUtility(Interface):
386    """A component that cares for authentication setup at site creation.
387
388    Utilities providing this interface are looked up when a Pluggable
389    Authentication Utility (PAU) for any
390    :class:`waeup.sirp.app.University` instance is created and put
391    into ZODB.
392
393    The setup-code then calls the `register` method of the utility and
394    expects a modified (or unmodified) version of the PAU back.
395
396    This allows to define any authentication setup modifications by
397    submodules or third-party modules/packages.
398    """
399
400    def register(pau):
401        """Register any plugins wanted to be in the PAU.
402        """
403
404    def unregister(pau):
405        """Unregister any plugins not wanted to be in the PAU.
406        """
407
408class IObjectConverter(Interface):
409    """Object converters are available as simple adapters, adapting
410       interfaces (not regular instances).
411
412    """
413
414    def fromStringDict(self, data_dict, context, form_fields=None):
415        """Convert values in `data_dict`.
416
417        Converts data in `data_dict` into real values based on
418        `context` and `form_fields`.
419
420        `data_dict` is a mapping (dict) from field names to values
421        represented as strings.
422
423        The fields (keys) to convert can be given in optional
424        `form_fields`. If given, form_fields should be an instance of
425        :class:`zope.formlib.form.Fields`. Suitable instances are for
426        example created by :class:`grok.AutoFields`.
427
428        If no `form_fields` are given, a default is computed from the
429        associated interface.
430
431        The `context` can be an existing object (implementing the
432        associated interface) or a factory name. If it is a string, we
433        try to create an object using
434        :func:`zope.component.createObject`.
435
436        Returns a tuple ``(<FIELD_ERRORS>, <INVARIANT_ERRORS>,
437        <DATA_DICT>)`` where
438
439        ``<FIELD_ERRORS>``
440           is a list of tuples ``(<FIELD_NAME>, <ERROR>)`` for each
441           error that happened when validating the input data in
442           `data_dict`
443
444        ``<INVARIANT_ERRORS>``
445           is a list of invariant errors concerning several fields
446
447        ``<DATA_DICT>``
448           is a dict with the values from input dict converted.
449
450        If errors happen, i.e. the error lists are not empty, always
451        an empty ``<DATA_DICT>`` is returned.
452
453        If ``<DATA_DICT>` is non-empty, there were no errors.
454        """
455
456class IObjectHistory(Interface):
457
458    messages = schema.List(
459        title = u'List of messages stored',
460        required = True,
461        )
462
463    def addMessage(message):
464        """Add a message.
465        """
466
467class IWAeUPWorkflowInfo(IWorkflowInfo):
468    """A :class:`hurry.workflow.workflow.WorkflowInfo` with additional
469       methods for convenience.
470    """
471    def getManualTransitions():
472        """Get allowed manual transitions.
473
474        Get a sorted list of tuples containing the `transition_id` and
475        `title` of each allowed transition.
476        """
477
478class ISiteLoggers(Interface):
479
480    loggers = Attribute("A list or generator of registered WAeUPLoggers")
481
482    def register(name, filename=None, site=None, **options):
483        """Register a logger `name` which logs to `filename`.
484
485        If `filename` is not given, logfile will be `name` with
486        ``.log`` as filename extension.
487        """
488
489    def unregister(name):
490        """Unregister a once registered logger.
491        """
492
493class ILogger(Interface):
494    """A logger cares for setup, update and restarting of a Python logger.
495    """
496
497    logger = Attribute("""A :class:`logging.Logger` instance""")
498
499
500    def __init__(name, filename=None, site=None, **options):
501        """Create a WAeUP logger instance.
502        """
503
504    def setup():
505        """Create a Python :class:`logging.Logger` instance.
506
507        The created logger is based on the params given by constructor.
508        """
509
510    def update(**options):
511        """Update the logger.
512
513        Updates the logger respecting modified `options` and changed
514        paths.
515        """
516
517class ILoggerCollector(Interface):
518
519    def getLoggers(site):
520        """Return all loggers registered for `site`.
521        """
522
523    def registerLogger(site, logging_component):
524        """Register a logging component residing in `site`.
525        """
526
527    def unregisterLogger(site, logging_component):
528        """Unregister a logger.
529        """
Note: See TracBrowser for help on using the repository browser.