压缩 activitywatch 的 SQLite 数据库

曾经关注过 activitywatch 数据文件尺寸的问题,之前先简单地用 Link Shell Extension 把数据目录从 %localappdata% 移动到次级磁盘。

过了一段时间发现目录已经涨到 3.22 GB 了,主要是 activitywatch/aw-server/peewee-sqlite.v2.db 这个文件吃掉了大部分。是个 SQLite3 文件,可以尝试用 VACUUM 命令来压缩。

但它的 PRAGMA main.freelist_count; 居然是零诶,也就是压缩完全没效果,实际执行验证也是如此。

我之前设置过 aw-watcher-utilization,现在感觉它没什么用,而且通过计算,它产生了 777403 / 1354613 约 57.3% 的数据。执行 delete from eventmodel where bucket_id in (select key from bucketmodel where client='aw-watcher-utilization'); 后, freelist_count 来到了 755943。

这时候执行 VACUUM,效果显著,尺寸从 3.22 GB 来到了 144 MB,瘦身率 95%。

沉浸式翻译因 CORS 问题无法连上 Ollama

最近又把 Ollama 拿出来用,打算在本地跑翻译模型。然而发现它的 CORS 头怎么就是返回不对。

按照 其他 AI 模型临时接入 | 沉浸式翻译 设置的,自定义 URL 地址:http://localhost:11434/v1/chat/completions,谁知道实际在沉浸式翻译中测试服务提示错误

Access to fetch at 'http://localhost:11434/v1/chat/completions' from origin 'chrome-extension://amkbmndfnliijdhojkpoglbnaaahippg' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'http://127.0.0.1:11434' that is not equal to the supplied origin. Have the server send the header with a valid value.

明明请求的 host 是 localhost,Origin 和 Access-Control-Allow-Origin 都是 127.0.0.1

OPTIONS /v1/chat/completions HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Access-Control-Request-Headers: api-key,authorization,content-type
Access-Control-Request-Method: POST
Connection: keep-alive
Host: localhost:11434
Origin: http://127.0.0.1:11434
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0
 
HTTP/1.1 204 No Content
Access-Control-Allow-Headers: Authorization,Content-Type,User-Agent,Accept,X-Requested-With,Openai-Beta,X-Stainless-Arch,X-Stainless-Async,X-Stainless-Custom-Poll-Interval,X-Stainless-Helper-Method,X-Stainless-Lang,X-Stainless-Os,X-Stainless-Package-Version,X-Stainless-Poll-Helper,X-Stainless-Retry-Count,X-Stainless-Runtime,X-Stainless-Runtime-Version,X-Stainless-Timeout
Access-Control-Allow-Methods: GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS
Access-Control-Allow-Origin: http://127.0.0.1:11434
Access-Control-Max-Age: 43200
Allow: POST
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Date: Mon, 08 Dec 2025 16:36:58 GMT

好好好,那我把沉浸式翻译插件设置的自定义 API 接口地址改为 http://127.0.0.1:11434/v1/chat/completions,提示保存成功,测试还是失败。甚至不论我改成什么乱七八糟的内容,请求发出的还是旧地址。

原来提示保存成功只是保存成功了,还得刷新页面才能生效,非常友好的用户体验了 😓

点测试服务,这次还是 CORS 拦截,响应里 CORS 头直接没了。
Ollama 还特殊处理了 127.0.0.1 的请求,完全不提供 Access-Control-Allow-Methods 响应

OPTIONS /v1/chat/completions HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Access-Control-Request-Headers: api-key,authorization,content-type
Access-Control-Request-Method: POST
Connection: keep-alive
Host: 127.0.0.1:11434
Origin: http://127.0.0.1:11434
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0
 
HTTP/1.1 405 Method Not Allowed
Allow: POST
Content-Type: text/plain
Date: Mon, 08 Dec 2025 16:47:17 GMT
Content-Length: 22

那还是老老实实地设置 OLLAMA_ORIGINS 吧。我想的是浏览器插件肯定是走 worker 发起的请求,那按照 How can I allow additional web origins to access Ollama? - FAQ - Ollama 设置 OLLAMA_ORIGINS=chrome-extension://*,moz-extension://*,safari-web-extension://* 应该没问题吧。不,不行,接入指南说得对,得设置成 OLLAMA_ORIGINS="*"

接下来就是另一个错误:

Access to fetch at 'http://localhost:11434/v1/chat/completions' from origin 'chrome-extension://amkbmndfnliijdhojkpoglbnaaahippg' has been blocked by CORS policy: Request header field api-key is not allowed by Access-Control-Allow-Headers in preflight response.

Oh,api-key 不被允许传入,然而 Support for API_KEY based authentication · Issue #8536 · ollama/ollama 社区建议整个前置代理来 处理 API_KEY,还能让 AI 自己动手弄,多 么 贴 心 😓同时沉浸式翻译插件还必须指定 API Key,我记得以前没那么麻烦

最后发现 [Bug]: Ollama用不了,设置了CORS还是报错 · Issue #3243 · immersive-translate/immersive-translate 和浏览器插件的站点访问权限设置有关,我为了避免所有网站都被 Inject Script,只在点击时才生效。这样导致浏览器强 CORS 校验。

同时也是这个站点访问权限设置的原因,多个翻译服务对比 功能会白屏,调完就好了

MerlinClash 强制绕行规则不处理 IPv6 地址

今天发现 ollama pull 时流量虽然都走到 Clash 的 DIRECT 规则去,但路由器 CPU 占用持续飙高,就想着把这几个同属 AS13335 的 r2.cloudflarestorage.com 解析结果的地址绕过 Clash,先加上看看影响面。

172.64.64.0/20      # r2.cloudflarestorage.com AS13335
2606:4700:2ff9::/48 # r2.cloudflarestorage.com AS13335

但在界面 IPtables前置分流编辑强制绕行规则 后,IPv6 地址并没有加进 ipset。在路由器上 ipset list ipset_proxyarround6 没有结果。当前插件版本 0.5.1.A64,目前看更新日志这个 bug 还没修复。日志提示

【2025年12月09日 02:12:35】: 开始创建强制绕行Clash的ipset规则集
【2025年12月09日 02:12:36】: 172.64.64.0/20为合法IPv4格式,进行处理
【2025年12月09日 02:12:36】: 2606:4700:2ff9::/48不为IP格式,检查是否为域名地址
【2025年12月09日 02:12:36】: 格式有误,略过

阅读代码,问题出在 detect_ip() 函数中,在多个文件有重复定义,比如 scripts/clash_ipsetproxyarroundchange.sh 。它的 IPv6 正则表达式长这样

简化版IPv6地址 + 可选掩码 /0-128
^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(::([0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}))(/([0-9]|[1-9][0-9]|1[01][0-9]|12[0-8]))?$

无法处理前两个用例,感觉是写错了

Test Case
2c0f:f7a8:9010::/48
2409:8a1e:6940:7c20::1/128
2409:8a1e:6940:7c20:a236:bcff:fe70:ce58/64

改成这样,主要是变了第二段匹配 :: 的地方

修改后的 IPv6 正则
^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(([0-9a-fA-F]{1,4}:){0,5}:([0-9a-fA-F]{1,4})?))(/([0-9]|[1-9][0-9]|1[01][0-9]|12[0-8]))?$

这项目报 bug 好难,我先自己试试验证。

结果很喜人,ollama pull ministral-3:8b 绕行了, CPU 占用几乎为零,但下载速度没什么提升