diff --git a/astrbot/core/provider/sources/gemini_source.py b/astrbot/core/provider/sources/gemini_source.py index 682fcbbb1..d5e52edea 100644 --- a/astrbot/core/provider/sources/gemini_source.py +++ b/astrbot/core/provider/sources/gemini_source.py @@ -18,7 +18,7 @@ class SimpleGoogleGenAIClient(): self.api_base = api_base[:-1] else: self.api_base = api_base - self.client = aiohttp.ClientSession() + self.client = aiohttp.ClientSession(trust_env=True) async def models_list(self) -> List[str]: request_url = f"{self.api_base}/v1beta/models?key={self.api_key}" diff --git a/astrbot/core/updator.py b/astrbot/core/updator.py index 2374e8a1d..66322f4ec 100644 --- a/astrbot/core/updator.py +++ b/astrbot/core/updator.py @@ -11,7 +11,7 @@ class AstrBotUpdator(RepoZipUpdator): def __init__(self, repo_mirror: str = "") -> None: super().__init__(repo_mirror) self.MAIN_PATH = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../")) - self.ASTRBOT_RELEASE_API = "https://api.github.com/repos/Soulter/AstrBot/releases" + self.ASTRBOT_RELEASE_API = "https://api.soulter.top/releases" def terminate_child_processes(self): try: diff --git a/astrbot/core/utils/io.py b/astrbot/core/utils/io.py index 0ef14925d..2b9dc7fa9 100644 --- a/astrbot/core/utils/io.py +++ b/astrbot/core/utils/io.py @@ -70,7 +70,7 @@ async def download_image_by_url(url: str, post: bool = False, post_data: dict = 下载图片, 返回 path ''' try: - async with aiohttp.ClientSession() as session: + async with aiohttp.ClientSession(trust_env=True) as session: if post: async with session.post(url, json=post_data) as resp: if not path: @@ -91,7 +91,7 @@ async def download_image_by_url(url: str, post: bool = False, post_data: dict = # 关闭SSL验证 ssl_context = ssl.create_default_context() ssl_context.set_ciphers('DEFAULT') - async with aiohttp.ClientSession(trust_env=False) as session: + async with aiohttp.ClientSession() as session: if post: async with session.get(url, ssl=ssl_context) as resp: return save_temp_img(await resp.read()) @@ -106,8 +106,8 @@ async def download_file(url: str, path: str, show_progress: bool = False): 从指定 url 下载文件到指定路径 path ''' try: - async with aiohttp.ClientSession() as session: - async with session.get(url, timeout=300) as resp: + async with aiohttp.ClientSession(trust_env=True) as session: + async with session.get(url, timeout=120) as resp: if resp.status != 200: raise Exception(f"下载文件失败: {resp.status}") total_size = int(resp.headers.get('content-length', 0)) @@ -130,8 +130,8 @@ async def download_file(url: str, path: str, show_progress: bool = False): # 关闭SSL验证 ssl_context = ssl.create_default_context() ssl_context.set_ciphers('DEFAULT') - async with aiohttp.ClientSession(trust_env=False) as session: - async with session.get(url, ssl=ssl_context, timeout=300) as resp: + async with aiohttp.ClientSession() as session: + async with session.get(url, ssl=ssl_context, timeout=120) as resp: total_size = int(resp.headers.get('content-length', 0)) downloaded_size = 0 start_time = time.time() diff --git a/astrbot/core/utils/metrics.py b/astrbot/core/utils/metrics.py index 8acbb80b3..0064f62d3 100644 --- a/astrbot/core/utils/metrics.py +++ b/astrbot/core/utils/metrics.py @@ -30,7 +30,7 @@ class Metric(): pass try: - async with aiohttp.ClientSession() as session: + async with aiohttp.ClientSession(trust_env=True) as session: async with session.post(base_url, json=payload, timeout=3) as response: if response.status != 200: pass diff --git a/astrbot/core/utils/t2i/local_strategy.py b/astrbot/core/utils/t2i/local_strategy.py index c937aaf51..cb0ad7423 100644 --- a/astrbot/core/utils/t2i/local_strategy.py +++ b/astrbot/core/utils/t2i/local_strategy.py @@ -83,7 +83,7 @@ class LocalRenderStrategy(RenderStrategy): try: image_url = re.findall(IMAGE_REGEX, line)[0] print(image_url) - async with aiohttp.ClientSession() as session: + async with aiohttp.ClientSession(trust_env=True) as session: async with session.get(image_url) as resp: image_res = Image.open(BytesIO(await resp.read())) images[i] = image_res diff --git a/astrbot/core/utils/t2i/network_strategy.py b/astrbot/core/utils/t2i/network_strategy.py index 6d6b62e4e..a8254e088 100644 --- a/astrbot/core/utils/t2i/network_strategy.py +++ b/astrbot/core/utils/t2i/network_strategy.py @@ -33,7 +33,7 @@ class NetworkRenderStrategy(RenderStrategy): } } if return_url: - async with aiohttp.ClientSession() as session: + async with aiohttp.ClientSession(trust_env=True) as session: async with session.post(f"{self.BASE_RENDER_URL}/generate", json=post_data) as resp: ret = await resp.json() return f"{self.BASE_RENDER_URL}/{ret['data']['id']}" diff --git a/astrbot/core/zip_updator.py b/astrbot/core/zip_updator.py index ade94fa6e..39df1c3da 100644 --- a/astrbot/core/zip_updator.py +++ b/astrbot/core/zip_updator.py @@ -29,7 +29,7 @@ class RepoZipUpdator(): 返回一个列表,每个元素是一个字典,包含版本号、发布时间、更新内容、commit hash等信息。 ''' try: - async with aiohttp.ClientSession() as session: + async with aiohttp.ClientSession(trust_env=True) as session: async with session.get(url) as response: result = await response.json() if not result: @@ -111,7 +111,7 @@ class RepoZipUpdator(): releases = await self.fetch_release_info(url=release_url) if not releases: # download from the default branch directly. - logger.warning(f"未在仓库 {author}/{repo} 中找到任何发布版本,正在从默认分支下载。") + logger.info(f"未在仓库 {author}/{repo} 中找到任何发布版本,正在从默认分支下载。") release_url = f"https://github.com/{author}/{repo}/archive/refs/heads/master.zip" else: release_url = releases[0]['zipball_url'] diff --git a/astrbot/dashboard/routes/plugin.py b/astrbot/dashboard/routes/plugin.py index bc42d508e..b2bdd8d67 100644 --- a/astrbot/dashboard/routes/plugin.py +++ b/astrbot/dashboard/routes/plugin.py @@ -27,7 +27,7 @@ class PluginRoute(Route): async def get_online_plugins(self): url = "https://soulter.github.io/AstrBot_Plugins_Collection/plugins.json" try: - async with aiohttp.ClientSession() as session: + async with aiohttp.ClientSession(trust_env=True) as session: async with session.get(url) as response: result = await response.json() return Response().ok(result).__dict__ diff --git a/astrbot/dashboard/routes/stat.py b/astrbot/dashboard/routes/stat.py index 2cd33b4e4..4e5d68ecd 100644 --- a/astrbot/dashboard/routes/stat.py +++ b/astrbot/dashboard/routes/stat.py @@ -15,7 +15,6 @@ class StatRoute(Route): self.routes = { '/stat/get': ('GET', self.get_stat), '/stat/version': ('GET', self.get_version), - '/stat/dashboard-version': ('GET', self.get_dashboard_version), '/stat/start-time': ('GET', self.get_start_time), '/stat/restart-core': ('GET', self.restart_core) } @@ -37,16 +36,6 @@ class StatRoute(Route): "version": VERSION }).__dict__ - async def get_dashboard_version(self): - async with aiohttp.ClientSession() as session: - async with session.get('https://api.github.com/repos/Soulter/Astrbot-dashboard/actions/artifacts') as resp: - data = await resp.json() - return Response().ok({ - "data": data, - "mark": "unimplemented feature" - }).__dict__ - - async def get_start_time(self): return Response().ok({ "start_time": self.core_lifecycle.start_time diff --git a/astrbot/dashboard/routes/update.py b/astrbot/dashboard/routes/update.py index 2494ee6bf..e6e9b90c6 100644 --- a/astrbot/dashboard/routes/update.py +++ b/astrbot/dashboard/routes/update.py @@ -4,6 +4,8 @@ from .route import Route, Response, RouteContext from quart import request from astrbot.core.updator import AstrBotUpdator from astrbot.core import logger, pip_installer +from astrbot.core.utils.io import download_dashboard, get_dashboard_version +from astrbot.core.config.default import VERSION class UpdateRoute(Route): def __init__(self, context: RouteContext, astrbot_updator: AstrBotUpdator) -> None: @@ -17,15 +19,24 @@ class UpdateRoute(Route): self.register_routes() async def check_update(self): + type_ = request.args.get('type', None) + try: - ret = await self.astrbot_updator.check_update(None, None) - return Response( - status="success", - message=str(ret) if ret is not None else "已经是最新版本了。", - data={ - "has_new_version": ret is not None - } - ).__dict__ + if type_ == 'dashboard': + dv = await get_dashboard_version() + return Response().ok({ + "has_new_version": dv != f"v{VERSION}", + "current_version": dv + }).__dict__ + else: + ret = await self.astrbot_updator.check_update(None, None) + return Response( + status="success", + message=str(ret) if ret is not None else "已经是最新版本了。", + data={ + "has_new_version": ret is not None + } + ).__dict__ except Exception as e: logger.error(traceback.format_exc()) return Response().error(e.__str__()).__dict__ @@ -41,6 +52,13 @@ class UpdateRoute(Route): latest = False try: await self.astrbot_updator.update(latest=latest, version=version) + + if latest: + try: + await download_dashboard() + except Exception as e: + logger.error(f"下载管理面板文件失败: {e}。") + if reboot: threading.Thread(target=self.astrbot_updator._reboot, args=(2, )).start() return Response().ok(None, "更新成功,AstrBot 将在 2 秒内全量重启以应用新的代码。").__dict__ diff --git a/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue b/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue index dae789c65..96148f7a3 100644 --- a/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue +++ b/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue @@ -136,11 +136,15 @@ commonStore.getStartTime(); - 更新项目 + 更新 AstrBot

