Contribuv/ 豪子博客 Python版
一个基于 Flask 的轻量级个人技术博客,支持 Markdown 写作、文章分类、评论、友情链接、GitHub 项目展示、时间线等。前端为服务端渲染(Jinja2 模板 + 原生 CSS/JS),数据使用 SQLite 存储,零外部服务依赖,开箱即用。
HTML 35.6%
Python 31.6%
CSS 25.3%
JavaScript 7.1%
Shell 0.3%
Batchfile 0.1%
项目文档
文档更新于 5 小时前infowe Blog
一个基于 Flask 的轻量级个人技术博客,支持 Markdown 写作、文章分类、评论、友情链接、GitHub 项目展示、时间线等。前端为服务端渲染(Jinja2 模板 + 原生 CSS/JS),数据使用 SQLite 存储,零外部服务依赖,开箱即用。
当前项目已停止更新,现在以PHP+Mysql重构发布 https://github.com/Contribuv/haozi_blog
功能特性
- 文章发布(Markdown)、分类、标签、精选、阅读时长
- 前台:首页、文章详情、分类/标签筛选、搜索、分页、关于页、时间线
- 后台:文章管理、设置、友情链接、项目(GitHub)管理、评论管理
- 评论系统(可开关),IP 归属地由内置 ip2region 离线库解析(无外部请求)
- 友情链接申请与审核
- GitHub 项目页抓取与展示
- 登录防爆破(基于 IP 的失败计数 + 验证码)
目录结构
blog/
├── app.py # 主应用(Flask 入口、路由、DB 初始化)
├── requirements.txt # Python 依赖
├── gunicorn.conf.py # 生产 WSGI 服务器配置
├── gunicorn_conf.py # 另一份 gunicorn 配置样例(宝塔风格)
├── blog.service # systemd 服务单元样例
├── deploy_infowe.site.conf # Nginx 反代配置样例
├── DEPLOY.md # 详细部署文档
├── data/ # 数据库与数据(blog.db、posts.json)
├── posts/ # Markdown 文章源文件
├── static/ # 静态资源(CSS / JS / 图片)
├── vendor/ip2region/ # IP 归属地离线库(xdb v4/v6 + 纯 Python 绑定,Apache-2.0)
└── templates/ # Jinja2 模板(default 为内置默认主题,新主题放独立子目录)
环境要求
- Python 3.8+
- 依赖:
flask、markdown、Pillow、pillow-heif(详见requirements.txt)
快速开始(本地开发)
# 1. 安装依赖
pip install -r requirements.txt
# 2. 启动(Windows / 本地开发)
python app.py
启动后访问 http://127.0.0.1:5000 ,后台地址 http://127.0.0.1:5000/admin/login 。
数据库会自动创建
首次启动时 app.py 中的 init_db() 会在 data/blog.db 自动建库建表(前提是 data/ 目录存在)。无需手动创建数据库。
默认管理员账号
仅当
users表为空时自动创建(SQLite 触发器保证整个系统只有 1 个管理员)。
- 用户名:
admin - 密码:首次启动时随机生成(
secrets.token_hex16 位),打印在启动日志中:
[初始化] 默认管理员账号: admin / 密码: xxxxxxxxxxxxxxxx
[初始化] 初始密码已写入 data/.initial_admin_password,首次登录修改密码后自动删除
⚠️ 首次登录后请务必到后台「设置」中修改账号名与密码;修改成功后初始密码文件会被自动删除。
初始密码在哪里看(两处,内容相同):
- 密码文件(推荐):
data/.initial_admin_password(权限 600)——宝塔「文件」管理器直接打开看,或 SSHcat data/.initial_admin_password;首次登录修改密码后自动删除 - 启动日志(
print输出到进程 stdout):- 本地开发(
python app.py):直接显示在当前终端窗口 - 服务器(systemd + gunicorn):
- 本地开发(
- 宝塔 Python 项目管理器:该项目「日志」标签;也可 SSH 停掉项目后前台
python app.py直接看输出
注意:初始密码只在 users 表为空的首次启动生成一次(全新部署才会出现)。错过且密码未修改过,可通过登录页「忘记密码」(需配置 SMTP)邮箱找回;全新部署也可删除
data/blog.db后重启重新初始化。
后台管理
登录后台 /admin/login 后可:
- 发布 / 编辑 / 删除文章
- 修改站点设置、关于页、技能等
- 管理友情链接、GitHub 项目、时间线、评论
- 修改管理员账号名与密码(在「设置」页)
注意:后台修改账号名是对原记录执行
UPDATE(改名,不新增),修改后原admin用户名将不可用,需用新用户名登录。密码需 ≥ 6 位。
生产部署
生产环境使用 Nginx + gunicorn,完整步骤见 DEPLOY.md。
要点:
- 安装依赖并安装
gunicorn。 - 建议设置环境变量
BLOG_SECRET_KEY为强随机串;未设置时启动会自动生成随机密钥并持久化到data/.secret_key(权限 600,重启后 session 不失效),源码中已无硬编码默认值。 - 用
gunicorn -c gunicorn.conf.py app:app启动,并通过blog.service(systemd)守护。 - 配置
deploy_infowe.site.conf(Nginx 反代 + 可选 HTTPS)。
# 生成强随机密钥
python3 -c "import secrets; print(secrets.token_hex(32))"
常用命令
# 本地开发
python app.py
# 生产启动(gunicorn)
gunicorn -c gunicorn.conf.py app:app
# systemd 重启(修改代码后生效)
sudo systemctl restart blog
注意事项
data/目录需存在,sqlite3.connect不会自动创建父目录。- 若
data/posts.json存在且数据库为空,首次启动会自动迁移其中的文章。 - 评论、上传等文件保存在根目录
uploads/下。 vendor/ip2region/随项目分发(约 48MB),不可遗漏:缺失时评论归属地静默不展示,不影响其他功能。若上传体积受限,可单独上传ip2region_v4.xdb/ip2region_v6.xdb补齐。
版本更新日志
v1.3.63
- 修复后台「安全验证」OTP 无法关闭:开关字符串
'0'被not判断为真,关闭分支永不执行;改为布尔值,取消勾选即清空密钥与恢复码 - 修复文章标签自动填入只填一部分:原一次性锁定只填最先匹配的标签;改为渐进式补全,持续追加新匹配标签,手动增删后立即锁定、绝不覆盖
app.pyVERSION 同步至 1.3.63
历史版本日志(v1.3.62 及更早)
v1.3.62
- 消除
tech/模板 CSS lint 警告:模板内联样式style="background: {{ l[2] }};"与style="width: {{ skill.level }}%;"中的 Jinja 占位符被 Trae / VS Code CSS 校验器误判为非法 CSS。改为 CSS 自定义属性--lang-color/--sl(值允许任意 token 序列),CSS 通过var()读取,与default/admin主题既有写法一致。视觉行为完全不变 app.pyVERSION 同步至 1.3.62
v1.3.61
- 修复评论 IP 归属地城市显示错误:原实现调用 3 个免费在线接口(ip.useragentinfo.com / api.vore.top / ip-api.com),数据不准且受网络波动影响。实测
220.192.40.209(重庆电信)被标为「北京市 西城区」、14.117.243.23(江门电信)被标为「广东 广州」。改为内置 ip2region 离线库(Apache-2.0),约 0.1ms/次,零网络请求、零新增 pip 依赖 - 历史评论已用离线库重查回填,5 条修正:4 条「北京 西城区」→「重庆」,1 条「广东 广州」→「广东 江门」
- 归属地展示统一去行政区划后缀(重庆市→重庆、四川省→四川、广西壮族自治区→广西);回环 / 私网 / 链路本地 / 畸形 IP 及
::ffff:a.b.c.d形式统一归一处理,查不到则不展示 - 项目详情页改为 GitHub 仓库页式头部(owner / repo 面包屑 + 操作按钮组),README 内
details折叠块补样式 pyrightconfig.json补extraPaths,消除 vendor 内联绑定的导入误报;.vscode/settings.json关闭模板内联样式误报app.pyVERSION 同步至 1.3.61
v1.3.60
- 消除控制台 unload Violation 警告:新增响应头
Permissions-Policy: unload=*显式允许 unload(百度统计等老式脚本需要),Chrome 127+ 不再报[Violation] Permissions policy violation;统计功能行为不变。控制台里chrome-extension://开头的报错是浏览器自身扩展产生,与网站无关 app.pyVERSION 同步至 1.3.60
v1.3.59
- 修复项目详情页提交评论 HTTP 500:老库
comments.post_id是 NOT NULL(早期评论只挂文章的遗留约束),项目评论插入post_id=NULL直接违反约束——项目评论上线以来从未成功过。启动迁移自动重建表放宽约束(幂等、老数据零丢失),部署后重启服务即生效,无需手工操作 - 项目页按钮重设计:「访问 GitHub」改 GitHub 品牌深色实底,hover 轻微上浮带阴影;「反馈」更名为「反馈 Bug」,改为柔和浅底次级按钮,hover 主题色微染上浮(双主题一致)
app.pyVERSION 同步至 1.3.59
v1.3.56
- 安全加固:移除源码硬编码 Secret Key(未设置
BLOG_SECRET_KEY时自动生成随机密钥持久化到data/.secret_key,权限 600,重启 session 不失效);初始管理员密码由固定admin123改为随机 16 位并打印到启动日志;后台修改密码需先验证旧密码;管理员账号名格式校验 - XSS/SSRF 防御:新增安全响应头(nosniff / DENY / CSP / HSTS);Session Cookie 加固(SameSite=Lax / HttpOnly / Secure);统计代码保存前消毒(仅保留
<script>);Markdown 链接过滤javascript:伪协议;服务监控 URL 拒绝内网/回环地址 - 修复:启动崩溃(
BASE_DIR未定义先使用);登录/评论防爆破字典内存泄漏;IP 归属地内网判断改用ipaddress精确检测;水印批量重做遗漏 uploads 根目录;评论 Cookie 有效期 1 年 → 30 天 app.pyVERSION 同步至 1.3.56
v1.3.55
- 后台登录族页面移动端禁缩放:
/admin/login、/admin/otp、/admin/otp/recover、/admin/forgot四个独立页面补齐maximum-scale=1.0, user-scalable=no, viewport-fit=cover(iPhone 双击/捏合不再放大页面) app.pyVERSION 同步至 1.3.55
v1.3.54
- 文章页公众号式排版(移动端 ≤767px):16px 字号、1.6 行高、24px 段距、两端对齐(含
<br>段落自动排除);正文标题字号体系重建(桌面 h1 26 / h2 22 / h3 19,移动 h1 23 / h2 20 / h3 18,字重 700),修复 H 标签与正文层级倒挂;复合选择器对抗 markdown-body.css 加载顺序覆盖;tech 主题条目标题/表格字号全站协调 app.pyVERSION 同步至 1.3.54
v1.3.53
- 分享卡片图:文章封面 > 正文首图 > 默认图的优先级自动生成 og:image;新增
/share-thumb/路由按需生成 4:3(800×600)轻量缩略图(懒生成 + 磁盘缓存 + 源图更新自动失效),微信朋友圈/Twitter 分享卡片展示文章配图;正文首图注入 width/height 并禁用懒加载(提升微信爬虫抓取成功率);默认分享图重制为 4:3 app.pyVERSION 同步至 1.3.53
v1.3.52
- 系统升级双源检测:新增 Gitee 镜像仓库
infowe/infowe_blog回退源——版本检测优先 GitHub Releases,超时/限流时自动切换 Gitee API;升级包下载链路「GitHub 直连 → 加速镜像 → Gitee 归档包」逐级降级。升级卡片显示检测来源,查看按钮随来源变化 - tag 规范化防御:Gitee 发行版标签名误填标题(如
v1.3.51:安全加固)时,自动解析语义版本重构规范 tag,下载 URL 不受脏 tag 影响;UPGRADE_GITEE_REPO环境变量可覆盖镜像仓库 app.pyVERSION 同步至 1.3.52
v1.3.51
- 单管理员硬保证(数据库层):仅支持 1 个管理员账号。schema_version=3 迁移自动清理多账号(保留最早创建的账号),SQLite 触发器
users_single_admin_guard拦截一切 users 表 INSERT;忘记密码找回同步简化为唯一管理员(无需输入账号名) - OTP 邮箱找回后直达重绑:验证通过登录后台后自动定位设置页「安全验证」卡片并展开绑定流程、生成新二维码,扫码确认即完成重绑
- 修复 init_db 默认管理员 INSERT 引用不存在的 created_at 列(全新环境首启崩溃)
app.pyVERSION 同步至 1.3.51
v1.3.50
- 登录页新增「忘记密码」找回功能:登录页右下「忘记密码?」入口(/admin/forgot),输入账号名 → 绑定邮箱收 6 位验证码(10 分钟有效、60 秒限频)→ 设置新密码。重置精确锁定到发码时校验的账号,users 表多账号不会误改;未配置 SMTP 时给出替代方案提示;验证码错误/不存在账号均计入登录防爆破
- 设置页开关行全局对齐修复(开关与文字垂直居中偏差 2px)+ 设置组间距放宽
- /admin/otp 验证页与找回页 PC 端卡片改为屏幕居中(单栏布局)
- 设置页「账号安全」分组:管理员 + 安全验证两卡紧贴成组(双栏瀑布流防劈裂)
- OTP 二维码容器跟随深浅主题(白底仅保留在二维码图片区域),容器内元素居中修复
app.pyVERSION 同步至 1.3.50
v1.3.49
- 后台新增 OTP 双重验证。设置页「安全验证」卡片一键开启:登录 /admin 时账号密码通过后还需输入一步 6 位动态验证码,密码泄露也无法直接进入后台。标准 RFC 6238 TOTP(HMAC-SHA1 / 30 秒步长),Google Authenticator、1Password、Authy 等通用验证器 App 均可扫码绑定;开启时强制「扫码 + 验证码确认」双确认,防止把自己锁在门外
- OTP 丢失找回三级保障:① 开启时自动发放 10 个一次性恢复码(只存哈希,可下载保存,用后即销);② 配置 SMTP 后可邮箱找回(发 6 位验证码,验证通过自动重置 OTP);③ 服务器兜底「
touch data/.otp_disable」临时跳过 OTP,登录后设置页一键恢复 - 验证码输错复用登录防爆破:递增延迟 + 15 分钟锁定 + 验证码,拖慢暴力破解
app.pyVERSION 同步至 1.3.49
v1.3.48
- 修复严重 bug:线上水印永远 9px,改大小档位完全没反应。之前字体路径只硬编码了 3 个 Linux 位置,生产服务器(宝塔)上一个都没有;兜底时调用内置字体又没传字号,结果不管设置图宽 2%/3%/4%(本该 28/52/76px),水印永远是 9px 蚂蚁字
- 字体发现改成三级保障:已知候选路径 → 运行时扫描系统字体目录(CJK 字体优先)→ 仓库自带开源中文字体
fonts/wqy-microhei.ttc(文泉驿微米黑,Apache-2.0,随代码走,服务器不用装任何字体);极端情况下内置默认字体也会按档位缩放 - 已本地复现 bug 并验证修复:三档实际字高从修复前 9/9/9 变为 19/37/55,中英文、横图竖图小图 5 组场景全部正常
- 部署后到后台设置页重新保存一次水印设置,历史图片即从无痕原图全部重做
app.pyVERSION 同步至 1.3.48
v1.3.47
- 图片水印能选字号了。后台「图片水印」卡片多了「水印大小」下拉:小(图宽 2%)/ 标准(图宽 3%)/ 大(图宽 4%)。以前字号写死图宽 2% 还压了 28px 封顶,横图上字明显偏小;现在默认就是「标准」档,不进设置页也能大一圈。做成档位而不是填像素,是因为同样 28px 在 800px 和 1920px 图上观感完全不同,档位底下仍按图宽缩放,各尺寸图片观感一致;边距也随字号走,大字不贴边。保存后历史图片照常后台自动刷新
- 后台「文件清理」页(/admin/orphans)交互重做:
- 图片行直接显示缩略图,桌面端悬停弹出跟随鼠标的大图(自动避开窗口边缘);非图片显示扩展名方块(PDF/ZIP 等)
- 进页面默认就是批量选择态,点行任意位置即可勾选(链接除外),选中行整行浅蓝高亮
- 文件名即时搜索、全部/图片/其他类型切换,文件/大小/上传时间三栏点表头排序
- 批量条实时显示「已选 N 个 · 占 XX MB」,没选时删除按钮置灰
- 删除改 AJAX:成功行淡出移除、失败行标红提示,全删完自动切完成态,不再整页刷新
- 删除接口保留原表单流程,非 AJAX 调用行为完全不变
app.pyVERSION 同步至 1.3.47
v1.3.46
- SQLite 连接加 busy_timeout=15000。以前多 worker 部署 + 监控线程同时写库,写锁短暂碰撞立刻抛
database is locked、偶发 500;现在自动等最长 15 秒,消化高峰期的抖动 - Flask 请求体上限 32MB。以前只靠上传里读 Content-Length 兜底,分块上传没这个头就能绕过,超大文件一路写进磁盘;现在超限在解析阶段直接 413
- 两处内存缓存加上限:IP 归属地缓存最多 2000 条;登录失败记录清理超 1 天的、总量超 2000 重置,防止跑久了内存悄悄涨
app.pyVERSION 同步至 1.3.46
v1.3.45
- 给博客接统计脚本,终于不用手改模板了。 以前想挂个百度统计得自己往 base 模板里塞代码,一升级就丢,还得记着哪个文件改过。现在后台设置页加了一栏「统计代码」:把百度统计(或 Google Analytics、Umami 这类)给你的一整段脚本粘进去保存,全站每个前台页面都会在底部自动带上这段代码——tech / default 两套主题都覆盖,以后换主题也不丢。留空就什么都不注入,平时打开页面一点痕迹都没有,也不拖慢加载。
app.pyVERSION 同步至 1.3.45
v1.3.44
- 时区又补了一刀。v1.3.43 只把存量 UTC 行搬到了 CST,写入端还在吃 SQLite
DEFAULT CURRENT_TIMESTAMP(永远是 UTC),新数据照样会偏。现在 app.py 加_now(),所有 INSERT / UPDATE 显式写本地时间,不再依赖默认值 - 自动迁移钩子:init_db() 检查 settings.schema_version,小于 2 时首次启动自动跑一次 UTC→CST 转换(posts 纯日期和 12:00:00 整点是历史 CST 数据,跳过;其余表 +8h),换服务器或旧库都能自己修回来
app.pyVERSION 同步至 1.3.44
v1.3.43
- 时区彻底收拢成一层:库里只存 CST,模板直接切片显示,不再有 UTC→CST 转换层。起因是 v1.3.42 那套 filter 一刀切 +8h,但 posts 表里混着三套时区(早期导入脚本存的是 CST、Hexo 迁移是 12:00:00 整点、34 号之后 CURRENT_TIMESTAMP 才是 UTC),filter 对前两类二次 +8h,时间直接跑飞
- 数据迁移
_migrate_tz.py:posts 纯日期和 12:00:00 整点原样保留,其余 UTC 行 +8h;comments / projects / timeline / links 全是 UTC 统一 +8h。迁移前备份了data/blog.db.bak - 代码回滚:删掉两个 Jinja filter,10 个模板 19 处
| csttime/| cstdate还原成[:16]/[:10];年份筛选 SQL 去掉+8 hours;RSS pubDate 改成给 CST 字符串补+08:00后按 RFC822 输出 app.pyVERSION 同步至 1.3.43
- 数据迁移
v1.3.42
- 时区修复:UTC 存储 → 中国时区(CST +8)显示(后发现与历史导入数据冲突,v1.3.43 回滚 filter 层,改为 DB 层统一)
app.pyVERSION 同步至 1.3.42
v1.3.41
- 整理后台删除按钮的 bug。v1.3.38 留下的坑:单条删除的
<form>被套在批量表单里,HTML 不允许 form 嵌套,浏览器把内层丢掉,按钮就报「无效的批量操作」。comments / posts / categories / timeline / links 五个模板统一改成 projects.html 的写法——按钮用form="xxxForm{id}"归属,单条 form 移到批量表单外藏起来,确认弹窗保留。 app.pyVERSION 同步至 1.3.41
v1.3.40
- tech 主题毛玻璃三连:
.tech-nav/.tech-search-layer/.tech-toast统一半透明背景(--nav-bg,light 72% 白 / dark 72% 深)+backdrop-filter: saturate(180%) blur(14px);滚动内容在导航后柔和透出,toast 浮起反馈更明显 - iOS Safari sticky 1px 漏出修复:nav 顶部加
box-shadow: 0 -1px 0 0 var(--nav-bg)兜底,滚动时上方不再漏 1px 缝 - search-layer 移出 nav:原嵌于 nav 内部时 backdrop-filter 嵌套失效(CSS Filter Effects 规范行为),移出后改
position: fixed; top: 56px; left/right: 0; z-index: 99,紧贴 nav 下方吸顶 - 首页格言纯本地化:移除远程「一言 API」调用(
https://v1.hitokoto.cn/),刷新按钮仅随机抽取本地FALLBACK数组;首屏秒出、无超时控制、零网络依赖;同时清理theme.js/index.html中过时的「一言 API」注释 - 后台文章标签推荐重构(tech 主题):自动识别区改为纯基于本文(标题+正文)的高频英文术语提取,不再混入历史标签,避免老标签污染新文章;常用区改为匹配本文的已有标签按频率展示,不再给整站 Top 6 无关标签;自动填入来源改为匹配本文的历史标签
- 后台 admin 移动端禁止缩放:admin base viewport meta 加
maximum-scale=1.0, user-scalable=no,iPhone Safari 无法双指缩放 admin 页面 - logo 改为闪动光标样式:
<infowe.site/>改为infowe.site|(|蓝色闪动,hover 变紫),纯 CSS 动画、无 JS 依赖 - 文章 TOC 点击后自动关闭:点选目录节点后
<details>自动收起,移动端体验更顺,桌面端连续浏览也避免遮挡正文 app.pyVERSION 同步至 1.3.40
v1.3.38
- 优化:同步流程前端反馈:项目列表页同步改为 AJAX 提交 + 原地轮询进度(不再 302 整页跳转)——点击「同步 / 一键同步全部」立即出现进度条「后台同步中 N/M(当前:xx)…」,每 2 秒更新;完成后按结果显示绿色(成功)或红色(失败)提示并自动刷新一次;运行中重复提交会被拒绝并提示;若打开页面时已有同步在后台执行,也会直接接续显示进度。
- 同步/一键同步接口改为返回 JSON,不再依赖跳转与 flash 消息。
v1.3.37
- 修复:后台所有页面 500(升级检测缓存落盘引入):
data/upgrade_cache.json里version是 tuple 序列化后的数组,读回为 list,与parse_version()返回的 tuple 比较抛TypeError,导致后台每个页面渲染都崩。现读缓存时自动还原为 tuple。 - 修复:
/admin/projects点「同步」报「无效的批量操作」:同步/删除按钮的表单原本嵌套在批量操作表单内,违反 HTML 规范——浏览器丢弃内层表单action,点击实际提交到批量接口。已改为表格外定义表单 +form属性归属。 - 修复:同步完成后页面无限闪屏:
finished状态常驻,页面每次加载都触发自动刷新,形成 reload 死循环。现仅当本次加载观测到「进行中→完成」转变才刷新;打开页面时同步早已完成则静默不提示。 - 优化:同步完成提示不再常驻:自动刷新前先
consume完成状态,之后重新进入/刷新页面不再看到「同步完成」旧提示。 - 优化:同步状态落盘(
data/project_sync_state.json):gunicorn 多 worker 下状态跨进程一致——提交、进度轮询、防重复并发均以磁盘为权威,任一 worker 都能看到同步进度与结果。
v1.3.36
- 修复:项目同步触发 nginx 60s 上游超时:同步单个项目需拉取 GitHub 数据并本地化 README 图片,耗时 1-2 分钟(一键同步全部更久),远超 nginx 默认 60s 上游超时,日志报
upstream timed out ... POST /admin/projects/1/sync。现在同步改为后台线程执行,POST 立即返回(实测 6.9ms),后台页面每 2 秒轮询/admin/projects/sync-status进度,完成后自动刷新列表;同步进行中重复提交会被拒绝并提示。
v1.3.35
- 修复:多进程部署下项目详情页文档「一会儿有一会儿没有」:前台缓存此前只读进程内存,管理员在某 worker 上同步后,其他 worker 内存里没有结果,访客请求轮询到不同 worker 就时有时无。现在详情页缓存以磁盘为权威——内存 miss 自动回退
data/project_gh_cache.json,磁盘结果比内存新时也取磁盘,任何 worker 都能读到最新同步结果(带 mtime 快照,不增加每请求 IO)。 - 修复:系统升级检测缓存落盘:版本检测结果此前只存内存,重启后首个访问升级页的请求必等 GitHub(国内网络常超时)。现在落盘到
data/upgrade_cache.json,成功/失败均缓存 10 分钟,重启与多进程下结果一致、页面秒开。 - 版本号同步到 1.3.35。
v1.3.34
- 前台零 GitHub 拉取:项目详情页不再实时请求 GitHub,改为只读「同步快照」——有缓存直接秒开,没缓存则提示管理员到后台同步。匿名 API 限额(60/小时)不再被访客消耗,全部留给管理员低频操作;移除了 1.3.33 的 5 分钟缓存、前台「刷新」按钮与轮询脚本。
- 管理员手动同步:新增项目、单个同步、一键同步全部时才去拉取仓库元数据与 README,结果写入内存并持久化到
data/project_gh_cache.json——服务重启后已同步过的项目依然秒开。 - README 图片本地化:同步时把 README 中指向同仓库
raw.githubusercontent.com的图片下载到本站(存于uploads/projects/<仓库>/readme/,文件名取图片 URL 的 md5),前台直接走本地/uploads/访问,不再受 GitHub 图床龟速拖累。多图并发下载,raw 域名慢时自动回退api.github.com拉取(带 Token 时配额充足),并支持中文文件名路径;每次同步按新内容清理已废弃的旧图,避免目录膨胀。shields.io 徽章因走 CDN 保持远端不动。 - 版本号同步到 1.3.34。
v1.3.33
- /projects 页面改版:点击项目不再是直接跳 GitHub,改为进入项目详情页(
/projects/<id>)。详情页顶部是项目卡片——名称、简介、Star、语言、标签一应俱全,右上角保留「访问 GitHub」入口;中部实时拉取该 GitHub 仓库的 README 渲染成文档(默认缓存 5 分钟,GitHub 上的 MD 更新后详情页会自动跟随,也可点「刷新」立即重拉);底部接了完整评论区,支持楼中楼、审核、私密评论,和文章页共用一套评论系统。 - iPhone 禁止放大缩小:详情页与列表页加了双层防护——
disable-zoom.js拦截双指捏合与双击缩放,再加touch-action: manipulation兜底,iPhone 上打开页面再也不会被系统强行缩放。 - 双主题适配:详情页同时适配 default / tech 两套主题,各自一套专属样式,暗色主题下代码块复制按钮也补齐了。
- 后台配套:评论列表新增「文章 / 项目」来源列(点击直达对应详情页评论区);项目列表加了「前台」入口;系统设置新增「项目文档缓存时间(秒)」,可自定义 README 缓存时长。
- 版本号同步到 1.3.33。
v1.3.32
- 撤销「重启服务」按钮:1.3.30 起加的一键重启在宝塔面板这类托管环境下靠不住——托管的服务根本不该由应用自己去杀进程、裸起新进程,容易闹出「端口占用、服务反复重启失败」的烂摊子(服务器上那串
Address already in use就是这来的)。干脆把升级页的「重启服务」按钮和后端重启路由整个撤掉,回归手动重启:systemd 托管用systemctl restart blog,python app.py直跑就自己跑仓库根目录的restart.bat/restart.sh,托管器之外的事不掺和。 - 版本号同步到 1.3.32。
v1.3.31
- 「重启服务」按钮适配宝塔面板:宝塔部署的服务由 supervisord 托管,之前的重启脚本只认「裸进程」,在宝塔下要么白杀进程要么裸起抢端口。现在脚本会自动探测:发现进程挂在 supervisord 下就改用
supervisorctl restart重启(自动认宝塔的 supervisorctl 路径),匹配不到程序名就结束进程交给 supervisor 自动拉起;裸进程场景保持原有停旧起新逻辑。 - 排错增强:重启脚本的输出(含 supervisorctl 报错)会写入
logs/restart.log,重启失败能查到原因。 - 版本号同步到 1.3.31。
v1.3.30
- 升级页加「重启服务」按钮:之前升级完要自己跑脚本、麻烦。现在系统升级页「升级说明」右上角多了个「重启服务」按钮,点一下自动停掉旧进程、背后台拉起新的(仅适用于
python app.py直跑部署;systemd 托管还是走systemctl restart)。点完页面会提示"已下发重启",几秒后刷新即可。 - 修复:重启指令下发改用 Python 侧延迟,绕开 cmd 嵌套引号不可靠的问题(之前的那种写法在 Windows 上会静默失效)。
- 版本号同步到 1.3.30。
v1.3.29
- 新增一键重启脚本:升级完总要手动重启,嫌麻烦?仓库根目录加了
restart.bat(Windows)和restart.sh(Linux),后台升级成功后跑一下,自动停掉占用 5000 端口的旧进程、再背后台拉起新进程,日志写进logs/app.log,以后排错也有完整输出。仅适用于python app.py直跑的部署方式。 - 版本号同步到 1.3.29。
v1.3.28
- 修了一个要命的稳定性 bug:跑一段时间后网页打不开,只有首页能开。根子是数据库写锁被长期占住——之前每个请求都要开好几个数据库连接,每个连接还都傻乎乎地重设一遍 WAL 模式,这个操作要抢数据库锁,人一多、跑久了就开始撞车报
database is locked;再加上状态监控线程每 5 分钟轮询时,把一长串网络探测塞进一个大事务里,动不动占着写锁几十秒,后台保存、评论全被堵死。WAL 的特性是读不挡写、写不挡读,所以首页这种纯读的页面一直能开,其它页面全瘫。 - 修法三管齐下:一,去掉每个连接重复设置 WAL(模式建库时一次激活、永久生效);二,监控探测改成每条结果一个小事务落库,写锁占用从几十秒缩到几毫秒;三,每次请求的多个数据库连接合并成一个,反复开关连接的损耗和抢锁概率一起降下来。
- 版本号同步到 1.3.28。
v1.3.27
- 「保存文章」按钮上下不对称修好了。它上面那个字段自带一段底部留白,跟按钮自身的上边距叠在一起成了 32px,比下面的 20px 宽出一截,看着像断层。现在把字段那段多余留白压掉,按钮上下各 20px,齐整了。
- 版本号同步到 1.3.27。
v1.3.26
- 标签建议区终于能用了。之前「常用」那一排标签死活不显示,查到头是代码里拿错了容器,
querySelector只找后代找不到自己,画了个寂寞;改了一行指向就正常了。 - 空组不再「标签悬空」。以前没标签时「常用」两个字会孤零零挂一行,现在没有就整个藏起来,清爽。
- 每个建议区最多 6 个,挤在一起反而看不清,够用就好。
- 顺手把自动填标签的毛病治了:之前它会从正文里抓
trim、const这种代码词当真标签写进输入框,存进数据库到处都是垃圾标签。现在只拿真正的标签来填,历史污染的那篇也清掉了。 - 版本号同步到 1.3.26。
v1.3.25
- 批量选择模式(6 个列表页):posts/comments/categories/projects/links/timeline 选择列与批量工具条默认隐藏,页头「批量操作」按钮进入/退出(Esc 亦可退出),选中状态仅激活时可见;移动端窄屏同样生效(选择列批量模式下方块显示)
- comments/links 卡片化统一:评论页与友链页表格容器补齐
.card > form > bulk-bar + .table-wrap > table结构,与其他列表页视觉完全一致(此前 form 与 table-wrap 裸放页面导致边框/间距不一致) - 主题三模式(系统自适应/深色/浅色):后台顶栏与侧栏主题按钮改为三态循环(跟随系统 → 浅色 → 深色),与前台共用
infowe-theme键(auto/light/dark);auto模式实时跟随系统偏好变化,图标三态(显示器/太阳/月亮)、侧栏文字标签同步;登录页同款三模式;旧存储值(light/dark)无缝迁移为显式模式 - 编辑器暗色预览自适应修复:此前后台暗色时
data-theme属性被移除(而非显式设dark),编辑器读到空值回退亮色预览;现显式设置两值,/admin/posts/newVditor 界面(vditor--dark)、内容区(dark contentTheme)、代码高亮(github-dark)在暗色下全部正确适配且随切换实时联动 - 页头按钮统一:全站页头主按钮统一
btn btn-primary btn-sm(14px 图标)+.page-actions容器,批量操作按钮统一挂容器末尾——主操作在前、批量在后排序一致,按钮高度/对齐实测完全吻合(28px 基线对齐);projects 页「添加项目」移至最前与其他页统一 - 静态资源破缓存:后台 CSS/JS 引用附加 mtime 版本参数(
admin_ver),改动后浏览器无需强制刷新即命中新资源 app.pyVERSION 同步至 1.3.25
v1.3.24
- 后台整体重构:admin.css 全新设计系统(CSS 变量令牌 + 统一间距/圆角/阴影),19 个后台模板排版全部重做;PC 固定侧栏 + 顶栏、平板(<1024)抽屉式、移动端(<768)单列卡片化,表格窄屏自动转卡片(data-label),全端交互统一
- 编辑器三主题联动:文章编辑器(/admin/posts/new 与 /edit)Vditor 的界面主题、内容主题(contentTheme dark/light)、代码高亮主题(github / github-dark)随后台暗/亮切换实时联动,暗色下代码块不再刺眼白底
- 设置页 PC 双栏:≥1024 两列等宽流式排布(顶部对齐、底部保存按钮通栏),移动端回退单列
- 主题预览图防溢出:主题管理页预览区固定 16:10 容器 + 图片绝对定位裁剪(object-fit: cover),超长竖版预览图(如 390×8487)不再撑爆卡片破坏排版
- 数据管理页排版均衡:6 个统计卡大屏(≥1200)一行六列 / 中屏三列两行,不再 4+2 参差折行;「导出操作」按钮组包进卡片与页面风格统一
- 侧栏去重:移除侧栏底部版本链接(页脚仍保留版本号展示)
app.pyVERSION 同步至 1.3.24
v1.3.23
- 前台评论头像兜底(两端主题):访客评论未留邮箱、或邮箱在 Cravatar/WeAvatar 均未注册时,头像直接回退为博客默认头像(
data-default),不再出现空白/首字母占位;外部头像源加载失败或超时挂起时依次回退备用源 → 本地默认头像 - 后台编辑器宽度自适应:文章编辑页主区最大宽度放宽至 1480px,Vditor 分屏预览(桌面端)编辑/预览两栏各占 50%(拖动分隔条仍可微调),侧栏 320→340px,PC 大屏下不再显得窄
- 编辑器暗色主题修复:补齐
data-theme属性联动,VditorcontentTheme现随后台主题正确切换;暗色主题下预览区代码块、表格、引用、链接配色全部适配(此前表格为白色硬编码) - 设置页间距精细化:卡片内留白统一(header 通栏 + 内容区 18/22/24 padding),form-group 间距 0→14px,卡片间距 16→20px,表单最大宽度 980→1080px
- 后台整体排版微调:卡片 header/body 统一 22px 水平留白、侧栏卡片(发布设置/文章信息)内容与标题统一间距
app.pyVERSION 同步至 1.3.23
v1.3.22
- 评论区博主头像单独判断(两端主题):评论判定为博主(昵称 = 后台作者名)时,头像优先使用后台「设置」页上传的头像(
/admin/settings的 avatar 配置);未设置或图片文件已被删除时,回退到原 Cravatar(后台联系邮箱生成)。普通访客头像逻辑不变,仍走站内/avatar/...代理 app.pyVERSION 同步至 1.3.22
v1.3.21
- 首页结构优化(tech 主题):精选区独立成块(最多 3 条)+ 分隔线,主文章列表不再重复显示精选、也不跳号(精选改由
db_get_featured_posts独立取,主列表db_load_home_posts(..., exclude_featured=True)仅取普通文章);首页featured与posts统一附加分类名 - 「★ 精选」徽标:改为主题强调色
--accent(亮暗自动适应),与标题 hover / 箭头 / 彩条同色系,亮色下清晰不糊灰 - PC 首页 Hero「头轻脚重」修正:
min-width:769px下重心上收(padding 40/40 → 36/28,格言间距 28 → 20)、宽屏补存在感(标题 32 → 40px,格言 15 → 17px);移动端完全不动 - 无障碍:
prefers-reduced-motion:系统开启「减弱动态效果」时关闭光标闪烁 / 动画 / 位移过渡,避免前庭敏感用户不适 - 一言格言改为「本地优先」:首屏立即出本地句(秒出),在线一言仅作后台增强(5s 超时成功才替换,失败静默不回退)——弱网 / 一言域名受阻时不再白等 5s、不再报错
- 格言库扩充:
FALLBACK由 12 条增至 20 条,新增贴合博主内容调性的句子(房产 / 流量 / 独处 / 开源 / 做事风格) - heading 层级补全:主列表前加视觉隐藏
h2.sr-only(新增.sr-only工具类),全文 h1→h2→h3 层级完整 app.pyVERSION 同步至 1.3.21
v1.3.20
- 评论表单不再被「回到顶部」悬浮球遮挡(tech 主题):移动端(≤768px)「写评论」表单进入视口时,右下角
.tech-top悬浮球自动隐藏(IntersectionObserver 监听#comment-form,滚离后恢复显示)。此前球固定right:28px / bottom:72px且z-index:150,恰好压在表单.foot右侧的「提交评论」按钮上,真机点不到按钮 app.pyVERSION 同步至 1.3.20
v1.3.19
- 评论跨文章可见泄漏修复:
db_load_comments普通访客分支的 SQL 运算符优先级缺陷——status='approved' AND is_private=0 OR (id IN ... AND is_private=0)中OR缺括号,导致同一作者在其它文章提交的(含待审核)评论会被错误加载到当前文章页评论区。加括号收紧为(status='approved' AND is_private=0) OR (id IN (...) AND is_private=0),仅当前文章、仅非私密 app.pyVERSION 同步至 1.3.19
v1.3.18
- 评论通知时序修复:待审核的回复不再立即通知被回复者(此前对方点进链接却看不到待审核内容);审核通过后由
_notify_reply_recipient补发,复用同一套排除逻辑(博主邮箱 / 自己回复自己) - 博主免审核评论立即通知:博主(后台收件人邮箱)评论/回复直接
approved,被回复者通知即时发送 - 博主自己评论/回复不打扰:
notify_email与contact_email任一命中即视为博主,博主自评不触发任何通知 - 评论表单定位优化(tech 主题):点「写评论」展开表单后,仅当表单被视口截断(底部/顶部超出)才平滑滚动定位,页面本身能装下表单时不滚动,避免多余跳动;滚动定位时表单上下各留 50px 边距不贴边
app.pyVERSION 同步至 1.3.18
v1.3.17
- 评论通知邮件模板去重:邮件正文删掉与标题栏重复的《文章名》行(此前同一标题显示两遍);同步清理无用的
.article样式 - 「查看详情」链接核对:邮件中链接为
站点域名/post/<文章ID>#comments,拼接逻辑正确,指向评论区锚点 app.pyVERSION 同步至 1.3.17
v1.3.15
- 博主身份条头像 QQ 邮箱适配:博主身份条头像(
cmt-admin-avatar)在后台联系邮箱为 QQ 邮箱时改用 qlogo 源(q<QQ>代理 key),不再强制走 Cravatar/WeAvatar(部分服务器出站抓取失败显示 404) - 升级页更新日志 Markdown 渲染:
/admin/upgrade更新日志确认走body_html(_md_to_safe_html)渲染而非原文 - 头像代理 SSL 降级修复:
_fetch_image_bytes在服务器缺少系统根证书时(精简环境/宝塔编译版 Python)SSLError 导致全部头像源失败、代理 404;现改为先校验证书、失败降级为不校验证书重试 app.pyVERSION 同步至 1.3.15
v1.3.16
- 评论区竖向节奏统一(tech 主题):评论线程内部缝隙收敛到统一 32px(标题→首条、线程间、末条→表单四处 24/36/46/38 不齐 → 全 32);表单上边距 22→14
- tech 主题评论样式独立:新增
static/css/comments-tech.css(原与 default 共用comments.css),两主题评论样式互不影响 - 评论区宽度与标题边距(default 主题):评论区分隔线随容器收窄对齐正文(padding 内缩改 margin 层);标题上下边距去叠层
- 折叠态回复自动展开:点「回复」时评论框折叠态自动展开
app.pyVERSION 同步至 1.3.16
v1.3.13
- 评论区盖楼 v2:评论样式抽离为独立
comments.css(两主题共用,变量走主题 CSS 变量,亮/暗色自动适配);回复/取消回复交互完善,操作结果 toast 轻提示 - 评论头像配色亮暗适配:头像背景色随主题变量变化,亮色/暗色下均清晰可辨
- 博主头像固定用后台「联系邮箱」:博主(
is_author)评论头像不再用评论者邮箱,统一由后台设置的联系邮箱生成 Cravatar - 博主登录后以博主身份评论:前台评论区显示博主身份条(头像 + 昵称),隐藏昵称/邮箱/网址表单;提交时昵称/邮箱强制取后台设置,忽略表单
- 评论 IP 归属地:
_ip_location增加第三数据源ip-api.com(前两源超时时兜底);本机127.*直接返回空不显示 - 后台评论管理「来源」列:展示
ip_location(徽标)+ip_text(子行),两者皆空显— - 邮件发件名称:settings 新键
smtp_sender_name(留空回退博客名),_smtp_send的From头使用该名称 - 邮件模板样式修复:CSS 原先被拼进
<div style="...">属性导致选择器规则全部失效,改为完整 HTML 文档 +<head><style>内嵌(评论通知邮件 + 两处 SMTP 测试邮件) - 博主评论免审核:评论者邮箱 == 后台「收件人」邮箱时直接
approved,其余仍pending - 后台项目表格:仓库地址独立成列(只显示
owner/repo,完整地址走 title 悬浮);表格启用table-layout: fixed,修复 nowrap 单元格抢占列宽(项目名列被压到 61px、行高 150px)的问题;语言列折叠为前 2 个 ++N徽标 - 后台表格响应式:卡片化断点 768 → 640(iPad 竖屏保留真表格,溢出由
.table-wrap横滑兜底);平板(≤1024)隐藏次要列,移动端卡片视图恢复仓库地址列 - 后台设计令牌:修复
--r-full未定义导致所有 pill/徽章圆角失效渲染成直角;新增--fz-2xs/--sp-0-5,20 处硬编码尺寸统一到令牌 app.pyVERSION 同步至 1.3.13
v1.3.12
- 评论系统大升级(盖楼):评论表新增
parent_id树形结构,支持楼中楼回复(@提及 + 深度标记,第 2 层起平铺防无限嵌套);删除评论级联删除整棵子树;旧库自动ALTER TABLE迁移,新库建表即含新列 - Cravatar 头像:评论可选填邮箱,仅存 MD5 哈希(不存明文),经 Cravatar 生成头像(自动回退 Gravatar → QQ 头像 → 默认 mp);无邮箱时显示昵称首字圆形占位
- 评论审核机制:新评论默认
pending待审核,通过后才前台展示;后台可审核/删除;本人待审核评论前台可见并标「待审核」(cookie 校验昵称防伪造) - 私密评论:勾选后仅博主可见(含待审核),普通访客始终不可见
- 评论防滥用:昵称/内容/邮箱/网址格式校验(网址仅允许 http/https,防
javascript:伪协议);父评论必须属于同一篇文章(防跨文章伪造);IP 评论冷却 - 记住评论者:昵称/邮箱/网址写入 cookie,下次免填,可一键修改
- 导航菜单开关(后台设置):新增
nav_posts/nav_tags/nav_projects/nav_links/nav_status/nav_about六项开关,关闭后对应页面返回 404 且 nav/页脚不再显示 - 两套主题评论样式重做:default 主题改纯净分隔线式(去卡片,杜绝大小不一割裂感);tech 主题盖楼去竖线,子回复轻缩进 + 浅色背景块柔和分层;回复按钮/@提及/私密与待审核徽标统一
- 后台评论管理升级:列表展示头像/邮箱/网址/状态,支持审核通过、删除(含子树)、私密标记
- 正文表格横向滚动:文章正文宽表格自动包
table-wrap容器,移动端可横向滑动,溢出时显示滑动提示 app.pyVERSION 同步至 1.3.12
v1.3.11
- 文章列表项移动端 hover 不再「变宽」(tech 主题):
.tech-post-item原为margin: 0 -16px+padding: 16px,hover 底色比正文左右各宽 16px;390px 屏上底色正好顶满整屏(两侧零留白、10px 圆角被裁掉),观感像整条突然变宽。现于 ≤768px 取消外扩,底色与正文同宽(文字位置不变) - 消除触摸端 hover 滞留:三条
.tech-post-item:hover规则包入@media (hover: hover),触摸端点按文章后不再一直保持高亮底色与右侧箭头 - 后台服务监控表移动端排版修复:
admin/status.html监控表 7 个<td>补data-label(接入admin.css的移动端表格卡片化方案,此前无标签导致排版错乱);JS「添加服务」新增行同步补标签,并补回svc-cell/latency-cell/cert-cell类名(此前新增行探测结果无法回填) - default 主题补齐
info.json:与 tech 主题对称;list_themes()重构为 default 与其它主题统一读取info.json(抽出_read_theme_info()),字段缺失时回退内置文案,向后兼容 - 工程:新增
pyrightconfig.json关闭 basedpyright 噪音规则(app.py告警清零);清理db_get_all_tags被同名函数遮蔽的重复定义 app.pyVERSION 同步至 1.3.11
v1.3.9
- 移动端导航修复(tech 主题):
.tech-nav-links移动端隐藏后,补回.tech-nav-actions { margin-left:auto }(桌面靠 links 的 auto 推力顶右,移动端需自己补回),搜索/主题/汉堡图标组恢复靠右 - 回到顶部按钮避让备案号:移动端
.tech-top.scrolled压缩态同样上移至bottom:72px(原仅覆盖非压缩态,压缩态 28px 压住页脚备案号) - 抽屉菜单头改为「菜单」:头部标题由
blog_name(与桌面 logo 三处重复)改为固定「菜单」二字 - 抽屉头文字对齐:
.tech-drawer-head左右 padding 由 16px 统一为 20px,与下方菜单链接左缘对齐 app.pyVERSION 同步至 1.3.9
v1.3.8
- 导航链接组几何居中(tech 主题):
.tech-nav-links { margin: 0 auto }使 7 个导航链接以导航条中心为轴精确居中,左侧logo→链接与右侧链接→工具图标空隙完全对称(实测 delta 1px);同时移除.tech-nav-actions的margin-left:auto(此前与 links 的 auto 竞争导致链接偏左 47px) - 修复
.tech-post-excerpt标准line-clamp属性:编译告警提示补回标准属性(与-webkit-line-clamp: 2并存),editor problems 清零 app.pyVERSION 同步至 1.3.8
v1.3.7
- 导航左移 + 中段留白(tech 主题):
space-between三等分 →flex-start聚左;logo 与首链接保持 24px 呼吸空间,链接组与正文左列对齐,右侧工具图标margin-left:auto贴右,中段自然留白,消除导航「居中悬空」观感 - active 导航底部指示条:当前页链接下方新增 2px accent 指示条(随链接宽度、左右各留 12px),导航位置反馈明确
- 「写作」入口图标化:后台入口从导航文字链接改为右侧铅笔图标(进入后台 active 高亮);移动端 ≤768px 隐藏该图标,与抽屉菜单「写作」文字入口去重(单一入口,避免重复)
- 汉堡按钮桌面隐藏:汉堡默认
display:none,仅 ≤768px 显示(原恒显示,桌面冗余) - 修复 CSS 标准属性警告:
.tech-post-excerpt/.tech-project-desc补充标准line-clamp属性(与-webkit-line-clamp并存),editor problems 清零 app.pyVERSION 同步至 1.3.7
v1.3.6
- 内容宽度定稿 940px(tech 主题):全站页面宽度由 720px 统一加宽至 940px(720 显窄、1000 显宽,居中视觉最稳)
- 导航菜单顺序重排(tech 主题):首页 → 文章 → 项目 → 标签 → 友链 → 状态 → 关于 → 写作,信息层级更清晰
- 关于页补全页头:新增
.tech-page-head页头(标题「关于」+ 描述),与其余页面结构统一 - 列表整卡可点(首页 / 文章页):文章卡片 hover 整体浅底色 + 标题 accent 染色 + 右上角
→箭头浮现,整卡点击命中区域扩大 - 文章详情页排版与目录体验:标题区外部间距收紧(
margin 28→20px)、正文段落行距放宽(16→18px)节奏更稳;目录点击平滑滚动定位并同步 URL 锚点,滚动时实时高亮当前章节(IntersectionObserver +rootMargin屏宽自适应);正文链接统一 accent 下划线风格(半透明底线 + hover 加深 + 浅底色) - 回到顶部按钮压缩态:滚动超过阈值后由圆形按钮压缩为 36px 圆形胶囊,移动端上移避让备案号文字
- /posts 筛选条间距统一:底部细线保留 + 列表间距收紧至 24px,全站间距标尺对齐 8 的倍数齐
- 项目页语言标签降噪:语言统计收敛为前 2 项 +「+N 种」chip,减少视觉噪音
- 页脚文案:
Powered by Flask © 2026 infowe.site app.pyVERSION 同步至 1.3.6
v1.3.5(累积修订)
- 版本号收敛回退至 1.3.5:此前 v1.3.6~v1.4.4 期间的全部功能变更统一计入本版(内容不变,仅重置版本号基数,后续改动自 1.3.5 起递增)
- 关于页(tech 主题):头像光环瘦身至 border 2px / 外环 3px,亮色改为半透明蓝紫渐变(
--ring-a/--ring-b)消除割裂、暗色维持#58a6ff→#d2a8ff发光感;前台移除「关于这个网站」区块(后台about_intro配置保留,default 主题继续展示);「技术栈」与「网站历程」之间新增 1pxvar(--border)淡色分隔线,仅相邻区块时显示 - /posts 筛选下拉(tech 主题):三个原生
<select>替换为站内自定义下拉组件(弹层为普通 DOM、随主题变量亮暗即时切换,解决 iOS/WebView 原生弹层恒白),修复选项点击无响应(绑定选择器契约不一致);移动端 ≤480px 自适应 2+1 对齐 - 控制台品牌提示:tech 主题注入与 default 主题一致的
console.log(infowe.site 豪子 - 工作机会 VX:CQGGTF),两主题控制台观感统一 - 静态资源缓存键:
theme.css?t=随版本号刷新,避免旧样式长期驻留浏览器缓存
v1.3.5
- 首页终端格言行(tech 主题):首页页头新增「终端式」动态格言行——等宽
~/<站点名> $前缀、逐字打字机输出、主题色光标闪烁、行尾「换一句」按钮(带旋转动效) - 格言数据「一言 API + 本地兜底」:优先请求免费「一言」开放接口(
v1.hitokoto.cn,仅取中文、5 秒超时、无 Key);接口不可达 / 超时 / 站点为 http 被浏览器拦截 mixed content 时,自动回退内置本地句子库,纯前端实现、无需后端改动 - 仅首页展示:标签筛选 / 搜索态不渲染该区块,不影响列表浏览体验;亮暗两色均通过主题 CSS 变量自动适配
app.pyVERSION 同步至 1.3.5
v1.3.4
- 主题三态切换(跟随系统 / 浅色 / 深色):亮暗默认跟随系统偏好(Windows / macOS / iOS / Android 等各平台浏览器均可),点击导航主题按钮按「跟随系统 → 浅色 → 深色 → 跟随系统」循环;
auto(跟随系统)态按钮右上角带小圆点标识,系统主题变化时auto态实时跟随;tech 主题同步补齐系统主题变化监听(此前仅 default 具备) - 文章分享去除 Web Share API:PC / 移动端点击文章「分享」统一改为打开站内分享面板,主操作即复制链接(clipboard +
execCommand兜底),不再调起系统分享面板 - 免 API 社交分享:分享面板新增微博、QQ 空间官方开放分享入口(新窗口跳转官方分享页,无需任何 API Key);微信因无网页直跳接口,本地集成开源 qrcode-generator(MIT)生成文章二维码,扫码后在微信内转发
- 分享能力零外站依赖:二维码库本地化至
static/vendor/qrcode/,分享逻辑抽为通用static/js/share.js与static/css/share.css,default / tech 两主题复用;app.pyVERSION 同步至 1.3.4
v1.3.3
- 文章正文 Markdown 排版统一为 GitHub 风格:新增共享样式
static/css/markdown-body.css(.markdown-body语义),default 与 tech 两主题文章正文共用同一套排版参数与配色,观感逐像素一致;明暗配色随站点主题([data-theme])自动切换 - 代码高亮配色对齐 GitHub:文章代码块改用 GitHub 浅色 / 深色两套 token 配色(默认主题不再恒定深色 atom-one-dark,修复浅色模式下代码对比度问题)
- 移动端正文适配:小屏下正文代码自动折行、不再横向溢出,表格等宽内容不超出视口
- 文章页复制按钮去重:文章页内联的代码复制按钮与全局脚本互斥,同一代码块不再渲染两个「复制」按钮
- tech 主题分享按钮增强:优先调用 Web Share API(调起系统分享面板),不支持时降级剪贴板复制;新增 toast 操作反馈——分享 / 复制成功与失败均有明确提示,用户主动取消(
AbortError)不打扰 - tech 主题移动端页脚适配:窄屏页脚改为纵向堆叠,备案号整条可折行,不再溢出
- 仓库根目录废弃文件清理(测试截图、无障碍树快照、旧站备份目录等移除版本管理)
app.pyVERSION 同步至 1.3.3
v1.3.2
- projects 页面固定双栏:项目卡片网格由自适应列数改为固定两列(移动端仍单栏),布局更稳定
- 修复项目页语言标签筛选失效:筛选脚本选择器类名与卡片实际类名不匹配(
.tech-project-item→.tech-project-card),导致点击标签无反应 - tech-logo 闪烁动画:logo 末尾
/>加入终端光标式闪烁(steps(2, start)步进动画,不产生位移) - tech-nav-actions 恢复默认:去掉负 margin,导航右侧按钮与内容对齐
- 同步 app.py VERSION 至 1.3.2:此前 VERSION 停留在 1.3.0,后台升级检测与发布版本脱节
v1.3.1
- 新增 tech 主题(
templates/tech/):深色技术风主题,全套页面覆盖(首页 / 文章列表 / 文章详情 / 项目 / 状态 / 标签 / 关于 / 友链 / 404 / 500),后台「外观与主题」一键切换 - logo 括号特效:站点 logo 的
</>括号随 hover 变色 - 文章 md 亮暗色适配:markdown 内容在亮/暗色下均有正确对比度
- 首页头部统计徽章:首页头部展示文章数、标签数等统计徽章
- 项目页卡片网格:项目页改为卡片网格布局
- 导航按钮右对齐:导航右侧操作按钮右对齐
- 后台主题管理页:新增
admin/themes.html,主题选择卡片带预览图
v1.3.0
- 多主题系统:前台支持多套主题,后台「博客设置 → 外观与主题」卡片式一键切换,选择后立即生效,无需重启服务。主题为「样式 + 模板」两级:
theme.css可覆盖默认样式(推荐用 CSS 变量换肤),同名模板可整体重排页面(例如用posts.html覆盖默认文章列表页) - 主题目录结构变更:内置默认主题迁移至
templates/default/(原templates/下所有模板整体移入);新主题放在templates/<主题名>/文件夹即可被后台自动识别。单个主题文件夹可选内容:info.json:主题元数据(name展示名 /author/description/version)theme.css:覆盖默认样式,推荐用:rootCSS 变量换肤(见static/css/style.css的变量定义)- 同名模板:整体覆盖默认页面结构(如
index.html、posts.html) preview.png:后台选择卡片上的主题预览图(可选,缺省显示主题色球)- 主题机制细节:模板按「活动主题 → default」两级回退,主题模板优先;切换主题或手动改库后模板缓存自动同步,无需重启;
theme_static路由带扩展名白名单与目录穿越防护;TEMPLATES_AUTO_RELOAD已开启,主题文件改动免重启生效 - 随包附带示例主题
templates/example/(暖橙配色,纯 theme.css 变量换肤),可复制该目录作为开发新主题的起点。主题开发教程详见 DEPLOY.md
v1.2.10
- 导航菜单排序调整:顶部导航「标签」与「文章」顺序对调(原为 首页/标签/文章 → 现为 首页/文章/标签)。标签是文章的主题聚合索引,属二级入口,先文章后标签符合常规博客访问路径;「写作」管理入口仍固定置末
v1.2.9
- 彻底修复服务器上 SSL 证书天数恒为 -1:v1.2.8 的探测详情定位到真实原因——服务器缺少系统 CA 根证书,证书校验分支必失败;回退到不校验后 Python 在
CERT_NONE模式下getpeercert()返回空字典,既拿不到notAfter也拿不到 SAN,最终恒为 -1(这正是「HTTP 200 通但证书取不到」的原因)。本次修复:① 默认校验证书上下文自动探测并补齐常见系统 CA bundle(/etc/pki/tls/certs/ca-bundle.crt、/etc/ssl/certs/ca-certificates.crt等),让校验分支恢复可用;② 新增极简 ASN.1 DER 解析器(不依赖任何私有 API),不校验模式下直接从握手返回的证书字节解析notAfter与 subject 域名,无根证书环境同样能拿到证书剩余天数 - 保留 127.0.0.1 环回取证与失败原因透出:异常不再静默,探测详情会显示具体错误;反代部署下监控自身公网域名仍可经环回取证书
v1.2.8
- 修复 SSL 证书天数在服务器上始终为 -1:此前证书获取失败时所有异常被静默吞掉,无法定位原因;现失败原因会透出到探测详情(后台 probe 返回的
detail直接可见具体错误,如连接超时 / 握手失败 / 证书不匹配) - 新增 127.0.0.1 环回取证回退:以 https 反代 http://127.0.0.1:5000 部署时,监控公网域名会解析到本机公网 IP,本机回连自己公网 IP(hairpin)常被云 VPC 直接丢弃导致超时;现直连失败后自动改用
127.0.0.1:port环回握手(TLS SNI 仍填公网域名),由本机 Nginx 按 SNI 返回对应证书,环回流量不丢包;回退结果会校验证书确实匹配该域名,不会误取本机其他站点证书
v1.2.7
- 修复 SSL 证书天数按 URL 端口获取:监控目标为
https://域名:自定义端口(如 NAS 的 5001)时,此前证书读取固定用 443 端口,在服务器上会连接超时并拖慢整个探测、SSL 显示「—」;现按 URL 实际端口取证书,秒级返回正确天数
v1.2.6
- 修复监控 URL 误粘反引号导致 SSL 证书天数异常:后台保存或从前端复制 URL 时若带入 markdown 反引号(如 `
https://xxx/`),探测与证书读取将异常;现已在保存、解析、探测三处统一清洗 URL(去除首尾空白与反引号),带反引号的配置也能正确探测并显示证书剩余天数 - 防御多实例并行部署:若服务器残留旧版进程与新版进程并存抢占 5000 端口,页面访问可能被旧进程接住而请求到旧代码;部署时请先
pkill -f "python app.py"停净旧进程再启动
v1.2.5
- 急修:云 API 同步与 HTTP(S) 监控全部不可用:v1.2.4 禁代理直连时误用
OpenerDirector.open(context=...)(该参数仅顶层urlopen支持),证书校验失败回退分支必抛TypeError,导致同步、探测整套链路报错;已改为用HTTPSHandler(context=...)单独构造不校验证书的 opener,证书回退链路恢复正常
v1.2.4
- 云 API 禁系统代理直连:同步阿里云 / 腾讯云数据不再受系统代理残留影响(曾导致
WinError 10061 连接被拒),国内直连域名稳定出网 - 本机 / 私网监控目标快速判定:探测
http://127.0.0.1:5000等本机或内网地址时(本身无 443 证书),立即返回无证书,不再空等连接失败 - SSL 证书天数解析增强:证书
notAfter改用标准库parsedate_to_datetime解析(兼容 GMT 等时区名),修复 Python 3.12+ 下strptime %Z解析失败导致的 SSL 剩余天数显示为空;http / https 域名目标均能正确获取证书天数
v1.2.3
- 修复 HTTP(S) 服务监控证书校验失败:探测目标与 SSL 证书天数读取在无根证书环境同样报
CERTIFICATE_VERIFY_FAILED,现已与云 API 同步支持证书校验失败自动回退;统一封装_open_url复用
v1.2.2
- 修复云 API 请求证书校验失败:服务器缺少根证书时(如未安装 ca-certificates),请求阿里云/腾讯云 API 报
CERTIFICATE_VERIFY_FAILED;现自动回退为不校验证书重试(云 API 为固定官方域名,正常环境仍完整校验)
v1.2.1
- 云 API 按需同步:页面访问(前台 /status、后台配置页)永不主动请求云 API,仅后台「同步」按钮才会调用,点「保存全部配置」后生效;结果持久化 SQLite,进程重启不丢
- 状态页 UI 统一重构:到期时间与在线服务改为同款单栏卡片,布局、字体、间距完全一致;在线服务移除 URL 显示,前端只看探测结果,隐私更安全、无需打开新窗口
- 后台密钥明文切换:AccessKey Secret / SecretKey 输入框新增眼睛按钮,一键切换明文 / 脱敏显示
- 到期临近视觉提醒:即将到期显示橙色警示条、已到期显示红色警示条,日期与状态指标同步着色
v1.2.0
- 新增服务器状态页(
/status):前台独立页展示云资源到期时间与 HTTP(S) 服务在线状态,数据每 5 分钟自动探测、页面每 60 秒轮询刷新 - 云到期时间自动查询:后台「系统 → 服务时效」填写阿里云 / 腾讯云密钥,调用官方 API(HMAC-SHA1 / TC3 签名)自动获取服务器与域名到期时间;未配置密钥可手动填写兜底
- HTTP(S) 服务监控:后台可增删探测目标,守护线程每 5 分钟轮询状态码、延迟、SSL 证书天数与近 24h 可用率,持久化 SQLite,重启不丢
- 阿里云支持轻量 + ECS 双通道、腾讯云域名到期:服务器类型可切换,自动走
ListInstances/DescribeInstances/DescribeDomainBaseInfo;修复多处 API 兼容问题(endpoint 地域、Action 名称、Content-Type、TC3 签名密钥前缀等) - 修复后台「服务时效」JS 语法错误与监控保存后需等 5 分钟才有数据的问题(保存即开始探测)
v1.1.9
- 修复文章排版间距错乱:
style.css的:root变量表此前缺少--sp-7(28px)与--sp-9(36px)的定义,导致 H2/H3 依赖这两个变量的margin属性整体失效回退为 0,章节标题顶部间距全部塌陷;已补齐变量定义,H2 上间距 36px、H3 上间距 28px 恢复设计值 - 统一分隔线间距:正文
<hr>上下间距从 32px/40px 三种不一致取值归一为 24px,与引用块、代码块、图片、表格的块间距节奏完全一致;删除花括号孤立重复的.post-body hr覆盖规则(原 40px) - 补齐 H5/H6 样式规则:此前仅 H1-H4 有排版规则,H5/H6 回退浏览器默认样式;已按「上间距随层级递减、下间距统一 8px」的标题体系补齐(H5:fz-base/20px 上间距,H6:fz-sm/16px 上间距,H6 用次级色弱化)
- 前端静态资源横幅版本号
?t=随VERSION升至 v1.1.9,浏览器/CDN 将自动获取新样式,无需手动清缓存
v1.1.8
- CDN 全部本地化:
base.html中 cdnjs 的 highlight.js CSS/JS 引用替换为本地static/vendor/highlight.js/,外网依赖归零 - 代码高亮库瘦身:highlight.js 从 11.7.0 完整包(明文 1MB / gzip 301KB)降级到 10.7.3 common 版(明文 135KB / gzip 42KB),文章页首屏体积减负 ~86%。11.x 自 11.0 起 common 构建仅提供 ESM 模块,10.7.3 是最后一个带 UMD common 单文件的版本;API 与 atom-one-dark 主题完全兼容,含博客常用的 37 种语言
- Nginx 性能优化文档(
DEPLOY_BT.md新增 7.5 节):补齐 gzip_types 全类型(CSS/JS/字体/SVG)、/static与/uploads加Cache-Control: public, max-age=2592000, immutable、可选 Brotli 压缩、Cloudflare 等 CDN 边缘缓存规则 - JS 加载优化:高亮
hljs.highlightAll()改用requestIdleCallback(timeout 1.5s),长文章首帧主线程不再被高亮阻塞 - 无障碍/省 CPU:粒子背景监听
prefers-reduced-motion: reduce,开启系统级减少动效时跳过粒子动画,桌面端持续省电
v1.1.7
- 文章浏览计数:文章详情页显示「N 次浏览」。精准统计:页面可见且累计停留满 5 秒才计一次(秒开秒关、切后台不计);同一会话刷新不重复计数(sessionStorage);服务端对同一 IP 同一文章 60 秒窗口兜底防刷
- 文章分类展示:文章详情页
post-header-meta显示分类(排序:日期 · 分类 · 阅读时长 · 浏览数);首页文章卡片同步显示分类;新增.card-category样式,分类图标与文字垂直居中对齐
v1.1.6
- 文章标签自动添加:编辑/创建文章时,输入正文与标题后自动识别候选标签;标签为空时自动将词频最高的 5-7 个标签填入(数量随机取 5-7,选词按词频优先)。识别按小写去重,不再出现
Python/python大小写重复;自动添加后建议区自动过滤已选标签
v1.1.5
- 修复升级页卡片间距与文本行距:升级页 JS 检测结果卡片包裹在
#upgrade-result容器内,原有间距规则(.admin-main > .card)匹配不上,导致结果卡片与「升级说明」卡片紧贴、说明文本上下无行距。已为容器内卡片补齐间距规则 - 静态资源版本号动态化:
admin.css/admin.js/style.css/main.js的缓存版本参数由固定日期改为跟随应用版本号(t=v版本号)。升级后版本号自动变化,浏览器自动拉取新资源,无需再手动改版本号
v1.1.3
- 修复升级页转圈卡死:此前后台每次请求都会同步请求 GitHub API 检测版本,网络受限时(DNS/TLS 阻塞)整个后台与升级页会长时间转圈。现改为异步检测:升级页立即渲染(毫秒级),由前端 JS 请求
/admin/upgrade/check接口填充版本信息;后台其他页面仅读取缓存,不再主动联网
v1.1.2
- 修复升级锁卡死:升级过程异常中断(进程被杀/断电)会残留
upgrade.lock导致永久提示"升级任务已在进行中"。现锁文件记录时间戳,超过 10 分钟自动视为过期并清理,可正常重试升级
v1.1.1
- 修复文章链接丢失:正文中的 Markdown 自动链接
<https://...>在 Vditor 编辑器往返转换时会丢失(打开编辑页再保存 URL 即消失)。现已在编辑页加载、保存、渲染三层统一规范化为标准链接[URL](URL),编辑保存不再丢链接
v1.1.0
- 文章编辑体验:Slug 自动生成改为纯 ASCII(剔除中文),新增 Slug 实时预览;摘要支持从正文自动获取(保存时后端自动截取 + 编辑页「从正文自动获取」按钮)
- 标签自动识别增强:标签库统计含草稿文章;正文高频英文术语自动提取为候选标签(如 fnos/oauth/websocket);自动识别区与常用标签区扩容至 20 个
- 文章阅读体验:正文超链接默认新窗口打开(页内
#锚点除外);标题自动生成锚点 ID,支持#12-章节名页内定位;任务列表[ ]/[x]渲染为勾选符号;正文排版优化(行高 1.85、标题层级清晰、表格/代码字号增大) - 后台编辑页面板自适应彻底修复:侧栏内容不超视口时固定跟随,超高时自动回退随页面滚动,任何分辨率/缩放均不裁剪
- 登录页品牌动态化:表单品牌区显示博客名称,左侧品牌区显示首页标题(留空则用站点名)
- 换行符规范化:新增
.gitattributes统一 LF,消除 Windows 下 git diff/status 换行警告刷屏
v1.0.9
- 修复 iOS 18 HEIC 上传失败:iPhone(iOS 18 起)拍摄的 HEIC 元数据结构变化,内置 libheif < 1.18.2 的 pillow-heif(如 0.15.0 / libheif 1.17.6)解码时报
Metadata not correctly assigned to image。需将 pillow-heif 升级至 ≥ 0.18(内置 libheif ≥ 1.18.1,推荐 0.22.0 / libheif 1.19.7) - HEIC 诊断增强:启动时打印 pillow_heif / libheif / Pillow 版本;解码失败时错误提示透出真实异常与版本号,便于定位(此前为笼统的"文件可能损坏"提示)
v1.0.8
- 修复系统升级卡住:升级包下载改为直连 GitHub 优先、连接失败/超时(60s)后自动降级镜像,避免部分网络环境直连 codeload 长时间挂起;镜像列表可用环境变量
UPGRADE_MIRRORS配置(逗号分隔,设空串则纯直连) - 修复 HEIC 上传误报:
pillow_heif解码改为open_heif()直解码,不再依赖 Pillow 插件注册机制(解决已安装 pillow_heif 仍提示"缺少解码支持"的问题);错误提示区分"未安装"与"解码失败"两种原因;头像上传同步支持 HEIC
v1.0.7
- 上传目录迁移:附件存储由
static/uploads/迁至项目根目录uploads/,新增/uploads/静态路由;服务器升级后启动时自动迁移旧文件并批量替换数据库中已存储的/static/uploads/URL 为/uploads/(幂等,重复启动安全) - 修复上传严重 Bug:修复
_save_upload分支嵌套错误,此前非图片类文件(zip/pdf/mp4 等)上传后不会落盘却返回 URL,产生大量死链 - 升级保护目录新增根目录
uploads/;Nginx 配置样例新增/uploads静态 location(HTTP/HTTPS 两处)
v1.0.6
- 新增 HEIC/HEIF 照片上传支持(iPhone 拍摄照片):pillow-heif 解码后自动转 JPEG 压缩存储,覆盖文章编辑器与头像上传
- 修复后台
/admin/posts/new编辑页右侧设置面板在部分分辨率下显示不全的问题:短视口回退阈值由 760px 提升至 900px,覆盖 1366×768 等常见笔记本分辨率
v1.0.5
- 系统升级检测优化:成功检测缓存由 1 小时缩短至 10 分钟,避免新版发布后提示滞后
- 升级页新增「重新检测」按钮(强制跳过缓存重新查询 GitHub Releases)
- 首页
/?tag=xxx与文章列表/posts?tag=xxx的<title>显示「标签 - 站点名称」
v1.0.3
- 新建 / 编辑文章支持自定义发布日期(
datetime-local选择,留空默认当前时间) - 编辑页标签自动识别(标题、正文) + 常用标签快捷点选,可手动补齐未识别标签
- 新增系统升级:后台检测 GitHub Releases 最新版本,可一键备份数据(数据库 + 上传文件)后下载覆盖代码升级,文章 / 分类 / 评论 / 设置等数据保留
- 后台侧边栏版本号改为链接至升级页,检测到新版本时仪表盘与侧边栏均有提示
v1.0.2
- 文章详情页正文区域接入
post-card卡片样式,与首页卡片风格统一、自适应更好看
v1.0.1
- 后台仪表盘「友情链接」统计修正:仅计入已通过审核(
approved)的链接,排除已拒绝/待审核项 - 后台侧边栏底部新增版本号显示(
infowe Blog v1.0.1),并链接至开源仓库(新窗口打开) - GitHub 同步支持 Token 认证 + certifi SSL 校验 + 精确错误提示
评论 0
还没有评论,来抢沙发吧~