普通视图

Received yesterday — 2026年4月20日

济南,济南

作者obaby
2026年4月20日 13:29

济南,一个自己待了数年的地方。自己也没想到,等那天真的离开之后,就不再常有去的机会了。上一次去济南还是参加室友的婚宴,一眨眼已经快十年了。

现在,又到了一个春意盎然的季节,宝子虽然已经去过很多的城市,山东省内周边依然都跑遍了,现在剩下的还有靠近最西面的那几个城市。济南,曾经也多次想去转一转,看一看,是不是还是记忆中的样子。然而,却又纠结于出行的便利性,对象总说,去了济南几次,体验印象总是不好。交通差,环境一般,又热。

眨眼时间,感觉年还没过完多长时间,就到了五一了。五一出去玩总是感觉体验更差了。并且,按照济南的温度,等五一的时候就更热了,看那人山人海,总是感觉有些抗拒,最后还是选择了这个周末带着孩子去溜达溜达。

早上七点多高铁,到济南十点多。刚从高铁出来,就开始狂打喷嚏,空气中飞舞的杨树毛毛实在是太多了。从车站出来,本来想打个六座商务,一顿狂奔跑到上车地点,发现竟然是辆出租车。只好让他们先走,自己后面再打一辆车。然而再次打车的时候,发现有进行中的订单,没法打车,好在另外一个手机上还有个滴滴,不然这真就麻烦了。

大明湖畔的夏雨荷?

安顿好,吃过午饭下午就可以出去玩了。对象同学推荐的珍珠泉宾馆,在公园内,出门去哪里都很方便。最终也是选择了这个地方,到了之后找吃饭的地方,也费了一番周章。宝子姥姥这不吃,那不吃,济南小吃把子肉自然是就被排除了。最后选择了一家离住的地方比较近的的全景餐厅。

一顿饭吃下来,除了贵的确没什么优点。羊肉又老又硬,备注不让放蒜的菜,里面还有独头蒜,可能独头蒜不是蒜吧。整体吃下来,就九转肥肠还有佛跳墙勉强可以。其余的几个菜,实在是水平一般。

中午回到住处稍微休息会儿,下午出门的时候从酒店窗户看出去,还以为是阴天了,出门以后发现完全不是,艳阳高照。沿着珍珠泉内部游览,到北门的时候却发现是封闭的,根本出不去,如果要想去大明湖,只能原路返回,从珍珠泉公园围墙西侧绕行过去。

 

这可能只是个普通的周末吧,路上的游人络绎不绝。当然,也有无数穿汉服的小姐姐,只是妆画的稍微浓了点,没那么精致。不过户外拍照可能也好,毕竟室外的光线和环境还是蛮不错的。当然,不精致的好处就是化妆时间可以大大减少,这样就可以多画几个了。

大明湖,最出名的竟然是夏雨荷。一个源自琼瑶小说的人物,这个文创的出发点的确有点让人匪夷所思。济南那么多名人,最后竟然选了一个夏雨荷。上次逛大明湖,还是从厦门回到青岛的时候,带一个姐妹来大明湖转了一圈。只是,从始至终,两个人甚至连一张合照都没有,而现在,也悄然断了联系。

空气中的毛毛,落在草丛里也叠成了厚厚的一层,看上去仿佛下了一场雪。湖中,那个破败的船,不知道是年久失修还是尚未完工,看起来的确也没什么美感,就这么坐落在湖中。

这半圈下来,宝子的姥姥姥爷已经走不动了。带他们出去准备去商场吃饭,顺便对象去给宝子买条裙子。白天玩的时候,一直嚷嚷好热啊,好热啊,跟复读机一样。

母校

他们去逛商场买东西,自己约了在济南的几个室友。准备去学校吃点东西,上次来学校也已然是十多年前了。每次来,总是能看到一些变化,每次来又感觉还是那个样子。

打车往学校走,到处都是修路的影子,从自己第一次来济南感觉就在修路,直到后来离开济南,还是在修路。现在再来的时候,还是在修路,济南的路感觉永远也修不完。路上的电动车自行车浩浩荡荡,在车上我都担心司机可能会蹭到他们。

现在想进校门不再那么方便了,需要校友卡或者提前预约。室友L发了个小程序的链接,好在自己提前注册认证好了。到门口出示校友卡,刷身份证就可以进入了。

从北门进入,现在操场下面是一堆小店,移动、联通等等。路上的道闸一层又一层,不知道是出于什么设计理念。

一路向南,貌似拆了几栋楼,自己原来的宿舍里依然还在,看似来除了外墙稍微新了点,似乎也没什么变化。

_

小树林还是多年前的木地板,稀稀落落的坐着几个人。

还有一个红色的牌子。

只是,现在回家多少有点麻烦。

溜达到快到南门的时候,发现了一个主题邮局,这个貌似之前来的时候还没有。

买了一件粉色的连帽T恤,一个粉色的笔记本,还有那个粉色的小熊。小熊不是很好带,只好让他们帮忙给寄回去。

从南门出来,也已然不是记忆里的样子,对面的书店,现在变得高级感十足。

晚上在学校餐厅三楼点了几个菜,X去买了几瓶rio,算是简单的相聚。晚饭后沿着学校的道路溜达,从南门到北门,操场,教学楼。太多的地方依然不是记忆里的样子。

曾经昏暗的八角楼,现在变得亮如白昼。

南门广场终于也不再是那种绿洼洼的射灯,现在看起来温暖多了。

北门的外卖柜,的确是个高级设计,外面投,里面取。S说,这可以说是这个学校最伟大改进。

路过宿舍楼的时候,听到两个小情侣在闹分手。

女:我想分开一段时间。

男:想分就分吧,我不觉得自己有什么问题,我觉得我做的挺好的,你想跟谁就跟谁吧。

女:不是这个意思,……

我跟L说,那俩分了,你去不领一个走?

X问:啥要分了?

我说:后面那俩在闹分手呢。我简单复述了一下他们的对话。

X说:这叫极限拉扯,在追求自己的利益呢。

我说:能干就干,不能干就滚呗!

L大惊:啥意思?

我的意思是,能过就过,不能过就分。这种自认为完美无瑕的男人,我要是那个女生,早就撒丫子跑了。我忙解释道。

X说:你头一直这么铁吗?

不不不,我上学的时候也是傻逼。还没经受过社会毒打,经过社会毒打之后才变得这么铁的,哈哈哈。我回道。

快出校门的时候,X说,你们等一下,我去骑我的小电动。

我跟L刷卡出去,站在外面看路边的标牌。我说:『刚看这个网吧,我还想什么沙雕名字,墨迹网咖,咋地越打越墨迹?后来才发现我看错了,是星迹网吧。』

『你还是那么幽默』L说,的确,我这不认字、以及看错顺序的毛病不是一天两天了。

X过了十几分钟从道闸出来,说:『刚才被吓一跳,一个男生在大马路上去找一个女生要微信,被无情的拒绝了!』

『现在还流行这么要联系方式吗?如果找我要,我也不给!』我说。

趵突泉

这也是济南必去的景点了,来都来了,怎么能不去呢。早上一早起来就奔趵突泉而去,这次尝试只选商务,然而,很不幸根本没有。最后还是打了一辆出租车。他们走了之后自己解锁了一辆共享单车骑过去。在路上这自行车道有的在辅路的左侧,有的在右侧,直接整懵逼了。

趵突泉树上的牌子写着:『再喂就嘎了』,意思是已然不让投喂锦鲤。实际情况也是并没有人投喂,然而对象在入口给宝子买了六包小鱼食,最后终于在一个比较偏的小河中,找到一群小金鱼,把鱼食投喂了出去。

再出发之前就看到有人发的把子肉味的酸奶,这下也总算是体验到了。

感觉是一股咸肉粽的味道,腻歪歪。不过那个荷叶味道的还是蛮清新的。

相比大明湖,趵突泉就小多了,用了个把小时转悠一下就准备下一站了。博物馆,当然,很多人都觉得写的是山东情妇馆。

 

鉴于上午退房之后,现在有三个大背包,想着找个储物柜存起来。去发现所有的储物柜都是满的。进去之后,发现包里有自拍杆,保安提示可以把自拍杆寄存到保安室,这下正好就可以把其他的几个包寄存了,省下一个带笔记本的,怕万一有点什么事情也不好处理就背在身上。

从四层一层层的往下走,当然主要是为了看现眼包文物。那个青铜首饰盒上面的两个小人是全裸的,嗯嗯,这就蛮有意思的。关键是,那个小男人,JJ绷的又长又直。

看到那根巨长的胫骨,我跟我对象说,它好长啊,我感觉比我的骨头长,我的也就两扎多点,那个至少得有三扎,我得拍下来。

一层层转下来,已经是下午一点,隔着一个街区,路过美术馆就到了万象汇,所有的饭店都在排号,想着找个排队少的,也挺难的。趁他们在等椰子鸡的时候,自己去溜达了一下,找到一个北京羲和烤鸭,刚开始还想,这義和烤鸭,我第一个想到的竟然是义和团。等了十几分钟,大桌叫号之后自己进去等,给他们打电话通知过来。想着叫义和烤鸭总是有点不对,只是告诉他们是北京烤鸭。对象来了之后,我说,这义和烤鸭名字是不是有点那啥,让我想到了义和团。对象说,我也是,第一眼这么像的,后来发现不是,是羲和烤鸭,你看盘子上。

仔细观察才发现真的是羲和烤鸭,得被没吆喝说让他们来义和烤鸭。

完善的火车,下午依然有足够的时间。刚好就可以去路过的美术馆了。虽然没啥美术细胞,但是看看嘛,总也是好的。

一楼的问道,一不小心,就问到了三楼。

其他的就是各种美术展,陶瓷展,属于自己看不懂的犯愁了,唯一能看懂的就是这个万花筒。

离开的时候,又经过门口的那个雕塑,还是忍不住拍了下来。

这光屁股的男人,身材是真的好,头上顶个蛋,抬着头,双手捂着私处。

这雕塑难道是想告诉我:别折腾了,折腾来折腾去,有个蛋用啊!

 

Received before yesterday

偷梁换柱 — 解决『出境易暂不支持此应用。』

作者obaby
2026年4月17日 15:30

前几天去买手机的时候,销售小哥说,如果你不喜欢这个纯血鸿蒙,或者感觉无法满足需求可以回来去二楼,找技术把系统进行降级。

当时我在想:对于我这种买手机不怎么玩游戏或者需求没那么多的人来说,应该能解决我的绝大多数需求,毕竟系统上还有 出境易、卓易通。

然而事情总有例外,自己常用的浏览器vivaldi发现竟然无法安装,这就让人非常的抑郁了。

下载apk安装的时候提示:出境易暂不支持此应用。

哎,咱们可不兴这么搞啊,这就离谱啦。我已我不稳定的智商来猜测这个东西肯定是有个神马白名单或者黑名单机制,至于黑白名单,到时也没那么关键,大不了就改个包名嘛。然而安装 apktool m的时候同样的提示也出现了,这个东西大概率就是黑名单了。

算鸟,算鸟,直接用模拟器改吧:

点击快速编辑:

原来的包名:com.vivaldi.brower,咱们假装是uc咋样呢:

反正我也不用uc浏览器,嘎嘎。

修改之后,发送到手机进行安装,一切顺利,嘻嘻:

鸿蒙next:我要验牌!牌没有问题!

尝试同步功能:

完美!

到这里就结束啦,对于同步问题,有的宝子说非得搭梯子,也不一定。可以直接修改hosts,可以在路由器配置或者dns配置,或者神马别的地方配置:

vivaldi.com. 172.66.165.60
bifrost.vivaldi.com. 31.209.137.10
cdn.jsdelivr.net. 151.101.89.229

 

生日快乐 — 又是一年二十九

作者obaby
2026年4月16日 13:52

年复一年,时间似乎过的很快,又过的很慢。今天一直在忙各种事情,直到现在才有片刻的空闲,来庆祝下自己的生日。

这一年发生了很多意料之外的事情,甚至有的事情到现在还没有结论,后续如何更是一个未知数。然而,不管如何,生活还是要继续的。这慢慢人生,没有太多的时间去彷徨,去挣扎,去苦闷。

