feat: 加入状态字段标记不可见和已失效视频,标记后不做重复处理

This commit is contained in:
amtoaer
2023-11-25 13:13:51 +08:00
parent be6b8eaa89
commit 5629dcce69
5 changed files with 60 additions and 4 deletions

5
.gitignore vendored
View File

@@ -5,4 +5,7 @@ videos
config.test.json
database.test.db*
example.json
thumbs.test
thumbs.test
config
data
thumb

View File

@@ -30,6 +30,20 @@ class MediaType(IntEnum):
VIDEO_COLLECTION = 21
class MediaStatus(IntEnum):
NORMAL = 1 # 正常稿件
INVISIBLE = 2 # 不可见稿件
DELETED = 3 # 已失效视频
@property
def text(self) -> str:
return {
MediaStatus.NORMAL: "normal",
MediaStatus.INVISIBLE: "invisible",
MediaStatus.DELETED: "deleted",
}[self]
TORTOISE_ORM = {
"connections": {"default": f"sqlite://{DEFAULT_DATABASE_PATH}"},
"apps": {

View File

@@ -0,0 +1,11 @@
from tortoise import BaseDBAsyncClient
async def upgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "favoriteitem" ADD "status" SMALLINT NOT NULL DEFAULT 1 /* NORMAL: 1\nINVISIBLE: 2\nDELETED: 3 */;"""
async def downgrade(db: BaseDBAsyncClient) -> str:
return """
ALTER TABLE "favoriteitem" DROP COLUMN "status";"""

View File

@@ -9,6 +9,7 @@ from constants import (
DEFAULT_THUMB_PATH,
MIGRATE_COMMAND,
TORTOISE_ORM,
MediaStatus,
MediaType,
)
from settings import settings
@@ -47,6 +48,9 @@ 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
)
bvid = fields.CharField(max_length=255)
desc = fields.TextField()
cover = fields.TextField()

View File

@@ -7,10 +7,11 @@ from pathlib import Path
import aiofiles
import httpx
from bilibili_api import HEADERS, favorite_list, video
from bilibili_api.exceptions import ResponseCodeException
from loguru import logger
from tortoise import Tortoise
from constants import FFMPEG_COMMAND, MediaType
from constants import FFMPEG_COMMAND, MediaStatus, MediaType
from credential import credential
from models import FavoriteItem, FavoriteList, Upper
from nfo import Actor, EpisodeInfo
@@ -154,7 +155,7 @@ async def process_favorite(favorite_id: int) -> None:
if not (continue_flag and favorite_video_list["has_more"]):
break
all_unprocessed_items = await FavoriteItem.filter(
favorite_list=fav_list, downloaded=False
favorite_list=fav_list, status=MediaStatus.NORMAL, downloaded=False
).prefetch_related("upper")
await asyncio.gather(
*[process_video(item) for item in all_unprocessed_items],
@@ -240,5 +241,28 @@ async def process_video(fav_item: FavoriteItem) -> None:
logger.info(
"{} {} processed successfully.", fav_item.bvid, fav_item.name
)
except ResponseCodeException as e:
match e.code:
case 62002:
fav_item.status = MediaStatus.INVISIBLE
case -404:
fav_item.status = MediaStatus.DELETED
case _:
logger.exception(
"Failed to process video {} {}, error_code: {}",
fav_item.bvid,
fav_item.name,
e.code,
)
return
await fav_item.save()
logger.error(
"Video {} {} is not available, marked as {}",
fav_item.bvid,
fav_item.name,
fav_item.status.text,
)
except Exception:
logger.exception("Failed to process video {}", fav_item.name)
logger.exception(
"Failed to process video {} {}", fav_item.bvid, fav_item.name
)