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

Last change on this file since 6910 was 6907, checked in by Henrik Bettermann, 13 years ago

Implement a configuration container. Transfer attributes from University class to ConfigurationContainer? class.

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