1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-12-23 01:16:18 +00:00

Temporarily disable watcher when scanning

This commit is contained in:
spl0k 2019-04-22 14:48:56 +02:00
parent 7f8369cac4
commit d2ff37428f
3 changed files with 43 additions and 11 deletions

View File

@ -62,7 +62,7 @@ class Daemon(object):
if extensions: if extensions:
extensions = extensions.split(' ') extensions = extensions.split(' ')
self.__scanner = ScannerThread(args = folders, kwargs = { 'force': force, 'extensions': extensions }) self.__scanner = ScannerThread(self.__watcher, folders, kwargs = { 'force': force, 'extensions': extensions, 'notify_watcher': False })
self.__scanner.start() self.__scanner.start()
def terminate(self): def terminate(self):
@ -71,25 +71,31 @@ class Daemon(object):
self.__watcher.stop() self.__watcher.stop()
class ScannerThread(Thread): class ScannerThread(Thread):
def __init__(self, *args, **kwargs): def __init__(self, watcher, folders, *args, **kwargs):
super(ScannerThread, self).__init__(*args, **kwargs) super(ScannerThread, self).__init__(*args, **kwargs)
self.__watcher = watcher
self.__folders = folders
self.__scanned = {} self.__scanned = {}
def run(self): def run(self):
force = self._kwargs.get('force', False) s = Scanner(*self._args, **self._kwargs)
extensions = self._kwargs.get('extensions')
s = Scanner(force = force, extensions = extensions)
with db_session: with db_session:
if self._args: if self.__folders:
folders = Folder.select(lambda f: f.root and f.name in self._args) folders = Folder.select(lambda f: f.root and f.name in self.__folders)
else: else:
folders = Folder.select(lambda f: f.root) folders = Folder.select(lambda f: f.root)
for f in folders: for f in folders:
name = f.name name = f.name
if self.__watcher is not None:
self.__watcher.remove_folder(f)
try:
logger.info('Scanning %s', name) logger.info('Scanning %s', name)
s.scan(f, lambda x: self.__scanned.update({ name: x })) s.scan(f, lambda x: self.__scanned.update({ name: x }))
finally:
if self.__watcher is not None:
self.__watcher.add_folder(f)
s.finish() s.finish()

View File

@ -16,6 +16,8 @@ from datetime import datetime
from pony.orm import db_session from pony.orm import db_session
from .covers import find_cover_in_folder, CoverFile from .covers import find_cover_in_folder, CoverFile
from .daemon.exceptions import DaemonUnavailableError
from .daemon.client import DaemonClient
from .db import Folder, Artist, Album, Track, User from .db import Folder, Artist, Album, Track, User
from .db import StarredFolder, StarredArtist, StarredAlbum, StarredTrack from .db import StarredFolder, StarredArtist, StarredAlbum, StarredTrack
from .db import RatingFolder, RatingTrack from .db import RatingFolder, RatingTrack
@ -34,11 +36,12 @@ class Stats(object):
self.errors = [] self.errors = []
class Scanner: class Scanner:
def __init__(self, force = False, extensions = None): def __init__(self, force = False, extensions = None, notify_watcher = True):
if extensions is not None and not isinstance(extensions, list): if extensions is not None and not isinstance(extensions, list):
raise TypeError('Invalid extensions type') raise TypeError('Invalid extensions type')
self.__force = force self.__force = force
self.__notify = notify_watcher
self.__stats = Stats() self.__stats = Stats()
self.__extensions = extensions self.__extensions = extensions
@ -47,6 +50,11 @@ class Scanner:
if not isinstance(folder, Folder): if not isinstance(folder, Folder):
raise TypeError('Expecting Folder instance, got ' + str(type(folder))) raise TypeError('Expecting Folder instance, got ' + str(type(folder)))
if self.__notify:
daemon = DaemonClient()
try: daemon.remove_watched_folder(folder.path)
except DaemonUnavailableError: pass
# Scan new/updated files # Scan new/updated files
to_scan = [ folder.path ] to_scan = [ folder.path ]
scanned = 0 scanned = 0
@ -96,6 +104,10 @@ class Scanner:
folder.last_scan = int(time.time()) folder.last_scan = int(time.time())
if self.__notify:
try: daemon.add_watched_folder(folder.path)
except DaemonUnavailableError: pass
@db_session @db_session
def finish(self): def finish(self):
self.__stats.deleted.albums = Album.prune() self.__stats.deleted.albums = Album.prune()

View File

@ -224,6 +224,12 @@ class ScannerProcessingQueue(Thread):
self.__timer = Timer(self.__timeout, self.__wakeup) self.__timer = Timer(self.__timeout, self.__wakeup)
self.__timer.start() self.__timer.start()
def unschedule_paths(self, basepath):
with self.__cond:
for path in self.__queue.keys():
if path.startswith(basepath):
del self.__queue[path]
def __wakeup(self): def __wakeup(self):
with self.__cond: with self.__cond:
self.__cond.notify() self.__cond.notify()
@ -262,10 +268,18 @@ class SupysonicWatcher(object):
watch = self.__observer.schedule(self.__handler, path, recursive = True) watch = self.__observer.schedule(self.__handler, path, recursive = True)
self.__folders[path] = watch self.__folders[path] = watch
def remove_folder(self, path): def remove_folder(self, folder):
if isinstance(folder, Folder):
path = folder.path
elif isinstance(folder, strtype):
path = folder
else:
raise TypeError('Expecting string or Folder, got ' + str(type(folder)))
logger.info("Unscheduling watcher for %s", path) logger.info("Unscheduling watcher for %s", path)
self.__observer.unschedule(self.__folders[path]) self.__observer.unschedule(self.__folders[path])
del self.__folders[path] del self.__folders[path]
self.__queue.unschedule_paths(path)
def start(self): def start(self):
self.__queue = ScannerProcessingQueue(self.__delay) self.__queue = ScannerProcessingQueue(self.__delay)