Erik Thuning eab9808832 Implemented a workaround for permission problems on uploaded recordings.
The recorder uploads presentations without group write permissions, which is
necessary for the play-daemon to be able to properly process recordings.
Hence we set the group write permission on all newly detected uploads
2024-06-18 13:10:37 +02:00

86 lines
2.7 KiB
Python

import logging
import os
from pathlib import Path
import requests
from watchdog.events import PatternMatchingEventHandler
from watchdog.observers.polling import PollingObserver
class Watcher(PatternMatchingEventHandler):
def __init__(self, watchdir: Path, notify_url: str):
super().__init__(ignore_directories=True)
self.watchdir = watchdir
self.notify_url = notify_url
self.watcher = PollingObserver()
self.watcher.schedule(self, self.watchdir, recursive=True)
self.logger = logging.getLogger('arec-watcher.Watcher')
def start(self) -> None:
self.logger.debug('Starting')
self.logger.info("Montoring '%s' for new uploads, notifying to '%s'",
self.watchdir,
self.notify_url)
self._pickup_existing()
return self.watcher.start()
def shutdown(self) -> None:
self.logger.debug('Stopping')
return self.watcher.stop()
def is_datfile(self, path: Path) -> bool:
return path.match('*.dat')
def _pickup_existing(self):
for subdir in self.watchdir.iterdir():
if not subdir.is_dir():
continue
for child in subdir.iterdir():
self._process(child)
def _process(self, path: Path) -> None:
if not self.is_datfile(path):
return
basedir = path.parent
sentinel = basedir / 'arec-watcher-notified'
if sentinel.exists():
self.logger.debug('Ignored %s due to sentinel file present',
basedir)
return
self.logger.info('Picked up %s', basedir)
# The arec upload fails to respect the parent's ACL,
# so we have to fix the permissions here.
self._make_group_writable(basedir)
try:
result = requests.post(self.notify_url,
data={'upload_dir': basedir})
result.raise_for_status()
sentinel.touch(exist_ok=False)
self.logger.info('Successfully notified %s about %s',
self.notify_url,
basedir)
except requests.HTTPError as e:
self.logger.error('Failed to notify %s about %s',
self.notify_url,
basedir,
exc_info=e)
def on_created(self, event):
self._process(Path(event.src_path))
def on_moved(self, event):
self._process(Path(event.dest_path))
def _make_group_writable(self, path: Path):
# Python doesn't have any good tools for recursive permissions,
# so we lean on the OS.
os.system(f'chmod -R g+w {path}')