rgs1/zk_shell

View on GitHub
zk_shell/watcher.py

Summary

Maintainability
A
0 mins
Test Coverage
from __future__ import print_function

import difflib


class ChildrenHandler(object):
    def __init__(self, path, verbose=False, print_func=print):
        self._path = path
        self._verbose = verbose
        self._running = True
        self._current = []
        self._print_func = print_func

    def stop(self):
        self._running = False

    def __call__(self, children):
        if self._running is False:
            return False

        if self._verbose:
            diff = difflib.ndiff(sorted(self._current), sorted(children))
            self._print_func("\n%s:\n%s" % (self._path, '\n'.join(diff)))
        else:
            self._print_func("\n%s:%d\n" % (self._path, len(children)))

        self._current = children


class ChildWatcher(object):
    def __init__(self, client, print_func):
        self._client = client
        self._by_path = {}
        self._print_func = print_func

    def update(self, path, verbose=False):
        """ if the path isn't being watched, start watching it
            if it is, stop watching it
        """
        if path in self._by_path:
            self.remove(path)
        else:
            self.add(path, verbose)

    def remove(self, path):
        # If we don't have the path, we are done.
        if path not in self._by_path:
            return

        self._by_path[path].stop()
        del self._by_path[path]

    def add(self, path, verbose=False):
        # If we already have the path, do nothing.
        if path in self._by_path:
            return

        ch = ChildrenHandler(path, verbose, print_func=self._print_func)
        self._by_path[path] = ch
        self._client.ChildrenWatch(path, ch)


_cw = None


def get_child_watcher(client, print_func=print):
    global _cw
    if _cw is None:
        _cw = ChildWatcher(client, print_func=print_func)

    return _cw