# psu - paster shell utilities # use this from (e.g.): # # bin/paster shell deploy.ini # # then: # # from cco.common import psu # from custom.config import myproject as config # psu.setup(root, 'path/to/loopsRoot', config) # obj = psu.byuid('578457950') # import os from transaction import commit, abort from zope.app.authentication.principalfolder import Principal from zope.app.component.hooks import setSite from zope.app.container.contained import ObjectAddedEvent, ObjectRemovedEvent from zope.cachedescriptors.property import Lazy from zope.catalog.interfaces import ICatalog from zope.copypastemove.interfaces import IContainerItemRenamer from zope import component from zope.event import notify from zope.exceptions.interfaces import DuplicationError from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent from zope.publisher.browser import TestRequest as BaseTestRequest from zope.security.management import getInteraction, newInteraction, endInteraction from zope.interface import Interface from cybertools.util.date import date2TimeStamp, strptime from cybertools.util.jeep import Jeep from loops.common import adapted, baseObject from loops.util import getObjectForUid, getUidForObject, getCatalog, reindex #from xxx import config os.environ['NLS_LANG'] = 'German_Germany.UTF8' sc = Jeep() # shortcuts def setup(root, loopsRootPath=[], config=None): global sm, smdefault, intids, pau, loopsRoot, sc setSite(root) sm = component.getSiteManager(root) smdefault = sm['default'] intids = smdefault['IntIds'] pau = smdefault['PluggableAuthentication'] user = getattr(config, 'shell_user', 'zope.manager') password = (getattr(config, 'shell_pw', None) or raw_input('Enter manager password: ')) login(Principal(user, password, u'Manager')) loopsRoot = root for name in loopsRootPath.split('/'): if name: loopsRoot = loopsRoot[name] sc.concepts = loopsRoot['concepts'] for name in ('standard', 'hasType',): sc[name] = sc.concepts[name] def byuid(uid): return getObjectForUid(uid) def uid(obj): return getUidForObject(obj) def notifyModification(obj): obj = baseObject(obj) notify(ObjectModifiedEvent(obj)) def save(obj): notifyModification(obj) commit() def notifyAdded(obj): obj = baseObject(obj) notify(ObjectAddedEvent(obj)) def notifyRemoved(obj): obj = baseObject(obj) notify(ObjectRemovedEvent(obj)) def delete(container, name, docommit=True): obj = container.get(name) if obj is None: print '*** Object', name, 'not found!' return notifyRemoved(obj) del container[name] if docommit: commit() def rename(container, old, new, docommit=True): obj = container.get(old) if obj is None: print '*** Object', old, 'not found!' return renamer = IContainerItemRenamer(container) if new != old: try: renamer.renameItem(old, new) except DuplicationError: print '*** Object', new, 'already exists!' # container[new] = obj # notifyAdded(obj) notifyModification(obj) if docommit: commit() def move(source, target, name): obj = source.get(name) if obj is None: print '*** Object', name, 'not found!' return #notifyRemoved(obj) #del source[name] target[name] = obj #notifyAdded(obj) notifyModification(obj) commit() def get(container, obj): if isinstance(obj, basestring): name = obj obj = container.get(name) if obj is None: print '*** Object', name, 'not found!' return None return adapted(obj) # startup, loop, finish... def startup(msg, **kw): print '***', msg step = kw.pop('step', 10) return Jeep(count=0, step=step, message=msg, **kw) def update(fct, obj, info): info.count += 1 start = info.get('start') if start and info.count < start: return if info.count % info.step == 0: try: objInfo = obj.__name__ except: try: objInfo = obj.context.__name__ except: objInfo = obj print '*** Processing object # %i: %s' % (info.count, objInfo) if info.get('updated'): print '*** updated: %i.' % info.updated if info.get('errors'): print '*** errors: %i.' % info.error commit() return fct(obj, info) def finish(info): print '*** count: %i.' % info.count if info.get('updated'): print '*** updated: %i.' % info.updated if info.get('errors'): print '*** errors: %i.' % info.error commit() def stop_condition(info): stop = info.get('stop') return stop is not None and info.count > stop def loop(message, objects, fct, **kw): def _fct(obj, info): params = info.get('fctparams', {}) fct(obj, info, **params) info = startup(message, **kw) for obj in objects: update(_fct, obj, info) if stop_condition(info): break finish(info) # indexing def reindex_objects(objs, **kw): catalog = util.getCatalog(objs[0]) def do_reindex(obj, info): util.reindex(obj, catalog) loop('reindex %s objects' % len(objs), objs, do_reindex, **kw) # some common repair tasks def get_type_instances(name): return sc.concepts[name].getChildren([sc.hasType]) def notify_modification(c, info): notifyModification(c) def update_type_instances(**kw): objs = get_type_instances(kw.pop('type')) loop('Notify Type Instances', objs, notify_modification, **kw) def update_type_instances_title_from_adapted(**kw): def update_type_title_from_adapted(c, info): c.title = adapted(c).title notifyModification(c) objs = get_type_instances(kw.pop('type')) loop('Update Type Instances Title', objs, update_type_title_from_adapted, **kw) def removeRecords(container, **kw): """Remove records from container selected by the criteria given.""" def remove(obj, info): notifyRemoved(obj) del container[obj.__name__] info = startup('Remove records', **kw) date = kw.pop('date', None) if date: kw['timeFromTo'] = ( date2TimeStamp(strptime(date + ' 00:00:00')), date2TimeStamp(strptime(date + ' 23:59:59'))) loop('Remove records', container.query(**kw), remove, **kw) # helper functions and classes def login(principal): endInteraction() newInteraction(Participation(principal)) class TestRequest(BaseTestRequest): basePrincipal = BaseTestRequest.principal @Lazy def principal(self): interaction = getInteraction() if interaction is not None: parts = interaction.participations if parts: prin = parts[0].principal if prin is not None: return prin return self.basePrincipal class Participation(object): """ Dummy Participation class for testing. """ interaction = None def __init__(self, principal): self.principal = principal