From de6eaeb4a6828bd10d24d326d31b5d8e1d7ff43f Mon Sep 17 00:00:00 2001 From: amtoaer Date: Tue, 5 Dec 2023 23:59:46 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E6=95=B4=E7=90=86=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E9=80=BB=E8=BE=91=EF=BC=8C=E7=95=99=E5=87=BA=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E5=AD=97=E5=B9=95=E7=9A=84=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 10 ++++-- commands.py | 92 +++++++++++++++++++++++++++++----------------------- entry.py | 20 +++++++++--- models.py | 14 ++++++++ processor.py | 18 ++++++++-- 5 files changed, 104 insertions(+), 50 deletions(-) diff --git a/Makefile b/Makefile index 0731ade..4ea96bd 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: install fmt start-daemon start-once +.PHONY: install fmt start-daemon start-once db-init db-migrate db-upgrade sync-conf install: @echo "Installing dependencies..." @@ -22,4 +22,10 @@ db-migrate: @poetry run aerich migrate db-upgrade: - @poetry run aerich upgrade \ No newline at end of file + @poetry run aerich upgrade + +sync-conf: + @echo "Syncing config..." + @cp ${CONFIG_SRC} ./config/ + @cp ${DB_SRC} ./data/ + @echo "Done." \ No newline at end of file diff --git a/commands.py b/commands.py index d0c688c..4a14fa8 100644 --- a/commands.py +++ b/commands.py @@ -1,11 +1,14 @@ import asyncio +import functools +from pathlib import Path +from typing import Callable from loguru import logger from constants import MediaStatus, MediaType -from models import FavoriteItem, Upper -from processor import download_content, process_video -from utils import aexists, amakedirs, aremove +from models import FavoriteItem +from processor import process_favorite_item +from utils import aexists, aremove async def recheck(): @@ -37,52 +40,59 @@ async def recheck(): logger.info("Database updated.") -async def upper_thumb(): - """将up主的头像批量写入数据库,从不支持up主头像的版本升级上来后需要手动调用一次""" - makedir_tasks = [] - other_tasks = [] - for upper in await Upper.all(): - if all( - await asyncio.gather( - aexists(upper.thumb_path), aexists(upper.meta_path) - ) - ): - logger.info( - "Upper {} {} already exists, skipped.", upper.mid, upper.name - ) - makedir_tasks.append(amakedirs(upper.thumb_path.parent, exist_ok=True)) - logger.info("Saving metadata for upper {} {}...", upper.mid, upper.name) - other_tasks.extend( - [ - upper.save_metadata(), - download_content(upper.thumb, upper.thumb_path), - ] - ) - await asyncio.gather(*makedir_tasks) - await asyncio.gather(*other_tasks) - logger.info("All done.") - - -async def refresh_tags(): - """刷新已存在的视频的标签,从不支持标签的版本升级上来后需要手动调用一次""" - items = await FavoriteItem.filter( - downloaded=True, - tags=None, - ).prefetch_related("upper") +async def _refresh_favorite_item_info( + path_getter: Callable[[FavoriteItem], list[Path]], + process_poster: bool = False, + process_video: bool = False, + process_nfo: bool = False, + process_upper: bool = False, + process_subtitle: bool = False, +): + items = await FavoriteItem.filter(downloaded=True).prefetch_related("upper") await asyncio.gather( - *[aremove(item.nfo_path) for item in items], + *[aremove(path) for item in items for path in path_getter(item)], return_exceptions=True, ) await asyncio.gather( *[ - process_video( + process_favorite_item( item, - process_poster=False, - process_video=False, - process_nfo=True, - process_upper=False, + process_poster=process_poster, + process_video=process_video, + process_nfo=process_nfo, + process_upper=process_upper, + process_subtitle=process_subtitle, ) for item in items ], return_exceptions=True, ) + + +refresh_nfo = functools.partial( + _refresh_favorite_item_info, lambda item: [item.nfo_path], process_nfo=True +) + +refresh_poster = functools.partial( + _refresh_favorite_item_info, + lambda item: [item.poster_path], + process_poster=True, +) + +refresh_video = functools.partial( + _refresh_favorite_item_info, + lambda item: [item.video_path], + process_video=True, +) + +refresh_upper = functools.partial( + _refresh_favorite_item_info, + lambda item: item.upper_path, + process_upper=True, +) + +refresh_subtitle = functools.partial( + _refresh_favorite_item_info, + lambda item: [item.subtitle_path], + process_subtitle=True, +) diff --git a/entry.py b/entry.py index 02a4984..5260f50 100644 --- a/entry.py +++ b/entry.py @@ -4,7 +4,14 @@ import uvloop from loguru import logger -from commands import recheck, refresh_tags, upper_thumb +from commands import ( + recheck, + refresh_nfo, + refresh_poster, + refresh_subtitle, + refresh_upper, + refresh_video, +) from models import init_model from processor import cleanup, process from settings import settings @@ -14,12 +21,15 @@ async def entry() -> None: await init_model() - for command, func in [ + for command, func in ( ("once", process), ("recheck", recheck), - ("upper_thumb", upper_thumb), - ("refresh_tags", refresh_tags), - ]: + ("refresh_poster", refresh_poster), + ("refresh_upper", refresh_upper), + ("refresh_nfo", refresh_nfo), + ("refresh_video", refresh_video), + ("refresh_subtitle", refresh_subtitle), + ): if any(command in _ for _ in sys.argv): logger.info("Running {}...", command) await func() diff --git a/models.py b/models.py index 5ea5edc..3fc2070 100644 --- a/models.py +++ b/models.py @@ -133,6 +133,20 @@ def poster_path(self) -> Path: / f"{self.bvid}-poster.jpg" ) + @property + def upper_path(self) -> list[Path]: + return [ + self.upper.thumb_path, + self.upper.meta_path, + ] + + @property + def subtitle_path(self) -> Path: + return ( + Path(settings.path_mapper[self.favorite_list_id]) + / f"{self.bvid}.zh-CN.default.ass" + ) + async def init_model() -> None: await Tortoise.init(config=TORTOISE_ORM) diff --git a/processor.py b/processor.py index 07b1fb0..124674a 100644 --- a/processor.py +++ b/processor.py @@ -149,19 +149,20 @@ async def process_favorite(favorite_id: int) -> None: downloaded=False, ).prefetch_related("upper") await asyncio.gather( - *[process_video(item) for item in all_unprocessed_items], + *[process_favorite_item(item) for item in all_unprocessed_items], return_exceptions=True, ) logger.info("Favorite {} {} processed successfully.", favorite_id, title) @concurrent_decorator(4) -async def process_video( +async def process_favorite_item( fav_item: FavoriteItem, process_poster=True, process_video=True, process_nfo=True, process_upper=True, + process_subtitle=True, ) -> None: logger.info("Start to process video {} {}", fav_item.bvid, fav_item.name) if fav_item.type != MediaType.VIDEO: @@ -234,6 +235,19 @@ async def process_video( fav_item.bvid, fav_item.name, ) + if process_subtitle: + pass + # # 写入字幕,上游库获取字幕有 bug,暂时不做实现 + # if not await aexists(fav_item.subtitle_path): + # await ass.make_ass_file_danmakus_protobuf( + # v, 0, str(fav_item.subtitle_path.resolve()) + # ) + # else: + # logger.info( + # "Subtitle of {} {} already exists, skipped.", + # fav_item.bvid, + # fav_item.name, + # ) if process_video: if await aexists(fav_item.video_path): fav_item.downloaded = True