work in progress: synchronization, i.e. export and import of changes
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@3727 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
d12dac7e37
commit
bfbca480af
6 changed files with 94 additions and 23 deletions
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2009 Helmut Merz helmutm@cy55.de
|
||||
# Copyright (c) 2010 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
|
||||
|
|
79
external/base.py
vendored
79
external/base.py
vendored
|
@ -39,10 +39,11 @@ from cybertools.typology.interfaces import IType
|
|||
from loops.common import adapted
|
||||
from loops.external.interfaces import ILoader, IExtractor, ISubExtractor
|
||||
from loops.external.element import elementTypes
|
||||
from loops.interfaces import IConceptSchema, IResourceSchema
|
||||
from loops.interfaces import IConceptSchema, IResourceSchema, IResource
|
||||
from loops.layout.base import LayoutNode
|
||||
from loops.resource import Document, MediaAsset
|
||||
from loops.setup import SetupManager
|
||||
from loops import util
|
||||
|
||||
|
||||
class Base(object):
|
||||
|
@ -159,19 +160,44 @@ class Extractor(Base):
|
|||
self.count += 1
|
||||
yield elem
|
||||
|
||||
def extractChanged(self, changedSince, parents=None, predicates=None,
|
||||
def extractChanges(self, changedSince, parents=None, predicates=None,
|
||||
includeSubconcepts=False, includeResources=False,):
|
||||
rm = self.context.getRecordManager()
|
||||
if rm is not None:
|
||||
changes = rm.get('changes')
|
||||
changes = self.getChangeRecords()
|
||||
if not changes:
|
||||
return []
|
||||
return
|
||||
objects = []
|
||||
assignments = []
|
||||
deassignments = []
|
||||
tracks = changes.query(timeFrom=changedSince)
|
||||
# work in progress: TODO:
|
||||
# select objects,
|
||||
# check parents using predicates given,
|
||||
# include children and resources if corresponding flags are set.
|
||||
return []
|
||||
for tr in tracks:
|
||||
obj = util.getObjectForUid(tr.taskId)
|
||||
action = tr.data.get('action')
|
||||
if action in ('add', 'modify'):
|
||||
if not self.checkParents(obj, parents, predicates):
|
||||
continue
|
||||
if obj not in objects:
|
||||
objects.append(obj)
|
||||
name = getName(obj)
|
||||
yield self.getConceptOrResourceElement(name, obj)
|
||||
elif action in ('assign', 'deassign'):
|
||||
child = util.getObjectForUid(tr.data['second'])
|
||||
pred = util.getObjectForUid(tr.data['predicate'])
|
||||
if child is None or pred is None:
|
||||
# may have been deleted already - can be ignored
|
||||
continue
|
||||
if (not self.checkParents(obj, parents, predicates) and
|
||||
not self.checkParents(child, parents, predicates)):
|
||||
continue
|
||||
if action == 'assign':
|
||||
element = self.getAssignmentElement(obj, child, pred)
|
||||
else:
|
||||
element = self.getDeassignmentElement(obj, child, pred)
|
||||
if element is not None:
|
||||
yield element
|
||||
# TODO: include new parent and child relations
|
||||
# TODO: include statements for removal of relations if necessary
|
||||
# (or remove relations not in import file upon import)
|
||||
# TODO: include children and resources if corresponding flags are set.
|
||||
|
||||
def extractForParents(self, parents, predicates=None,
|
||||
includeSubconcepts=False, includeResources=False,):
|
||||
|
@ -212,6 +238,37 @@ class Extractor(Base):
|
|||
|
||||
# helper methods
|
||||
|
||||
def getChangeRecords(self):
|
||||
rm = self.context.getRecordManager()
|
||||
if rm is not None:
|
||||
return rm.get('changes')
|
||||
|
||||
def checkParents(self, obj, parents, predicates):
|
||||
if not parents:
|
||||
return True
|
||||
objParents = obj.getParents(predicates)
|
||||
for p in parents:
|
||||
if p in objParents:
|
||||
return True
|
||||
return False
|
||||
|
||||
def getConceptOrResourceElement(self, name, obj):
|
||||
if IResource.providedBy(obj):
|
||||
return self.getResourceElement(name, obj)
|
||||
return self.getConceptElement(name, obj)
|
||||
|
||||
def getAssignmentElement(self, obj, child, predicate):
|
||||
if IResource.providedBy(obj):
|
||||
for r in obj.getResourceRelations([predicate], child):
|
||||
return self.getResourceRelationElement(r)
|
||||
else:
|
||||
for r in obj.getChildRelations([predicate], child):
|
||||
return self.getChildElement(r)
|
||||
|
||||
def getDeassignmentElement(self, obj, child, predicate):
|
||||
args = getName(obj), getName(child), getName(predicate)
|
||||
return elementTypes['deassign'](*args)
|
||||
|
||||
def getConceptElement(self, name, obj):
|
||||
if obj.conceptType is None:
|
||||
raise ValueError('Concept type is None for %s.' % getName(obj))
|
||||
|
|
5
external/browser.py
vendored
5
external/browser.py
vendored
|
@ -81,8 +81,7 @@ class ExportImport(object):
|
|||
parents = [p for p in parents if p is not None]
|
||||
predicateIds = form.get('predicates')
|
||||
if predicateIds:
|
||||
predicates = (predicateIds and [self.conceptManager[id]
|
||||
for id in predicateIds] or None)
|
||||
predicates = ([self.conceptManager[id] for id in predicateIds])
|
||||
changed = form.get('changed')
|
||||
includeSubconcepts = form.get('include_subconcepts')
|
||||
includeResources = form.get('include_resources')
|
||||
|
@ -90,7 +89,7 @@ class ExportImport(object):
|
|||
if changed:
|
||||
changed = self.parseDate(changed)
|
||||
if changed:
|
||||
elements = extractor.extractChanged(changed, parents, predicates,
|
||||
elements = extractor.extractChanges(changed, parents, predicates,
|
||||
includeSubconcepts, includeResources)
|
||||
elif parents:
|
||||
elements = extractor.extractForParents(parents, predicates,
|
||||
|
|
14
external/element.py
vendored
14
external/element.py
vendored
|
@ -190,6 +190,19 @@ class ResourceRelationElement(ChildElement):
|
|||
relevance = self.get('relevance') or 1.0)
|
||||
|
||||
|
||||
class DeassignmentElement(Element):
|
||||
|
||||
elementType = 'deassign'
|
||||
posArgs = ('first', 'second', 'predicate')
|
||||
|
||||
def __init__(self, *args):
|
||||
for idx, arg in enumerate(args):
|
||||
self[self.posArgs[idx]] = arg
|
||||
|
||||
def execute(self, loader):
|
||||
loader.deassignResource(self['first'], self['second'], self['predicate'])
|
||||
|
||||
|
||||
class NodeElement(Element):
|
||||
|
||||
elementType = 'node'
|
||||
|
@ -230,6 +243,7 @@ elementTypes = dict(
|
|||
child=ChildElement,
|
||||
resource=ResourceElement,
|
||||
resourceRelation=ResourceRelationElement,
|
||||
deassign=DeassignmentElement,
|
||||
node=NodeElement,
|
||||
layoutNode=LayoutNodeElement,
|
||||
I18NValue=I18NValue,
|
||||
|
|
8
external/exportimport.pt
vendored
8
external/exportimport.pt
vendored
|
@ -26,7 +26,7 @@
|
|||
<div> </div>
|
||||
<div class="row">
|
||||
<table>
|
||||
<tr tal:condition="nothing">
|
||||
<tr tal:condition="string:nothing">
|
||||
<td>
|
||||
<label for="changed">Export only objects changed since:<br />
|
||||
(YYYY-MM-DD[ HH:MM[:SS]])</label></td>
|
||||
|
@ -42,7 +42,7 @@
|
|||
</td>
|
||||
<td>
|
||||
<label for="predicates">Predicates</label><br />
|
||||
<select multiple name="predicates" id="predicates"
|
||||
<select multiple name="predicates:list" id="predicates"
|
||||
size="9">
|
||||
<option tal:repeat="pred view/predicates"
|
||||
tal:attributes="value pred/name"
|
||||
|
@ -52,11 +52,11 @@
|
|||
<br />
|
||||
<input type="checkbox" name="include_subconcepts"
|
||||
id="include_subconcepts" />
|
||||
<label for="include_subconcepts">Include Subconcepts</label>
|
||||
<label for="include_subconcepts">Include Assigned Subconcepts</label>
|
||||
<br />
|
||||
<input type="checkbox" name="include_resources"
|
||||
id="include_resources" />
|
||||
<label for="include_resources">Include Resources</label>
|
||||
<label for="include_resources">Include Assigned Resources</label>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
@ -201,14 +201,15 @@ class Resource(Image, Contained):
|
|||
if canListObject(r.first, noSecurityCheck))
|
||||
return sorted(rels, key=sort)
|
||||
|
||||
# simplify common access for concepts and resources:
|
||||
getParentRelations = getConceptRelations
|
||||
|
||||
def getConcepts(self, predicates=None, noSecurityCheck=False):
|
||||
obj = getMaster(self)
|
||||
return [r.first for r in obj.getConceptRelations(predicates,
|
||||
noSecurityCheck=noSecurityCheck)]
|
||||
|
||||
# simplify common access for concepts and resources:
|
||||
getParentRelations = getConceptRelations
|
||||
getParents = getConcepts
|
||||
|
||||
def assignConcept(self, concept, predicate=None, order=0, relevance=1.0):
|
||||
obj = getMaster(self)
|
||||
concept.assignResource(obj, predicate, order, relevance)
|
||||
|
|
Loading…
Add table
Reference in a new issue