source: main/waeup.sirp/trunk/src/waeup/sirp/applicants/root.py @ 6370

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

Make local_roles a simple static class attribute. It is not computed
dynamically.

File size: 5.5 KB
Line 
1##
2## root.py
3## Login : <uli@pu.smp.net>
4## Started on  Thu Jan 20 04:17:59 2011 Uli Fouquet
5## $Id$
6##
7## Copyright (C) 2011 Uli Fouquet
8## This program is free software; you can redistribute it and/or modify
9## it under the terms of the GNU General Public License as published by
10## the Free Software Foundation; either version 2 of the License, or
11## (at your option) any later version.
12##
13## This program is distributed in the hope that it will be useful,
14## but WITHOUT ANY WARRANTY; without even the implied warranty of
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16## GNU General Public License for more details.
17##
18## You should have received a copy of the GNU General Public License
19## along with this program; if not, write to the Free Software
20## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21##
22"""
23The root for applicants.
24"""
25import logging
26import grok
27import os
28from hurry.query import Eq
29from hurry.query.interfaces import IQuery
30from zope.component import getUtility
31from waeup.sirp.interfaces import IWAeUPSIRPPluggable
32from waeup.sirp.accesscodes import get_access_code
33from waeup.sirp.applicants.interfaces import IApplicantsRoot
34
35class ApplicantsRoot(grok.Container):
36    """The root of applicants-related components. It contains only
37    containers for applicants.
38    """
39    grok.implements(IApplicantsRoot)
40
41    local_roles = ['waeup.ApplicationsOfficer']
42
43    @property
44    def logger(self):
45        """Get a logger for applicants.
46        """
47        # We need a different logger for every site...
48        site = grok.getSite()
49        sitename = getattr(site, '__name__', 'app')
50        loggername = 'waeup.sirp.%s.applicants' % sitename
51        logger = logging.getLogger(loggername)
52        if not logger.handlers:
53            logger = self._setupLogger(logger)
54        return logger
55
56    def _setupLogger(self, logger):
57        """Setup applicants logger.
58        """
59        logdir = os.path.join(grok.getSite()['datacenter'].storage, 'logs')
60        if not os.path.exists(logdir):
61            os.mkdir(logdir)
62        filename = os.path.join(logdir, 'applicants.log')
63
64        # Create a rotating file handler logger for datacenter.
65        handler = logging.handlers.RotatingFileHandler(
66            filename, maxBytes=5*1024**1, backupCount=5)
67        formatter = logging.Formatter(
68            '%(asctime)s - %(levelname)s - %(message)s')
69        handler.setFormatter(formatter)
70
71        # Here we decide, whether our messages will _also_ go to
72        # application log.
73        logger.propagate = False
74        logger.setLevel(logging.DEBUG)
75        logger.addHandler(handler)
76        return logger
77
78
79class ApplicantsPlugin(grok.GlobalUtility):
80    """A WAeUPSIRPPlugin that creates an applicants root in portal.
81
82    This plugin should be called by a typical
83    `waeup.sirp.app.Universtiy` instance on creation time. The
84    :meth:`update` method normally can also be triggered manually over
85    the main site configuration.
86
87    Implements :class:`waeup.sirp.interfaces.IWAeUPSIRPPluggable`
88    """
89    grok.name('applicants')
90    grok.implements(IWAeUPSIRPPluggable)
91    log_prefix = 'ApplicantsPlugin'
92
93    def setup(self, site, name, logger):
94        """Create a new :class:`ApplicantsRoot` instance in `site`.
95        """
96        site['applicants'] = ApplicantsRoot()
97        logger.info(
98            '%s: Installed applicants root.' % (self.log_prefix,)
99            )
100        return
101
102    def update(self, site, name, logger):
103        """Update site wide ``applicants`` root.
104
105        If the site already contains a suitable ``applicants`` root,
106        leave it that way. If not create one and delete the old one if
107        appropriate.
108        """
109        app_folder = site.get('applicants', None)
110        site_name = getattr(site, '__name__', '<Unnamed Site>')
111        if IApplicantsRoot.providedBy(app_folder):
112            # Applicants up to date. Return.
113            logger.info(
114                '%s: Updating site at %s: Nothing to do.' % (
115                    self.log_prefix, site_name,)
116                )
117            return
118        elif app_folder is not None:
119            # Applicants need update. Remove old instance.
120            logger.warn(
121                '%s: Outdated applicants folder detected at site %s.'
122                'Removing it.' % (self.log_prefix, site_name)
123                    )
124            del site['applicants']
125        # Add new applicants.
126        logger.info(
127            '%s: Updating site at %s. Installing '
128            'applicants.' % (self.log_prefix, site_name,)
129            )
130        self.setup(site, name, logger)
131        return
132
133def get_applicant_data(identifier):
134    """Get applicant data associated with `identifier`.
135
136    Returns the applicant object if successful and ``None`` else.
137
138    As `identifier` we expect an access code in format
139    like ``PREFIX-XXX-YYYYYYYY`` where ``PREFIX`` is something like
140    ``APP`` or ``PUDE``, ``XXX`` the access code series and
141    ``YYYYYYYYYY`` the real accesscode number.
142
143    This function requires a fully blown setup as it does catalog
144    lookups for finding applicants.
145    """
146    query = getUtility(IQuery)
147    results = list(query.searchResults(
148            Eq(('applicants_catalog', 'access_code'), identifier)
149            ))
150    if len(results) == 0:
151        return None
152    return results[0]
153
154def application_exists(identifier):
155    """Check whether an application for the given identifier already
156       exists.
157
158       `identifier` will normally be an access code.
159    """
160    applicant = get_applicant_data(identifier)
161    if applicant is None:
162        return False
163    return True
Note: See TracBrowser for help on using the repository browser.