diff --git a/src/server.py b/src/server.py index 7b7c40f..c21b47a 100755 --- a/src/server.py +++ b/src/server.py @@ -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__":