4teamwork / ftw.linkchecker

0 stars 0 forks source link

Exclude PloneSite "self" when getting all plonesites #16

Closed busykoala closed 5 years ago

busykoala commented 5 years ago

When running the routine it tries to find all PloneSites set up. But we need all of them excluding the one started in the instance running.

This has been solved already here: https://github.com/4teamwork/bgbern.ng/blob/dbc4612e77617727d27e2c275b9187b65804c5ca/bgbern/ng/utils.py#L82-L84

busykoala commented 5 years ago

@Nachtalb before I start working on that could you please ensure I understand the behaviour of your implementation?

Nachtalb commented 5 years ago

def get_plone_sites(own=False):
    plone_root = plone.api.portal.getSite()  # is the the current PloneSite / platform you are operating on
    root = filter(IApplication.providedBy, plone_root.aq_chain)[0]  # Go up the acquisition chain until we reach the the "OFS.Application.Application", which is the "Application" of the site (the "app" variable in a instance script)

    def _get_plone_sites(obj):
        for child in obj.objectValues():  # iterate through all child objects of the current object
            if child.meta_type == 'Plone Site':  # if the child object is a PloneSite yield it (yield means the function returns a generator https://wiki.python.org/moin/Generators)
                yield child
            elif child.meta_type == 'Folder':  # Recursively run our "_get_plone_sites" function if the current object is a folder, because it could include more PloneSites (a ZODB Mountpoint is a folder but not every folder is a ZODB Mountpoint)
                for item in _get_plone_sites(child):
                    yield item

    if own:  # If own (bool) is set to True, return all PloneSite's including the current "plone_root"
        return _get_plone_sites(root)

    # If "own" is set to False, exclude the current "plone_root"
    own_physical_path = plone_root.getPhysicalPath()  # Get the physical path of the "plone_root", locally this is typically ['', 'platform'] on deployments ['', 'foo_bar', 'platform'] (where foo_bar is the ZODB mountpoint name, defined via "filestorage-parts" in your deployment cfg)

    # "filter(function, iterable)" call the "function" for every item in the "iterables". If the "function" returns True, keep the element if False, throw it away https://docs.python.org/3/library/functions.html#filter
    # "lambda i:" oneline function wrapper which accepts one item. https://docs.python.org/3/tutorial/controlflow.html?highlight=lambda#lambda-expressions
    # "i.getPhysicalPath() != own_physical_path" if the items physical path DOES NOT MATCH the "plone_roots" path, return True, if it DOES MATCH it means the current item is out "plone_root" and it returns False, which throws it away: eg. current item has path like ['', 'foo', 'platform'] and plone_root ['', 'bar', 'platform'] == The paths do not match, keep the item. The next item has the path ['', 'bar', 'plaform'] == The item has the same path as our plone_root, meaning it IS our plone_root, so we return False.
    # "_get_plone_sites(root)" all PloneSites including current "plone_root"
    return filter(lambda i: i.getPhysicalPath() != own_physical_path, _get_plone_sites(root))
Nachtalb commented 5 years ago

Hope this explanation is understandable, if not feel free to ask any question.