mirror of
https://github.com/migatu/conjurer.git
synced 2026-07-21 17:22:09 +00:00
share: dockerize the file-share pipeline and document it
The Python half of the short-lived share links lived in the repo; the Apache config and the cron entries that make it work were hand-placed on the host, so the feature could not be rebuilt from a checkout. This adds the missing half. Scripts (defaults unchanged, so existing bare-metal cron keeps working): * scan_shares.py / revoke_shares.py take their paths from CONJURER_SHARE_* instead of hardcoding the Pi layout, and create their parent dirs; * the revoke TTL is now CONJURER_SHARE_TTL_SECONDS. Its --help claimed "2min" while the code used a hardcoded 3600 - the help text now reports the real, configured value. New share service: * docker/Dockerfile.share - Apache + the two jobs, reusing the same scripts rather than forking copies; * docker/share-vhost.conf.tpl - the previously undocumented Apache half. Three settings are load-bearing and commented as such: +FollowSymLinks (the shares ARE symlinks), -Indexes (a listing would expose every live token), and a deny rule for dotfiles (revoke_shares.py keeps .downloads.json - a map of every live token - inside the served directory); * docker/entrypoint.share.sh - renders the vhost, seeds the index on first run, then runs scanner/revoker in sleep loops beside Apache (no cron, so their output shows up in docker logs); * compose + env example, incl. the two volumes that MUST be shared with the musician (it creates the links and reads the index). docs/deployment/FILE_SHARING.md documents the mechanism, both deployment routes (docker and existing host Apache), the Discord command, why each Apache setting matters, verification commands, and the known limitations - notably that a link nobody ever downloads is never revoked, since the TTL starts at first download. Verified: scanner and revoker exercised end-to-end against temp dirs (index built; token recorded from a combined-format log line and the symlink unlinked). Compose file not validated - no docker on this machine. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,12 +1,18 @@
|
||||
#!/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
|
||||
from pathlib import Path
|
||||
|
||||
# Configuration
|
||||
SCAN_PATH = '/mnt/shares'
|
||||
OUTPUT_FILE = '/var/log/share_scan.json'
|
||||
# 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."""
|
||||
@@ -34,7 +40,8 @@ def main():
|
||||
'root': SCAN_PATH,
|
||||
'entries': scan_directory(SCAN_PATH),
|
||||
}
|
||||
# Write atomically
|
||||
# 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)
|
||||
|
||||
Reference in New Issue
Block a user