Revert "fix: trigger initial subscribe search"

This reverts commit 76803ae7a3.
This commit is contained in:
jxxghp
2026-07-06 19:14:42 +08:00
parent b16c50b03a
commit 992031ef95
4 changed files with 6 additions and 206 deletions

View File

@@ -27,24 +27,9 @@ from app.schemas.types import MediaType, EventType, SystemConfigKey
router = APIRouter()
def _schedule_subscribe_search(
background_tasks: Optional[BackgroundTasks], subscribe_id: Optional[int]
) -> None:
"""
入队新增订阅的首次搜索任务。
"""
if not background_tasks or not subscribe_id:
return
background_tasks.add_task(
Scheduler().start,
job_id="new_subscribe_search",
**{"sid": subscribe_id, "state": None, "manual": False},
)
def start_subscribe_add(
title: str, year: str, mtype: MediaType, tmdbid: int, season: int, username: str
) -> None:
):
"""
启动订阅任务
"""
@@ -146,7 +131,6 @@ async def list_subscribes(_: Annotated[str, Depends(verify_apitoken)]) -> Any:
async def create_subscribe(
*,
subscribe_in: schemas.Subscribe,
background_tasks: BackgroundTasks,
current_user: User = Depends(get_current_active_user_async),
) -> schemas.Response:
"""
@@ -183,8 +167,6 @@ async def create_subscribe(
owner_scope=not current_user.is_superuser,
**subscribe_dict,
)
if message == "新增订阅成功":
_schedule_subscribe_search(background_tasks, sid)
return schemas.Response(success=bool(sid), message=message, data={"id": sid})
@@ -746,7 +728,6 @@ async def subscribe_share_delete(
@router.post("/fork", summary="复用订阅", response_model=schemas.Response)
async def subscribe_fork(
sub: schemas.SubscribeShare,
background_tasks: BackgroundTasks,
current_user: User = Depends(get_current_active_user_async),
) -> Any:
"""
@@ -758,9 +739,7 @@ async def subscribe_fork(
if not hasattr(schemas.Subscribe(), key):
sub_dict.pop(key)
result = await create_subscribe(
subscribe_in=schemas.Subscribe(**sub_dict),
background_tasks=background_tasks,
current_user=current_user,
subscribe_in=schemas.Subscribe(**sub_dict), current_user=current_user
)
if result.success:
await MoviePilotServerHelper.async_sub_fork(share_id=sub.id)

View File

@@ -1190,7 +1190,7 @@ class SubscribeChain(ChainBase):
if subscribe.date:
now = datetime.now()
subscribe_time = datetime.strptime(subscribe.date, '%Y-%m-%d %H:%M:%S')
if not sid and not manual and (now - subscribe_time).total_seconds() < 60:
if (now - subscribe_time).total_seconds() < 60:
logger.debug(f"订阅标题:{subscribe.name} 新增小于1分钟暂不搜索...")
continue
# 随机休眠1-5分钟

View File

@@ -1,176 +0,0 @@
import asyncio
from datetime import datetime
from types import SimpleNamespace
from typing import Any, Callable, Optional
from unittest.mock import AsyncMock, patch
from app.api.endpoints.subscribe import create_subscribe
from app.chain.subscribe import SubscribeChain
from app.schemas.subscribe import Subscribe
from app.schemas.types import MediaType
class _BackgroundTasks:
"""
最小后台任务替身,记录订阅创建接口入队的任务。
"""
def __init__(self) -> None:
self.tasks = []
def add_task(self, func: Callable[..., Any], **kwargs: Any) -> None:
"""
记录后台任务函数和参数。
"""
self.tasks.append({"func": func, "kwargs": kwargs})
class _User(SimpleNamespace):
"""
最小用户替身,模拟订阅创建接口依赖的用户字段。
"""
def __init__(self, name: str, is_superuser: bool) -> None:
super().__init__(name=name, is_superuser=is_superuser)
class _SubscribeOper:
"""
最小订阅 Oper 替身,隔离 SubscribeChain.search 的数据库访问。
"""
subscribe: Optional[SimpleNamespace] = None
updates: list[tuple[int, dict[str, Any]]] = []
def get(self, sid: int) -> Optional[SimpleNamespace]:
"""
按 ID 返回测试订阅对象。
"""
return self.subscribe if self.subscribe and self.subscribe.id == sid else None
def list(self, _state: str) -> list[SimpleNamespace]:
"""
返回批量搜索需要的测试订阅列表。
"""
return [self.subscribe] if self.subscribe else []
def update(self, sid: int, payload: dict[str, Any]) -> None:
"""
记录订阅状态更新请求。
"""
self.updates.append((sid, payload))
def _new_subscribe() -> SimpleNamespace:
"""
构造一个刚创建的电影订阅。
"""
return SimpleNamespace(
id=31,
name="测试电影",
year="2026",
type=MediaType.MOVIE.value,
tmdbid=12345,
doubanid=None,
season=None,
custom_words=None,
date=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
state="N",
episode_group=None,
)
def test_create_subscribe_schedules_first_search_for_new_subscribe() -> None:
"""
API 新增订阅成功后应立即入队该订阅的首次后台搜索。
"""
background_tasks = _BackgroundTasks()
subscribe_in = Subscribe(
name="测试电影",
year="2026",
type=MediaType.MOVIE.value,
)
with patch(
"app.api.endpoints.subscribe.SubscribeChain.async_add",
new=AsyncMock(return_value=(31, "新增订阅成功")),
), patch("app.api.endpoints.subscribe.Scheduler") as scheduler:
response = asyncio.run(
create_subscribe(
subscribe_in=subscribe_in,
background_tasks=background_tasks,
current_user=_User(name="alice", is_superuser=False),
)
)
assert response.success
assert len(background_tasks.tasks) == 1
assert background_tasks.tasks[0]["func"] == scheduler.return_value.start
assert background_tasks.tasks[0]["kwargs"] == {
"job_id": "new_subscribe_search",
"sid": 31,
"state": None,
"manual": False,
}
def test_create_subscribe_does_not_search_existing_subscribe() -> None:
"""
重复订阅返回已存在时不应额外触发首次搜索。
"""
background_tasks = _BackgroundTasks()
subscribe_in = Subscribe(
name="测试电影",
year="2026",
type=MediaType.MOVIE.value,
)
with patch(
"app.api.endpoints.subscribe.SubscribeChain.async_add",
new=AsyncMock(return_value=(31, "订阅已存在")),
), patch("app.api.endpoints.subscribe.Scheduler") as scheduler:
response = asyncio.run(
create_subscribe(
subscribe_in=subscribe_in,
background_tasks=background_tasks,
current_user=_User(name="alice", is_superuser=False),
)
)
assert response.success
assert background_tasks.tasks == []
scheduler.assert_not_called()
def test_subscribe_search_runs_single_new_subscribe_immediately(monkeypatch) -> None:
"""
指定订阅 ID 的首次搜索不应被新建 60 秒保护挡住。
"""
subscribe = _new_subscribe()
_SubscribeOper.subscribe = subscribe
_SubscribeOper.updates = []
monkeypatch.setattr("app.chain.subscribe.SubscribeOper", _SubscribeOper)
with patch.object(SubscribeChain, "recognize_media", return_value=None) as recognize:
chain = object.__new__(SubscribeChain)
chain.search(sid=subscribe.id, state=None, manual=False)
recognize.assert_called_once()
assert _SubscribeOper.updates == [(subscribe.id, {"state": "R"})]
def test_subscribe_search_keeps_batch_new_subscribe_delay(monkeypatch) -> None:
"""
定时批量扫描新订阅时仍保留 60 秒编辑窗口。
"""
subscribe = _new_subscribe()
_SubscribeOper.subscribe = subscribe
_SubscribeOper.updates = []
monkeypatch.setattr("app.chain.subscribe.SubscribeOper", _SubscribeOper)
with patch.object(SubscribeChain, "recognize_media", return_value=None) as recognize:
chain = object.__new__(SubscribeChain)
chain.search(state="N", manual=False)
recognize.assert_not_called()
assert _SubscribeOper.updates == []

View File

@@ -362,7 +362,7 @@ class SubscribeEndpointTest(TestCase):
with patch(
"app.api.endpoints.subscribe.Subscribe.async_list_by_username",
new=AsyncMock(return_value=owned),
), patch("app.api.endpoints.subscribe.Scheduler"):
):
response = asyncio.run(
search_subscribes(
background_tasks=background_tasks,
@@ -610,11 +610,10 @@ class SubscribeEndpointTest(TestCase):
with patch(
"app.api.endpoints.subscribe.SubscribeChain.async_add",
new=AsyncMock(return_value=(1, "新增订阅成功")),
) as async_add, patch("app.api.endpoints.subscribe.Scheduler"):
) as async_add:
response = asyncio.run(
create_subscribe(
subscribe_in=subscribe_in,
background_tasks=_EndpointBackgroundTasks(),
current_user=_EndpointUser(name="moviepilot-user", is_superuser=False),
)
)
@@ -644,11 +643,10 @@ class SubscribeEndpointTest(TestCase):
), patch(
"app.api.endpoints.subscribe.SubscribeChain.async_add",
new=AsyncMock(return_value=(1, "新增订阅成功")),
) as async_add, patch("app.api.endpoints.subscribe.Scheduler"):
) as async_add:
response = asyncio.run(
create_subscribe(
subscribe_in=subscribe_in,
background_tasks=_EndpointBackgroundTasks(),
current_user=_EndpointUser(name="moviepilot-user", is_superuser=False),
)
)
@@ -674,7 +672,6 @@ class SubscribeEndpointTest(TestCase):
response = asyncio.run(
create_subscribe(
subscribe_in=subscribe_in,
background_tasks=_EndpointBackgroundTasks(),
current_user=_EndpointUser(name="admin", is_superuser=True),
)
)