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

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

Add SessionConfigurationManageFormPage? and SessionConfigurationBreadcrumb?.

  • Property svn:eol-style set to native
File size: 15.2 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
251    def getSessionString():
252        """Returns the session string from the vocabulary.
253        """
254
255
256class ISessionConfigurationAdd(ISessionConfiguration):
257    """A session configuration object in add mode.
258    """
259
260    academic_session = schema.Choice(
261        title = u'Academic Session',
262        source = academic_sessions_vocab,
263        default = None,
264        required = True,
265        readonly = False,
266        )
267
268ISessionConfigurationAdd['academic_session'].order =  ISessionConfiguration[
269    'academic_session'].order
270
271class IDataCenter(IWAeUPObject):
272    """A data center.
273
274    TODO : declare methods, at least those needed by pages.
275    """
276    pass
277
278class IDataCenterFile(Interface):
279    """A data center file.
280    """
281
282    name = schema.TextLine(
283        title = u'Filename')
284
285    size = schema.TextLine(
286        title = u'Human readable file size')
287
288    uploaddate = schema.TextLine(
289        title = u'Human readable upload datetime')
290
291    lines = schema.Int(
292        title = u'Number of lines in file')
293
294    def getDate():
295        """Get creation timestamp from file in human readable form.
296        """
297
298    def getSize():
299        """Get human readable size of file.
300        """
301
302    def getLinesNumber():
303        """Get number of lines of file.
304        """
305
306class IDataCenterStorageMovedEvent(IObjectEvent):
307    """Emitted, when the storage of a datacenter changes.
308    """
309
310class IObjectUpgradeEvent(IObjectEvent):
311    """Can be fired, when an object shall be upgraded.
312    """
313
314class ILocalRoleSetEvent(IObjectEvent):
315    """A local role was granted/revoked for a principal on an object.
316    """
317    role_id = Attribute(
318        "The role id that was set.")
319    principal_id = Attribute(
320        "The principal id for which the role was granted/revoked.")
321    granted = Attribute(
322        "Boolean. If false, then the role was revoked.")
323
324class IQueryResultItem(Interface):
325    """An item in a search result.
326    """
327    url = schema.TextLine(
328        title = u'URL that links to the found item')
329    title = schema.TextLine(
330        title = u'Title displayed in search results.')
331    description = schema.Text(
332        title = u'Longer description of the item found.')
333
334class IWAeUPSIRPPluggable(Interface):
335    """A component that might be plugged into a WAeUP SIRP app.
336
337    Components implementing this interface are referred to as
338    'plugins'. They are normally called when a new
339    :class:`waeup.sirp.app.University` instance is created.
340
341    Plugins can setup and update parts of the central site without the
342    site object (normally a :class:`waeup.sirp.app.University` object)
343    needing to know about that parts. The site simply collects all
344    available plugins, calls them and the plugins care for their
345    respective subarea like the applicants area or the datacenter
346    area.
347
348    Currently we have no mechanism to define an order of plugins. A
349    plugin should therefore make no assumptions about the state of the
350    site or other plugins being run before and instead do appropriate
351    checks if necessary.
352
353    Updates can be triggered for instance by the respective form in
354    the site configuration. You normally do updates when the
355    underlying software changed.
356    """
357    def setup(site, name, logger):
358        """Create an instance of the plugin.
359
360        The method is meant to be called by the central app (site)
361        when it is created.
362
363        `site`:
364           The site that requests a setup.
365
366        `name`:
367           The name under which the plugin was registered (utility name).
368
369        `logger`:
370           A standard Python logger for the plugins use.
371        """
372
373    def update(site, name, logger):
374        """Method to update an already existing plugin.
375
376        This might be called by a site when something serious
377        changes. It is a poor-man replacement for Zope generations
378        (but probably more comprehensive and better understandable).
379
380        `site`:
381           The site that requests an update.
382
383        `name`:
384           The name under which the plugin was registered (utility name).
385
386        `logger`:
387           A standard Python logger for the plugins use.
388        """
389
390class IAuthPluginUtility(Interface):
391    """A component that cares for authentication setup at site creation.
392
393    Utilities providing this interface are looked up when a Pluggable
394    Authentication Utility (PAU) for any
395    :class:`waeup.sirp.app.University` instance is created and put
396    into ZODB.
397
398    The setup-code then calls the `register` method of the utility and
399    expects a modified (or unmodified) version of the PAU back.
400
401    This allows to define any authentication setup modifications by
402    submodules or third-party modules/packages.
403    """
404
405    def register(pau):
406        """Register any plugins wanted to be in the PAU.
407        """
408
409    def unregister(pau):
410        """Unregister any plugins not wanted to be in the PAU.
411        """
412
413class IObjectConverter(Interface):
414    """Object converters are available as simple adapters, adapting
415       interfaces (not regular instances).
416
417    """
418
419    def fromStringDict(self, data_dict, context, form_fields=None):
420        """Convert values in `data_dict`.
421
422        Converts data in `data_dict` into real values based on
423        `context` and `form_fields`.
424
425        `data_dict` is a mapping (dict) from field names to values
426        represented as strings.
427
428        The fields (keys) to convert can be given in optional
429        `form_fields`. If given, form_fields should be an instance of
430        :class:`zope.formlib.form.Fields`. Suitable instances are for
431        example created by :class:`grok.AutoFields`.
432
433        If no `form_fields` are given, a default is computed from the
434        associated interface.
435
436        The `context` can be an existing object (implementing the
437        associated interface) or a factory name. If it is a string, we
438        try to create an object using
439        :func:`zope.component.createObject`.
440
441        Returns a tuple ``(<FIELD_ERRORS>, <INVARIANT_ERRORS>,
442        <DATA_DICT>)`` where
443
444        ``<FIELD_ERRORS>``
445           is a list of tuples ``(<FIELD_NAME>, <ERROR>)`` for each
446           error that happened when validating the input data in
447           `data_dict`
448
449        ``<INVARIANT_ERRORS>``
450           is a list of invariant errors concerning several fields
451
452        ``<DATA_DICT>``
453           is a dict with the values from input dict converted.
454
455        If errors happen, i.e. the error lists are not empty, always
456        an empty ``<DATA_DICT>`` is returned.
457
458        If ``<DATA_DICT>` is non-empty, there were no errors.
459        """
460
461class IObjectHistory(Interface):
462
463    messages = schema.List(
464        title = u'List of messages stored',
465        required = True,
466        )
467
468    def addMessage(message):
469        """Add a message.
470        """
471
472class IWAeUPWorkflowInfo(IWorkflowInfo):
473    """A :class:`hurry.workflow.workflow.WorkflowInfo` with additional
474       methods for convenience.
475    """
476    def getManualTransitions():
477        """Get allowed manual transitions.
478
479        Get a sorted list of tuples containing the `transition_id` and
480        `title` of each allowed transition.
481        """
482
483class ISiteLoggers(Interface):
484
485    loggers = Attribute("A list or generator of registered WAeUPLoggers")
486
487    def register(name, filename=None, site=None, **options):
488        """Register a logger `name` which logs to `filename`.
489
490        If `filename` is not given, logfile will be `name` with
491        ``.log`` as filename extension.
492        """
493
494    def unregister(name):
495        """Unregister a once registered logger.
496        """
497
498class ILogger(Interface):
499    """A logger cares for setup, update and restarting of a Python logger.
500    """
501
502    logger = Attribute("""A :class:`logging.Logger` instance""")
503
504
505    def __init__(name, filename=None, site=None, **options):
506        """Create a WAeUP logger instance.
507        """
508
509    def setup():
510        """Create a Python :class:`logging.Logger` instance.
511
512        The created logger is based on the params given by constructor.
513        """
514
515    def update(**options):
516        """Update the logger.
517
518        Updates the logger respecting modified `options` and changed
519        paths.
520        """
521
522class ILoggerCollector(Interface):
523
524    def getLoggers(site):
525        """Return all loggers registered for `site`.
526        """
527
528    def registerLogger(site, logging_component):
529        """Register a logging component residing in `site`.
530        """
531
532    def unregisterLogger(site, logging_component):
533        """Unregister a logger.
534        """
Note: See TracBrowser for help on using the repository browser.