好几天之前,刷到一个视频,我跟对象说,我要把这个在我生日那天发朋友圈,之前保存下载,今天早上就出现在了自己的朋友圈了,虽然没人点赞,没人回复,我倒是也不在乎,自己开心就好。

至于生日礼物,上周的时候对象就问自己想要什么。

『我要三折叠』

『没有』

『我要双折叠』

『也没有』

对于这种折叠屏手机,只是没用过,有点喜欢,可能也没那么喜欢。昨天中午,趁着午饭的时间,去乐客城外面的华为体验店看了一眼。

只是出来之后,原来的华为竟然变成了小米。高德搜了一下发现地标还没变,但是在其他的地方有另外两个,只好往另外一边的华为体验店走。

中午时间,店里没几个顾客,连店员都没几个。看了下三折叠跟双折叠,三折叠太贵,双折叠的尺寸总是觉得有些奇怪。

双折叠的感觉就是叠起来,打开比例看着都挺奇怪的。三折叠的价格,实在是不敢恭维,快两万块钱买个手机,这已经远远超出自己的可承受范围了。走之前给对象发消息,得到了明确答复,坚决不同意买三折叠。

最后,目标还是落在了mate 80 和pure 80上,至于mate,那个中间的摄像头总是感觉有些别扭,店员还说,那个特别商务,看起来比较大气。问题是,我不喜欢商务风啊。

鉴于线下还能领国补,虽然没有自己想要的金色,还是果断下单了,最终选的的白色,黑色也不喜欢。

还给了一堆乱七八糟的赠品,聊胜于无吧。

之前的p70 pro彻底放弃了,而至于30,也的确支撑的有点吃力,至于90,新机价格大概率比较贵,所以现在马上换代了,80 就80吧。

晚上回家的时候,收到了对象送的猫和老鼠的小手办,老鼠被压成鼠饼的那一集,嘻嘻。

中午的时候,买的新的车载空气清新剂和另外一条瑜伽裤到了,之所以再买一条是感觉上一条的弹力不够大,跳绳的时候没有足够的压力支撑。

上面是原来的,现在已经没什么味道了、下面是新买的。

味道还是蛮清新的,喜欢女生味的可以考虑下哦,香型:香奈五号。香奈儿的就不考虑了哈,那个太贵了,很多仿这个香味的。

比原来的大一圈,放到前面的杯架刚刚合适。

至于瑜伽裤,感觉弹力的确比上一条要好一些,价格也自然是贵了点,上一条黑色瑜伽裤的两倍。

上身效果:

最后,贴一下现在的手机壁纸,希望锦鲤给所有人都带来好运哦:

我要赚钱钱 我要暴富富
我要变美变瘦变酷酷
我要钱多多 我要买车车

Baby Press — 前后端分离的WP系统

作者obaby
2026年4月14日 09:53

WP的系统怎么说呢,有时候真的感觉一言难尽,庞杂的功能,丰富的插件、主题。几乎能满足所有人的需求,当然,也能满足我的需求。

之所以要做这么个东西,最主要的是前几天在杜老师的聊天室收到一条消息:

跟随这条消息我也去了解了一下这个东西,按照官方的说法,其实是这么个东西:

Cloudflare 将这款项目命名为 EmDash,将其定位为 WordPress 的精神继承者,这并不是对 WordPress 简单的复刻,而是用现代化技术栈,重新实现一套面向未来的 CMS,并且重点解决了 WordPress 24 年发展中积累的的架构臃肿、安全隐患与性能瓶颈问题。

说是高性能的wp,但是实际上跟wp没有任何的关系,除了所谓的精神继承。刚开始我还以为是基于wp的优化,现在看来其实是完全做了另外一套系统,这精神继承,可以说是非常抽象了。

再加上 『爱看』在我没有丢失以前的网站数据的时候,就一直建议可以自己写个系统。重新搭建之后,他又提过几次:

既然 cf可以这么干,那么自己当然也可以这么干。只是,这次自己既不想重写,又不想使用php,于是,我换了最熟悉的django+vue3来实现这个新的系统,至于数据库当然还是用wp原来的。既然设计好这一切,那么声息的就是让ai开始动工了。

当然在开发过程中,不可避免的要面临一些问题,例如wp的shortcode,主题插件的一些功能:相册、代码高亮等等。不过这些东西都可以重新通过python进行处理和渲染。还有一些php的原生小组件渲染就有些困难了,这些只能通过其他方法进行实现。例如归属地、ua,访客信息等等。暂时尚未完成,为了处理ip归属地查询,目前将插件的归属地查询已经独立成了python服务,开源地址:https://cnb.cool/oba.by/baby-ip-location

测试地址:https://ip.zhongxiaojie.cn

当前测试页面效果:

访问地址:

https://i.zhongxiaojie.cn

代码暂未开源,还在继续完善。

虚惊一场

作者obaby
2026年4月13日 13:26

春节过后,就去过一次台球厅,之前充的钱大概还剩个四百多。这次这么着急想去,是因为上次去的时候,感觉老板和员工全部都换了一个认识的也没有。

而之所以隔了这么久没去,是因为没有球搭子,自己一个人去也着实没什么意思。好不容易约上一个哥们去打会儿球,路上我还说:『我得赶紧把球杆拿走了,老板换了好几波了感觉。』

台球厅提供免费的球杆寄存服务,最开始的时候会给各密码锁的小柜子。自己设置好密码就可以了,然而,后来某一天去玩的时候发现球杆明显被人用过。之所以会被发现,是因为自己的球杆是粉色的,连巧克粉都是粉色的。球杆从杆盒里拿出来之后,却在皮头上看到了明显的蓝色的巧克粉使用痕迹。两次打球之间的时间间隔也有点长,调监控看谁用的感觉也不大值当的。也就不了了之,后来发现有人会把球杆寄存到前台。这次时间之后,也就把球杆寄存到了前台。之所以能被开锁是因为那个密码想有个超级密码,可以强制开启,而开启时候随便设置一个新的密码就能再锁上了。这也就解释了为什么之前有时候自己明明输对了密码却打不开箱子,明显是被改了密码。

 

比较尴尬的地方在于,这只球杆的杆盒有点长,粉皮的后备箱竟然塞不进去,唯一一个方向能塞进去那就是斜着,不过这样塞进去就没法放其他的东西了。所以现在车上放着是另外一只球杆。

多年以前在厦门的时候买的第一支球杆现在在大白上,买的第二支球杆送了别人。现在还有三只球杆,每辆车上一支,常去的球厅一支,现在球厅的球杆不能放了也就只能带着了。

(图文无关,照片不是最近拍的)

到了台球厅前台,发现前台寄存的球杆竟然都不在了。问了下老板,老板说球杆都被放到寄存柜内了,问有没有加之前老板的微信可以问一下。

一通交涉之后,说寄存到时候应该都拍照了,让提供照片,他们去找。

随便拿根球杆先去玩着,过了半了多小时,有个哥们过来说,找到了,在15号柜。一通折腾之后,总算是找到了。拿出来之后,看了下批头,依然是有些蓝色的使用痕迹。

猜测应该是又被别人用了,看来是时候换个台球厅了。

今天中午终于没有剩饭需要消灭了,之前回老家晚上开车的时候因为玻璃太脏别了大奔。现在雨过天晴,该去洗洗车了,不然玻璃真的是看不清楚了,尤其是晚上开车,后方情况完全看不清楚。洗白白,晚上就能看清楚了,虽然每蹭到,但是回想起来仍心有余悸。

刚扫完码,过来一个大爷说,这台机器的显示屏坏了,但是不影响使用,直接按钮就可以了。显示屏到时无所谓,能用就完了。洗到一半,隔壁车位来了一辆开奔驰的小姐姐。

竟然也是直接一个人洗车~~

苟延残喘

作者obaby
2026年4月10日 15:23

经历一轮一轮的裁员,这两年差不多每最长半年裁一次。研发人员的规模也终于裁到了原来的1/3,整天嚷嚷着使用ai提效,其实我觉得,按照现在的趋势和他们的逻辑,研发完全裁掉,就剩下几个领导,一个人养上20只龙虾,这就足够了,让龙虾24小时工作。

没到这个时候,走了不见得不好,留下来也不见得好。做得乱七八糟的项目,日常维护和新系统的开发都是问题,人少了,活多了。我总觉得过了长江就没个正常的所谓互联网公司,尤其是山东这个地界,的确是垃圾。在一轮轮的淘汰中,苟延残喘到了现在。一种用的那台破电脑也苟延残喘到了现在,每天都在提示磁盘空间不足,想办法清理一点之后,第二天继续提示,如噩梦一般挥之不去。

终于昨天实在受不了,重装了系统。

这256的硬盘,的确是小了点。

装完系统,安装价格必须的工具,就差不多占用了一半的磁盘空间。之前还给硬盘分了两个分区,现在看来,分不分的也没啥大用,就这点片空间,也不够干啥的。能往移动硬盘放的,就放移动硬盘把。现在常用的工具比之前也少了很多,只需要一个cursor、hbuilder 、xcode 之类的东西就够了,剩下的东西暂时也不需要安装,等哪天用到了再说吧。

从年前开始折腾,到现在又好几个月了,想着做点自己的事情,却一直没能抽出什么时间,google play就这么拖着,拖着。华为应用商店,商户号卡住了,也没什么进展,找技术支持也没解决,后续更是不知道如何处理,准备上个阉割版。不过最近折腾几个月,把三星应用商店给上了,也算是有那么一丢丢的进步。

https://apps.galaxyappstore.com/detail/ma.dayi.app?ads=ddb0e6f9&directOpen=true&nonOrgType=fce692ba&source=GBadge_01_8594313_tag

这几天连续折腾下来,也有点上火,对象牙疼了一个星期,现在感觉自己也开始牙疼了,昨天看了以下牙龈肿了。听他们说,这一轮流感病毒是专门让人牙疼的,这就让人有些抑郁了。牙疼一周,总是有些让人伤心。

至于这一波能再苟多久,谁也不知道。以后的事以后再说吧。

四月天

作者obaby
2026年4月7日 13:55

清明节假期还是如约而至了,跟着一起来的还有临近下班的时候收到的一条竞岗通知,让假期最后一天十二点之前提交竞岗申请表。

下班收到这条通知,我并不想现在去填那个申请表,还要领导签字之后上交。由他去吧,到家之后看到手机又有一些消息,打开大概浏览了一下,意思是,如果无法提交纸质版,或者领导无法签字,可以先提交电子版。跟对象提及此事,她说,『该交就交吧。该走的流程还是要走的,如果视在不行,那就拿补偿走人,也挺好的。现在我觉得,你能不能继续干下去都挺好的,能干就干,不能干就走。』稍微顿了以下,继续说:『找时间咱们去看看把公积金提出来吧,我同事都提了好多次了。不过咱们的契税单子没了,不知道能不能提。』

『嗐,担心那个干嘛,直接用手机申请下不就知道了』我一边说,一边去拿手机。支付宝打开公积金小程序,一堆查询走下去,并且有什么异常提示。尝试直接提取,理由选择偿还商业贷款。一步步操作,到最后验证贷款的时候,选择贷款银行,最后竟然只需要一个贷款时间和贷款金额就能查询到贷款信息了,这一点做得的确不错。选择金额之后,点击提交申请,没有提示需要提交任何资料。提交完了才发现,忘了选择银行卡了。竟然填写的是多年以前的交通银行的银行卡。

对象担心银行卡还能不能用,索性直接登录手机银行,发现申请提现的金额已经到账了。现在该想一下怎么处理这笔钱了,第一步想着再去存个定期。然而,前段时间存的一张定期的单子,五年年利率只有1.75。打开兴业银行的贷款明细,看了下贷款利率石3.2。 这还存什么定期,干脆还款得了。

从兴业银行的手机银行再申请提前还款,于是这一笔钱就在手里打个转,过几天就又成了别人的了。看了下贷款信息,70万,还了十年,一共出去了30万,实际剩余的贷款还剩50万。相当于交了10万利息。不过反过来想,这十年租房子十万也不够,两室一厅的房子,十年房租下来也得二十多万了。这么一想,还是得感谢对象的眼光,房子买的早,想尽办法借钱买了这套房子,也得感谢自己不是犟种,觉得租房子也可,没坚持租房子。

至于假期,其实也没什么好的打算,还是带宝子回老家。四月天,正好是在户外放飞的时候。

