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 #!/usr/bin/env python3
from __future__ import annotations
import argparse import argparse
import json import json
import logging import logging
@ -7,9 +9,14 @@ import os
import socketserver import socketserver
from http import HTTPStatus from http import HTTPStatus
from http.server import SimpleHTTPRequestHandler from http.server import SimpleHTTPRequestHandler
import time
from typing import Optional from typing import Optional
from urllib.parse import parse_qs, unquote, urlparse 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 # https://stackoverflow.com/a/10551190/11109181
class EnvDefault(argparse.Action): class EnvDefault(argparse.Action):
@ -32,17 +39,20 @@ class EnvDefault(argparse.Action):
setattr(namespace, self.dest, values) setattr(namespace, self.dest, values)
class MyHandler(SimpleHTTPRequestHandler): class HTTPHandler(SimpleHTTPRequestHandler):
MAX_PAYLOAD_SIZE = 1e6 SERVER: MeliesServer = None
DATA_DIR = "metadata"
CACHE = {} CACHE = {}
def __init__(self, *args, **kwargs): 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__( super().__init__(
*args, *args,
directory=os.path.join(os.path.dirname(__file__), "public"), directory=os.path.join(os.path.dirname(__file__), "public"),
**kwargs **kwargs
) )
self.query: dict = {} self.query: dict = {}
self.data: Optional[dict|list] = None self.data: Optional[dict|list] = None
@ -178,6 +188,66 @@ class MyHandler(SimpleHTTPRequestHandler):
self.CACHE[filename] = meta 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(): def main():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Starts the Melies server", description="Starts the Melies server",
@ -199,6 +269,20 @@ def main():
type=int, type=int,
help="Maximum POST payload size in bytes that the server accepts" 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( parser.add_argument(
"--metadata-dir", "--metadata-dir",
action=EnvDefault, action=EnvDefault,
@ -208,26 +292,14 @@ def main():
) )
args = parser.parse_args() args = parser.parse_args()
server = MeliesServer(
port = args.port args.port,
MyHandler.MAX_PAYLOAD_SIZE = args.max_payload_size args.to_convert_dir,
MyHandler.DATA_DIR = args.metadata_dir args.converted_dir,
args.metadata_dir,
if not os.path.exists(args.metadata_dir): args.max_payload_size
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.start()
try:
with socketserver.TCPServer(("", port), MyHandler) as httpd:
logging.info(f"Serving on port {port}")
httpd.serve_forever()
except KeyboardInterrupt:
pass
if __name__ == "__main__": if __name__ == "__main__":