def correct_ref(self, change=''): """ Correct empty ref number in dmsmail 0.1 """ if not check_zope_admin(): return "You must be a zope manager to run this script" pc = self.portal_catalog brains = pc(portal_type='dmsincomingmail', sort_on='created') prev_ref = '' out = [] for brain in brains: if brain.internal_reference_number is not None: prev_ref = brain.internal_reference_number else: obj = brain.getObject() # with default config value (begin, nb) = prev_ref.split('/') new_ref = '%s/%d' % (begin, int(nb) + 1) # for cpas mons # nb = prev_ref # new_ref = '%03d' % (int(nb) + 1) out.append("<a href='%s'>%s</a>, %s, %s" % (obj.absolute_url(), obj.Title(), prev_ref, new_ref)) prev_ref = new_ref if change == '1': obj.internal_reference_no = prev_ref obj.reindexObject() out[-1] += " => %s" % obj.Title() return '\n<br />'.join(out)
def import_organization(self, dochange=''): if not check_zope_admin(): return "You must be a zope manager to run this script" out = [] if not dochange: out.append("To really import, call the script with param:") out.append("-> dochange=1") out.append("by example ...?dochange=1\n") real = False if dochange not in ('', '0', 'False', 'false'): real = True portal = getToolByName(self, "portal_url").getPortalObject() if 'organization_list' not in portal.objectIds(): return "You must create a DTMLDocument containing the list of organizations to create" annuaire = portal.annuaire lines = portal.organization_list.raw.splitlines() for line in lines: line = line.strip(' \n') if not line: continue (orga, prov, pop) = line.split(';') for typ in (u'ac', u'cpas'): gen_id = generate_password(length=20, upper=0, special=0, readable=False) out.append("Will create orga: '%s %s' with id '%s'" % (typ, orga.decode('utf8'), gen_id)) if real: annuaire.invokeFactory('organization', id=gen_id, title=orga.decode('utf8'), province=prov.decode('utf8'), citizen=int(pop), organization_type=typ, use_parent_address=False) obj = annuaire[gen_id] obj.reindexObject() return '\n'.join(out)
def do_transition(self, typ='dmsincomingmail', transition='close_manager', criteria="{}", limit=10000, change=''): """ Apply a transition to many objects """ if not check_zope_admin(): return "You must be a zope manager to run this script" from Products.CMFCore.WorkflowCore import WorkflowException from DateTime import DateTime pc = self.portal_catalog pw = self.portal_workflow ret = [] ret.append('Parameters:') ret.append("typ= '%s'" % typ) ret.append("transition: '%s'" % transition) ret.append("criteria: '%s'" % criteria) ret.append("limit: '%s'" % limit) ret.append("change: '%s'\n" % change) try: crit_dic = eval(criteria) except Exception, msg: ret.append("Problem evaluating criteria: %s" % msg) return '\n'.join(ret)
def doSearch(self, searchString): # noqa results = super(BaseOverviewControlPanel, self).doSearch(searchString) if check_zope_admin(): return results adapted_results = [] for item in results: adapted_item = item.copy() for role in self.portal_roles: adapted_item['roles'][role]['canAssign'] = False adapted_item['can_delete'] = False adapted_results.append(adapted_item) return adapted_results
def add_md5(self, change=''): """ Add md5 value if none """ if not check_zope_admin(): return "You must be a zope manager to run this script" from plone import api from imio.dms.mail.setuphandlers import list_templates from Products.CMFPlone.utils import base_hasattr templates_list = [(tup[1], tup[2]) for tup in list_templates()] portal = api.portal.getSite() ret = [] for (ppath, ospath) in templates_list: ppath = ppath.strip('/ ') obj = portal.unrestrictedTraverse(ppath, default=None) if not base_hasattr(obj, 'style_modification_md5'): continue if obj.style_modification_md5 is None: ret.append('%s with empty md5' % ppath) if change == '1': obj.style_modification_md5 = obj.current_md5 if not ret: return 'Nothing changed' return '\n'.join(ret)
def import_person(self, dochange=''): if not check_zope_admin(): return "You must be a zope manager to run this script" out = [] if not dochange: out.append("To really import, call the script with param:") out.append("-> dochange=1") out.append("by example ...?dochange=1\n") real = False if dochange not in ('', '0', 'False', 'false'): real = True subs = {} portal = getToolByName(self, "portal_url").getPortalObject() if 'person_list' not in portal.objectIds(): return "You must create a DTMLDocument containing the list of persons to create" pc = portal.portal_catalog slug = Slugify(to_lower=True, safe_chars="()-'", separator=' ') lines = portal.person_list.raw.splitlines() for line in lines: line = line.strip(' \n') if not line: continue (userid, email, nom, prenom, typ, orga, groupe) = line.split(';') sortable_title = slug('%s %s' % (typ, orga)) brains = pc(portal_type='organization', sortable_title=sortable_title) if not brains: out.append("Cannot find organization '%s %s' with '%s'" % (typ, orga, sortable_title)) continue elif len(brains) > 1: out.append("Find multiple organization '%s'" % ', '.join([brain.Title for brain in brains])) continue orga = brains[0].getObject() gen_id = slugify('%s %s' % (nom, prenom), to_lower=True).encode('utf8') gen_id = generate_password(length=10, upper=0, special=0, readable=False) out.append("Will create person: '%s %s' with id '%s'" % (nom, prenom, gen_id)) if real: orga.invokeFactory('person', id=gen_id, firstname=prenom.decode('utf8'), lastname=nom.decode('utf8'), email=email, userid=userid, invalidmail=False) obj = orga[gen_id] obj.reindexObject() if orga.id not in subs: subs[orga.id] = {} groups = eval(groupe) if 'cotisants2012-2013' in groups: subs[orga.id][2012] = True if 'cotisants2013-2014' in groups: subs[orga.id][2013] = True if 'cotisants2014-2015' in groups: subs[orga.id][2014] = True tots = {2012: 0, 2013: 0, 2014: 0} for gen_id in subs: brains = pc(portal_type='organization', id=gen_id) if len(brains) != 1: out.append('Cannot find organization with id %s' % gen_id.encode('utf8')) continue brain = brains[0] res = [] for year in sorted(subs[gen_id].keys()): res.append({'payment': True, 'year': year}) tots[year] += 1 if not res: continue out.append("For orga %s, subscriptions=%s" % (brain.Title.encode('utf8'), res)) if real: brain.getObject().subscriptions = res out.append('') for year in sorted(tots.keys()): out.append("Year %d: %d subscriptions" % (year, tots[year])) return '\n'.join(out)
def clean_examples(self): """ Clean created examples """ if not check_zope_admin(): return "You must be a zope manager to run this script" out = [] portal = api.portal.getSite() portal.portal_properties.site_properties.enable_link_integrity_checks = False # Delete os brains = api.content.find(portal_type='strategicobjective', path='/'.join(portal.pst.getPhysicalPath())) for brain in brains: log_list(out, "Deleting os '%s'" % brain.getPath()) api.content.delete(obj=brain.getObject(), check_linkintegrity=False) portal.pst.last_reference_number = 0 # Deactivate own organizations ownorg = portal['contacts']['plonegroup-organization'] brains = api.content.find(context=ownorg, portal_type='organization', id=['plonegroup-organization', 'echevins', '1er-echevin', 'services', 'accueil']) kept_orgs = [brain.UID for brain in brains] log_list(out, "Activating only 'accueil'") api.portal.set_registry_record(name=ORGANIZATIONS_REGISTRY, value=[ownorg['services']['accueil'].UID()]) # Delete organization brains = api.content.find(context=ownorg, portal_type='organization', sort_on='path', sort_order='descending') for brain in brains: uid = brain.UID if uid in kept_orgs: continue log_list(out, "Deleting organization '%s'" % brain.getPath()) api.content.delete(obj=brain.getObject(), check_linkintegrity=False) # Delete users for userid in ['psteditor', 'pstreader', 'chef', 'agent']: user = api.user.get(userid=userid) if user: for brain in api.content.find(Creator=userid, sort_on='path', sort_order='descending'): log_list(out, "Deleting object '%s' created by '%s'" % (brain.getPath(), userid)) api.content.delete(obj=brain.getObject(), check_linkintegrity=False) for group in api.group.get_groups(user=user): if group.id == 'AuthenticatedUsers': continue log_list(out, "Removing user '%s' from group '%s'" % (userid, group.getProperty('title'))) api.group.remove_user(group=group, user=user) log_list(out, "Deleting user '%s'" % userid) api.user.delete(user=user) # Delete groups functions = [dic['fct_id'] for dic in api.portal.get_registry_record(FUNCTIONS_REGISTRY)] groups = api.group.get_groups() for group in groups: if '_' not in group.id or group.id in ['pst_editors', 'pst_readers']: continue parts = group.id.split('_') if len(parts) == 1: continue org_uid = parts[0] function = '_'.join(parts[1:]) if org_uid in kept_orgs or function not in functions: continue log_list(out, "Deleting group '%s'" % group.getProperty('title')) api.group.delete(group=group) portal.portal_properties.site_properties.enable_link_integrity_checks = True return '\n'.join(out)
def import_principals(self, add_user='', create_file='', ungroup='', dochange=''): """ Import principals from the file 'Extensions/principals.csv' containing OrgId;OrgTitle;Userid;Fullname;email;Éditeur;Lecteur;Créateur CS;N+;Tel;Label;ImHandle Variable N+ columns following configuration ! """ if not check_zope_admin(): return "You must be a zope manager to run this script" exm = self.REQUEST['PUBLISHED'] path = os.path.dirname(exm.filepath()) # path = '%s/../../Extensions' % os.environ.get('INSTANCE_HOME') portal = api.portal.get() out = [] lf = '\n' out.append("Import principals from principals.csv. Possible parameters:") out.append("-> add_user=1 : add missing users. Default 0") out.append( "-> create_file=1 : create principals_gen.csv and exit. Default 0") out.append( "-> ungroup=1 : remove from group if role column is empty. Default 0") out.append("-> dochange=1 : apply changes. Default 0") out.append("") cf = False if create_file == '1': cf = True doit = False if dochange == '1': doit = True users = get_user_from_criteria(portal, email='@') userids = {} emails = {} # {'description': u'Scanner', 'title': u'Scanner', 'principal_type': 'user', 'userid': 'scanner', # 'email': '*****@*****.**', 'pluginid': 'mutable_properties', 'login': '******', 'id': 'scanner'} for dic in users: userids[dic['userid']] = dic['email'] uids = emails.setdefault(dic['email'], []) uids.append(dic['userid']) for eml in emails: if len(emails[eml]) > 1: out.append("!! same email '{}' for multiples users: {}".format( eml, ', '.join(emails[eml]))) orgas = get_organizations(self, obj=True) # [(uid, title)] val_levels = [('n_plus_{}'.format(dic['parameters']['validation_level']), dic['parameters']['function_title']) for dic in get_applied_adaptations() if dic['adaptation'] == u'imio.dms.mail.wfadaptations.IMServiceValidation'] fields = [ 'oi', 'ot', 'ui', 'fn', 'eml', 'ed', 'le', 'cs', 'ph', 'lb', 'im' ] fieldnames = [ 'OrgId', 'OrgTitle', 'Userid', 'Nom complet', 'Email', 'Éditeur', 'Lecteur', 'Créateur CS', 'Tél', 'Fonction', 'Autre' ] for fct, tit in reversed(val_levels): fields.insert(5, fct) fieldnames.insert(5, tit.encode('utf8')) if cf: lines = [";".join(fieldnames)] # TODO improve creation by using existing user group associations for uid, title in orgas: lines.append("{};{};{}".format(uid, title.encode('utf8'), ';' * (len(fields) - 3))) if doit: gen_file = os.path.join(path, 'principals_gen.csv') out.append("Creating file {}".format(gen_file)) fh = open(gen_file, 'w') for line in lines: fh.write("%s\n" % line) fh.close() out.extend(lines) return '\n'.join(out) filename = os.path.join(path, 'principals.csv') out.append("Reading file {}".format(filename)) msg, rows = system.read_dictcsv(filename, fieldnames=fields, strip_chars=' ', skip_empty=True, skip_lines=1, **{'delimiter': ';'}) if msg: # stop if csv error return msg regtool = self.portal_registration cu = False if add_user == '1': cu = True for dic in rows: ln = dic.pop('_ln') try: validate_email_address(dic['eml']) except Exception: out.append("Line %d: incorrect email value '%s'" % (ln, dic['eml'])) continue if dic['ph']: dic['ph'] = filter(type(dic['ph']).isdigit, dic['ph']) try: validate_phone(dic['ph']) except Exception: out.append("Line %d: incorrect phone value '%s'" % (ln, dic['ph'])) continue # check userid if not dic['ui']: out.append("Line %d: userid empty. Skipping line" % ln) continue if not re.match(r'[a-zA-Z1-9\-]+$', dic['ui']): out.append("Line %d: userid '%s' is not well formed" % (ln, dic['ui'])) continue # check user if dic['ui'] not in userids: emlfound = dic['eml'] in emails if not cu: out.append("Line %d: userid '%s' not found" % (ln, dic['ui'])) if emlfound: out.append("Line %d: but email '%s' found on users '%s'" % (ln, dic['eml'], ', '.join(emails[dic['eml']]))) continue else: try: out.append("=> Create user '%s': '%s', '%s'" % (dic['ui'], dic['fn'], dic['eml'])) if emlfound: out.append( "Line %d: but email '%s' found on users '%s'" % (ln, dic['eml'], ', '.join(emails[dic['eml']]))) userids[dic['ui']] = dic['eml'] uids = emails.setdefault(dic['eml'], []) uids.append(dic['ui']) if doit: user = api.user.create( username=dic['ui'], email=dic['eml'], password=regtool.generatePassword(), properties={'fullname': dic['fn']}) except Exception, ex: out.append("Line %d, cannot create user: %s" % (ln, safe_encode(ex.message))) continue user = api.user.get(userid=dic['ui']) # groups if user is not None: try: groups = [ g.id for g in api.group.get_groups(username=dic['ui']) ] except Exception, ex: out.append("Line %d, cannot get groups of userid '%s': %s" % (ln, dic['ui'], safe_encode(ex.message))) groups = []