晚上教练还问,第一天要不要上网球课。刚开始想着可以下课之后再走,晚上八点多开始下雨,十一点多的时候雨逐渐变大,路上也慢慢有了积水,既然如此,那室外的网球场第二天可能也没法打了,不如干脆请假。对象最近牙疼,假期也就不跟着回了,找时间去查一下看看怎么处理。

回老家的路上,前一段还算是比较顺利,绕行机场高速,绕过了最堵的市区高速。然而,等往青银转的时候,提示拥堵距离五公里,磨蹭到匝道入口才发现,车流量实在是太大了,只有一个车道,所有的车不得不慢慢悠悠的往里蹭。高速路况除了这一段,剩下的基本倒是顺畅,下了高速之后,开始另一段拥堵。高速工作人员指挥右转车辆走应急车道。左转的两个车道就只能等交警指挥放行了。

远远的就能看到省道上密密麻麻的车,下高速之后虽然之后十几公里的路程,却开了接近五十分钟,这还是最后到镇上之后抄小道绕过了一部分拥堵路段。

到家之后,宝子的姐姐躲在屋里的帐篷里。就是在室内又搭了一个帐篷,藏在里面。早上走的匆忙,也没买什么东西,让宝子给老太太一个红包,这件事算是过去了。在回来之前还给宝子的姐姐定了一份外卖,拉丝芝士棒,说想吃这个。六个芝士棒拿出来之后,实际他就吃了一个。剩下的几个到了中午才被其他人吃掉。

虽然晚上还在下雨,但是假期第一天的天气还算不错,虽然气温低了点。中午收拾好东西,去上坟。山路边的地里,已经又开始种满了杨树苗,几年前禁止耕地种树的决定,现在看来应该是又被废弃了。现在杨树的价格,却一言难尽,很多租地种树的甚至连租地的钱都挣不出来。尽管如此,还是有大面积的耕地被种满了树苗,好处是不用怎么管理,稍微去外面干点活,总是比种那点粮食收入能好很多。偶尔在破败的院落边上能看到一树桃花,娇艳欲滴。

下午孩子们在玩的时候,突然记起来去年买的那条绳子和滑轮。年前的时候在院子里玩过几次,受限于场地只能拴在门框上,另外一头拴在了墙上。现在孩子们比去年肿了,尼龙绳子又有一定的弹力,稍微一拉伸可能就拖到地上了。想着去户外的树林子重新搭一套滑道,试了几棵树都不大行。这时候姐姐提议用邻居宅基地里面的那几棵树,刚好一头比较高,另外一头比较低。

搬梯子拴上去,试了以下,刚好。

几个孩子就这么在这个简易滑索上玩了大半个下午,剩下的时间爬门楼的平台,通过那个手工捆绑的梯子,爬上来,爬下去。有时候还要带着猫咪一起爬。

坐在月台上,猫咪和小狗就在身边嬉闹。

不过并不是总是那么和谐,有时候狗子也会直接张大嘴咬猫咪的脑袋,这时候猫咪就只剩下望风而逃了。

在家的日子过的也快,转眼一下午的时间就没了。晚上宝子跟她姐姐挤在那个帐篷里睡了一晚上,虽然地方小,但是睡得挺好,第二天早上九点多过去看的时候,还没起。等起床洗刷完依然过了十点,连早饭都省了。

中午包水饺,宝子跟她姐姐一起上阵,包的饺子挺好的,有模有样,这时候二姐说到:『你想想办法,把抽屉的锁给弄开吧,钥匙丢了,已经半年多没开了。』

这个锁其实已经换过一次了,上次也是钥匙丢了。用钢锯条锯开之后,换了一把新的,这次,自然也是同样的方法。出门骑电动车到镇上五金店,买了五根锯条,一把锁,一共花了七块五。老板对于我怎么锯开写字台的锁表示很好奇,我解答说:『就那么直接把锯条伸进去锯就行了。』我说完,他依然一脸不可置信。

到家,带上一副厚手套,大约五分钟,在崩了三根锯条之后终于成功了。

拆掉旧的,装上新的。

不过,这次买的锁头稍微小了一点,周边留出很多缝隙。也无所谓了,能用就行。给老太太留下一把钥匙,另外一把钥匙找地方放了起来。以防哪天钥匙又丢了。

下午吃完饭,宝子们又嚷嚷着要爬梯子。但是鉴于之前扣车上苹果模型的熊孩子还没走,自己就把梯子给撤了。然而,过了不一会儿,宝子跑进来说,滑索坏掉了,拖到地上了。用屁股想也知道,肯定是那个熊孩子上去了,目测近一百斤的体重,那一根尼龙绳子怎么能提供那么大的张力。绳子已经被全部拉了下来,关键是还怕熊孩子玩的时候万一受伤,说都说不清楚,只好把滑索给拆掉了。

下午跟姐姐带着宝子们去外面溜达,小狗也一直跟着,一会儿跑的无影无踪了,不知道什么时候又跑了回来,乐此不疲。路边开满了野花,孩子们也去折了一些。

田里也有些许忙碌的身影,在整理田地。有的在浇麦子,一个熊孩子在低头跑来跑去,看着我们过去,前面有个小狗。熊孩子拾起一块石头开始去追狗子,朝着狗子扔了过去。好在没打中狗子,狗子跑回来了。

刚开始狗子并没发怒,看熊子过来,开始围着自己转圈跑,熊孩子就在后面追,追了一会儿熊孩子看追不上,捡起石头来继续扔狗子。这时候狗子明显怒了,停下来朝着熊孩子龇牙咧嘴,眼看如果熊孩子敢再扔的话,狗子就扑上去了。我只好喝退狗子,把熊孩子也训了一顿,让他赶紧走远点。

回去的时候,也不想再见到那个熊孩子,就直接带着他们下到了沟里,顺便弄了几根杨树条给他们扭了一个哨子。

村里但凡能种树的地方,都种满了杨树。自从没人种地之后,原本经常走的一些小路也就没了踪迹,只能沿着沟底前进。

原本在路上看到几株野果的乔木,想扒出来带回家种下去的,因为没走回头路也未能如愿。现在都开花了,可能哪怕带回家了也不容易成活吧。

夜晚总是如期而至,从来都不会迟到。吃完晚饭也就该回县城了,天黑之后,路况反而没那么拥堵了。

刚开始以为是车贴的膜太黑了,右侧总是看不清楚。路上别到一辆大本,过了一会儿,从右侧超了上来,打开窗户,超我一通比划,可能还有问候吧。不过我没开窗户,一句都没听到。大哥笔画半天之后,超到了自己前面,既然是自己做得不对。那就认怂认骂,老老实实的跟在后面。等到了一个右侧的岔路口,大哥先打了个右转向,又开了双闪。还以为这无牌大哥要停车跟自己干架呢,不过自己超过去之后,对方也没什么反应,应该是对方到了目的地了。停车之后,才发现右侧车床应该是自己用湿巾擦玻璃上的鸟屎的时候,没擦干净,反而抹的那一块更加不清楚了。

把身上的衣服换下来,全部扔到洗衣机,让宝子去洗澡。衣服上占满了猫毛,狗毛,粘了半天也没粘干净,最后直接扔洗衣机给洗了。而至于鞋子,只能等回家之后再洗了。洗衣店的会员卡,基本都用来洗鞋了,价格也挺合适的9.9一双。

最后一天,八点多宝子还没醒。过去把她叫醒,洗刷吃饭,开始往回赶,毕竟作业没写完,下午还有网球课。两天疯玩,体力消耗也蛮厉害的。只是玩的时候从来都不会觉得累吧。

有时候真的羡慕这样的童年,有陪自己一起折腾的父母,也有长时间的陪伴。只是,现在,还是得为了工作绞尽脑汁,甚至有可能哪一天依然需要背井离乡。

人间四月天,总是生机勃勃,至于明天不确定的事情,明天再说吧。

Baby Anti-Spam 自建反垃圾评论系统

作者obaby
2026年4月6日 18:05

很久之前,就经常收到akismet的授权提醒,对应一个错误码10010。

刚开始还以为是多域名访问导致的授权校验出问题了。后来换了n个key,同时添加了插件hook掉所有的垃圾评论检测逻辑,让全部走统一的域名,结果前几天又收到这个提醒了。

插件代码:

<?php
/**
 * Plugin Name: Akismet 单一主域名(多域名站点)
 * Description: 当站点配置了多个域名时,强制发往 Akismet 的请求只使用一个主域名,避免被计为多站点触发 10010。
 * Version: 1.0
 * Author: obaby
 *
 * 使用:在下方设置 AKISMET_CANONICAL_HOME 为主域名(或留空则用 WordPress「设置」里的站点地址)。
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * 主域名(规范 URL,不要末尾斜杠)。留空则使用 get_option( 'home' )。
 * 例如: https://www.example.com
 */
if ( ! defined( 'AKISMET_CANONICAL_HOME' ) ) {
    define( 'AKISMET_CANONICAL_HOME', 'https://zhongxiaojie.cn' );
}

/**
 * 获取发往 Akismet 时使用的唯一主域名 URL。
 */
function akismet_single_domain_get_canonical_home() {
    $home = AKISMET_CANONICAL_HOME;
    if ( $home === '' || $home === null ) {
        $home = get_option( 'home' );
    }
    return untrailingslashit( $home );
}

/**
 * 将任意 URL 替换为使用主域名的版本(只改 host,保留 path/query)。
 */
function akismet_single_domain_normalize_url( $url, $canonical_home ) {
    if ( empty( $url ) || ! is_string( $url ) ) {
        return $url;
    }
    $parsed = wp_parse_url( $url );
    $canon  = wp_parse_url( $canonical_home );
    if ( empty( $canon['scheme'] ) || empty( $canon['host'] ) ) {
        return $url;
    }
    $scheme = isset( $parsed['scheme'] ) ? $parsed['scheme'] : $canon['scheme'];
    $host   = $canon['host'];
    $path   = isset( $parsed['path'] ) ? $parsed['path'] : '/';
    $query  = isset( $parsed['query'] ) ? '?' . $parsed['query'] : '';
    $frag   = isset( $parsed['fragment'] ) ? '#' . $parsed['fragment'] : '';
    return $scheme . '://' . $host . $path . $query . $frag;
}

/**
 * 统一 verify-key / get-subscription / get-stats 的 blog 为主域名。
 */
add_filter( 'akismet_request_args', function ( $request_args, $path ) {
    $paths = array( 'verify-key', 'get-subscription', 'get-stats' );
    if ( ! in_array( $path, $paths, true ) ) {
        return $request_args;
    }
    $canon = akismet_single_domain_get_canonical_home();
    if ( ! empty( $request_args['blog'] ) ) {
        $request_args['blog'] = $canon;
    }
    return $request_args;
}, 10, 2 );

/**
 * 统一 comment-check(以及 recheck)的 blog、permalink,并把请求里的 HTTP_HOST 等改为主域名。
 */
add_filter( 'akismet_request_args', function ( $request_args, $path ) {
    if ( $path !== 'comment-check' ) {
        return $request_args;
    }
    $canon = akismet_single_domain_get_canonical_home();
    $parsed = wp_parse_url( $canon );
    if ( empty( $parsed['host'] ) ) {
        return $request_args;
    }
    $canon_host = $parsed['host'];

    $request_args['blog'] = $canon;
    if ( ! empty( $request_args['permalink'] ) ) {
        $request_args['permalink'] = akismet_single_domain_normalize_url( $request_args['permalink'], $canon );
    }

    // 让服务端看到的“当前请求”也统一为主域名,减少被计为多站点
    if ( isset( $request_args['HTTP_HOST'] ) ) {
        $request_args['HTTP_HOST'] = $canon_host;
    }
    if ( isset( $request_args['REQUEST_URI'] ) ) {
        $uri = $request_args['REQUEST_URI'];
        $request_args['REQUEST_URI'] = ( is_string( $uri ) && ( $p = wp_parse_url( $uri, PHP_URL_PATH ) ) !== null ) ? $p : '/';
    }
    if ( isset( $request_args['DOCUMENT_URI'] ) ) {
        $uri = $request_args['DOCUMENT_URI'];
        $request_args['DOCUMENT_URI'] = ( is_string( $uri ) && ( $p = wp_parse_url( $uri, PHP_URL_PATH ) ) !== null ) ? $p : '/';
    }
    return $request_args;
}, 10, 2 );

