Source code for dynamo_consistency.emptyremover

"""
Defines a class that can remove nodes from a :py:class:`DirectoryInfo` object
"""

import logging

from os.path import join

from . import datatypes
from . import history
from . import config
from .backend import registry


LOG = logging.getLogger(__name__)


[docs]class EmptyRemover(object): """ This class handles the removal of empty directories from the tree by behaving as a callback. It also calls deletions for the registry at the same time. :param str site: Site name. If value is ``None``, then don't enter deletions into the registry, but still remove node from tree :param function check: The function to check against orphans to not delete. The full path name is passed to the function. If it returns ``True``, the directory is not deleted. """ def __init__(self, site, check=None): self.site = site self.check = check or (lambda _: False) self.removed = 0 self.root = config.config_dict()['RootPath'] # This is a set of directories that have a filtered directory inside self.not_empty = set()
[docs] def fullname(self, name): """ Get the full LFN of a path. Checkes if the root is included, and adds it if necessary. .. Note:: Won't work if the root name is the same as a relative path inside it. :param str name: May be a relative path to the root :returns: Full LFN :rtype: str """ return join(self.root, name) \ if not name.startswith(self.root) else name
def __call__(self, tree): """ Removes acceptable empty directories from the tree :param tree: The tree that is periodically cleaned by this :type tree: :py:class:`datatypes.DirectoryInfo` """ tree.setup_hash() empties = [empty for empty in tree.empty_nodes_list() if not self.check(self.fullname(empty)) and empty not in self.not_empty] LOG.debug('Sees %s', empties) strip_len = len(tree.name) + 1 empties_info = [] for path in empties: try: info = ( self.fullname(path), tree.get_node(path[strip_len:], make_new=False).mtime ) tree.remove_node(path) empties_info.append(info) except datatypes.NotEmpty as msg: LOG.warning('While removing %s: %s', path, msg) self.not_empty.add(path) full_empties = [info[0] for info in empties_info] history.report_empty(empties_info) self.removed += registry.delete(self.site, full_empties) \ if self.site and full_empties else len(full_empties)
[docs] def get_removed_count(self): """ :returns: The number of directories removed by this function object :rtype: int """ return self.removed