diff --git a/.github/workflows/dashboard_ci.yml b/.github/workflows/dashboard_ci.yml index 19e681b84..3c96297e8 100644 --- a/.github/workflows/dashboard_ci.yml +++ b/.github/workflows/dashboard_ci.yml @@ -25,7 +25,8 @@ jobs: echo "COMMIT_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV mkdir -p dashboard/dist/assets echo $COMMIT_SHA > dashboard/dist/assets/version - zip -r dashboard/dist.zip dashboard/dist + cd dashboard + zip -r dist.zip dist - name: Archive production artifacts uses: actions/upload-artifact@v4 diff --git a/astrbot/core/updator.py b/astrbot/core/updator.py index d7ee77bf5..e76c6f032 100644 --- a/astrbot/core/updator.py +++ b/astrbot/core/updator.py @@ -89,7 +89,6 @@ class AstrBotUpdator(RepoZipUpdator): file_url = update_data[0]["zipball_url"] elif str(version).startswith("v"): # 更新到指定版本 - logger.info(f"正在更新到指定版本: {version}") for data in update_data: if data["tag_name"] == version: file_url = data["zipball_url"] @@ -98,8 +97,8 @@ class AstrBotUpdator(RepoZipUpdator): else: if len(str(version)) != 40: raise Exception("commit hash 长度不正确,应为 40") - logger.info(f"正在尝试更新到指定 commit: {version}") - file_url = "https://github.com/Soulter/AstrBot/archive/" + version + ".zip" + file_url = f"https://github.com/Soulter/AstrBot/archive/{version}.zip" + logger.info(f"准备更新至指定版本的 AstrBot Core: {version}") if proxy: proxy = proxy.removesuffix("/") @@ -107,6 +106,7 @@ class AstrBotUpdator(RepoZipUpdator): try: await download_file(file_url, "temp.zip") + logger.info("下载 AstrBot Core 更新文件完成,正在执行解压...") self.unzip_file("temp.zip", self.MAIN_PATH) except BaseException as e: raise e diff --git a/astrbot/core/utils/io.py b/astrbot/core/utils/io.py index 2b34c2a14..5f854c5bc 100644 --- a/astrbot/core/utils/io.py +++ b/astrbot/core/utils/io.py @@ -8,6 +8,7 @@ import base64 import zipfile import uuid import psutil +import logging import certifi @@ -16,6 +17,8 @@ from typing import Union from PIL import Image from .astrbot_path import get_astrbot_data_path +logger = logging.getLogger("astrbot") + def on_error(func, path, exc_info): """ @@ -212,19 +215,50 @@ async def get_dashboard_version(): return None -async def download_dashboard(path: str = None, extract_path: str = "data"): +async def download_dashboard( + path: str | None = None, + extract_path: str = "data", + latest: bool = True, + version: str | None = None, + proxy: str | None = None, +): """下载管理面板文件""" if path is None: path = os.path.join(get_astrbot_data_path(), "dashboard.zip") - dashboard_release_url = "https://astrbot-registry.soulter.top/download/astrbot-dashboard/latest/dist.zip" - try: - await download_file(dashboard_release_url, path, show_progress=True) - except BaseException as _: - dashboard_release_url = ( - "https://github.com/Soulter/AstrBot/releases/latest/download/dist.zip" + if latest or len(str(version)) != 40: + logger.info("准备下载最新发行版本的 AstrBot WebUI") + ver_name = "latest" if latest else version + dashboard_release_url = f"https://astrbot-registry.soulter.top/download/astrbot-dashboard/{ver_name}/dist.zip" + try: + await download_file(dashboard_release_url, path, show_progress=True) + except BaseException as _: + if latest: + dashboard_release_url = "https://github.com/Soulter/AstrBot/releases/latest/download/dist.zip" + else: + dashboard_release_url = f"https://github.com/Soulter/AstrBot/releases/download/{version}/dist.zip" + if proxy: + dashboard_release_url = f"{proxy}/{dashboard_release_url}" + await download_file(dashboard_release_url, path, show_progress=True) + else: + logger.info(f"准备下载指定版本的 AstrBot WebUI: {version}") + + url = ( + "https://api.github.com/repos/AstrBotDevs/astrbot-release-harbour/releases" ) - await download_file(dashboard_release_url, path, show_progress=True) - print("解压管理面板文件中...") + if proxy: + url = f"{proxy}/{url}" + async with aiohttp.ClientSession(trust_env=True) as session: + async with session.get(url) as resp: + if resp.status == 200: + releases = await resp.json() + for release in releases: + if version in release["tag_name"]: + download_url = release["assets"][0]["browser_download_url"] + await download_file(download_url, path, show_progress=True) + else: + logger.warning(f"未找到指定的版本的 Dashboard 构建文件: {version}") + return + with zipfile.ZipFile(path, "r") as z: z.extractall(extract_path) diff --git a/astrbot/core/zip_updator.py b/astrbot/core/zip_updator.py index a09342795..c72965e67 100644 --- a/astrbot/core/zip_updator.py +++ b/astrbot/core/zip_updator.py @@ -181,14 +181,13 @@ class RepoZipUpdator: """ os.makedirs(target_dir, exist_ok=True) update_dir = "" - logger.info(f"解压文件: {zip_path}") with zipfile.ZipFile(zip_path, "r") as z: update_dir = z.namelist()[0] z.extractall(target_dir) + logger.debug(f"解压文件完成: {zip_path}") files = os.listdir(os.path.join(target_dir, update_dir)) for f in files: - logger.info(f"移动更新文件/目录: {f}") if os.path.isdir(os.path.join(target_dir, update_dir, f)): if os.path.exists(os.path.join(target_dir, f)): shutil.rmtree(os.path.join(target_dir, f), onerror=on_error) @@ -198,13 +197,13 @@ class RepoZipUpdator: shutil.move(os.path.join(target_dir, update_dir, f), target_dir) try: - logger.info( + logger.debug( f"删除临时更新文件: {zip_path} 和 {os.path.join(target_dir, update_dir)}" ) shutil.rmtree(os.path.join(target_dir, update_dir), onerror=on_error) os.remove(zip_path) except BaseException: - logger.warn( + logger.warning( f"删除更新文件失败,可以手动删除 {zip_path} 和 {os.path.join(target_dir, update_dir)}" ) diff --git a/astrbot/dashboard/routes/update.py b/astrbot/dashboard/routes/update.py index f88e9a208..79aa56bc8 100644 --- a/astrbot/dashboard/routes/update.py +++ b/astrbot/dashboard/routes/update.py @@ -48,7 +48,7 @@ class UpdateRoute(Route): "version": f"v{VERSION}", "has_new_version": ret is not None, "dashboard_version": dv, - "dashboard_has_new_version": dv != f"v{VERSION}", + "dashboard_has_new_version": dv and dv != f"v{VERSION}", }, ).__dict__ except Exception as e: @@ -82,11 +82,12 @@ class UpdateRoute(Route): latest=latest, version=version, proxy=proxy ) - if latest: - try: - await download_dashboard() - except Exception as e: - logger.error(f"下载管理面板文件失败: {e}。") + try: + await download_dashboard( + latest=latest, version=version, proxy=proxy + ) + except Exception as e: + logger.error(f"下载管理面板文件失败: {e}。") # pip 更新依赖 logger.info("更新依赖中...") diff --git a/dashboard/src/i18n/locales/en-US/core/header.json b/dashboard/src/i18n/locales/en-US/core/header.json index c7e354086..ee0949988 100644 --- a/dashboard/src/i18n/locales/en-US/core/header.json +++ b/dashboard/src/i18n/locales/en-US/core/header.json @@ -31,9 +31,9 @@ "description": "Versions marked as pre-release may contain unknown issues or bugs and are not recommended for production use. If you encounter any problems, please visit ", "issueLink": "GitHub Issues" }, - "tip": "💡 TIP: Switching to an older version or a specific version will not re-download the dashboard files, which may cause some data display errors. You can find the corresponding dashboard files dist.zip at", - "tipLink": "here", - "tipContinue": ", extract and replace the data/dist folder. Of course, the frontend source code is in the dashboard directory, you can also build it yourself using npm install and npm build.", + "tip": "💡 TIP:", + "tipLink": "", + "tipContinue": "By default, the corresponding version of the WebUI files will be downloaded when switching versions. The WebUI code is located in the dashboard directory of the project, and you can use npm to build it yourself.", "dockerTip": "The `Update to Latest Version` button will try to update both the bot main program and the dashboard. If you are using Docker deployment, you can also re-pull the image or use", "dockerTipLink": "watchtower", "dockerTipContinue": "to automatically monitor and pull.", diff --git a/dashboard/src/i18n/locales/zh-CN/core/header.json b/dashboard/src/i18n/locales/zh-CN/core/header.json index 11331a419..611ad31c3 100644 --- a/dashboard/src/i18n/locales/zh-CN/core/header.json +++ b/dashboard/src/i18n/locales/zh-CN/core/header.json @@ -31,9 +31,8 @@ "description": "标有预发布标签的版本可能存在未知问题或 Bug,不建议在生产环境使用。如发现问题,请提交至 ", "issueLink": "GitHub Issues" }, - "tip": "💡 TIP: 跳到旧版本或者切换到某个版本不会重新下载管理面板文件,这可能会造成部分数据显示错误。您可在", - "tipLink": "此处", - "tipContinue": "找到对应的面板文件 dist.zip,解压后替换 data/dist 文件夹即可。当然,前端源代码在 dashboard 目录下,你也可以自己使用 npm install 和 npm build 构建。", + "tip": "💡 TIP: ", + "tipContinue": "默认在切换版本时会下载对应版本的 WebUI 文件。WebUI 代码位于项目的 dashboard 目录,您可使用 npm 自行构建。", "dockerTip": "`更新到最新版本` 按钮会同时尝试更新机器人主程序和管理面板。如果您正在使用 Docker 部署,也可以重新拉取镜像或者使用", "dockerTipLink": "watchtower", "dockerTipContinue": "来自动监控拉取。", diff --git a/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue b/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue index 3e4f94f75..1ce5642e4 100644 --- a/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue +++ b/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue @@ -342,8 +342,7 @@ commonStore.getStartTime();