升级到最新版本

+ +
+ 会同时尝试更新机器人主程序和管理面板。如果您正在使用 Docker 部署,也可以重新拉取镜像或者使用 watchtower 来自动监控拉取。 +

{{ updateStatus }}

@@ -149,6 +153,9 @@ commonStore.getStartTime();

切换到指定版本或指定提交

+
+ 跳到旧版本不会重新下载管理面板文件,这可能会造成部分数据显示错误。您可在 此处 找到对应的面板文件 dist.zip,解压后替换 data/dist 文件夹即可。 +
diff --git a/dashboard/src/layouts/full/vertical-sidebar/VerticalSidebar.vue b/dashboard/src/layouts/full/vertical-sidebar/VerticalSidebar.vue index e3c8c1688..58afcbea2 100644 --- a/dashboard/src/layouts/full/vertical-sidebar/VerticalSidebar.vue +++ b/dashboard/src/layouts/full/vertical-sidebar/VerticalSidebar.vue @@ -27,10 +27,10 @@ const sidebarMenu = shallowRef(sidebarItems); 构建: {{ buildVer }} - 构建: embedded + 构建: embedded @@ -50,19 +50,12 @@ export default { }, data: () => ({ version: "", - buildVer: "" + buildVer: "", + hasWebUIUpdate: false, }), mounted() { this.get_version() - fetch('/assets/version').then((res) => { - return res.text() - }).then((res) => { - if (res.length > 10) { - // 不是版本,不显示 😎 - return - } - this.buildVer = res.replace(/\s+/g, '') - }) + this.check_webui_update() }, methods: { get_version() { @@ -73,6 +66,16 @@ export default { .catch((err) => { console.log(err); }); + }, + check_webui_update() { + axios.get('/api/update/check?type=dashboard') + .then((res) => { + this.hasWebUIUpdate = res.data.data.has_new_version; + this.buildVer = res.data.data.current_version; + }) + .catch((err) => { + console.log(err); + }); } }, }; diff --git a/packages/astrbot/main.py b/packages/astrbot/main.py index 6feed5231..3523c985b 100644 --- a/packages/astrbot/main.py +++ b/packages/astrbot/main.py @@ -24,7 +24,7 @@ class Main(star.Star): async def _query_astrbot_notice(self): try: - async with aiohttp.ClientSession() as session: + async with aiohttp.ClientSession(trust_env=True) as session: async with session.get("https://astrbot.soulter.top/notice.json", timeout=2) as resp: return (await resp.json())["notice"] except BaseException: diff --git a/packages/python_interpreter/main.py b/packages/python_interpreter/main.py index 5b5dc7325..ccd1f1cd6 100644 --- a/packages/python_interpreter/main.py +++ b/packages/python_interpreter/main.py @@ -127,7 +127,7 @@ class Main(star.Star): s3_file_url = f"{S3_URL}/{uuid.uuid4().hex}{ext}" - async with aiohttp.ClientSession(headers = {"Accept": "application/json"}) as session: + async with aiohttp.ClientSession(headers = {"Accept": "application/json"}, trust_env=True) as session: async with session.put(s3_file_url, data=file) as resp: if resp.status != 200: raise Exception(f"Failed to upload image: {resp.status}") @@ -159,7 +159,7 @@ class Main(star.Star): async def download_image(self, image_url: str, workplace_path: str, filename: str) -> str: '''Download image from url to workplace_path''' - async with aiohttp.ClientSession() as session: + async with aiohttp.ClientSession(trust_env=True) as session: async with session.get(image_url) as resp: if resp.status != 200: return "" diff --git a/packages/web_searcher/main.py b/packages/web_searcher/main.py index 59fa0e5ad..2186d67b4 100644 --- a/packages/web_searcher/main.py +++ b/packages/web_searcher/main.py @@ -39,7 +39,7 @@ class Main(star.Star): '''获取网页内容''' header = HEADERS header.update({'User-Agent': random.choice(USER_AGENTS)}) - async with aiohttp.ClientSession() as session: + async with aiohttp.ClientSession(trust_env=True) as session: async with session.get(url, headers=header, timeout=6) as response: html = await response.text(encoding="utf-8") doc = Document(html)