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

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

Also show global roles on UserContainerPage?.

Change user field titles again.

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