Skip to content

Commit

Permalink
Merge pull request #1 from collective/thet-uuidindexing
Browse files Browse the repository at this point in the history
Upgrade to UUID based indexing
  • Loading branch information
thet committed Apr 26, 2015
2 parents 51df245 + b49890c commit b49423e
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 18 deletions.
14 changes: 12 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,18 @@ Changelog
0.5 (unreleased)
----------------

- Don't let the ``lineage.childsites`` vocabulary fail, if there are multiple
childsites with the same id.
- Depend on ``plone.api`` and use it to get the portal object.
[thet]

- Add ``chilsiteForContext`` method, which returns the childsite UUID for a
given context.
[thet]

- Upgrade to ``UUID`` basd indexing instead of using the ``id``. The id is not
unique and causes problems when multiple lineage subsites with the same id
are registered. Furthermore, the uuid can be used to retrieve the lineage
childsite object without traversing up the content tree. A upgrade step is
included.
[thet]


Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
install_requires=[
'setuptools',
'collective.lineage',
'plone.api',
],
entry_points="""
[z3c.autoinclude.plugin]
Expand Down
9 changes: 9 additions & 0 deletions src/lineage/index/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,13 @@
description="Index for searching content of childsites"
provides="Products.GenericSetup.interfaces.EXTENSION"/>

<genericsetup:upgradeStep
source="1"
destination="2"
title="Upgrade to UUID based indexing."
description="Rebuild the catalog to reindex UUID values instead the id."
profile="lineage.index:default"
handler=".upgrades.upgrade_uuid"
/>

</configure>
11 changes: 6 additions & 5 deletions src/lineage/index/index.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
from Acquisition import aq_base
from Products.CMFCore.interfaces import IContentish
from Products.CMFCore.utils import getToolByName
from Products.CMFPlone import utils
from collective.lineage.interfaces import IChildSite
from plone.indexer.decorator import indexer
from plone.uuid.interfaces import IUUID
import plone.api


def getNextChildSite(context, portal):
"""Returns the nearest parent object implementing INavigationRoot.
"""Returns the nearest parent object implementing IChildSite.
Code borrowed from plone.app.layout.navigation.root.getNavigationRootObject
"""
obj = context
Expand All @@ -19,14 +20,14 @@ def getNextChildSite(context, portal):

@indexer(IContentish)
def childsite(obj):
"""Return the id of the closest INavigationRoot up the hierarchy or None if
"""Return the uuid of the closest childsite up the hierarchy or None if
there is no subsite.
"""
portal = getToolByName(obj, 'portal_url').getPortalObject()
portal = plone.api.portal.get()
childsite = getNextChildSite(obj, portal)

if childsite == portal:
# Index None so that you can get all non-child site content
return None

return childsite.id
return IUUID(childsite)
2 changes: 1 addition & 1 deletion src/lineage/index/profiles/default/metadata.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<metadata>
<version>1</version>
<version>2</version>
<dependencies>
<dependency>profile-collective.lineage:default</dependency>
</dependencies>
Expand Down
21 changes: 21 additions & 0 deletions src/lineage/index/upgrades.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from Products.CMFCore.utils import getToolByName
import logging

logger = logging.getLogger('lineage.index')


def upgrade_uuid(context):
"""Reindex the childsite index to use UUID instead of id values. This makes
it possible to have multiple childsites with the same id in different
paths.
"""
index_id = 'childsite'
cat = getToolByName(context, 'portal_catalog')
cat.delColumn(index_id)
cat.addColumn(index_id)
res = (it.getObject() for it in cat.searchResults()) # generator expr.
for cnt, ob in enumerate(res):
ob.reindexObject(idxs=(index_id,))
if cnt % 100 == 0:
# 100-batch
logger.info("Reindex next batch, starting with {0}".format(cnt))
27 changes: 26 additions & 1 deletion src/lineage/index/view.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,43 @@
from Acquisition import aq_parent
from Products.CMFCore.utils import getToolByName
from Products.Five.browser import BrowserView
from plone.memoize.view import memoize_contextless
from plone.uuid.interfaces import IUUID
from zope.component import getUtility
from zope.schema.interfaces import IVocabularyFactory
import plone.api


# Special cases
try:
from plone.event.interfaces import IOccurrence
except ImportError:
IOccurrence = None


class ChildsiteView(BrowserView):

@memoize_contextless
def titleForKey(self, key):
"""returns the childsite's title for their vocabulary value.
"""Returns the childsite's title for their vocabulary value.
"""
util = getUtility(IVocabularyFactory, 'lineage.childsites')
vocab = util(self.context)
try:
return vocab.getTerm(key).title
except LookupError:
return key

def childsiteForContext(self, item):
"""Returns the childsite UUID for a context object by looking up it's
brain in the catalog.
"""
childsite = ''
if IOccurrence and IOccurrence.providedBy(item):
item = aq_parent(item)
portal = plone.api.portal.get()
cat = getToolByName(self.context, 'portal_catalog')
res = cat(UID=IUUID(item, None), path=portal.getPhysicalPath())
if res:
childsite = res[0].childsite
return childsite
19 changes: 10 additions & 9 deletions src/lineage/index/vocabulary.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
from plone.memoize import ram
from zope.interface.declarations import directlyProvides
from zope.schema.interfaces import IVocabularyFactory
from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary
from zope.schema.vocabulary import SimpleTerm
from zope.schema.vocabulary import SimpleVocabulary
import plone.api


# cache until next zope restart
Expand All @@ -13,17 +15,16 @@ def childSiteVocabulary(context):
"""returns the available childsites of the portal
"""
cat = getToolByName(context, 'portal_catalog')
portal = plone.api.portal.get()
brains = cat(
object_provides=IChildSite.__identifier__,
path=portal.getPhysicalPath(),
sort_on='sortable_title'
)
set_brains = []
terms = []
for brain in brains:
val = brain.id
if val not in set_brains:
# vocabulary values and tokens must be unique
set_brains.append(val)
terms.append(SimpleTerm(value=val, token=val, title=brain.Title))
terms = [
SimpleTerm(value=brain.UID, token=brain.UID, title=brain.Title)
for brain in brains
]
return SimpleVocabulary(terms)

directlyProvides(childSiteVocabulary, IVocabularyFactory)

0 comments on commit b49423e

Please sign in to comment.