mirror of
https://github.com/langbot-app/LangBot.git
synced 2025-11-26 03:44:58 +08:00
feat: 公告和更新检查
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import abc
|
import abc
|
||||||
import uuid
|
import uuid
|
||||||
import json
|
import json
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from ..provider.requester import modelmgr as llm_model_mgr
|
|||||||
from ..provider.sysprompt import sysprompt as llm_prompt_mgr
|
from ..provider.sysprompt import sysprompt as llm_prompt_mgr
|
||||||
from ..provider.tools import toolmgr as llm_tool_mgr
|
from ..provider.tools import toolmgr as llm_tool_mgr
|
||||||
from ..config import manager as config_mgr
|
from ..config import manager as config_mgr
|
||||||
# from ..utils.center import v2 as center_mgr
|
from ..audit.center import v2 as center_mgr
|
||||||
from ..command import cmdmgr
|
from ..command import cmdmgr
|
||||||
from ..plugin import manager as plugin_mgr
|
from ..plugin import manager as plugin_mgr
|
||||||
from . import pool, controller
|
from . import pool, controller
|
||||||
@@ -35,7 +35,7 @@ class Application:
|
|||||||
|
|
||||||
tips_mgr: config_mgr.ConfigManager = None
|
tips_mgr: config_mgr.ConfigManager = None
|
||||||
|
|
||||||
# ctr_mgr: center_mgr.V2CenterAPI = None
|
ctr_mgr: center_mgr.V2CenterAPI = None
|
||||||
|
|
||||||
plugin_mgr: plugin_mgr.PluginManager = None
|
plugin_mgr: plugin_mgr.PluginManager = None
|
||||||
|
|
||||||
@@ -61,13 +61,11 @@ class Application:
|
|||||||
await self.plugin_mgr.load_plugins()
|
await self.plugin_mgr.load_plugins()
|
||||||
await self.plugin_mgr.initialize_plugins()
|
await self.plugin_mgr.initialize_plugins()
|
||||||
|
|
||||||
|
try:
|
||||||
tasks = [
|
tasks = [
|
||||||
asyncio.create_task(self.im_mgr.run()),
|
asyncio.create_task(self.im_mgr.run()),
|
||||||
asyncio.create_task(self.ctrl.run())
|
asyncio.create_task(self.ctrl.run())
|
||||||
]
|
]
|
||||||
|
|
||||||
try:
|
|
||||||
|
|
||||||
await asyncio.wait(tasks)
|
await asyncio.wait(tasks)
|
||||||
|
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ from ..platform import manager as im_mgr
|
|||||||
from ..command import cmdmgr
|
from ..command import cmdmgr
|
||||||
from ..plugin import manager as plugin_mgr
|
from ..plugin import manager as plugin_mgr
|
||||||
from ..audit.center import v2 as center_v2
|
from ..audit.center import v2 as center_v2
|
||||||
from ..utils import version, proxy
|
from ..utils import version, proxy, announce
|
||||||
|
|
||||||
use_override = False
|
use_override = False
|
||||||
|
|
||||||
@@ -82,16 +82,26 @@ async def make_app() -> app.Application:
|
|||||||
ap.cfg_mgr = cfg_mgr
|
ap.cfg_mgr = cfg_mgr
|
||||||
ap.tips_mgr = tips_mgr
|
ap.tips_mgr = tips_mgr
|
||||||
|
|
||||||
ap.query_pool = pool.QueryPool()
|
|
||||||
|
|
||||||
proxy_mgr = proxy.ProxyManager(ap)
|
proxy_mgr = proxy.ProxyManager(ap)
|
||||||
await proxy_mgr.initialize()
|
await proxy_mgr.initialize()
|
||||||
ap.proxy_mgr = proxy_mgr
|
ap.proxy_mgr = proxy_mgr
|
||||||
|
|
||||||
|
# 发送公告
|
||||||
|
ann_mgr = announce.AnnouncementManager(ap)
|
||||||
|
announcements = await ann_mgr.fetch_new()
|
||||||
|
|
||||||
|
for ann in announcements:
|
||||||
|
ap.logger.info(f'[公告] {ann.time}: {ann.content}')
|
||||||
|
|
||||||
|
ap.query_pool = pool.QueryPool()
|
||||||
|
|
||||||
ver_mgr = version.VersionManager(ap)
|
ver_mgr = version.VersionManager(ap)
|
||||||
await ver_mgr.initialize()
|
await ver_mgr.initialize()
|
||||||
ap.ver_mgr = ver_mgr
|
ap.ver_mgr = ver_mgr
|
||||||
|
|
||||||
|
if await ap.ver_mgr.is_new_version_available():
|
||||||
|
ap.logger.info("有新版本可用,请使用 !update 命令更新")
|
||||||
|
|
||||||
plugin_mgr_inst = plugin_mgr.PluginManager(ap)
|
plugin_mgr_inst = plugin_mgr.PluginManager(ap)
|
||||||
await plugin_mgr_inst.initialize()
|
await plugin_mgr_inst.initialize()
|
||||||
ap.plugin_mgr = plugin_mgr_inst
|
ap.plugin_mgr = plugin_mgr_inst
|
||||||
@@ -109,7 +119,7 @@ async def make_app() -> app.Application:
|
|||||||
"msg_source": cfg['msg_source_adapter'],
|
"msg_source": cfg['msg_source_adapter'],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
# ap.ctr_mgr = center_v2_api
|
ap.ctr_mgr = center_v2_api
|
||||||
|
|
||||||
cmd_mgr_inst = cmdmgr.CommandManager(ap)
|
cmd_mgr_inst = cmdmgr.CommandManager(ap)
|
||||||
await cmd_mgr_inst.initialize()
|
await cmd_mgr_inst.initialize()
|
||||||
|
|||||||
106
pkg/utils/announce.py
Normal file
106
pkg/utils/announce.py
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
import typing
|
||||||
|
import os
|
||||||
|
import base64
|
||||||
|
|
||||||
|
import pydantic
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from ..core import app
|
||||||
|
|
||||||
|
|
||||||
|
class Announcement(pydantic.BaseModel):
|
||||||
|
"""公告"""
|
||||||
|
|
||||||
|
id: int
|
||||||
|
|
||||||
|
time: str
|
||||||
|
|
||||||
|
timestamp: int
|
||||||
|
|
||||||
|
content: str
|
||||||
|
|
||||||
|
enabled: typing.Optional[bool] = True
|
||||||
|
|
||||||
|
def to_dict(self) -> dict:
|
||||||
|
return {
|
||||||
|
"id": self.id,
|
||||||
|
"time": self.time,
|
||||||
|
"timestamp": self.timestamp,
|
||||||
|
"content": self.content,
|
||||||
|
"enabled": self.enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class AnnouncementManager:
|
||||||
|
"""公告管理器"""
|
||||||
|
|
||||||
|
ap: app.Application = None
|
||||||
|
|
||||||
|
def __init__(self, ap: app.Application):
|
||||||
|
self.ap = ap
|
||||||
|
|
||||||
|
async def fetch_all(
|
||||||
|
self
|
||||||
|
) -> list[Announcement]:
|
||||||
|
"""获取所有公告"""
|
||||||
|
resp = requests.get(
|
||||||
|
url="https://api.github.com/repos/RockChinQ/QChatGPT/contents/res/announcement.json",
|
||||||
|
proxies=self.ap.proxy_mgr.get_forward_proxies(),
|
||||||
|
timeout=5
|
||||||
|
)
|
||||||
|
obj_json = resp.json()
|
||||||
|
b64_content = obj_json["content"]
|
||||||
|
# 解码
|
||||||
|
content = base64.b64decode(b64_content).decode("utf-8")
|
||||||
|
|
||||||
|
return [Announcement(**item) for item in json.loads(content)]
|
||||||
|
|
||||||
|
async def fetch_saved(
|
||||||
|
self
|
||||||
|
) -> list[Announcement]:
|
||||||
|
if not os.path.exists("res/announcement_saved.json"):
|
||||||
|
with open("res/announcement_saved.json", "w", encoding="utf-8") as f:
|
||||||
|
f.write("[]")
|
||||||
|
|
||||||
|
with open("res/announcement_saved.json", "r", encoding="utf-8") as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
if not content:
|
||||||
|
content = '[]'
|
||||||
|
|
||||||
|
return [Announcement(**item) for item in json.loads(content)]
|
||||||
|
|
||||||
|
async def write_saved(
|
||||||
|
self,
|
||||||
|
content: list[Announcement]
|
||||||
|
):
|
||||||
|
|
||||||
|
with open("res/announcement_saved.json", "w", encoding="utf-8") as f:
|
||||||
|
f.write(json.dumps([
|
||||||
|
item.to_dict() for item in content
|
||||||
|
], indent=4, ensure_ascii=False))
|
||||||
|
|
||||||
|
async def fetch_new(
|
||||||
|
self
|
||||||
|
) -> list[Announcement]:
|
||||||
|
"""获取新公告"""
|
||||||
|
all = await self.fetch_all()
|
||||||
|
saved = await self.fetch_saved()
|
||||||
|
|
||||||
|
to_show: list[Announcement] = []
|
||||||
|
|
||||||
|
for item in all:
|
||||||
|
# 遍历saved检查是否有相同id的公告
|
||||||
|
for saved_item in saved:
|
||||||
|
if saved_item.id == item.id:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if item.enabled:
|
||||||
|
# 没有相同id的公告
|
||||||
|
to_show.append(item)
|
||||||
|
|
||||||
|
await self.write_saved(all)
|
||||||
|
return to_show
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
import base64
|
|
||||||
import os
|
|
||||||
import json
|
|
||||||
|
|
||||||
import requests
|
|
||||||
|
|
||||||
|
|
||||||
def read_latest() -> list:
|
|
||||||
import pkg.utils.network as network
|
|
||||||
resp = requests.get(
|
|
||||||
url="https://api.github.com/repos/RockChinQ/QChatGPT/contents/res/announcement.json",
|
|
||||||
proxies=network.wrapper_proxies()
|
|
||||||
)
|
|
||||||
obj_json = resp.json()
|
|
||||||
b64_content = obj_json["content"]
|
|
||||||
# 解码
|
|
||||||
content = base64.b64decode(b64_content).decode("utf-8")
|
|
||||||
return json.loads(content)
|
|
||||||
|
|
||||||
|
|
||||||
def read_saved() -> list:
|
|
||||||
# 已保存的在res/announcement_saved
|
|
||||||
# 检查是否存在
|
|
||||||
if not os.path.exists("res/announcement_saved.json"):
|
|
||||||
with open("res/announcement_saved.json", "w", encoding="utf-8") as f:
|
|
||||||
f.write("[]")
|
|
||||||
|
|
||||||
with open("res/announcement_saved.json", "r", encoding="utf-8") as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
return json.loads(content)
|
|
||||||
|
|
||||||
|
|
||||||
def write_saved(content: list):
|
|
||||||
# 已保存的在res/announcement_saved
|
|
||||||
with open("res/announcement_saved.json", "w", encoding="utf-8") as f:
|
|
||||||
f.write(json.dumps(content, indent=4, ensure_ascii=False))
|
|
||||||
|
|
||||||
|
|
||||||
def fetch_new() -> list:
|
|
||||||
latest = read_latest()
|
|
||||||
saved = read_saved()
|
|
||||||
|
|
||||||
to_show: list = []
|
|
||||||
|
|
||||||
for item in latest:
|
|
||||||
# 遍历saved检查是否有相同id的公告
|
|
||||||
for saved_item in saved:
|
|
||||||
if saved_item["id"] == item["id"]:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
# 没有相同id的公告
|
|
||||||
to_show.append(item)
|
|
||||||
|
|
||||||
write_saved(latest)
|
|
||||||
return to_show
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
|
||||||
resp = requests.get(
|
|
||||||
url="https://api.github.com/repos/RockChinQ/QChatGPT/contents/res/announcement.json",
|
|
||||||
)
|
|
||||||
obj_json = resp.json()
|
|
||||||
b64_content = obj_json["content"]
|
|
||||||
# 解码
|
|
||||||
content = base64.b64decode(b64_content).decode("utf-8")
|
|
||||||
print(json.dumps(json.loads(content), indent=4, ensure_ascii=False))
|
|
||||||
@@ -49,7 +49,8 @@ class VersionManager:
|
|||||||
"""获取发行列表"""
|
"""获取发行列表"""
|
||||||
rls_list_resp = requests.get(
|
rls_list_resp = requests.get(
|
||||||
url="https://api.github.com/repos/RockChinQ/QChatGPT/releases",
|
url="https://api.github.com/repos/RockChinQ/QChatGPT/releases",
|
||||||
proxies=self.ap.proxy_mgr.get_forward_proxies()
|
proxies=self.ap.proxy_mgr.get_forward_proxies(),
|
||||||
|
timeout=5
|
||||||
)
|
)
|
||||||
|
|
||||||
rls_list = rls_list_resp.json()
|
rls_list = rls_list_resp.json()
|
||||||
|
|||||||
Reference in New Issue
Block a user