#!/usr/bin/env python3 """Build the share index that the musician's /get_share_list endpoint searches. Walks the media root and writes a JSON catalogue of every file/dir found. Meant to run periodically (cron on bare metal, the scheduler loop in the share container). Paths are environment-overridable; the defaults reproduce the original Raspberry Pi layout, so existing cron entries keep working unchanged. """ import os import json import time # Configuration (env-overridable; defaults = original bare-metal Pi layout) SCAN_PATH = os.getenv('CONJURER_SHARE_SCAN_PATH', '/mnt/shares') OUTPUT_FILE = os.getenv('CONJURER_SHARE_DB', '/var/log/share_scan.json') def scan_directory(root): """Recursively walk `root` and collect metadata.""" entries = [] for dirpath, dirs, files in os.walk(root): for name in dirs + files: full = os.path.join(dirpath, name) try: stat = os.stat(full) entries.append({ 'path': full, 'is_dir': os.path.isdir(full), 'size_bytes': stat.st_size, 'mtime': time.strftime('%Y-%m-%dT%H:%M:%S%z', time.localtime(stat.st_mtime)), }) except Exception as e: # skip items we can't stat continue return entries def main(): data = { 'scanned_at': time.strftime('%Y-%m-%dT%H:%M:%S%z', time.localtime()), 'root': SCAN_PATH, 'entries': scan_directory(SCAN_PATH), } # Write atomically (create the target dir first so a fresh volume works) os.makedirs(os.path.dirname(OUTPUT_FILE) or '.', exist_ok=True) temp = OUTPUT_FILE + '.tmp' with open(temp, 'w') as f: json.dump(data, f, indent=2) os.replace(temp, OUTPUT_FILE) if __name__ == '__main__': main()