Refactor new program class

This commit is contained in:
EstrellaXD
2023-05-17 20:41:07 +08:00
parent bba98f43bb
commit 0bc25fe00b
17 changed files with 232 additions and 134 deletions

View File

@@ -4,8 +4,7 @@ import uvicorn
from module.api import router
from module.conf import settings, setup_logger
log_level = logging.DEBUG if settings.log.debug_enable else logging.INFO
setup_logger(log_level, reset=True)
setup_logger(reset=True)
logger = logging.getLogger(__name__)
uvicorn_logging_config = {
"version": 1,
@@ -13,7 +12,7 @@ uvicorn_logging_config = {
"handlers": logger.handlers,
"loggers": {
"uvicorn": {
"level": log_level,
"level": logger.level,
},
"uvicorn.access": {
"level": "WARNING",

View File

@@ -2,46 +2,58 @@ import os
import signal
import logging
from fastapi.exceptions import HTTPException
from .download import router
from module.core import start_thread, start_program, stop_thread, stop_event, check_status, check_rss, check_downloader
from module.core import Program, check_status, check_rss, check_downloader
logger = logging.getLogger(__name__)
program = Program()
@router.on_event("startup")
async def startup():
await start_program()
await program.startup()
@router.on_event("shutdown")
async def shutdown():
stop_event.set()
await program.stop()
logger.info("Stopping program...")
@router.get("/api/v1/restart", tags=["program"])
async def restart():
stop_thread()
start_thread()
return {"status": "ok"}
try:
await program.restart()
return {"status": "ok"}
except Exception as e:
logger.debug(e)
logger.warning("Failed to restart program")
raise HTTPException(status_code=500, detail="Failed to restart program")
@router.get("/api/v1/start", tags=["program"])
async def start():
start_thread()
return {"status": "ok"}
try:
await program.start()
return {"status": "ok"}
except Exception as e:
logger.debug(e)
logger.warning("Failed to start program")
raise HTTPException(status_code=500, detail="Failed to start program")
@router.get("/api/v1/stop", tags=["program"])
async def stop():
stop_thread()
await program.stop()
return {"status": "ok"}
@router.get("/api/v1/status", tags=["program"])
async def status():
if stop_event.is_set():
if not program.is_running:
return {"status": "stop"}
else:
return {"status": "running"}
@@ -49,7 +61,7 @@ async def status():
@router.get("/api/v1/shutdown", tags=["program"])
async def shutdown_program():
stop_thread()
await program.stop()
logger.info("Shutting down program...")
os.kill(os.getpid(), signal.SIGINT)
return {"status": "ok"}

View File

@@ -0,0 +1 @@
from .checker import Checker

View File

@@ -0,0 +1,49 @@
import os.path
from module.downloader import DownloadClient
from module.network import RequestContent
from module.conf import settings, DATA_PATH
class Checker:
def __init__(self):
pass
def check_renamer(self) -> bool:
if self.check_downloader() and\
settings.bangumi_manage.enable:
return True
else:
return False
def check_analyser(self) -> bool:
if self.check_torrents() and\
self.check_downloader() and\
settings.rss_parser.enable:
return True
else:
return False
@staticmethod
def check_downloader() -> bool:
with DownloadClient() as client:
if client.authed:
return True
else:
return False
@staticmethod
def check_torrents() -> bool:
with RequestContent() as req:
torrents = req.get_torrents(settings.rss_link)
if torrents:
return True
else:
return False
@staticmethod
def check_first_run() -> bool:
if os.path.exists(DATA_PATH):
return False
else:
return True

View File

@@ -49,7 +49,8 @@ class Settings(Config):
with open(CONFIG_PATH, "w", encoding="utf-8") as f:
json.dump(config_dict, f, indent=4)
def rss_link(self):
@property
def rss_link(self) -> str:
if "://" not in self.rss_parser.custom_url:
return f"https://{self.rss_parser.custom_url}/RSS/MyBangumi?token={self.rss_parser.token}"
return (

View File

@@ -1,10 +1,12 @@
import os
import logging
from .config import settings
LOG_PATH = "data/log.txt"
def setup_logger(level: int = logging.INFO, reset: bool = False):
level = logging.DEBUG if settings.log.debug_enable else level
if not os.path.isdir("data"):
os.mkdir("data")
if reset and os.path.isfile(LOG_PATH):

View File

@@ -1,2 +1,2 @@
from .sub_thread import *
from .program import Program
from .check import check_status, check_rss, check_downloader

View File

@@ -0,0 +1,48 @@
import logging
from .sub_thread import RenameThread, RSSThread
from module.conf import settings, VERSION
logger = logging.getLogger(__name__)
class Program(RenameThread, RSSThread):
@staticmethod
def __start_info():
with open("icon", "r") as f:
for line in f.readlines():
logger.info(line.strip("\n"))
logger.info(
f"Version {VERSION} Author: EstrellaXD Twitter: https://twitter.com/Estrella_Pan"
)
logger.info("GitHub: https://github.com/EstrellaXD/Auto_Bangumi/")
logger.info("Starting AutoBangumi...")
async def startup(self):
self.__start_info()
await self.start()
async def start(self):
self.stop_event.clear()
settings.load()
if self.enable_renamer:
self.rename_start()
logger.info("Renamer started.")
if self.enable_rss:
self.rss_start()
logger.info("RSS started.")
return {"status": "Program started."}
async def stop(self):
if self.is_running:
self.stop_event.set()
self.rename_stop()
self.rss_stop()
else:
return {"status": "Program is not running."}
async def restart(self):
await self.stop()
await self.start()
return {"status": "Program restarted."}

View File

44
src/module/core/status.py Normal file
View File

@@ -0,0 +1,44 @@
import threading
from module.checker import Checker
class ProgramStatus(Checker):
def __init__(self):
super().__init__()
self.stop_event = threading.Event()
self.lock = threading.Lock()
self._downloader_status = False
self._torrents_status = False
@property
def is_running(self):
return not self.stop_event.is_set()
@property
def is_stopped(self):
return self.stop_event.is_set()
@property
def downloader_status(self):
if not self._downloader_status:
self._downloader_status = self.check_downloader()
return self._downloader_status
@property
def torrents_status(self):
if not self._torrents_status:
self._torrents_status = self.check_torrents()
return self._torrents_status
@property
def enable_rss(self):
return self.check_analyser()
@property
def enable_renamer(self):
return self.check_renamer()
@property
def first_run(self):
return self.check_first_run()

View File

@@ -1,118 +1,69 @@
import os.path
import time
import logging
import threading
from .data_migration import data_migration
from .check import check_status
from .status import ProgramStatus
from module.rss import RSSAnalyser, add_rules
from module.manager import Renamer, FullSeasonGet
from module.database import BangumiDatabase
from module.downloader import DownloadClient
from module.conf import settings, VERSION, DATA_PATH
logger = logging.getLogger(__name__)
stop_event = threading.Event()
from module.conf import settings
def rss_loop(stop_event):
rss_analyser = RSSAnalyser()
rss_link = settings.rss_link()
while not stop_event.is_set():
rss_analyser.run(rss_link)
add_rules()
if settings.bangumi_manage.eps_complete:
with FullSeasonGet() as full_season_get:
full_season_get.eps_complete()
stop_event.wait(settings.program.rss_time)
class RSSThread(ProgramStatus):
def __init__(self):
super().__init__()
self._rss_thread = threading.Thread(
target=self.rss_loop,
)
def rss_loop(self):
rss_analyser = RSSAnalyser()
while not self.stop_event.is_set():
rss_analyser.run()
add_rules()
if settings.bangumi_manage.eps_complete:
with FullSeasonGet() as full_season_get:
full_season_get.eps_complete()
self.stop_event.wait(settings.program.rss_time)
def rss_start(self):
self.rss_thread.start()
def rss_stop(self):
if self._rss_thread.is_alive():
self._rss_thread.join()
@property
def rss_thread(self):
if not self._rss_thread.is_alive():
self._rss_thread = threading.Thread(
target=self.rss_loop,
)
return self._rss_thread
def rename_loop(stop_event):
while not stop_event.is_set():
with Renamer() as renamer:
renamer.rename()
stop_event.wait(settings.program.rename_time)
class RenameThread(ProgramStatus):
def __init__(self):
super().__init__()
self._rename_thread = threading.Thread(
target=self.rename_loop,
)
def rename_loop(self):
while not self.stop_event.is_set():
with Renamer() as renamer:
renamer.rename()
self.stop_event.wait(settings.program.rename_time)
rss_thread = threading.Thread(
target=rss_loop,
args=(stop_event,),
)
rename_thread = threading.Thread(
target=rename_loop,
args=(stop_event,),
)
def start_info():
with open("icon", "r") as f:
for line in f.readlines():
logger.info(line.strip("\n"))
logger.info(
f"Version {VERSION} Author: EstrellaXD Twitter: https://twitter.com/Estrella_Pan"
)
logger.info("GitHub: https://github.com/EstrellaXD/Auto_Bangumi/")
logger.info("Starting AutoBangumi...")
def stop_thread():
global rss_thread, rename_thread
if not stop_event.is_set():
stop_event.set()
rename_thread.join()
rss_thread.join()
def start_thread():
global rss_thread, rename_thread
if stop_event.is_set():
time.sleep(1)
settings.load()
stop_event.clear()
else:
return {"status": "Program is running."}
if not check_status():
stop_event.set()
logger.info("Program paused.")
return {"status": "start failed"}
rss_thread = threading.Thread(target=rss_loop, args=(stop_event,))
rename_thread = threading.Thread(target=rename_loop, args=(stop_event,))
if settings.rss_parser.enable:
rss_thread.start()
if settings.bangumi_manage.enable:
rename_thread.start()
return {"status": "Restart successfully."}
def first_run():
if not os.path.exists(DATA_PATH):
if data_migration():
logger.info("Updated, data migration completed.")
else:
logger.info("First run, init downloader.")
with DownloadClient() as client:
client.init_downloader()
client.add_rss_feed(settings.rss_link())
async def start_program():
global rss_thread, rename_thread
start_info()
if not check_status():
stop_event.set()
logger.info("Program paused.")
else:
first_run()
with BangumiDatabase() as database:
database.update_table()
rss_thread = threading.Thread(target=rss_loop, args=(stop_event,))
rename_thread = threading.Thread(target=rename_loop, args=(stop_event,))
if settings.rss_parser.enable:
rss_thread.start()
if settings.bangumi_manage.enable:
rename_thread.start()
def rename_start(self):
self.rename_thread.start()
def rename_stop(self):
if self._rename_thread.is_alive():
self._rename_thread.join()
@property
def rename_thread(self):
if not self._rename_thread.is_alive():
self._rename_thread = threading.Thread(
target=self.rename_loop,
)
return self._rename_thread

View File

@@ -1 +0,0 @@
from .inspector import Inspector

View File

@@ -1,10 +0,0 @@
class Inspector:
def __init__(self):
pass
def check_downloader(self) -> bool:
pass
def check_link(self, url) -> bool:
pass

View File

@@ -193,6 +193,7 @@ class Renamer(DownloadClient):
def rename(self):
# Get torrent info
logger.debug("Start rename process.")
download_path = settings.downloader.path
rename_method = settings.bangumi_manage.rename_method
recent_info, torrent_count = self.rename_info()
@@ -237,3 +238,4 @@ class Renamer(DownloadClient):
)
else:
logger.warning(f"{info.name} has no media file")
logger.debug("Rename process finished.")

View File

@@ -67,7 +67,7 @@ class RSSAnalyser:
database.insert_list(new_data)
return new_data
def run(self, rss_link: str):
def run(self, rss_link: str = settings.rss_link):
logger.info("Start collecting RSS info.")
try:
self.rss_to_data(rss_link)

View File