/**
 * 统一 submit-spam / submit-ham 的 blog、permalink。
 */
add_filter( 'akismet_request_args', function ( $request_args, $path ) {
    if ( ! in_array( $path, array( 'submit-spam', 'submit-ham' ), true ) ) {
        return $request_args;
    }
    $canon = akismet_single_domain_get_canonical_home();
    $request_args['blog'] = $canon;
    if ( ! empty( $request_args['permalink'] ) ) {
        $request_args['permalink'] = akismet_single_domain_normalize_url( $request_args['permalink'], $canon );
    }
    return $request_args;
}, 10, 2 );

这次授权的密钥撑得时间稍微长了点,但是最终还是收到了这个提醒,意思是需要订购商业版授权。我这个人站点为了发垃圾评论订购一个商业版授权,确实有些难以接受。

于是,我决定自建反垃圾评论系统,基于scikit-learn实现了现在的这套垃圾评论检测系统,训练数据一部分来源于github的开源数据,另外一个就是我自己博客的评论数据。为了保证样本正例和负例数量差别不至于过大,经过各种方式进行了多轮数据清洗。

如果想要评论识别更加准确,可以提供自己的博客评论数据,如果能提供垃圾评论更好。现在欠缺的主要是垃圾评论数据,正常的评论数据我已经提供几千条数据。

效果测试:

测试地址:https://anti-spam.zhongxiaojie.cn/test/spam

简介:

面向 中英混合 评论的 WordPress 垃圾识别方案:PHP 插件在评论入库前调用 本机 Python 服务,由小型多语种向量模型 + 分类器(或演示用规则)给出垃圾概率。

适合评论量不大、单机部署(例如 4 核 / 8GB RAM 的 Ubuntu),服务与 WordPress 同机时使用 127.0.0.1 即可。

目录结构:

baby_anti_spam/
├── README.md
├── screenshots/             # 文档:服务启动与 curl 自测示意
│   ├── service.png
│   └── test.png
├── service/                 # Python FastAPI 侧车服务
│   ├── .env.example
│   ├── requirements.txt
│   ├── requirements-ml.txt
│   ├── run.py
│   ├── app/
│   │   └── stats_backends/   # 统计存储:sqlite / mysql
│   └── scripts/
│       ├── init_stats_mysql.sql
│       └── init_stats_mysql.py
│       ├── train_sklearn.py
│       ├── download_embedding_model.py
│       └── download_embedding_model.sh
└── wordpress/baby-anti-spam/
    └── baby-anti-spam.php # WordPress 插件

关键配置:

| 变量 | 说明 |
|------|------|
| `SPAM_HOST` | 监听地址,同机建议 `127.0.0.1` |
| `SPAM_PORT` | 端口,默认 `8765` |
| `SPAM_API_SECRET` | **单密钥模式(兼容旧版)**:未配置 `SPAM_API_KEYS` 且未配置 `SPAM_API_KEYS_FILE` 时,仅此密钥有效,等价于 name=`default`、不限流(`max_rpm=0`)。与 WP 插件里填写的密钥一致 |
| `SPAM_API_KEYS` | **多密钥**:JSON 数组。每项为 `name`(唯一,用于统计与限流分组)、`key` 或 `secret`(与请求头一致)、`max_rpm` 或 `rpm`(每分钟最大请求数,`0` 表示不限制)。与 `SPAM_API_KEYS_FILE` 合并时:**先读文件条目,再追加本变量** |
| `SPAM_API_KEYS_FILE` | 可选,指向 JSON 文件,根节点为与上表相同结构的**数组**。文件必须存在,否则进程启动失败 |
| `SPAM_MODEL_PATH` | 训练得到的 `*.joblib` 路径;留空则取决于 `SPAM_FALLBACK_RULES` |
| `SPAM_FALLBACK_RULES` | 无模型文件时是否启用内置极简规则(演示用);生产训练后应设为 `false` 并配置 `SPAM_MODEL_PATH` |
| `SPAM_LABEL_THRESHOLD` | 可选,默认 `0.8`。`spam_score` ≥ 此值时 JSON 中 `label` 为 `spam`,否则为 `normal` |
| `SPAM_DFA_ENABLED` | 默认 `true`。为 `true` 时使用 `dfa-python-filter/keywords` 做敏感词检测;命中则直接 `spam_score=1`、`detail=dfa_sensitive`(早于 sklearn) |
| `SPAM_DFA_KEYWORDS_PATH` | 可选,自定义敏感词文件路径;留空则用 `service/dfa-python-filter/keywords` |
| `SPAM_NON_CHINESE_FLOOR_ENABLED` | 默认 `true`。为 `true` 时若合并后的 author/email/url/text 中**无任何 CJK 表意字符**(主要针对中文训练语料),则将 `spam_score` **至少**抬到 `SPAM_NON_CHINESE_SPAM_FLOOR` |
| `SPAM_NON_CHINESE_SPAM_FLOOR` | 默认 `0.9`。与上项配合,在「无中文」评论上与 sklearn / 规则分取 `max` |
| `SPAM_STATS_ENABLED` | 默认 `true`。为 `true` 时记录每次**成功**返回的 `/v1/classify` 请求与响应(失败 / 401 不落库),并允许 `/v1/mark-spam` 写入 `spam_marks` 表 |
| `SPAM_STATS_BACKEND` | `sqlite`(默认)或 `mysql`。选 `mysql` 时需安装 `pymysql`(已在 `requirements.txt`)并配置下方 MySQL 变量 |
| `SPAM_STATS_DB_PATH` | 仅 `sqlite`:数据库文件路径;留空则为 `service/data/stats.sqlite`(已加入 `.gitignore`) |
| `SPAM_STATS_MYSQL_HOST` / `SPAM_STATS_MYSQL_PORT` | 仅 `mysql`:默认 `127.0.0.1` / `3306` |
| `SPAM_STATS_MYSQL_USER` / `SPAM_STATS_MYSQL_PASSWORD` | 仅 `mysql`:连接账号(`user` 必填) |
| `SPAM_STATS_MYSQL_DATABASE` | 仅 `mysql`:库名(必填),默认示例 `baby_spam_stats` |
| `SPAM_STATS_MYSQL_CHARSET` | 仅 `mysql`:默认 `utf8mb4` |

 

系统服务启动截图:

wp插件配置:

项目地址:https://anti-spam.zhongxiaojie.cn

代码地址:https://cnb.cool/oba.by/baby-wp-anti-spam

说明:如果自己不想训练数据,下载发布版的spam_pipeline.joblib 放入指定目录下配置服务启动即可,baby-anti-spam.zip 为wp插件。

训练耗时大约11分钟:

下载微信公众号的视频

作者obaby
2026年4月2日 16:46

作为一个专业的程序媛,前端时间折腾龙虾转发公众号的文章到闺蜜圈wiki,之前已经处理了图片和文章的问题,今天转发的时候发现另外一个问题:文章里面的视频无法正常播放。

刚开始的时候想着直接去chrome的缓存里面找,但是试了下chrome://cache发现无效,又不想去找插件来干这件事情。直接去调试工具找对应的视频地址:

然而直接贴到地址栏,直接报403了。

唉,好尴尬,既然有本地缓存文件了。那么直接尝试将接收到的数据流写入到文件呗。找了半天没发现怎么直接把请求到的数据写入到文件,点击开始播放等待缓冲结束。

加载完了右下角的数据也就有了,直接切换成base64,复制粘贴:

然而,尝试decode 之后,播放不了,缺少mp4的头文件,这就挺奇怪的。文件头哪里去了?my_video为通过代码下载的mp4,video为通过base64 处理的图片。

文章测试地址:https://mp.weixin.qq.com/s/heoer_zm4SFwFKsk4tRecQ

看了下是video标签实现的:

<div data-v-c66e8e28="" class="js_inner inner not_fullscreen"><div data-v-c66e8e28="" class="js_video_poster video_poster"><div data-v-c66e8e28="" class="video_mask"></div><video data-v-c66e8e28="" src="https://mpvideo.qpic.cn/0bc3pidsgaahauamxiglsruvo6wden5aoiya.f10002.mp4?dis_k=247900efb8791f0718998ea0813793c9&amp;dis_t=1775118363&amp;play_scene=10120&amp;auth_info=d9/5u/dlYUBWn6qY0Sp2SXM9PUdEOj5CZmQ3H2k2TzNOXXtjTwYQen0+WTMXEzdWIDNuS0hkIHgTMSlENWAcfUpBcQ==&amp;auth_key=ed4a91866522f27b4b89c5e71e04d115&amp;vid=wxv_4453415887525888005&amp;format_id=10002&amp;support_redirect=0&amp;mmversion=false" poster="http://mmbiz.qpic.cn/sz_mmbiz_jpg/GAVxEAgJstytcf0uF3dpdZKia9G96C3loxCNaBrbFLHCiak3GvJDfASC7uYqNjjAZ5e2OHSmHoBQrONRJ8UIq6icJjjFXMfUBtdhy7VWlfb3MM/0?wx_fmt=jpeg&amp;wxfrom=16" webkit-playsinline="isiPhoneShowPlaysinline" playsinline="isiPhoneShowPlaysinline" preload="metadata" crossorigin="anonymous" controlslist="nodownload" class="" style="display: block; width: 655px; height: 492px;"> 您的浏览器不支持 video 标签 </video></div><div data-v-f4ee5450="" data-v-c66e8e28="" class="video_poster__info__play" style="display: none;"><i data-v-f4ee5450="" data-v-c66e8e28="" class=""></i></div><div data-v-f4ee5450="" data-v-c66e8e28="" class="video_poster__info" style="display: none;"><p data-v-f4ee5450="" data-v-c66e8e28="" class="video_poster__info__title" style="font-size: 17px;">继续观看</p><p data-v-f4ee5450="" data-v-c66e8e28="" class="video_poster__info__desc" style="font-size: 12px;"> 孤独症,就是不爱说话吗? </p></div><div data-v-f4ee5450="" data-v-c66e8e28="" class="video_poster__info__mask" style="width: 100%; display: none;"></div></div>

还是说着这个东西还有另外的处理逻辑?哪位大神知道原因还望不吝赐教。

既然decode不行,那就直接上代码吧:

#!/usr/bin/env python3
"""
下载 mpvideo.qpic.cn 等需 Referer 的 MP4(微信视频 CDN)。

Author: obaby
  https://zhongxiaojie.cn
  https://oba.by
"""

import argparse
import sys
import urllib.error
import urllib.request

# 与常见微信内嵌页一致,避免 403
DEFAULT_REFERER = "https://mp.weixin.qq.com/"
DEFAULT_UA = (
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
    "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 "
    "MicroMessenger/7.0.20"
)


def main() -> None:
    p = argparse.ArgumentParser(description="带 Referer 下载 mpvideo MP4")
    p.add_argument("url", help="完整 mp4 URL(含查询参数)")
    p.add_argument(
        "-o",
        "--output",
        default="downloaded.mp4",
        help="保存路径(默认 downloaded.mp4)",
    )
    p.add_argument("--referer", default=DEFAULT_REFERER, help="Referer 头")
    p.add_argument("--user-agent", default=DEFAULT_UA, help="User-Agent")
    args = p.parse_args()

    req = urllib.request.Request(
        args.url,
        headers={
            "User-Agent": args.user_agent,
            "Referer": args.referer,
        },
        method="GET",
    )
    try:
        with urllib.request.urlopen(req, timeout=120) as resp:
            data = resp.read()
    except urllib.error.HTTPError as e:
        print(f"HTTP {e.code}: {e.reason}", file=sys.stderr)
        sys.exit(1)

    out = open(args.output, "wb") if args.output != "-" else sys.stdout.buffer
    try:
        out.write(data)
    finally:
        if out is not sys.stdout.buffer:
            out.close()
            print(f"已写入 {args.output},{len(data)} 字节")
            if len(data) >= 8 and data[4:8] == b"ftyp":
                print("魔数检测:疑似标准 MP4(含 ftyp)")


if __name__ == "__main__":
    main()

现在就可以下载之后,上传了,发布的文章地址:

孤独症,就是不爱说话吗?

💾

弱弱的问一下,我的网站怎么被镜像了嗫?

作者obaby
2026年4月1日 11:18

其实网站被镜像这件事情,本身没什么稀奇的,如果想搭建一个镜像网站,从零开始也不过个吧小时的时间。

