source: main/waeup.kofa/trunk/src/waeup/kofa/applicants/root.py @ 14346

Last change on this file since 14346 was 13234, checked in by Henrik Bettermann, 9 years ago

Log the numbers of removed applicant and student ids.

  • Property svn:keywords set to Id
File size: 7.4 KB
Line 
1## $Id: root.py 13234 2015-08-27 08:50:56Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18"""
19The root for applicants.
20"""
21import grok
22from hurry.query import Eq
23from hurry.query.interfaces import IQuery
24from zope.securitypolicy.interfaces import IPrincipalRoleManager
25from zope.component import getUtility
26from zope.component.interfaces import ComponentLookupError
27from zope.catalog.interfaces import ICatalog
28from zope.catalog.field import FieldIndex
29from zope.schema import getFields
30from waeup.kofa.interfaces import IKofaPluggable
31from waeup.kofa.applicants.interfaces import IApplicantsRoot
32from waeup.kofa.utils.logger import Logger
33from waeup.kofa.utils.helpers import attrs_to_fields
34
35class ApplicantsRoot(grok.Container, Logger):
36    """The root of applicants-related components. It contains only
37    containers for applicants.
38    """
39    grok.implements(IApplicantsRoot)
40
41    local_roles = []
42    description_dict = {}
43    logger_name = 'waeup.kofa.${sitename}.applicants'
44    logger_filename = 'applicants.log'
45
46ApplicantsRoot = attrs_to_fields(ApplicantsRoot)
47
48class ApplicantsPlugin(grok.GlobalUtility):
49    """A KofaPlugin that creates an applicants root in portal.
50
51    This plugin could be called by a typical
52    `waeup.kofa.app.Universtiy` instance on creation time. The
53    :meth:`update` method normally can also be triggered manually over
54    the main site configuration.
55
56    Implements :class:`waeup.kofa.interfaces.IKofaPluggable`
57    """
58    grok.name('applicants')
59    grok.implements(IKofaPluggable)
60    log_prefix = 'ApplicantsPlugin'
61
62    def setup(self, site, name, logger):
63        """Create a new :class:`ApplicantsRoot` instance in `site`.
64        """
65        site['applicants'] = ApplicantsRoot()
66        logger.info(
67            '%s: Installed applicants root.' % (self.log_prefix,)
68            )
69        return
70
71    def update(self, site, name, logger):
72        """Update site wide ``applicants`` root.
73
74        If the site already contains a suitable ``applicants`` root,
75        leave it that way. If not create one and delete the old one if
76        appropriate.
77
78        Update applicants catalog.
79
80        Remove deprecated applicant ids from global role map.
81        """
82        app_folder = site.get('applicants', None)
83        site_name = getattr(site, '__name__', '<Unnamed Site>')
84        if IApplicantsRoot.providedBy(app_folder):
85            items = getFields(IApplicantsRoot).items()
86            nothing_to_do = True
87            #for i in items:
88            #    if not hasattr(app_folder,i[0]):
89            #        nothing_to_do = False
90            #        setattr(app_folder,i[0],i[1].missing_value)
91            #        logger.info(
92            #            '%s: %s added to root.' % (self.log_prefix,i[0]))
93            # can be removed after upgrading futminna
94            #if not hasattr(app_folder, 'description_dict'):
95            #    nothing_to_do = False
96            #    setattr(app_folder,'description_dict',{})
97            #    logger.info(
98            #        '%s: description_dict added to root.' % self.log_prefix)
99
100            # Add container_code index
101            try:
102                cat = getUtility(ICatalog, name='applicants_catalog')
103                if 'container_code' not in cat.keys():
104                    nothing_to_do = False
105                    cat[u'container_code'] = FieldIndex(field_name=u'container_code')
106                    cat.updateIndexes()
107                    logger.info(
108                        '%s: container_code index added to applicants_catalog.'
109                        % self.log_prefix)
110            except ComponentLookupError: # in unit tests
111                pass
112
113            # Remove old applicant ids from global role map.
114            try:
115                removed_applicant_ids = []
116                cat = getUtility(ICatalog, name='applicants_catalog')
117                role_manager = IPrincipalRoleManager(grok.getSite())
118                principals = role_manager.getPrincipalsForRole('waeup.Applicant')
119                for principal in principals:
120                    applicant_id = principal[0]
121                    results = cat.searchResults(applicant_id=(applicant_id, applicant_id))
122                    if len(results):
123                        continue
124                    # The applicant does no longer exist.
125                    nothing_to_do = False
126                    role_manager.unsetRoleForPrincipal(
127                        'waeup.Applicant', applicant_id)
128                    removed_applicant_ids.append(applicant_id)
129                if len(removed_applicant_ids):
130                    logger.info(
131                        '%s: %s applicant ids removed from global role map: %s'
132                        % (self.log_prefix, len(removed_applicant_ids),
133                           removed_applicant_ids))
134            except ComponentLookupError: # in unit tests
135                pass
136
137            # Remove old student ids from global role map.
138            try:
139                removed_student_ids = []
140                cat = getUtility(ICatalog, name='students_catalog')
141                role_manager = IPrincipalRoleManager(grok.getSite())
142                principals = role_manager.getPrincipalsForRole('waeup.Student')
143                for principal in principals:
144                    student_id = principal[0]
145                    results = cat.searchResults(student_id=(student_id, student_id))
146                    if len(results):
147                        continue
148                    # The student does no longer exist.
149                    nothing_to_do = False
150                    role_manager.unsetRoleForPrincipal(
151                        'waeup.Student', student_id)
152                    removed_student_ids.append(student_id)
153                if len(removed_applicant_ids):
154                    logger.info(
155                        '%s: %s student ids removed from global role map: %s'
156                        % (self.log_prefix, len(removed_student_ids),
157                           removed_student_ids))
158            except ComponentLookupError: # in unit tests
159                pass
160
161            if nothing_to_do:
162                logger.info(
163                    '%s: Updating site at %s: Nothing to do.' % (
164                        self.log_prefix, site_name,)
165                    )
166            return
167        elif app_folder is not None:
168            # Applicants need update. Remove old instance.
169            logger.warn(
170                '%s: Outdated applicants folder detected at site %s.'
171                'Removing it.' % (self.log_prefix, site_name)
172                    )
173            del site['applicants']
174        # Add new applicants.
175        logger.info(
176            '%s: Updating site at %s. Installing '
177            'applicants.' % (self.log_prefix, site_name,)
178            )
179        self.setup(site, name, logger)
180        return
Note: See TracBrowser for help on using the repository browser.