mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 23:47:41 +08:00
feat:订阅支持通用mediaid
This commit is contained in:
@@ -7,9 +7,11 @@ from app import schemas
|
|||||||
from app.chain.media import MediaChain
|
from app.chain.media import MediaChain
|
||||||
from app.core.config import settings
|
from app.core.config import settings
|
||||||
from app.core.context import Context
|
from app.core.context import Context
|
||||||
|
from app.core.event import eventmanager
|
||||||
from app.core.metainfo import MetaInfo, MetaInfoPath
|
from app.core.metainfo import MetaInfo, MetaInfoPath
|
||||||
from app.core.security import verify_token, verify_apitoken
|
from app.core.security import verify_token, verify_apitoken
|
||||||
from app.schemas import MediaType
|
from app.schemas import MediaType, MediaRecognizeConvertEventData
|
||||||
|
from app.schemas.types import ChainEventType
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
@@ -138,18 +140,32 @@ def media_info(mediaid: str, type_name: str,
|
|||||||
根据媒体ID查询themoviedb或豆瓣媒体信息,type_name: 电影/电视剧
|
根据媒体ID查询themoviedb或豆瓣媒体信息,type_name: 电影/电视剧
|
||||||
"""
|
"""
|
||||||
mtype = MediaType(type_name)
|
mtype = MediaType(type_name)
|
||||||
tmdbid, doubanid, bangumiid = None, None, None
|
mediainfo = None
|
||||||
if mediaid.startswith("tmdb:"):
|
if mediaid.startswith("tmdb:"):
|
||||||
tmdbid = int(mediaid[5:])
|
mediainfo = MediaChain().recognize_media(tmdbid=int(mediaid[5:]), mtype=mtype)
|
||||||
elif mediaid.startswith("douban:"):
|
elif mediaid.startswith("douban:"):
|
||||||
doubanid = mediaid[7:]
|
mediainfo = MediaChain().recognize_media(doubanid=mediaid[7:], mtype=mtype)
|
||||||
elif mediaid.startswith("bangumi:"):
|
elif mediaid.startswith("bangumi:"):
|
||||||
bangumiid = int(mediaid[8:])
|
mediainfo = MediaChain().recognize_media(bangumiid=int(mediaid[8:]), mtype=mtype)
|
||||||
if not tmdbid and not doubanid and not bangumiid:
|
else:
|
||||||
return schemas.MediaInfo()
|
# 广播事件解析媒体信息
|
||||||
|
event_data = MediaRecognizeConvertEventData(
|
||||||
|
mediaid=mediaid,
|
||||||
|
convert_type=settings.RECOGNIZE_SOURCE
|
||||||
|
)
|
||||||
|
event = eventmanager.send_event(ChainEventType.MediaRecognizeConvert, event_data)
|
||||||
|
# 使用事件返回的上下文数据
|
||||||
|
if event and event.event_data:
|
||||||
|
event_data: MediaRecognizeConvertEventData = event.event_data
|
||||||
|
if event_data.media_dict:
|
||||||
|
new_id = event_data.media_dict.get("id")
|
||||||
|
if event_data.convert_type == "themoviedb":
|
||||||
|
mediainfo = MediaChain().recognize_media(tmdbid=new_id, mtype=mtype)
|
||||||
|
elif event_data.convert_type == "douban":
|
||||||
|
mediainfo = MediaChain().recognize_media(doubanid=new_id, mtype=mtype)
|
||||||
# 识别
|
# 识别
|
||||||
mediainfo = MediaChain().recognize_media(tmdbid=tmdbid, doubanid=doubanid, bangumiid=bangumiid, mtype=mtype)
|
|
||||||
if mediainfo:
|
if mediainfo:
|
||||||
MediaChain().obtain_images(mediainfo)
|
MediaChain().obtain_images(mediainfo)
|
||||||
return mediainfo.to_dict()
|
return mediainfo.to_dict()
|
||||||
|
|
||||||
return schemas.MediaInfo()
|
return schemas.MediaInfo()
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ def search_by_id(mediaid: str,
|
|||||||
if event_data.convert_type == "themoviedb":
|
if event_data.convert_type == "themoviedb":
|
||||||
torrents = SearchChain().search_by_id(tmdbid=search_id,
|
torrents = SearchChain().search_by_id(tmdbid=search_id,
|
||||||
mtype=mtype, area=area, season=season)
|
mtype=mtype, area=area, season=season)
|
||||||
else:
|
elif event_data.convert_type == "douban":
|
||||||
torrents = SearchChain().search_by_id(doubanid=search_id,
|
torrents = SearchChain().search_by_id(doubanid=search_id,
|
||||||
mtype=mtype, area=area, season=season)
|
mtype=mtype, area=area, season=season)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ def create_subscribe(
|
|||||||
season=subscribe_in.season,
|
season=subscribe_in.season,
|
||||||
doubanid=subscribe_in.doubanid,
|
doubanid=subscribe_in.doubanid,
|
||||||
bangumiid=subscribe_in.bangumiid,
|
bangumiid=subscribe_in.bangumiid,
|
||||||
|
mediaid=subscribe_in.mediaid,
|
||||||
username=current_user.name,
|
username=current_user.name,
|
||||||
best_version=subscribe_in.best_version,
|
best_version=subscribe_in.best_version,
|
||||||
save_path=subscribe_in.save_path,
|
save_path=subscribe_in.save_path,
|
||||||
@@ -171,7 +172,6 @@ def subscribe_mediaid(
|
|||||||
"""
|
"""
|
||||||
根据 TMDBID/豆瓣ID/BangumiId 查询订阅 tmdb:/douban:
|
根据 TMDBID/豆瓣ID/BangumiId 查询订阅 tmdb:/douban:
|
||||||
"""
|
"""
|
||||||
result = None
|
|
||||||
title_check = False
|
title_check = False
|
||||||
if mediaid.startswith("tmdb:"):
|
if mediaid.startswith("tmdb:"):
|
||||||
tmdbid = mediaid[5:]
|
tmdbid = mediaid[5:]
|
||||||
@@ -192,6 +192,10 @@ def subscribe_mediaid(
|
|||||||
result = Subscribe.get_by_bangumiid(db, int(bangumiid))
|
result = Subscribe.get_by_bangumiid(db, int(bangumiid))
|
||||||
if not result and title:
|
if not result and title:
|
||||||
title_check = True
|
title_check = True
|
||||||
|
else:
|
||||||
|
result = Subscribe.get_by_mediaid(db, mediaid)
|
||||||
|
if not result and title:
|
||||||
|
title_check = True
|
||||||
# 使用名称检查订阅
|
# 使用名称检查订阅
|
||||||
if title_check and title:
|
if title_check and title:
|
||||||
meta = MetaInfo(title)
|
meta = MetaInfo(title)
|
||||||
@@ -311,6 +315,10 @@ def delete_subscribe_by_mediaid(
|
|||||||
subscribe = Subscribe().get_by_doubanid(db, doubanid)
|
subscribe = Subscribe().get_by_doubanid(db, doubanid)
|
||||||
if subscribe:
|
if subscribe:
|
||||||
delete_subscribes.append(subscribe)
|
delete_subscribes.append(subscribe)
|
||||||
|
else:
|
||||||
|
subscribe = Subscribe().get_by_mediaid(db, mediaid)
|
||||||
|
if subscribe:
|
||||||
|
delete_subscribes.append(subscribe)
|
||||||
for subscribe in delete_subscribes:
|
for subscribe in delete_subscribes:
|
||||||
Subscribe().delete(db, subscribe.id)
|
Subscribe().delete(db, subscribe.id)
|
||||||
# 发送事件
|
# 发送事件
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ class SearchChain(ChainBase):
|
|||||||
def search_by_id(self, tmdbid: int = None, doubanid: str = None,
|
def search_by_id(self, tmdbid: int = None, doubanid: str = None,
|
||||||
mtype: MediaType = None, area: str = "title", season: int = None) -> List[Context]:
|
mtype: MediaType = None, area: str = "title", season: int = None) -> List[Context]:
|
||||||
"""
|
"""
|
||||||
根据TMDBID/豆瓣ID搜索资源,精确匹配,但不不过滤本地存在的资源
|
根据TMDBID/豆瓣ID搜索资源,精确匹配,不过滤本地存在的资源
|
||||||
:param tmdbid: TMDB ID
|
:param tmdbid: TMDB ID
|
||||||
:param doubanid: 豆瓣 ID
|
:param doubanid: 豆瓣 ID
|
||||||
:param mtype: 媒体,电影 or 电视剧
|
:param mtype: 媒体,电影 or 电视剧
|
||||||
|
|||||||
+43
-3
@@ -28,7 +28,8 @@ from app.helper.message import MessageHelper
|
|||||||
from app.helper.subscribe import SubscribeHelper
|
from app.helper.subscribe import SubscribeHelper
|
||||||
from app.helper.torrent import TorrentHelper
|
from app.helper.torrent import TorrentHelper
|
||||||
from app.log import logger
|
from app.log import logger
|
||||||
from app.schemas.types import MediaType, SystemConfigKey, MessageChannel, NotificationType, EventType
|
from app.schemas import MediaRecognizeConvertEventData
|
||||||
|
from app.schemas.types import MediaType, SystemConfigKey, MessageChannel, NotificationType, EventType, ChainEventType
|
||||||
from app.utils.singleton import Singleton
|
from app.utils.singleton import Singleton
|
||||||
|
|
||||||
|
|
||||||
@@ -58,6 +59,7 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
|
|||||||
tmdbid: int = None,
|
tmdbid: int = None,
|
||||||
doubanid: str = None,
|
doubanid: str = None,
|
||||||
bangumiid: int = None,
|
bangumiid: int = None,
|
||||||
|
mediaid: str = None,
|
||||||
season: int = None,
|
season: int = None,
|
||||||
channel: MessageChannel = None,
|
channel: MessageChannel = None,
|
||||||
source: str = None,
|
source: str = None,
|
||||||
@@ -69,7 +71,29 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
|
|||||||
"""
|
"""
|
||||||
识别媒体信息并添加订阅
|
识别媒体信息并添加订阅
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __get_event_meida(_mediaid: str, _meta: MetaBase) -> Optional[MediaInfo]:
|
||||||
|
"""
|
||||||
|
广播事件解析媒体信息
|
||||||
|
"""
|
||||||
|
event_data = MediaRecognizeConvertEventData(
|
||||||
|
mediaid=_mediaid,
|
||||||
|
convert_type=settings.RECOGNIZE_SOURCE
|
||||||
|
)
|
||||||
|
event = eventmanager.send_event(ChainEventType.MediaRecognizeConvert, event_data)
|
||||||
|
# 使用事件返回的上下文数据
|
||||||
|
if event and event.event_data:
|
||||||
|
event_data: MediaRecognizeConvertEventData = event.event_data
|
||||||
|
if event_data.media_dict:
|
||||||
|
new_id = event_data.media_dict.get("id")
|
||||||
|
if event_data.convert_type == "themoviedb":
|
||||||
|
return self.mediachain.recognize_media(meta=_meta, tmdbid=new_id)
|
||||||
|
elif event_data.convert_type == "douban":
|
||||||
|
return self.mediachain.recognize_media(meta=_meta, doubanid=new_id)
|
||||||
|
return None
|
||||||
|
|
||||||
logger.info(f'开始添加订阅,标题:{title} ...')
|
logger.info(f'开始添加订阅,标题:{title} ...')
|
||||||
|
|
||||||
mediainfo = None
|
mediainfo = None
|
||||||
metainfo = MetaInfo(title)
|
metainfo = MetaInfo(title)
|
||||||
if year:
|
if year:
|
||||||
@@ -82,27 +106,41 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
|
|||||||
# 识别媒体信息
|
# 识别媒体信息
|
||||||
if settings.RECOGNIZE_SOURCE == "themoviedb":
|
if settings.RECOGNIZE_SOURCE == "themoviedb":
|
||||||
# TMDB识别模式
|
# TMDB识别模式
|
||||||
if not tmdbid and doubanid:
|
if not tmdbid:
|
||||||
|
if doubanid:
|
||||||
# 将豆瓣信息转换为TMDB信息
|
# 将豆瓣信息转换为TMDB信息
|
||||||
tmdbinfo = self.mediachain.get_tmdbinfo_by_doubanid(doubanid=doubanid, mtype=mtype)
|
tmdbinfo = self.mediachain.get_tmdbinfo_by_doubanid(doubanid=doubanid, mtype=mtype)
|
||||||
if tmdbinfo:
|
if tmdbinfo:
|
||||||
mediainfo = MediaInfo(tmdb_info=tmdbinfo)
|
mediainfo = MediaInfo(tmdb_info=tmdbinfo)
|
||||||
|
elif mediaid:
|
||||||
|
# 未知前缀,广播事件解析媒体信息
|
||||||
|
mediainfo = __get_event_meida(mediaid, metainfo)
|
||||||
else:
|
else:
|
||||||
# 识别TMDB信息,不使用缓存
|
# 使用TMDBID识别
|
||||||
mediainfo = self.recognize_media(meta=metainfo, mtype=mtype, tmdbid=tmdbid, cache=False)
|
mediainfo = self.recognize_media(meta=metainfo, mtype=mtype, tmdbid=tmdbid, cache=False)
|
||||||
else:
|
else:
|
||||||
|
if doubanid:
|
||||||
# 豆瓣识别模式,不使用缓存
|
# 豆瓣识别模式,不使用缓存
|
||||||
mediainfo = self.recognize_media(meta=metainfo, mtype=mtype, doubanid=doubanid, cache=False)
|
mediainfo = self.recognize_media(meta=metainfo, mtype=mtype, doubanid=doubanid, cache=False)
|
||||||
|
elif mediaid:
|
||||||
|
# 未知前缀,广播事件解析媒体信息
|
||||||
|
mediainfo = __get_event_meida(mediaid, metainfo)
|
||||||
if mediainfo:
|
if mediainfo:
|
||||||
# 豆瓣标题处理
|
# 豆瓣标题处理
|
||||||
meta = MetaInfo(mediainfo.title)
|
meta = MetaInfo(mediainfo.title)
|
||||||
mediainfo.title = meta.name
|
mediainfo.title = meta.name
|
||||||
if not season:
|
if not season:
|
||||||
season = meta.begin_season
|
season = meta.begin_season
|
||||||
|
|
||||||
|
# 使用名称识别兜底
|
||||||
|
if not mediainfo:
|
||||||
|
mediainfo = self.recognize_media(meta=metainfo, mtype=mtype)
|
||||||
|
|
||||||
# 识别失败
|
# 识别失败
|
||||||
if not mediainfo:
|
if not mediainfo:
|
||||||
logger.warn(f'未识别到媒体信息,标题:{title},tmdbid:{tmdbid},doubanid:{doubanid}')
|
logger.warn(f'未识别到媒体信息,标题:{title},tmdbid:{tmdbid},doubanid:{doubanid}')
|
||||||
return None, "未识别到媒体信息"
|
return None, "未识别到媒体信息"
|
||||||
|
|
||||||
# 总集数
|
# 总集数
|
||||||
if mediainfo.type == MediaType.TV:
|
if mediainfo.type == MediaType.TV:
|
||||||
if not season:
|
if not season:
|
||||||
@@ -137,6 +175,7 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
|
|||||||
else:
|
else:
|
||||||
# 避免season为0的问题
|
# 避免season为0的问题
|
||||||
season = None
|
season = None
|
||||||
|
|
||||||
# 更新媒体图片
|
# 更新媒体图片
|
||||||
self.obtain_images(mediainfo=mediainfo)
|
self.obtain_images(mediainfo=mediainfo)
|
||||||
# 合并信息
|
# 合并信息
|
||||||
@@ -144,6 +183,7 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
|
|||||||
mediainfo.douban_id = doubanid
|
mediainfo.douban_id = doubanid
|
||||||
if bangumiid:
|
if bangumiid:
|
||||||
mediainfo.bangumi_id = bangumiid
|
mediainfo.bangumi_id = bangumiid
|
||||||
|
|
||||||
# 添加订阅
|
# 添加订阅
|
||||||
kwargs.update({
|
kwargs.update({
|
||||||
'quality': self.__get_default_subscribe_config(mediainfo.type, "quality") if not kwargs.get(
|
'quality': self.__get_default_subscribe_config(mediainfo.type, "quality") if not kwargs.get(
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ class Subscribe(Base):
|
|||||||
tvdbid = Column(Integer)
|
tvdbid = Column(Integer)
|
||||||
doubanid = Column(String, index=True)
|
doubanid = Column(String, index=True)
|
||||||
bangumiid = Column(Integer, index=True)
|
bangumiid = Column(Integer, index=True)
|
||||||
|
mediaid = Column(String, index=True)
|
||||||
# 季号
|
# 季号
|
||||||
season = Column(Integer)
|
season = Column(Integer)
|
||||||
# 海报
|
# 海报
|
||||||
@@ -107,6 +108,14 @@ class Subscribe(Base):
|
|||||||
result = db.query(Subscribe).filter(Subscribe.state.in_(states)).all()
|
result = db.query(Subscribe).filter(Subscribe.state.in_(states)).all()
|
||||||
return list(result)
|
return list(result)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@db_query
|
||||||
|
def get_by_title(db: Session, title: str, season: int = None):
|
||||||
|
if season:
|
||||||
|
return db.query(Subscribe).filter(Subscribe.name == title,
|
||||||
|
Subscribe.season == season).first()
|
||||||
|
return db.query(Subscribe).filter(Subscribe.name == title).first()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@db_query
|
@db_query
|
||||||
def get_by_tmdbid(db: Session, tmdbid: int, season: int = None):
|
def get_by_tmdbid(db: Session, tmdbid: int, season: int = None):
|
||||||
@@ -117,14 +126,6 @@ class Subscribe(Base):
|
|||||||
result = db.query(Subscribe).filter(Subscribe.tmdbid == tmdbid).all()
|
result = db.query(Subscribe).filter(Subscribe.tmdbid == tmdbid).all()
|
||||||
return list(result)
|
return list(result)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@db_query
|
|
||||||
def get_by_title(db: Session, title: str, season: int = None):
|
|
||||||
if season:
|
|
||||||
return db.query(Subscribe).filter(Subscribe.name == title,
|
|
||||||
Subscribe.season == season).first()
|
|
||||||
return db.query(Subscribe).filter(Subscribe.name == title).first()
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@db_query
|
@db_query
|
||||||
def get_by_doubanid(db: Session, doubanid: str):
|
def get_by_doubanid(db: Session, doubanid: str):
|
||||||
@@ -135,6 +136,11 @@ class Subscribe(Base):
|
|||||||
def get_by_bangumiid(db: Session, bangumiid: int):
|
def get_by_bangumiid(db: Session, bangumiid: int):
|
||||||
return db.query(Subscribe).filter(Subscribe.bangumiid == bangumiid).first()
|
return db.query(Subscribe).filter(Subscribe.bangumiid == bangumiid).first()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@db_query
|
||||||
|
def get_by_mediaid(db: Session, mediaid: str):
|
||||||
|
return db.query(Subscribe).filter(Subscribe.mediaid == mediaid).first()
|
||||||
|
|
||||||
@db_update
|
@db_update
|
||||||
def delete_by_tmdbid(self, db: Session, tmdbid: int, season: int):
|
def delete_by_tmdbid(self, db: Session, tmdbid: int, season: int):
|
||||||
subscrbies = self.get_by_tmdbid(db, tmdbid, season)
|
subscrbies = self.get_by_tmdbid(db, tmdbid, season)
|
||||||
@@ -149,6 +155,13 @@ class Subscribe(Base):
|
|||||||
subscribe.delete(db, subscribe.id)
|
subscribe.delete(db, subscribe.id)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@db_update
|
||||||
|
def delete_by_mediaid(self, db: Session, mediaid: str):
|
||||||
|
subscribe = self.get_by_mediaid(db, mediaid)
|
||||||
|
if subscribe:
|
||||||
|
subscribe.delete(db, subscribe.id)
|
||||||
|
return True
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@db_query
|
@db_query
|
||||||
def list_by_username(db: Session, username: str, state: str = None, mtype: str = None):
|
def list_by_username(db: Session, username: str, state: str = None, mtype: str = None):
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ class SubscribeHistory(Base):
|
|||||||
tvdbid = Column(Integer)
|
tvdbid = Column(Integer)
|
||||||
doubanid = Column(String, index=True)
|
doubanid = Column(String, index=True)
|
||||||
bangumiid = Column(Integer, index=True)
|
bangumiid = Column(Integer, index=True)
|
||||||
|
mediaid = Column(String, index=True)
|
||||||
# 季号
|
# 季号
|
||||||
season = Column(Integer)
|
season = Column(Integer)
|
||||||
# 海报
|
# 海报
|
||||||
|
|||||||
@@ -79,8 +79,6 @@ class MediaInfo(BaseModel):
|
|||||||
title_year: Optional[str] = None
|
title_year: Optional[str] = None
|
||||||
# 当前指定季,如有
|
# 当前指定季,如有
|
||||||
season: Optional[int] = None
|
season: Optional[int] = None
|
||||||
# 合集等id
|
|
||||||
collection_id: Optional[int] = None
|
|
||||||
# TMDB ID
|
# TMDB ID
|
||||||
tmdb_id: Optional[int] = None
|
tmdb_id: Optional[int] = None
|
||||||
# IMDB ID
|
# IMDB ID
|
||||||
@@ -91,6 +89,12 @@ class MediaInfo(BaseModel):
|
|||||||
douban_id: Optional[str] = None
|
douban_id: Optional[str] = None
|
||||||
# Bangumi ID
|
# Bangumi ID
|
||||||
bangumi_id: Optional[int] = None
|
bangumi_id: Optional[int] = None
|
||||||
|
# 合集ID
|
||||||
|
collection_id: Optional[int] = None
|
||||||
|
# 其它媒体ID前缀
|
||||||
|
mediaid_prefix: Optional[str] = None
|
||||||
|
# 其它媒体ID值
|
||||||
|
media_id: Optional[str] = None
|
||||||
# 媒体原语种
|
# 媒体原语种
|
||||||
original_language: Optional[str] = None
|
original_language: Optional[str] = None
|
||||||
# 媒体原发行标题
|
# 媒体原发行标题
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ class MediaRecognizeConvertEventData(ChainEventData):
|
|||||||
convert_type (str): 转换类型 仅支持:themoviedb/douban,需要转换为对应的媒体数据并返回
|
convert_type (str): 转换类型 仅支持:themoviedb/douban,需要转换为对应的媒体数据并返回
|
||||||
|
|
||||||
# 输出参数
|
# 输出参数
|
||||||
media_dict (dict): TheMovieDb或豆瓣的媒体数据
|
media_dict (dict): TheMovieDb/豆瓣的媒体数据
|
||||||
"""
|
"""
|
||||||
# 输入参数
|
# 输入参数
|
||||||
mediaid: str = Field(..., description="媒体ID")
|
mediaid: str = Field(..., description="媒体ID")
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class Subscribe(BaseModel):
|
|||||||
tmdbid: Optional[int] = None
|
tmdbid: Optional[int] = None
|
||||||
doubanid: Optional[str] = None
|
doubanid: Optional[str] = None
|
||||||
bangumiid: Optional[int] = None
|
bangumiid: Optional[int] = None
|
||||||
|
mediaid: Optional[str] = None
|
||||||
# 季号
|
# 季号
|
||||||
season: Optional[int] = None
|
season: Optional[int] = None
|
||||||
# 海报
|
# 海报
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
"""2.1.0
|
||||||
|
|
||||||
|
Revision ID: ca5461f314f2
|
||||||
|
Revises: 55390f1f77c1
|
||||||
|
Create Date: 2025-02-06 18:28:00.644571
|
||||||
|
|
||||||
|
"""
|
||||||
|
import contextlib
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects import sqlite
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'ca5461f314f2'
|
||||||
|
down_revision = '55390f1f77c1'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
# 订阅增加mediaid
|
||||||
|
with contextlib.suppress(Exception):
|
||||||
|
op.add_column('subscribe', sa.Column('mediaid', sa.String(), nullable=True))
|
||||||
|
op.create_index('ix_subscribe_mediaid', 'subscribe', ['mediaid'], unique=False)
|
||||||
|
op.add_column('subscribehistory', sa.Column('mediaid', sa.String(), nullable=True))
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
pass
|
||||||
Reference in New Issue
Block a user