之所以写这个东西,是因为最近有看到好几个人被镜像的,这一个(爱娃子),还有 这一个(我是军爸)。

不过,既然还有人有疑惑,那就简单的教一下大家怎么来镜像个网站吧。

为此,我创建了一个开源项目:

OpenResty + OpenCC 反向代理简繁转换


基于 OpenResty 反向代理上游站点,对 HTML 正文 做 OpenCC 简繁转换(默认:简体 → 繁体,配置文件为 s2t.json)。适合在不改源站的情况下,为访客提供另一种字体习惯版本。

功能概览

能力 说明
反向代理 HTTPS 回源(示例站点:zhongxiaojie.cn),客户端走本机证书与域名。
HTML 简繁转换 仅当 Content-Type 含 text/html 时对整页做 OpenCC UTF-8 转换。
gzip 解压 通过 Lua zlib 尝试解压响应体(与去掉 Content-Encoding 的配合视上游行为而定)。
链接与图片 URL 保护 转换前将 href / src / poster / data-src / srcset 及裸 http(s):// 链接替换为占位符,转换后还原,避免路径或查询串中的汉字被改写导致 404
IPv4 优先解析 resolver … ipv6=off + 变量 proxy_pass,减轻云主机无 IPv6 时对 AAAA 连接失败的问题。
静态资源直过 图片、CSS、JS、字体等扩展名单独 location不做 OpenCC,减轻负担、避免误伤二进制。
动态库加载 对 libopencc.so 按常见路径依次尝试 ffi.load,降低找不到共享库的概率。

限制与说明

  • JSON / JS / CSS 内嵌字符串若不在上述保护规则内,仍可能被转换;重要数据建议不要用全文 HTML OpenCC 硬转。
  • 内联样式 style="background:url(...)" 未单独做保护,若遇少数破图可再扩展规则。
  • 转换配置在 nginx/opencc/opencc-filter.lua 中的 OPENCC_CONFIG(默认 /usr/share/opencc/s2t.json);若需 繁体 → 简体 可改为 t2s.json 等(需系统已安装对应 OpenCC 数据文件)。

