From 4facfbe275aca73c39581e86263d494e60abca16 Mon Sep 17 00:00:00 2001 From: spl0k Date: Fri, 13 Jun 2014 19:04:00 +0200 Subject: [PATCH] Added a naive suboptimal foreground filesystem watcher --- bin/supysonic-watcher | 92 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100755 bin/supysonic-watcher diff --git a/bin/supysonic-watcher b/bin/supysonic-watcher new file mode 100755 index 0000000..eea9269 --- /dev/null +++ b/bin/supysonic-watcher @@ -0,0 +1,92 @@ +#!/usr/bin/python +# coding: utf-8 + +# This file is part of Supysonic. +# +# Supysonic is a Python implementation of the Subsonic server API. +# Copyright (C) 2014 Alban 'spl0k' FĂ©ron +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import time, sys +import logging +from watchdog.observers import Observer +from watchdog.events import PatternMatchingEventHandler + +from supysonic import config +from supysonic.scanner import Scanner + +class SupysonicWatcherEventHandler(PatternMatchingEventHandler): + def __init__(self, logger): + extensions = config.get('base', 'scanner_extensions') + patterns = map(lambda e: "*." + e.lower(), extensions.split()) if extensions else None + super(SupysonicWatcherEventHandler, self).__init__(patterns = patterns, ignore_directories = True) + + self.__logger = logger + + def on_created(self, event): + self.__logger.debug("Scanning created file %s", event.src_path) + Scanner(db.session).scan_file(event.src_path) + db.session.commit() + + def on_deleted(self, event): + self.__logger.debug("File %s deleted", event.src_path) + track = db.Track.query.filter(db.Track.path == event.src_path).first() + if track: + folder = track.root_folder + Scanner(db.session).prune(folder) + db.session.commit() + else: + self.__logger.debug("Deleted file %s not in the database", event.src_path) + + def on_modified(self, event): + self.__logger.debug("Scanning modified file %s", event.src_path) + Scanner(db.session).scan_file(event.src_path) + db.session.commit() + + def on_moved(self, event): + pass + +if __name__ == "__main__": + if not config.check(): + sys.exit(1) + + logger = logging.getLogger(__name__) + log_handler = logging.StreamHandler(sys.stdout) + log_handler.setFormatter(logging.Formatter("%(asctime)s [%(levelname)s] %(message)s")) + logger.addHandler(log_handler) + logger.setLevel(logging.DEBUG) + + from supysonic import db + db.init_db() + + if not db.Folder.query.filter(db.Folder.root == True).count(): + logger.info("No folder set. Exiting.") + sys.exit(0) + + handler = SupysonicWatcherEventHandler(logger) + observer = Observer() + for folder in db.Folder.query.filter(db.Folder.root == True): + logger.info("Starting watcher for %s", folder.path) + observer.schedule(handler, folder.path, recursive = True) + + observer.start() + try: + while True: + time.sleep(1) + except KeyboardInterrupt: + logger.info("Stopping watcher") + observer.stop() + observer.join() +