From d06f96388d754ed41876f7fccb63f84241d44963 Mon Sep 17 00:00:00 2001 From: Michaƫl Ball Date: Sun, 26 Mar 2017 10:19:59 +0100 Subject: Works on python 2/pypy --- watcher.py | 120 +++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 98 insertions(+), 22 deletions(-) (limited to 'watcher.py') diff --git a/watcher.py b/watcher.py index 9af4a6b..353636a 100644 --- a/watcher.py +++ b/watcher.py @@ -1,41 +1,104 @@ -import atexit -import configparser +""" +Defines a watcher service to update the media library. + +This module implements a monitoring service to update the library when files +are added or removed from the media library directory. +""" +from atexit import register +import logging import os import pyinotify -import library +from db.db_manager import DbManager +from library import MediaLibrary + + +_LOGGER = logging.getLogger(__name__) class EventHandler(pyinotify.ProcessEvent): + """Event handler defining actions for adding/moving/removing files. + + Extends: + pyinotify.ProcessEvent + + """ + + def __init__(self, media_library, pevent=None, **kwargs): + """Create the event handler. + + Args: + media_library (MediaLibrary): The media library. + + """ + self.__library = media_library + + super(self.__class__, self).__init__(pevent=None, **kwargs) + def process_IN_CREATE(self, event): - print("Creating:", event.pathname) - library.run(event.pathname) + """Add a file to the library when it is created. + + Args: + event (pynotify.Event) - the event raised by inotify. + + """ + _LOGGER.debug("Creating: %s", event.pathname) + self.__library.run(event.pathname) def process_IN_DELETE(self, event): - print("Removing:", event.pathname) + """Remove a file from the library when it is deleted. + + Args: + event (pynotify.Event) - the event raised by inotify. + + """ + _LOGGER.debug("Removing: %s", event.pathname) if not os.path.isdir(event.pathname): - library.delete_file(event.pathname) + self.__library.delete_file(event.pathname) def process_IN_MOVED_TO(self, event): - print("Moved to:", event.pathname) - library.update_track_filename(event.src_pathname, event.pathname) + """Update a file's information in the library when it is moved. + + Args: + event (pynotify.Event) - the event raised by inotify. + + """ + _LOGGER.debug("Moved to: %s", event.pathname) + self.__library.update_track_filename(event.src_pathname, + event.pathname) # moving the file may also hint that the metadata has changed - library.update_file(event.pathname) + self.__library.update_file(event.pathname) def process_IN_MODIFY(self, event): - print("Modified:", event.pathname) + """Update a file's information in the library when it is modified. + + Args: + event (pynotify.Event) - the event raised by inotify. + + """ + _LOGGER.debug("Modified: %s", event.pathname) if not os.path.isdir(event.pathname): - library.update_file(event.pathname) + self.__library.update_file(event.pathname) -class LibraryWatcher: +class LibraryWatcher(object): + """Watches the library.""" - def __init__(self, path): - print("Setting up library watcher") + def __init__(self, path, database_path): + """Create the LibraryWatcher. + + Args: + path (str): the patch of the directory to watch. + + """ + _LOGGER.info("Setting up library watcher") + database = DbManager(database_path) + library = MediaLibrary(path, database) + _LOGGER.info("Using %s", database) if not hasattr(self, "path"): setattr(self, "path", path) @@ -50,25 +113,38 @@ class LibraryWatcher: if not hasattr(self, "notifier"): setattr(self, "notifier", - pyinotify.ThreadedNotifier(self.wm, EventHandler())) - - self.notifier.coalesce_events() - self.notifier.start() + pyinotify.Notifier(self.wm, EventHandler(library), + timeout=10)) if not hasattr(self, "wdd"): setattr(self, "wdd", self.wm.add_watch(path, mask, rec=True, auto_add=True)) - print("Set up watch on ", path) + self.notifier.coalesce_events() + + _LOGGER.info("Set up watch on %s", path) - atexit.register(self.stop) + register(self.stop) def stop(self): + """Remove all the watched paths.""" if self.wdd[self.path] > 0: self.wm.rm_watch(self.wdd[self.path], rec=True) + def check_for_events(self): + """Check for any notification events.""" + assert self.notifier._timeout is not None + self.notifier.process_events() + while self.notifier.check_events(): + self.notifier.read_events() + self.notifier.process_events() + + if __name__ == "__main__": + from six.moves import configparser + config = configparser.ConfigParser() config.read("mach2.ini") - watch = LibraryWatcher(config["DEFAULT"]["media_dir"]) + watch = LibraryWatcher(config.get("DEFAULT", "media_dir"), + config.get("DEFAULT", "library")) -- cgit v1.2.3