部署要求

  • OpenResty(带 lua-nginx-module)。
  • OpenCC 运行时:系统安装 libopencc.so 与词典数据(如 /usr/share/opencc/*.json),并保证 worker 进程能加载到 .so(见下文「共享库」)。
  • Lua 可 require('zlib') 的模块(用于 zlib.inflate,若无 gzip 体则 pcall 失败会跳过解压,不影响后续逻辑)。
  • 上游为 HTTPS 时,本机需能解析并访问该域名(已用 resolver 时 VARIABLE 形式 proxy_pass 才会走指定 resolver)。

部署步骤

1. 安装 OpenCC 与数据文件

以 Debian / Ubuntu 为例(包名因发行版略有差异):

sudo apt update 
sudo apt install -y libopencc1.1 opencc # 或 libopencc2 等,以仓库为准 
或者手工复制 lib64目录下的文件到 脚本对应的路径就是这个 /usr/lib64

 

确认存在词典,例如:

ls /usr/share/opencc/s2t.json

 

2. 确保能找到 libopencc.so

若日志出现 libopencc.so: cannot open shared object file

  • 将库放在系统默认搜索路径,例如 Ubuntu amd64:
  • ldconfig -p | grep opencc

     

  • 若库仅在 /usr/lib64 等非默认路径,可执行(与仓库 fix.md 一致):
  • echo '/usr/lib64' | sudo tee /etc/ld.so.conf.d/usr-lib64.conf sudo ldconfig

     

  • 或在 OpenResty 的 systemd 单元 中设置 Environment="LD_LIBRARY_PATH=/usr/lib64:/usr/local/lib"  后重启。

脚本内已对多路径做了 ffi.load 尝试;仍失败时请对照 ldd 与 opencc 包实际安装位置排查。

3. 部署 Lua 脚本

将 nginx/opencc/opencc-filter.lua 复制到服务端约定路径(与 nginx 配置一致),例如:

sudo mkdir -p /usr/local/openresty/lua 
sudo cp nginx/opencc/opencc-filter.lua /usr/local/openresty/lua/opencc-filter.lua

按需修改脚本顶部 OPENCC_CONFIG 指向本机实际的 JSON 配置。

4. 合并 Nginx / OpenResty 配置

  • 将 zero.zhongxiaojie.cn.conf 中的 server 块纳入主配置(include 或粘贴到 nginx.conf 的 http {} 下)。
  • 修改 证书路径日志路径上游域名 zhongxiaojie.cn、以及 body_filter_by_lua_file 的路径,使其与当前环境一致。
  • header_filter_by_lua 中去除 Content-Encoding,便于对明文 HTML 做处理;若上游与解压逻辑不匹配,需自行观察是否需要调整。

5. 校验并重载

sudo /usr/local/openresty/nginx/sbin/nginx -t 
sudo /usr/local/openresty/nginx/sbin/nginx -s reload 
# 或 systemctl reload openresty

 

6. 验证

  • 浏览器访问你的站点,查看页面简繁是否符合预期。
  • 检查 图片与站内链接是否正常(尤其含中文或 % 编码的路径)。
  • error.log 中不应再出现 OpenCC 库加载失败或大量 IPv6 unreachable(在无 IPv6 环境)。

配置项速查

项目 位置
OpenCC 配置 JSON opencc-filter.lua → OPENCC_CONFIG
Lua 脚本路径 zero.zhongxiaojie.cn.conf → body_filter_by_lua_file
上游站点 set $upstream_host … 与 proxy_pass https://$upstream_host$request_uri
DNS / 仅 IPv4 resolver 223.5.5.5 8.8.8.8 valid=300s ipv6=off
不参与转换的静态文件 `location ~* .(gif

故障排查

现象 可能原因
libopencc.so 找不到 未安装包、ldconfig 未包含库目录,或需 LD_LIBRARY_PATH
body_filter 报错、栈指向 ffi.load 同上;或架构不一致(如 32/64 位混用)
上游连接 IPv6 失败 已用 ipv6=off + 变量 proxy_pass;仍失败则检查防火墙与 DNS
图片 404 历史上多为 OpenCC 改了 URL 内汉字;当前脚本对常见属性已做保护,若仍有个别,检查是否来自 CSS url() 或 JS 动态拼接

如需改为其他域名、证书路径或 t2s 转换方向,只需改配置文件与 OPENCC_CONFIG,无需改 OpenResty 核心。

实际效果:

开源项目地址:https://gitee.com/obaby/baby-website-mirroring-tool

参考链接:https://blog.csdn.net/wzj_110/article/details/127758020

https://blog.rexskz.info/support-traditional-chinese-using-openresty-and-opencc.html

局部有雨

作者obaby
2026年3月30日 11:00

春天到了,又到了万物复苏的季节。小草也从土里钻出了头,露出了点点的绿色。树上的花也开始绽放,虽然没有绿叶的衬托,倒是也别有一番韵味。

每个周末,都大同小异。跟上班一样,也没有什么特别的,与渐渐生机勃勃的春天比起来,似乎有些过于平淡了。每周依然是带着宝子上课,上课,剩下偶尔有那么一点时间,也不能走的太远,只能周边小范围的溜达溜达。

宝子现在上课不太需要自己去帮忙了,至少能隔网之后,不用自己跟着去抛球了。这样就有点时间可以继续跑步了,围着网球场一圈一圈的跑。

不过相比操场的400米跑道,这一圈一百多米跑起来感觉更累,感觉跟拉磨的驴一样。

周日上午的网球课推迟到了十一点,早上早点起来,宝子嚷嚷着去公园,我嚷嚷着去轮渡。当然,公园是上午去,轮渡是下午去。对象再次征求宝子的意见,得到的答复是两个都去。

急忙吃完东西,开车去公园。上车之后发现前挡风玻璃上面有点雨点,想着是不是要下雨,跟宝子说,下雨了可能。她表示怀疑,没感觉到雨点啊。不过既然没感觉到,那就去公园吧,一路上虽然天依然阴沉,刚停好车,拉开车门的瞬间,一阵大雨落了下来,赶忙重新钻进车里。前后不到五秒中的时间,就让这场公园之旅化为了泡影。

回家之后,宝子在家换上轮滑鞋,来回溜达。想着,既然下雨了,应该网球课也停了吧,然而等到十点半依然没消息。既然如此,那可能市北没有下雨吧。一路上天变得越来越晴朗,到了学校之后依然是一篇艳阳天。

下课去学校餐厅吃点东西,下午就可以去轮渡了。

虽然是中午的饭店,想找个空位置还是蛮方便的,买了两碗麻辣烫,没有小碗。去隔壁的卤肉饭要了个小碗。餐厅门口从外面能感受到吹进来的真真的凉风。吃完饭,到了室外反而变得更加的温暖,与餐厅的温度完全不同。

一路小道辗转到环湾大道,路况还是比较畅通的,半个小时就到了轮渡停车场。怕找不到停车位,在入口找了个空塞了进入。往里走,大约100米发现内部竟然有一个大的停车场,并且还有大量的空位。

候船厅入口,写了一些方言的标语。

虽然购票的时候显示有场次,但是实际买的时候,就是看人数,人够了就发船。感觉到了县城做镇上的客车的感觉,流水车,流水船。检票的时候会给一个油条,这个油条并不是给游客吃的,是给海鸥吃的。

这个码头,在海底隧道和跨海大桥开通之后就已经停了好几年,这两年才又重新开放,用来做海上观光。成人票两个人90,宝子2块,价格还是蛮合适的,海上50分钟的观光,说可以看到跨海大桥。

检票上船,刚找地方坐下,就有工作人员开始喊,大家可以去喂海鸥了。喂海鸥只能在一楼,二楼是观光区域,油条投喂完之后可以上二楼。带着宝子来到船尾,大家都在那里观望,也不知道在等什么,我扔了一块油条出去之后,马山就有无数的海鸥飞过来开始争抢。大家也跟着开始往海里投喂。

发船之后,海鸥依然跟着游船,甚至能感受到海鸥翅膀煽动的时候,甩出来的水滴。

还有跟着游船一直来回盘旋,不断的争抢从游客手里抛出的油条。

当然啦,如果足够大胆,也可以直接用手拿着让海鸥去吃。

不过,这天气稍微微差点了,大约半小时不到,就开始掉头返航了。说好的看跨海大桥呢?海面的能见度并不算高。只能隐约看到一个轮廓,远处的货轮也一样,飘渺。

回港之后,依然能看到很多人在等着检票。如果五点多应该能看到海上的日落,很多人也在等那个最好的时间。

海上的冷风吹来,单穿一条牛仔裤还是冷了点。

好在没有因为家里的一场雨而不出门,毕竟其他的地方是一片艳阳天,不过局部有雨。

m3u8 downloader v26.03.28

作者obaby
2026年3月29日 21:58

基于 ffmpeg 的 m3u8 / 归档页解析下载工具,支持单链接、批量 CSV/文本、自定义输出目录与 ffmpeg 路径。

参数 说明
-i 输入:直链 m3u8、含 archives 的归档详情页、或带 cms_player 的播放页;也支持 .mp4 / .avi / .mov / .mpeg 直链(走 HTTP 分段下载,非 ffmpeg)
-o 输出文件名(自动补 .mp4);对部分模式用于覆盖默认标题名
-p 输出目录;可为本机路径或 UNC(如 \\服务器\共享\目录
-f 批量输入文件:.csv 或纯文本(每行一个链接)
-m 指定 ffmpeg 可执行文件路径

注意: 必须提供 -i 或 -f 之一。

单条示例

python m3u8_downloader.py -i "https://example.com/video.m3u8?token=xxx" -o myvideo -p D:\Videos

 

批量 CSV

 

  • 编码建议 UTF-8(含 BOM 亦可),表头需包含列 link;可选列 name(用于在部分逻辑里拼接输出名后缀,空单元格按空字符串处理,不会出现 nan 文件名)。
  • 会跳过空的 link 或内容为 link 的占位行。
  • 按行 顺序执行:上一任务结束(含 ffmpeg)后才会处理下一行。
python m3u8_downloader.py -f list.csv -p "\\192.168.1.12\media\Videos"

 

纯文本列表

 

每行一个 URL,行为与逐次 -i 类似;可通过 -o 传入统一输出名(视链接类型而定)。

功能说明

 

链接类型与行为

 

  1. .m3u8 直链
    使用 ffmpeg 拉流并 remux 为 .mp4-c copy)。
  2. URL 中含 archives(归档站 / bl05 类页面)
    请求页面,解析多个 div.dplayer 的 data-config,得到多路 m3u8;按路依次下载,文件名一般为 页面标题 + 序号,并经 safe_mp4_filename 净化。
  3. 其它播放页(非 archives)
    解析 var cms_player = {...} 的 JSON,取 url 作为 m3u8,再走 ffmpeg。
  4. .mp4 等直链
    使用 requests 分段下载(file_download.download_from_url),带 tqdm 进度条,不经过 ffmpeg

页面编码

 

抓取 HTML 时依次尝试 UTF-8 → UTF-8-sig → gb18030,减轻标题乱码。

输出文件名

 

  • 去除 Windows 非法字符,过长截断并可带 crc 后缀兜底。
  • 对「UTF-8 被误当成 latin-1」类乱码标题做启发式纠正(日志中可能出现 [F] 标题疑似 UTF-8/latin-1 乱码,已尝试纠正)。

覆盖策略

 

  • 若目标 .mp4 已存在os.path.isfile),跳过该次下载。
  • 调用 ffmpeg 时带 -n:不在终端交互询问覆盖;若因路径编码等导致检测不一致,ffmpeg 侧也会拒绝覆盖而非静默覆盖。

本地 m3u8 文件

 

-f 指向 .m3u8 / .m3u 时,当前代码分支为占位(pass),尚未实现。

目录说明

 

路径(相对程序目录) 用途
bin/ffmpeg.exe Windows 打包/放置 ffmpeg 的常见位置
download/m3u8_files 内部与 make_dir 相关的子目录逻辑
download/mp4 未指定 -p 时的默认输出目录

下载地址:

https://www.123912.com/s/ucY7Vv-njQAA?pwd=HwGK#

简单的快乐

作者obaby
2026年3月27日 16:03

过年的时候买了两条牛仔裤,虽然是过年买的,但是有一条却并没怎么穿。主要是因为那是一条洞洞裤,穿洞洞裤里面穿的太厚了总是感觉有些奇怪。

洞洞裤最好的搭配可能就是薄裤袜或者光腿了,有时候总是看到什么各种短视频,见男朋友的最高礼仪-裤里丝。

不过可能更多男生喜欢的是黑丝吧。老妈看着自己的裤子,还以为是穿破了。用手指扣进去扣了一下,转头问我:『裤子坏了,你还不扔了?买不起裤子了吗?要不我给你缝一下?』

她总是说,你俩挣得也不少啊,买个东西扣扣搜搜的。多买几条裤子不行啊,别买那些几十块钱的鞋,太烂了。

有时候不得不承认,我的快乐就是来源于那些便宜的小玩意儿,哪怕穿几天坏了,扔了都不心疼。不过买东西的时候,宝子和她姥姥的眼光的确毒辣,给她们买衣服买鞋子,总是一眼就能相中那个最贵的。至于自己的日常穿搭,一百块钱的牛仔裤,500的鞋子,两百的衬衣,600的外套。内搭就不算了,这几本就是全部了,但是这些东西能穿好久,尤其是外套已经穿了好几年了。

有时候去逛街其实也不知道要买什么,就是纯粹瞎逛,基本也不会买什么衣服。等到换季的时候,偶尔买那么一两件。或者干脆从网上买,两百块钱买好几件,喜欢的留下,不喜欢的退回去。

周末带宝子去吃米线的时候看到的那家牛杂店,终于前天没忍住还是去了。看了一眼没地方停车,把车停到了对面充电停车场,于是在一片电车中间,混进了一辆纯油车。进入店里,虽然是午饭时间,店里只有两个大哥。

盯着菜单看了好久,才看到纯牛杂,小份35。

又要了一个肉夹馍,一瓶可乐,一共51块。等了半天,终于上了,不得不说,这小份真的不大的样子。刚开始害怕吃多了,影响自己减肥,后来才发现是自己想多了。

而至于味道,也没吃出小时候的味道。吃完出门给对象发消息说,『我去吃周末看到的那个店里的牛杂了,味道没有自己预想的那么好。』

发完消息,等红灯,过马路,这时候看到停车场的告示牌上写着:『中午11点-下午2点,充电高峰期禁止燃油车入内……』

这我往里进的时候自动放行了,也确实没注意,赶紧上车准备开走。这时候手机响了一声,拿起来看到一条微信消息:『那你以后还会再去吗?』

迟疑了一下,我回复:『不会去了,还不如我自己从二手东买处理好的,我自己煮。』

下午,从二手东买了之前看的牛杂,127三斤。

到了晚上依然是少吃,运动。白天走的少了,晚上就多跳几个,白天步数多的时候就可以少跳几个,目标就是凑够一万步。

跳习惯了之后,其实至于现在三千,五千,还是七千,感觉区别都不大,唯一的区别也就在于时长了。有时候跳完感觉还是有点紧绷的感觉。

偶尔也想能全身再按一下,上次按摩应该还是去年十月份左右吧。转眼快半年了,早上从高德上扒拉了半天,找到一个相对来说看着还算可以的。

最起码那个名字看起来还满顺眼的。

鉴于第一次去,没有选择太复杂的项目。不过也有不靠谱的地方,那个巨幕是个啥,确实没看到。刚开始趴在床上,技师按的挺舒服的,感觉都快睡着了。等开始按小腿的时候,一下就给按醒了,还是挺疼得。两个腿都是如此,聊了会儿,建议经常运动还是要多按一下。

为了按摩,中午吃饭的时间就没了。70分钟,甚至已经超了下午上班的点了。

喝点水,顺便看了下价目表,嗯,下次可以做个全身精油按摩,价格貌似跟之前经常去的那家店差不多。

按完还完衣服赶紧往公司赶,店外的停车场也挺让人崩溃的,一遍有台阶,整体过道也比较窄,好在车不多,来回倒腾十来次才从停车场开出来。

路上等红灯的时候,遇到一辆typeR,至于是不是真的,其实我也不大认识。后来着急从左侧超了过去,等上立交桥的时候发现那辆typeR紧贴在后面,不是,姐姐我不是想飙车啊,我是真的到上班点了。

直到自己从从主路转到辅路他还紧贴在后面,但是,姐姐我到啦。

停好车往电梯口走,发现小腿依然有点疼,可能是长时间不按,不习惯了吧。

哼,还是得多按几次。

绽放

作者obaby
2026年3月25日 17:19

我要变成野花开在你身边
将我摘走吧在枯萎之前  — 戴娆 《绽放》

周末带宝子去上课的时候,竟然又听到了这首歌。上次听的时候应该是十年前了,眨眼间十几年竟然就过去了。那种轻松欢快的旋律,总是能让人心情变得更加的雀跃。

对我来说,绽放的年龄似乎依然是过去了,剩下的只有残花败柳,跟着时间一起变老。在老去的过程中也看到有的人的凋零,一个接着一个。上周的时候,同事神秘兮兮的说,公司有个哥们没了。说着拿手机给我看,我接过来,在他的朋友圈看到一条消息:『***因为心脏问题,医治无效去世,将在**举行告别仪式……』

看到这条消息的时候,内心并没有太大的波动。这几年,已经看着好多的人凋零,同村的邻居,自己的亲人,自己的同事,还有网上的名人。

昨天晚上对象说,下午看说什么张雪峰的头像变灰了,后面好像又给换回来了。我上网搜了一下,最开始看到的是张的助理说不清楚,合伙人说无可奉告。后来去微博搜的时候,就看到了张的微博账号发的讣告,的确是心脏问题去世了。

张还说自己跑马拉松什么的,身体没问题,网友都不见得能跑过他。然而,这他也没跑赢心脏病。看完消息之后,我一度都想直接买个aed放在家里了。不过对象说不至于,没啥必要。

张雪峰比我大一些,另外一个去世的同事比我大的更多一些。如果身体不好,看来真的不适合当牛马。而至于运动,真的能提高寿命吗?可能也没什么必然的相关性,有的疾病可能没有什么症状,而等到发病的时候,身体素质好的人可能存活的机会更少。身体素质不好的,可能会被拖垮但是不至于要命。当然,也有人说,锻炼是为了更体面的离开。身体拖垮了,可能就只剩下苟延残喘,没有质量的生活。

总是觉得来生还长,似乎有的是时间。现在看来,很多的人时间并没有那么多。或许正在绽放的时候,就被意外给消灭了。相比生命来说,其他的也就没那么重要了。钱多钱少,只要能活的开心就好了。体验生活,享受生活,才是关键,总是让自己活的不后悔才是对的。

很久之前刷短视频,看到一款个别假的手链。前几天又刷到了,去淘宝下了单买了四条,原价12块钱,最后实际花了3块钱。快递到了之后,带回家,对象看到说:『你真无聊,这有什么好玩的啊』

『没什么好玩的啊,我就是喜欢那种很假的感觉。』我答到。

我喜欢的是ta的视觉效果 ,有个角度看过去特别假。感觉都不想这个世界的东西。有时候买这些乱七八糟的小玩意儿,也会上瘾。可能买来不会戴,但是买的时候还是挺开心的。有时候也会买特别廉价的衣服神马的,并且买的衣服也真的不会穿出去。

有时候也挺矛盾的,这一身加起来不到100块钱,然而,周一去加油,大半箱油就花掉了300。加几次一辆电动车出来了,这还是里程数不多的情况下。粉皮每年花的钱,比我花的钱多多了。这么一向,感觉也挺无语。拍写真都够好多套了,不过下次拍,争取把十斤体重先减下来。跳绳的时候想到这些天天运动还猝死的,有感觉有那么一丝丝凉意。运动并不会使人长寿,健康也不会使人长寿,但是,我还是喜欢健康苗条。

最近事情的确有点多,一点点的堆积着都没来得及处理。工行发短信,说新信用卡已经到了营业厅了,但是却一直没去取。偶然想起来小时候吃的牛杂汤,忽然就很想吃。然而,美团、高德搜了一圈都没找到能吃牛杂的地方。想从二手东买,买回来自己加工,对象表示这个东西可能就你自己吃,买那么多也不合适,还是找个地方出去吃罢。

只是,到现在还没找到一个能吃牛杂的地方。周日带宝子去吃罐罐米线的时候,看到万达边上有一个牛杂店,好几天了,却还是没有来的及去。每天中午回家去消灭宝子姥姥在周末包的水饺,荠菜的,韭菜的。每次怕不够吃都会包很多,虽然很好吃,但是为了控制体重,剩下的水饺到现在已经吃了三天了,还有一些在冷冻上,明天不能再吃了,想去吃牛杂了。有的时候,那种记忆真的是刻在了骨子里。熟悉的味道,总是能让人感慨良多。而闺蜜圈的新版本发布,总是一波三折。华为的商户资质,三星的各种材料提交,总是有无数的关卡卡在前面,有时候也在想,不如放弃吧,反正也不挣钱,自己用也够了。

原本,今天似乎能有点空闲时间。然而,早上到公司拉代码的时候,发现移动硬盘坏了,mac 能识别磁盘,但是挂载不了,尝试急救失败。

Checking if the parent's minkey can be updated...
error: btn: oid (854310), xid (36994), type (0x40000003), subtype (0xb), flags (0x4) level (1)
error: btn: unable to repair minkey
   Object map is invalid.
** The volume /dev/rdisk5s1 with UUID 381DE7AB-BD78-4F75-879C-0E618699D213 was found to be corrupt and cannot be repaired.
** Verifying allocated space.
warning: found spaceman free queue tree entry (0xcfef0+17, xid 36987) which overlaps with existing range (0xcfef1+1)
warning: found spaceman free queue tree entry (0xcfef0+17, xid 36987) which overlaps with existing range (0xcfefb+1)
warning: found spaceman free queue tree entry (0xcff16+9, xid 36987) which overlaps with existing range (0xcff16+1)
warning: found spaceman free queue tree entry (0xcff16+9, xid 36987) which overlaps with existing range (0xcff1a+1)
warning: found spaceman free queue tree entry (0xcff16+9, xid 36987) which overlaps with existing range (0xcff1c+1)
warning: found spaceman free queue tree entry (0xcff22+1, xid 36987) which overlaps with existing range (0xcff22+1)
warning: found spaceman free queue tree entry (0xcff2c+3, xid 36987) which overlaps with existing range (0xcff2d+1)
warning: found spaceman free queue tree entry (0xcff30+3, xid 36987) which overlaps with existing range (0xcff31+1)
warning: found spaceman free queue tree entry (0xcff45+2, xid 36987) which overlaps with existing range (0xcff45+1)
warning: found spaceman free queue tree entry (0xcff4c+1, xid 36987) which overlaps with existing range (0xcff4c+1)
warning: found spaceman free queue tree entry (0xcffcc+3, xid 36987) which overlaps with existing range (0xcffcd+1)
warning: found spaceman free queue tree entry (0xcffcc+3, xid 36987) which overlaps with existing range (0xcffce+1)
warning: found spaceman free queue tree entry (0xcfe0f+11, xid 36988) which overlaps with existing range (0xcfe13+1)
warning: found spaceman free queue tree entry (0xcfe22+12, xid 36988) which overlaps with existing range (0xcfe24+1)
warning: found spaceman free queue tree entry (0xcfe22+12, xid 36988) which overlaps with existing range (0xcfe25+1)
warning: found spaceman free queue tree entry (0xcfe60+1, xid 36988) which overlaps with existing range (0xcfe60+1)
warning: found spaceman free queue tree entry (0xcfe85+1, xid 36988) which overlaps with existing range (0xcfe85+1)
warning: found spaceman free queue tree entry (0xcfe96+3, xid 36988) which overlaps with existing range (0xcfe98+1)
warning: found spaceman free queue tree entry (0xcff12+2, xid 36988) which overlaps with existing range (0xcff13+1)
warning: found spaceman free queue tree entry (0xcfe1c+1, xid 36989) which overlaps with existing range (0xcfe1c+1)
warning: found spaceman free queue tree entry (0xcfe36+1, xid 36989) which overlaps with existing range (0xcfe36+1)
warning: found spaceman free queue tree entry (0xcfe3e+1, xid 36989) which overlaps with existing range (0xcfe3e+1)
warning: found spaceman free queue tree entry (0xcfe57+2, xid 36989) which overlaps with existing range (0xcfe57+1)
warning: found spaceman free queue tree entry (0xcfea9+3, xid 36989) which overlaps with existing range (0xcfeab+1)
warning: found spaceman free queue tree entry (0xcfebe+1, xid 36989) which overlaps with existing range (0xcfebe+1)
warning: found spaceman free queue tree entry (0xcfee3+1, xid 36989) which overlaps with existing range (0xcfee3+1)
warning: found spaceman free queue tree entry (0xcff2f+1, xid 36989) which overlaps with existing range (0xcff2f+1)
warning: found spaceman free queue tree entry (0xcffd8+3, xid 36989) which overlaps with existing range (0xcffd9+1)
warning: found spaceman free queue tree entry (0xcfd9e+3, xid 36990) which overlaps with existing range (0xcfd9f+1)
warning: found spaceman free queue tree entry (0xcfd9e+3, xid 36990) which overlaps with existing range (0xcfda0+2)
warning: found spaceman free queue tree entry (0xcfe6e+1, xid 36990) which overlaps with existing range (0xcfe6e+1)
warning: found spaceman free queue tree entry (0xcfee6+1, xid 36990) which overlaps with existing range (0xcfee6+1)
warning: found spaceman free queue tree entry (0xcff29+1, xid 36990) which overlaps with existing range (0xcff29+1)
warning: found spaceman free queue tree entry (0xcfdc9+1, xid 36991) which overlaps with existing range (0xcfdc9+1)
warning: found spaceman free queue tree entry (0xcfe11+1, xid 36991) which overlaps with existing range (0xcfe0f+11)
warning: found spaceman free queue tree entry (0xcfda1+1, xid 36992) which overlaps with existing range (0xcfd9e+4)
warning: found spaceman free queue tree entry (0xcfdb5+1, xid 36992) which overlaps with existing range (0xcfdb5+1)
warning: found spaceman free queue tree entry (0xcfe4e+1, xid 36992) which overlaps with existing range (0xcfe4e+1)
warning: found spaceman free queue tree entry (0xcfe66+1, xid 36992) which overlaps with existing range (0xcfe66+1)
warning: found spaceman free queue tree entry (0xcfe88+1, xid 36992) which overlaps with existing range (0xcfe88+1)
warning: found spaceman free queue tree entry (0xcff41+1, xid 36992) which overlaps with existing range (0xcff41+1)
warning: found spaceman free queue tree entry (0xcfe40+1, xid 36993) which overlaps with existing range (0xcfe40+1)
warning: found spaceman free queue tree entry (0xcfeda+1, xid 36993) which overlaps with existing range (0xcfeda+1)
warning: found spaceman free queue tree entry (0xcff6c+1, xid 36993) which overlaps with existing range (0xcff6c+1)
warning: found spaceman free queue tree entry (0xcff7b+1, xid 36993) which overlaps with existing range (0xcff7a+2)
** Performing deferred repairs.
error: Unable to perform deferred repairs without full space verification
** The container /dev/rdisk5 could not be verified completely.

尝试各种修复方式,最终都以失败告终,apfs看来也不咋靠谱。只能格式化硬盘,重新拉代码,重新配置运行环境,拉代码大半天时间竟然就没了。

只是,退堂鼓一向,内心又觉得不甘。应该让她绽放的,辛辛苦苦的折腾到现在,总是不想功亏一篑。好好的东西,夭折了,也的确不是我的风格。

如果按照所谓的平均寿命,现在看来,正是如花似玉的年龄。该绽放就绽放吧,哪怕花开的有些晚了,也是总要开的。

🦞龙虾养殖小技巧

作者obaby
2026年3月25日 15:21

在深入体验这个东西之前,其实我并未对龙虾抱有太高的期望。不过这几天实际使用下来,感觉还算可以,最起码没那么智障,一些简单的事情也能给处理好。

然而,龙虾虽好,但是养殖却还是稍显麻烦。尤其是系统配置不高的情况下,最开始的时候一切都配置好了,结果在某天晚上gateway就再也启动不了了,启动的的时候就报内存溢出。cpu和内存都直接跑满,等降下来之后,龙虾也跟着死了。刚开始以为是配置问题,改错东西导致启动失败了,结果在回滚镜像之后依然报错,这个镜像是刚安装好的时候创建的镜像。那么此时就有另外一个问题了,同样的镜像为什么系统重启之后就启动不了了?

当时没想这么多,解决办法是备份memory文件等进行重装,好在重装之后接本的功能和代码都在,让龙虾从新加载配置文件,也恢复到了之前的状态。不过,在重装的时候npm源也是个问题,可以考虑直接修改系统的npm源:

npm config set registry https://registry.npmmirror.com

检查修改是否生效:

npm config get registry

另外一个,那就是我给龙虾外层套了一层认证,当然这个做法有点傻,但是呢。这些乱七八糟的东西直接暴露出来总是多少感觉有点问题,于是还是套了一层nginx的认证。

毕竟,前几天周鸿祎还吆喝发现了龙虾的oday漏洞。

相关登录界面实现参考:https://cnb.cool/oba.by/baby-claw

然而,安装之后,昨天尝试更新龙虾,结果更新之后重启又开始报内存溢出,这就有点尴尬了,直接运行doctor:

ubuntu@VM-0-11-ubuntu:~$ openclaw doctor

🦞 OpenClaw 2026.3.23-2 (77e4) — I'm like tmux: confusing at first, then suddenly you can't live without me.

▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
██░▄▄▄░██░▄▄░██░▄▄▄██░▀██░██░▄▄▀██░████░▄▄▀██░███░██
██░███░██░▀▀░██░▄▄▄██░█░█░██░█████░████░▀▀░██░█░█░██
██░▀▀▀░██░█████░▀▀▀██░██▄░██░▀▀▄██░▀▀░█░██░██▄▀▄▀▄██
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
                  🦞 OPENCLAW 🦞                    
 
┌  OpenClaw doctor
│
◇  Update ──────────────────────────────────────────────────────────────────────────────────╮
│                                                                                           │
│  This install is not a git checkout.                                                      │
│  Run `openclaw update` to update via your package manager (npm/pnpm), then rerun doctor.  │
│                                                                                           │
├───────────────────────────────────────────────────────────────────────────────────────────╯
│
◇  Startup optimization ─────────────────────────────────────────────────────────────────────╮
│                                                                                            │
│  - NODE_COMPILE_CACHE is not set; repeated CLI runs can be slower on small hosts (Pi/VM).  │
│  - OPENCLAW_NO_RESPAWN is not set to 1; set it to avoid extra startup overhead from        │
│    self-respawn.                                                                           │
│  - Suggested env for low-power hosts:                                                      │
│    export NODE_COMPILE_CACHE=/var/tmp/openclaw-compile-cache                               │
│    mkdir -p /var/tmp/openclaw-compile-cache                                                │
│    export OPENCLAW_NO_RESPAWN=1                                                            │
│                                                                                            │
├────────────────────────────────────────────────────────────────────────────────────────────╯
13:24:32 [plugins] plugins.allow is empty; discovered non-bundled plugins may auto-load: openclaw-qqbot (/home/ubuntu/.openclaw/extensions/openclaw-qqbot/index.ts). Set plugins.allow to explicit trusted ids.
[qqbot-channel-api] Registered QQ channel API proxy tool
[qqbot-remind] Registered QQBot remind tool
│
◇  Archive 1 orphan transcript file in ~/.openclaw/agents/main/sessions? This only renames them to *.deleted.<timestamp>.
│  No
│
◇  State integrity ─────────────────────────────────────────────────────────────────────────╮
│                                                                                           │
│  - OAuth dir not present (~/.openclaw/credentials). Skipping create because no            │
│    WhatsApp/pairing channel config is active.                                             │
│  - Found 1 orphan transcript file in ~/.openclaw/agents/main/sessions.                    │
│    These .jsonl files are no longer referenced by sessions.json, so they are not part of  │
│    any active session history.                                                            │
│    Doctor can archive them safely by renaming each file to *.deleted.<timestamp>.         │
│    Examples: 9ede0dd4-5344-4156-a156-a9035538b1cb0d.jsonl                                   │
│                                                                                           │
├───────────────────────────────────────────────────────────────────────────────────────────╯
│
◇  Security ─────────────────────────────────╮
│                                            │
│  - No channel security warnings detected.  │
│  - Run: openclaw security audit --deep     │
│                                            │
├────────────────────────────────────────────╯
│
◇  Systemd ───────────────────────────────────────────────────────────────────────────╮
│                                                                                     │
│  Gateway runs as a systemd user service. Without lingering, systemd stops the user  │
│  session on logout/idle and kills the Gateway.                                      │
│  We can enable lingering now (may require sudo; writes /var/lib/systemd/linger).    │
│                                                                                     │
├─────────────────────────────────────────────────────────────────────────────────────╯
│
◇  Enable systemd lingering for ubuntu?
│  Yes
│
◇  Systemd ───────────────────────────────╮
│                                         │
│  Enabled systemd lingering for ubuntu.  │
│                                         │
├─────────────────────────────────────────╯

这时候才发现关键性的几行:

◇  Startup optimization ─────────────────────────────────────────────────────────────────────╮
│                                                                                            │
│  - NODE_COMPILE_CACHE is not set; repeated CLI runs can be slower on small hosts (Pi/VM).  │
│  - OPENCLAW_NO_RESPAWN is not set to 1; set it to avoid extra startup overhead from        │
│    self-respawn.                                                                           │
│  - Suggested env for low-power hosts:                                                      │
│    export NODE_COMPILE_CACHE=/var/tmp/openclaw-compile-cache                               │
│    mkdir -p /var/tmp/openclaw-compile-cache                                                │
│    export OPENCLAW_NO_RESPAWN=1                                                            │
│                                                                                            │
├────────────────────────────────────────────────────────────────────────────────────────────╯

这个startup 优化,不知道是不是针对gateway的启动也有效。不过在升级到最新版之后,感觉启动稍微顺畅了一点。似乎没那么卡了。

新版本貌似也同时修复了用量显示问题,上个版本,不管怎么查询用量都只显示今天的,新版貌似是没问题了:

服务器作为一个比较干净的环境,如果要实现一些其他的功能,就得能够进行文件快速交互,所以文件上传下载也就是一个必备的技能,推荐filebrower:

至此对我来说,一个简单的勉强能用的龙虾就实现了。可以尝试各种工作了:

1. 手搓elf可执行文件

2.给我发布闺蜜圈wiki的文章:

3.批量创建停机申请表:

skill这个东西,可以有,但是也不是必须的。

 

野心家

作者obaby
2026年3月24日 08:58

时间总是太少,感觉有太多的事情想要做,太多的东西想要学。总是觉得时间太少,仿佛永远都没有够用的时候。总也赶不上发展的步伐,被时代狠狠的甩到了后面。

跟着滚滚洪流,跟在后面跑的精疲力尽,却总是感觉和这个世界脱节越来越严重,渐行渐远。有时候很容易有一种错觉,就是我上我也行,看着简单的东西,实际操作起来从来都不简单。并且没有什么捷径。

学了很多的技术,也许了很多的东西,然而,却似乎从来没有经通过,也不曾足够深入一项技术。总是感慨人与人之间的差距,不单纯是智商的差距,而是物种的差距,似乎完全不能理解别人是如何做到的。什么99%的汗水+1%的灵感,却鲜有人告诉你,那1%才是最重要的。

这几天体验养龙虾,几天下来感觉一些复杂的东西也能处理,至于能处理多复杂的东西就看用的模型多先进了。

以前自己做家里的家居控制系统的时候,只能用简单的语音识别加ifttt的指令简单识别。包括前几天给闺蜜圈做得快捷指令也是通过指令匹配的方式做得,现在看来是真的落伍。不过要体验新的东西,总是要付出代价的,巨量的token消耗。新技术的发展和迭代必然会改变一些事情,也会改变一些人的生存方式,这个是无解的。当然,也催生了一堆新的职业,例如那群生产孵化各种龙虾的,虽然现在看来各种虾是真的瞎。

以前花费好长时间才能掌握的汇编、java、oc等等,现在各种工具连一分钟的时间都不用就能生成可以运行的代码。或许,这依然不是极限,以前在windows上曾经手写十六进制,构造可执行文件。或许已经有ai能够实现不需要高级语言直接生成可执行文件了,不管是windows的pe文件,还是linux的efl文件,遵循特定的文件结构,剩下的就是生成导入导出表,编译机器码。如果这样,还要什么高级语言,你告诉ai需要什么格式,到时候可能就直接给出exe、so、apk、ipa文件了。最终的发展趋势就是从机器码->低级语言->高级语言->机器码。以前从命令行到了gui,现在又有很多人从gui回到了命令行,现在的ide编辑器似乎也没那么重要了,全部ai驱动,只需要一个输入输出窗口就行了。广义来说,龙虾也是此类进化方式,不再需要关注具体的代码,也不用修改,全部ai驱动。 

文件:hello_obaby

上午让workbuddy给整理汇总图片里的运维日志,结果卡住了之后,一天都没进展。

最后还是切到了龙虾上,虽然费功夫,但是确实做到了。

ai甚至说,人工识别了这些图片。可能ai才是野心家,哪天想把人类取而代之吧。

周末给龙虾装了个看板,结果在折腾到晚上的时候,因为qqbot的一个问题,把系统整挂了,通过快照还愿之后,cpu一直卡在100,最后也没能再起来。相比之下,自己的确不如ai,然而,ai却无法自救。

之前看《机器学习》的时候,总觉得自己也能写个模型出来,然而,前几天尝试用机器学习计算月经的预期时间都没弄好,想着改进算法却一直没时间。时间也不知道都干嘛去了,当然,与最近工作的事情也有关系,乱七八糟的事情实在是多,每天都有解决不完的问题。

那广泛的涉猎,到现在已经没有太大的意义,因为连自己的空闲时间都挤不出来。

也许,等哪天自己不眠不休,或者能活500年的时候,才能成为真正的野心家吧。

岁月是把猪饲料

作者obaby
2026年3月20日 10:54

前段时间,孙燕姿开演唱会,网上的评论都是变胖了,以及说什么穿着不合体,不好看之类的。

只是变胖的又何止是她,还有好多人也都变胖了。曾经的女神,现在变成胖女神了,还有人调侃石矶娘娘的。

然而,女神们也曾经风华正茂,身材婀娜过啊。

说到穿衣造型,其实作为一个胖女生,可塑空间就变得非常小,很多衣服或者穿搭就没那么合适,所以有时候不能全怪造型师,也不能全怪变胖的女神们。

毕竟在时光的洗礼下谁又不胖,最近带着对象运动,然而,确时常听到:『我现在吃的不多啊,还蹭蹭的长肉。现在连吃都不能吃了,还有什么乐趣?』

减肥的时候真的挺没乐趣的,第一次去拍写真的时候,肚肚还非常的突出,第二次去拍的时候,摄影师甚至问,『你上次拍照的时候带的那个束腰带了吗?』

然而,那个束腰第一次没用上,第二次想用的时候已经被我扔了。以前在记得时候,偶尔用一次对象总说:『那玩意儿不管用,你少戴吧』

真正开始减肥了,还是靠控制饮食和运动,当然,最主要的运动就是跳绳。昨天晚上在家跳的时候,竟然断了。

重新插回去之后就变得一个长一个短了,等哪天看看把那根长的也调整下。跳绳一年多,右手可能是握姿有问题,竟然磨出了茧子。翻了下记录,才发现真的挺久了。

至于跑步,其实这两年跑的并不多,主要集中在还有跑步机的时候。

不过那时候跑步却没有变瘦,真正减肥还是去年,一共减掉了40斤,今年的目标是再减掉10斤。不过这个周期可能就比较长了。

岁月的猪饲料是平等的,雨露均沾,谁都躲不过,看身边的男人,多数一个个都停着大大的肚子。女生也一个个的出现了小肚子,哪怕是还没有结婚的那个同学,身材也开始走样了。

谁都想一直好看,然而,不是所有人都能抗住岁月的变迁。

好看一天是一天,就酱紫吧。

🦞龙虾初体验

作者obaby
2026年3月19日 16:04

龙虾刚出来的时候,我无动于衷;龙虾爆火的时候,我依然无动于衷;龙虾开始被卸载的时候,我终于不再无动于衷了。

从春节的时候,龙虾忽然就开始变得热度极高。几乎所有人都在讨论龙虾,以及养虾的话题。这儿东西最开始的时候,给我的感觉就是,如果本地没有足够多的资源,龙虾就发挥不出自己的作用;如果直接用自己的电脑去安装,又会出现龙虾权限过高的问题。

龙虾做得事情,可能在我的预期范围之外。单纯为龙虾创建一个沙盒环境,意义感觉也不是很大。如果一个问题需要解决两遍,那感觉和不解决似乎也没太多的区别。

尽管如此,龙虾的热度还是越来越高,一度出现各种上门安装的服务。

再后来出现线了,各种收费卸载的服务。果然是此一时,彼一时,三十年河东三十年河西。

然而,在这滚滚的卸载浪潮中,我逆流而上,反其道而行之,我安装龙虾了。

不得不多,openclaw基于node的服务还是蛮笨重的,安装的确有点麻烦,刚开始为了省事,直接百度云买了个所谓的9.9的open claw实例,然而订阅coding plan的时候发现根本抢不到。

使用按量付费之后,简单尝试了以下,发现效果还是可以的,不过就是太费token了。千帆大模型感觉体验也还ok。

可以理解你的意图,也能正常的推进任务。然而,不能订阅,这个长期跑费用是个问题。

于是再次尝试别的方式,直接腾讯清凉弄了台99的服务器,干净安装openclaw,模型选择参考的杜郎的文章里提到的nvidia nim。好处是免费,当然,速率还是有限制的。

昨天的时候,第一次玩这个东西没啥经验,还是用的kimi,后来尝试minimax,但是效果怎么说呢,不知道是配置问题还是啥问题,总是不尽如意。

再后来看到了zero claw,号称体积更小,占用资源更少。直接二进制安装,下载之后启动:

至于怎么在公网访问,直接使用nginx反代即可,参考: https://cnb.cool/oba.by/baby-claw

这次直接用glm5,配置好之后,整体体验感觉有些差,就是非常智障的感jio。

假装执行,这种处理逻辑真是可以,如果我不知道文章分类都有啥,差点就信了。在这种状况下不得不再切回openclaw。鉴于昨天的配置问题,今天reset之后,尝试重新配置运行,依然用与zero claw同样的glm5,这次相对来说还是比较顺利的。

与之前zero claw的对比就会发现了,这次好歹是真的获取到相关的分类了,而不是假装执行。

所以,有的时候虽然都说自己很厉害,但是不对比永远都不知道谁更厉害。很多东西不是单纯说说就可以的,当然zero的优势在于部署方便,占用资源更低,但是作为一个agent,实际的效果并没有赶上open claw。

所以,现在各种龙虾层出不穷,如果不知道选择哪一只,建议还是选择原版,open claw,虽然安装费劲点。但是相对来说,没那么弱智(在同样的模型glm5下)。

上图为三小时token消耗量。

微信公众号文章,自动发布wp效果:

相关资源:

https://cnb.cool/oba.by/baby-claw 

https://dujun.io/28c43a95-478f-5e2a-8805-510244c99494.html

https://build.nvidia.com/z-ai/glm5

https://q.qq.com/qqbot/openclaw/index.html

不确定性

作者obaby
2026年3月17日 16:35

昨晚,对象接自己下班的时候。刚上车,还没系好安全带,就听她说:『咱们租的那个车位要没了,那大姐不租了。房子也不租了,自己去住,所以车位也就不再往外出租了。』

这个车位,租用的时间也蛮长了,大概快三年了吧。小区里的车位一直比较紧张,买房的的时候就就已经没车位了。后来,物业在路边又画了几个,但是,没有任何的声响,那些车位又没了。至于怎么分配出去的,并不清楚。也不知道那些人是怎么弄到那些车位的。

马上租的车位没了,两辆车就都没地方停了。之前都是周末对象把车开回去,登记了车牌方便一些。自己也就偶尔中午回家吃个饭开开,其他时间并不会停在小区里。现在小区里已然没有地方能停了,而小区中间的收费车位,虽然费用不贵,一天6块钱,但是回去晚了就没空闲位置了。能不能有地方停完全是运气。

山上公园的停车场,周五可以停进去,但是周末如果开车出去,那就再也进不去了。公园的路边都停满了车,又怎么可能停的进去。

再有停车的地方就剩下区政府的停车场了,然而这停车场的入口走过去得二里地。来来回回周末要想出门叶诚然是异常麻烦。之前每天早上开车送宝子上学,以后可能就只能做公交车,或者走过去了。当然,也不是不行,只是不管那种方式,都得更早出门。只有这样,才不会迟到,毕竟公交车需要提前等,而走过去需要花费更多的时间,不管是哪种方式,都意味着要更早出门。

对象提议把房子租出去,找个有车位的房子租。然而,这种方式能解决眼下问题,解决不了长久问题。租的房子,说不定哪天房东不租了,就需要搬家,来回折腾。这么折腾也定然不是长久之计。

当然,还有另外一个办法,就是把现在的房子卖了,买个有车位的房子。这个解决了长久问题,但是战线又被无限的拉长。不管是那种决定,都充满了不确定性。并且这种不确定性不是自己能左右的,也没有任何的可以遵循的规律。一旦开始了,就是长期。

中午回家吃饭,消灭掉了周末剩下的两篇披萨,还有早上的两个小笼包。拿着手机去刷碗的时候,手机啪的一声掉到了地上。捡起来看了以下虽然屏幕没碎,但是后盖裂了,用手摸上去能明显感觉到一条条的玻璃纹路。总感觉哪天不小心可能会扎自己手上。

从美团搜了下手机壳,发现现在还在卖p30手机壳的商户不多了。随便找了一个,下单,竟然需要凑单。

然而,换了几个不同的店铺之后就更离谱了,需要凑单的金额一个比一个高,竟然需要凑到90。问题是我只需要一个破手机壳啊。

返回第一次看的那个店铺,买了一条肉色的裤袜,算是凑够了。

然而,等外卖到了,才发现tm给发的黑色的。这尼玛就离谱,连裤袜颜色都能看错。

真是tm薛定谔的丝袜。

 

❌