feat: add basic watchdog

This commit is contained in:
Louis Heredero 2025-05-04 12:13:45 +02:00
parent 371fb9042d
commit 4a4949b474
Signed by: HEL
GPG Key ID: 8D83DE470F8544E7

View File

@ -1,5 +1,7 @@
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import json
import logging
@ -7,9 +9,14 @@ import os
import socketserver
from http import HTTPStatus
from http.server import SimpleHTTPRequestHandler
import time
from typing import Optional
from urllib.parse import parse_qs, unquote, urlparse
from watchdog.events import DirModifiedEvent, FileSystemEventHandler
from watchdog.observers import Observer
from watchdog.observers.api import BaseObserver
# https://stackoverflow.com/a/10551190/11109181
class EnvDefault(argparse.Action):
@ -32,17 +39,20 @@ class EnvDefault(argparse.Action):
setattr(namespace, self.dest, values)
class MyHandler(SimpleHTTPRequestHandler):
MAX_PAYLOAD_SIZE = 1e6
DATA_DIR = "metadata"
class HTTPHandler(SimpleHTTPRequestHandler):
SERVER: MeliesServer = None
CACHE = {}
def __init__(self, *args, **kwargs):
self.MAX_PAYLOAD_SIZE: int = self.SERVER.max_payload_size
self.DATA_DIR: str = self.SERVER.metadata_dir
super().__init__(
*args,
directory=os.path.join(os.path.dirname(__file__), "public"),
**kwargs
)
self.query: dict = {}
self.data: Optional[dict|list] = None
@ -178,6 +188,66 @@ class MyHandler(SimpleHTTPRequestHandler):
self.CACHE[filename] = meta
class MeliesServer(FileSystemEventHandler):
def __init__(
self,
port: int,
to_convert_dir: str,
converted_dir: str,
metadata_dir: str,
max_payload_size: int):
super().__init__()
self.port: int = port
self.to_convert_dir: str = to_convert_dir
self.converted_dir: str = converted_dir
self.metadata_dir: str = metadata_dir
self.max_payload_size: int = max_payload_size
HTTPHandler.SERVER = self
if not os.path.exists(self.to_convert_dir):
os.mkdir(self.to_convert_dir)
if not os.path.exists(self.converted_dir):
os.mkdir(self.converted_dir)
if not os.path.exists(self.metadata_dir):
os.mkdir(self.metadata_dir)
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
datefmt=r"%Y-%m-%d %H:%M:%S"
)
self.httpd: Optional[socketserver.TCPServer] = None
self.observer: BaseObserver = Observer()
self.observer.schedule(self, self.converted_dir, event_filter=[DirModifiedEvent])
self.last_event: float = time.time()
def start(self):
self.observer.start()
try:
with socketserver.TCPServer(("", self.port), HTTPHandler) as self.httpd:
logging.info(f"Serving on port {self.port}")
self.httpd.serve_forever()
except KeyboardInterrupt:
pass
self.stop()
def stop(self):
self.observer.stop()
self.observer.join()
def on_modified(self, event: DirModifiedEvent):
t: float = time.time()
logging.info(event)
if t - self.last_event > 1:
self.last_event = t
def main():
parser = argparse.ArgumentParser(
description="Starts the Melies server",
@ -199,6 +269,20 @@ def main():
type=int,
help="Maximum POST payload size in bytes that the server accepts"
)
parser.add_argument(
"--to-convert-dir",
action=EnvDefault,
envvar="MELIES_TO_CONVERT_DIR",
default="to_convert",
help="Path to the directory containing medias to convert"
)
parser.add_argument(
"--converted-dir",
action=EnvDefault,
envvar="MELIES_CONVERTED_DIR",
default="converted",
help="Path to the directory containing converted medias"
)
parser.add_argument(
"--metadata-dir",
action=EnvDefault,
@ -208,26 +292,14 @@ def main():
)
args = parser.parse_args()
port = args.port
MyHandler.MAX_PAYLOAD_SIZE = args.max_payload_size
MyHandler.DATA_DIR = args.metadata_dir
if not os.path.exists(args.metadata_dir):
os.mkdir(args.metadata_dir)
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
datefmt=r"%Y-%m-%d %H:%M:%S"
server = MeliesServer(
args.port,
args.to_convert_dir,
args.converted_dir,
args.metadata_dir,
args.max_payload_size
)
try:
with socketserver.TCPServer(("", port), MyHandler) as httpd:
logging.info(f"Serving on port {port}")
httpd.serve_forever()
except KeyboardInterrupt:
pass
server.start()
if __name__ == "__main__":