diff --git a/scanner/scanner/monitor.py b/scanner/scanner/monitor.py index e17ace46..1584622f 100644 --- a/scanner/scanner/monitor.py +++ b/scanner/scanner/monitor.py @@ -1,5 +1,5 @@ from logging import getLogger -from os.path import isdir +from os.path import isdir, dirname, exists, join from watchfiles import awatch, Change from .publisher import Publisher from .scanner import scan, get_ignore_pattern @@ -8,16 +8,33 @@ from providers.kyoo_client import KyooClient logger = getLogger(__name__) +def is_ignored_path(path: str) -> bool: + """Check if the path is within a directory that contains a `.ignore` file.""" + current_path = path + while current_path != "/": # Traverse up to the root directory + if exists(join(current_path, ".ignore")): + return True + current_path = dirname(current_path) + return False + + async def monitor(path: str, publisher: Publisher, client: KyooClient): ignore_pattern = get_ignore_pattern() async for changes in awatch(path, ignore_permission_denied=True): for event, file in changes: + # Check for ignore conditions + if is_ignored_path(file): + logger.info( + "Ignoring event %s for file %s (due to .ignore file)", event, file + ) + continue if ignore_pattern and ignore_pattern.match(file): logger.info( "Ignoring event %s for file %s (due to IGNORE_PATTERN)", event, file ) continue - logger.info("Change %s occured for file %s", event, file) + + logger.info("Change %s occurred for file %s", event, file) match event: case Change.added if isdir(file): await scan(file, publisher, client) @@ -28,4 +45,4 @@ async def monitor(path: str, publisher: Publisher, client: KyooClient): case Change.modified: pass case _: - logger.warn("Unknown file event %s (for file %s)", event, file) + logger.warning("Unknown file event %s (for file %s)", event, file) diff --git a/scanner/scanner/scanner.py b/scanner/scanner/scanner.py index 90f21daa..75cf420b 100644 --- a/scanner/scanner/scanner.py +++ b/scanner/scanner/scanner.py @@ -25,17 +25,25 @@ async def scan( path_: Optional[str], publisher: Publisher, client: KyooClient, remove_deleted=False ): path = path_ or os.environ.get("SCANNER_LIBRARY_ROOT", "/video") - - logger.info("Starting the scan. It can take some times...") + logger.info("Starting the scan. It can take some time...") ignore_pattern = get_ignore_pattern() registered = await client.get_registered_paths() - videos = [ - os.path.join(dir, file) for dir, _, files in os.walk(path) for file in files - ] - if ignore_pattern is not None: - logger.info(f"Ignoring with pattern {ignore_pattern}") - videos = [p for p in videos if not ignore_pattern.match(p)] + videos = [] + + for dirpath, dirnames, files in os.walk(path): + # Skip directories with a `.ignore` file + if ".ignore" in files: + dirnames.clear() # Prevents os.walk from descending into this directory + continue + + for file in files: + file_path = os.path.join(dirpath, file) + # Apply ignore pattern, if any + if ignore_pattern and ignore_pattern.match(file_path): + continue + videos.append(file_path) + to_register = [p for p in videos if p not in registered] if remove_deleted: