Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99e5bc3617 | ||
|
|
2411ae4963 |
Binary file not shown.
Binary file not shown.
BIN
data/Books.plist
BIN
data/Books.plist
Binary file not shown.
@@ -70,7 +70,7 @@ class IBookExportApp(CoverMixin, FinishedBooksMixin, QWidget):
|
|||||||
total_books = len(self.sorted_assetids)
|
total_books = len(self.sorted_assetids)
|
||||||
if hasattr(self, 'label') and isinstance(self.label, QLabel):
|
if hasattr(self, 'label') and isinstance(self.label, QLabel):
|
||||||
self.label.setText(f"请选择要导出的书籍【{total_books}本】:")
|
self.label.setText(f"请选择要导出的书籍【{total_books}本】:")
|
||||||
self.label.setStyleSheet("QLabel { background-color: #4c221b; color: #ffffff; font-family: 'STHeiti, Heiti SC, SimHei'; font-weight: bold; padding:4px 6px; border-radius:4px; }")
|
self.label.setStyleSheet("QLabel { background-color: #4c221b; color: #ffffff; font-weight: bold; padding:4px 6px; border-radius:4px; }")
|
||||||
except Exception as _e_lbl:
|
except Exception as _e_lbl:
|
||||||
print('信息: 设置导出提示标签样式失败:', _e_lbl)
|
print('信息: 设置导出提示标签样式失败:', _e_lbl)
|
||||||
# 调整导出 & 配置按钮为同一行 + 圆角胶囊风格
|
# 调整导出 & 配置按钮为同一行 + 圆角胶囊风格
|
||||||
|
|||||||
@@ -354,7 +354,7 @@ class IBookExportApp(CoverMixin, FinishedBooksMixin, QWidget):
|
|||||||
import matplotlib, json
|
import matplotlib, json
|
||||||
matplotlib.rcParams['axes.unicode_minus'] = False
|
matplotlib.rcParams['axes.unicode_minus'] = False
|
||||||
# 优先使用苹方
|
# 优先使用苹方
|
||||||
zh_pref = ['PingFang SC','PingFang','Heiti SC','STHeiti','Hiragino Sans GB','Songti SC','SimHei','Microsoft YaHei']
|
zh_pref = ['PingFang SC','PingFang','Hiragino Sans GB','Songti SC','Microsoft YaHei']
|
||||||
try:
|
try:
|
||||||
from matplotlib import font_manager
|
from matplotlib import font_manager
|
||||||
avail = set(f.name for f in font_manager.fontManager.ttflist)
|
avail = set(f.name for f in font_manager.fontManager.ttflist)
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
重组目录;新增模块拆分、UML、AI 简评与可视化章节整理
|
重组目录;新增模块拆分、UML、AI 简评与可视化章节整理
|
||||||
|
|
||||||
## v1.2
|
## v1.2
|
||||||
**发布时间**: 2025-10-21
|
发布时间: 2025-10-21
|
||||||
|
|
||||||
**版本代号**: CFI 排序与优化版本
|
**版本代号**: CFI 排序与优化版本
|
||||||
|
|
||||||
### 重大更新
|
### 重大更新
|
||||||
|
|||||||
221
release.sh
221
release.sh
@@ -1,221 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Git 自动发布脚本
|
|
||||||
# 功能:检查分支、工作区,生成 tag,并在 Gitea 上创建 Release
|
|
||||||
|
|
||||||
# 1. 检查分支
|
|
||||||
branch=$(git rev-parse --abbrev-ref HEAD)
|
|
||||||
if [ "$branch" != "main" ]; then
|
|
||||||
echo "❌ 错误:请在 main 分支运行,当前是 $branch"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "✅ 分支: $branch"
|
|
||||||
|
|
||||||
# 可选:检查本地 Gitea 配置中的默认分支设置(如果仓库里包含 Gitea 配置)
|
|
||||||
# 读取 custom/conf/app.ini 中的 DEFAULT_BRANCH 值并给出警告(不强制退出)
|
|
||||||
if [ -f custom/conf/app.ini ]; then
|
|
||||||
DEFAULT_BRANCH=$(grep -i '^DEFAULT_BRANCH' custom/conf/app.ini | head -n1 | cut -d'=' -f2 | tr -d ' ')
|
|
||||||
if [ -n "$DEFAULT_BRANCH" ]; then
|
|
||||||
if [ "$DEFAULT_BRANCH" = "main" ]; then
|
|
||||||
echo "⚠️ 警告: Gitea 配置 custom/conf/app.ini 中 DEFAULT_BRANCH 设置为 'main',这可能存在风险"
|
|
||||||
echo " 如果希望强制中止发布,请在脚本中启用退出逻辑。"
|
|
||||||
else
|
|
||||||
echo "ℹ️ Gitea 配置 DEFAULT_BRANCH=$DEFAULT_BRANCH"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 2. 检查工作区是否干净
|
|
||||||
if [ -n "$(git status --porcelain)" ]; then
|
|
||||||
echo "❌ 错误:工作区有未提交的更改,请先提交或 stash"
|
|
||||||
git status
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "✅ 工作区干净"
|
|
||||||
|
|
||||||
# 3. 更新代码
|
|
||||||
echo "⬇️ 拉取远程代码..."
|
|
||||||
git fetch origin
|
|
||||||
git pull origin main
|
|
||||||
echo "✅ 已同步最新代码"
|
|
||||||
|
|
||||||
# 4. 从 release.md 提取版本和说明
|
|
||||||
if [ ! -f release.md ]; then
|
|
||||||
echo "❌ 未找到 release.md"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
VERSION=$(grep "^## v" release.md | tail -n 1 | sed 's/^## //')
|
|
||||||
TAG_MESSAGE=$(awk "/^## $VERSION\$/{flag=1;next}/^## v/{if(flag) flag=0}flag" release.md)
|
|
||||||
|
|
||||||
# 过滤掉 emoji(4 字节 unicode,范围 U+10000 - U+10FFFF),避免 utf8mb4 字符导致服务器侧 collation 问题
|
|
||||||
# 仅在发送到 Gitea 时使用过滤后的内容,保留原始 TAG_MESSAGE 用于本地 tag 注释
|
|
||||||
RELEASE_BODY=$(printf '%s' "$TAG_MESSAGE" | perl -CSD -0777 -pe 's/[\x{10000}-\x{10FFFF}]//g')
|
|
||||||
|
|
||||||
if [ -z "$VERSION" ]; then
|
|
||||||
echo "❌ release.md 中未找到版本号"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "📝 版本号: $VERSION"
|
|
||||||
echo "说明:"
|
|
||||||
echo "$TAG_MESSAGE"
|
|
||||||
|
|
||||||
# 5. 创建 tag(如已存在则删除后重建)
|
|
||||||
if git rev-parse "$VERSION" >/dev/null 2>&1; then
|
|
||||||
echo "⚠️ 标签 $VERSION 已存在,删除旧标签..."
|
|
||||||
git tag -d "$VERSION"
|
|
||||||
git push origin ":refs/tags/$VERSION"
|
|
||||||
fi
|
|
||||||
|
|
||||||
git tag -a "$VERSION" -m "$TAG_MESSAGE"
|
|
||||||
echo "✅ 已创建 tag $VERSION"
|
|
||||||
|
|
||||||
# 6. 推送代码和 tag
|
|
||||||
echo "🚀 推送到远程..."
|
|
||||||
git push origin main
|
|
||||||
git push origin "$VERSION"
|
|
||||||
|
|
||||||
# 7. 创建 Gitea Release
|
|
||||||
echo ""
|
|
||||||
echo "🌐 创建 Gitea Release..."
|
|
||||||
|
|
||||||
# 自动解析 GITEA_URL 和 REPO
|
|
||||||
remote_url=$(git config --get remote.origin.url)
|
|
||||||
if [[ "$remote_url" == ssh://git@biboer.cn:21174/* ]]; then
|
|
||||||
# 特殊处理 biboer.cn:21174 的情况,Web 界面在 /gitea 路径下
|
|
||||||
GITEA_URL="https://biboer.cn/gitea"
|
|
||||||
GITEA_REPO=$(echo "$remote_url" | sed 's|ssh://git@biboer\.cn:21174/||' | sed 's|\.git$||')
|
|
||||||
elif [[ "$remote_url" =~ ^ssh://([^/]+)/([^/]+)/(.+)\.git$ ]]; then
|
|
||||||
GITEA_URL="https://${BASH_REMATCH[1]}"
|
|
||||||
GITEA_REPO="${BASH_REMATCH[2]}/${BASH_REMATCH[3]}"
|
|
||||||
elif [[ "$remote_url" =~ ^([^@]+@[^:]+):([^/]+)/(.+)\.git$ ]]; then
|
|
||||||
# git@biboer.cn:21174/gavin/note-to-mp.git
|
|
||||||
hostport=$(echo "${BASH_REMATCH[1]}" | cut -d@ -f2)
|
|
||||||
GITEA_URL="https://${hostport}"
|
|
||||||
GITEA_REPO="${BASH_REMATCH[2]}/${BASH_REMATCH[3]}"
|
|
||||||
else
|
|
||||||
echo "❌ 无法解析远程地址: $remote_url"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
if [ -z "$GITEA_TOKEN" ]; then
|
|
||||||
echo "⚠️ 未设置 GITEA_TOKEN,只推送了 tag,没有创建 Release"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 如果远程已经存在该 Release(通过 tag 查询),先删除它(避免 409 Conflict)
|
|
||||||
echo "🔍 检查远程 Release 是否已存在..."
|
|
||||||
check_response=$(curl -s -w "\n%{http_code}" \
|
|
||||||
-X GET "$GITEA_URL/api/v1/repos/$GITEA_REPO/releases/tags/$VERSION" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN")
|
|
||||||
|
|
||||||
check_http_code=$(echo "$check_response" | tail -n 1)
|
|
||||||
check_body=$(echo "$check_response" | sed '$d')
|
|
||||||
|
|
||||||
if [ "$check_http_code" -eq 200 ]; then
|
|
||||||
release_id=$(echo "$check_body" | jq -r '.id')
|
|
||||||
echo "⚠️ 远程已存在 Release $VERSION (ID: $release_id),正在删除..."
|
|
||||||
delete_response=$(curl -s -w "\n%{http_code}" \
|
|
||||||
-X DELETE "$GITEA_URL/api/v1/repos/$GITEA_REPO/releases/$release_id" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN")
|
|
||||||
delete_http_code=$(echo "$delete_response" | tail -n 1)
|
|
||||||
if [ "$delete_http_code" -eq 204 ] || [ "$delete_http_code" -eq 200 ]; then
|
|
||||||
echo "✅ 已删除旧的 Release"
|
|
||||||
else
|
|
||||||
echo "⚠️ 删除旧 Release 失败 (HTTP $delete_http_code),继续尝试创建新的 Release"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 使用 jq 生成正确的 JSON
|
|
||||||
JSON_PAYLOAD=$(echo "$RELEASE_BODY" | jq -R -s -c --arg version "$VERSION" '{
|
|
||||||
tag_name: $version,
|
|
||||||
name: $version,
|
|
||||||
body: .,
|
|
||||||
draft: false,
|
|
||||||
prerelease: false
|
|
||||||
}')
|
|
||||||
|
|
||||||
# 尝试创建 Release,若返回 409(冲突),再查询并删除后重试一次
|
|
||||||
echo "🔄 正在创建 Release(首次尝试)..."
|
|
||||||
response_full=$(curl -s -w "\n%{http_code}" \
|
|
||||||
-X POST "$GITEA_URL/api/v1/repos/$GITEA_REPO/releases" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
|
||||||
-d "$JSON_PAYLOAD")
|
|
||||||
|
|
||||||
http_code=$(echo "$response_full" | tail -n 1)
|
|
||||||
resp_body=$(echo "$response_full" | sed '$d')
|
|
||||||
|
|
||||||
if [ "$http_code" -eq 201 ]; then
|
|
||||||
echo "✅ Release 创建成功: $VERSION"
|
|
||||||
else
|
|
||||||
if [ "$http_code" -eq 409 ]; then
|
|
||||||
echo "⚠️ 创建 Release 返回 409 Conflict,尝试删除远程冲突的 Release 并重试..."
|
|
||||||
# 再次查询 Release id
|
|
||||||
check_response=$(curl -s -w "\n%{http_code}" \
|
|
||||||
-X GET "$GITEA_URL/api/v1/repos/$GITEA_REPO/releases/tags/$VERSION" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN")
|
|
||||||
check_http_code=$(echo "$check_response" | tail -n 1)
|
|
||||||
check_body=$(echo "$check_response" | sed '$d')
|
|
||||||
if [ "$check_http_code" -eq 200 ]; then
|
|
||||||
release_id=$(echo "$check_body" | jq -r '.id')
|
|
||||||
delete_response=$(curl -s -w "\n%{http_code}" \
|
|
||||||
-X DELETE "$GITEA_URL/api/v1/repos/$GITEA_REPO/releases/$release_id" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN")
|
|
||||||
delete_http_code=$(echo "$delete_response" | tail -n 1)
|
|
||||||
if [ "$delete_http_code" -eq 204 ] || [ "$delete_http_code" -eq 200 ]; then
|
|
||||||
echo "✅ 已删除冲突的 Release,准备重试创建..."
|
|
||||||
# 重试创建一次
|
|
||||||
retry_response=$(curl -s -w "\n%{http_code}" \
|
|
||||||
-X POST "$GITEA_URL/api/v1/repos/$GITEA_REPO/releases" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
|
||||||
-d "$JSON_PAYLOAD")
|
|
||||||
retry_code=$(echo "$retry_response" | tail -n 1)
|
|
||||||
retry_body=$(echo "$retry_response" | sed '$d')
|
|
||||||
if [ "$retry_code" -eq 201 ]; then
|
|
||||||
echo "✅ Release 创建成功 (重试): $VERSION"
|
|
||||||
else
|
|
||||||
echo "❌ 重试创建 Release 仍然失败 (HTTP $retry_code)"
|
|
||||||
echo "响应: $retry_body"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "❌ 删除冲突 Release 失败 (HTTP $delete_http_code),无法重试"
|
|
||||||
echo "响应: $delete_response"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "❌ 查询冲突 Release 失败 (HTTP $check_http_code),响应: $check_body"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# 如果是 500 并且包含 collation/utf8 相关错误,回退到英文 body 重试
|
|
||||||
if [ "$http_code" -eq 500 ] || echo "$resp_body" | grep -qi "collation\|utf8\|Conversion from collation"; then
|
|
||||||
echo "⚠️ 检测到字符集/编码错误 (HTTP $http_code),尝试回退到英文说明并重试..."
|
|
||||||
ENGLISH_BODY="## Release Notes\n\nThis is release $VERSION: $RELEASE_TITLE\n\nFor detailed Chinese release notes, please see release.md in the repository.\n\nQuick start:\n\n\`\`\`bash\ngit pull origin main\ncd web && npm install\nnpm run dev\n\`\`\`"
|
|
||||||
JSON_PAYLOAD_EN=$(jq -n -c --arg version "$VERSION" --arg name "$VERSION" --arg body "$ENGLISH_BODY" '{tag_name: $version, name: $name, body: $body, draft: false, prerelease: false}')
|
|
||||||
echo "🔄 正在创建 Release(英文回退,重试)..."
|
|
||||||
en_resp=$(curl -s -w "\n%{http_code}" \
|
|
||||||
-X POST "$GITEA_URL/api/v1/repos/$GITEA_REPO/releases" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
|
||||||
-d "$JSON_PAYLOAD_EN")
|
|
||||||
en_code=$(echo "$en_resp" | tail -n 1)
|
|
||||||
en_body=$(echo "$en_resp" | sed '$d')
|
|
||||||
if [ "$en_code" -eq 201 ]; then
|
|
||||||
echo "✅ Release 创建成功 (英文回退): $VERSION"
|
|
||||||
else
|
|
||||||
echo "❌ 英文回退重试失败 (HTTP $en_code)"
|
|
||||||
echo "响应: $en_body"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "❌ Release 创建失败,HTTP $http_code"
|
|
||||||
echo "响应: $resp_body"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "🎉 发布完成!"
|
|
||||||
echo "📦 版本:$VERSION"
|
|
||||||
@@ -39,5 +39,6 @@
|
|||||||
- **细节打磨** - 极致的细节体验和性能优化
|
- **细节打磨** - 极致的细节体验和性能优化
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*最后更新: 2025-10-21*
|
*最后更新: 2025-10-21*
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user