fix: 修复 bangumi search API 中的流式接口,webui 对应接口定义方法改造

- StreamingResponse 换成 EventSourceResponse,即 Server Send Event Source 方式发送数据
- webui 中 search 接口改成 rxjs Observable 方式,
  这次来不及改到 vue 里,但是写了接口 usage example;
- 顺手补了一些 vscode 通用的开发配置,
  补了之前配置文件解析漏了一个可用环境变量的 host 字段
This commit is contained in:
zthxxx
2023-08-31 23:48:07 +08:00
parent 16bbf6f866
commit 7d50e360ed
12 changed files with 177 additions and 23 deletions

View File

@@ -1,29 +1,31 @@
from fastapi import APIRouter, Query, Depends
from fastapi.responses import StreamingResponse
from sse_starlette.sse import EventSourceResponse
from module.searcher import SearchTorrent, SEARCH_CONFIG
from module.security.api import get_current_user, UNAUTHORIZED
from module.models import Torrent
from module.models import Bangumi
router = APIRouter(prefix="/search", tags=["search"])
@router.get("/", response_model=list[Torrent])
@router.get("/", response_model=EventSourceResponse[Bangumi])
async def search_torrents(
site: str = "mikan",
keywords: str = Query(None),
current_user=Depends(get_current_user),
):
"""
Server Send Event for per Bangumi item
"""
if not current_user:
raise UNAUTHORIZED
if not keywords:
return []
keywords = keywords.split(" ")
with SearchTorrent() as st:
return StreamingResponse(
return EventSourceResponse(
content=st.analyse_keyword(keywords=keywords, site=site),
media_type="application/json",
)

View File

@@ -10,7 +10,7 @@ class Program(BaseModel):
class Downloader(BaseModel):
type: str = Field("qbittorrent", description="Downloader type")
host: str = Field("172.17.0.1:8080", description="Downloader host")
host_: str = Field("172.17.0.1:8080", alias="host", description="Downloader host")
username_: str = Field("admin", alias="username", description="Downloader username")
password_: str = Field(
"adminadmin", alias="password", description="Downloader password"
@@ -18,6 +18,10 @@ class Downloader(BaseModel):
path: str = Field("/downloads/Bangumi", description="Downloader path")
ssl: bool = Field(False, description="Downloader ssl")
@property
def host(self):
return expandvars(self.host_)
@property
def username(self):
return expandvars(self.username_)

View File

@@ -1,4 +1,5 @@
import json
from typing import TypeAlias
from module.models import Bangumi, Torrent, RSSItem
from module.network import RequestContent
@@ -15,6 +16,7 @@ SEARCH_KEY = [
"dpi",
]
BangumiJSON: TypeAlias = str
class SearchTorrent(RequestContent, RSSAnalyser):
def search_torrents(
@@ -23,18 +25,14 @@ class SearchTorrent(RequestContent, RSSAnalyser):
torrents = self.get_torrents(rss_item.url, limit=limit)
return torrents
def analyse_keyword(self, keywords: list[str], site: str = "mikan"):
def analyse_keyword(self, keywords: list[str], site: str = "mikan") -> BangumiJSON:
rss_item = search_url(site, keywords)
torrents = self.search_torrents(rss_item)
# Generate a list of json
yield "["
for idx, torrent in enumerate(torrents):
# yield for EventSourceResponse (Server Send)
for torrent in torrents:
bangumi = self.torrent_to_data(torrent=torrent, rss=rss_item)
if bangumi:
yield json.dumps(bangumi.dict())
if idx != len(torrents) - 1:
yield ","
yield "]"
yield json.dumps(bangumi.dict(), separators=(',', ':'))
def search_season(self, data: Bangumi):
keywords = [getattr(data, key) for key in SEARCH_KEY if getattr(data, key)]