82 lines
3.0 KiB
Python
82 lines
3.0 KiB
Python
import os, logging
|
|
DEBUG = os.environ.get('DEBUG')
|
|
logging.basicConfig(
|
|
format='[%(asctime)s] %(levelname)s %(module)s/%(funcName)s - %(message)s',
|
|
level=logging.DEBUG if DEBUG else logging.INFO)
|
|
|
|
import secrets
|
|
import threading
|
|
import requests
|
|
from inotify_simple import INotify, flags
|
|
|
|
SCAN_DELAY_SECONDS = 10
|
|
timer = None
|
|
|
|
|
|
def trigger_scan():
|
|
"""Trigger a library scan in Immich."""
|
|
logging.info("Triggering Immich library scan.")
|
|
url = f"{secrets.IMMICH_URL}/api/libraries/{secrets.LIBRARY_UUID}/scan"
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'x-api-key': secrets.IMMICH_API_KEY,
|
|
}
|
|
try:
|
|
response = requests.post(url, headers=headers)
|
|
response.raise_for_status()
|
|
logging.info(f"Scan triggered successfully: {response.status_code}")
|
|
except requests.exceptions.RequestException as e:
|
|
logging.error(f"Failed to trigger scan: {e}")
|
|
|
|
|
|
def add_watch_recursive(inotify, path, watch_flags):
|
|
"""Walk a directory path and add watches recursively."""
|
|
try:
|
|
for root, _, _ in os.walk(path):
|
|
try:
|
|
logging.info(f"Watching {root}")
|
|
inotify.add_watch(root, watch_flags)
|
|
except OSError as e:
|
|
logging.error(f"Error adding watch for {root}: {e}")
|
|
except FileNotFoundError:
|
|
logging.warning(f"Could not scan {path} as it was not found.")
|
|
|
|
|
|
def main():
|
|
global timer
|
|
watch_flags = flags.MODIFY | flags.CREATE | flags.DELETE | flags.MOVED_FROM | flags.MOVED_TO
|
|
|
|
with INotify() as inotify:
|
|
for path in secrets.WATCH_PATHS:
|
|
logging.info(f"Watching {path} and its subdirectories recursively.")
|
|
add_watch_recursive(inotify, path, watch_flags)
|
|
|
|
try:
|
|
while True:
|
|
events = inotify.read(timeout=1000)
|
|
if events:
|
|
for event in events:
|
|
logging.debug(f"Event: {event!r}")
|
|
if event.mask & flags.ISDIR and (event.mask & flags.CREATE or event.mask & flags.MOVED_TO):
|
|
parent_dir_path_bytes = inotify.paths[event.wd]
|
|
new_dir_path_bytes = os.path.join(parent_dir_path_bytes, event.name)
|
|
new_dir_path = new_dir_path_bytes.decode('utf-8')
|
|
logging.info(f"New directory {new_dir_path} detected, adding watches.")
|
|
add_watch_recursive(inotify, new_dir_path, watch_flags)
|
|
|
|
if timer:
|
|
timer.cancel()
|
|
logging.info('Debounce cancelled timer.')
|
|
timer = threading.Timer(SCAN_DELAY_SECONDS, trigger_scan)
|
|
timer.start()
|
|
logging.info(f"Modification detected. Triggering scan in {SCAN_DELAY_SECONDS} seconds.")
|
|
except KeyboardInterrupt:
|
|
logging.info("Shutting down...")
|
|
finally:
|
|
if timer:
|
|
timer.cancel()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|