feat: implement dashboard download caching and fallback mechanism
- Add local file caching for dashboard downloads with version validation - Implement fallback to 'latest' version if specific version download fails - Add robust error handling in CLI check_dashboard to prevent crashes - Remove dashboard caching from smoke tests (backend-only mode)
This commit is contained in:
@@ -39,7 +39,9 @@ jobs:
|
||||
|
||||
- name: Run smoke tests
|
||||
run: |
|
||||
uv run main.py &
|
||||
# uv run main.py &
|
||||
uv tool install -e . --force
|
||||
astrbot run --backend-only
|
||||
APP_PID=$!
|
||||
|
||||
echo "Waiting for application to start..."
|
||||
|
||||
@@ -45,13 +45,16 @@ async def check_dashboard(astrbot_root: Path) -> None:
|
||||
abort=True,
|
||||
):
|
||||
click.echo("Installing dashboard...")
|
||||
await download_dashboard(
|
||||
path="data/dashboard.zip",
|
||||
extract_path=str(astrbot_root / "data"),
|
||||
version=f"v{VERSION}",
|
||||
latest=False,
|
||||
)
|
||||
click.echo("Dashboard installed successfully")
|
||||
try:
|
||||
await download_dashboard(
|
||||
path="data/dashboard.zip",
|
||||
extract_path=str(astrbot_root / "data"),
|
||||
version=f"v{VERSION}",
|
||||
latest=False,
|
||||
)
|
||||
click.echo("Dashboard installed successfully")
|
||||
except Exception as e:
|
||||
click.echo(f"Failed to install dashboard: {e}")
|
||||
|
||||
case str():
|
||||
if VersionComparator.compare_version(VERSION, dashboard_version) <= 0:
|
||||
|
||||
+100
-28
@@ -285,35 +285,107 @@ async def download_dashboard(
|
||||
else:
|
||||
zip_path = Path(path).absolute()
|
||||
|
||||
if latest or len(str(version)) != 40:
|
||||
ver_name = "latest" if latest else version
|
||||
dashboard_release_url = f"https://astrbot-registry.soulter.top/download/astrbot-dashboard/{ver_name}/dist.zip"
|
||||
logger.info(
|
||||
f"准备下载指定发行版本的 AstrBot WebUI 文件: {dashboard_release_url}",
|
||||
)
|
||||
try:
|
||||
await download_file(
|
||||
dashboard_release_url,
|
||||
str(zip_path),
|
||||
show_progress=True,
|
||||
# 缓存机制
|
||||
cache_dir = Path(get_astrbot_data_path()).absolute() / "cache"
|
||||
if not cache_dir.exists():
|
||||
cache_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
use_cache = False
|
||||
|
||||
# Only use cache if not requesting "latest" (we don't know the version yet)
|
||||
if not latest and version:
|
||||
cache_name = f"dashboard_{version}.zip"
|
||||
cache_path = cache_dir / cache_name
|
||||
|
||||
if cache_path.exists():
|
||||
logger.info(f"发现本地缓存的管理面板文件: {cache_path}")
|
||||
try:
|
||||
with zipfile.ZipFile(cache_path, "r") as z:
|
||||
if z.testzip() is None:
|
||||
logger.info("缓存文件校验通过,将直接使用缓存。")
|
||||
if str(cache_path) != str(zip_path):
|
||||
shutil.copy(cache_path, zip_path)
|
||||
use_cache = True
|
||||
else:
|
||||
logger.warning("缓存文件损坏,将重新下载。")
|
||||
os.remove(cache_path)
|
||||
except zipfile.BadZipFile:
|
||||
logger.warning("缓存文件损坏 (BadZipFile),将重新下载。")
|
||||
os.remove(cache_path)
|
||||
|
||||
if not use_cache:
|
||||
if latest or len(str(version)) != 40:
|
||||
ver_name = "latest" if latest else version
|
||||
dashboard_release_url = f"https://astrbot-registry.soulter.top/download/astrbot-dashboard/{ver_name}/dist.zip"
|
||||
logger.info(
|
||||
f"准备下载指定发行版本的 AstrBot WebUI 文件: {dashboard_release_url}",
|
||||
)
|
||||
except BaseException as _:
|
||||
if latest:
|
||||
dashboard_release_url = "https://github.com/AstrBotDevs/AstrBot/releases/latest/download/dist.zip"
|
||||
else:
|
||||
dashboard_release_url = f"https://github.com/AstrBotDevs/AstrBot/releases/download/{version}/dist.zip"
|
||||
try:
|
||||
await download_file(
|
||||
dashboard_release_url,
|
||||
str(zip_path),
|
||||
show_progress=True,
|
||||
)
|
||||
except BaseException as _:
|
||||
try:
|
||||
if latest:
|
||||
dashboard_release_url = "https://github.com/AstrBotDevs/AstrBot/releases/latest/download/dist.zip"
|
||||
else:
|
||||
dashboard_release_url = f"https://github.com/AstrBotDevs/AstrBot/releases/download/{version}/dist.zip"
|
||||
if proxy:
|
||||
dashboard_release_url = f"{proxy}/{dashboard_release_url}"
|
||||
await download_file(
|
||||
dashboard_release_url,
|
||||
str(zip_path),
|
||||
show_progress=True,
|
||||
)
|
||||
except Exception as e:
|
||||
if not latest:
|
||||
logger.warning(
|
||||
f"下载指定版本({version})失败: {e},尝试下载最新版本。"
|
||||
)
|
||||
await download_dashboard(
|
||||
path=path,
|
||||
extract_path=extract_path,
|
||||
latest=True,
|
||||
proxy=proxy,
|
||||
)
|
||||
return
|
||||
raise e
|
||||
else:
|
||||
url = f"https://github.com/AstrBotDevs/astrbot-release-harbour/releases/download/release-{version}/dist.zip"
|
||||
logger.info(f"准备下载指定版本的 AstrBot WebUI: {url}")
|
||||
if proxy:
|
||||
dashboard_release_url = f"{proxy}/{dashboard_release_url}"
|
||||
await download_file(
|
||||
dashboard_release_url,
|
||||
str(zip_path),
|
||||
show_progress=True,
|
||||
)
|
||||
else:
|
||||
url = f"https://github.com/AstrBotDevs/astrbot-release-harbour/releases/download/release-{version}/dist.zip"
|
||||
logger.info(f"准备下载指定版本的 AstrBot WebUI: {url}")
|
||||
if proxy:
|
||||
url = f"{proxy}/{url}"
|
||||
await download_file(url, str(zip_path), show_progress=True)
|
||||
url = f"{proxy}/{url}"
|
||||
await download_file(url, str(zip_path), show_progress=True)
|
||||
|
||||
# 下载完成后存入缓存
|
||||
try:
|
||||
save_cache_name = None
|
||||
if not latest and version:
|
||||
save_cache_name = f"dashboard_{version}.zip"
|
||||
else:
|
||||
# 尝试从下载的文件中读取版本号
|
||||
try:
|
||||
with zipfile.ZipFile(zip_path, "r") as z:
|
||||
for v_path in ["dist/assets/version", "assets/version"]:
|
||||
try:
|
||||
with z.open(v_path) as f:
|
||||
v = f.read().decode("utf-8").strip()
|
||||
save_cache_name = f"dashboard_{v}.zip"
|
||||
break
|
||||
except KeyError:
|
||||
continue
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if save_cache_name:
|
||||
cache_save_path = cache_dir / save_cache_name
|
||||
if str(zip_path) != str(cache_save_path):
|
||||
shutil.copy(zip_path, cache_save_path)
|
||||
logger.info(f"已缓存管理面板文件至: {cache_save_path}")
|
||||
except Exception as e:
|
||||
logger.warning(f"缓存管理面板文件失败: {e}")
|
||||
|
||||
with zipfile.ZipFile(zip_path, "r") as z:
|
||||
z.extractall(extract_path)
|
||||
|
||||
Reference in New Issue
Block a user