init(api): use fastapi

This commit is contained in:
OverflowCat 2023-10-16 16:38:47 +08:00 committed by yzqzss
parent d6f90cf723
commit a123b5903c
9 changed files with 146 additions and 12 deletions

3
.gitignore vendored
View File

@ -7,3 +7,6 @@ videos/
.vscode/settings.json
bilibili_archive_dir/
dist/
.ia_keys.txt
.cookies.txt

View File

@ -1,6 +1,8 @@
# biliarchiver
> 基于 bilix 的 BiliBili 存档工具
> Archiving tool for Bilibili based on bilix
[![PyPI version](https://badge.fury.io/py/biliarchiver.svg)](https://badge.fury.io/py/biliarchiver)
## Install

View File

@ -62,7 +62,7 @@ def check_ia_item_exist(client: Client, identifier: str) -> bool:
raise ValueError(f'Unexpected code: {r_json["code"]}')
def _down(
async def _down(
bvids: str,
skip_ia_check: bool,
from_browser: Optional[str],
@ -77,8 +77,7 @@ def _down(
pypi_project="biliarchiver", self_version=BILI_ARCHIVER_VERSION
)
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop = asyncio.get_event_loop()
d = DownloaderBilibili(
hierarchy=True,
@ -150,9 +149,7 @@ def _down(
continue
if len(tasks) >= config.video_concurrency:
loop.run_until_complete(
asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
)
await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
tasks_check()
print(f"=== {bvid} ({index+1}/{len(bvids_list)}) ===")
@ -164,9 +161,7 @@ def _down(
tasks.append(task)
while len(tasks) > 0:
loop.run_until_complete(
asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
)
await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
tasks_check()
print("DONE")

View File

@ -40,7 +40,9 @@ def down(**kwargs):
from biliarchiver.cli_tools.bili_archive_bvids import _down
try:
_down(**kwargs)
import asyncio
asyncio.run(_down(**kwargs))
except KeyboardInterrupt:
print("KeyboardInterrupt")
finally:

View File

@ -34,7 +34,9 @@ BILIBILI_VIDEOS_SUB_1_COLLECTION = "bilibili_videos_sub_1"
default=False,
help=_("使用 `$storage_home_dir/videos` 目录下的所有视频"),
)
@click.option("--update-existing", is_flag=True, default=False, help=_("更新已存在的 item"))
@click.option(
"--update-existing", "-u", is_flag=True, default=False, help=_("更新已存在的 item")
)
@click.option(
"--collection",
"-c",

View File

@ -0,0 +1,30 @@
from biliarchiver.cli_tools.bili_archive_bvids import _down
from biliarchiver._biliarchiver_upload_bvid import upload_bvid
from biliarchiver.config import config
class BiliVideo:
def __init__(self, bvid) -> None:
if not bvid.startswith("BV"):
bvid = "BV" + bvid
self.bvid = bvid
def __str__(self) -> str:
return self.bvid
async def down(self):
await _down(
bvids=self.bvid,
skip_ia_check=True,
from_browser=None,
min_free_space_gb=1,
skip_to=0,
)
async def up(self):
upload_bvid(
self.bvid,
update_existing=False,
collection="default",
delete_after_upload=False,
)

View File

@ -0,0 +1,68 @@
import asyncio
from asyncio import Queue
from fastapi import FastAPI, BackgroundTasks
from pydantic import BaseModel
from biliarchiver.rest_api.bilivid import BiliVideo
from datetime import datetime
from biliarchiver.version import BILI_ARCHIVER_VERSION
app = FastAPI()
queue = Queue()
class Video:
def __init__(self, vid):
self.vid = vid
@app.get("/")
async def root():
return {
"status": "ok",
"biliarchiver": {"version": BILI_ARCHIVER_VERSION},
"api": {"version": 1},
"timestamp": int(datetime.now().timestamp()),
}
@app.put("/archive/{vid}")
@app.post("/archive/{vid}")
async def add(vid: str):
video = BiliVideo(vid)
await queue.put(video)
return {"success": True, "vid": vid}
@app.get("/archive")
async def get():
return {"success": True, "queue": map(str, queue)}
@app.get("/archive/{vid}")
async def get(vid: str):
if vid in queue:
return {"success": True, "vid": vid}
return {"success": False, "vid": vid}
@app.delete("/archive/{vid}")
async def delete(vid: str):
return {"success": True, "vid": vid}
async def scheduler():
while True:
print("Getting a video URL... If no video URL is printed, the queue is empty.")
video = await queue.get()
print(f"Start donwloading {video}")
await video.down()
print(f"Start uploading {video}")
await video.up()
@app.on_event("startup")
async def startup_event():
bg_task = BackgroundTasks()
bg_task.add_task(scheduler)
asyncio.create_task(scheduler())

View File

@ -0,0 +1,28 @@
import asyncio
from biliarchiver.rest_api.bilivid import BiliVideo
class ArchiveScheduler:
def __init__(self) -> None:
self.queue = []
self.loop = asyncio.get_event_loop()
self.loop.run_until_complete(self.main())
self.should_stop = False
async def main(self):
while True:
if self.should_stop:
break
if len(self.queue) > 0:
vid = self.queue.pop(0)
await vid.down()
await vid.up()
else:
await asyncio.sleep(5)
def add(self, vid: BiliVideo):
self.queue.append(vid)
def stop(self):
self.should_stop = True
self.loop.close()

View File

@ -16,6 +16,10 @@ browser-cookie3 = "^0.19.1"
click = "^8.1.6"
click-option-group = "^0.5.6"
[tool.poetry.group.api.dependencies]
fastapi = "^0.101.1"
uvicorn = {extras = ["standard"], version = "^0.23.2"}
[tool.poetry.scripts]
biliarchiver = "biliarchiver.cli_tools.biliarchiver:biliarchiver"