Compare commits

...
Sign in to create a new pull request.

2 commits

Author SHA1 Message Date
eeab12f6d9 backport catalog import 2016-05-05 16:06:30 +02:00
89b9b33b60 backport shell utilities and repair routines 2016-05-05 16:01:34 +02:00
3 changed files with 278 additions and 0 deletions

160
psu.py Normal file
View file

@ -0,0 +1,160 @@
# psu - paster shell utilities
# use this from (e.g.):
#
# bin/paster shell deploy.ini
#
# then:
#
# from loops import psu
# psu.setup(root)
# obj = psu.byuid('578457950')
#
from transaction import commit, abort
from zope.app.authentication.principalfolder import Principal
from zope.app.catalog.interfaces import ICatalog
from zope.app.component.hooks import setSite
from zope.app.container.contained import ObjectAddedEvent, ObjectRemovedEvent
from zope.cachedescriptors.property import Lazy
from zope import component
from zope.event import notify
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.jeep import Jeep
from loops.common import adapted, baseObject
from loops.util import getObjectForUid, getUidForObject
#from xxx import config
sc = Jeep() # shortcuts
rf = None # root folder
def setup(root):
global rf, sm, smdefault, intids, pau, sc
rf = root
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: '))
user = 'zope.manager'
password = raw_input('Enter manager password: ')
login(Principal(user, password, u'Manager'))
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):
obj = container.get(name)
if obj is None:
print '*** Object', name, 'not found!'
return
notifyRemoved(obj)
del container[name]
commit()
def rename(container, old, new):
obj = container.get(old)
if obj is None:
print '*** Object', old, 'not found!'
return
container[new] = obj
#notifyAdded(obj)
notifyModification(obj)
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)
# catalog / indexing
def getCatalog(context):
context = baseObject(context)
for cat in component.getAllUtilitiesRegisteredFor(ICatalog, context=context):
return cat
print '*** No catalog found!'
def reindex(obj, catalog=None):
obj = baseObject(obj)
if catalog is None:
catalog = getCatalog(obj)
if catalog is not None:
catalog.index_doc(int(getUidForObject(obj)), obj)
# 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

1
repair/__init__.py Normal file
View file

@ -0,0 +1 @@
# package loops.repair

117
repair/base.py Normal file
View file

@ -0,0 +1,117 @@
#
# Copyright (c) 2016 Helmut Merz helmutm@cy55.de
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
Basic stuff for database fixes.
"""
import os
from cybertools.util.date import date2TimeStamp, strptime
from cybertools.util.jeep import Jeep
from loops.common import baseObject
from loops import psu
os.environ['NLS_LANG'] = 'German_Germany.UTF8'
# start, 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
psu.commit()
return fct(obj, info)
def finish(info):
print '*** count: %i.' % info.count
if info.get('updated'):
print '*** updated: %i.' % info.updated
psu.commit()
def stop_condition(info):
stop = info.get('stop')
return stop is not None and info.count > stop
# generic loop
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)
# auxiliary functions
def get_type_instances(name):
return psu.sc.concepts[name].getChildren([psu.sc.hasType])
def notify_modification(c, info):
psu.notifyModification(c)
# some common repair tasks
def removeRecords(container, **kw):
"""Remove records from container selected by the criteria given."""
def remove(obj, info):
psu.notifyRemoved(obj)
del info.container[obj.__name__]
info = startup('Remove records', container=container, **kw)
dateTo = kw.pop('dateTo', None)
if dateTo:
timeTo = date2TimeStamp(strptime(dateTo + ' 23:59:59'))
kw['timeTo'] = timeTo
date = kw.pop('date', None)
if date:
kw['timeFromTo'] = (
date2TimeStamp(strptime(date + ' 00:00:00')),
date2TimeStamp(strptime(date + ' 23:59:59')))
for obj in container.query(**kw):
update(remove, obj, info)
if stop_condition(info):
break
finish(info)