From 9204bbb4ad7cfc738e467cd1e3cdce891a46e676 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=B4=80=E1=B4=8D=E1=B4=9B=E1=B4=8F=E1=B4=80=E1=B4=87?= =?UTF-8?q?=CA=80?= Date: Sat, 20 Jan 2024 15:37:43 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E9=A1=B9=E6=B2=A1=E6=9C=89=E5=86=99=E5=85=A5?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=8C=E6=89=A9=E5=85=85=E5=8D=95=E8=A1=8C=E5=AD=97=E7=AC=A6?= =?UTF-8?q?=E9=99=90=E5=88=B6=20(#33)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- entry.py | 4 +--- models.py | 46 ++++++++++------------------------------------ processor.py | 38 ++++++++++---------------------------- pyproject.toml | 4 ++-- settings.py | 9 +++++---- 5 files changed, 28 insertions(+), 73 deletions(-) diff --git a/entry.py b/entry.py index 0d41e9d..0b0481e 100644 --- a/entry.py +++ b/entry.py @@ -48,9 +48,7 @@ async def entry() -> None: if __name__ == "__main__": # 确保 docker 退出时正确触发资源释放 - signal.signal( - signal.SIGTERM, lambda *_: os.kill(os.getpid(), signal.SIGINT) - ) + signal.signal(signal.SIGTERM, lambda *_: os.kill(os.getpid(), signal.SIGINT)) with asyncio.Runner() as runner: try: runner.run(entry()) diff --git a/models.py b/models.py index 26cddc8..77ce2e9 100644 --- a/models.py +++ b/models.py @@ -41,15 +41,11 @@ class Upper(Model): @property def thumb_path(self) -> Path: - return ( - DEFAULT_THUMB_PATH / str(self.mid)[0] / f"{self.mid}" / "folder.jpg" - ) + return DEFAULT_THUMB_PATH / str(self.mid)[0] / f"{self.mid}" / "folder.jpg" @property def meta_path(self) -> Path: - return ( - DEFAULT_THUMB_PATH / str(self.mid)[0] / f"{self.mid}" / "person.nfo" - ) + return DEFAULT_THUMB_PATH / str(self.mid)[0] / f"{self.mid}" / "person.nfo" async def save_metadata(self): async with aopen(self.meta_path, "w") as f: @@ -74,16 +70,12 @@ class FavoriteItem(Model): id = fields.IntField(pk=True) name = fields.CharField(max_length=255) type = fields.IntEnumField(enum_type=MediaType) - status = fields.IntEnumField( - enum_type=MediaStatus, default=MediaStatus.NORMAL - ) + status = fields.IntEnumField(enum_type=MediaStatus, default=MediaStatus.NORMAL) bvid = fields.CharField(max_length=255) desc = fields.TextField() cover = fields.TextField() tags = fields.JSONField(null=True) - favorite_list = fields.ForeignKeyField( - "models.FavoriteList", related_name="items" - ) + favorite_list = fields.ForeignKeyField("models.FavoriteList", related_name="items") upper = fields.ForeignKeyField("models.Upper", related_name="uploads") ctime = fields.DatetimeField() pubtime = fields.DatetimeField() @@ -101,38 +93,23 @@ def safe_name(self) -> str: @property def tmp_video_path(self) -> Path: - return ( - Path(settings.path_mapper[self.favorite_list_id]) - / f"tmp_{self.bvid}_video" - ) + return Path(settings.path_mapper[self.favorite_list_id]) / f"tmp_{self.bvid}_video" @property def tmp_audio_path(self) -> Path: - return ( - Path(settings.path_mapper[self.favorite_list_id]) - / f"tmp_{self.bvid}_audio" - ) + return Path(settings.path_mapper[self.favorite_list_id]) / f"tmp_{self.bvid}_audio" @property def video_path(self) -> Path: - return ( - Path(settings.path_mapper[self.favorite_list_id]) - / f"{self.bvid}.mp4" - ) + return Path(settings.path_mapper[self.favorite_list_id]) / f"{self.bvid}.mp4" @property def nfo_path(self) -> Path: - return ( - Path(settings.path_mapper[self.favorite_list_id]) - / f"{self.bvid}.nfo" - ) + return Path(settings.path_mapper[self.favorite_list_id]) / f"{self.bvid}.nfo" @property def poster_path(self) -> Path: - return ( - Path(settings.path_mapper[self.favorite_list_id]) - / f"{self.bvid}-poster.jpg" - ) + return Path(settings.path_mapper[self.favorite_list_id]) / f"{self.bvid}-poster.jpg" @property def upper_path(self) -> list[Path]: @@ -143,10 +120,7 @@ def upper_path(self) -> list[Path]: @property def subtitle_path(self) -> Path: - return ( - Path(settings.path_mapper[self.favorite_list_id]) - / f"{self.bvid}.zh-CN.default.ass" - ) + return Path(settings.path_mapper[self.favorite_list_id]) / f"{self.bvid}.zh-CN.default.ass" class Program(Model): diff --git a/processor.py b/processor.py index b88eae7..9cd11a6 100644 --- a/processor.py +++ b/processor.py @@ -45,9 +45,7 @@ async def manage_model(medias: list[dict], fav_list: FavoriteList) -> None: ) for media in medias ] - await Upper.bulk_create( - uppers, on_conflict=["mid"], update_fields=["name", "thumb"] - ) + await Upper.bulk_create(uppers, on_conflict=["mid"], update_fields=["name", "thumb"]) items = [ FavoriteItem( name=media["title"], @@ -114,10 +112,8 @@ async def process_favorite(favorite_id: int) -> None: while True: page += 1 if page > 1: - favorite_video_list = ( - await favorite_list.get_video_favorite_list_content( - favorite_id, page=page, credential=credential - ) + favorite_video_list = await favorite_list.get_video_favorite_list_content( + favorite_id, page=page, credential=credential ) # 先看看对应 bvid 的记录是否存在 existed_items = await FavoriteItem.filter( @@ -125,14 +121,10 @@ async def process_favorite(favorite_id: int) -> None: bvid__in=[media["bvid"] for media in favorite_video_list["medias"]], ) # 记录一下获得的列表中的 bvid 和 fav_time - media_info = { - (media["bvid"], media["fav_time"]) - for media in favorite_video_list["medias"] - } + media_info = {(media["bvid"], media["fav_time"]) for media in favorite_video_list["medias"]} # 如果有 bvid 和 fav_time 都相同的记录,说明已经到达了上次处理到的位置 continue_flag = not media_info & { - (item.bvid, int(item.fav_time.timestamp())) - for item in existed_items + (item.bvid, int(item.fav_time.timestamp())) for item in existed_items } await manage_model(favorite_video_list["medias"], fav_list) if not (continue_flag and favorite_video_list["has_more"]): @@ -186,9 +178,7 @@ async def process_favorite_item( await amakedirs(fav_item.upper.thumb_path.parent, exist_ok=True) await asyncio.gather( fav_item.upper.save_metadata(), - download_content( - fav_item.upper.thumb, fav_item.upper.thumb_path - ), + download_content(fav_item.upper.thumb, fav_item.upper.thumb_path), return_exceptions=True, ) else: @@ -299,9 +289,7 @@ async def process_favorite_item( ) streams = detector.detect_best_streams(codecs=settings.codec) if detector.check_flv_stream(): - await download_content( - streams[0].url, fav_item.tmp_video_path - ) + await download_content(streams[0].url, fav_item.tmp_video_path) process = await create_subprocess_exec( FFMPEG_COMMAND, "-i", @@ -314,12 +302,8 @@ async def process_favorite_item( fav_item.tmp_video_path.unlink() else: await asyncio.gather( - download_content( - streams[0].url, fav_item.tmp_video_path - ), - download_content( - streams[1].url, fav_item.tmp_audio_path - ), + download_content(streams[0].url, fav_item.tmp_video_path), + download_content(streams[1].url, fav_item.tmp_audio_path), ) process = await create_subprocess_exec( FFMPEG_COMMAND, @@ -358,9 +342,7 @@ async def process_favorite_item( fav_item.status.text, ) except Exception: - logger.exception( - "Failed to process video {} {}", fav_item.bvid, fav_item.name - ) + logger.exception("Failed to process video {} {}", fav_item.bvid, fav_item.name) await fav_item.save() logger.info( "{} {} is processed successfully.", diff --git a/pyproject.toml b/pyproject.toml index b817838..7fddf9c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,10 +24,10 @@ ipython = "8.17.2" ruff = "0.1.6" [tool.black] -line-length = 80 +line-length = 100 [tool.ruff] -line-length = 80 +line-length = 100 select = [ "F", # https://beta.ruff.rs/docs/rules/#pyflakes-f "E", diff --git a/settings.py b/settings.py index 0d786b0..f06540c 100644 --- a/settings.py +++ b/settings.py @@ -1,5 +1,4 @@ from pathlib import Path -from typing import Self from bilibili_api.video import VideoCodecs from pydantic import BaseModel, Field, field_validator @@ -42,7 +41,7 @@ def codec_validator(cls, codecs: list[VideoCodecs]) -> list[VideoCodecs]: return codecs @staticmethod - def load(path: Path | None = None) -> Self: + def load(path: Path | None = None) -> "Config": if not path: path = DEFAULT_CONFIG_PATH try: @@ -51,7 +50,7 @@ def load(path: Path | None = None) -> Self: except Exception as e: raise RuntimeError(f"Failed to load config file: {path}") from e - def save(self, path: Path | None = None) -> Self: + def save(self, path: Path | None = None) -> "Config": if not path: path = DEFAULT_CONFIG_PATH try: @@ -65,8 +64,10 @@ def save(self, path: Path | None = None) -> Self: def init_settings() -> Config: if not DEFAULT_CONFIG_PATH.exists(): + # 配置文件不存在的情况下,写入空的默认值 Config().save(DEFAULT_CONFIG_PATH) - return Config.load(DEFAULT_CONFIG_PATH) + # 读取配置文件,校验出错会抛出异常,校验通过则重新保存一下配置文件(写入新配置项的默认值) + return Config.load(DEFAULT_CONFIG_PATH).save() settings = init_settings()