mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 07:27:15 +08:00
refactor: complete runtime configuration migration
This commit is contained in:
@@ -115,7 +115,7 @@ class AgentChatOper(DbOper):
|
||||
}
|
||||
payload = {key: value for key, value in payload.items() if value is not None}
|
||||
if chat:
|
||||
chat.update(self._db, payload)
|
||||
self._stage_update(chat, payload)
|
||||
return self.get(session_id=session_id, user_id=user_id) or self.get(session_id=session_id)
|
||||
|
||||
chat = AgentChat(
|
||||
@@ -134,7 +134,7 @@ class AgentChatOper(DbOper):
|
||||
created_at=now,
|
||||
updated_at=now,
|
||||
)
|
||||
chat.create(self._db)
|
||||
self._stage_create(chat)
|
||||
return self.get(session_id=session_id, user_id=user_id) or self.get(session_id=session_id)
|
||||
|
||||
def save_agent_messages(
|
||||
@@ -153,8 +153,8 @@ class AgentChatOper(DbOper):
|
||||
chat = self.ensure_session(session_id=session_id, user_id=user_id)
|
||||
if not chat:
|
||||
return
|
||||
chat.update(
|
||||
self._db,
|
||||
self._stage_update(
|
||||
chat,
|
||||
{
|
||||
"agent_messages": messages or [],
|
||||
"updated_at": self._now(),
|
||||
@@ -192,8 +192,8 @@ class AgentChatOper(DbOper):
|
||||
return
|
||||
if self.has_custom_title(chat.title):
|
||||
return
|
||||
chat.update(
|
||||
self._db,
|
||||
self._stage_update(
|
||||
chat,
|
||||
{
|
||||
"title": normalized_title,
|
||||
"updated_at": self._now(),
|
||||
@@ -232,8 +232,8 @@ class AgentChatOper(DbOper):
|
||||
if self.has_custom_title(chat.title)
|
||||
else self._normalize_title(title, normalized_messages)
|
||||
)
|
||||
chat.update(
|
||||
self._db,
|
||||
self._stage_update(
|
||||
chat,
|
||||
{
|
||||
"title": normalized_title,
|
||||
"preview": self._normalize_preview(normalized_messages),
|
||||
@@ -311,7 +311,7 @@ class AgentChatOper(DbOper):
|
||||
chat = await self.async_get(session_id=session_id, user_id=user_id)
|
||||
if not chat:
|
||||
return False
|
||||
await AgentChat.async_delete(self._db, chat.id)
|
||||
await self._stage_async_delete(AgentChat, chat.id)
|
||||
return True
|
||||
|
||||
async def async_stage_delete(
|
||||
|
||||
@@ -59,7 +59,7 @@ class DownloadHistoryOper(DbOper):
|
||||
"""
|
||||
新增下载历史
|
||||
"""
|
||||
DownloadHistory(**kwargs).create(self._db)
|
||||
self._stage_create(DownloadHistory(**kwargs))
|
||||
|
||||
def stage_add(self, payload: dict) -> DownloadHistory:
|
||||
"""在调用方同步 Session 中暂存下载历史并返回已分配 ID 的记录。"""
|
||||
@@ -76,7 +76,7 @@ class DownloadHistoryOper(DbOper):
|
||||
"""
|
||||
for file_item in file_items:
|
||||
downloadfile = DownloadFiles(**file_item)
|
||||
downloadfile.create(self._db)
|
||||
self._stage_create(downloadfile)
|
||||
|
||||
def stage_add_files(self, file_items: List[dict]) -> None:
|
||||
"""在调用方事务内批量暂存下载文件,不逐条提交。"""
|
||||
@@ -89,7 +89,7 @@ class DownloadHistoryOper(DbOper):
|
||||
"""
|
||||
清空下载历史文件记录
|
||||
"""
|
||||
DownloadFiles.truncate(self._db)
|
||||
self._stage_truncate(DownloadFiles)
|
||||
|
||||
def get_files_by_hash(self, download_hash: str, state: Optional[int] = None) -> List[DownloadFiles]:
|
||||
"""
|
||||
@@ -171,13 +171,13 @@ class DownloadHistoryOper(DbOper):
|
||||
"""
|
||||
异步删除下载记录。
|
||||
"""
|
||||
await DownloadHistory.async_delete(self._db, historyid)
|
||||
await self._stage_async_delete(DownloadHistory, historyid)
|
||||
|
||||
def truncate(self):
|
||||
"""
|
||||
清空下载记录
|
||||
"""
|
||||
DownloadHistory.truncate(self._db)
|
||||
self._stage_truncate(DownloadHistory)
|
||||
|
||||
def get_last_by(self, mtype=None, title: Optional[str] = None, year: Optional[str] = None,
|
||||
season: Optional[str] = None, episode: Optional[str] = None,
|
||||
@@ -230,7 +230,7 @@ class DownloadHistoryOper(DbOper):
|
||||
"""
|
||||
删除下载记录
|
||||
"""
|
||||
DownloadHistory.delete(self._db, historyid)
|
||||
self._stage_delete(DownloadHistory, historyid)
|
||||
|
||||
def stage_delete_history(self, historyid: int) -> None:
|
||||
"""暂存下载记录删除,不由模型装饰器提交事务。"""
|
||||
@@ -244,4 +244,4 @@ class DownloadHistoryOper(DbOper):
|
||||
"""
|
||||
删除下载文件记录
|
||||
"""
|
||||
DownloadFiles.delete(self._db, downloadfileid)
|
||||
self._stage_delete(DownloadFiles, downloadfileid)
|
||||
|
||||
@@ -35,7 +35,7 @@ class MediaServerOper(DbOper):
|
||||
return False
|
||||
item = MediaServerItem(**kwargs)
|
||||
if not item.get_by_server_itemid(self._db, server, item_id):
|
||||
item.create(self._db)
|
||||
self._stage_create(item)
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -51,10 +51,10 @@ class MediaServerOper(DbOper):
|
||||
|
||||
item = MediaServerItem.get_by_server_itemid(self._db, server, item_id)
|
||||
if item:
|
||||
item.update(self._db, kwargs)
|
||||
self._stage_update(item, kwargs)
|
||||
return False
|
||||
|
||||
MediaServerItem(**kwargs).create(self._db)
|
||||
self._stage_create(MediaServerItem(**kwargs))
|
||||
return True
|
||||
|
||||
def empty(self, server: Optional[str] = None):
|
||||
|
||||
@@ -99,7 +99,7 @@ class MessageOper(DbOper):
|
||||
if k not in Message.__table__.columns.keys(): # noqa
|
||||
kwargs.pop(k)
|
||||
|
||||
return await Message(**kwargs).async_create(self._db)
|
||||
return await self._stage_async_create(Message(**kwargs))
|
||||
|
||||
def list_by_page(self, page: int = 1, count: int = 30) -> list[Message]:
|
||||
"""
|
||||
|
||||
@@ -21,11 +21,11 @@ class PluginDataOper(DbOper):
|
||||
"""
|
||||
plugin = PluginData.get_plugin_data_by_key(self._db, plugin_id, key)
|
||||
if plugin:
|
||||
plugin.update(self._db, {
|
||||
self._stage_update(plugin, {
|
||||
"value": value
|
||||
})
|
||||
else:
|
||||
PluginData(plugin_id=plugin_id, key=key, value=value).create(self._db)
|
||||
self._stage_create(PluginData(plugin_id=plugin_id, key=key, value=value))
|
||||
|
||||
async def async_save(self, plugin_id: str, key: str, value: Any) -> None:
|
||||
"""
|
||||
@@ -39,11 +39,11 @@ class PluginDataOper(DbOper):
|
||||
self._db, plugin_id, key
|
||||
)
|
||||
if plugin:
|
||||
await plugin.async_update(self._db, {"value": value})
|
||||
await self._stage_async_update(plugin, {"value": value})
|
||||
else:
|
||||
await PluginData(
|
||||
plugin_id=plugin_id, key=key, value=value
|
||||
).async_create(self._db)
|
||||
await self._stage_async_create(
|
||||
PluginData(plugin_id=plugin_id, key=key, value=value)
|
||||
)
|
||||
|
||||
def get_data(self, plugin_id: str, key: Optional[str] = None) -> Any:
|
||||
"""
|
||||
@@ -102,7 +102,7 @@ class PluginDataOper(DbOper):
|
||||
"""
|
||||
清空插件数据
|
||||
"""
|
||||
PluginData.truncate(self._db)
|
||||
self._stage_truncate(PluginData)
|
||||
|
||||
def get_data_all(self, plugin_id: str) -> Any:
|
||||
"""
|
||||
|
||||
+24
-22
@@ -21,7 +21,7 @@ class SiteOper(DbOper):
|
||||
"""
|
||||
site = Site(**kwargs)
|
||||
if not site.get_by_domain(self._db, kwargs.get("domain")):
|
||||
site.create(self._db)
|
||||
self._stage_create(site)
|
||||
return True, "新增站点成功"
|
||||
return False, "站点已存在"
|
||||
|
||||
@@ -113,7 +113,7 @@ class SiteOper(DbOper):
|
||||
"""
|
||||
删除站点
|
||||
"""
|
||||
Site.delete(self._db, sid)
|
||||
self._stage_delete(Site, sid)
|
||||
|
||||
def reset(self) -> None:
|
||||
"""清空站点表;兼容入口的事务由组合根统一持有。"""
|
||||
@@ -130,7 +130,7 @@ class SiteOper(DbOper):
|
||||
site = Site.get(self._db, sid)
|
||||
if not site:
|
||||
return None
|
||||
site.update(self._db, payload)
|
||||
self._stage_update(site, payload)
|
||||
return site
|
||||
|
||||
async def async_update(self, sid: int, payload: dict) -> Optional[Site]:
|
||||
@@ -139,7 +139,7 @@ class SiteOper(DbOper):
|
||||
"""
|
||||
site = await self.async_get(sid)
|
||||
if site:
|
||||
await site.async_update(self._db, payload)
|
||||
await self._stage_async_update(site, payload)
|
||||
return site
|
||||
|
||||
def get_by_domain(self, domain: str) -> Optional[Site]:
|
||||
@@ -179,7 +179,7 @@ class SiteOper(DbOper):
|
||||
site = Site.get_by_domain(self._db, domain)
|
||||
if not site:
|
||||
return False, "站点不存在"
|
||||
site.update(self._db, {
|
||||
self._stage_update(site, {
|
||||
"cookie": cookies
|
||||
})
|
||||
return True, "更新站点Cookie成功"
|
||||
@@ -191,7 +191,7 @@ class SiteOper(DbOper):
|
||||
site = Site.get_by_domain(self._db, domain)
|
||||
if not site:
|
||||
return False, "站点不存在"
|
||||
site.update(self._db, {
|
||||
self._stage_update(site, {
|
||||
"rss": rss
|
||||
})
|
||||
return True, "更新站点RSS地址成功"
|
||||
@@ -215,10 +215,10 @@ class SiteOper(DbOper):
|
||||
if siteuserdatas:
|
||||
# 存在则更新
|
||||
if not payload.get("err_msg"):
|
||||
siteuserdatas[0].update(self._db, payload)
|
||||
self._stage_update(siteuserdatas[0], payload)
|
||||
else:
|
||||
# 不存在则插入
|
||||
SiteUserData(**payload).create(self._db)
|
||||
self._stage_create(SiteUserData(**payload))
|
||||
return True, "更新站点用户数据成功"
|
||||
|
||||
def get_userdata(self) -> List[SiteUserData]:
|
||||
@@ -287,9 +287,11 @@ class SiteOper(DbOper):
|
||||
icon_base64 = f"data:image/ico;base64,{icon_base64}" if icon_base64 else ""
|
||||
siteicon = self.get_icon_by_domain(domain)
|
||||
if not siteicon:
|
||||
SiteIcon(name=name, domain=domain, url=icon_url, base64=icon_base64).create(self._db)
|
||||
self._stage_create(
|
||||
SiteIcon(name=name, domain=domain, url=icon_url, base64=icon_base64)
|
||||
)
|
||||
elif icon_base64:
|
||||
siteicon.update(self._db, {
|
||||
self._stage_update(siteicon, {
|
||||
"url": icon_url,
|
||||
"base64": icon_base64
|
||||
})
|
||||
@@ -313,7 +315,7 @@ class SiteOper(DbOper):
|
||||
note = dict(sorted(note.items(), key=lambda x: x[0], reverse=True)[:10])
|
||||
avg_seconds = sum([v for v in note.values()]) // avg_times
|
||||
|
||||
sta.update(self._db, {
|
||||
self._stage_update(sta, {
|
||||
"success": sta.success + 1,
|
||||
"seconds": avg_seconds or sta.seconds,
|
||||
"lst_state": 0,
|
||||
@@ -326,7 +328,7 @@ class SiteOper(DbOper):
|
||||
note = {
|
||||
lst_date: seconds or 1
|
||||
}
|
||||
SiteStatistic(
|
||||
self._stage_create(SiteStatistic(
|
||||
domain=domain,
|
||||
success=1,
|
||||
fail=0,
|
||||
@@ -334,7 +336,7 @@ class SiteOper(DbOper):
|
||||
lst_state=0,
|
||||
lst_mod_date=lst_date,
|
||||
note=note
|
||||
).create(self._db)
|
||||
))
|
||||
|
||||
def fail(self, domain: str):
|
||||
"""
|
||||
@@ -343,19 +345,19 @@ class SiteOper(DbOper):
|
||||
lst_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
sta = SiteStatistic.get_by_domain(self._db, domain)
|
||||
if sta:
|
||||
sta.update(self._db, {
|
||||
self._stage_update(sta, {
|
||||
"fail": sta.fail + 1,
|
||||
"lst_state": 1,
|
||||
"lst_mod_date": lst_date
|
||||
})
|
||||
else:
|
||||
SiteStatistic(
|
||||
self._stage_create(SiteStatistic(
|
||||
domain=domain,
|
||||
success=0,
|
||||
fail=1,
|
||||
lst_state=1,
|
||||
lst_mod_date=lst_date
|
||||
).create(self._db)
|
||||
))
|
||||
|
||||
async def async_success(self, domain: str, seconds: Optional[int] = None):
|
||||
"""
|
||||
@@ -375,7 +377,7 @@ class SiteOper(DbOper):
|
||||
note = dict(sorted(note.items(), key=lambda x: x[0], reverse=True)[:10])
|
||||
avg_seconds = sum([v for v in note.values()]) // avg_times
|
||||
|
||||
await sta.async_update(self._db, {
|
||||
await self._stage_async_update(sta, {
|
||||
"success": sta.success + 1,
|
||||
"seconds": avg_seconds or sta.seconds,
|
||||
"lst_state": 0,
|
||||
@@ -388,7 +390,7 @@ class SiteOper(DbOper):
|
||||
note = {
|
||||
lst_date: seconds or 1
|
||||
}
|
||||
await SiteStatistic(
|
||||
await self._stage_async_create(SiteStatistic(
|
||||
domain=domain,
|
||||
success=1,
|
||||
fail=0,
|
||||
@@ -396,7 +398,7 @@ class SiteOper(DbOper):
|
||||
lst_state=0,
|
||||
lst_mod_date=lst_date,
|
||||
note=note
|
||||
).async_create(self._db)
|
||||
))
|
||||
|
||||
async def async_fail(self, domain: str):
|
||||
"""
|
||||
@@ -405,16 +407,16 @@ class SiteOper(DbOper):
|
||||
lst_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
sta = await SiteStatistic.async_get_by_domain(self._db, domain)
|
||||
if sta:
|
||||
await sta.async_update(self._db, {
|
||||
await self._stage_async_update(sta, {
|
||||
"fail": sta.fail + 1,
|
||||
"lst_state": 1,
|
||||
"lst_mod_date": lst_date
|
||||
})
|
||||
else:
|
||||
await SiteStatistic(
|
||||
await self._stage_async_create(SiteStatistic(
|
||||
domain=domain,
|
||||
success=0,
|
||||
fail=1,
|
||||
lst_state=1,
|
||||
lst_mod_date=lst_date
|
||||
).async_create(self._db)
|
||||
))
|
||||
|
||||
@@ -227,7 +227,7 @@ class SubscribeOper(DbOper):
|
||||
if after_commit:
|
||||
after_commit(subscribe.id)
|
||||
return subscribe.id, "订阅已存在"
|
||||
Subscribe(**_persistable(payload)).create(self._db)
|
||||
self._stage_create(Subscribe(**_persistable(payload)))
|
||||
subscribe = self._exists(identity, username)
|
||||
if not subscribe:
|
||||
return 0, "新增订阅失败"
|
||||
@@ -251,7 +251,7 @@ class SubscribeOper(DbOper):
|
||||
if after_commit:
|
||||
await after_commit(subscribe.id)
|
||||
return subscribe.id, "订阅已存在"
|
||||
await Subscribe(**_persistable(payload)).async_create(self._db)
|
||||
await self._stage_async_create(Subscribe(**_persistable(payload)))
|
||||
subscribe = await self._async_exists(identity, username)
|
||||
if not subscribe:
|
||||
return 0, "新增订阅失败"
|
||||
@@ -472,13 +472,13 @@ class SubscribeOper(DbOper):
|
||||
"""
|
||||
删除订阅
|
||||
"""
|
||||
Subscribe.delete(self._db, rid=sid)
|
||||
self._stage_delete(Subscribe, sid)
|
||||
|
||||
async def async_delete(self, sid: int):
|
||||
"""
|
||||
异步删除订阅。
|
||||
"""
|
||||
await Subscribe.async_delete(self._db, rid=sid)
|
||||
await self._stage_async_delete(Subscribe, sid)
|
||||
|
||||
async def stage_delete(self, sid: int) -> None:
|
||||
"""登记订阅删除但不提交,由 Application UnitOfWork 控制事务边界。"""
|
||||
@@ -493,7 +493,7 @@ class SubscribeOper(DbOper):
|
||||
subscribe = await self.async_get(sid)
|
||||
if subscribe:
|
||||
payload = _normalize_integer_flags(payload)
|
||||
await subscribe.async_update(self._db, payload)
|
||||
await self._stage_async_update(subscribe, payload)
|
||||
return subscribe
|
||||
|
||||
async def async_stage_update(
|
||||
@@ -527,7 +527,7 @@ class SubscribeOper(DbOper):
|
||||
subscribe = self.get(sid)
|
||||
if subscribe:
|
||||
payload = _normalize_integer_flags(payload)
|
||||
subscribe.update(self._db, payload)
|
||||
self._stage_update(subscribe, payload)
|
||||
return subscribe
|
||||
|
||||
def list_by_username(self, username: str, state: Optional[str] = None,
|
||||
@@ -556,7 +556,7 @@ class SubscribeOper(DbOper):
|
||||
if "id" in kwargs:
|
||||
kwargs.pop("id")
|
||||
subscribe = SubscribeHistory(**kwargs)
|
||||
subscribe.create(self._db)
|
||||
self._stage_create(subscribe)
|
||||
|
||||
def exist_history(
|
||||
self, media_source: MediaSource, media_id: str,
|
||||
|
||||
@@ -47,4 +47,4 @@ class SubscribeHistoryOper(DbOper):
|
||||
|
||||
async def async_delete(self, history_id: int) -> None:
|
||||
"""异步删除订阅历史。"""
|
||||
await SubscribeHistory.async_delete(self._db, history_id)
|
||||
await self._stage_async_delete(SubscribeHistory, history_id)
|
||||
|
||||
@@ -43,12 +43,12 @@ class SystemConfigOper(DbOper, metaclass=Singleton):
|
||||
if old_value != value:
|
||||
# 假值(False/0/None/空容器)同样落库而不是删除记录:
|
||||
# 读取端以「无记录」表示未配置并回落默认值,删除会使布尔开关的关闭态无法持久化
|
||||
conf.update(self._db, {"value": value})
|
||||
self._stage_update(conf, {"value": value})
|
||||
return True
|
||||
return None
|
||||
else:
|
||||
conf = SystemConfig(key=key, value=value)
|
||||
conf.create(self._db)
|
||||
self._stage_create(conf)
|
||||
return True
|
||||
|
||||
async def async_set(self, key: Union[str, SystemConfigKey], value: Any) -> Optional[bool]:
|
||||
@@ -78,10 +78,10 @@ class SystemConfigOper(DbOper, metaclass=Singleton):
|
||||
if conf:
|
||||
# 假值(False/0/None/空容器)同样落库而不是删除记录:
|
||||
# 读取端以「无记录」表示未配置并回落默认值,删除会使布尔开关的关闭态无法持久化
|
||||
await conf.async_update(self._db, {"value": value})
|
||||
await self._stage_async_update(conf, {"value": value})
|
||||
else:
|
||||
conf = SystemConfig(key=key, value=value)
|
||||
await conf.async_create(self._db)
|
||||
await self._stage_async_create(conf)
|
||||
# 数据库更新成功后,再更新缓存
|
||||
with self._rlock:
|
||||
self.__SYSTEMCONF[key] = copy.deepcopy(value)
|
||||
@@ -132,5 +132,5 @@ class SystemConfigOper(DbOper, metaclass=Singleton):
|
||||
# 写入数据库
|
||||
conf = SystemConfig.get_by_key(self._db, key)
|
||||
if conf:
|
||||
conf.delete(self._db, conf.id)
|
||||
self._stage_delete(SystemConfig, conf.id)
|
||||
return True
|
||||
|
||||
@@ -177,7 +177,7 @@ class TransferHistoryOper(DbOper):
|
||||
kwargs.update({
|
||||
"date": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
|
||||
})
|
||||
TransferHistory(**kwargs).create(self._db)
|
||||
self._stage_create(TransferHistory(**kwargs))
|
||||
|
||||
def statistic(self, days: int = 7) -> List[Any]:
|
||||
"""
|
||||
@@ -226,7 +226,7 @@ class TransferHistoryOper(DbOper):
|
||||
"""
|
||||
删除转移记录
|
||||
"""
|
||||
TransferHistory.delete(self._db, historyid)
|
||||
self._stage_delete(TransferHistory, historyid)
|
||||
|
||||
def stage_delete(self, historyid: int) -> None:
|
||||
"""暂存整理记录删除,不由模型装饰器提交事务。"""
|
||||
@@ -244,13 +244,13 @@ class TransferHistoryOper(DbOper):
|
||||
"""
|
||||
异步删除转移记录。
|
||||
"""
|
||||
await TransferHistory.async_delete(self._db, historyid)
|
||||
await self._stage_async_delete(TransferHistory, historyid)
|
||||
|
||||
def truncate(self):
|
||||
"""
|
||||
清空转移记录
|
||||
"""
|
||||
TransferHistory.truncate(self._db)
|
||||
self._stage_truncate(TransferHistory)
|
||||
|
||||
def add_force(self, **kwargs) -> Optional[TransferHistory]:
|
||||
"""
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ class UserOper(DbOper):
|
||||
新增用户
|
||||
"""
|
||||
user = User(**kwargs)
|
||||
user.create(self._db)
|
||||
self._stage_create(user)
|
||||
|
||||
def get_by_name(self, name: str) -> Optional[User]:
|
||||
"""
|
||||
|
||||
@@ -31,12 +31,12 @@ class UserConfigOper(DbOper, metaclass=Singleton):
|
||||
conf = UserConfig.get_by_key(db=self._db, username=username, key=key)
|
||||
if conf:
|
||||
if value:
|
||||
conf.update(self._db, {"value": value})
|
||||
self._stage_update(conf, {"value": value})
|
||||
else:
|
||||
conf.delete(self._db, conf.id)
|
||||
self._stage_delete(UserConfig, conf.id)
|
||||
else:
|
||||
conf = UserConfig(username=username, key=key, value=value)
|
||||
conf.create(self._db)
|
||||
self._stage_create(conf)
|
||||
|
||||
def get(self, username: str, key: Optional[Union[str, UserConfigKey]] = None) -> Any:
|
||||
"""
|
||||
|
||||
@@ -67,7 +67,7 @@ class WorkflowOper(DbOper):
|
||||
"""
|
||||
wf = Workflow(**kwargs)
|
||||
if not wf.get_by_name(self._db, kwargs.get("name")):
|
||||
wf.create(self._db)
|
||||
self._stage_create(wf)
|
||||
return True, "新增工作流成功"
|
||||
return False, "工作流已存在"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user