chore: optimize 1panel app builder skill

This commit is contained in:
arch3rPro
2026-05-26 01:07:55 +08:00
parent 155cc17d2c
commit 4092625c30
9 changed files with 905 additions and 925 deletions
+151 -43
View File
@@ -14,6 +14,9 @@ YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# 路径配置
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# 图标源配置
DASHBOARD_ICONS="https://dashboardicons.com/icons"
SIMPLE_ICONS="https://cdn.simpleicons.org"
@@ -21,6 +24,12 @@ SELFHST_ICONS="https://selfh.st/icons"
# 默认输出尺寸
DEFAULT_SIZE=200
MODE="auto"
CACHE_DIR="${ICON_CACHE_DIR:-${SCRIPT_DIR}/../.cache/icons}"
ICON_URL=""
CONNECT_TIMEOUT="${ICON_CONNECT_TIMEOUT:-3}"
MAX_TIME="${ICON_MAX_TIME:-8}"
RETRY="${ICON_RETRY:-1}"
# 打印帮助
print_help() {
@@ -28,13 +37,23 @@ print_help() {
${BLUE}Icon Downloader${NC} - 从多个图标源下载应用图标
${YELLOW}用法:${NC}
$0 <应用名称> [输出文件] [尺寸]
$0 [选项] <应用名称> [输出文件] [尺寸]
${YELLOW}参数:${NC}
应用名称 - 应用的名称(如 alist, nginx, redis
输出文件 - 图标保存路径(默认: ./logo.png
尺寸 - 图标尺寸(默认: 200x200
${YELLOW}选项:${NC}
--mode auto|required|skip|cache-only
auto: 优先缓存,缺失时尝试下载,未找到不创建占位图
required: 找不到图标时返回失败
skip: 跳过图标下载
cache-only: 只使用缓存,不访问网络
--cache-dir <目录>
图标缓存目录(默认: skills/.cache/icons
--url <URL> 从指定 URL 下载图标
${YELLOW}图标源优先级:${NC}
1. Dashboard Icons (dashboardicons.com)
2. Simple Icons (simpleicons.org)
@@ -52,13 +71,59 @@ log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
normalize_name() {
echo "$1" | tr '[:upper:]' '[:lower:]' | tr ' _' '--' | tr -cd 'a-z0-9.-'
}
valid_icon_file() {
local file="$1"
[[ -s "$file" ]] || return 1
if head -c 512 "$file" | grep -qiE '<!doctype|<html|<Error>|AccessDenied'; then
return 1
fi
return 0
}
copy_from_cache() {
local app_name="$1"
local output="$2"
local name_lower
name_lower=$(normalize_name "$app_name")
local ext cached
for ext in png svg webp jpg jpeg; do
cached="${CACHE_DIR}/${name_lower}.${ext}"
if valid_icon_file "$cached"; then
mkdir -p "$(dirname "$output")"
cp "$cached" "$output"
log_info "✓ 使用缓存图标: $cached"
return 0
fi
done
return 1
}
save_to_cache() {
local app_name="$1"
local file="$2"
local name_lower
name_lower=$(normalize_name "$app_name")
mkdir -p "$CACHE_DIR"
cp "$file" "${CACHE_DIR}/${name_lower}.png" 2>/dev/null || true
}
# 下载并调整图标尺寸
download_and_resize() {
local url="$1"
local output="$2"
local size="$3"
local tmp
tmp="$(mktemp)"
if curl -sSL -o "$output" "$url" 2>/dev/null && [[ -s "$output" ]]; then
if curl -fsSL --connect-timeout "$CONNECT_TIMEOUT" --max-time "$MAX_TIME" --retry "$RETRY" -o "$tmp" "$url" 2>/dev/null && valid_icon_file "$tmp"; then
mkdir -p "$(dirname "$output")"
mv "$tmp" "$output"
# 检查是否安装了 ImageMagick 或 sips (macOS)
if command -v convert &>/dev/null; then
convert "$output" -resize "${size}x${size}" "$output" 2>/dev/null || true
@@ -67,6 +132,7 @@ download_and_resize() {
fi
return 0
fi
rm -f "$tmp"
return 1
}
@@ -77,20 +143,32 @@ try_download_icon() {
local size="$3"
local name_lower
name_lower=$(echo "$app_name" | tr '[:upper:]' '[:lower:]' | tr -d ' ')
name_lower=$(normalize_name "$app_name")
log_info "尝试下载图标: $app_name"
if [[ -n "$ICON_URL" ]]; then
log_info "尝试指定图标 URL..."
if download_and_resize "$ICON_URL" "$output" "$size"; then
save_to_cache "$app_name" "$output"
log_info "✓ 从指定 URL 下载成功"
return 0
fi
return 1
fi
# 1. Dashboard Icons
log_info "尝试 Dashboard Icons..."
local dashboard_url="${DASHBOARD_ICONS}/${name_lower}.png"
if download_and_resize "$dashboard_url" "$output" "$size"; then
save_to_cache "$app_name" "$output"
log_info "✓ 从 Dashboard Icons 下载成功"
return 0
fi
# 尝试带 -dark 后缀
if download_and_resize "${DASHBOARD_ICONS}/${name_lower}-dark.png" "$output" "$size"; then
save_to_cache "$app_name" "$output"
log_info "✓ 从 Dashboard Icons (dark) 下载成功"
return 0
fi
@@ -99,18 +177,20 @@ try_download_icon() {
log_info "尝试 Simple Icons..."
local simple_url="${SIMPLE_ICONS}/${name_lower}"
if download_and_resize "$simple_url" "$output" "$size"; then
save_to_cache "$app_name" "$output"
log_info "✓ 从 Simple Icons 下载成功"
return 0
fi
# Simple Icons 也支持 SVG
if curl -sSL -o "${output%.png}.svg" "${SIMPLE_ICONS}/${name_lower}" 2>/dev/null && [[ -s "${output%.png}.svg" ]]; then
if curl -fsSL --connect-timeout "$CONNECT_TIMEOUT" --max-time "$MAX_TIME" --retry "$RETRY" -o "${output%.png}.svg" "${SIMPLE_ICONS}/${name_lower}" 2>/dev/null && valid_icon_file "${output%.png}.svg"; then
log_info "✓ 从 Simple Icons 下载 SVG 成功"
# 如果有 SVG,尝试转换
if command -v convert &>/dev/null; then
convert "${output%.png}.svg" -resize "${size}x${size}" "$output" 2>/dev/null || true
if [[ -s "$output" ]]; then
rm -f "${output%.png}.svg"
save_to_cache "$app_name" "$output"
return 0
fi
fi
@@ -120,6 +200,7 @@ try_download_icon() {
log_info "尝试 selfh.st Icons..."
local selfhst_url="${SELFHST_ICONS}/${name_lower}.png"
if download_and_resize "$selfhst_url" "$output" "$size"; then
save_to_cache "$app_name" "$output"
log_info "✓ 从 selfh.st Icons 下载成功"
return 0
fi
@@ -127,43 +208,58 @@ try_download_icon() {
return 1
}
# 创建占位图标
create_placeholder() {
local output="$1"
local size="$2"
parse_args() {
POSITIONAL=()
while [[ $# -gt 0 ]]; do
case "$1" in
--mode)
MODE="${2:-}"
shift 2
;;
--cache-dir)
CACHE_DIR="${2:-}"
shift 2
;;
--url)
ICON_URL="${2:-}"
shift 2
;;
-h|--help)
print_help
exit 0
;;
--)
shift
POSITIONAL+=("$@")
break
;;
-*)
log_error "未知选项: $1"
exit 2
;;
*)
POSITIONAL+=("$1")
shift
;;
esac
done
log_warn "创建占位图标"
# 使用 ImageMagick 创建简单的占位图标
if command -v convert &>/dev/null; then
convert -size "${size}x${size}" xc:'#4A90E2' \
-gravity center \
-pointsize 48 \
-fill white \
-annotate 0 "?" \
"$output" 2>/dev/null
return $?
fi
# macOS sips 方式
if command -v sips &>/dev/null; then
# 创建一个简单的 1x1 像素 PNG 然后放大
local temp_file="/tmp/placeholder_${RANDOM}.png"
echo -n "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" | base64 -d > "$temp_file"
sips -z "$size" "$size" "$temp_file" --out "$output" &>/dev/null
rm -f "$temp_file"
return $?
fi
# 最简单的占位符
echo -n "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" | base64 -d > "$output"
case "$MODE" in
auto|required|skip|cache-only) ;;
*)
log_error "无效模式: $MODE"
exit 2
;;
esac
}
# 主函数
main() {
local app_name="${1:-}"
local output="${2:-./logo.png}"
local size="${3:-$DEFAULT_SIZE}"
parse_args "$@"
local app_name="${POSITIONAL[0]:-}"
local output="${POSITIONAL[1]:-./logo.png}"
local size="${POSITIONAL[2]:-$DEFAULT_SIZE}"
# 参数检查
if [[ -z "$app_name" ]] || [[ "$app_name" == "-h" ]] || [[ "$app_name" == "--help" ]]; then
@@ -171,10 +267,19 @@ main() {
exit 0
fi
# 确保输出目录存在
local output_dir
output_dir=$(dirname "$output")
mkdir -p "$output_dir"
if [[ "$MODE" == "skip" ]]; then
log_info "跳过图标下载: $app_name"
exit 0
fi
if copy_from_cache "$app_name" "$output"; then
exit 0
fi
if [[ "$MODE" == "cache-only" ]]; then
log_warn "缓存中未找到图标: $app_name"
exit 0
fi
# 尝试下载
if try_download_icon "$app_name" "$output" "$size"; then
@@ -182,13 +287,16 @@ main() {
exit 0
fi
# 下载失败,创建占位符
create_placeholder "$output" "$size"
log_warn "未找到图标,已创建占位符: $output"
rm -f "$output" "${output%.png}.svg"
log_warn "未找到图标,未创建占位图: $output"
log_info "请手动从以下网站下载合适的图标:"
echo " - https://dashboardicons.com/icons?q=${app_name}"
echo " - https://simpleicons.org/?q=${app_name}"
echo " - https://selfh.st/icons/"
if [[ "$MODE" == "required" ]]; then
exit 1
fi
}
# 执行主函数