From 99e5bc361738506e9c0273841a30e70baa2079a2 Mon Sep 17 00:00:00 2001 From: douboer Date: Wed, 22 Oct 2025 09:35:43 +0800 Subject: [PATCH] 'update' --- data/AEAnnotation.sqlite | Bin 5849088 -> 5861376 bytes data/BKLibrary.sqlite | Bin 1060864 -> 1060864 bytes data/Books.plist | Bin 550178 -> 550178 bytes ibook_export_app.py | 2 +- ibook_export_app_matplot.py | 2 +- release.md | 5 +- release.sh | 221 ------------------------------------ todolist.md | 1 + 8 files changed, 6 insertions(+), 225 deletions(-) delete mode 100755 release.sh diff --git a/data/AEAnnotation.sqlite b/data/AEAnnotation.sqlite index c9bb0a38506ebb57441cd38d2cbac03e28b5da36..f580aa6fe1f403ce67703ff37590d7976eb5a218 100644 GIT binary patch delta 11163 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 Ma&{LhxH$H|0g9Tn#sB~S delta 1399 zcmYk+eN0nV6aeto`@Z_|`brh?qf!bKDcC|kpamT5Q2CfJEOwNF$eN(b;>=|7$Ml~C z(X^Qc_Nw4XT;hmJT+FrvhIkDV*TpFb!NiQjEF@bRH?nM*qr~9iOw3O0KYK5~o807_ zdvnjb=MAM+$k5OVQB3?xhT+E&mVoNzR8*;F>(qr8pVmK9O-%pk|1}>9dIanATCZ6J zXAZX%kqtf5p1#kFD#w|n<8TKYPWFEHxjne_j&{vmp*5DnIt2g68DQGpiT>Bu%(4D znoJ8vgp2dNY3IR8v%g(uyD9i~Qk2YvXD;5w<%++%u}9~kvhP!EVR^t%DEN}UZa zJnOL%=}A2Qlt}YWsegY*)dhS?T>v{$>I+0(rnge+FZ9q+)4UXSud0y-X{mcv_v1t+ zR*^m}Fbr#t86pNwR_pxIVR>1elzZiv{)YaXKB~*r;Bo3gV5x29>E?vgCPDuL<8>-s zk=Ca;{S78l0R0g-7Sy+kx(nPgH_3rfG4IS~tOoV>BqH~|Dti3!Aw7M3NVXKQQKlRC zA-NIShU5?6n^E4DP=r@Cqfdt9L5b*ZWK%{*l!o|^=^nl|O)&1uT6?^-v-UF+LXJ~E>MWI=_f2o)nMDnUC?DYBt5 zR8C#%JC|lvJ-|=e55eI{dk^6}^vekt1Y{Vf)$5?8jt{t%ve~+G~U?(AktR zha{9zu#9OrNCnk}@w~xWREKt<*HAt3)4ajJ-`m+P)f|XQpbXm52lAjr3G~7>C2%*P zM6#di`$V9jopmxzcqy^b2tZnOvO zMUAM54zDy1Z&SbE%-DSV*o@Tjj7^+2$1Pk7dIRmF7OwTT^MX(KmoYp7^F(DHSfZUW zbtn;RHzA09;t{Wcm<$#|o723529rUXn2CSYpe;2K zYkXloh&t%P{DHcNsu6fg$OnE)C=9nPAsd~wgbH|SoY?n^Dxr*L^7wd%Eri}eohXdD zXooE_)6Cr$RQIWNAaYy9o$mi~5Q2+aH(3fDnZF9-Uer^p-=XH zds_>Mk;pC>dOxC<-8Gdid!5Twl^Lobaw1ada@J;FUya-6ta5v+E2_L+uh0Acd9~Z^ zbXIt>f%NMWk*+x%C$2NnQE^>s&`{$;-*$dVSs>h*{I7OGgR-{-f{t#U7T0wDEdB?c CMe7Ry diff --git a/data/BKLibrary.sqlite b/data/BKLibrary.sqlite index 2679b0b66fa180a6edae7ab9e4397e0c582aff92..788ccaccb72373ff716ebf096ab1649b9f321837 100644 GIT binary patch delta 225 zcmZp8;Lz~EVZ&c_W^4A|Ng6+xlDQ`{>i!aHu4Ck8;ACRrU}92l_t3Z`k~x`8>oZd_ zD@eBat9JWWZAKtw0%B$$W&vVWAZFYCRhvCn%Eq4K+egRaA?m&c%|iCK`pz~mFfceC z)0$N})kqE~t|k^THwZ|p>U{aE<9Ix{-+tR|eVtH~*C4g+EpF^U%mKul+gseYrtA{q zXyBj6|B0iBBZVWJ--g4BL!a*jQ_glhMs8J1iEzr Dz!Xra delta 225 zcmZp8;Lz~EVZ&c_W@GlYNg6+xk{(QE)cqyYT*t`Gz{$kK!NjEA?xAsBBz-cQ)@P=q zry$wpuiEWjwHbk!35c12m<5PgftYRkS8euSDH}_UZyz0x2lv}=`#915@(EQ31_lPl zV_LIHry9wD#ND~;*FofO>%(ZBP?Oj8+g&fVx45wbF$WNHZf|kpnzBobDTkwhe;)rQ wjv|f}j&Ob(4lfRUz8Bl|7`dGpSwP0Omojk!F%J;)0x=&D^KUO@66n?i0GK3F^8f$< diff --git a/data/Books.plist b/data/Books.plist index 703bbee971afa95e29989c7dcb95c561dfd3bfde..cf60aca9b95dfc2976c233f72f0f697f768a6e0f 100644 GIT binary patch delta 30140 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 diff --git a/ibook_export_app.py b/ibook_export_app.py index 99eb959..5d859d1 100644 --- a/ibook_export_app.py +++ b/ibook_export_app.py @@ -70,7 +70,7 @@ class IBookExportApp(CoverMixin, FinishedBooksMixin, QWidget): total_books = len(self.sorted_assetids) if hasattr(self, 'label') and isinstance(self.label, QLabel): 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: print('信息: 设置导出提示标签样式失败:', _e_lbl) # 调整导出 & 配置按钮为同一行 + 圆角胶囊风格 diff --git a/ibook_export_app_matplot.py b/ibook_export_app_matplot.py index 46a0ec1..8804b9c 100644 --- a/ibook_export_app_matplot.py +++ b/ibook_export_app_matplot.py @@ -354,7 +354,7 @@ class IBookExportApp(CoverMixin, FinishedBooksMixin, QWidget): import matplotlib, json 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: from matplotlib import font_manager avail = set(f.name for f in font_manager.fontManager.ttflist) diff --git a/release.md b/release.md index a261e94..06be0e9 100644 --- a/release.md +++ b/release.md @@ -8,8 +8,9 @@ **发布时间**: 2025-09 重组目录;新增模块拆分、UML、AI 简评与可视化章节整理 -## v1.3 -**发布时间**: 2025-10-21 +## v1.2 +发布时间: 2025-10-21 + **版本代号**: CFI 排序与优化版本 ### 重大更新 diff --git a/release.sh b/release.sh deleted file mode 100755 index 4ef8773..0000000 --- a/release.sh +++ /dev/null @@ -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" diff --git a/todolist.md b/todolist.md index 2258daf..ac78400 100644 --- a/todolist.md +++ b/todolist.md @@ -39,5 +39,6 @@ - **细节打磨** - 极致的细节体验和性能优化 --- + *最后更新: 2025-10-21*