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
|
# 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
|
# 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.common import adapted
|
||||||
from loops.external.interfaces import ILoader, IExtractor, ISubExtractor
|
from loops.external.interfaces import ILoader, IExtractor, ISubExtractor
|
||||||
from loops.external.element import elementTypes
|
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.layout.base import LayoutNode
|
||||||
from loops.resource import Document, MediaAsset
|
from loops.resource import Document, MediaAsset
|
||||||
from loops.setup import SetupManager
|
from loops.setup import SetupManager
|
||||||
|
from loops import util
|
||||||
|
|
||||||
|
|
||||||
class Base(object):
|
class Base(object):
|
||||||
|
@ -159,19 +160,44 @@ class Extractor(Base):
|
||||||
self.count += 1
|
self.count += 1
|
||||||
yield elem
|
yield elem
|
||||||
|
|
||||||
def extractChanged(self, changedSince, parents=None, predicates=None,
|
def extractChanges(self, changedSince, parents=None, predicates=None,
|
||||||
includeSubconcepts=False, includeResources=False,):
|
includeSubconcepts=False, includeResources=False,):
|
||||||
rm = self.context.getRecordManager()
|
changes = self.getChangeRecords()
|
||||||
if rm is not None:
|
|
||||||
changes = rm.get('changes')
|
|
||||||
if not changes:
|
if not changes:
|
||||||
return []
|
return
|
||||||
|
objects = []
|
||||||
|
assignments = []
|
||||||
|
deassignments = []
|
||||||
tracks = changes.query(timeFrom=changedSince)
|
tracks = changes.query(timeFrom=changedSince)
|
||||||
# work in progress: TODO:
|
for tr in tracks:
|
||||||
# select objects,
|
obj = util.getObjectForUid(tr.taskId)
|
||||||
# check parents using predicates given,
|
action = tr.data.get('action')
|
||||||
# include children and resources if corresponding flags are set.
|
if action in ('add', 'modify'):
|
||||||
return []
|
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,
|
def extractForParents(self, parents, predicates=None,
|
||||||
includeSubconcepts=False, includeResources=False,):
|
includeSubconcepts=False, includeResources=False,):
|
||||||
|
@ -212,6 +238,37 @@ class Extractor(Base):
|
||||||
|
|
||||||
# helper methods
|
# 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):
|
def getConceptElement(self, name, obj):
|
||||||
if obj.conceptType is None:
|
if obj.conceptType is None:
|
||||||
raise ValueError('Concept type is None for %s.' % getName(obj))
|
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]
|
parents = [p for p in parents if p is not None]
|
||||||
predicateIds = form.get('predicates')
|
predicateIds = form.get('predicates')
|
||||||
if predicateIds:
|
if predicateIds:
|
||||||
predicates = (predicateIds and [self.conceptManager[id]
|
predicates = ([self.conceptManager[id] for id in predicateIds])
|
||||||
for id in predicateIds] or None)
|
|
||||||
changed = form.get('changed')
|
changed = form.get('changed')
|
||||||
includeSubconcepts = form.get('include_subconcepts')
|
includeSubconcepts = form.get('include_subconcepts')
|
||||||
includeResources = form.get('include_resources')
|
includeResources = form.get('include_resources')
|
||||||
|
@ -90,7 +89,7 @@ class ExportImport(object):
|
||||||
if changed:
|
if changed:
|
||||||
changed = self.parseDate(changed)
|
changed = self.parseDate(changed)
|
||||||
if changed:
|
if changed:
|
||||||
elements = extractor.extractChanged(changed, parents, predicates,
|
elements = extractor.extractChanges(changed, parents, predicates,
|
||||||
includeSubconcepts, includeResources)
|
includeSubconcepts, includeResources)
|
||||||
elif parents:
|
elif parents:
|
||||||
elements = extractor.extractForParents(parents, predicates,
|
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)
|
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):
|
class NodeElement(Element):
|
||||||
|
|
||||||
elementType = 'node'
|
elementType = 'node'
|
||||||
|
@ -230,6 +243,7 @@ elementTypes = dict(
|
||||||
child=ChildElement,
|
child=ChildElement,
|
||||||
resource=ResourceElement,
|
resource=ResourceElement,
|
||||||
resourceRelation=ResourceRelationElement,
|
resourceRelation=ResourceRelationElement,
|
||||||
|
deassign=DeassignmentElement,
|
||||||
node=NodeElement,
|
node=NodeElement,
|
||||||
layoutNode=LayoutNodeElement,
|
layoutNode=LayoutNodeElement,
|
||||||
I18NValue=I18NValue,
|
I18NValue=I18NValue,
|
||||||
|
|
8
external/exportimport.pt
vendored
8
external/exportimport.pt
vendored
|
@ -26,7 +26,7 @@
|
||||||
<div> </div>
|
<div> </div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<table>
|
<table>
|
||||||
<tr tal:condition="nothing">
|
<tr tal:condition="string:nothing">
|
||||||
<td>
|
<td>
|
||||||
<label for="changed">Export only objects changed since:<br />
|
<label for="changed">Export only objects changed since:<br />
|
||||||
(YYYY-MM-DD[ HH:MM[:SS]])</label></td>
|
(YYYY-MM-DD[ HH:MM[:SS]])</label></td>
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<label for="predicates">Predicates</label><br />
|
<label for="predicates">Predicates</label><br />
|
||||||
<select multiple name="predicates" id="predicates"
|
<select multiple name="predicates:list" id="predicates"
|
||||||
size="9">
|
size="9">
|
||||||
<option tal:repeat="pred view/predicates"
|
<option tal:repeat="pred view/predicates"
|
||||||
tal:attributes="value pred/name"
|
tal:attributes="value pred/name"
|
||||||
|
@ -52,11 +52,11 @@
|
||||||
<br />
|
<br />
|
||||||
<input type="checkbox" name="include_subconcepts"
|
<input type="checkbox" name="include_subconcepts"
|
||||||
id="include_subconcepts" />
|
id="include_subconcepts" />
|
||||||
<label for="include_subconcepts">Include Subconcepts</label>
|
<label for="include_subconcepts">Include Assigned Subconcepts</label>
|
||||||
<br />
|
<br />
|
||||||
<input type="checkbox" name="include_resources"
|
<input type="checkbox" name="include_resources"
|
||||||
id="include_resources" />
|
id="include_resources" />
|
||||||
<label for="include_resources">Include Resources</label>
|
<label for="include_resources">Include Assigned Resources</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -201,14 +201,15 @@ class Resource(Image, Contained):
|
||||||
if canListObject(r.first, noSecurityCheck))
|
if canListObject(r.first, noSecurityCheck))
|
||||||
return sorted(rels, key=sort)
|
return sorted(rels, key=sort)
|
||||||
|
|
||||||
# simplify common access for concepts and resources:
|
|
||||||
getParentRelations = getConceptRelations
|
|
||||||
|
|
||||||
def getConcepts(self, predicates=None, noSecurityCheck=False):
|
def getConcepts(self, predicates=None, noSecurityCheck=False):
|
||||||
obj = getMaster(self)
|
obj = getMaster(self)
|
||||||
return [r.first for r in obj.getConceptRelations(predicates,
|
return [r.first for r in obj.getConceptRelations(predicates,
|
||||||
noSecurityCheck=noSecurityCheck)]
|
noSecurityCheck=noSecurityCheck)]
|
||||||
|
|
||||||
|
# simplify common access for concepts and resources:
|
||||||
|
getParentRelations = getConceptRelations
|
||||||
|
getParents = getConcepts
|
||||||
|
|
||||||
def assignConcept(self, concept, predicate=None, order=0, relevance=1.0):
|
def assignConcept(self, concept, predicate=None, order=0, relevance=1.0):
|
||||||
obj = getMaster(self)
|
obj = getMaster(self)
|
||||||
concept.assignResource(obj, predicate, order, relevance)
|
concept.assignResource(obj, predicate, order, relevance)
|
||||||
|
|
Loading…
Add table
Reference in a new issue