fix(subscribe): scope duplicate checks by episode group (#6219)

This commit is contained in:
InfinityPacer
2026-08-01 18:40:29 +08:00
committed by GitHub
parent 93761fe7e4
commit 7c3f9629bf
6 changed files with 268 additions and 34 deletions

View File

@@ -1295,6 +1295,7 @@ class SubscribeChain(ChainBase):
media_source=media_source,
media_id=media_id,
season=meta.begin_season if meta else None,
episode_group=mediainfo.episode_group,
):
return True
return False
@@ -2288,7 +2289,8 @@ class SubscribeChain(ChainBase):
anilistid=share_sub.get("anilistid"),
media_source=share_sub.get("media_source"),
media_id=share_sub.get("media_id"),
season=share_sub.get("season")):
season=share_sub.get("season"),
episode_group=share_sub.get("episode_group")):
continue
# 已经订阅过跳过
if subscribeoper.exist_history(tmdbid=share_sub.get("tmdbid"),
@@ -2297,7 +2299,8 @@ class SubscribeChain(ChainBase):
anilistid=share_sub.get("anilistid"),
media_source=share_sub.get("media_source"),
media_id=share_sub.get("media_id"),
season=share_sub.get("season")):
season=share_sub.get("season"),
episode_group=share_sub.get("episode_group")):
continue
# 去除无效属性
for key in list(share_sub.keys()):
@@ -2328,6 +2331,7 @@ class SubscribeChain(ChainBase):
year=subscribe_in.year,
tmdbid=subscribe_in.tmdbid,
season=subscribe_in.season,
episode_group=subscribe_in.episode_group,
doubanid=subscribe_in.doubanid,
bangumiid=subscribe_in.bangumiid,
anilistid=subscribe_in.anilistid,

View File

@@ -130,8 +130,9 @@ class Subscribe(Base):
doubanid: Optional[str] = None, bangumiid: Optional[int] = None,
anilistid: Optional[int] = None, media_source: Optional[str] = None,
media_id: Optional[str] = None, season: Optional[int] = None,
episode_group: Optional[str] = None,
):
"""按媒体身份季号查询已有订阅。"""
"""按媒体身份季号与剧集组查询已有订阅。"""
condition = cls._identity_condition(
media_source, media_id, tmdbid, doubanid, bangumiid, anilistid
)
@@ -140,6 +141,7 @@ class Subscribe(Base):
query = db.query(cls).filter(condition)
if season is not None:
query = query.filter(cls.season == season)
query = query.filter(cls.episode_group == episode_group)
return query.first()
@classmethod
@@ -149,8 +151,9 @@ class Subscribe(Base):
doubanid: Optional[str] = None, bangumiid: Optional[int] = None,
anilistid: Optional[int] = None, media_source: Optional[str] = None,
media_id: Optional[str] = None, season: Optional[int] = None,
episode_group: Optional[str] = None,
):
"""异步按媒体身份季号查询已有订阅。"""
"""异步按媒体身份季号与剧集组查询已有订阅。"""
condition = cls._identity_condition(
media_source, media_id, tmdbid, doubanid, bangumiid, anilistid
)
@@ -159,6 +162,7 @@ class Subscribe(Base):
query = select(cls).filter(condition)
if season is not None:
query = query.filter(cls.season == season)
query = query.filter(cls.episode_group == episode_group)
result = await db.execute(query)
return result.scalars().first()
@@ -169,9 +173,10 @@ class Subscribe(Base):
doubanid: Optional[str] = None, bangumiid: Optional[int] = None,
anilistid: Optional[int] = None, media_source: Optional[str] = None,
media_id: Optional[str] = None, season: Optional[int] = None,
episode_group: Optional[str] = None,
):
"""
按订阅 owner 查询同一媒体的订阅行。
按订阅 owner、媒体身份、季号与剧集组查询订阅行。
"""
if not username:
return None
@@ -183,6 +188,7 @@ class Subscribe(Base):
query = db.query(cls).filter(cls.username == username, condition)
if season is not None:
query = query.filter(cls.season == season)
query = query.filter(cls.episode_group == episode_group)
return query.first()
@classmethod
@@ -192,9 +198,10 @@ class Subscribe(Base):
doubanid: Optional[str] = None, bangumiid: Optional[int] = None,
anilistid: Optional[int] = None, media_source: Optional[str] = None,
media_id: Optional[str] = None, season: Optional[int] = None,
episode_group: Optional[str] = None,
):
"""
异步按订阅 owner 查询同一媒体的订阅行。
异步按订阅 owner、媒体身份、季号与剧集组查询订阅行。
"""
if not username:
return None
@@ -206,6 +213,7 @@ class Subscribe(Base):
query = select(cls).filter(cls.username == username, condition)
if season is not None:
query = query.filter(cls.season == season)
query = query.filter(cls.episode_group == episode_group)
result = await db.execute(query)
return result.scalars().first()

