From f3c2aeded858488bf71ff21e51e9728fa03fca6b Mon Sep 17 00:00:00 2001 From: EstrellaXD Date: Tue, 9 May 2023 23:17:09 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=BA=BF=E7=A8=8B=E5=90=AF?= =?UTF-8?q?=E5=81=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.py | 124 ++++++++++++++++------------- src/module/conf/uvicorn_logging.py | 40 ++++++++++ src/module/core/api_func.py | 8 +- src/module/manager/eps_complete.py | 2 +- 4 files changed, 115 insertions(+), 59 deletions(-) create mode 100644 src/module/conf/uvicorn_logging.py diff --git a/src/main.py b/src/main.py index 6bf4cf1a..857e0d9e 100644 --- a/src/main.py +++ b/src/main.py @@ -1,83 +1,103 @@ -import os -import signal import logging import uvicorn -import multiprocessing +import threading +import time from fastapi import Request from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates -from module import app from module.api import router -from module.conf import VERSION, settings +from module.conf import VERSION, settings, setup_logger +from module.rss import RSSAnalyser +from module.conf.uvicorn_logging import logging_config logger = logging.getLogger(__name__) -main_process = multiprocessing.Process(target=app.run, args=(settings,)) + +stop_event = threading.Event() + +rss_link = settings.rss_link() + + +def rss_loop(stop_event, rss_link: str): + rss_analyser = RSSAnalyser() + while not stop_event.is_set(): + rss_analyser.run(rss_link) + logger.info("RSS loop finished.") + stop_event.wait(settings.program.sleep_time) + + +rss_thread = threading.Thread( + target=rss_loop, + args=(stop_event, rss_link), +) @router.on_event("startup") async def startup(): - global main_process - main_process.start() + global rss_thread + setup_logger() + rss_thread = threading.Thread( + target=rss_loop, + args=(stop_event, rss_link), + ) + rss_thread.start() @router.on_event("shutdown") async def shutdown(): - global main_process - if main_process.is_alive(): - os.kill(main_process.pid, signal.SIGTERM) + stop_event.set() + logger.info("Stopping RSS analyser...") @router.get("/api/v1/restart", tags=["program"]) async def restart(): - global main_process - if main_process.is_alive(): - os.kill(main_process.pid, signal.SIGTERM) - logger.info("Restarting...") - else: - logger.info("Starting...") - settings.reload() - main_process = multiprocessing.Process(target=app.run, args=(settings,)) - main_process.start() - logger.info("Restarted") - return {"status": "success"} - - -@router.get("/api/v1/stop", tags=["program"]) -async def stop(): - global main_process - if not main_process.is_alive(): - return {"status": "failed", "reason": "Already stopped"} - logger.info("Stopping...") - os.kill(main_process.pid, signal.SIGTERM) - logger.info("Stopped") - return {"status": "success"} + global rss_thread + if not rss_thread.is_alive(): + return {"status": "Already stopped."} + stop_event.set() + logger.info("Stopping RSS analyser...") + rss_thread.join() + stop_event.clear() + time.sleep(1) + settings.load() + rss_link = settings.rss_link() + if "://" not in rss_link: + rss_link = f"https://{rss_link}" + rss_thread = threading.Thread( + target=rss_loop, + args=(stop_event, rss_link), + ) + rss_thread.start() + return {"status": "ok"} @router.get("/api/v1/start", tags=["program"]) async def start(): - global main_process - if main_process.is_alive(): - return {"status": "failed", "reason": "Already started"} - logger.info("Starting...") - settings.reload() - main_process = multiprocessing.Process(target=app.run, args=(settings,)) - main_process.start() - logger.info("Started") - return {"status": "success"} + global rss_thread + if rss_thread.is_alive(): + return {"status": "Already started."} + rss_thread = threading.Thread( + target=rss_loop, + args=(stop_event, rss_link), + ) + rss_thread.start() + return {"status": "ok"} -@router.get("/api/v1/status", tags=["program"]) -async def status(): - global main_process - if main_process.is_alive(): - return True - else: - return False +@router.get("/api/v1/stop", tags=["program"]) +async def stop(): + global rss_thread + if not rss_thread.is_alive(): + return {"status": "Already stopped."} + stop_event.set() + logger.info("Stopping RSS analyser...") + rss_thread.join() + stop_event.clear() + return {"status": "ok"} if VERSION != "DEV_VERSION": @@ -98,10 +118,6 @@ else: if __name__ == "__main__": - log_config = uvicorn.config.LOGGING_CONFIG - log_config["formatters"]["default"][ - "fmt" - ] = "[%(asctime)s] %(levelname)-8s %(message)s" uvicorn.run( - router, host="0.0.0.0", port=settings.program.webui_port, log_config=log_config + router, host="0.0.0.0", port=settings.program.webui_port ) diff --git a/src/module/conf/uvicorn_logging.py b/src/module/conf/uvicorn_logging.py new file mode 100644 index 00000000..59f24bb8 --- /dev/null +++ b/src/module/conf/uvicorn_logging.py @@ -0,0 +1,40 @@ +logging_config = { + "version": 1, + "disable_existing_loggers": False, + "loggers": { + "uvicorn.error": { + "level": "INFO", + "handlers": ["default"], + "propagate": True, + }, + "uvicorn.access": { + "level": "INFO", + "handlers": ["access"], + "propagate": True, + }, + }, + "handlers": { + "default": { + "class": "logging.StreamHandler", + "level": "INFO", + "formatter": "default", + "stream": "ext://sys.stderr", + }, + "access": { + "class": "logging.StreamHandler", + "level": "INFO", + "formatter": "access", + "stream": "ext://sys.stdout", + }, + }, + "formatters": { + "default": { + "format": "[%(asctime)s] %(levelname)s: %(message)s", + "datefmt": "%Y-%m-%d %H:%M:%S", + }, + "access": { + "format": "[%(asctime)s] %(levelname)s: %(client_addr)s - \"%(request_line)s\" %(status_code)s", + "datefmt": "%Y-%m-%d %H:%M:%S", + }, + }, +} \ No newline at end of file diff --git a/src/module/core/api_func.py b/src/module/core/api_func.py index 299fd821..0d380f34 100644 --- a/src/module/core/api_func.py +++ b/src/module/core/api_func.py @@ -17,20 +17,20 @@ logger = logging.getLogger(__name__) class APIProcess: def __init__(self, settings: Config): - self._rss_analyser = RSSAnalyser(settings) - self._client = DownloadClient(settings) + self._rss_analyser = RSSAnalyser() + self._client = DownloadClient() self._full_season_get = FullSeasonGet(settings) self._custom_url = settings.rss_parser.custom_url def link_process(self, link): - return self._rss_analyser.rss_to_data(link, _filter=False) + return self._rss_analyser.rss_to_data(link) @api_failed def download_collection(self, link): if not self._client.authed: self._client.auth() data = self.link_process(link) - self._full_season_get.download_collection(data, link, self._client) + self._full_season_get.download_collection(data, link) return data @api_failed diff --git a/src/module/manager/eps_complete.py b/src/module/manager/eps_complete.py index 236b020b..67655262 100644 --- a/src/module/manager/eps_complete.py +++ b/src/module/manager/eps_complete.py @@ -13,7 +13,7 @@ logger = logging.getLogger(__name__) class FullSeasonGet(DownloadClient): def __init__(self, settings: Config): - super().__init__(settings) + super().__init__() self.SEARCH_KEY = [ "group", "title_raw",