feat(ingest): db-only library ingest and telegram manual ingest
This commit is contained in:
1 parent
d2adb65e08
commit
62abbd7ea1
6 files changed
+866
-28
No files matched your search
@@ -24,6 +24,17 @@ class UpsertOutcome:
|
||||
moved_folder: bool
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class IngestOutcome:
|
||||
"""入库(候选确认或手动)结果。"""
|
||||
|
||||
aid: int
|
||||
status: str
|
||||
previous_status: str | None
|
||||
created: bool
|
||||
recovered: bool
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class FolderRow:
|
||||
media_id: int
|
||||
@@ -399,6 +410,84 @@ class Repository:
|
||||
return [dict(row) for row in rows]
|
||||
return self.db.read(run)
|
||||
|
||||
def ingest_video(
|
||||
self,
|
||||
*,
|
||||
aid: int,
|
||||
bvid: str | None,
|
||||
title: str,
|
||||
up_mid: int | None,
|
||||
up_name: str | None,
|
||||
pubdate: int,
|
||||
duration: int | None = None,
|
||||
pages: int | None = None,
|
||||
cover: str | None = None,
|
||||
source: str = "manual",
|
||||
now: int | None = None,
|
||||
) -> IngestOutcome:
|
||||
"""把一条视频写入库并置为 ``active``(候选确认 / Telegram 手动入库共用)。
|
||||
|
||||
不写 B 站收藏夹、不设置 ``folder_id``;同时删除同 aid 的候选行。
|
||||
既有的 ``removed`` / ``dropped`` / ``unfaved`` 状态都会被重新激活。
|
||||
"""
|
||||
now = self._now() if now is None else int(now)
|
||||
aid = int(aid)
|
||||
|
||||
def run(conn: sqlite3.Connection) -> IngestOutcome:
|
||||
previous = conn.execute(
|
||||
"SELECT status FROM video WHERE aid = ?", (aid,)
|
||||
).fetchone()
|
||||
previous_status = str(previous["status"]) if previous else None
|
||||
conn.execute(
|
||||
"""
|
||||
INSERT INTO video(aid, bvid, title, up_mid, up_name, pubdate,
|
||||
duration, pages, cover, folder_id, fav_time, status,
|
||||
source, first_seen, last_sync, attr)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, NULL, 'active', ?, ?, ?, 0)
|
||||
ON CONFLICT(aid) DO UPDATE SET
|
||||
bvid = COALESCE(excluded.bvid, video.bvid),
|
||||
title = CASE
|
||||
WHEN excluded.title != '' THEN excluded.title
|
||||
ELSE video.title
|
||||
END,
|
||||
up_mid = COALESCE(excluded.up_mid, video.up_mid),
|
||||
up_name = COALESCE(excluded.up_name, video.up_name),
|
||||
pubdate = CASE
|
||||
WHEN excluded.pubdate > 0 THEN excluded.pubdate
|
||||
ELSE video.pubdate
|
||||
END,
|
||||
duration = COALESCE(excluded.duration, video.duration),
|
||||
pages = COALESCE(excluded.pages, video.pages),
|
||||
cover = COALESCE(excluded.cover, video.cover),
|
||||
status = 'active',
|
||||
source = COALESCE(video.source, excluded.source),
|
||||
last_sync = excluded.last_sync
|
||||
""",
|
||||
(
|
||||
aid,
|
||||
bvid,
|
||||
title or "(无标题)",
|
||||
up_mid,
|
||||
up_name,
|
||||
int(pubdate or 0),
|
||||
None if duration is None else int(duration),
|
||||
None if pages is None else int(pages),
|
||||
cover,
|
||||
source,
|
||||
now,
|
||||
now,
|
||||
),
|
||||
)
|
||||
conn.execute("DELETE FROM candidate WHERE aid = ?", (aid,))
|
||||
return IngestOutcome(
|
||||
aid=aid,
|
||||
status="active",
|
||||
previous_status=previous_status,
|
||||
created=previous is None,
|
||||
recovered=previous_status in {"removed", "dropped", "unfaved"},
|
||||
)
|
||||
return self.db.write(run)
|
||||
|
||||
# ------------------------------------------------------- up profile
|
||||
|
||||
def apply_up_follower(
|
||||
|
||||
Reference in new issue
Block a user