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

Last change on this file since 6495 was 6481, checked in by uli, 13 years ago

Move logger interfaces to final destination.

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