mirror of
https://github.com/amtoaer/bili-sync.git
synced 2026-09-05 07:28:04 +08:00
feat: 加入状态字段标记不可见和已失效视频,标记后不做重复处理
This commit is contained in:
+4
-1
@@ -5,4 +5,7 @@ videos
|
|||||||
config.test.json
|
config.test.json
|
||||||
database.test.db*
|
database.test.db*
|
||||||
example.json
|
example.json
|
||||||
thumbs.test
|
thumbs.test
|
||||||
|
config
|
||||||
|
data
|
||||||
|
thumb
|
||||||
@@ -30,6 +30,20 @@ class MediaType(IntEnum):
|
|||||||
VIDEO_COLLECTION = 21
|
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 = {
|
TORTOISE_ORM = {
|
||||||
"connections": {"default": f"sqlite://{DEFAULT_DATABASE_PATH}"},
|
"connections": {"default": f"sqlite://{DEFAULT_DATABASE_PATH}"},
|
||||||
"apps": {
|
"apps": {
|
||||||
|
|||||||
@@ -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";"""
|
||||||
@@ -9,6 +9,7 @@ from constants import (
|
|||||||
DEFAULT_THUMB_PATH,
|
DEFAULT_THUMB_PATH,
|
||||||
MIGRATE_COMMAND,
|
MIGRATE_COMMAND,
|
||||||
TORTOISE_ORM,
|
TORTOISE_ORM,
|
||||||
|
MediaStatus,
|
||||||
MediaType,
|
MediaType,
|
||||||
)
|
)
|
||||||
from settings import settings
|
from settings import settings
|
||||||
@@ -47,6 +48,9 @@ class FavoriteItem(Model):
|
|||||||
id = fields.IntField(pk=True)
|
id = fields.IntField(pk=True)
|
||||||
name = fields.CharField(max_length=255)
|
name = fields.CharField(max_length=255)
|
||||||
type = fields.IntEnumField(enum_type=MediaType)
|
type = fields.IntEnumField(enum_type=MediaType)
|
||||||
|
status = fields.IntEnumField(
|
||||||
|
enum_type=MediaStatus, default=MediaStatus.NORMAL
|
||||||
|
)
|
||||||
bvid = fields.CharField(max_length=255)
|
bvid = fields.CharField(max_length=255)
|
||||||
desc = fields.TextField()
|
desc = fields.TextField()
|
||||||
cover = fields.TextField()
|
cover = fields.TextField()
|
||||||
|
|||||||
+27
-3
@@ -7,10 +7,11 @@ from pathlib import Path
|
|||||||
import aiofiles
|
import aiofiles
|
||||||
import httpx
|
import httpx
|
||||||
from bilibili_api import HEADERS, favorite_list, video
|
from bilibili_api import HEADERS, favorite_list, video
|
||||||
|
from bilibili_api.exceptions import ResponseCodeException
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
from tortoise import Tortoise
|
from tortoise import Tortoise
|
||||||
|
|
||||||
from constants import FFMPEG_COMMAND, MediaType
|
from constants import FFMPEG_COMMAND, MediaStatus, MediaType
|
||||||
from credential import credential
|
from credential import credential
|
||||||
from models import FavoriteItem, FavoriteList, Upper
|
from models import FavoriteItem, FavoriteList, Upper
|
||||||
from nfo import Actor, EpisodeInfo
|
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"]):
|
if not (continue_flag and favorite_video_list["has_more"]):
|
||||||
break
|
break
|
||||||
all_unprocessed_items = await FavoriteItem.filter(
|
all_unprocessed_items = await FavoriteItem.filter(
|
||||||
favorite_list=fav_list, downloaded=False
|
favorite_list=fav_list, status=MediaStatus.NORMAL, downloaded=False
|
||||||
).prefetch_related("upper")
|
).prefetch_related("upper")
|
||||||
await asyncio.gather(
|
await asyncio.gather(
|
||||||
*[process_video(item) for item in all_unprocessed_items],
|
*[process_video(item) for item in all_unprocessed_items],
|
||||||
@@ -240,5 +241,28 @@ async def process_video(fav_item: FavoriteItem) -> None:
|
|||||||
logger.info(
|
logger.info(
|
||||||
"{} {} processed successfully.", fav_item.bvid, fav_item.name
|
"{} {} 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:
|
except Exception:
|
||||||
logger.exception("Failed to process video {}", fav_item.name)
|
logger.exception(
|
||||||
|
"Failed to process video {} {}", fav_item.bvid, fav_item.name
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user