# -*- coding: UTF-8 -*- """ PcfAnnuaire Class """ import os import time import calendar import ldap import urllib from interfaces import IPcfAnnuaire from zope.interface import implements from Products.Archetypes.public import * from Products.CMFCore.utils import getToolByName from plone.memoize.volatile import cache, DontCache from Acquisition import aq_base schema = BaseSchema def get_sort_key(x): return (getattr(x, 'sn') + getattr(x, 'givenName')).lower() class PcfAnnuaireEntry: def __init__(self, directory, ldap_dn, ldap_entry): def get_attr(x): try: return ldap_entry.get(x)[0].strip() except (IndexError, TypeError): return None self.directory = directory self._debug_entry = ldap_entry self.debug_entry = ldap_entry self.ldap_entry = ldap_entry self.dn = ldap_dn self.cn = get_attr('cn') self.sn = get_attr('sn') self.telephoneNumbers = ldap_entry.get('telephoneNumber') if self.telephoneNumbers: self.shortTelephoneNumber = self.telephoneNumbers[0][-3:] else: self.shortTelephoneNumber = None self.givenName = get_attr('givenName') self.displayName = get_attr('displayName') self.mobile = get_attr('mobile') self.service = get_attr('department') self.building = get_attr('destinationIndicator') self.floor = get_attr('extensionAttribute1') self.plan_filename = 'unknown.jpg' if self.building and self.floor: if self.building == 'Hôtel de Ligne': bld = 'hdl' elif self.building == 'Hôtel du Greffe': bld = 'hdg' else: bld = 'unknown' self.plan_filename = '%s%s.jpg' % (bld, self.floor) self.office = get_attr('physicalDeliveryOfficeName') self.fax = get_attr('facsimileTelephoneNumber') self.email = get_attr('mail') self.division = get_attr('division') self.title = get_attr('title') self.company = get_attr('company') self.samaccountname = get_attr('sAMAccountName') self.manager = get_attr('manager') self.manager_name = None if self.manager: self.manager_url = urllib.quote(self.manager) self.manager_name = self.manager.split('=')[1].split(',')[0] def all_managers(self): service_managers = [] if self.manager: manager = self.directory.getPerson(self.manager) service_managers = self.directory.getServiceManager(self.service) if self.manager in [x.dn for x in service_managers]: return [manager] + [x for x in service_managers if x.dn != self.manager] else: return [manager] def all_manager_couples(self): return [(urllib.quote(x.dn), x.cn) for x in self.all_managers()] def __str__(self): return urllib.quote(self.dn) def has_a_chief(self): if not self.manager: return False if self.service in ('Service du Greffier', 'Secrétariat général'): return True sec_gen = self.directory.getSecretaireGeneral() if self.manager == sec_gen.dn: return False return True has_a_chief = property(has_a_chief) class PcfAnnuaireService: pass def cache_key(method, self): # append time, so old entries do not get returned forever; (they will still # get removed as stale entries are automatically removed after 3 days) # (cf plone/memoize/volatile.py) return '%s_%s' % (hash(self), (int(time.time()) / 300)) class PcfAnnuaire(BaseContent): implements(IPcfAnnuaire) schema = schema _at_rename_after_creation = True def get_ldap_conn(self): portal = getToolByName(self, 'portal_url').getPortalObject() ldapdir = aq_base(portal.acl_users.ldap) luf = ldapdir._getLDAPUserFolder() server = luf._delegate.getServers()[0] ldap_conn = ldap.initialize('%(protocol)s://%(host)s:%(port)s' % server) ldap_conn.simple_bind_s(luf._binduid, luf._bindpwd) return ldap_conn def get_users_base(self): portal = getToolByName(self, 'portal_url').getPortalObject() ldapdir = aq_base(portal.acl_users.ldap) luf = ldapdir._getLDAPUserFolder() users_base = 'OU=ouPCF,' + luf.users_base return users_base def getObjectEntries(self): ldap_conn = self.get_ldap_conn() result = ldap_conn.search_s(self.get_users_base(), ldap.SCOPE_SUBTREE, 'objectClass=person') return [PcfAnnuaireEntry(self, *x) for x in result] @cache(cache_key) def getEntries(self): t = [x for x in self.getObjectEntries() if \ x.givenName and x.company == 'Parlement de la Communauté française de Belgique'] t.sort(key=get_sort_key) return t def getServices(self): entries = self.getObjectEntries() services = {} for entry in entries: if not entry.division: continue if not entry.division in services: service = Service() service.name = entry.division service.agents = [] services[division] = service service = services.get(entry.division) service.agents.append(entry) def get_name(x): return getattr(x, 'name') services = sorted([x for x in services.values()], key=get_name) for service in services: services.agents.sort(key=get_sort_key) return services def getEntriesWithPhone(self): return sorted([x for x in self.getEntries() if x.telephoneNumbers], key=get_sort_key) def getSecretaireGeneral(self): try: return [x for x in self.getEntries() if x.title == 'Secrétaire Général'][0] except IndexError: raise KeyError def getServices(self): services = {} for entry in self.getEntries(): services[entry.service] = True services = sorted(services.keys()) return services def getServiceManager(self, service): sec_gen = self.getSecretaireGeneral() if service in ('Service du Greffier', 'Secrétariat général'): return [sec_gen] try: return [x for x in self.getEntries() if x.service == service and x.manager == sec_gen.dn] except IndexError: return None def getServiceNonManagers(self, service): service_managers_dn = [x.dn for x in self.getServiceManager(service)] entries = [x for x in self.getEntries() if \ x.service == service and x.manager in service_managers_dn and x.division in (None, ' ')] return sorted(entries, key=get_sort_key) def getCellules(self, service): service_managers_dn = [x.dn for x in self.getServiceManager(service)] entries = [x for x in self.getEntries() if x.manager in service_managers_dn] cells = {} for entry in entries: if entry.division and entry.division != ' ': cells[entry.division] = True cells = sorted(cells.keys()) return cells def getCelluleManagers(self, service, cellule): if cellule == 'Secrétariat général': return [self.getSecretaireGeneral()] service_managers_dn = [x.dn for x in self.getServiceManager(service)] entries = [x for x in self.getEntries() if \ x.service == service and x.division == cellule and x.manager in service_managers_dn] return sorted(entries, key=get_sort_key) def getCellulePeople(self, service, cellule): cellule_managers = [x.dn for x in self.getCelluleManagers(service, cellule)] entries = [x for x in self.getEntries() if \ x.service == service and x.division == cellule and x.dn not in cellule_managers] return sorted(entries, key=get_sort_key) def getPerson(self, dn): person = [x for x in self.getEntries() if x.dn == dn][0] return person registerType(PcfAnnuaire)