View File

@@ -161,8 +161,9 @@ class SubscribeHistory(Base):
doubanid: Optional[str] = None, bangumiid: Optional[int] = None,
anilistid: Optional[int] = None, media_source: Optional[str] = None,
media_id: Optional[str] = None, season: Optional[int] = None,
episode_group: Optional[str] = None,
):
"""按媒体身份季号查询订阅历史。"""
"""按媒体身份季号及可选剧集组查询订阅历史。"""
condition = cls._identity_condition(
media_source, media_id, tmdbid, doubanid, bangumiid, anilistid
)
@@ -171,6 +172,7 @@ class SubscribeHistory(Base):
query = db.query(cls).filter(condition)
if season is not None:
query = query.filter(cls.season == season)
query = query.filter(cls.episode_group == episode_group)
return query.first()
@classmethod
@@ -180,8 +182,9 @@ class SubscribeHistory(Base):
doubanid: Optional[str] = None, bangumiid: Optional[int] = None,
anilistid: Optional[int] = None, media_source: Optional[str] = None,
media_id: Optional[str] = None, season: Optional[int] = None,
episode_group: Optional[str] = None,
):
"""异步按媒体身份季号查询订阅历史。"""
"""异步按媒体身份季号及可选剧集组查询订阅历史。"""
condition = cls._identity_condition(
media_source, media_id, tmdbid, doubanid, bangumiid, anilistid
)
@@ -190,5 +193,6 @@ class SubscribeHistory(Base):
query = select(cls).filter(condition)
if season is not None:
query = query.filter(cls.season == season)
query = query.filter(cls.episode_group == episode_group)
result = await db.execute(query)
return result.scalars().first()

View File

@@ -45,6 +45,7 @@ class SubscribeOper(DbOper):
"media_source": media_source,
"media_id": media_id,
"season": kwargs.get("season"),
"episode_group": mediainfo.episode_group,
}
if username:
subscribe = Subscribe.exists_by_username(self._db,
@@ -106,6 +107,7 @@ class SubscribeOper(DbOper):
"media_source": media_source,
"media_id": media_id,
"season": kwargs.get("season"),
"episode_group": mediainfo.episode_group,
}
if username:
subscribe = await Subscribe.async_exists_by_username(self._db,
@@ -152,21 +154,22 @@ class SubscribeOper(DbOper):
self, tmdbid: Optional[int] = None, doubanid: Optional[str] = None,
bangumiid: Optional[int] = None, anilistid: Optional[int] = None,
media_source: Optional[str] = None, media_id: Optional[str] = None,
season: Optional[int] = None,
season: Optional[int] = None, episode_group: Optional[str] = None,
) -> bool:
"""
判断是否存在
按媒体身份、季号及可选剧集组判断订阅是否存在
"""
return bool(Subscribe.exists(
self._db,
tmdbid=tmdbid,
doubanid=doubanid,
bangumiid=bangumiid,
anilistid=anilistid,
media_source=media_source,
media_id=media_id,
season=season,
))
identity_params = {
"tmdbid": tmdbid,
"doubanid": doubanid,
"bangumiid": bangumiid,
"anilistid": anilistid,
"media_source": media_source,
"media_id": media_id,
"season": season,
"episode_group": episode_group,
}
return bool(Subscribe.exists(self._db, **identity_params))
def get(self, sid: int) -> Subscribe:
"""
@@ -300,18 +303,19 @@ class SubscribeOper(DbOper):
self, tmdbid: Optional[int] = None, doubanid: Optional[str] = None,
bangumiid: Optional[int] = None, anilistid: Optional[int] = None,
media_source: Optional[str] = None, media_id: Optional[str] = None,
season: Optional[int] = None,
season: Optional[int] = None, episode_group: Optional[str] = None,
) -> bool:
"""
判断是否存在订阅历史
按媒体身份、季号及可选剧集组判断订阅历史是否存在。
"""
return bool(SubscribeHistory.exists(
self._db,
tmdbid=tmdbid,
doubanid=doubanid,
bangumiid=bangumiid,
anilistid=anilistid,
media_source=media_source,
media_id=media_id,
season=season,
))
identity_params = {
"tmdbid": tmdbid,
"doubanid": doubanid,
"bangumiid": bangumiid,
"anilistid": anilistid,
"media_source": media_source,
"media_id": media_id,
"season": season,
"episode_group": episode_group,
}
return bool(SubscribeHistory.exists(self._db, **identity_params))