feat: add support for ".ignore" file

This commit is contained in:
Felipe Marinho 2024-11-14 19:18:02 -03:00 committed by Zoe Roux
parent 04a628e195
commit d39694ae24
No known key found for this signature in database
2 changed files with 36 additions and 11 deletions

View File

@ -1,5 +1,5 @@
from logging import getLogger from logging import getLogger
from os.path import isdir from os.path import isdir, dirname, exists, join
from watchfiles import awatch, Change from watchfiles import awatch, Change
from .publisher import Publisher from .publisher import Publisher
from .scanner import scan, get_ignore_pattern from .scanner import scan, get_ignore_pattern
@ -8,16 +8,33 @@ from providers.kyoo_client import KyooClient
logger = getLogger(__name__) 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): async def monitor(path: str, publisher: Publisher, client: KyooClient):
ignore_pattern = get_ignore_pattern() ignore_pattern = get_ignore_pattern()
async for changes in awatch(path, ignore_permission_denied=True): async for changes in awatch(path, ignore_permission_denied=True):
for event, file in changes: 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): if ignore_pattern and ignore_pattern.match(file):
logger.info( logger.info(
"Ignoring event %s for file %s (due to IGNORE_PATTERN)", event, file "Ignoring event %s for file %s (due to IGNORE_PATTERN)", event, file
) )
continue continue
logger.info("Change %s occured for file %s", event, file)
logger.info("Change %s occurred for file %s", event, file)
match event: match event:
case Change.added if isdir(file): case Change.added if isdir(file):
await scan(file, publisher, client) await scan(file, publisher, client)
@ -28,4 +45,4 @@ async def monitor(path: str, publisher: Publisher, client: KyooClient):
case Change.modified: case Change.modified:
pass pass
case _: case _:
logger.warn("Unknown file event %s (for file %s)", event, file) logger.warning("Unknown file event %s (for file %s)", event, file)

View File

@ -25,17 +25,25 @@ async def scan(
path_: Optional[str], publisher: Publisher, client: KyooClient, remove_deleted=False path_: Optional[str], publisher: Publisher, client: KyooClient, remove_deleted=False
): ):
path = path_ or os.environ.get("SCANNER_LIBRARY_ROOT", "/video") path = path_ or os.environ.get("SCANNER_LIBRARY_ROOT", "/video")
logger.info("Starting the scan. It can take some time...")
logger.info("Starting the scan. It can take some times...")
ignore_pattern = get_ignore_pattern() ignore_pattern = get_ignore_pattern()
registered = await client.get_registered_paths() registered = await client.get_registered_paths()
videos = [ videos = []
os.path.join(dir, file) for dir, _, files in os.walk(path) for file in files
] for dirpath, dirnames, files in os.walk(path):
if ignore_pattern is not None: # Skip directories with a `.ignore` file
logger.info(f"Ignoring with pattern {ignore_pattern}") if ".ignore" in files:
videos = [p for p in videos if not ignore_pattern.match(p)] 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] to_register = [p for p in videos if p not in registered]
if remove_deleted: if remove_deleted: