mirror of
https://github.com/EstrellaXD/Auto_Bangumi.git
synced 2026-03-31 01:01:31 +08:00
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:
@@ -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",
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -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_)
|
||||
|
||||
@@ -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)]
|
||||
|
||||
Reference in New Issue
Block a user