# -*- coding: utf-8 -*- import datetime import re import time from DateTime.DateTime import DateTime from zope.i18n.locales import locales from Products.CMFCore.WorkflowCore import WorkflowException from Products.Five.browser import BrowserView from z3c.sqlalchemy import getSAWrapper, createSAWrapper from Products.CMFCore.utils import getToolByName from zope.event import notify from zope.lifecycleevent import ObjectAddedEvent, ObjectModifiedEvent from zope import component from zope.app.intid.interfaces import IIntIds from z3c.relationfield import RelationValue from zope.i18n.locales import locales from plone.app.textfield.value import RichTextValue import transaction from plone.registry.interfaces import IRegistry from tabellio.config.interfaces import ITabellioSettings class SyncFromPcfDbView(BrowserView): def setup(self): self.settings = component.getUtility(IRegistry).forInterface(ITabellioSettings, False) self.portal = getToolByName(self.context, 'portal_url').getPortalObject() self.plone_utils = getToolByName(self.context, 'plone_utils') self.intids = component.getUtility(IIntIds) self.portal_workflow = getToolByName(self.context, 'portal_workflow') self.portal_types = getToolByName(self.context, 'portal_types') def db_connection(self): return self.portal.db._wrapper.connection db_connection = property(db_connection) def get_folder_at_path(self, path): current = self.portal for part in path.split('/'): if not part: continue current = getattr(current, part) return current _deputies_folder = None def deputies_folder(self): if self._deputies_folder: return self._deputies_folder path = self.settings.deputiesPath self._deputies_folder = self.get_folder_at_path(path) return self._deputies_folder deputies_folder = property(deputies_folder) _ministries_folder = None def ministries_folder(self): if self._ministries_folder: return self._ministries_folder path = self.settings.ministriesPath self._ministries_folder = self.get_folder_at_path(path) return self._ministries_folder ministries_folder = property(ministries_folder) _persons_folder = None def persons_folder(self): if self._persons_folder: return self._persons_folder path = self.settings.personsPath self._persons_folder = self.get_folder_at_path(path) return self._persons_folder persons_folder = property(persons_folder) _polgroups_folder = None def polgroups_folder(self): if self._polgroups_folder: return self._polgroups_folder path = self.settings.polgroupsPath self._polgroups_folder = self.get_folder_at_path(path) return self._polgroups_folder polgroups_folder = property(polgroups_folder) _parlevents_folder = None def parlevents_folder(self): if self._parlevents_folder: return self._parlevents_folder path = self.settings.parleventsPath self._parlevents_folder = self.get_folder_at_path(path) return self._parlevents_folder parlevents_folder = property(parlevents_folder) _polgroups_intids = None def get_polgroup_intid(self, title): if not self._polgroups_intids: self._polgroups_intids = {} if title in self._polgroups_intids: return self._polgroups_intids.get(title) polgroup_id = self.plone_utils.normalizeString(title) if not hasattr(self.polgroups_folder, polgroup_id): self.polgroups_folder.invokeFactory('themis.datatypes.polgroup', polgroup_id, title=title) try: self.portal_workflow.doActionFor(getattr(self.polgroups_folder, polgroup_id), 'publish') except WorkflowException: pass polgroup_intid = self.intids.getId(getattr(self.polgroups_folder, polgroup_id)) self._polgroups_intids[title] = polgroup_intid return polgroup_intid _documents_folder = None def documents_folder(self): if self._documents_folder: return self._documents_folder path = self.settings.documentsPath self._documents_folder = self.get_folder_at_path(path) return self._documents_folder documents_folder = property(documents_folder) _dossiers_folder = None def dossiers_folder(self): if self._dossiers_folder: return self._dossiers_folder path = self.settings.dossiersPath self._dossiers_folder = self.get_folder_at_path(path) return self._dossiers_folder dossiers_folder = property(dossiers_folder) _commissions_folder = None def commissions_folder(self): if self._commissions_folder: return self._commissions_folder path = self.settings.commissionsPath self._commissions_folder = self.get_folder_at_path(path) return self._commissions_folder commissions_folder = property(commissions_folder) _questions_folder = None def questions_folder(self): if self._questions_folder: return self._questions_folder path = self.settings.questionsPath self._questions_folder = self.get_folder_at_path(path) return self._questions_folder questions_folder = property(questions_folder) _author_intids = None def get_author_intid(self, author_id): if not self._author_intids: self._author_intids = {} if author_id in self._author_intids: return self._author_intids.get(author_id) cursor = self.db_connection.cursor() cursor.execute('''SELECT nom, prenom, st FROM t_pers WHERE t_pers.id = %(id)s''', {'id': author_id}) row = cursor.fetchone() cursor.close() lastname, firstname, st = row if lastname and firstname: fullname = '%s %s' % (firstname, lastname) else: fullname = lastname new_id = self.plone_utils.normalizeString(fullname) if hasattr(self.deputies_folder, new_id): obj = getattr(self.deputies_folder, new_id) else: try: if st == 'S_PARL': obj = getattr(self.deputies_folder, new_id) elif st == 'S_MINISTRE': obj = getattr(self.ministries_folder, new_id) elif st in ('S_CREATED', 'S_DEAD'): obj = getattr(self.persons_folder, new_id) else: print 'unhandled type', st, author_id, new_id self._author_intids[author_id] = None return None except AttributeError: print 'missing author:', fullname self._author_intids[author_id] = None return None author_intid = self.intids.getId(obj) self._author_intids[author_id] = author_intid return author_intid def get_author_intid_from_name(self, firstname, lastname, st='S_PARL'): if lastname and firstname: fullname = '%s %s' % (firstname, lastname) else: fullname = lastname new_id = self.plone_utils.normalizeString(fullname) if st == 'S_PARL': obj = getattr(self.deputies_folder, new_id) elif st == 'S_MINISTRE': obj = getattr(self.ministries_folder, new_id) author_intid = self.intids.getId(obj) return author_intid def get_document_and_intid(self, doc_id): folder = self.documents_folder try: obj = getattr(folder, doc_id) except AttributeError: print 'missing doc', doc_id return None, None try: return obj, self.intids.getId(obj) except KeyError: self.intids.register(obj) return obj, self.intids.getId(obj) _commissions = None def get_commission(self, com_id): if not self._commissions: self._commissions = {} if com_id in self._commissions: return self._commissions.get(com_id) cursor = self.db_connection.cursor() cursor.execute('''SELECT t_comcat.nom, code FROM t_com JOIN t_comcat ON (t_com.comcat = t_comcat.id) WHERE t_com.id = %(id)s''', {'id': com_id}) row = cursor.fetchone() if row is None: return None category, code = row cat_id = self.plone_utils.normalizeString(category) folder = getattr(self.commissions_folder, cat_id) code_id = self.plone_utils.normalizeString(code) obj = getattr(folder, code_id) self._commissions[com_id] = obj return obj _commission_intids = None def get_commission_intid(self, com_id): if not self._commission_intids: self._commission_intids = {} if com_id in self._commission_intids: return self._commission_intids.get(com_id) obj = self.get_commission(com_id) try: intid = self.intids.getId(obj) except KeyError: self.intids.register(obj) intid = self.intids.getId(obj) self._commission_intids[com_id] = intid return intid _commission_titles = None def get_commission_title(self, com_id): # this function should only be used in case we do not mind getting a # title without a corresponding object. if not self._commission_titles: self._commission_titles = {} if com_id in self._commission_titles: return self._commission_titles.get(com_id) cursor = self.db_connection.cursor() cursor.execute('''SELECT id, nom FROM t_com WHERE t_com.id = %(id)s''', {'id': com_id}) row = cursor.fetchone() if row is None: return None id, title = row self._commission_titles[com_id] = title return title def publish(self, object): current_state = self.portal_workflow.getStatusOf( self.portal_workflow.getChainFor(object)[0], object).get('review_state') if current_state != 'published': try: self.portal_workflow.doActionFor(object, 'publish') except WorkflowException: pass try: self.intids.getId(object) except KeyError: self.intids.register(object) def unpublish(self, object): current_state = self.portal_workflow.getStatusOf( self.portal_workflow.getChainFor(object)[0], object).get('review_state') if current_state == 'published': try: self.portal_workflow.doActionFor(object, 'retract') except WorkflowException: pass def get_polgroups_id_to_title(self, cursor): polgroups_id_to_title = {} cursor.execute('''SELECT id, abbr FROM t_comppol''') while True: row = cursor.fetchone() if row is None: break polgroups_id_to_title[row[0]] = row[1] return polgroups_id_to_title def __call__(self): self.setup() def format_duration(v): r = '' if v > 3600: r = r + '%dh' % int(v/3600) v = v % 3600 if v > 60 or r: r = r + '%02dm' % int(v/60) v = v % 60 r = r + '%02ds' % int(v) return r timestamp = self.request.form.get('timestamp') objects = self.request.form.get('objects', '').split(',') report = [] for object in ('polgroups', 'sessions', 'deputies', 'ministries', 'persons', 'commissions', 'documents', 'dossiers', 'questions', 'reunions', 'deptables', 'thesaurus'): if not 'all' in objects: if not object in objects: continue t0 = time.time() result = getattr(self, 'sync_'+object)(timestamp) duration = time.time() - t0 report.append('%-14s: %6s [%s]' % (object, result, format_duration(duration))) transaction.commit() print '\n'.join(report) return '\n'.join(report) + '\n' def get_address(self, address_id): if not address_id: return None cursor = self.db_connection.cursor() cursor.execute('''SELECT titre, batbur, rueno, zip, localite, tel1, tel2, fax, email FROM t_adresse WHERE t_adresse.id = %(id)s''', {'id': address_id}) row = cursor.fetchone() if not row: return None (titre, batbur, street, zipcode, city, phone1, phone2, fax, email) = row from themis.datatypes.address import Address addr = Address() addr.title = titre or batbur addr.street = street addr.zipcode = zipcode addr.city = city addr.phone1 = phone1 addr.phone2 = phone2 addr.fax = fax addr.email = email cursor.close() return addr def sync_sessions(self, timestamp=None): cursor = self.db_connection.cursor() cursor.execute('''SELECT t_legisl.nom, t_sess.id FROM t_sess JOIN t_legisl ON (t_sess.legislid = t_legisl.id) ORDER BY t_sess.datedeb DESC''') sessions = [] while True: row = cursor.fetchone() if row is None: break sessions.append('%s:%s' % row) cursor.close() self.settings.sessions = '\n'.join(sessions) return 'OK' def sync_thesaurus(self, timestamp=None): cursor = self.db_connection.cursor() cursor.execute('''SELECT t_thesaurus_term.id, t_thesaurus_term.term FROM t_thesaurus_term WHERE EXISTS ( SELECT * FROM t_thesaurus_rel WHERE sectermid = t_thesaurus_term.id AND rel not in ('HN', 'SN'))''') terms = [] while True: row = cursor.fetchone() if row is None: break terms.append('%s|%s' % row) cursor.close() self.settings.topics = '\n'.join(terms) return 'OK' def sync_polgroups(self, timestamp=None): cursor = self.db_connection.cursor() cursor.execute('''SELECT st, abbr FROM t_comppol''') while True: row = cursor.fetchone() if row is None: break st, title = row polgroup_id = self.plone_utils.normalizeString(title) if not hasattr(self.polgroups_folder, polgroup_id): self.polgroups_folder.invokeFactory('themis.datatypes.polgroup', polgroup_id, title=title) object = getattr(self.polgroups_folder, polgroup_id) object.active = (st == 'S_ACTIVE') notify(ObjectModifiedEvent(object)) self.publish(object) cursor.close() return 'OK' def sync_deputies(self, timestamp=None): cursor = self.db_connection.cursor() where_ts = '' if timestamp: where_ts = cursor.mogrify('AND t_pers.ts > %s', (timestamp,)) # previous deputies cursor.execute('''SELECT t_pers.id, t_pers.nom, prenom, sexe, datenaiss, t_comppol.abbr FROM t_pers, t_pershistoline, t_comppol WHERE (t_pers.st = 'S_CREATED' or t_pers.st = 'S_DEAD' or t_pers.st = 'S_MINISTRE') and t_pers.prenom is not NULL and t_pers.id = t_pershistoline.pers and t_pershistoline.description = t_comppol.id and t_pershistoline.type = 'P_CMPL' and t_pershistoline.fin IS NOT NULL %s ORDER BY t_pershistoline.fin DESC''' % where_ts) polgroup_ids = {} count = 0 while True: row = cursor.fetchone() if row is None: break count += 1 (pers_id, lastname, firstname, sex, birthdate, polgroup) = row fullname = '%s %s' % (firstname, lastname) new_id = self.plone_utils.normalizeString(fullname) if not hasattr(self.deputies_folder, new_id): self.deputies_folder.invokeFactory('themis.datatypes.deputy', new_id, firstname=firstname, lastname=lastname) object = getattr(self.deputies_folder, new_id) object.firstname = firstname object.lastname = lastname object.sex = sex object.birthdate = birthdate object.polgroup = RelationValue(self.get_polgroup_intid(polgroup)) object.active = False notify(ObjectModifiedEvent(object)) self.publish(object) # currently active deputies cursor.execute('''SELECT t_pers.id, t_pers.nom, prenom, sexe, datenaiss, t_pers.addrpriv, t_pers.addrprof1, t_pers.addrprof2, t_comppol.abbr, t_arrond.nom FROM t_pers, t_pershistoline, t_comppol, t_parl, t_arrond WHERE t_pers.st = 'S_PARL' and t_pers.prenom is not NULL and t_pers.id = t_pershistoline.pers and t_pershistoline.description = t_comppol.id and t_pershistoline.type = 'P_CMPL' and t_pershistoline.fin IS NULL and t_pers.id = t_parl.id and t_parl.arrond = t_arrond.id %s''' % where_ts) polgroup_ids = {} while True: row = cursor.fetchone() if row is None: break count += 1 (pers_id, lastname, firstname, sex, birthdate, privaddr, workaddr1, workaddr2, polgroup, district) = row fullname = '%s %s' % (firstname, lastname) new_id = self.plone_utils.normalizeString(fullname) if not hasattr(self.deputies_folder, new_id): self.deputies_folder.invokeFactory('themis.datatypes.deputy', new_id, firstname=firstname, lastname=lastname) object = getattr(self.deputies_folder, new_id) object.firstname = firstname object.lastname = lastname object.sex = sex object.birthdate = birthdate object.district = district object.polgroup = RelationValue(self.get_polgroup_intid(polgroup)) object.private_address = self.get_address(privaddr) object.work_address = self.get_address(workaddr1) object.work_address_2 = self.get_address(workaddr2) object.active = True notify(ObjectModifiedEvent(object)) self.publish(object) cursor.close() return count def sync_ministries(self, timestamp=None): cursor = self.db_connection.cursor() where_ts = '' if timestamp: where_ts = cursor.mogrify('AND t_pers.ts > %s', (timestamp,)) cursor.execute('''SELECT t_pers.id, t_pers.nom, prenom, sexe, datenaiss FROM t_pers WHERE t_pers.st = 'S_MINISTRE' and t_pers.prenom is not NULL %s''' % where_ts) count = 0 while True: row = cursor.fetchone() if row is None: break count += 1 pers_id, lastname, firstname, sex, birthdate = row fullname = '%s %s' % (firstname, lastname) new_id = self.plone_utils.normalizeString(fullname) if not hasattr(self.ministries_folder, new_id): self.ministries_folder.invokeFactory('themis.datatypes.ministry', new_id, firstname=firstname, lastname=lastname) object = getattr(self.ministries_folder, new_id) object.firstname = firstname object.lastname = lastname object.sex = sex object.birthdate = birthdate notify(ObjectModifiedEvent(object)) self.publish(object) cursor.close() return count def sync_persons(self, timestamp=None): cursor = self.db_connection.cursor() where_ts = '' if timestamp: where_ts = cursor.mogrify('AND t_pers.ts > %s', (timestamp,)) cursor.execute('''SELECT t_pers.id, t_pers.nom, prenom, sexe, datenaiss FROM t_pers WHERE t_pers.st = 'S_CREATED' OR t_pers.st = 'S_DEAD' %s''' % where_ts) count = 0 while True: row = cursor.fetchone() if row is None: break pers_id, lastname, firstname, sex, birthdate = row if firstname and lastname: fullname = '%s %s' % (firstname, lastname) else: fullname = lastname new_id = self.plone_utils.normalizeString(fullname) if not hasattr(self.persons_folder, new_id): self.persons_folder.invokeFactory('themis.datatypes.contact', new_id, title=fullname) object = getattr(self.persons_folder, new_id) object.title = fullname notify(ObjectModifiedEvent(object)) self.publish(object) cursor.close() return count def sync_commissions(self, timestamp=None): cursor = self.db_connection.cursor() where_ts = '' if timestamp: where_ts = cursor.mogrify('AND t_com.ts > %s', (timestamp,)) cursor.execute('''SELECT t_com.id, t_com.st, t_com.nom, code, compets, t_comcat.nom FROM t_com JOIN t_comcat ON (t_com.comcat = t_comcat.id) WHERE t_com.st = 'S_ACTIVE' %s''' % where_ts) count = 0 while True: row = cursor.fetchone() if row is None: break count += 1 com_id, state, title, code, compets, category = row print 'processing com:', com_id, code cat_id = self.plone_utils.normalizeString(category) if not hasattr(self.commissions_folder, cat_id): self.commissions_folder.invokeFactory('Folder', cat_id, title=category) commission_folder = getattr(self.commissions_folder, cat_id) com_code = self.plone_utils.normalizeString(code) if title[0] == title[0].lower(): title = title[0].upper() + title[1:] if not hasattr(commission_folder, com_code): commission_folder.invokeFactory('themis.datatypes.commission', com_code, title=title) object = getattr(commission_folder, com_code) object.title = title object.active == (state == 'S_ACTIVE') object.code = code pers_cursor = self.db_connection.cursor() pers_cursor.execute('''SELECT t_pershistoline.type, nom, prenom FROM t_pers JOIN t_pershistoline ON t_pershistoline.pers = t_pers.id WHERE t_pershistoline.description = %(id)s AND t_pershistoline.fin IS NULL''', {'id': com_id}) object.president = None object.vicepresidents = [] object.members = [] object.substitutes = [] while True: row = pers_cursor.fetchone() if row is None: break type, lastname, firstname = row if not (lastname and firstname): # this is some placeholder for a future person, skip it continue if type == 'P_COMM_PR': object.president = RelationValue( self.get_author_intid_from_name(firstname, lastname)) elif type == 'P_COMM_VP': object.vicepresidents.append( RelationValue(self.get_author_intid_from_name(firstname, lastname))) elif type == 'P_COMM_TI': object.members.append( RelationValue(self.get_author_intid_from_name(firstname, lastname))) elif type == 'P_COMM_SU': object.substitutes.append( RelationValue(self.get_author_intid_from_name(firstname, lastname))) pers_cursor.close() # compets compet_cursor = self.db_connection.cursor() compet_cursor.execute('''SELECT t_compet.nom FROM t_com JOIN t_com_compets ON (t_com.id = t_com_compets.id) JOIN t_compet ON (t_com_compets.value = t_compet.id) WHERE t_compet.st = 'S_ACTIVE' AND t_com.id = %(id)s ORDER BY t_compet.nom''', {'id': com_id}) object.competences = [] while True: row = compet_cursor.fetchone() if row is None: break object.competences.append(row[0]) compet_cursor.close() # ministries minist_cursor = self.db_connection.cursor() minist_cursor.execute('''SELECT t_pers.prenom, t_pers.nom FROM t_com JOIN t_com_compets ON (t_com.id = t_com_compets.id) JOIN t_compet ON (t_com_compets.value = t_compet.id) JOIN t_pershistoline ON (t_compet.id = t_pershistoline.description) JOIN t_pers ON (t_pershistoline.pers = t_pers.id) WHERE t_compet.st = 'S_ACTIVE' AND t_pershistoline.fin IS NULL AND t_com.id = %(id)s GROUP BY t_pers.prenom, t_pers.nom''', {'id': com_id}) object.ministries = [] while True: row = minist_cursor.fetchone() if row is None: break firstname, lastname = row object.ministries.append(RelationValue( self.get_author_intid_from_name( firstname, lastname, 'S_MINISTRE'))) minist_cursor.close() secr_cursor = self.db_connection.cursor() secr_cursor.execute('''SELECT titre, sexe, nom, prenom, adjoint, email, attrib FROM t_comsecr WHERE comid = %(id)s ORDER BY adjoint, nom''', {'id': com_id}) s = ['
Président | %s |
%s | %s |
Secrétaires du Parlement |
|
Greffier (Secrétaire général) | %s %s %s Courriel : %s Téléphone : %s Fax : %s |
Noms | Appartenance politique |
---|---|
%s | %s |
%s | %s |
%s | %s |