普通视图

发现新文章,点击刷新页面。
昨天 — 2025年5月8日obaby

2025年5月8日 09:52

“包好!小栓——你不要这么咳。包好!”  — 《药》

五一假期,提前两天就回来了,想着也是如果宝子有落下的作业,再补补作业。不过,这一旦有了时间,宝子的姥姥就开始准备做吃的,主要也就是两种,一种是水饺,另外一种是馅饼。

听起来,似乎温馨充满了整个房间,到处都洋溢着幸福的味道。

其实,有时候我挺不喜欢他们这种所谓的自残式的的付出的,看着让人心惊胆颤。出去玩的这几天没怎么控制饮食,所以导致体重又上升了好几斤。回来之后感觉单纯的靠锻炼已经没有什么效果了,于是开始服用药物。

所以对于吃什么的,自己并没有太多的想法。想着只要宝子能吃好就行了,自己吃不吃倒是也无所谓。尽管如此,还是不想他们大费周章的去做什么。

不过宝子的姥姥姥爷既然已经决定动手了,自己也不好再说什么。姥姥给的理由是他们俩给宝子的小姨看孩子,平时不在这里,做什么吃的我们也吃不上,觉得不公平,对不起我们。宝子的小姨自己一个人在家带孩子,可以中午过来吃。

这一切听起来似乎也没什么问题,然而,在干了不到一半的时候。宝子的姥爷突然说,你妈肩膀疼,你们找时间去跟她检查检查。

“啥时候肩膀疼了?”我问了一句。

就这一句惹了祸了,姥姥瞬间提高了声调:“我肩膀疼和你们说了多少次了?!也没个人和我去看看”

听到这句话我瞬间懵了,这从来我都没听到过啊。对象说,可能是和双双(宝子的小姨)说的。

“恁妈这肩膀疼了很长时间了,……”宝子的姥爷开始解释。

有的时候真的挺佩服她的,自己肩膀疼,一方面说自己不想麻烦孩子,但是自己也不去看,就是懒得出门,一旦有点什么事情就不想露头,什么都想让被人代劳。然而,不明说,还要到处阴阳别人。本来一句话的事情,就说自己要去看看肩膀,但凡这么说了,请假都陪她去。然而,他这个疼也是天天吆喝,狼来了的故事一次次上映,也不知道她是真疼还是假疼。

终于水饺煮好了,让过去吃饭。我怕烫,都是等凉凉了才过去吃。宝子、小姨、宝子的弟弟先去吃。

吃饭的时候,看到姥姥去逗弟弟,问:“姥姥能不能挨着你啊?”

“不行”弟弟说道,一边说,一边往边上推她。

“恁这些白眼狼,都是白眼狼”看着宝子说道,“你是大狼”,又指着弟弟说道,“这是小狼!”说完就气呼呼的走了。

吃完饭,大家开始商量着挂号,检查的事情。放假有的科室不上班,想着等上班了去挂号检查。于是就这么简单的决定了。

下午吃完饭,他们都走了,姥姥姥爷跟着小姨带着孩子一块走了,毕竟还得给他们看孩子。

晚上宝子做作业,我在看电视,这时候大门开了。姥姥回来了,气鼓鼓的样子。问了下才知道,原来小姨下午回去之后也肩膀疼,然后就去拿药了。左等右等不见回来,终于过了一个多小时回来了,原来是在社区医院做了针灸。

这下算是捅了篓子了,自己肩膀疼没人管,自己肩膀疼就知道马上去医院看,去医院针灸拿药。这大公主哪受得了这刺激,直接气鼓鼓的跑回来了。看那个表情,也的确不想搭理她,爱咋咋地吧。

周二晚上,下班一起往回走的时候,宝子的小姨说:“老妈以为我今天是生日,说什么孩生日,娘苦日。逼着老爸给她煮了碗面条,还加了个荷包蛋吃了。但是问题是我是明天生日啊,以为我过生日,结果什么都没提。” 医院的预约也排上了,系统检查需要住院,大概得两三天,她说为了能让她好好水饺,预定的单间。呵,不得不说,这待遇真是牛逼到顶了。

昨天晚上,下班凑到一起,宝子的小姨又说了:“老妈今天又以我过生日的名义,让老爸出去给她买的鱼吃的。撒娇女人真好命”

这概括也的确准确啊,他们这些人,把养育子女当成了投资,所以一旦自己的孩子,少有不顺心,就开始各种 pua。白眼狼,白养了,各种话就开始絮叨不停。动不动就是为了你们怎么怎么着,问题是我不需要你为了我们。如果觉得自己的孩子是负担,那就别要孩子。那种苦难式的的付出,没困难制造困难也要表达他们的付出的,看着就累。也无法共情。

电视上,那些通情达理的父母果然都是别人的,而至于自己的父母,除了 pua 就是 cpu。哪有这么所谓的同理心,在他们看来孩子不过是自己的附属品,他们有绝对的权威。没有公主命,却得了公主病。带她出去玩也罢,出去吃饭也罢。都得不断的照顾她的喜好,这不吃,那不吃,这不行,那不行。即使满足了这一切,稍微哪天自己做的不到位,之前的种种新仇旧恨就一起翻出来,开始各种批斗。仿佛她们现在的这种境遇都是我们造成的。

即使是按照他们的投资逻辑来看自己的子女,他们的投入有多少?他们又给了什么?这一切都是我们奋斗来的,而不是他们给予的。说道给与,不过是给了条命,仅此而已。父母有恩吗?父母无恩,养育自己的子女那是义务,子女扶养父母,也是义务。是该做的,他们对我无恩,我对宝子也无恩,这是我的孩子,我对她好,只是因为我爱她,而不是我对她有什么所谓的恩情,也不希望她将来会为了报恩来委屈自己。

体检报告全部出来了,各种异常情况比之前又多了很多。建议还是减肥,低盐低脂饮食等等,这一切似乎也无药可医,至于他们的心病,我也无药可施。

昨天下午同事过来说,公司又要裁员了。现在的这些年轻人,之前是他们说的扶不起的 80 后,现在这些 80 后门承担的压力超过了之前他们所有的人,他们的压力和心病又有什么药能治疗?除了要承担工作,生活的压力,还要不断的应付父母,忍受他们的 pua,这又有什么药能治疗?

“包好”,这人血馒头治疗不了小栓的咳嗽,这世间的药,也解不了生活的疾苦。

The post appeared first on obaby@mars.

昨天以前obaby

窦娥,冤

2025年5月5日 15:07

假期还是如约而至了,晚上本来想早点休息的,毕竟早上两点就要爬起来出发了。

但是,洗刷完,却怎么也睡不着了。终于十一点多 迷迷糊糊睡着了,夜里起来上一趟厕所,看了下时间,差几分钟不到一点。

256块钱的早餐

宝子的小姨凌晨多一点点在群里发了一条消息说到家了,她们带着孩子,晚上八点就走了,两百多公里的路程,走了四个多小时,也在意料之内。从晚上就不断的关注路况,生怕堵车,高速的拥堵状况直到睡觉前,还有很多地方是大段的红色。

醒来之后再也睡不着了,打开地图看下路况,仅剩下往京沪高速拐的地方有一点红色,等跑到那里应该也就差不多了。窗外传来雨滴打在玻璃上的声音,躺在床上刷了会儿手机,一点半把他们叫起来,穿好衣服就准备出门了。

提前下去把车开到楼下,这样一来可以不用拖着行李走太多的路程,第二也免得那么多人被雨打湿衣服。

一路上相对来说还算顺畅,不过在到了临沂之后,导航提示出高速更快,然而,出高速之后导航的长深。在出发之前已经做过功课,长身高速修路,整体限速80,所以段然是不可以走的。出了高速,重新导航,折返一段,最终还是走的京沪。比较幸运的是一路上基本没什么突发状况,除了有一辆车翻在路中间,黑乎乎的看不清楚,其他的还是比较畅通的。

出发早的好处,在此刻也就体现出来了,路上没什么人,并且服务区也没什么人。

最终,终于在三个小时之后,天亮了。此时对象可以开车了,换自己休息下。不过,这临沂境内的大雾,真的浓重。可见度异常的低,只能降低车速行驶。

到处弥漫着浓重的雾气,这些雾气,让远处的风景变得不可捉摸。

五个小时候,总算是到了淮安。

到目的地之后,第一件事情,自然是找地方吃早饭啦。大众点评,找个最近的饭店,路上经过一座塔,后来折返回来之后才发现这座塔叫做爱心塔。

在饭店门口停车的时候,开过来一辆宾利。

“哇哦,咱们跟开宾利的吃一样儿的餐厅哎”我说。

“会不会吃不起啊?”对象问。

“不至于,不至于。开宾利的都吃,可能真的不错”我说完,就带着他们往里走。

在前台点餐,给个定位器,给张单子,就可以进去随便找地方做了。虽然已经快八点,不过吃饭的人还真的不少。

当然,最贵的还是蟹黄汤包,38一个。

给了一根吸管,用来喝汤。整体来说味道还算不错,但是没有那么惊艳,可能是没有多少蟹黄的原因吧。

一桌子菜,对于早餐来说确实多了点,不过,这一顿吃完,下一顿饭可能就得很晚啦。

 

窦娥,冤

吃完饭去民宿,安置好,稍微休息一下。不过,这民宿也是第一次见到没有电视的民宿,只有个电视机,古老的panda品牌,没有机顶盒,也没什么其他的播放设备,就这么孤零零的一个电视。的确有点匪夷所思。

中午简单的游览下,最终选择了清晏园。一个不大的园林,周边有两个停车场。然而到达目的地之后,却发现都满了,围着院子转了一圈,终于在门口又等到了机会,有车出来才好歹停了进去。不大的园林,好处是人不多,适合溜达,自然也不需要导游讲解。

一天的时间,过得还是很快,毕竟这一天的时间,还有很多实在路上消耗的。

第二天的行程自然也简单,主要目标是周恩来纪念馆。驱车前往导航的停车场,快到目的地的时候发现前方异常拥堵,直接右拐,找了个停车场停了进去。步行围绕纪念馆前面的湖转半圈即可到达,入口处的喇叭在广播持身份证入场,不过在实际进入的时候也没有查验。

主楼仅有雕塑能看,其他的地方都不开放。

沿着边上继续参观的牌子前进,竟然直接出来了。往后绕直仿照总理之前办公场所一比一复刻的办公室。

纪念馆人潮涌动,被裹挟着一路向前。从纪念馆出来之后,刚好可以从另外一侧的出口绕出去,沿着河岸继续前进,走不远就到了淮安府署,另外一个景点。

而至于,淮安府署。门票60一张,的确不便宜,然而,这个地方确满足了自己对于古代那些刑具的好奇心,与我而言的确是物超所值。淮安府署属于国内唯二保存完整的府衙结构之一,在刑狱一块的完整程度的确比较高。在其他地方不曾见过这些东西,之前的了解也仅限于书上,或者影视作品,或者之前看《世界酷刑简史》里面的一些图片。

而窦娥,也是在这个地方被斩首处死的。《窦娥冤》的故事大家应该都听过,讲的是:

是元代戏曲家 关汉卿 创作的杂剧,刊行于明万历十年(公元1582年),故事原型来自《列女传》中的《东海孝妇》。 全剧四折一楔子,写弱小寡妇 窦娥,在无赖 张驴儿 陷害、昏官 桃杌 毒打下,屈打成招,成为杀人凶手,被判斩首示众。 临刑前,满腔悲愤的窦娥许下三桩誓愿:血溅 白练,六月飞雪,大旱三年。 果然,窦娥冤屈感天动地,三桩誓愿一一实现。

这是语文课本中的内容,其实,后面还有,那就是:

刽子手行刑后。窦娥的鲜血竟然一滴都没有落在地上,全部飞溅在了高挂的白布上。当时围观的百姓暗自称奇。紧接着天地变色,狂风大作,天空飘起鹅毛大雪,密密地覆盖在窦娥的身上。那时候正是六月夏天,每一个在场的人都惊呼:“这窦娥真是冤枉的!”
接下来,楚州果真大旱了三年。所有人都相信窦娥的冤屈,为窦娥抱不平,直到窦娥的父亲窦天章在京城做官返乡,窦娥的冤案才得到昭雪,杀人凶手张驴儿被处以死刑,贪官知府也得到了应有的惩罚。

而至于窦娥冤,这罪魁祸首,自然是她的父亲,为了凑盘缠考取功名,把自己的女儿卖了!

刑科外面现在还矗立着腰斩台,用来实行腰斩的钺依然高悬。

只是不知道这死在腰斩台台上的人,有多少罪大恶极,又有多少含冤负恨。用来控制钺升起的绞绳已经被锁死,自然无法再拉上去,或者放下来。另外一侧没有锁死,可以自由的转动,但是不会有任何实质性的变化。

本来,想着这淮安府署也不过如此,自己坐在院子里耍手机,对象带着宝子去溜达,过了回来对象回来很神秘的跟我说:“你该去看看刑科的东西,应该是你感兴趣的”

听到这句话,我蹭的一声蹦起来,这自然是要去看的。腰斩台边上叫做皮场庙,这个庙自然是用来剥皮的。

既然是针对贪官剥皮,在古代自然都是男性,不得不说,这里面的还原度是真的不错,连阴茎的皮都给呈现了出来,自然,这种活在古代也是一种手艺。剥皮自然要完整,不过这个东西无法申请非遗,毕竟现在申请了,那些贪官也不能拿来真给剥皮。

初次之外,看到了另外一个刑具,那就是木驴。

这个刑具,其实并不是单纯给女性设计的。男性一样适用,毕竟男人下面也有个洞不是吗?看着这粗大的棍子,就该猜到插到下体里面是什么感觉了。《窦娥冤》最后一折,就有关于张驴儿骑木驴的判罚:

你这一行人,听我下断:张驴儿毒杀亲爷,谋占寡妇,合拟凌迟,押付市曹中,钉上木驴,剐一百二十刀处死。

钉上木驴,自然就是汤张驴儿直接骑到这个东西上面。之后就是凌迟处死,不过这个凌迟的判罚并不算重,一百二十刀而已,如果真的判千刀万剐,一千刀,那自然是要割完一千刀才能死。对于这种行刑,自然也是需要深厚功力,申请非遗恐怕也找不到师傅了。这凌迟要从身体最不重要的部位开始,比如乳头,耳朵,鼻子,嘴唇,屁股,大腿等等。一步一步的向中间靠近,据传最厉害的刽子手,在快一千刀割完的时候,胸部只剩下一层薄膜,透过肋骨能看到跳动的心脏。

而这最后一刀就是捅进心脏里。

而至于这其他的刑法,不管是世界酷刑描述的多么厉害,其实与中国古代的酷刑相比,并没多先进,人性使然,所以折磨人的方法也自然大同小异。

当然,也有专门区分性别的刑法,例如“乳夹”,这个要夹男人的话可能就有些难度了。

不过有个屋子做了各种行刑的动画,当然,我最想看的木驴和凌迟没有,有点遗憾。

只是,这窦娥,的确死的冤!

 

金湖水上森林,我比窦娥还冤

第三天,选了个稍微远点的地方,金湖水上森林,这个地方在大众点评上的评价两极分化。不过来都来了,去看看也行,驱车前往一百公里,的确有点远,不过好在路上还是比较畅通的。

买票的时候本来想就买个门票,剩下的就算了,对象表示买套票,最后买了110的套票。进门就遇到了第一个障碍,等摆渡车的人排队都要排到大门外了。

只好先去做竹排,沿着最美步道,一路前行。步道的美景真的不错。

那种原始森林的感觉,让人心旷神怡。然而在步行了差不多一公里到了竹排的地方,发现排队的都要排到大路上了。

带拐弯的队伍,并且队伍又粗又长,看到这种队伍就真的让人挺反感的。主要问题还是工作人员的不作为,警戒线就在拐弯的地方有一点点。终于到了拐弯的地方,还出现一堆插队的,跟维持秩序的工作人员说,我们是一起的,于是一下子塞进来五六个人。工作人员装死,啥都没看到,自己也没必要说什么了。更神奇的是,塞进来的那些都没买船票,问题船票那里买的,这就尼玛离谱。

又让我想到了昨天中午吃饭排队等号的情景,看所有的餐厅都在排队,唯有一家浦园中桌和大桌没有排队的,于是选了他们。到了之后,取号也很方便,给了个b09。说现在叫号的是06,需要等三桌。然而,等了半个小时了,一个号都没叫,问什么情况,说要等。

终于,快一个小时了,再问说现在是按照等待时间叫号,跟小卓一起的,中桌是加的凳子,真是心里一万个草泥马奔过。

但是a都从a40叫到a60了,实在忍不住去看叫号机。这时候刚要叫a61,实在忍不住了问服务员:“刚才就说下一桌,现在下一桌怎么又要61了?!”

“再下一桌就是你们了”服务员说答到。

“你们不是按照等待时长吗?我们等了69分钟了,a61只有60分钟,凭什么先叫61?”我继续问。

“这……”服务员吞吞吐吐,“你们先来吧”

就这菜算吃上饭,而此时已经都两点了,等号的人就还我们几个。吃饭的都吃完走了,这体验真的只能说是垃圾!

现在又来这么一出,我也不管队伍粗不粗了,拉着宝子往前挤,我可去你妈的吧。就这样,我一个人开路,拉着四个人往里挤,把那几个给挤到了后面。

半个小时一个项目,等下一个项目小火车,这次要好很多,因为有围栏,只能一个一个往前走。排进去,等了十几分钟不动,这时候有人说小火车半小时一趟。我数了数前面的人,大约得最少一个小时。这时候有人等不了了,直接跳出去或者逆行出去了,就这样等了半小时,等没了二十几个人。不过好处是,感觉等一个小时就能坐上了。

鉴于这种秩序,我要然还是拉着宝子尽量往前走。小火车拉着人走的时候我说:“这也太慢了,蛆guyong的都比他快!”

“别瞎说,比蛆快”我对象说,“等你上车了就不嫌他慢了,慢悠悠多好”

这体验,不说要求有多高,最起码把秩序维护好吧。

下了小火车,宝子的姥姥姥爷死活不往回走了。于是带着宝子去萌宠乐园等其他的地方玩,说实话,真的啥都没有。风筝广场,就他们自己放的三四个风筝。

只看到尼玛跟葫芦娃一起上天了。

玻璃栈道上都是人,下滑的速度太慢了,本来还想跟宝子去的,后来看这个速度直接放弃了。

这景区,感觉真的不值这个价格,如果评价的话,五星能得一星,其中0.9星是给那个最美步行道的。

而至于这最美味卫生间(我给他起的名字,其实叫最美卫生间),真的不知道有啥卵用。

出园的时候发现小火车排满了,而这么多人,没四五个小时根本排不上。来这地方,果然是妥妥大冤种。

 

接着奏乐,接着舞

晚上的夜市,感觉更有意思。

古城,国内的古城都大同小异,看不出太多的区别。

第二天大学城的夜市人头攒动。

天还没黑就已经很多人了。

逛了会儿,发现卖香水的,于是69买了一只香水。

然后买了半只兔兔吃掉了。

最后一晚,来都来了,怎么也得去最热闹的地方看看。九点多出门,自己住的地方一如往日的宁静,路上也没什么车。然而,到了里运河文化长廊才发现,人可能都在这里吧。路上行人如织,走都走不动。终于找了个路边把车停下。往河边走各种拍照打卡的,卖各种吃的小贩,占满了整个街道。

而既然来了,那就酱紫吧。接着奏乐,接着舞。

The post 窦娥,冤 appeared first on obaby@mars.

今天中午吃啥子,罗非罗非罗非鱼

2025年4月30日 13:27

自从体检完之后,身体状况感觉每况愈下,小腿酸胀。体检报告出来的数据越来越多,随之而来的毛病也越来越多,现在感觉能正常活着都不容易了。导致另外一个问题,就是做啥都提不起兴趣,前几天刚说要放弃投降。昨天下午改了下闺蜜圈,把 ai 功能屏蔽了,又提交了华为的应用市场,今天早上通知审核通过了。

至于后续的打算,华为商店的就不再更新了。等节后回来发个新版本,如果升级的话自然就可以升级到带 ai 功能的版本了。

这段时间,体重再也没下降,起起落~,只看到了起起,却没看到落落。至于中午吃饭,也是在是不知道吃什么。有时候中午干脆不吃,或者随便吃点什么。每到中午吃饭的时候也让人无比的犯愁,鉴于现在的状况,不知道是该控制饮食还是增加锻炼强度。

小腿酸胀的问题,前段去按摩了一次,但是效果感觉并不明显。不过按摩完小姐姐说自己现在穿的鞋子很舒服,说可以买一双。然后就提着让我拍照记录一下。

不过可能是拍照角度的问题吧,找同款的时候感觉总是有些区别,不过也无所谓啦。

临近中午,吃这么的问题就又出现了,上周百无聊赖跑万达转了一圈,汤姆家还有充值的余额,点了一份牛排。

这周前两天,连续点了两天外卖,都是沙拉。今天实在不想吃沙拉了,感觉再吃都变成吃草的驴了。

中午本来想叫着公司的一个姐妹一块去吃饭,结果她带饭了。自己继续往万达跑,在路上也想好了要吃什么。

中午人不算多,停车上黑咕隆咚的,再加上倒车影像有点暗,让自己有种做瞎子的感觉。

米线还没上来,服务员问能不能直接煮好了给送过来,就不在单独上了。这个倒是无所谓,也没那么讲究。

吃饭的时候,杜郎在抖音发了个消息,说一个特效可以试试。

原视频效果是酱紫的:

然后我生成的效果是酱紫的:

tm 这是幽会外星人?就尼玛离谱。

不得不说,这人工智能,真 tm 有创造力。这都能从天而降,看到那只脚的时候,小脑都萎缩了,就尼玛离谱。

不过这眼看到假期了,说实话也没什么心思工作,主要是也不大想做。现在对接的项目无法连接互联网每次更新代码都得 git 离线 am 代码,有时候还会出问题,就很烦。为了更新代码,得把 patch文件,从自己的 mac 复制到远程的内网的 windows,从 windows 在复制到内网的 linux。在服务器上 am 代码。

不过好在,过完今天下午就暂时解放啦,定了淮安的民宿,可以去吃淮扬菜啦。

不过这一个假期,希望体重不要上升啊。小红书上看有人说从青岛去淮安高速各种修路,于是决定早上两点爬起来出发,

虽然绕出去一百多公里,但是整体时间还是更划算的。

希望早上不要堵车哦~~

 

The post 今天中午吃啥子,罗非罗非罗非鱼 appeared first on obaby@mars.

一劳永逸?

2025年4月28日 10:21

忘了是周几了,在杜郎杜郎那里看到《Coze扣子空间邀请码》,取了一枚邀请码注册了一下。

刚拿到的时候试了一下,发现生成效率有点低。昨天又   尝试了一下,让 coze 根据上传的图片还原生成 ui。上传的图片:

输入的指令:

静态页面有了,那么是不是同样能够生成后端工程,然而让尝试生成后端项目的时候。表示无法生成项目,不过通过尝试创建目录和文件的方式是可以的。

不过后端代码的整体效果就比较一般了:

导入了序列化的类,但是却没有把数据序列化返回。

相对来说,前端的还原度和代码质量就要高很多,实际效果:

页面访问地址:https://space.coze.cn/web?uri=7497853897668313142%2F%E6%9B%B4%E6%96%B0%E5%90%8E%E7%9A%84uniapp%E8%BF%90%E5%8A%A8%E6%95%B0%E6%8D%AE%E9%A1%B5%E9%9D%A2-1d16562ed0.jsx

整体来说扣子空间前端代码能力还是不错的,包括图片识别,页面设计等等,体验还算不错。但是对于 django 框架,实际的体验就比较一般,当然也有可能是这个框架太小众了。

附几个邀请码:

小妖精 邀请你体验扣子空间,快来和 Agent 一起开始你的工作吧!
https://www.coze.cn/space-preview?invite_code=QL9FGUG1

https://www.coze.cn/space-preview?invite_code=8UQSUMXW

https://www.coze.cn/space-preview?invite_code=B13LD82P

https://www.coze.cn/space-preview?invite_code=1QP96OUJ

https://www.coze.cn/space-preview?invite_code=Y1V1I0YB

昨天收到联通发的消息,说要升级设备。

不出意外,今天早上家里服务都无法访问了,看下了报了个错误。这个错误,应该是 cdn 升级之后导致的,接口变了。

[E] 发生错误: 请求参数错误: username为必填字段
[T] 获取到 token: None
Traceback (most recent call last):
  File "/home/obaby/dnspod-ddns/ddns.py", line 346, in <module>
    loop.run_until_complete(main())
  File "/home/obaby/dnspod-ddns/ddns.py", line 235, in main
    update_ipv4_record(current_ip)
  File "/home/obaby/dnspod-ddns/ddns.py", line 109, in update_ipv4_record
    update_domain_source(domain_list_v2, new_ip_address)
  File "/home/obaby/dnspod-ddns/baby_dunyun.py", line 248, in update_domain_source
    site_list = get_site_list(token)
  File "/home/obaby/dnspod-ddns/baby_dunyun.py", line 54, in get_site_list
    'authorization': 'Bearer ' + token,
TypeError: can only concatenate str (not "NoneType") to str

对于这种错误,其实没什么好的预见手段,只能出了问题再去改。

上午把错误修复了,同事改了下更新 ipv6 地址的逻辑。

就在刚刚,收到华为应用商店的短信,提示 app 被下架了了。

果然跟自己预料的差不多,至于举报只是其中一部分,关键的一部分在于实名认证。但是这个实名认证真的是不怎么好办,不管哪种认证方式,都非自己所愿。就是个记录大姨妈的 app,干嘛非得实名认证,而至于 ai 生成的内容,实名认证了就不会生成敏感内容了吗?这个不应该是 ai 服务提供商来解决 ai 的问题吗?为什么要把问题转嫁给用户?

之前还说永不投降,其实啊,哪里有什么骨气?我不想收集那些用户敏感信息,对此也没兴趣。所以,对于实名认证这件事情我投降了。

至于一劳永逸?那就更不存在了,唯一的就是跟着不断的折腾,折腾,折腾。

天底下没什么免费的午餐,更没什么永葆青春的秘诀。

哪怕是再遥遥领先的高潮针,也解决不了时间的鞭挞。

补充邀请码:

小妖精 邀请你体验扣子空间,快来和 Agent 一起开始你的工作吧!
https://www.coze.cn/space-preview?invite_code=O0RDW20W

https://www.coze.cn/space-preview?invite_code=6WXD0SC0

https://www.coze.cn/space-preview?invite_code=WLCJH5LK

https://www.coze.cn/space-preview?invite_code=RESH9SKJ

https://www.coze.cn/space-preview?invite_code=DLKZFGTF

The post 一劳永逸? appeared first on obaby@mars.

拼多多?

2025年4月27日 09:46

每到各种节假日的时候,伴随而来的是各种调休。为了拼那几天假期而拼,看起来不少,但是实际上去了原来的周末,也没几天。拼多多?一点都 tm 不多。

一个好好的周末就剩了一天,而这一天基本也没什么自由时间。上午配宝子学钢琴,下午配宝子上网球,而至于中午,前几天看电视说青岛的鲜鲅鱼上市了。美食节目说什么一鱼四吃。这种鲅鱼就大了,得十几斤,问宝子要不要吃,表示只想吃鱼丸。既然剩下的三吃没了,自然也就不用买那么大的鲅鱼了。

上午下课,带宝子去超市。路上看到一辆车屁股上贴了好多小玩意儿,宝子说,想给他把苹果薅下来。当然,宝子肯定是不会这么干的。

不过这个加菲实在是太丑了啊,送给我我都不要。

鲅鱼 39 一斤,价格还算可以。转了一圈,有看到了最喜爱的大西瓜,不过价格嘛,稍微贵了点 6.99。本来想那个西瓜也就 50 块钱,称完发现 70。

做鱼丸的时候,宝子竟然想要自己动手。这倒是难得一见,平时宝子对做饭什么的都不感兴趣。把鱼肉做成鱼蓉,水开了,把宝子叫过来,教她怎么弄成小丸子。不得不说,虽然小了点,但是弄得还挺像那么回事的。

下午的网球课依然在小学的体育场,自己去周边的公园溜达。公园上面是高压线,一侧是青银高速。蒲公英的绽放的刚刚好,一朵朵圆圆的,毛茸茸的。如果有个人在身边真想让他吹的时候,猛的把花球塞他嘴里。

从另外一侧转回来的时候,问到一股熟悉的味道。不出意外的话,应该就是石楠了。

看似洁白无瑕的小花,散发出的味道真的当然一言难尽。其实更让人崩溃的是小区里面的那几颗板栗树,没当板栗树开花的时候,散发的味道比石楠花更接近精液的味道。每次从那几棵树边经过去开车的时候,都想绕道。

溜达完,回到停车的地方。发现里下课还有差不多半个小时。坐在车上百无聊赖刷短视频,这时候忽然脑子里蹦出来一个念头。趁着有时间不如把车上的 gps 拆掉吧。

这个 gps,不是平时导航用的 gps,而是贷款的时候安装的 gps。买第一辆车的时候,出了安装 gps 还办理了抵押,那个安装的 gps 给开放了权限,可以通过网页查询车辆位置,为了能实时查看车辆位置,自己还开发了个 app。

不过这个破玩意儿的确是耗电,车停在那里可能七八天不开就没电了。就来就把这个破玩意儿给拆掉了。

而第二辆车大白上的 gps,其实一直就没给开放权限。所以也无法查询定位信息,而之所以知道这个 gps 安装在那里是因为前年去威海玩的时候,在高速上忽然掉出来了。当时吓一跳,还想这怎么个情况怎么还掉装备了,找了个地方又给塞回去了。

之所以想拆掉,主要是这个东西出了耗电也实在是没啥别的用处。从方向盘下面扒拉了一下,找到了那个 gps,跟着是一根长长的线。拉出来发现一头接的保鲜盒的保险丝,另外两根线直接接的 obd的线。

最开始只是拆掉了盒子,后来一想那一大堆线留着也是隐患,直接打开保险丝盒子,把 obd 和后面的线一块给拆掉了。

这样就干净多啦。

不过不得不说,这个 gps 质量是真好啊,都八年了,拆下来,电池不鼓包。感觉一切运行还正常。

这一番折腾下来一天又没了。

而至于今天干嘛,那自然是上班了。还不是为了那个拼多多拼假期!不过,五一对象说定了个什么地方的酒店准备要去,而这个地方自己问了很多次了。到现在也没记住,希望到时候不要堵车。

The post 拼多多? appeared first on obaby@mars.

紫慕的明信片

2025年4月23日 10:11

前段时间,看到紫慕的百信计划紫慕。于是自己留了个地址,今天收到博友的明信片啦,开心。

对于寄明信片这件事情,多年以前度蜜月旅行,在很多地方给自己寄了明信片,然而,最终却一张都没收到。从此之后不管去哪里再也没寄过明信片。

这次收到紫慕的明信片还是很开心的,毕竟,貌似十几年没收到过明信片了。

The post 紫慕的明信片 appeared first on obaby@mars.

Inner Peace

2025年4月22日 10:37

该剪头发了,昨天中午约了 119group hair 。修剪完也不知道该吃啥,在万达溜达的时候看到了汤姆家的牛排西餐厅,想起来之前办的卡应该还有钱,去点了份牛排,最近减肥也的确在刻意的控制饮食。

不过饮料上来之后,用习惯喝了一口,直接吸不动了。

可能是看到我在给饮料拍照,不一会儿又给那里一根粗的吸管。咱就是说一开始不能给根粗的吗。

宝子上周三期中考试,昨天拿回去两张试卷,说要签字。语文 99,英语 100。数学的还没发,不过英语倒是不需要签字。而至于这个 99也不是什么大的错误,山羊招待小伙伴,做了很多好吃的,让写一句话给山羊,宝子写的简单了点,两分扣了一分。

等宝子做完作业,继续一起看《三叉戟 2》,原以为是 36 集,结果之后 34 集。豆瓣的评分,对于这一步刑侦剧来说稍微苛刻了一些,只有 7.7。我个人觉的 9 分还是值得。

早上起床,对象给宝子煮的馄饨,宝子洗刷完之后看着桌子上的馄饨来了一句:“怎么又是馄饨啊,昨晚就吃的馄饨”

好在还有几个面包,于是坐在那里刷手机等宝子吃完去送她。我约了今天早上七点半到八点的体检,眼看都七点半了,手里的那个面包还剩一半。而自己从七点二十就催促她快点。这慢悠悠的速度真是让人无语,不管你怎么着,都要急死了,她一副事不关己的样子。如果不是今天约了体检,真的跟她一起磨。

终于35 洗刷完,准备穿衣服,学校要求 50 前到校。今天开的车没登记,还得缴费出场。小区里各种逆行的,汇车就头大。终于四十出了停车场,怪上主路的时候,感觉车尾都甩出去了。路口又是两个连续 90 秒的红灯,也是在不想理她。终于送到学校,往医院赶,这一路,红的发紫。的确让人崩溃,更让人崩溃的是导航直接导到了高架桥底下,这里没停车长,继续转圈。

终于又转了一圈之后,终于找到一个停车场停车。不过好在今天人不是很多,这体检完,很多结果就能查到了。不出意外,去年有问题的今年依然有问题。

这还只是目前能看到的,看不到的东西自然更多了。

之前 萧俊介  说自己心态好,其实,也有崩的时候。

崩的时候,主要是因为宝子那个无所谓的态度,真的让人上火。哪怕自己要急死了,她都慢慢悠悠。这个心态的确是厉害。这时候,我总是能想到《功夫熊猫》里master oogwui 和 maste xifu 的 inner peace。

inner inner peace.

The post Inner Peace appeared first on obaby@mars.

我们的纪念日

2025年4月21日 10:19

周五晚上去海底捞的时候,在门口看到了个 hello kitty 的盲盒机。里面的 kitty 的造型真的挺别致的,特别符合自己的审美。于是跟宝子约定吃完饭出来抽盲盒。

39 一个的盲盒,看构造还是蛮复杂的。按照之前买的盲盒,这个东西价格可能得在 49 左右。先给宝子买了一个,自己也买了一个。回家组装完发现蛮有意思的,我的那个是一个背着汽笛喇叭的赛博朋克风格的 kitty。

宝子的那个是带着高科技眼镜的未来战士风格的 kitty,不过宝子说,可能是个潜水员。

而边上那个敖光,就更值得一说了。这个是在另外一家店买的哪吒盲盒,里面有个所谓的隐藏款就是他啦。周五的时候宝子说想再买一个,于是,不出意外的又抽到一个隐藏款的敖光。😂,忽然觉得抽到那么多隐藏款也不是什么特别让人开心的事情,不过宝子已经决定把这个敖光送人了。知我的蓝胖子后面的卡片,都是我买的,并且都是最低级的卡。这运气不得不说,区别有点大。当然宝子不可能就这几个,柜子里已经塞了很多了。

各种乱七八糟的小玩意儿。

周日早上打开电视,在播放青岛马拉松的直播赛事,对象提议去石老人的海边溜达一下。出门之后,打开导航发现目的地封路了。于是决定调转车头去高架桥底下的运动场打网球。这次原来的断头路,在公园入口直接停了一辆三轮车,把路堵死了,里面还有混凝土车在施工。球馆的场地依然没有划线,还有几个场地封闭施工,所以能选的地方并不多。

最终还是选了头上一个 pickle ball 的运动场地,在里面打了会儿,而至于这个吧 ball 到底是什么 ball,我也不甚了然。我跟宝子站了长的一半场地,另外一边还能容纳几个人,期间来个两个男士,看运动装备真的好专业,一个包里放了三种运动器械:网球拍,乒乓球拍还有高尔夫球杆。不得不说这运动技能应该是点了不少,不过在打球的时候明显不专业,应该也是业余爱好。

宝子不知道是累了还是怎么着的,到后来越打球越近。可能也是打累了吧,也近中午了,那就打道回府吧。

穿过曲折的小区,回到车上打开导航。虽然来过几次,但是每次不开导航还是不知道怎么走。就在到那个发卡弯的时候,对象忽然说道:“前面这条路是不是能直接到高架桥?我记得应该有条路能上去”

在得到这个提示之后,我毫不犹豫的开了过去,然而却发现越开越不对劲,虽然后面有辆车跟在后面,但是当路对面开过来一辆大货车的时候发现自己正在逆行,这应该是之前自己从学校出来的时候看到的那条匝道。

自己把车靠到路边,后面的黑色 suv 超了过去,对面的大货停了会儿,黑车逆行上了高架。此时自己的想法是直接倒出去,毕竟一个车道调头有些困难。踩着油门倒车速度是真快啊。怕后侧有人过来,自己还不断的看着倒车影像和后视镜。终于这几百里的路倒出来的时候还比较顺利,后方没有来车。

在路边挺好准备往发卡弯拐的时候,发现前面儿大货车距离有点近,于是想着再倒一点。然后就听到砰的一声,车屁股怼到了路边的车上。

“你倒的太 high 了”对象说。

“前面大车有点近,我想再倒点来着。”我说。不过侧面碰上去的感觉不是很严重,把车稍微往前挪一点,去找路边车上的联系方式。

围着车转了好几圈,只看到驾驶位前面放着一个二维码,扫了一下发现车牌也对应不上,二维码识别的电话还是个空号。这尼玛,心里一万个草泥马奔腾而过。那个破别克,真的也的确挺烂的,都是自己补漆,填补的前挡风玻璃还有一条巨大的裂纹,其实就算自己跑了应该也不会被发现。但是,这跑了总不是什么高招,更何况路上还有两个监控探头。跑了心里也难免不踏实,于是打 122 通报情况,同时告知保险公司自己出了事故的情况。

122 详细询问了下情况以及事故发生地址,过了没多久四方交警大队的交警打来电话了解情况,说帮忙联系车主。这时候保险公司也开始一个一个电话的了解情况,把报保险的手机给对象,让她跟保险公司沟通,自己继续和交警联系。

自己一边给事故现场拍照,一边等交警通知。不一会儿收到交警电话告知,车主在外地,联系上了车主的儿子,让下午四点去交警大队处理。既然有了明确答复那就不用再等了,直接回家吃饭,这一折腾又是半个多小时。自己在忙着拍照处理的时候,宝子叽叽喳喳来回跑,当然,她没经历过这种事情,反而觉得有点好玩。

从发卡弯拐过去没多久,又接到一个电话,是四儿子店的,说修车的话可以去他们那里,这的确是一条龙服务了,我还没决定休不休就先联系上了。

“还是得听导航的,他不让走那里肯定是有道理的”我说。

“路边也没指示标志神马的,谁知道那是单行啊”对象说。

回家,吃饭,下午继续刷自己的电视剧《三叉戟 2》。两点左右收到交警电话,说车主的儿子到了,现在在交警大队,你们看怎么协商处理下还是怎么着?

“私了吧”我答道,就那个破车,喷个漆也就两三百块钱,自己目前也没想给大白喷漆。

“好的,稍等,我让车主的儿子跟你聊”交警说道,正好趁这个功夫我打开了通话录音。

“你好,你看咱们是怎么弄啊?私了还是走保险”对方问。

“私了吧,你看是什么想法?”我问到。

“事故也不严重,我看了,喷个漆什么的也得三五百块钱”对方说。

“嗐,那个车也没那么新,喷不喷也没啥,两百块钱得了”

“现在人工多贵啊,这两百实在是弄不了啊。”对方继续说道。

“行吧,那看看三百?实在不行就走保险吧”

“行吧,那就三百,我把电话给交警”对方说完,一阵沉默之后,另外一个声音船里,“你们协商好了是吧?钱是怎么给?”

“我微信转给他?”我问。

“你现在有时间吗?来趟交警大队吧,我给录像也好记录下,留个凭证”交警问。

“可以,我现在过去得二十多分钟,你们得等下”我答复。

“没问题,你现在过来吧”

挂上电话,叫着对象一块去交警大队,宝子也想跟着去,毕竟没经历过有点好奇。让她去换衣服,结果找裤袜找了半天没找到,也就没再跟着。

剩下的就简单了,交警打开执法记录仪,我把 300 块钱给了车主的儿子,这件事情就算了了。剩下的就是买个补漆笔,简单的补下漆就完了。

“倒车的时候,是不是倒车雷达没响?那么一大片障碍物竟然没动静”我问。

“没响,这个之前我也遇到过,姥爷丧事,跟老妈回老家时候我也怼了,把车头给撞了。”对象说。

“咋撞的,我咋没发现?”

“上次回去,那个小胡同我不想进去,老妈非得让拐进去,结果就 duang 了。舅舅还说:”你那么近,雷达响你没听到啊”,其实雷达就没响我怀疑雷达坏了”

“这破玩意儿,我也怀疑是坏了,不过速度快了,那个雷达貌似不提示”我说道。

“高级车是不是能自动刹停?”对象问。

“啊,貌似不能吧,往前走可以,貌似倒车不行”我答道。毕竟有一次开粉皮去吃饭,倒车快了点,差点怼到宝子小姨的车上。而至于那些高科技的新能源自己就不知道了,毕竟也没体验过。

等红绿灯的时候,对象很神秘的拿过手来说,“你看,我忽然发现的”

我盯着看了半天,发现是个日历界面,上面也没什么标记。盯着那个当前日期看了半天才想起来:“我们去买个大金链子吧”我说,毕竟这结婚纪念日,或者说领证纪念日真的没什么存在感。差不多每年都会被忘记,也没什么存在感。

“不买,没啥意思”对象说道,“这纪念日也太没仪式感了”

“嗐,那里啊,毕竟咱们还听了个响不是?”我说。

晚上,一家人继续呆在一起刷电视剧。这几天宝子也跟着自己看警匪片,其实也没啥不好的。毕竟,比跟着她姥姥看那种家长里短的狗血电视剧,跟着姥爷看各种抗战片能好那么一丢丢。刷电视剧的时候,对象又把手机递给我说:“你看人家小陆还给老婆送了花,我都没想到,竟然是同一天的纪念日”

“这我也没想到啊,这还挺有仪式感的”我说,“要不咱们点饮料喝吧?”

“不减肥了?”对象问。

“嗐,周末沉了好几斤,不差这一点”,拿着手机翻了半天,发现美团的那个沪上阿姨,貌似不是真的沪上阿姨,叫什么沪上阿姨鲜果茶。打开瑞幸小程序,想买纳瑞冰,发现竟然没有。这也太离谱了,于是把手机放下说不买了。

“啊,你们不买了吧?我还想喝呢”宝子说。只好把手机递给宝子,让她自己去选自己要喝什么。

划拉了一会儿,看来是选好了,问:“用你的手机付款码?”

“你不考虑给我们也选一个吗?”我问。

“谁知道你们要喝啥,不是说不喝吗”宝子说完把手机递了回来。

划拉半天,总算是凑齐了三杯饮料。不过,送过啦之后发现貌似都不是很浓的样子,养乐多的比例明显要小很多。

“这饮料,越来越来越不行了,也不值二十块钱啊”对象说。

不过喝起来,味道也还行,就自己把饮料喝完了,他俩都喝了不到一半。这,看来的确是没那么好喝?至于纪念日,总得留下点东西,这砰的一声就挺好的,能记好几年。

等明年再到这时候,可能会比今年的印象深刻,就像多年前的愚人节,接到交警电话说自己车在路边挺着被撞了一样。原以为是玩笑,没想到是真的。

砰的一声,也算是给纪念日放了礼炮了。

The post 我们的纪念日 appeared first on obaby@mars.

投降?

2025年4月18日 10:23

上周的降温,最直接的结果就是自己被吹感冒了。天天流鼻涕🤧,昨晚睡觉的时候我跟对象说,我每天流鼻涕也能轻二两,助力了我的减肥事业。

对象回了我俩字:“恶心”。

最近这段时间,减肥似乎又停滞了。没什么下降的迹象,但是最近的运动量其实并没有下降。比较奇怪的是每天的生活路径跟之前是一样的,步数缺少了很多。做完结结束了 4200 个的跳绳之后,步数也只有 8000 多,的确让人有点匪夷所思。

可能是这十来天流鼻涕流的太多了,最开始的几天喝蒲地蓝口服液。喝了几天发现没什么好转,看了下说明书发现貌似并不治疗流鼻涕。

后面连天开始吃感康,然而,不知道是因为感冒问题,还是吃药导致的副作用,血氧饱和度在某一个时刻降到了 70。有时候竟然有些头晕,这尼玛就有些离谱了。吃了两天也果断放弃,后面几天就是硬扛着,每天用掉一包纸。好在这几天康复的差不多了,昨天上去想起来在按摩店办的会员卡,约了中午去做后背理疗。

中午回家吃点东西,也不知道该吃啥,早上还有剩下的一个玉米。抱着那个玉米啃了之后,直接开车去按摩,店门口虽然有位置,但是也不敢停。

停车位在马路牙子上,边上是水泥修的段斜坡。第一次来看上面一个车位上停了一辆奔驰 c200,想着它能上去,粉皮应该也可以。小心翼翼的往上尝试了一下,听到咔擦一声,就知道是蹭上去了。并不是真的我上我也行,转到路边,找个地方停下。这次路边竟然异常的火爆,没有任何的空闲位置,有转出去百十米才找到停车位。

按摩的时候,大姐说,这个后背可能会出痧没问题吧?

这个其实也在意料之内,出就出吧。其实每次按摩,最难熬的就是按摩师说自己有各种病。这次技师并不是前两次的那个,按的时候开始说自己的各种问题:脊柱有点侧弯,背部有的地方比较高,肝脏肾不好,有的地方有结节……

嗐,这些问题,也不是一天两天了。按到最后的时候,没那么用力了,就感觉很舒服,趴着差点睡着了。按的时候,技师还给后背拍了个照,按完给看了一下,其实也没什么好意外的,肯定是红彤彤的一片。

刚要走,收到一封邮件,华为开发者:

对于这种监管机制,真的挺头大的。主要是不知道该从哪里下手,也不知道该怎么下手。有时候,真的想,嗐,投降吧,何苦呢。

最近事情的确比较多,乱七八糟的搞得自己挺头大的。晚上回家,晚饭也不知道该吃啥,找了点零食对付了一下。

跳绳的时候,对象说;“明天老爸(Father in law)生日,还是继续海底捞。”

宝子说:“干嘛不早说啊,我可以提前画张贺卡啊。”

“现在也来的及,之前买了一些不是,直接写一张吧”我说。

现在聚餐,其实也没什么太多的好选的地方,一般就直接海底捞解决了。前段时间我在海底捞过生日的时候,遇到一个小朋友,特别喜欢唱生日歌,于是每桌唱歌的时候,他都要跟着一起唱,甚至还自带了道具。

有时候想,这种生活真的不错啊,可以做自己喜欢的事情。关键是父母能陪着一起玩,这才是生活该有的样子。

今天上午收到了 qq 邮箱的邮件,祝自己生日快乐。

哦吼,这都能凑到一天去,我的阳历,凑到了老爸的阴历上。这的确是巧合了,不然,可能自己都没注意今天是个什么日子。

白天的按摩可能的确管用吧,竟然一觉睡到了天亮,想再扛一会儿,也扛不住了。主要还是憋尿实在憋不住了,这件事情该投降就投降吧,硬抗也没什么好结果。

而至于其他的事情,投降?永不!

The post 投降? appeared first on obaby@mars.

南墙 WAF 系列(三)– API SDK

2025年4月16日 17:47

手里乱七八糟的域名实在是有点多,而这些域名,多数都解析到了同样的站点。或者说是回源是同样的站点,最开始其实并没有套 cdn,中间有段时间连这种 301 302 跳转都被打,就变得很尴尬。301 跳转都能让沙雕给打挂,也的确什么好办法了。

后来发现盾云的 scdn性价比的确不错,于是一股脑的全部套了 scdn,不过,有的也的确没什么流量,于是一些没那么重要的东西放哪里就有些浪费:

所以,思索再三,几天申请了一台 99 块钱的海外轻量,每个月 1t 的流量,感觉应该足够应付这些乱七八糟的服务了。当然,最主要的还是要套上南墙 waf,直接裸奔感觉也不大行。

当然,waf 后面的回源多数还是家里的服务器。这就需要有个工具来更新 waf 的回源地址,今天又完善了一下南墙的 api 接口,代码直接提交 github 的,有需要可以自取。

功能特性

 

  • 证书管理
    • 获取证书列表
    • 检查证书
    • 提交证书配置
    • 删除证书
  • 站点配置
    • 获取站点列表
    • 更新站点配置
  • 用户认证
    • 用户名密码登录
    • 支持双因素认证(OTP)

环境要求

 

  • Python 3.x
  • 必需的 Python 包:
    • requests
    • jwt
    • urllib3

安装说明

 

  1. 克隆仓库:
git clone https://github.com/obaby/baby-nanqiang-waf-api-toos.git 
cd baby-nanqiang-waf-api-toos
  1. 安装依赖包:
pip install -r requirements.txt

 

使用说明

基础用法

from baby_nanqiang_api_tools import NanQiangAPI

# 初始化 API 客户端
api = NanQiangAPI(base_url="https://lang.bi:443")

# 登录
result = api.login(username="your_username", password="your_password")
if result:
    print("登录成功")
    
    # 获取证书列表
    cert_list = api.get_cert_list()
    if cert_list:
        parsed_certs = api.parse_cert_list(cert_list)
        print("证书列表:", parsed_certs)
证书管理
# 从文件检查证书
cert_result = api.check_cert_from_files("cert.pem", "key.pem")
if cert_result:
    # 提交证书配置
    submit_result = api.submit_cert_config(cert_result)
    
# 删除证书
delete_result = api.delete_cert(cert_id=123)

站点配置

 

# 获取站点列表
site_list = api.get_site_list()
if site_list:
    parsed_sites = api.parse_site_list(site_list)
    print("站点列表:", parsed_sites)

# 更新站点配置
update_result = api.update_site_config(
    ip="192.168.1.1",
    port=443,
    site_id=123,
    uid=456,
    description="我的网站"
)

仓库地址:
https://github.com/obaby/baby-nanqiang-waf-api-tools

The post 南墙 WAF 系列(三)– API SDK appeared first on obaby@mars.

大风吹

2025年4月14日 10:53

周五宝子放学,老师在群里发布了大风预警的通知,让宝子们尽量不要外出。然而,周五晚上没有收到任何的班要停课的消息。十一点,夜已经静了,路上的车也变少了。今晚,破天换的没有渣土车的轰鸣声,让夜晚变得少有的宁静。

关灯之后,耳畔隐约传来了一点打在窗户上的声音。爬起来走到床边,窗户上已经密密麻麻的一层水珠,远处交通信号灯的红色灯光在经过水珠的折射之后,也变得氤氲起来。偶尔,有那么几个大雨点,打在金属的晾衣杆上发出清脆的金属撞击声。这或许才是夜本来的样子。

早上起床,与似乎没有停的样子,不知道是下了一夜,还是阵雨间歇。不过这早上的雨声,又变成了另外的样子,大风中裹挟着小冰雹,一片片的落下来,有的地方甚至出现了薄薄的一层冰雹粒。万幸的是,冰雹不算大,即使打在车上也会有什么损伤,如果真的有鸡蛋大小的话,那就该思考下怎么保护自己的车了。

天气愈发恶劣,然而,依然没有老师说要停课。看起来似乎只要天上不下刀子,这课就得去上。上午的钢琴课,宝子表现非常的差。清明假期,再加上最近两周确实没练琴,导致之前学的都忘了。一首谱子,最后能记住的只剩下了最后一段。要期中考试了,周末布置的作业也多了,下课回家,宝子想去小姨家。然而,这一堆作业都没做完,又怎么能让她去。

在一番“友好的”沟通之后,宝子气呼呼的躲进了自己的屋里,嘎巴一声把房门锁上了。我也懒得理她,就让她自己在里面呆着吧。不一会儿宝子的姥爷回来了,问为什么没看到孩子。“又绝交了,自己在屋里躲着呢”我答道。宝子姥爷小心翼翼的去门口敲门,好说歹说才把门给叫开。

一番折腾,时间已近中午。不想做饭也不知道该做什么,采用老办法外卖解决。下午的网球课依然没消息,不说停课,那就是要继续了。鉴于这种天气也着实不想让她去上课,果断给宝子请假了。请假之后下午的时间,似乎还该干点什么。搜了下附近的网球场,发现就在小区二期边上有一个带发球机的场地,价格也不算贵,优惠完 68 一小时。电话问了一下,下午场还能约上,定了下午三点的时间。

吃完饭,看到教练在群里发的消息,训练赚到了小学的室内场地。这课的确是非得上不行,不过既然请假了,也就没什么必要去了。饭后,宝子去写作业,自己去眯了一会儿。上午出去的时候似乎穿的太少了,回来之后就开始流鼻涕。这一风给吹感冒了,也是让人绝望。

下午迷迷糊糊的被叫起来,说快三点了,这才记起来还要继续去打球的。简单收拾下,开车过去倒是也快。三点准时到了球场。老板给调整好速度、正反手,然后就开始了。

一轮发球下来,自己看了下时间大约 8 分钟左右,不过发球机发出来的球速度比自己发的要快一些。之前跟宝子练球的时候,为了让球好接,球速并没有太快,现在发球机的速度的确会快一些。如果要将球打过网,需要发的力也更多一些。

两个人轮流接发球,还能稍微缓一缓,一轮球打下来。出的力气明显比对打要高很多,原本想着第二天继续去的。周日早上一睁眼发现已经八点多了,而宝子这个点了还没醒,又过了一个小时才醒。看来这一个小时的发球机训练强度的确是够的,原来自己就手腕有点疼,现在手腕感不到疼了,小手臂开始疼,大手臂也跟着疼,看来这才是全身运动。

自然,周日的打球训练也只得作罢。鼻涕流的越来越严重了,找了一盒蒲地蓝口服液喝了两瓶,的确难喝,相比三九那种甜甜的口感,蒲地蓝可以说是喝过的最难喝的药水了。

到了晚上依然没有好转的迹象,晚上睡觉前继续三九+蒲地蓝。可能还是以为三九的助眠作用吧,晚上睡得还是挺沉的,不过可能是晚上睡觉之前看了一道奥数的竞赛题讲解,做梦做了一晚的题。不过黑板上的题目,自己绞尽脑汁也没算出来,而老师还在不断的找人上黑板解题。

正在自己想怎么躲过被抽到的命运的时候,老师走到了身边,问:“通过这个题目,你还发现了什么?”

我看着自己的书上的答案,慢吞吞的答道:“发现了外生生物,还有一些不合常理的东西……”

“你看下这个图,”老师指着自己的笔记本说道:“这些东西发现了吗?”

我扭头看向他的笔记本,上面画了几个小人,只是,小人的形状都比较奇怪,一个像人民大学的 logo,另外一个,两个外星人把一个女人夹在中间,跟三明治一样,让我想到了自己很多年前玩的人体俄罗斯方块。

“3P?”我问。

“是的,外形繁殖就是用这种方式的……”老师解释到。

这是哪门子繁殖方式,不是,为什么要用这么诡异的姿势呢。正思考着,一阵阵尿意袭来,再也憋不住了,不然就该尿床了,赶紧爬起来上厕所。

回来之后总算是放松了不少,看来这四月的一阵风把自己给吹出毛病来了。脑子里装的乱七八糟的东西,都被这一阵风搅和到一起了。

用华佗的话说,叫做“风涎入脑”,唯有开颅以治之?

The post 大风吹 appeared first on obaby@mars.

白嫖百度网盘超级会员和7T空间

2025年4月13日 19:07

前几天看到文案姐姐发的这篇文章,尝试白嫖了一下百度网盘的vip。的确是可以白嫖成功的,不过白嫖的过程中需要准备一些材料,并不是直接就能白嫖到的。当然,多数能访问到我的博客的基本都具备这个条件,在申请的过程中需要提供自己的渠道信息。

渠道可以是:博客,微博,B站等等,所以在白嫖之前需要有相关的自媒体账号或者平台才能申请。

这件事情本质上是申请的推广联盟的账号,联盟提供svip和空间扩容。所以,继续之前,请先了解上面的信息哈,免得最后落差感太大。

这个东西本质上是推广来获取权益,也可以挂着看能不能获取到一些推广费用:

发放规则:
会员/空间权益根据推广渠道网盘账号官方自动发放会员权益以及扩容空间,(达到条件自动发放,不用找平台申请)
发放时间:权益目前是每天发1次,报备通过后在第二个工作日下午18:00点左右会发完
* SVIP权益
* 首次签约权益: 赠SVIP14天,拉新收益大于50元,可再赠送14天;
* 30天内转存收益达600元:赠SVIP季卡,每个账号一个季度限领一次;
* 30天内转存收益达1500元:赠SVIP年卡,每个账号一年限领一次;
* 30天内转存收益达3000元:赠40TB/季度,每个账号一季度限领一次;

* 空间权益:
* 7天内转存收益达6元,赠10TB/月,每个账号限1次/月
* 30天内转存收益达300元:赠20TB/月,每个账号限1次/月
* 30天内转存收益达1000元:赠20TB/季度,每个账号限1次/季度
* 首次累计拉新人数超10人,自动发放扩容20TB/月;
* 累计拉新人数超过100人,自动发放扩容20TB/季度;
* 累计拉新人数超过300人,自动发放扩容40TB/季度;
* 累计拉新人数超过1000人,自动发放扩容80TB/年。
具体拉新人数要求 会根据数据项目单价上下浮动。


会员权益发放调整通知:

自2024年12月5日起,签约报备成功的网盘账号 14天SVIP会员发放延迟T+1发放,遇周末节假日顺延。

 

最终白嫖效果:

vip有效期大约十几天,至于空间的有效期目前不清楚,我也不知道从哪里看网盘容量的有效期。

如果感兴趣可以开始下面的流程了,开通之后,用这十几天狂下资源还是可以的。

第一步:

登录百度网盘账号(【注意】一定要使用百度网盘app

第二步:

获取UK码

用微信或下载登录百度网盘app

点链接:https://snsyun.baidu.com/sl/j6fEY

进行渠道关系绑定(如果出现无法参与/绑定失败、则需换在重新注册一个网盘账号扫码绑定。)

第三步:

复制UK码+绑定成功截图,在任推邦【申请推广码】处填写报备信息,审核通过后即可推广。
温馨提示:BD联盟是平台机构名称,请复制UK填写报备UK号码,报备UK填错将影响您的结算

第四步:

点击(任推帮平台https://dt.bd.cn/)手机注册登录 

邀请码:4301575

第五步:

点击这个链接,申请推广百度网盘:https://dt.bd.cn/#/pages/index/components/detail?appId=649&invite_code=4301575

申请的时候,需要进行实名认证,添加渠道等一系列操作。

渠道可以写自己的博客,微博等信息,需要提供屏幕截图,管理后台截图等一系列信息。

第六步:

填写刚刚第三步获取的绑定码和截图!

点击申请就可以了。审核时间一般当天能过,而至于网盘容量和svip是第二天下午六点之前完成充值。

耐心等待吧,如果审核不通过新注册个百度网盘账号尝试。

 

The post 白嫖百度网盘超级会员和7T空间 appeared first on obaby@mars.

虎背熊腰

2025年4月10日 10:55

在清明假期之前,就约了这次的外景拍摄。过完年之后,气温忽高忽低跟过山车一样,厚衣服刚收起来,结果一阵寒潮袭来温度又到了 0 度。

一次次的波动之下,也不想再把厚衣服拿出来,就这几天倒是也好挨,就那么熬过去了。青岛四月的天气,至于暖和不暖和其实自己心里也没谱。不过好在,清明假期之后,天气真的开始暖和了,即使在外面穿短袖感觉也不会冷。

虽然,目前看起来之后不到二十度,中午出去即使光腿穿裙子也不会感觉到冷。当然,最主要的是现在穿裙子的太少,这时候穿裙子出去拍照也的确是显眼包无疑了。

 

早上换好衣服出门,为了让腿上的皮肤感觉更细一点,穿了条肉色的丝袜,结果开门拿东西的时候,让路边绿化带的树枝子直接给刮破了,出现了两个口子。好在现在也不是非得穿的那么整齐才行,有个破洞就有个吧,也没什么要紧的。出发之前,选了几双鞋子,每到换季的时候,总是要来回折腾,这次折腾出来的鞋子,其实就是觉得很好看,但是却不会穿出去的那种,在鞋柜里都放了很久很久,从来都没穿过,以后也不会穿出去,其实有时候感觉挺奇怪的,就是看别人的大长腿,穿什么鞋子都好看,还能让腿更长,但是自己却不行,主要也是没啥资本。

这次果断从鞋柜里拿出来,最后,扔到了回收柜里。毕竟,以后也不会穿他们。

虽然约的是十点,早上稍微一折腾也就到了这个点了。十点稍微多一点到工作室,化妆师小姐姐见面第一句话就是,“感觉你又瘦了哎”

听到这句话真的是让人开心,化妆的时候,摄影师也到了,也说感觉自己瘦了,小姐姐又补充道,感觉也更白了。

 

其实白倒是没怎么感觉,不过稍微能感觉到的还是应该瘦了那么一点点。等化好妆选好衣服,从工作室出门的时候已经十一点半了。至于去哪里拍其实也没啥太多的想法,主要是想拍点公路片的效果,刚开始提议去红岛的祥茂河公园,虽然不大,但是公园里面能把车开进去,另外一侧是河,也可以拍点河边的景色。

既然是公路片效果,摄影师建议不如直接去红岛的星河湾,一边是公路车也不多,另外近海边,有一点沙滩,正好可以拍几张海景。从工作室到海边的路异常的难走,可能这段路大车比较多,一路上坑坑洼洼,路中间的井盖子已经成了一个深井的样子,井盖子顶距离路面大约有十几公分,形成了一个个的炮弹坑,在这种路上开车的确有点不自信,一路蛇皮走位总算是通过了那几公里。

路边停了几辆车,有人躺在车上耍手机,有人坐在海边的凉亭下面聊天。

选的几套衣服,一条白色的裙子,一条黑色的短裙还有一条黑色抹胸长裙。白色的裙子比较宽松一些,两条黑色的裙子,穿起来稍微有点紧,如果自己最近没努力减肥的话应该也就穿不进去了。

拍照的时候,坐在凉亭里的大爷在交流。

“以前拍照的时候,还得用相机,对焦,快门什么的,现在好啊,直接手机就搞定了……”一个大爷说。

“是啊,你看现在多方便,手机,相机都行,这还有专门的摄影师……”另外一个大爷附和道。

拍照的时候,工作室主播小姐姐有些无聊,去扫码骑了一辆电动车来回跑,说一块五,找到了无穷的乐趣。

换好第三套衣服,去沙滩拍照。我穿着高跟鞋在沙滩上走,化妆师小姐姐喊,好厉害,高跟鞋在沙滩都走的这么稳。直播小姐姐也停好车跟了下来,蹲在地上玩沙子。

又过了几分钟,直播小姐姐从台阶上跑下来说,自己的电动车不见了。

想来是 有人看到电动车没锁,直接给骑走了。说能看到定位有好几公里,但是也找不到。这的确就比较麻烦了,到最后拍完走的时候也没见到电动车,只能花了 15 块钱,强制换车了。

看来,这一块五的快乐,最终快乐的价格也稍微贵了那么一点。

等这一切全部忙活了已经是一点半了。时间过得的确快,在台阶上拍照的时候,打扫卫生的阿姨就那么一直坐在那里看,似乎在想什么,就那么静静看着,直到在台阶上的照片全部拍完,她才转身离开,或许也在想自己年轻的时候吧,只是感觉自己现在也不年轻了。虽然不到 20 度的气温,中午的太阳异常的耀眼,一个多小时下来,身上已经微微出汗了。

回到车上,打开空调,感觉稍微舒服了一点。衣服也就不换了,但是为了开车,高跟鞋还是换掉了,毕竟,那个鞋子真的开不了车。

只是,这一天下来中午都没吃饭,晚上称体重的时候,昨天竟然比前天还沉了 500g,这就尼玛离谱。

减肥,毕竟是个持久战,还得继续。

The post 虎背熊腰 appeared first on obaby@mars.

Vidda(海信)电视安装第三方应用

2025年4月8日 13:27

每次电视第一次到手里,首要的事情就是安装 app。有两个是必须的:ds file 和 vlc 播放器。这两个的组合就解决了 nas 上影片播放的问题,至于为什么不用 nas 自带的影音系统,主要也是两个原因:1.需要安装解码器,然而每次安装都很麻烦,实际时候用效果也并不好;2.很多电影就看一次就行了,也不需要所谓的海报啊,简介之类的东西,看完就删掉了。

以前的时候,总感觉很多影片要留下来以后跟别人一起看。然而,现在更多的时候下载的电影自己看完了就删除了,甚至都没有保留的必要,甚至再也不会打开。

更离谱的事情在于,如果不删除这个影片,过一段时间之后再看到这不影片就会陷入怀疑,看过没有?看了一半之后才发现,哦,原来看过了。老了,这个记忆力真的不行了。现在每看完一部影片就会在豆瓣上标记一下,以后再看到的时候回去观影记录搜索一下,这样就不会再重新看了。

※观影记录/Movies※

以前的电视可以通过修改 apk 扩展名为 dat,让电视自带的资源管理器显示这个文件,打开方式选择安装器就行了,然而,现在却不行了。虽然 u 盘不可以了,但是 Hi 投屏还是可以传送文件的的。

打开电视的Hi 投屏:

切换到最后一项海信爱家 app,进入:

此时会出现个文件投屏,需要在点击一下,在这里是不能传送的。

进入接收界面就可以了,打开手机上的海信爱家 app:

点击文件,进入文件传输功能:

找到 apk 下面对应的安装包发送,在电视上就能接收了。接收完会自动进入安装界面。

安装完成就可以用啦。整体体验感觉还是可以的,并不会比用 u 盘差,说到 u 盘,忽然发现自己钥匙串上的 u 盘不知道什么时候丢了。

The post Vidda(海信)电视安装第三方应用 appeared first on obaby@mars.

虚无缥缈的 Hello Kitty

2025年4月7日 10:50

当时那个hello kitty离我近了 40公分,但是二分之一柱香之后,导航信号会彻底消失。 因为一边充电,一边导航,把 gps 芯片直接干歇菜了。

就在几天天,车机系统提示可以升级新版本,对于我这种喜欢跟着新版本跑的人,自然是毫不犹豫的就升级了。不得不说,这次升级体验的确提升了不少,最起码那个 pin 码总算有用了,不用每次都输入这个十几位的密码了。

其实,清明原本就没什么计划,至于去哪里没有提前规划。想要出去玩也似乎没什么方便去的地方,济南已经买不到高铁票了,至于开车去,其实是不大想去的,毕竟济南的交通状况,可能真的让人抓狂。规划了那么久,其实没问宝子的意思,当问她要不要回老家跟姐姐玩的时候,毫不犹豫的就答应了。

回家的时候顺便还得带着宝子的小姨,给送回县城。就这样,第一天的行程就算是计划好了。早上起床的时候也没有很晚,稍微收拾下就出发了。把宝子的安全座椅从大白搬到粉皮上,一切收拾好就出发了。开导航的时候发现仪表盘的导航面板现在可以显示导航地图了,这个升级的确不错啊。于是导航路线显示在仪表盘上,中控屏显示路线概览,真的不错唉。

然鹅,设置的时候🈶多开心,后面就会与多后悔。这一切看似非常人性化的体验升级,带来的是自己多跑了一百公里的代价。其实车子上了环湾过了跨海之后就开始提示信号弱,然后说什么开启北斗定位模式。这种情况之前也遇到过,想着应该没什么大问题,就继续前进了。

然而,在开了数十公里,经过了无数的拥堵路段之后,才感觉可能是跑错路了。

在跑完第一段 37km 之后,就已经完全没有 gps 信号了,完全是跟着路瞎跑。直到后来某个时间,宝子说,你看,那个是潍坊的出口。我心想,导航也没提示,应该不是走那个口吧,继续往前开,进入另外一段用户路段之后导航提示六公里右转,驶出当前高速。自己又开了三公里,然而导航地图没变的时候才发现可能真的是错过了无数个出口。

在看了下导航的额 hello kitty 已经变成了灰色,虚无缥缈的样子,这时候才发现问题严重了。把手机从无限充电的底座上拿下来,递给宝子的小姨,让她重新设置目的地。

“你手机怎么这么卡?”她说道,“点都点不动”

“不应该啊,之前不卡啊”我答道。

终于在他折腾了半天之后,算是重新上路了。原本是为了躲过 g20 的拥堵路段,结果绕着环湾跑了一圈,出门的时候两个小时,现在走了一个半小时了还是两个小时,直接麻了。

好在换了高速之后,路况好了不少,一路狂奔下来,终于在十二点之前到了县城。中午简单吃点东西,下午就回村里了。过节的时候,村里稍微热闹了一点,河里的水已经融化,有孩子在河边打水漂。

其实村里并没有太多的娱乐项目,回到村里。总是要带孩子去地里转悠转悠,挖野菜,或者纯粹就是溜达。野菜正好就可以带回家喂兔子,不过这次回家,并没有见到那个小傻狗。后来才知道是跑丢了,农村,丢狗变成了再正常不过的事情,一条狗,养着养着就不见了。

这三月的地里依然没有太多绿意,尽显黄土的本色,阡陌之上只剩下野草被焚烧过后留下的满目的黑灰。

在这灰烬之下,依然有野草顽强的冒出头,努力的生长。

“野火烧不尽,春风吹又生”

说是挖野菜,主要还是带孩子玩,现在自己很多野菜都不认识了。毕竟,似乎已经离开这块土地太久太久,不知道是野菜变了,还是自己变了。

看着地理的麦蒿,我拔了一些,做了一顶草帽,戴在头上,宝子说:“gang(三声)傻”(很傻)。我想套到他的头上,她死活不让,随后给了二姐。

荠菜早已过了最好的时间,已经开满了白花。目前最多的就是苦菜花,二姐说挖回去蘸酱吃。

“我才不吃来,冒苦”我说,其实我从来就不喜欢吃苦的东西,苦菜花,苦瓜,我都不喜欢。

短短个把小时,就挖满了满满的两个大号方便袋。这兔子未来几天的饭算是有了着落了。

晚上吃过晚饭,合计第二天去哪里,就在这时候看到对象发的消息说电视可能坏了。

这的确挺奇怪的,京东找了下订单,发过去问了余下,说可能是收到了伤害。

这,既然是外伤,并且已经过保,想免费修是不可能了。问了下换屏多少钱,得到的答复也真的不错。

以前六百块钱,这价格的确让人难绷,自己买的时候是 2600,这个 2000 是最后下架之前的价格。

既然如此就不如换新的了,二手东搜索了一下 vidda 的 65 寸现在 2200,算上国补,到手大约 1800。就这个价格,让自己怎么能有维修的心?既然如此就果断换新吧,旧电视走回收评估了一下,55 块钱。哈,我的破键盘还回收了 110 呢。

就在不就之后,找到了罪魁祸首,挂在右侧柜子上的一个铁架子,之前是要扔掉的,家里老人不舍得,就给挂到了柜子上面,也没有任何的固定,终于昨天掉下来了,就这样一下子砸没了两千块钱。

该直接扔掉的,大意了。

一番合计之后决定去诸城动物园,据说比潍坊的还要大一些。第二天一早简单吃点东西,八点就出发了。这动物园不得不说,开门是真早啊,七点半就开园了。九点半到了停车场之后比较近的位置已经停满了,只能继续往里走,好在里面树林里还是空着的,没有停车位,只能找两排树中间的位置停进去。

说是很大的动物园,其实人比动物多多了。入口是租电瓶车的地方,在入园之后电瓶车就开始堵车了。一路游览下来说不上有特色,就那些动物园常见的动物。只是最后一段让人颇为抑郁,周边没有任何动物,沿着河一直走,全程下来大约三公里没有任何风景,就这么溜达。九曲十八弯,不过边上的游乐设施不少,看到有人在玩滑道,宝子说自己也要去玩。

游乐场是单独收费的,并且我也是没有任何力气了。跟宝子商量,要不算了吧,回家之后我给搭一个,就酱紫把宝子给劝走了。

中午找地方吃饭,算是吃到了诸城烧肉,其实说就是烧猪肉头,不过这种做法,的确有不一样的感觉,吃起来味道还是蛮不错的。

也算是诸城特色美食了。

回家路上,顺路去五金店把绳子和滑轮买了。

买滑轮的时候老板问,你买多少吨的?

“多少吨?我就能承担一个孩子的重量就行了”我答道。

老板给找了个最小的承受 3 吨,35 块钱,剩下的就是买绳子,尼龙绳子七块钱一米,买了四十米。这样算是齐全了,剩下的就是在家里找地方把东西给搭建起来。一番忙活之后终于 ok 了。

一侧是门框,另外一侧是墙,承担二三十公斤的重量是完全没问题的。

就这样一个简单的滑道就算是完成了,最起码不用一直排队了。晚上吃过晚饭,宝子表示还想玩,于是打开外面所有的灯,看着她和她姐姐继续在那里玩。宝子可以自己骑上去,她姐姐去不行,需要自己在那里扶着。玩玩具还需要一个服务员,关键是服务员左手手腕还有点疼。

这一天下来,竟然走了两万多步,也第二次完成了 400% 的锻炼目标,不过多运动也好吧,毕竟这两天吃的也的确有点多。

第二天早上一早,宝子的奶奶就把自己搭的架子拆掉了,二姐说,也就是你弄的,要是别人把这个东西栓门框上,早就和你没完了。

剩下几个比较高的地方,自己也给拆掉了。也是昨天玩的太累了,早上快八点了,宝子还没起床,把他叫起来。吃点东西,再玩一会儿九点多就该回青岛了,毕竟还有些作业没做,周一的升旗仪式的主持词还得背一下。

这次,再也没敢把 hello kitty 放到中控屏上,因为这几天发现,自己的 iphone 13p,同时渲染两个屏幕,并且充电就会导致手机温度过高丢失 gps 信号。要么扒手机壳,不充电使用两个屏幕,要么直接使用中控单屏幕,即使带着手机壳充电问题也不大。

回程的路上,上午路况还算不错。

“那个 kitty 变成灰色的时候,就变成扁的了”宝子说道,“我给你看着中间的 kitty 如果她变成扁的了,我就告诉你”

“好的,不过这边路比较熟悉,变成扁的也不要紧,你可以不用一直盯着”我说道。

就在这时候,我看到左侧车道宝子小姨的车,“你小姨在左边,你给她打个电话呗”

宝子拨通之后提示正在通话,这时候车机电话响了,接起来就听到她小姨说:“看到你了,疯狂超车”

“我要赶紧去服务区上厕所,早上喝水喝多了”,简单说了几句挂掉电话也就到了服务区了。稍微休息一下,买个饮料继续出发。

到家的时候,电视早就送到了,对象说送电视的说架子太小,承担不住。其实我觉得是足够的,不过还是买了另外一个架子,安装需要用冲击钻,只能等海信的上门安装。终于晚上七点左右过来安装了。

其实新买的架子,质感反而不如之前的,只是感觉大了一些而已。由于现在壁挂电视的安装点都在上面,原来的支架高都不合适,只能重新打孔。一段折腾之后总算是撞上了。为此又付出 170 块钱的安装费。

到现在自己挣的 4000 块钱的外快算是彻底花没了,过完家里不能放现金,应该早就花掉的。换了电视之后,给老太太包了一千红包,再加上出去玩的费用,其实都不止 4000,不过最后老太太没要红包,说要不她给我点,这我自然是不能要的。老太太没收的红包,就打算给大白换轮胎了。上午问了下一条轮胎 440,这下四条轮胎下来,一分钱没剩,都没了。

这 4000 块钱外快,感觉啥也没干,就这么虚无缥缈的就没了。

The post 虚无缥缈的 Hello Kitty appeared first on obaby@mars.

南墙 WAF 系列(二)– 网站证书自动更新

2025年4月2日 14:48

相对管理后台的 ssl来说,其实网站的 ssl 证书才是正事,毕竟这个关系到网站的访问。按照官方的说法在开放 80 端口的情况下,南墙可以自动申请更新证书,不过后台没找到配置的地方,我的 v4 的 80 也是不通的,所以就需要自己去维护管理证书了。

然而,上午在问了管理之后,得到的答复是没有 api,可以自己抓包进行修改。

嗐,这么看来其实也没啥,最起码说明后台的 api 接口是可以直接拿来用的。即使是有 api 文档,也是得自己去看,去写,没有的话 curl 抓包一样能解决问题。按照之前的方法,只直接复制 curl 给 cursor 就可以了。

api 文件baby_nanqiang_api_tools.py内容:

#!/usr/bin/env python3
import requests
import json
import jwt
from datetime import datetime
import os
import urllib3

# 禁用 SSL 验证警告
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

class NanQiangAPI:
    def __init__(self, base_url="https://lang.bi:443"):
        self.base_url = base_url
        self.session = requests.Session()
        self.session.verify = False  # 忽略SSL证书验证
        self.token = None
        self._setup_headers()

    def _setup_headers(self):
        """设置请求头"""
        self.headers = {
            'accept': 'application/json, text/plain, */*',
            'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
            'cache-control': 'no-cache',
            'content-type': 'application/json',
            'origin': self.base_url,
            'pragma': 'no-cache',
            'priority': 'u=1, i',
            'referer': f'{self.base_url}/',
            'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Google Chrome";v="134"',
            'sec-ch-ua-mobile': '?0',
            'sec-ch-ua-platform': '"macOS"',
            'sec-fetch-dest': 'empty',
            'sec-fetch-mode': 'cors',
            'sec-fetch-site': 'same-origin',
            'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36'
        }

    def _update_headers_with_token(self):
        """更新请求头,添加token"""
        if self.token:
            self.headers['Authorization'] = self.token  # 直接使用token,不添加'Bearer '前缀

    def delete_cert(self, cert_id):
        """
        删除指定ID的证书
        :param cert_id: 证书ID
        :return: 删除结果
        """
        if not self.is_logged_in():
            print("请先登录")
            return None

        url = f"{self.base_url}/api/v1/certs/{cert_id}"

        try:
            response = self.session.delete(
                url,
                headers=self.headers
            )
            
            response_data = response.json()
            
            if 'err' in response_data:
                print(f"删除证书失败: {response_data['err']}")
                return None
            
            # 检查删除是否成功
            if response_data.get('result') == 'success' and response_data.get('RowsAffected') > 0:
                print(f"证书 {cert_id} 删除成功")
                return True
            else:
                print(f"证书 {cert_id} 删除失败: 未找到证书或删除操作未生效")
                return False
            
        except requests.exceptions.RequestException as e:
            print(f"删除证书请求失败: {str(e)}")
            return None
        except json.JSONDecodeError as e:
            print(f"解析响应数据失败: {str(e)}")
            return None

    def parse_cert_list(self, cert_list):
        """
        解析证书列表数据
        :param cert_list: 证书列表数据
        :return: 解析后的证书信息列表
        """
        if not cert_list:
            return None

        parsed_certs = []
        for cert in cert_list:
            try:
                # 解析SNI字段(JSON字符串)
                sni_list = json.loads(cert.get('sni', '[]'))
                
                parsed_cert = {
                    'id': cert.get('id'),
                    'sni': sni_list,
                    'expire_time': cert.get('expire_time'),
                    'update_time': cert.get('update_time')
                }
                parsed_certs.append(parsed_cert)
            except json.JSONDecodeError as e:
                print(f"解析SNI字段失败: {str(e)}")
                continue
            except Exception as e:
                print(f"解析证书数据失败: {str(e)}")
                continue

        return parsed_certs

    def get_cert_list(self):
        """
        获取证书列表
        :return: 证书列表
        """
        if not self.is_logged_in():
            print("请先登录")
            return None

        url = f"{self.base_url}/api/v1/certs/"

        try:
            response = self.session.get(
                url,
                headers=self.headers
            )
            
            response_data = response.json()
            
            if 'err' in response_data:
                print(f"获取证书列表失败: {response_data['err']}")
                return None
                
            return response_data
            
        except requests.exceptions.RequestException as e:
            print(f"获取证书列表请求失败: {str(e)}")
            return None
        except json.JSONDecodeError as e:
            print(f"解析响应数据失败: {str(e)}")
            return None

    def login(self, username, password, otp=""):
        """
        登录接口
        :param username: 用户名
        :param password: 密码
        :param otp: 双因素认证码(可选)
        :return: 登录响应
        """
        url = f"{self.base_url}/api/v1/users/login"
        data = {
            "usr": username,
            "pwd": password,
            "otp": otp
        }

        try:
            response = self.session.post(
                url,
                headers=self.headers,
                json=data
            )
            
            # 获取响应数据
            response_data = response.json()
            
            # 检查是否有错误信息
            if 'err' in response_data:
                print(f"登录失败: {response_data['err']}")
                return None
            
            # 保存token
            if 'token' in response_data:
                self.token = response_data['token']
                self._update_headers_with_token()
                
                # # 解析token信息
                # try:
                #     # 使用 jwt.decode 替代 jwt.decode_complete
                #     token_data = jwt.decode(self.token, options={"verify_signature": False})
                #     exp_timestamp = token_data.get('exp')
                #     if exp_timestamp:
                #         exp_date = datetime.fromtimestamp(exp_timestamp)
                #         print(f"Token 有效期至: {exp_date}")
                # except Exception as e:
                #     print(f"无法解析token信息: {str(e)}")
                
            return response_data
            
        except requests.exceptions.RequestException as e:
            print(f"登录请求失败: {str(e)}")
            return None
        except json.JSONDecodeError as e:
            print(f"解析响应数据失败: {str(e)}")
            return None

    def check_cert(self, cert_content, key_content, mode=0):
        """
        检查证书
        :param cert_content: 证书内容
        :param key_content: 私钥内容
        :param mode: 模式,默认为0
        :return: 检查结果
        """
        if not self.is_logged_in():
            print("请先登录")
            return None

        url = f"{self.base_url}/api/v1/certs/check"
        
        # 准备multipart/form-data数据
        files = {
            'mode': (None, str(mode)),
            'cert': (None, cert_content),
            'key': (None, key_content)
        }

        try:
            # 临时移除content-type,让requests自动设置
            headers = self.headers.copy()
            headers.pop('content-type', None)
            
            response = self.session.post(
                url,
                headers=headers,
                files=files
            )
            
            response_data = response.json()
            
            if 'err' in response_data:
                print(f"证书检查失败: {response_data['err']}")
                return None
                
            return response_data
            
        except requests.exceptions.RequestException as e:
            print(f"证书检查请求失败: {str(e)}")
            return None
        except json.JSONDecodeError as e:
            print(f"解析响应数据失败: {str(e)}")
            return None

    def check_cert_from_files(self, cert_file_path, key_file_path, mode=0):
        """
        从文件检查证书
        :param cert_file_path: 证书文件路径
        :param key_file_path: 私钥文件路径
        :param mode: 模式,默认为0
        :return: 检查结果
        """
        try:
            with open(cert_file_path, 'r') as f:
                cert_content = f.read()
            with open(key_file_path, 'r') as f:
                key_content = f.read()
                
            return self.check_cert(cert_content, key_content, mode)
            
        except FileNotFoundError as e:
            print(f"文件不存在: {str(e)}")
            return None
        except Exception as e:
            print(f"读取文件失败: {str(e)}")
            return None

    def submit_cert_config(self, check_result):
        """
        提交证书配置
        :param check_result: 证书检查的结果数据
        :return: 提交结果
        """
        if not self.is_logged_in():
            print("请先登录")
            return None

        if not check_result:
            print("无效的证书检查结果")
            return None

        url = f"{self.base_url}/api/v1/certs/config"
        
        # 准备提交数据
        data = {
            "id": check_result.get("id", 0),
            "sni": check_result.get("sni", "[]"),
            "cert": check_result.get("cert", ""),
            "key": check_result.get("key", ""),
            "expire_time": check_result.get("expire_time", ""),
            "update_time": check_result.get("update_time", "")
        }

        try:
            response = self.session.post(
                url,
                headers=self.headers,
                json=data
            )
            
            response_data = response.json()
            
            if 'err' in response_data:
                print(f"证书配置提交失败: {response_data['err']}")
                return None
                
            return response_data
            
        except requests.exceptions.RequestException as e:
            print(f"证书配置提交请求失败: {str(e)}")
            return None
        except json.JSONDecodeError as e:
            print(f"解析响应数据失败: {str(e)}")
            return None

    def is_logged_in(self):
        """
        检查是否已登录
        :return: bool
        """
        return self.token is not None

def main():
    # 使用示例
    api = NanQiangAPI()
    
    # 登录信息
    username = "obaby"
    password = "obaby@mars"
    
    # 执行登录
    result = api.login(username, password)
    
    if result:
        print("登录成功:")
        print(json.dumps(result, indent=2, ensure_ascii=False))
        print(f"Token: {api.token}")
        
        # 获取证书列表
        cert_list = api.get_cert_list()
        if cert_list:
            # 解析证书列表
            parsed_certs = api.parse_cert_list(cert_list)
            if parsed_certs:
                print("解析后的证书列表:")
                print(json.dumps(parsed_certs, indent=2, ensure_ascii=False))
                
                # # 删除证书示例
                # cert_id = 4  # 要删除的证书ID
                # delete_result = api.delete_cert(cert_id)
                # if delete_result:
                #     print(f"证书 {cert_id} 删除成功")
                # else:
                #     print(f"证书 {cert_id} 删除失败")
        
        # 证书检查示例
        cert_file = "path/to/cert.pem"
        key_file = "path/to/key.pem"
        
        if os.path.exists(cert_file) and os.path.exists(key_file):
            return
            # 先检查证书
            cert_result = api.check_cert_from_files(cert_file, key_file)
            if cert_result:
                print("证书检查结果:")
                print(json.dumps(cert_result, indent=2, ensure_ascii=False))
                
                # 提交证书配置
                submit_result = api.submit_cert_config(cert_result)
                if submit_result:
                    print("证书配置提交成功:")
                    print(json.dumps(submit_result, indent=2, ensure_ascii=False))
                else:
                    print("证书配置提交失败")
    else:
        print("登录失败")

if __name__ == "__main__":
    main()

账号不要设置动态密码,如果设置了,那就创建一个新账号。

获取证书的脚本参考上一篇文章,对应的路径自己调整。更新证书的代码site_cert_auto_update_tool.py:

#!/usr/bin/env python3
import os
import subprocess
import hashlib
import json
from datetime import datetime
import logging
from baby_nanqiang_api_tools import NanQiangAPI

# Configuration
CERT_SOURCE_DIR = "/root/.acme.sh/h4ck.org.cn_ecc"
CERT_FILE = "fullchain.cer"
KEY_FILE = "h4ck.org.cn.key"
HASH_FILE = "web_cert_hash.json"
CERT_SCRIPT = "get_web_cert.sh"

def setup_logging():
    """设置日志"""
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(levelname)s - %(message)s',
        handlers=[
            logging.FileHandler('web_cert_update.log'),
            logging.StreamHandler()
        ]
    )

def get_file_hash(file_path):
    """计算文件的SHA-256哈希值"""
    sha256_hash = hashlib.sha256()
    with open(file_path, "rb") as f:
        for byte_block in iter(lambda: f.read(4096), b""):
            sha256_hash.update(byte_block)
    return sha256_hash.hexdigest()

def save_cert_hash(cert_hash, key_hash):
    """保存证书和私钥的哈希值到JSON文件"""
    with open(HASH_FILE, 'w') as f:
        json.dump({
            'cert_hash': cert_hash,
            'key_hash': key_hash
        }, f)

def load_cert_hash():
    """从JSON文件加载证书和私钥的哈希值"""
    try:
        with open(HASH_FILE, 'r') as f:
            data = json.load(f)
            return data.get('cert_hash'), data.get('key_hash')
    except (FileNotFoundError, json.JSONDecodeError):
        return None, None

def run_get_cert_script(script_path=None):
    """
    执行获取证书的脚本
    :param script_path: 脚本路径,如果为None则使用默认的get_web_cert.sh
    :return: bool 是否执行成功
    """
    try:
        # 如果没有指定脚本路径,使用默认的get_web_cert.sh
        if script_path is None:
            script_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), CERT_SCRIPT)
        
        # 检查脚本是否存在
        if not os.path.exists(script_path):
            logging.error(f"错误: 脚本文件 {script_path} 不存在")
            return False
            
        # 检查脚本是否可执行
        if not os.access(script_path, os.X_OK):
            logging.error(f"错误: 脚本文件 {script_path} 没有执行权限")
            return False
            
        # 执行脚本
        result = subprocess.run(['sh', script_path], 
                              capture_output=True, 
                              text=True)
        
        # 检查执行结果
        if result.returncode == 0:
            logging.info("证书获取脚本执行成功")
            if result.stdout:
                logging.info("脚本输出:\n%s", result.stdout)
            return True
        else:
            logging.error(f"证书获取脚本执行异常,返回码: {result.returncode}")
            if result.stderr:
                logging.error("异常输出:\n%s", result.stderr)
            return True
            
    except Exception as e:
        logging.error(f"执行证书获取脚本时发生错误: {str(e)}")
        return False

def read_file_content(file_path):
    """读取文件内容"""
    try:
        with open(file_path, 'r') as f:
            return f.read()
    except Exception as e:
        logging.error(f"读取文件 {file_path} 失败: {str(e)}")
        return None

def is_cert_expired(expire_time_str):
    """
    检查证书是否过期或即将过期(7天内)
    :param expire_time_str: 过期时间字符串
    :return: bool 是否过期或即将过期
    """
    try:
        expire_time = datetime.strptime(expire_time_str, "%Y-%m-%d %H:%M:%S")
        now = datetime.now()
        days_until_expire = (expire_time - now).days
        return days_until_expire <= 7
    except Exception as e:
        logging.error(f"解析过期时间失败: {str(e)}")
        return False

def process_same_sni_certs(api, parsed_certs, current_sni, current_cert_id):
    """
    处理具有相同SNI的证书
    :param api: API实例
    :param parsed_certs: 解析后的证书列表
    :param current_sni: 当前证书的SNI
    :param current_cert_id: 当前证书的ID
    :return: None
    """
    # 筛选出相同SNI的证书
    same_sni_certs = [cert for cert in parsed_certs 
                     if cert['sni'] == current_sni and cert['id'] != current_cert_id]
    
    if not same_sni_certs:
        return
        
    # 按过期时间排序(从早到晚)
    same_sni_certs.sort(key=lambda x: datetime.strptime(x['expire_time'], "%Y-%m-%d %H:%M:%S"))
    
    # 检查是否有过期或即将过期的证书
    for cert in same_sni_certs:
        if is_cert_expired(cert['expire_time']):
            logging.info(f"删除过期证书 ID: {cert['id']}")
            if not api.delete_cert(cert['id']):
                logging.error(f"删除证书 {cert['id']} 失败")
    
    # 检查是否有过期时间相同的证书
    if len(same_sni_certs) > 1:
        # 获取第一个证书的过期时间作为基准
        base_expire_time = same_sni_certs[0]['expire_time']
        
        # 删除过期时间相同的证书(保留第一个)
        for cert in same_sni_certs[1:]:
            if cert['expire_time'] == base_expire_time:
                logging.info(f"删除重复过期时间的证书 ID: {cert['id']}")
                if not api.delete_cert(cert['id']):
                    logging.error(f"删除证书 {cert['id']} 失败")

def main():
    # 设置日志
    setup_logging()
    
    try:
        # 执行证书获取脚本
        if not run_get_cert_script():
            logging.error("获取证书失败,退出程序")
            return
            
        # 检查证书文件是否存在
        cert_path = os.path.join(CERT_SOURCE_DIR, CERT_FILE)
        key_path = os.path.join(CERT_SOURCE_DIR, KEY_FILE)
        
        if not (os.path.exists(cert_path) and os.path.exists(key_path)):
            logging.error("证书文件不存在,退出程序")
            return
            
        # 计算新文件的哈希值
        new_cert_hash = get_file_hash(cert_path)
        new_key_hash = get_file_hash(key_path)
        
        # 获取旧的哈希值
        old_cert_hash, old_key_hash = load_cert_hash()
        
        # 检查文件是否发生变化
        if new_cert_hash != old_cert_hash or new_key_hash != old_key_hash:
            logging.info("证书文件已发生变化,开始更新流程")
            
            # 读取证书和私钥内容
            cert_content = read_file_content(cert_path)
            key_content = read_file_content(key_path)
            
            if not cert_content or not key_content:
                logging.error("读取证书文件失败")
                return
                
            # 初始化API
            api = NanQiangAPI()
            
            # 登录
            if not api.login("obaby", "obaby@mars"):
                logging.error("登录失败")
                return
                
            # 检查证书
            check_result = api.check_cert(cert_content, key_content)
            if not check_result:
                logging.error("证书检查失败")
                return
                
            # 提交证书配置
            if not api.submit_cert_config(check_result):
                logging.error("提交证书配置失败")
                return
                
            # 获取证书列表
            cert_list = api.get_cert_list()
            if not cert_list:
                logging.error("获取证书列表失败")
                return
                
            # 解析证书列表
            parsed_certs = api.parse_cert_list(cert_list)
            if not parsed_certs:
                logging.error("解析证书列表失败")
                return
                
            # 获取当前证书的SNI
            current_sni = check_result.get('sni', '[]')
            try:
                current_sni = json.loads(current_sni)
            except json.JSONDecodeError:
                logging.error("解析当前证书SNI失败")
                return
                
            # 处理相同SNI的证书
            process_same_sni_certs(api, parsed_certs, current_sni, check_result.get('id'))
            
            # 保存新的哈希值
            save_cert_hash(new_cert_hash, new_key_hash)
            logging.info("证书更新完成")
        else:
            logging.info("证书文件未发生变化,无需更新")
            
    except Exception as e:
        logging.error(f"程序执行出错: {str(e)}", exc_info=True)

if __name__ == "__main__":
    main()

添加定时任务,每天,或者每几天:

0 2 * * * /usr/bin/python3 /home/soft/baby-nanqiang-cert-tools/site_cert_auto_update_tool.py >> /home/soft/baby-nanqiang-cert-tools/web_cert_manager.log 2>&1

最终效果:

The post 南墙 WAF 系列(二)– 网站证书自动更新 appeared first on obaby@mars.

南墙 WAF 系列(一)– 管理后台证书自动更新

2025年4月2日 10:13

管理后台这个东西,当然可以不在公网暴露,但是如果一旦在公网允许访问配置,此时就会出现一个很尴尬的问题,各种证书错误提示。

在上一篇文章提过,waf 是通过 docker 部署的。相对来说管理倒是也算方便,按照官方文档的说法,管理后台的证书在下面的位置:

南墙管理后台的配置位于/uuwaf/web/conf/config.json中,addr字段值即为ip地址和端口。替换SSL证书可以替换/uuwaf/web/conf/目录中的server.crt和server.key文件,之后执行systemctl restart uuwaf重启服务使配置生效。

那么要更新证书,只需要解决下面几个问题就行了,由于不想付费买证书,那么现在最好的思路就是直接通过 acme.sh 自动申请证书,让后写个小工具自动将相关的文件复制到指定的目录下,重启 docker 服务就可以了。

1.acme.sh 自动申请证书。

a.安装 acme.sh:

curl https://get.acme.sh | sh -s email=my@example.com

b.配置 dnspod的 api key 和 secret(使用子账号):

创建策略,输入以下内容保存:

{
 "statement": [
     {
         "action": [
             "dnspod:DescribeRecordFilterList",
             "dnspod:DescribeRecordList",
             "dnspod:CreateRecord",
             "dnspod:DeleteRecord"
         ],
         "effect": "allow",
         "resource": [
             "*"
         ]
     }
 ],
 "version": "2.0"
}

登录 腾讯云控制台,进入 访问管理 页面,单击左侧菜单栏的 用户列表,进入用户列表页面,并单击新建用户

创建 api 访问账号之后,写一个获取证书的脚本:

export Tencent_SecretId="key"
export Tencent_SecretKey="secret"
"/usr/local/acme.sh"/acme.sh --issue --dns dns_tencent -d lang.bi -d *.lang.bi

到这里第一步就完成了,不过需要注意的事有的扩展名不支持,例如 by,本来想用 oba.by 域名的,结果提示失败了:

sh cert_get.sh 
[Wed Apr  2 08:51:41 AM CST 2025] Using CA: https://acme.zerossl.com/v2/DV90
[Wed Apr  2 08:51:41 AM CST 2025] Account key creation OK.
[Wed Apr  2 08:51:41 AM CST 2025] No EAB credentials found for ZeroSSL, let's obtain them
[Wed Apr  2 08:51:43 AM CST 2025] Registering account: https://acme.zerossl.com/v2/DV90
[Wed Apr  2 08:52:14 AM CST 2025] Registered
[Wed Apr  2 08:52:14 AM CST 2025] ACCOUNT_THUMBPRINT='mri378DxKFRt5hzNd_P7HBLV1zo4c7n1g7HBVNAKG-s'
[Wed Apr  2 08:52:14 AM CST 2025] Creating domain key
[Wed Apr  2 08:52:14 AM CST 2025] The domain key is here: /root/.acme.sh/oba.by_ecc/oba.by.key
[Wed Apr  2 08:52:14 AM CST 2025] Multi domain='DNS:oba.by,DNS:*.oba.by'
[Wed Apr  2 08:52:16 AM CST 2025] Error creating new order. Le_OrderFinalize not found. {"type":"urn:ietf:params:acme:error:rejectedIdentifier","status":400,"detail":"DNS identifier is disallowed [oba.by]"}
[Wed Apr  2 08:52:16 AM CST 2025] Please add '--debug' or '--log' to see more information.
[Wed Apr  2 08:52:16 AM CST 2025] See: https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh
h4ck# vim cert_get.sh
h4ck# sh cert_get.sh 
[Wed Apr  2 08:54:34 AM CST 2025] Using CA: https://acme.zerossl.com/v2/DV90
[Wed Apr  2 08:54:34 AM CST 2025] Multi domain='DNS:oba.by,DNS:www.oba.by,DNS:nas.oba.by'
[Wed Apr  2 08:55:23 AM CST 2025] Error creating new order. Le_OrderFinalize not found. {"type":"urn:ietf:params:acme:error:rejectedIdentifier","status":400,"detail":"DNS identifier is disallowed [oba.by]"}
[Wed Apr  2 08:55:23 AM CST 2025] Please add '--debug' or '--log' to see more information.
[Wed Apr  2 08:55:23 AM CST 2025] See: https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh

2.复制文件重启服务

至于第二步就更简单了,直接让 cursor 给写一个:

参考下面的内容给我编写一个 Python3 的文件,实现以下功能:首先需要调用 get_cert.sh 脚本,自动获取证书文件文件,如果获取成功,证书会保存在下面的路径:/root/.acme.sh/lang.bi_ecc/fullchain.cer 私钥会保存在下面的路径/root/.acme.sh/lang.bi_ecc/lang.bi.key;获取到这两个文件之后,需要根据判断证书文件是否变化(记录旧证书内容,用于判断文件变更),如果变化则需要更新对应 docker 下的证书和私钥文件;docker 对应container Id 为f7dd0b0a990b,对应的证书文件路径为/uuwaf/web/conf/目录中的server.crt和server.key文件,在替换文件之后,需要重启对应的 docker 容器。按照步骤实现上面的内容,并且完成代码编写

最终代码:

#!/usr/bin/env python3
import os
import subprocess
import hashlib
import json
from pathlib import Path

# Configuration
DOCKER_CONTAINER_ID = "f7dd0b0a990b"
CERT_SOURCE_DIR = "/root/.acme.sh/lang.bi_ecc"
CERT_DEST_DIR = "/uuwaf/web/conf"
CERT_FILE = "fullchain.cer"
KEY_FILE = "lang.bi.key"
DEST_CERT_FILE = "server.crt"
DEST_KEY_FILE = "server.key"
HASH_FILE = "cert_hash.json"
CERT_SCRIPT = "get_cert.sh"

def get_cert_hash(file_path):
    """Calculate SHA-256 hash of a file."""
    sha256_hash = hashlib.sha256()
    with open(file_path, "rb") as f:
        for byte_block in iter(lambda: f.read(4096), b""):
            sha256_hash.update(byte_block)
    return sha256_hash.hexdigest()

def save_cert_hash(cert_hash):
    """Save certificate hash to a JSON file."""
    with open(HASH_FILE, 'w') as f:
        json.dump({'cert_hash': cert_hash}, f)

def load_cert_hash():
    """Load certificate hash from JSON file."""
    try:
        with open(HASH_FILE, 'r') as f:
            data = json.load(f)
            return data.get('cert_hash')
    except (FileNotFoundError, json.JSONDecodeError):
        return None

def run_get_cert_script():
    """Run the get_cert.sh script."""
    script_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), CERT_SCRIPT)
    
    # Check if script exists
    if not os.path.exists(script_path):
        print(f"Error: {CERT_SCRIPT} not found in the current directory")
        print(f"Expected path: {script_path}")
        return False
    
    # Check if script is executable
    if not os.access(script_path, os.X_OK):
        print(f"Error: {CERT_SCRIPT} is not executable")
        print("Attempting to make it executable...")
        try:
            os.chmod(script_path, 0o755)
            print("Successfully made the script executable")
        except Exception as e:
            print(f"Failed to make script executable: {str(e)}")
            return False
    
    try:
        # Use absolute path to the script
        result = subprocess.run(['sh', script_path], capture_output=True, text=True)
        if result.returncode == 0:
            print("Certificate generation successful")
            return True
        else:
            print(f"Certificate generation ignored: {result.stderr}")
            return True
    except Exception as e:
        print(f"Error running {CERT_SCRIPT}: {str(e)}")
        return False

def copy_cert_files():
    """Copy certificate files to Docker container."""
    try:
        # Copy certificate
        subprocess.run([
            'docker', 'cp',
            f"{CERT_SOURCE_DIR}/{CERT_FILE}",
            f"{DOCKER_CONTAINER_ID}:{CERT_DEST_DIR}/{DEST_CERT_FILE}"
        ], check=True)
        
        # Copy private key
        subprocess.run([
            'docker', 'cp',
            f"{CERT_SOURCE_DIR}/{KEY_FILE}",
            f"{DOCKER_CONTAINER_ID}:{CERT_DEST_DIR}/{DEST_KEY_FILE}"
        ], check=True)
        
        print("Certificate files copied successfully")
        return True
    except subprocess.CalledProcessError as e:
        print(f"Error copying files: {str(e)}")
        return False

def restart_docker_container():
    """Restart the Docker container."""
    try:
        subprocess.run(['docker', 'restart', DOCKER_CONTAINER_ID], check=True)
        print("Docker container restarted successfully")
        return True
    except subprocess.CalledProcessError as e:
        print(f"Error restarting container: {str(e)}")
        return False

def main():
    # Step 1: Run get_cert.sh script
    if not run_get_cert_script():
        print("Failed to generate certificates")
        return

    # Step 2: Check if certificate files exist
    cert_path = os.path.join(CERT_SOURCE_DIR, CERT_FILE)
    key_path = os.path.join(CERT_SOURCE_DIR, KEY_FILE)
    
    if not (os.path.exists(cert_path) and os.path.exists(key_path)):
        print("Certificate files not found")
        return

    # Step 3: Calculate new certificate hash
    new_cert_hash = get_cert_hash(cert_path)
    old_cert_hash = load_cert_hash()

    # Step 4: Check if certificate has changed
    if new_cert_hash != old_cert_hash:
        print("Certificate has changed, updating...")
        
        # Copy new certificate files
        if copy_cert_files():
            # Restart Docker container
            if restart_docker_container():
                # Save new certificate hash
                save_cert_hash(new_cert_hash)
                print("Certificate update completed successfully")
            else:
                print("Failed to restart Docker container")
        else:
            print("Failed to copy certificate files")
    else:
        print("Certificate has not changed, no update needed")

if __name__ == "__main__":
    main()

除了运行sh 脚本有点问题,需要改一下,其他的基本都没啥问题。最终执行效果:

此时刷新页面,一切就都 ok 了:

The post 南墙 WAF 系列(一)– 管理后台证书自动更新 appeared first on obaby@mars.

逃之夭夭

2025年4月1日 09:33

就在上个周末,看李小白的话剧之前,在换票的地方领了张报名表。表示对于话剧有兴趣的可以报个名。

虽然不知道到底有没有用,但是想着,去看看也无所谓的态度,填写了报名表。

过了没几天,看到有人加微信,是青岛电视台的导演。简单的交流了一下,说邀请宝子去参加面试,最后时间定在了周日下午。

当然,还很贴心的给出了停车引导视频之类的。不过说实话,如果没有这个引导视频,真的找不到地方。曲里拐弯的,就给绕晕了。

然而,到了现场,发现小朋友还是挺多的,加起来有十来个。不过,按照之前发的通知来看,应该也快,毕竟就那么简单的几项。

加起来能有半个小时应该也就够了,然而,等一点半开场之后,现场导演简单介绍了一下情况,包括团队啊,演员啊,等等。最后说道考核,提到了初赛、复赛。一听瞬间头大了,今天竟然还有复赛,问题是本来我就是带宝子来打酱油的啊。这下算是上了贼船了,也不好意思直接说跑了。不知声溜了也不大合适。就这么熬着。

终于半个小时之后,进入了初赛环节。

十个小朋友依次自我介绍,表演才艺。宝子准备的是现代诗朗诵《找梦》,多数的小朋友都是朗诵,有两个唱歌的,还有一个跳《apt》的,说在幼儿园学的,不得不说,现在幼儿园也的确与时俱进了。

再往后是无实物临场发挥,一群小朋友去春游,表演路上遇到的各种情况,以及野餐。这一套下来,半个多小时又没了。就酱紫已经过了一个多小时,而现在我想的是赶快结束吧,我要跑了。

上去找地方去打网球,去了一个新的公园,结果没开放,宝子就嘟着嘴不开心的样子,现在我想的是尽快跑了,去打网球去。

结束后在外面等初试结果,又过了十分钟,出来公布结果,三个直接晋级的,剩下的进入加试环节。整体说起来就是全部都参与复试,复试的题目抽签决定,宝子抽了个《找作业本》,其他的题目还有《吃面条》,剩下的我忘了。

这个表演需要家长参与,于是跟宝子讨论了下具体的流程,整体结论就是一阵找:被窝里,柜子里,桌洞里,床底下等等,当然,最后在床底下找到了,扒拉出来就行。

不过鉴于是无实物表演,还有另外一个策略,我说 :“宝子,你就坐在那里,一边哼唧一边哭,说作业本没了,然后我去给你找”

反过来也不是不行,就是我坐在那里嚷嚷:“快找,快快快……马上要迟到了……”最后的结果就是打一仗。

在预演了好几个场景之后,第一场进去复试的还没结束,百无聊赖又想跑了。主要是呆着是真受罪啊,这酱油打的有点累。

在这件事情上,我成了孩子成长的绊脚石,应该鼓励孩子参与,而不是怂恿孩子快跑。

然而,想到现在周六已经没了,上午钢琴,下午网球,周日上午有可能带宝子继续练球。这周日再没了,那一周真的就没啥自己的时间了,所以也是真的想跑。

终于第一场复试的出来了,我看手里拿着一个类似书通知书的东西。看了下时间,半个小时又过去了,也是在是不想等了。站起来跟导演说了下自己还有事情,就带着宝子溜了。

到停车场找网球场,打电话问了几个,都是满场,最后还是回到了学校。

不过这边状态都不大行,自己腰疼,宝子也有点漫不经心。打了大约四十来分钟就停了,主要是天气也的确冷,风也大。就这样仓促的结束了第二场运动。

昨天上班的时候,看到班级群里老师发的照片,宝子参与校长杯的作文比赛,拿了个二等奖。

当时,看到照片的时候觉得真不错,聊胜于无嘛。

下班之后问宝子,你的奖状呢。对象说拿着拿着就拿没了。放学的时候东西的确有点多,书包、轮滑鞋、气球、奖状,嗯,最后就是奖状丢了。不得不说,这个丢的挺好的,啥都没见到。

这奖状也逃之夭夭了。

The post 逃之夭夭 appeared first on obaby@mars.

是 IPv6 吖 — V6 重生记

2025年3月31日 10:27

上周五的时候,在杜老师的聊天室聊天,hehe 提到一个关于家里 ipv6 地址申请的问题。这时候才想到自己家里的网络应该也是有 ipv6 的地址的。至于地址是不是公网的那就不知道了。

而至于想要弄这个东西,其实还有一个原因是 he.net 的 ipv6 徽章已经很久没更新了,还差最后一步 ipv6 only 的网络访问测试,而测试的域名就是 h4ck.org.cn。
IPv6 Certification Badge for obaby

为了通过这个测试,自然要折腾一下。通过之后,he说会免费邮寄一个 T 恤衫,尺码和地址都更新了。不过这跨国的快递,不知道能不能收到。

至于能不能收到,这就只能耐心等待啦。

远程登录路由器,直接访问 ip 地址,然后高级的一幕就出现了,竟然直接打开了路由器的登录页面:

那么也就是说联通在 v6 协议下竟然没有封禁 80 端口,这样的话我忽然就有了个大胆的想法。如果路由器将 v6 的映射打开,直接访问 v6 的地址,忽略证书错误。然后网站就顺利打开了:

既然如此,那么这一来也解决了自己的 cdn 流量超限的问题。

这个月流量超限之后,买了 100G 的扩展包,结果就用了四天就又没了。为了解决流量问题,文章中的视频,直接通过 url 转发了。而至于首页右下角的图片就直接去掉了。不知道是访问量还是神马问题,这些图片一天跑十几个 G 的流量。

然而,到现在就出现了另外几个问题,要想让网站直接在互联网上访问,没有任何的防护措施,的确感觉不怎么靠谱。

1.家里的 V6 地址也是动态的,需要能够动态更新 ipv6 的 AAAA 记录。

2.在家里的主机上安装 waf 系统,提供基础的防御功能。

3.其他的未知问题。

AAAA 记录

在测试的时候,添加 AAAA 记录,会因为存在 cname 记录而导致添加失败,AAAA 记录和 CNAME 记录有冲突,请先删除或暂停现有的 CNAME 记录后重试:

此时针对不同的线路分别添加解析就 ok 了:

那么,在这之后就来到了第二个问题,怎么获取本地的公网 ipv6地址。

最直接的想法是直接通过获取 ipv4 地址类似的写法,来获取 ipv6 的地址,让 cursor 给写了类似的代码:

def get_ipv6_by_httpbin():
    """通过 httpbin.org 获取 IPv6 地址"""
    url = 'https://api6.ipify.org?format=json'
    try:
        resp = request.urlopen(url=url, timeout=10).read()
        data = json.loads(resp.decode("utf-8"))
        if 'ip' in data:
            return data['ip']
        return None
    except Exception as e:
        logging.warning("get_ipv6_by_httpbin FAILED, error: %s", str(e))
        return None

def get_ipv6_by_icanhazip():
    """通过 icanhazip.com 获取 IPv6 地址"""
    url = 'https://icanhazip.com'
    try:
        resp = request.urlopen(url=url, timeout=10).read()
        ip = resp.decode("utf-8").strip()
        if regex_ipv6.match(ip):
            return ip
        return None
    except Exception as e:
        logging.warning("get_ipv6_by_icanhazip FAILED, error: %s", str(e))
        return None

def get_ipv6_by_ident_me():
    """通过 ident.me 获取 IPv6 地址"""
    url = 'https://v6.ident.me'
    try:
        resp = request.urlopen(url=url, timeout=10).read()
        ip = resp.decode("utf-8").strip()
        if regex_ipv6.match(ip):
            return ip
        return None
    except Exception as e:
        logging.warning("get_ipv6_by_ident_me FAILED, error: %s", str(e))
        return None

实际证明,代码写的不错,在自己的 mac 电脑上的确可以获取到 ipv6 的地址。

然而,在家里的服务器上却使用无法获取 ip 地址,所有 v6 协议的服务都是超时状态。搜索了一堆,问了一大圈的 ai,最终都没解决问题。

后来猜测是不是路由器的问题,于是重新登录路由器的 v6 配置页面,来回切换配置:

看网上有文章会所需要改为 slaac 模式,改过去之后无效,切换成原来的自动,继续沿用上面的配置。断线重连结果网络就好啦。注意,这两个 dns 是腾讯的 dns,不是联通默认的 dns。

然而,此时就出现了另外一个问题,直到这时候我才发现,获取到的这个地址是本地的 v6 地址,而不是路由器的 v6 地址,当然,更恐怖的是这个 v6 地址也是可以在互联网直接访问的。

那么怎么自动更新这个 dns 记录就成了问题,总不能自己去天天改啊。

问小杜无果之后,继续尝试通过路由或者 tracerout 的方式获取,最终都以失败告终。至此,简单的方法算是彻底没了招了,那么就剩下一条路了,之计通过路由器获取,然鹅,tplink 的企业路由器并没有开放相关的 api。只能自己去找接口。

结果在登录页面就被来了个下马威,获取到接口,让 cursor 写完代码之后登录不了。

看起来页面很简单不是,但是这个东西恶心的地方在于登录的密码是加密过得,直接使用明文密码是登录不了的。不过好在这个密码不是动态加密的,直接使用密码登录,截取登录的加密后密码进行登录就 ok 了。剩下的就是获取 ipv6 地址,更新 dnspod 的aaaa 记录:

tplink 相关代码:

import requests
import json
import urllib.parse

def login_tplink(ip, username, password):
    """
    Login to TP-Link router
    :param ip: Router IP address
    :param username: Login username
    :param password: Login password
    :return: Response from the router and stok if successful
    """
    url = f"http://{ip}/"
    
    headers = {
        'Accept': 'text/plain, */*; q=0.01',
        'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        'Content-Type': 'application/json; charset=UTF-8',
        'Origin': f'http://{ip}',
        'Pragma': 'no-cache',
        'Referer': f'http://{ip}/login.htm',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36',
        'X-Requested-With': 'XMLHttpRequest'
    }
    
    data = {
        "method": "do",
        "login": {
            "username": username,
            "password": password
        }
    }
    
    try:
        response = requests.post(
            url,
            headers=headers,
            json=data,
            verify=False
        )
        if response.status_code == 200:
            try:
                response_data = response.json()
                if 'stok' in response_data:
                    return response_data['stok']
            except json.JSONDecodeError:
                print("Failed to parse login response as JSON")
        return None
    except requests.exceptions.RequestException as e:
        print(f"Login error occurred: {e}")
        return None

def get_network_info(ip, stok):
    """
    Get network information from TP-Link router
    :param ip: Router IP address
    :param stok: Session token from login
    :return: Network information response
    """
    url = f"http://{ip}/stok={stok}/ds"
    
    headers = {
        'Accept': 'text/plain, */*; q=0.01',
        'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        'Content-Type': 'application/json; charset=UTF-8',
        'Origin': f'http://{ip}',
        'Pragma': 'no-cache',
        'Referer': f'http://{ip}/',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36',
        'X-Requested-With': 'XMLHttpRequest'
    }
    
    data = {
        "method": "get",
        "network": {
            "table": "if_info"
        }
    }
    
    try:
        response = requests.post(
            url,
            headers=headers,
            json=data,
            verify=False
        )
        return response
    except requests.exceptions.RequestException as e:
        print(f"Network info error occurred: {e}")
        return None

def get_wan1_pppoe_addresses(response_data):
    """
    Parse IPv4 and IPv6 addresses from network info response
    :param response_data: JSON response data
    :return: Dictionary containing IPv4 and IPv6 addresses
    """
    addresses = {
        'ipv4': None,
        'ipv6': None
    }
    
    try:
        if_info = response_data.get('network', {}).get('if_info', [])
        for interface in if_info:
            if 'wan1_pppoe' in interface:
                wan_data = interface['wan1_pppoe']
                if 'ipaddr' in wan_data:
                    addresses['ipv4'] = wan_data['ipaddr']
                if 'ip6addr' in wan_data:
                    addresses['ipv6'] = urllib.parse.unquote(wan_data['ip6addr'])
                break
    except Exception as e:
        print(f"Error parsing wan1_pppoe addresses: {e}")
    
    return addresses

def update_ipv6_nat_mapping(ip, stok, dest_ip):
    """
    Update IPv6 NAT mapping on TP-Link router
    :param ip: Router IP address
    :param stok: Session token from login
    :param dest_ip: Destination IPv6 address
    :return: Response from the router
    """
    url = f"http://{ip}/stok={stok}/ds"
    
    headers = {
        'Accept': 'text/plain, */*; q=0.01',
        'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        'Content-Type': 'application/json; charset=UTF-8',
        'Origin': f'http://{ip}',
        'Pragma': 'no-cache',
        'Referer': f'http://{ip}/',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36',
        'X-Requested-With': 'XMLHttpRequest'
    }
    
    # URL encode the IPv6 address
    encoded_dest_ip = urllib.parse.quote(dest_ip)
    
    data = {
        "method": "set",
        "firewall": {
            "redirect_4313056213": {
                "name": "mac_server_v6",
                "ip_proto": "IPv6",
                "if": ["WAN"],
                "src_dport": "443",
                "dest_port": "443",
                "dest_ip": encoded_dest_ip,
                "proto": "ALL",
                "loopback_ipaddr": "",
                "enable": "on",
                "src_dport_start": "65536",
                "src_dport_end": "65536",
                "dest_port_start": "65536",
                "dest_port_end": "65536"
            }
        }
    }
    
    try:
        response = requests.post(
            url,
            headers=headers,
            json=data,
            verify=False
        )
        return response
    except requests.exceptions.RequestException as e:
        print(f"Error updating IPv6 NAT mapping: {e}")
        return None

if __name__ == "__main__":
    # Disable SSL warnings
    requests.packages.urllib3.disable_warnings()
    
    # Router credentials
    ip = '192.168.1.1'
    username = 'obaby'
    password = '123456***加密后密码'
    
    # First login to get stok
    stok = login_tplink(ip, username, password)
    
    if stok:
        print(f"Login successful! Got stok: {stok}")
        
        # Get network information using the stok
        network_response = get_network_info(ip, stok)
        
        if network_response:
            try:
                response_data = network_response.json()
                addresses = get_wan1_pppoe_addresses(response_data)
                
                print("\nWAN1 PPPoE Addresses:")
                if addresses['ipv4']:
                    print(f"IPv4: {addresses['ipv4']}")
                if addresses['ipv6']:
                    print(f"IPv6: {addresses['ipv6']}")
                    
                    # Update NAT mapping with the IPv6 address
                    nat_response = update_ipv6_nat_mapping(ip, stok, addresses['ipv6'])
                    if nat_response:
                        print(f"NAT mapping update response: {nat_response.text}")
                    else:
                        print("Failed to update NAT mapping")
            except json.JSONDecodeError:
                print("Failed to parse network response as JSON")
        else:
            print("Failed to get network information")
    else:
        print("Login failed!")

至此第一个问题解决了。

开始第二个小问题,更新 aaaa 记录,这个就比较简单了,直接让 curosr 写就行了:

def get_record_id(domain, sub_domain, record_type='A', record_line='默认'):
    """获取记录ID,支持A和AAAA记录,以及不同的记录线路"""
    url = 'https://dnsapi.cn/Record.List'
    params = parse.urlencode({
        'login_token': cfg['login_token'],
        'format': 'json',
        'domain': domain
    })
    req = request.Request(url=url, data=params.encode('utf-8'), method='POST', headers=header())
    try:
        resp = request.urlopen(req).read().decode()
    except (error.HTTPError, error.URLError, socket.timeout):
        return None
    records = json.loads(resp).get('records', {})
    for item in records:
        if (item.get('name') == sub_domain and 
            item.get('type') == record_type and 
            item.get('line') == record_line):
            return item.get('id')
    return None

def update_ipv6_record(current_ipv6):
    """更新IPv6记录,支持多个记录和不同的记录线路"""
    ipv6_count = int(cfg.get('ipv6_count', '1'))
    ipv6_pool = cfg.get('ipv6_pool', '').split(',')[:ipv6_count]
    cfg['current_ipv6'] = current_ipv6
    
    if current_ipv6 not in ipv6_pool:
        logging.info("new IPv6 found: %s", current_ipv6)
        ipv6_pool.insert(0, current_ipv6)
        cfg['ipv6_pool'] = ','.join([str(x) for x in ipv6_pool[:ipv6_count]])
        
        # 获取所有需要更新的AAAA记录配置
        aaaa_records = cfg.get('aaaa_records', '').split(',')
        for record in aaaa_records:
            if not record.strip():
                continue
            try:
                sub_domain, record_line = record.strip().split(':')
                if update_record('AAAA', current_ipv6, record_line, sub_domain):
                    logging.info(f"成功更新AAAA记录: {sub_domain}.{cfg['domain']} 线路: {record_line}")
                else:
                    logging.error(f"更新AAAA记录失败: {sub_domain}.{cfg['domain']} 线路: {record_line}")
            except ValueError:
                logging.error(f"无效的AAAA记录配置: {record}")
        save_config()
    else:
        logging.info('IPv6 地址无变化,跳过更新')

到这里网站就能正常访问了。

WAF:雷池&南墙

至于 waf 系统,其实自己之前也没怎么系统了解过,也是杜老师推荐了这两个。首先尝试的是雷池,也是杜老师最开始推荐的。

雷池:

个人版是免费的,相对来说配置也比较简单。

官网地址:https://waf-ce.chaitin.cn

自动安装一行命令即可:

bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/manager.sh)"

安装为 docker 模式,相对来说侵入性比较小一些。并且不需要占用 80,443 端口,这一点其实相对比南墙安装配置要求要低一些。

安装之后就可以通过 9443 端口登录了。相关功能示例:

系统概览,不知道是不是因为是 v6 地址的原因,左侧地图都是空白的。

同样,这个地球上也是空白的,底部的功能都需要专业版才能查看

防护模块是全部可用的

加强防御需要专业版

通用配置模块也是 ok 的。

整体来说安装过程比较顺畅也没遇到什么问题,不过访问 ip 由于是通过路由转发进来的需要从 x-forward-for中取这个信息。

南墙

开源免费的 waf 系统

官网地址:https://waf.uusec.com/#/

在使用过程中遇到点问题,不过最后在他们的技术帮助下顺利解决了。在安装之后,首先遇到的问题就是获取的 ip 地址有问题,都是本地的地址。并且不管怎么选择地址,最后都是同一个 ip 地址。

使用测速工具测速之后,ip 地址还是一个,这肯定是有问题的。在群里问了一下,给了个指令修复这个问题:

firewall-cmd --permanent --zone=internal --change-interface=docker0
systemctl restart firewalld && systemctl daemon-reload && systemctl restart docker

不过这么执行之后可能会出现的问题就是所有的服务都访问不了了,需要在 public 区域重新开放相关服务:

sudo firewall-cmd --zone=public --permanent --add-port=10043/tcp
sudo firewall-cmd --zone=public --permanent --add-port=14443/tcp
sudo firewall-cmd --zone=public --permanent --add-port=880/tcp
sudo firewall-cmd --zone=public --permanent --add-port=3306/tcp
sudo firewall-cmd --zone=public --permanent --add-port=9443/tcp
sudo firewall-cmd --zone=public --permanent --add-port=8443/tcp

其他需要开放的服务和端口自行添加即可。

然而,这个命令并没有解决问题。包括卸载重装,其实重装这件事情对我来说有些麻烦,因为服务器的默认 80 和 443 都映射到公网了,如果直接改了也比较麻烦,只能去工控机上停掉 80 的监听,443 的修改端口重新添加映射,毕竟这台主机上相对服务少一些。

重新安装依然没解决问题,这时候提议安装主机版。

然而,更尴尬的事情粗线了,那就是主机版不支持 ubuntu,只能作罢继续使用 docker 版本。

并且安装主机版,需要提前备份数据库,安装脚本会重装 mysql。这一点一定要注意!

这时候管理员提议远程协助,于是将端口映射出去,提供账号密码,等管理员修复。

管理说可能是映射的问题,然而,雷池的没问题,那么说明一定是有解决办法的,管理提到 docker 的网络配置不一样的,于是提议修改网络配置。

最终,亲爱的管理员,成功的修复了问题:

这样这个问题算是解决了,整体而言,感觉雷池的在 v6 测速的时候更绿一些。

好啦,相对来说雷池基本所有的模块都是开放的,除了机器学习部分:

安全态势

系统信息

用户管理

日志

证书管理,这个证书管理直接上传即可,不需要去进行绑定。

cdn 加速,其实感觉更像缓存配置。

规则管理

网站管理,得添加多个。

整体来说体验还是不错的,然而,刚才去看了配置文件感觉还是 bridge 啊。奇怪了。

不过既然问题解决了,那也就不纠结了。

官方文档说明:

https://waf.uusec.com/#/guide/problems?id=%f0%9f%8d%8b-%e5%a6%82%e4%bd%95%e8%a7%a3%e5%86%b3%e5%8d%97%e5%a2%99docker%e7%89%88%e8%8e%b7%e5%8f%96%e7%9a%84%e5%ae%a2%e6%88%b7%e7%ab%afip%e4%b8%ba172%e7%9a%84%e9%97%ae%e9%a2%98%ef%bc%9f

 

🍋 解决部分南墙容器版获取的客户端ip为网桥ip的问题?

1.将Docker网桥加入到防火墙的internal区域,以便获取到真实的IP地址, 假设Docker网桥名称为docker0

firewall-cmd --permanent --zone=internal --change-interface=docker0
systemctl restart firewalld && systemctl daemon-reload && systemctl restart docker

2.如果方法1无效,可以修改docker-compose.yml文件,将uuwaf容器的网络设置为network_mode: host,同时修改数据库连接环境变量UUWAF_DB_DSN中的wafdb为127.0.0.1,并映射wafdb容器的3306端口,重启后生效。

 

其他问题

鉴于主机获取的 ipv6 地址能直接访问,其实我一度想直接把主机的地址更新到 dns aaaa 记录上,但是这么一搞,暴露主机的确不是我最终想要的。

于是想着映射本地的链路地址,然而,端口映射通过链路地址通过路由器的 v6 地址却打不开网站,但是这个链路地址在内网的主机上又能打开网站,于是只能放弃这个做法。获取 ipv6 地址的代码:

import re
import logging
import json
import subprocess
import socket
import os
from urllib import request, error, parse

# 匹配合法 IPv6 地址
regex_ipv6 = re.compile(
    r"(?:inet6\s+)?(fe80:[0-9a-fA-F:]+|"  # 特别处理链路本地地址格式
    + r"(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|"  # 标准格式
    + r"(?:[0-9a-fA-F]{1,4}:){6}:[0-9a-fA-F]{1,4}|"  # 压缩格式
    + r"(?:[0-9a-fA-F]{1,4}:){5}(?::[0-9a-fA-F]{1,4}){1,2}|"
    + r"(?:[0-9a-fA-F]{1,4}:){4}(?::[0-9a-fA-F]{1,4}){1,3}|"
    + r"(?:[0-9a-fA-F]{1,4}:){3}(?::[0-9a-fA-F]{1,4}){1,4}|"
    + r"(?:[0-9a-fA-F]{1,4}:){2}(?::[0-9a-fA-F]{1,4}){1,5}|"
    + r"(?:[0-9a-fA-F]{1,4}:){1}(?::[0-9a-fA-F]{1,4}){1,6}|"
    + r"(?::[0-9a-fA-F]{1,4}){1,7}|"
    + r"::"
    + r")")

# 特别匹配链路本地 IPv6 地址,确保能匹配到 fe80:: 开头的地址
regex_link_local_ipv6 = re.compile(r"inet6\s+(fe80:[0-9a-fA-F:]+)")

def get_ipv6():
    """获取公网 IPv6 地址,使用多个备选方法"""
    return (get_ipv6_by_ifconfig()  # 优先使用本地接口地址
        or get_ipv6_by_httpbin()
        or get_ipv6_by_icanhazip()
        or get_ipv6_by_ident_me()
        or get_ipv6_by_socket())

def get_ipv6_by_ifconfig():
    """通过 ifconfig 命令获取本地 IPv6 地址"""
    try:
        # Windows 系统使用 ipconfig
        if os.name == 'nt':
            cmd = ['ipconfig']
            output = subprocess.check_output(cmd, text=True)
        # Linux/Unix 系统使用 ifconfig
        else:
            cmd = ['ifconfig']
            output = subprocess.check_output(cmd, text=True)
            
        # 按行分割输出
        lines = output.split('\n')
        for line in lines:
            # 查找包含 inet6 的行
            if 'inet6' in line:
                # 使用正则表达式提取 IPv6 地址
                matches = regex_ipv6.findall(line)
                if matches:
                    ipv6 = matches[0]
                    # 排除本地回环地址
                    if not ipv6.startswith('::1'):
                        logging.info(f"Found IPv6 address: {ipv6}")
                        return ipv6
    except Exception as e:
        logging.warning("get_ipv6_by_ifconfig FAILED, error: %s", str(e))
    return None

def get_ipv6_by_socket():
    """通过 Python socket 库获取本地 IPv6 地址"""
    try:
        # 创建一个 IPv6 socket
        s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
        # 连接到一个外部地址(这里使用 Google 的 IPv6 DNS)
        s.connect(('2001:4860:4860::8888', 80))
        # 获取本地地址
        local_addr = s.getsockname()[0]
        s.close()
        return local_addr
    except Exception as e:
        logging.warning("get_ipv6_by_socket FAILED, error: %s", str(e))
        return None

def get_ipv6_by_httpbin():
    """通过 httpbin.org 获取 IPv6 地址"""
    url = 'https://api6.ipify.org?format=json'
    try:
        resp = request.urlopen(url=url, timeout=10).read()
        data = json.loads(resp.decode("utf-8"))
        if 'ip' in data:
            return data['ip']
        return None
    except Exception as e:
        logging.warning("get_ipv6_by_httpbin FAILED, error: %s", str(e))
        return None

def get_ipv6_by_icanhazip():
    """通过 icanhazip.com 获取 IPv6 地址"""
    url = 'https://icanhazip.com'
    try:
        resp = request.urlopen(url=url, timeout=10).read()
        ip = resp.decode("utf-8").strip()
        if regex_ipv6.match(ip):
            return ip
        return None
    except Exception as e:
        logging.warning("get_ipv6_by_icanhazip FAILED, error: %s", str(e))
        return None

def get_ipv6_by_ident_me():
    """通过 ident.me 获取 IPv6 地址"""
    url = 'https://v6.ident.me'
    try:
        resp = request.urlopen(url=url, timeout=10).read()
        ip = resp.decode("utf-8").strip()
        if regex_ipv6.match(ip):
            return ip
        return None
    except Exception as e:
        logging.warning("get_ipv6_by_ident_me FAILED, error: %s", str(e))
        return None

def get_link_local_ipv6():
    """专门获取链路本地 IPv6 地址"""
    try:
        # Windows 系统使用 ipconfig
        if os.name == 'nt':
            cmd = ['ipconfig']
            output = subprocess.check_output(cmd, text=True)
        # Linux/Unix 系统使用 ifconfig
        else:
            cmd = ['ifconfig']
            output = subprocess.check_output(cmd, text=True)
            
        # 按行分割输出
        lines = output.split('\n')
        for line in lines:
            # 查找包含 inet6 的行
            if 'inet6' in line:
                # 提取 IPv6 地址和 prefixlen
                if 'prefixlen 64' in line and 'scopeid 0x20<link>' in line:
                    # 调试输出
                    logging.debug(f"Processing line: {line}")
                    
                    # 使用特定正则表达式提取链路本地 IPv6 地址
                    matches = regex_link_local_ipv6.findall(line)
                    if matches:
                        ipv6 = matches[0]
                        logging.info(f"Found link-local IPv6 address with new regex: {ipv6}")
                        return ipv6
                    
                    # 如果特定正则表达式没有匹配到,尝试使用一般性正则表达式
                    matches = regex_ipv6.findall(line)
                    if matches:
                        ipv6 = matches[0]
                        logging.debug(f"Original regex matched: {ipv6}")
                        # 只返回链路本地地址
                        if ipv6.startswith('fe80'):
                            logging.info(f"Found link-local IPv6 address with original regex: {ipv6}")
                            return ipv6
                        elif 'fe80' in line:
                            # 如果行中包含fe80但匹配失败,记录错误
                            logging.warning(f"Regex failed to match fe80 in: {line}")
    except Exception as e:
        logging.warning("get_link_local_ipv6 FAILED, error: %s", str(e))
    return None

# 测试
if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    
    # 测试特定的 IPv6 地址匹配
    test_line = "inet6 fe80::e4d:e9ff:fec9:9de3  prefixlen 64  scopeid 0x20<link>"
    print("Testing regex with line:", test_line)
    
    # 测试链路本地特定正则
    matches = regex_link_local_ipv6.findall(test_line)
    if matches:
        print("Link-local regex matched:", matches[0])
    else:
        print("Link-local regex failed to match")
    
    # 测试一般 IPv6 正则
    matches = regex_ipv6.findall(test_line)
    if matches:
        print("General IPv6 regex matched:", matches[0])
    else:
        print("General IPv6 regex failed to match")
    
    print("\n--- Regular program output ---")
    print("Method 1 (httpbin):", get_ipv6_by_httpbin())
    print("Method 2 (icanhazip):", get_ipv6_by_icanhazip())
    print("Method 3 (ident.me):", get_ipv6_by_ident_me())
    print("Method 4 (ifconfig):", get_ipv6_by_ifconfig())
    print("Method 5 (socket):", get_ipv6_by_socket())
    print("Link-local IPv6:", get_link_local_ipv6())

获取到 v6 地址,就可以通过 tplink 的映射代码update_ipv6_nat_mapping进行地址映射了。

如果要用这个代码,需要根据自己的路由器配置获取映射的 id。

整体来说,速度还是可以的: 

 

The post 是 IPv6 吖 — V6 重生记 appeared first on obaby@mars.

祝自己生日快乐啊

2025年3月28日 09:59

阴历 二月二十九,不少人看到这个二月二十九,通常第一句话都会问:“你是不是四年才过一个生日啊?”

其实并不是,一直过生日都是过阴历的,如果去看日历就会发现,阴历每年都会有二月二十九。

说到阴历,有一点其实我挺好奇的,每日禁忌为什么所有的万年历看起来都一样?跟印刷的纸质万年历也毫无区别。至于黄道吉日的算法,搜了下,感觉这个说的蛮专业的样子:

黄道吉日”在我们的日常生活中运用的是相当频繁的,我们常常听到或看到结婚、殡葬、祭祀、商铺开业、建房动土、出差旅游、剖腹产的等等,都要翻看黄历,查找“黄道吉日”来使自己办事顺利,取得最大效益。现代人使用的虽多,却不一定都知道一年365天每天的宜忌是如何推算出来的。黄道吉日的推算方法主要有两种,一种是十二值,一种是十二地支配十二天神。十二值就是十二建星轮流值日。黄历以除、满、平、定、执、破、危、成、收、开、闭。黄历以十二建星周而复始观其所值,以定吉凶。

其起法很简单:每年从立春后第一个寅日起“建”,一天一位,按以上顺序以此往后排。逢节重复前一日的神值;一年共重复12次,这样刚好保证下一年立春后的第一个寅日为“建”。例如:正月建寅,正月的第一个寅日为“建”,次日卯日则为“除”,第三日辰日为“满”……;二月建卯,二月第一个卯日为“建”,次日辰日为“除”……,依此类推。

人们依据口诀“建满年好黑(黑道),除危定执黄(黄道),成开皆可用(黄道),闭破不能行(黑道)”将每天划分成“黄道吉日”和“黑道凶日”。但十二值不管是黄道还是黑道,都有宜和忌,吉凶要根据具体事项而定,不是固定不变的。

我们常说的黄道吉日是指万事皆宜,不避凶忌的日子。黄道黑道神煞有十二个:青龙,白虎,明堂,天刑,朱雀,金匮,天德,玉堂,天牢,元武,司命,勾陈。逢青龙,天德,玉堂,司命,明堂,金匮六黄道神煞所值值日就是黄道吉日,这天可以结婚、动土修造、商铺开业等。而剩余六神所值值日就是黑道凶日,不宜举行重大活动。

十二地支配十二神:

子日青龙丑日明堂

寅日天刑卯日朱雀

辰日金贵巳日天德

午日白虎未日玉堂

申日天牢酉日玄武

戌日司命亥日勾陈

综合以上我们可以得出:

黄历之中白虎,天刑,朱雀,天牢,玄武,勾陈–为六黑道凶日;

黄历之中青龙,天德,玉堂,司命,明堂,金匮–为六黄道吉日。

黄历之中除日、危日、定日、执日、成日、开日为吉;

黄历之中建日、满日、平日、破日、收日、闭日为凶。

择吉日的原则是:以事为经以神为纬,以神为目以事为纲。高勇强认为,择吉日因事(民事活动)而起,而不要择日办某事。需要根据所办事情的性质去寻找最能带来大吉大利的善神,同时明确可能造成大灾大难的的凶神恶煞。

原文链接:https://exzh.net/315.html

而至于我对象则是过阳历的,宝子有时候过阴历的有时候过阳历的。

至于过生日,其实没什么仪式感,连想法也没有。想要的东西,买不起,买得起的不想要。索性,就干脆不想了,主要是想了也没啥用。

其他的事情,还能选个黄道吉日,但是过生日这个不能选啊,毕竟就是这天嘛。那天按摩的时候,按摩的姐妹问自己多大了,让她猜。她猜了个二十七八。这当然有恭维的成分,不过最起码听着开心啊。可惜啊,现在已经不是二十七八了。

至于上次拍照,其实还拍了另外一组,不知道是什么问题,就是感觉挺怪的,没什么美感。所以这组图片一直也没发过,不过今天过生日嘛,就捡一张发一下吧,一个字足以概括,那就是丑,不过也没什么办法了,资质不行,全靠摄影和后期毕竟难度太大主要是减肥成果也不够明显,还需要减掉很多,很多。

晚上预定了海底捞,这一顿吃完,自己这一周的运动量又白费了,唉。

不过这吃完了,还是要继续运动啊。

要快乐,要永远十八岁哦。

The post 祝自己生日快乐啊 appeared first on obaby@mars.

铲子与锅

2025年3月27日 14:14

这几天又开始降温了,天气预报开始发布寒潮预警,气温又到了 3 度左右。稍微厚点的袜子都收起来了,也懒得在拉出来,毕竟穿完了就又要洗。

上周的时候,同事找过来让帮忙申请个信用卡。申请成功了可以有赠品,食用油啊,不粘锅啊神马的。

这不是第一次帮他去完成任务,之前推广社保卡的时候就在他老婆的银行开的户。现在又让帮忙,也不是不可以,毕竟还有赠品不是吗?申请倒是也简单,直接从线上填写资料,申请就 OK 了。然后就是等待审核,周日的时候顺丰打电话说信用卡到了,问在不在公司。沟通之后让周一再送,想着既然信用卡到了,那赠品应该也快到了。毕竟目的很明确,就是为了哪个赠品,至于激活,激活他干嘛呢?

前天夜里,对象忽然爬起来说,窗户怎么开了?你不觉得冷吗?

“没有啊“,我答道,翻个身继续睡,紧紧抱着我的被子 jiajia(一个角)。

早上起床之后,对象说感觉自己感冒了。但是这几天也没去人群太密集的地方,怎么就感冒了呢。而至于窗户,一般晚上都是直接关死的,怎么会被大风给吹开了?

奇哉怪也。

鉴于感冒了,中午回去做点饭吃,顺便休息一下。在厨房找东西的时候看到铁锅里有个塑料勺子,我问,老妈为什么非得用这些奇奇怪怪的东西炒菜呢。

“我把哪个铁铲子扔了“

“哦哦,酱紫,挺好的“我回应道。

“防患于未然,省的到时候新的不粘锅来了,她有用铁铲子一顿铲“

家里的锅已经换了无数个了,但是铲子基本没怎么换过,除了后来又买了几个木头铲子。然而不管怎么跟老人说,不粘锅有涂层不要硬铲,都没用。过不了多久,就成了一道一道的。之前家里有个挺好用的白色的炒锅,然而,最后也是死于他们的铁铲之下。

其实不单是老人,对象的妹妹也能干出同样的事来。之前也是拿到了一个不错的不粘锅,自己没舍得用,送给他们了。结果第一顿饭就牺牲在了战场之上。铁铲子一道道的划痕,让哪个不粘锅变成了次抛品。

回家的另外一个目的是拿身份证,现在想领到赠品必须得激活信用卡还得又两笔消费才行。虽然要求去营业网点激活,但是这助人为乐的事情也不能让帮忙的到处跑。于是就同事的老婆就呆着设备来公司给激活,但是激活的时候需要身份证。

不过不得不说,各种隐含的 app 使用体验是真的烂。

下午回家走不到一块,自己要开会,就让对象先回去了。晚上回去的时候,已经躺在床上睡着了,睡醒了说浑身疼。这忽如其来的病,我说是半夜起来关窗户,被邪风吹伤了。

自己虽然没有浑身疼,但是左手手腕却一直挺奇怪的,时不时的会疼,并且这么长时间了,感觉也没好转的迹象。至于去医院检查,感觉不严重,至于不去呢,却又总也好不了。

这一年一年似乎过的越来越快了,马上又要过生日了,至于过生日有什么意义?其实现在也没什么意义,就是家人聚在一起吃个饭,聊聊天。前端时间宝子在学网球的时候,自己到处溜达,找到一个还在营业的养生会所,进去溜达了一下,想着以后宝子上课的时候,自己可以找地方放松一下:

一眼看过去,价格的确不便宜。不过当天也安排不上,后来找了个时间中午过去按了一下。店长给推荐了个套餐,比价目表的就便宜多了:

于是办了张 380 的会员卡,平均下来一次几十块钱,也还可以吧。

只是,每次按完了,总是感觉皮疼,得过好几天才能缓过来,不知道是按的方式不对啊,还是什么情况。

只是这身体状况似乎还不如一口锅来的抗用,哪怕哪天锅不嫩用了,换一口就行,然而,这个神奇状态,却怎么也换不了,而至于调理,那更是旷日持久的持久战。更何况还有那么多铲子想一层层的扒皮。

The post 铲子与锅 appeared first on obaby@mars.

vivaldi 同步失败

2025年3月25日 15:44

自从 opera 被 360 收了之后,期间用了一段时间的chrome。然而由于 google 的服务稳定性一直不怎么样,数据在不同设备间同步就成了一件痛苦的事情。知道后来发现opera 的原创团队又出了个 vivaldi 浏览器,顺其自然就切到了 vivaldi 上面。

后来,在某年某月的某一天,vivaldi 的同步服务变得和 google 一样了。直接同步是无法同步的,其实手机上的同步倒是没那么重要,关键是不同的电脑设备间的同步就变得异常痛苦。在一台电脑上注册了,记住密码,到另外一台电脑上还得重新输入账号密码登录。

在这种状态下再怎么重试也没任何的意义。其实对于这种屏蔽,个人感觉应该不会做的太彻底,毕竟就是一个数据同步服务而已。

首先找到同步服务的域名,打开 clashx,查看链接,最后发现了这么一个域名,感觉应该就是了:

当然,也可以用 tcpdump,wireshark 之类的抓包,不过命令行不直观,鲨鱼没装,就地取材就完了。至于为什么是这个域名不是其他的,问就是直觉,我觉得它是。

去 itdog 查询域名解析,别选国内的 dns,选了会返回一堆没用的:

去掉国内的服务器,此时就只剩下一个了:

修改本地 hosts 文件,或者去路由器添加 dns 解析,或者直接修改自己的 dns 服务器的解析等,以上的方法都 ok,添加下面的解析:

31.209.137.10 bifrost.vivaldi.com

此时,就不需要什么魔法就能愉快的同步数据了:

The post vivaldi 同步失败 appeared first on obaby@mars.

要是能重来 我要选李白

2025年3月24日 10:47

就在上周末,带着宝子去练球,她下课之后,总觉得哪里不大对。发球不行,接球也不行。当然,最重要的原因在于学员太多了,一个教练带 8 个学生,一节课哪怕一个半小时,实际上手的时间也不过十几分钟,不由让自己想到了驾校学车的时候,现在看来,一样坑爹。

下课之后,宝子想买饮料,本来我是不想给她买的。不过最后还是买了,强忍着心里的怒火,总感觉她练的太少,上午的钢琴落下一些,下午的 网球也打不好,就让人很郁闷。

晚上回家之后还是没忍者,因为一点小事跟她发火了,说她啥都不行,琴,琴弹不好,球,球也打不好。

虽然不要求说能达到很高的高度,但是最起码得能说的过去吧。网球一年多了,现在接发球都是问题,也的确让人抑郁。当然,教练也有很大的问题,等课时用完了是该换个教练了。

这周六网球依然没什么太大的改观,总这么下去也不是办法。不过下课之后,也该带她去看话剧了。毕竟,赶到市南还是需要点时间的。

达到剧场,换了票出来,想找个地方吃点东西,也是个问题,来的时候一路上没什么开门的餐饮店。

只有路过的一个咖啡厅,勉强像能提供吃的东西。

原路返回,点了两杯咖啡,能提供的吃的,只有水饺。水饺配咖啡,也算是中西结合了。

鉴于宝子吃饭又怕热,吃的又慢,最后把咖啡里面的冰块捞了出来,跟水饺放在一个盘子里,算是解决了一个大问题。

吃完东西赶紧赶回剧场,原定六点半开始的演出,入座之后,等到 40 都还没开始。票的位置不是特别好。

后面的孩子还在不断的踢自己的椅子靠背,回头跟她说不要踢椅子背之后,算是安静了一会儿。眼看要开始了,中间相对来说比较好的位置依然没有坐满,这时候后排的一家三口就商量着跑到中间没人的地方去。在达成一致之后,开始往中间迁移,临走之前,熊孩子还又踢了两脚靠背。如果是自己的孩子,真 tm 想揪起来揍她一顿!不过好在最后熊孩子滚蛋了,也算是被动解决了个麻烦。

当然,除了他们还有很多的人在往中间迁移,宛如动物世界的大迁移一般。

不久,终于开始了。李白的出场比较惊艳,声、像、景俱佳。

的确有诗仙的样子。不过至于小演员,就稍显瑕疵,语速有点快,并且表达不是那么清晰,对比之下就能感受到巨大区别。

当然,最抽象的就是右侧的那两个了。最左边是个熊猫,右侧的两个一个是李小白的桌子,一个是李小白的椅子。主角就是中间的那个男孩,李小白。

故事从学校的诗歌朗诵比赛开始,期间穿越到了唐朝,分别遇见了,青年,中年,老年时期的李白。故事安排算是比较合理,对于小学生来说,算是个不错的体验。

不过,纵览李白的一生,也不是尽如人意,人生嘛,难免充满缺憾。

这缺憾,有的能弥补,有的不能弥补。而至于自己力所能及的,自然要做的更好一些。晚上跟宝子商量了一下,第二天带宝子去练球,至于怎么练其实也是个问题,自己不会打网球,甚至都没尝试过。

如果要作为陪练,带宝子练球,虽然有个带绳的球可以打出去自己弹回来,但是这种球,总是感觉少点东西。而自己要去配宝子练,就要求自己发球能发到宝子身边,这种喂球难度也的确有点高。

场地反而容易解决一些,对象说去小区的小广场,但是小广场是地砖,各种缝隙,对于球的路线来说是个大问题,尤其是弹跳之后。最后还是决定去青科大的场地,对象作为青科大的毕业生,想进入也简单,申请一下就好了。如果找不到场地,那就可以去上周末去的新建的广场。

教学楼前面的孔子像,依然是有一些水果,哪怕现在不是考试的时间。

早上九点多,校园里依然安静,路上没多少人。各种球场,除了带班的教练和学员,运动的人并不算多,但是网球场却是满了。本来两个人也用不了多大的场地,看边上的排球场空着,想着有半个排球场的场地也就够了。

带宝子进入场地,第一次打网球,力度确实不好掌握,尤其是要把球打到宝子身边,还要让她能接球。来回尝试几个回合之后总算是找到了一个比较合适的力度。

经过不断的练习,也算是渐入家境,宝子接球也越来越稳定了。从开始的发过来,发过去,到后来的打过来,打过去。那种进步的确让人高兴,最起码能感觉到打球的乐趣了。

一个小时下来,从最开始的接球一般,到现在能来回打十来个回合。也许,这种运动才会让人上瘾吧。运动的快乐不过如此。

不过早上起床之后,感觉就没那么舒服了,每天跳绳三千个没什么太大感觉,但是一个小时网球下来,早上起来大腿开始疼了,虽然不严重,但是能感受到阵阵的痛意。

早上把宝子送到学校,准备过马路去开车。眼看绿灯亮了,刚下台阶,这时候一辆奥迪 Q5 蹭的一下,闯红灯窜了过来,如果躲闪不及时就让这沙雕玩意儿给撞上了。

透过车窗看了下司机,挺年轻的一个男人,看着斯斯文文,没想到这么沙雕,不礼让行人也就罢了,还 tm 闯红灯。

这时候想起,话剧里面练剑的李白,如果手里有剑,好歹得把这个沙雕从车里揪出来,大喝一声:“沙雕,吃我一剑!”

The post 要是能重来 我要选李白 appeared first on obaby@mars.

418 I’m a teapot

2025年3月20日 09:57

这几天偶尔会折腾下 wp 的插件和数据的问题,更新了一下。偶然间充新打开了 wp 邮件的发送报告,看了下发送记录每天几千封邮件,一大半是失败的。

猜测肯定就是各种 bot 尝试注册账号导致发送注册确认邮件失败了。

看了下用户表,结果这个用户数量的确是无敌了。如果闺蜜圈目前能有这么多用户就好了。

昨天晚上回去连上数据库,直接代码删除了未激活用户,然后令人崩溃的事情出现了,博客直接挂了。哈哈哈。好在之前备份了数据库,直接数据回滚,不过问题就是丢失了部分评论数据。

另外一个问题就是 oba.by 的cdn 感觉也有问题,直接红了一大片:

这个目前自己解决不了,只能等别人解决啦。

说到这里,过年的时候喵呜酱免费赞助了一年的 cdn,现在另外一个域名 obaby.org.cn 是是用的这个 cdn,感兴趣的可以看一下。

网址:https://waf.pro

我用的国外的节点,整体感觉速度还算可以。

今天早上在看昨天红了一片的域名的时候发现了另外一个神奇的玩意儿,右侧有个图片不显示了:

调试发现了这么个错误:418 I’m a teapot

神 tm teapot。哈哈哈,来了解下这个 teapot:

HTTP错误代码418表示服务器拒绝尝试用一个茶壶冲泡咖啡,这一代码在1998年作为愚人节笑话被加入到超文本传输协议(HTTP)中。418 I’m a teapot 是由一份名为 “Hyper Text Coffee Pot Control Protocol”(HTCPCP)的网络通信协议草案引入的,该协议用来控制、监视和诊断咖啡壶。尽管418是个玩笑,但它在某些软件和服务中得到了实现,成为了一个文化现象,并在互联网社区被反复提及。

一、418 I’M A TEAPOT 的起源

HTTP状态码418的典故源自一个名为HTCPCP的愚人节笑话文档,RFC 2324,它在1998年由互联网工程任务组(IETF)发布。HTCPCP以幽默的方式描述了控制咖啡壶的扩展协议,而418则是在此基础上增加的一个状态代码,介绍一个遵循HTCPCP的茶壶是如何处理咖啡冲泡请求的。这个错误代码是对通常用于网络通信的严肃的规范文档的一种戏仿。

该协议详细说明了如何通过网络给咖啡壶发送指令,例如BREW或POST命令用以开始咖啡冲泡过程。418状态码成为了这个协议的一部分,象征着一个茶壶无法完成冲泡咖啡的任务,因为它是用来烧水做茶用的。

二、418状态码的实际应用

虽然在HTTP中定义为一个梗,418 I’m a teapot 状态码确实在某些实现中被采用了。例如,一些网页服务器和HTTP库支持返回这个玩笑的状态码。某些API和网络服务为了幽默或彩蛋也会使用418状态码回应特定的请求。为了庆祝这个状态码以及互联网文化的一部分,一些开发者甚至会在愚人节这一天专门返回418状态码。

回馈这个文化现象,418状态码逐渐成为了一个有趣的象征,指代那些不按常理出牌或者需要特殊处理的情况。它表明互联网社区对于HTTP协议和其他表面严肃的标准中潜入的幽默元素表示赞赏。

三、418状态码的文化意义

418状态码超出了它最初的设定,成为了互联网文化中的一块标志。它体现了互联网社区的幽默感和对传统技术规范的一种轻松对待方式。这个状态码经常被用来表明对规范的玩世不恭态度,或者是为了给用户带来一点乐趣。它代表了一个防止技术沦为无聊和机械过程的行动,鼓励人们在日常的技术工作中保持创造力和幽默感。

相关问答FAQs:

【FAQ 1】:什么是Http错误代码418?它有什么特殊典故或意义吗?

Http错误代码418是一种非常少见且有趣的错误代码,它指代“我是一个茶壶”(I’m a teapot)。这个错误代码的起源可以追溯到1998年,当时IETF(Internet工程任务组)的一位成员在一个恶搞提案中加入了这个错误代码作为一种玩笑。

【FAQ 2】:Http错误代码418的含义是什么?为什么会用“我是一个茶壶”来表示错误?

Http错误代码418的含义是表明服务器拒绝请求,因为它是一个茶壶,并且无法咖啡加热或者冲泡咖啡。虽然这个错误代码在实际应用中并没有太多意义,但它被创造出来主要是为了幽默和调侃,给人们一些欢乐和轻松的氛围。

【FAQ 3】:Http错误代码418在实际应用中有什么作用?哪些网站或服务曾经使用过它?

实际上,Http错误代码418并不被广泛使用,因为它并没有特别实用的作用。一些网站或服务曾经在特殊的场合使用过它来制造一些幽默和趣味性,例如谷歌曾在愚人节时将其用作错误页。

虽然Http错误代码418并不常见且不具有重要实际功能,但它作为一种有趣的元素,赋予了网络世界更多的乐趣和创意。

但是,这个图片正常访问是可以打开的,为什么会返回茶壶呢?

目前没修复这个错误,感兴趣的可以访问看看:https://oba.by

20250321更新:

知道为什么会是茶壶啦。昨天博客又被打了,需要滑动认证,在没认证的时候,cdn 就返回了个茶壶,哈哈哈

The post 418 I’m a teapot appeared first on obaby@mars.

春风无力百花残

2025年3月18日 10:31

暖和了那么几点,然而,今天早上送宝子上学的时候。忽然感觉那春风变得刺骨的寒冷,看了下车机上的温度,1 度。在青岛这个地方,体感温度总是让人怀疑天气预报的温度是不是准确。夜里可能也飘了一阵雪花,车顶,玻璃上还零星的粘着一些积雪,仿佛在告知大家,真的曾经下雪了。

李商隐曾经写过“东风无力百花残”,现在的东风吹在脸上,刮在身上,与冬天的别无二致。一条单薄的裤子,毫无抵抗之力,冷风顺着肌肤肆无忌惮的游走。暖意渐少,寒意渐浓。

自从苏州回来之后,一直挺忙的,也不知道在忙什么。左手手腕的疼痛变得更严重了,连续贴了好几天膏药,并没有好转,昨天看了下贴膏药的地方变得又红又肿,应该是过敏了。夜里,皮肤的刺痒醒了好多次,不挠就痒,一挠就疼。

偶尔跟对象提起挣钱的话题,总是感觉到一阵阵的无力,就像溺水的人,拼命的想把头伸出水面,却一阵阵的呛水一样。那种窒息感和无力感,甚至有那么一瞬间有了放弃的感觉。不会游泳的人,在水里挣扎的时候,那种感觉要死亡的无助,现在想起来依然那么的真实。

上周四儿子店打电话通知该首保了,约了个时间把车送了过去。差不多快到中午通知自己可以去开车了,结账的时候看了下报价单 1800,问售后“首保不是免费的吗?”

“额,像这种豪华车首保是不免费的”售后小姐姐答道

“这又算豪华车了?”我自嘲到。她开始介绍相关的保养套餐,给算折扣之类的。最后权衡之下,选了个 5000 四次基础保养的套餐,送一次车身打蜡。这样算下来每次能稍微便宜一些,按照正常的保养周期10 个月或者 8k 公里,差不多每年一次,倒是也说的过去。至于那送的车身打蜡,其实也不值钱,一般的洗车店也就是 50-80 的价格,聊胜于无吧。

一年一年,每到算钱的时候,总是感觉没剩下多少,而至于自己的钱干了什么,却又说不出来,没增加什么资产,更没购置什么东西,总感觉莫名其妙就没了。

偶尔,想自己做点事情,不指望能够翻身,偶尔能挣点钱也是好的。做的项目,目前看来都不怎么靠谱,除了靠爱发电,至于将来?那自然是看不到的。

跟之前的同事做点外面的项目,价格也比较堪忧。一套系统,大大小小的功能算下来几万块钱,一分之后就更少了,一个人也就万儿八千的。但是投入的业余精力却并不少。

搞技术,呵,真的没什么前途。而至于其他的东西,自己又真的不会。就算是会,也没那个闲钱往里投。就这么一边抱怨,一边装死。

偶尔,也只能像鸵鸟一样把脑袋埋在沙子里。

昨天同事问题,有没有投集团的其他的岗位。现在的境遇,的确比较尴尬,公司没有新项目承接,大项目接不来,小项目看不上。其实至于现在自己是什么定位,自己也搞不清楚了。下面的几个人都分到了不同的项目里,还有人想要从下面拉几个人出去直接加入别的项目。现在自己也是实至名归的孤家寡人。

手上也没什么项目,旧项目早就交付了,偶尔运维支持,新项目没有。需要负责的东西也没有,虽然乐得清闲,但是不知道什么时候可能也真的没活干了。一波一波的裁员,自然不会停止,至于老板的想法,或者长远规划,早就不是自己所需关注的内容了。这种土皇帝制的企业,所有的政策和人员调配不过是老板一句话的事。

边缘化已经不是一天两天的事情了,至于后期怎么打算,自己目前没想法。还有一部分垫付的费用没有报出来,自然不会直接走。而集团内部找岗。只要投了,肯定人力就知晓。至于后期会发生什么,现在看来,也不甚明了。如果说哪天在青岛找不到地方去了,不知道这个岁数去南方是不是能好一点?

之前,总觉得自己无所不能,虽然没有盲目自信,但是总感觉努力总会能做成一些事情。而现在可能已经进入另外一个境地了,盲目自卑,跟不上潮流,搞不动技术,垂垂老矣。黄忠虽老,仍能拉三石之弓。我现在看着各种突飞猛进的技术,看到的只是自己被替换的那个瞬间,只是不知道这个时间还有多久到来,应该也没多久,快了,快了。

今天上午想着抢救下那个 妙控键盘,买的胶水到了。找了个按键试了一下,真的很不错,差点直接粘住动不了了,只能把胶水全部再扣下来。然后从二手东下单了新的妙控键盘。好在阶段有国补,算是薅了点羊毛,不到 600 就能拿下了。

人生,就酱紫吧。何必那么委屈自己,毕竟谁知道以后会变成什么样呢。

何必杞人忧天,如果天真的要塌,那就塌吧!

艹!

The post 春风无力百花残 appeared first on obaby@mars.

后知后觉

2025年3月17日 10:40

当习惯成为一种本能之后,变化就成了刺痛。很多时候,不愿意进行尝试,并不是因为新技术或者新的工具不好,而是因为自己的懒惰。上周在发版的时候,苹果应用商店的第一次审核被驳回了。其中有一条是设计问题,登录界面在 ipad mini 或者 ipad 下页面位置错乱,的确不看入目。

周六的时候在家里的 mac mini 上做了多模拟器测试,发现页面的确有很多问题,字体样式不统一,不同页面显示效果差距太大的问题。在这一瞬间变得异常的明显。

上图为 ipad pro

上图为 ipad,这么看其实感觉还好,但是对比一下就会发现问题了:

这种风格迥异的表现,的确让人感觉设计有些难看。而至于怎么修改这个东西,其实一时间自己也没太多的想法,于是先从登录页面开始修改,毕竟这些页面比较简单,修改起来应该也不会太困难。

鉴于上周对 cursor 的表现和功能比较满意,于是直接扔给了 cursor,cursor 果然不负期望,把页面样式进行了一系列兼容之后,的确也达到了自己的要求。如法炮制,让 cursor 把注册、忘记密码等页面一起修改了。就这么修修改改,周六一天就过去了。

周日早上,想着根据昨天的修改继续对日历页面等相关页面进行修改,刚提问了几个问题,就提示试用期已经过了,需要升级 pro 版本。鉴于之前看到留言说可以去闲鱼之类的买魔法版本,手机上没有闲鱼,去淘宝搜了下。不得不说,卖这个东西的是真多。找了个所谓的个人 pro 无限制版本。

购买之后,发了个激活码和激活教程,按照教程下载激活工具,使用激活码激活,发现可以的确继续提问了。

激活之后为了测试实际效果,想着在 mac mini 上也激活一下,然而此时令人抑郁的情况就出现了,提示激活码已用。mac 下无法激活。

此时宝子嚷嚷着要出去玩,只能暂时作罢。这几年开始建设大大小小的公园和游乐场,这马上就要有一个新的又开放了。

公园的停车场出入口还是封闭的,不过导航的时候阴差阳错的导航到了另外一侧,找了个土路把车停下啦,反而无意间解决了停车的问题。

那高高的铁皮围挡外面是一个二手集市,有卖各种衣服、鞋子、日用品、工具的。

听说之前这个二手市场蛮大的,现在能看到的就路边一点点,也有可能在别的地方也有吧。

公园游乐设施和各种场地都非常多,不过在高架桥底下,风特别大,尤其是天气不好的时候,稍微待会儿就冻的开始流鼻涕。

老城区周边的小区不多,目前看来新建不大可能,河的另外一侧是工厂,也没多少居民,所以能来玩的应该也基本都是开车过来的。

河边的树终于抽出了绿芽,有那么一点点春天的意思了。河里还有叫不出名字的水鸟在停留。喝水还算清澈,一眼能看到水底,但是却看不到什么小鱼之类的踪迹。

中午找个地方简单吃点东西,想睡一会儿,结果怎么也睡不醒,三个小时就过去了,醒了之后继续折腾上午的授权问题。看了下登录的账号,发现是一个不知名的账号,那么现在也就明白这个东西的原理了。

所谓的无限 pro 账号,本身就是假的。这个授权工具其实是一个自动账号登录工具,激活之后,工具会自动获取那些免费的账号,进行登录,登录之后就可以使用这些临时账号的额度了。授权是和电脑绑定的,所以这四十多块钱,其实是买了个所谓的免费账号获取工具,并且还限制绑定的机器。

想到这里,自然也不想再继续去纠缠这些所谓的无限 pro 授权之类的。如果要在自己的电脑上授权,至少需要 pc,mbp,mac mini 三套授权,而这个破玩意儿一个就要 40 块钱,关键还不是所谓的 pro 账号。那么购买就毫无意义,此时就不如直接买官方的 pro 授权了,于是思索再三订阅了一个月的 pro 20$,现在至少自己的电脑上就都能用来,要调试修改页面的时候不用来回切换设备拉取代码了。

让人有点好奇的是,这个东西对于 python 的兼容性要比 vscode 好很多。不需要复杂的配置竟然就可以直接运行 djaong 项目了,甚至连之前折腾了半天在 vscode 里面报错的代码现在也不会报错了。

这一点的确比 vs 要好很多,不是说 vs 不好,而是 vs 需要配置的东西太多,对我来说不友好,像我这种懒人,能用现成的 ide 的自然是用现成的 ide,不过现在看来使用 cursor 来替换 pycharm 也不见得不可行,最起码现在体验起来感觉还是相当不错的。

免费的东西固然好,然而,这种到处贩卖的免费的东西,就不见得好了。虽然花了钱,但是体验并没有那么好,如果只有一台设备的话也可以考虑。但是这个东西如果要在多端用,官方的反而更有性价比。

在这个东西出来这么久之后,才开始使用,并不是因为这个东西不好,而是处于习惯,总觉得现有的东西够用了,切换到一个新的 ide,自然免不了这种折腾,先入为主,基于经验的判断,也容易让自己不会轻易去尝试一个新事物。

现在看来,这个新事物的确有能力帮自己解决一些事情,尤其是在问题明确的情况下。之前一直说有个wp 有个更新提示,但是不知道是什么,知道昨天也发现了是 object cache pro,有了新版本,这个新版本安装之后依然是提示授权无效。

经过一系列提示之后,cursor 成功的破解了这个插件,创建了授权信息,改掉了各种升级配置。不得不说,在某些时候代码得风格比我要好,甚至连数据结构的拼装都比我要做的更加的完美。

后知后觉也是好的,最起码能晚点知道自己要被淘汰掉。

The post 后知后觉 appeared first on obaby@mars.

Cursor 另类应用 — 逆向分析

2025年3月14日 13:28

hacker

昨天登录后台的时候,发现 loginpress 的设置界面挂了,所有的数据样式都是 hidden。让 deepseek 给分析了一通,都是废话,没什么卵用。

今天上午直接让 cursor 分析了一下代码,让给出解决方案,发现依然没什么效果:

不过查看页面元素的时候发现了一段提示:

<tr class="secret_key_v2_invisible" style="display: none;"><th scope="row"><label for="loginpress_setting[secret_key_v2_invisible]">Secret Key</label></th><td><input type="text" class="regular-text" id="loginpress_setting[secret_key_v2_invisible]" name="loginpress_setting[secret_key_v2_invisible]" value=""><p class="description">Get <a href="https://www.google.com/recaptcha/admin" target="_blank"> reCaptcha</a> secret key. <br> <span class="alert-note">Make sure you are adding right  secret key for this domain. If it's incorrect may be you'r not able to access your website.</span></p></td></tr>

让 cusour 分析了一通,依然没什么效果:

不过此时已经基本确认还是授权的问题了,基于上面的废话改起来难度较大,搜索了一下,找了一个新版本的 loginpress pro。

https://wpe98.com/loginpress-pro-nulled/

按照文件的方法直接添加 hook 代码:

<?php
function bypass_license_verification() {
    add_filter('loginpress_license_check', '__return_true');
    add_action('admin_notices', function() {
        echo '<div class="notice notice-success"><p>License successfully nulled for demonstration purposes!</p></div>';
    });
}
add_action('init', 'bypass_license_verification');
?>

此时后台显示的确 ok 了,虽然功能已经激活了,但是页面看起来有些蛋疼,显示没授权: 

根据提示信息搜索就会发现代码位于loginpress-pro 2/classes/loginpress-main.php

大概浏览下代码,发现基本数据都在所谓的授权信息中license_data的结构内,直接让 cursor 给生成一个结构:

此时直接修改授权代码为:

public static function get_registration_data() {
        $license_data = array(
            'success' => true|false,      // 布尔值,表示许可证验证是否成功
            'license' => 'valid',         // 字符串,许可证状态,可能的值包括: valid, invalid, expired, revoked, missing, site_inactive, item_name_mismatch, no_activations_left
            'error' => '',               // 字符串,如果有错误时的错误代码
            'expires' => '2050-10-10',             // 字符串,许可证过期日期,可以是具体日期或 'lifetime'
            'price_id' => 4,            // 整数,许可证价格ID,用于确定许可证类型:
                                        // 1 = Personal
                                        // 2 = Small Business
                                        // 3 或 6 = Agency
                                        // 4 = Ultimate
                                        // 7 = Startup
        );
return $license_data;
}

测试了一下没效果,继续看代码,发现外面还套嵌了一层,cursor 给继续处理一下:

继续调整代码为:

$result = array(
            'license_key' => '',         // 字符串,许可证密钥
            'license_data' => array(     // 数组,许可证详细数据
                'success' => true|false,      // 布尔值,表示许可证验证是否成功
                'license' => 'valid',         // 字符串,许可证状态,可能的值包括: valid, invalid, expired, revoked, missing, site_inactive, item_name_mismatch, no_activations_left
                'error' => '',               // 字符串,如果有错误时的错误代码
                'expires' => '2050-10-10',             // 字符串,许可证过期日期,可以是具体日期或 'lifetime'
                'price_id' => 4,            // 整数,许可证价格ID,用于确定许可证类型:
                                            // 1 = Personal
                                            // 2 = Small Business
                                            // 3 或 6 = Agency
                                            // 4 = Ultimate
                                            // 7 = Startup
            ),
            'error_message' => '',      // 字符串,错误信息
        );
        return $result;

此时再看效果,就完美啦:

 

The post Cursor 另类应用 — 逆向分析 appeared first on obaby@mars.

屈从

2025年3月14日 10:07

在某一天,洗手的时候发现洗手台上看一条黑黑的东西,最开始的时候以为是脏东西,仔细看了一下并不是,而是出现了一条裂缝,并且还有不断蔓延的趋势。

为了避免哪天这个东西彻底完蛋,伤到人直接买了套新的。配送的的工人也挺厉害的,直接就给抱上来了。不过在安装的时候发现还是小了一些,很多地方原来的螺丝孔都盖不住了。

捉襟见肘,盖住上面就要漏出下面的,盖住下面的就要漏出上面的。最后只能选择盖住下面的,上面的漏着就漏着吧。

洗手台换了,之前用来装热水的暖水瓶也不想用了,直接买个小厨宝放到下面。燃气热水器的水到洗手间得等半天,这样最起码不用每天都兑水了。

没有提前准备插排,找了个插排临时顶了一下,晚上用水的时候发现问题了,插排比较旧,可能功率也是虚标的 2500w 的插排,带 1750 瓦的热水器,电线热乎乎的跟面条一样,软趴趴的。

不想等待,直接从美团买了条电线,为了防止功率不够,买的 16a 的。到了之后看了下袋子还调侃,在来一个:

去插的时候发现问题了,插座都是 10a 的,大力出奇迹,我把热水器插头给插进去了,但是墙上的插头却怎么也插不进去了。

对象调侃道,你就是手太快,还能退吗?

“退不了了啊,我都给拆了。不是怕功率不够嘛”

“你难道不知道 10a 和 16a 的插座不一样吗?”

“不知道啊,我觉得都是一样的,我给插进去了不是?”我一边说,一边展示硬插进去的插头。

“你这不行”

“ok,再买一个”打开手机,又下单一个,半小时之后终于用上了正常的插排。

一切收拾好,就可以继续看电影了,最近没怎么看电影主要是也不知道该看啥。前段时间终于把《鹊刀门传奇 2》给看完了,前天开始看《屈从》也是讲机器人助理的。

简单说来情节也挺老套的的,就是男主因为妻子生病了,然后为了照顾孩子(或者说孩子自己喜欢)挑了一个机器人助理(孩子选的)。后来机器人助理在跟男主看了一场电影,观影过程中实现了删除记忆和限制指令的功能,后来一发不可收拾。一步步的跟男主发生了性关系,后来就想替代男主的妻子。开始解决上位路上各种问题的故事,当然最后还是男主干掉了机器人,保全了家人。

所以,这个东西其实也蛮无聊的,或者叫做《性爱娃娃上位记》更合适?至于屈从,感觉也没什么好屈的,做的时候看表情不也蛮舒服的嘛!

看完电影洗刷完,发现从下午开始的苹果应用商店的审核终于过了。并且苹果的 connect 还是生成效果不错的宣传视频。

https://apps.apple.com/us/app/%E9%97%BA%E8%9C%9C%E5%9C%88/id6470903382

然而,在上架之后,杜郎表示 ai 的答复不尽如人意:

于是今天上午把模型从 v3 切到了r1.个人感觉效果稍微好了那么一点点,至于更长期的优化,这个只能看后期没有什么更加优秀的替代方案。

然而,接入了 ai 之后似乎感觉又有新的事情要做了:语音识别,tts,等等。至于什么时候做,看情况吧,等自己没那么懒得时候或许。

The post 屈从 appeared first on obaby@mars.

Cursor 初体验

2025年3月12日 17:54

鉴于 vscode 对于python 或者说对 django 的支持没有想象的那么简单,在配置各种环境之后依然代码报各种错误。所以对于 cursor 这个东西一直没怎么仔细体验一下。

当然,很多人对于这个东西可能体验了挺长时间了。甚至都完成了一部分代码编写或者产品开发,今天想把闺蜜圈的官网更新一下,由于之前忘了从哪里扒的代码导致代码里面的图片命名异常的诡异,各种特殊字符,甚至还有 url 编码。

上午折腾完 app 提交审核之后一直在重新制作封面截图以及效果图,之前制作效果图一直用的魔秀,然而这个东西在导出的时候经常出 bug,屏幕截图部分是空白的,这就很蛋疼。

这个东西说实话没那么好用,并且编辑图片就会出现错位的情况,智能创建新项目。

昨天搜了半天发现了另外一个在线工具:https://studio.app-mockup.com

体验下来效果还是蛮不错的:

并且提供了实时预览效果:

现在回到旧话题,用 vscode 和百度的 comate 试了一下:

给了一堆修改建议,什么事情都没干,右侧有个 zulu 稍微好一点,给了脚本,给了文档修改:

然而没这个东西的问题在于,资源中的图片文件名并不是 20%而是空格,这就导致修改之后的代码全部都挂了,图片都失效了。

最后来看下 cursor 的效果:

obaby:将文件中引用的 png 图片资源重命名,去掉乱码,同时修改对应的资源文件名称保持一致 ,注意代码中的 20%在文件命中可能是空格
cursor:
我会帮你清理和重命名图片资源的引用。我会先分析文件中的图片引用,然后提出重命名方案。
让我们先看看需要重命名的图片资源:
65716ff484999b1ed90199b5_Logo.png -> logo.png
65716ff484999b1ed90199b1_Pattern%202.png -> pattern_2.png
65716ff484999b1ed90199b0_Pattern%201.png -> pattern_1.png
65716ff484999b1ed90199b2_Hero%20Image.png -> hero_image.png
65716ff484999b1ed90199b8_Expert.png -> expert.png
65716ff484999b1ed90199ae_Health.png -> health.png
65716ff484999b1ed90199ad_Booking.png -> booking.png
65716ff484999b1ed90199ab_Keep%20Track.png -> keep_track.png
65716ff484999b1ed90199ac_Doctor%20list%201.png -> doctor_list_1.png
65716ff484999b1ed90199b7_Doctor%20list%202.png -> doctor_list_2.png
65716ff484999b1ed90199a8_Booking%201.png -> booking_1.png
65716ff484999b1ed90199aa_Booking%202.png -> booking_2.png
65716ff484999b1ed90199a9_Reminder%201.png -> reminder_1.png
65716ff484999b1ed90199b6_Reminder%202.png -> reminder_2.png
65716ff484999b1ed90199bb_Video.png -> video.png
65716ff484999b1ed90199a7_Play%20button.png -> play_button.png
让我帮你修改文件中的这些引用:
现在我已经帮你修改了所有图片资源的引用。你需要相应地重命名实际的图片文件以匹配这些新的引用。以下是需要重命名的文件对应关系:
65716ff484999b1ed90199b5_Logo.png -> logo.png
65716ff484999b1ed90199b1_Pattern 2.png -> pattern_2.png
65716ff484999b1ed90199b0_Pattern 1.png -> pattern_1.png
65716ff484999b1ed90199b2_Hero Image.png -> hero_image.png
65716ff484999b1ed90199b8_Expert.png -> expert.png
65716ff484999b1ed90199ae_Health.png -> health.png
65716ff484999b1ed90199ad_Booking.png -> booking.png
65716ff484999b1ed90199ab_Keep Track.png -> keep_track.png
65716ff484999b1ed90199ac_Doctor list 1.png -> doctor_list_1.png
65716ff484999b1ed90199b7_Doctor list 2.png -> doctor_list_2.png
65716ff484999b1ed90199a8_Booking 1.png -> booking_1.png
65716ff484999b1ed90199aa_Booking 2.png -> booking_2.png
65716ff484999b1ed90199a9_Reminder 1.png -> reminder_1.png
65716ff484999b1ed90199b6_Reminder 2.png -> reminder_2.png
65716ff484999b1ed90199bb_Video.png -> video.png
65716ff484999b1ed90199a7_Play button.png -> play_button.png
同时,对于压缩版本的图片文件也需要相应重命名:
*-p-500.png -> 对应的新文件名 + -p-500.png
*-p-800.png -> 对应的新文件名 + -p-800.png
*-p-1080.png -> 对应的新文件名 + -p-1080.png
你需要在 images 目录下执行这些重命名操作。我可以帮你写一个命令来批量重命名这些文件,你想要我这样做吗?
obaby:需要
cursor:
好的,我来帮你写一个命令来批量重命名这些文件。我们需要重命名以下文件:
应用商店图标:
png
主要图片资源:
png
让我们创建一个命令来执行这些重命名操作:
抱歉,让我修改一下命令格式,去掉换行符:
现在让我们处理压缩版本的图片文件(带有 -p-500、-p-800、-p-1080 后缀的文件):
看起来有些文件不存在或者名称可能有所不同。让我们先检查一下目录中实际存在的文件:
我看到文件名中包含了URL编码的空格(%20)。让我们修改命令来处理这些文件:
现在让我们检查一下是否还有其他需要重命名的图片文件:
让我们继续重命名剩余的文件:
让我们最后检查一下是否还有任何需要重命名的文件:
很好!所有的文件都已经被重命名了。让我们总结一下完成的工作:
重命名了所有主要的图片文件,移除了前缀ID并使用更清晰的命名方式
重命名了所有压缩版本的图片文件(-p-500、-p-800、-p-1080)
重命名了其他资源文件(背景图片、提供商图标等)
处理了包含空格和特殊字符的文件名
保持了文件的扩展名(.png、.jpg、.psd)不变
所有文件现在都有了更清晰、更有意义的名称,这样更容易维护和理解。如果你需要对任何特定文件进行额外的重命名,请告诉我。
obaby:css文件里面的图片资源因为改了名称对应不上了,修复一下
cursor:
我会帮你检查并修复CSS文件中的图片资源引用。让我先分析一下需要修改的部分。
首先,我会检查CSS文件中所有的图片引用:
我看到在CSS文件中有几个需要更新的图片引用路径。让我修改这些路径以匹配新的文件名:
很好,我已经更新了CSS文件中的图片引用路径。以下是我做的更改:
65716ff484999b1ed90199af_Hero Background.png → hero_background.png
65716ff484999b1ed90199a6_Background Grey.png → background_grey.png
65716ff484999b1ed90199bb_Video.png → video.png
65716ff484999b1ed90199c1_Background color light.png → background_color_light.png
65716ff484999b1ed90199bc_Background color yellow.png → background_color_yellow.png
65716ff484999b1ed90199c0_Background color blue.png → background_color_blue.png
这些更改与之前重命名的图片文件相对应。现在CSS文件中的图片引用应该能够正确匹配新的文件名了。
你需要确保所有这些图片文件都已经按照新的名称重命名。如果还有其他需要修改的部分,请告诉我。

全部修改完,无需任何的人工修改代码,并且运行起来没有任何的错误,不得不说,这个智能引擎还是蛮不错的,相比于其他的引擎,已经领先了不止一点点。

更新后官网:

https://guimiauqn.cn

https://dayi.ma

https://gmq.app

The post Cursor 初体验 appeared first on obaby@mars.

❤️闺蜜圈(大姨妈记录) APP/H5/小程序[置顶] — 3.0.06(更新时间:2025.03.12)

2025年3月12日 10:06

时隔半年之后,我带来了另外一次更新,这次主要是接入了 deepseek 的 ai 引擎(仅 APP 支持,小程序/h5 暂不支持),另外就是优化了体重曲线的显示。

3.0.06
数字版本号:388
2025.03.10
1.新增AI智能助理闺小蜜(接入deepseek智能引擎)
2.优化体重管理数据显示样式

下载连接:

https://gmq.app

https://guimiquan.cn

https://uni.h4ck.org.cn

二维码:

用了这么久一直没发现 app 有个致命的 bug,那就是如果经期跨月的话无法在下个月份结束经期。这次正好是上个月最后两天开始的,结果前几天出去玩的时候想记录结束时间,结果却发现无法结束。这种低级错误竟然没有测试到,也是大写的无语。

2024.10.08
2.3.56
数字版本号:366
1.修复经期跨月无法设置结束时间
2.修复无法设置月经周期和天数问题
3.修复了一些其他的已知bug

这个月乱七八糟的事情太多了,也着实没怎么顾上,之前似水流年 建议加个青少年模式。由于懒惰一直没加,前几天有人在逼乎上加了自己,提到 app 的问题,说自己的孩子 10 岁,初潮了,需要一个记录月经的 app,然就就找到了我开发的这个。所以,这次主要更新就是加了个青少年模式,区别就是青少年模式下把爱爱记录隐藏了,之前记录的数据不会丢失。

2024.09.04
2.3.46
数字版本号:358
1.高级设置增加青少年模式
2.修复了一些已知的bug

一眨眼,又一个月要过去了。感觉依然很忙,但是不知道在忙些什么。不管怎样,既然产品都上线了,就得持续更新不是吗?虽然主要的功能已经有了,但是感觉想做的事情还很多很多。这一次主要是增加了二维码名片以及扫一扫添加好友的功能,毕竟搜索的话还是有些麻烦。

2024.07.28
2.3.38
数字版本号:356
1.增加个人二维码
2.支持扫码添加好友
3.修复了一些已知的bug

懒惰真的是会上瘾哒,不过尽管如此,还是在有限的空闲时间内又更新了 一个版本。在这个版本中没有大功能的更新,主要是一些 bug 修复,增加了闺蜜备注功能,对于 app 改名,可能大家都不怎么用吧。毕竟也没看到几个注册后会更改用户名的。

2024.07.09
2.3.36
数字版本号:350
1.修复我请求的列表数据展示问题
2.优化找回密码页面功能
3.支持给好友设置备注
4.修复了一些已知的bug

可能是吃药的后遗症吧,晚上竟然失眠了。但是,白天困啊,要困死了。哼唧唧。

尽管如此,我还是发布了 一个新版本,希望没有出错。好在代码都是之前改的。

2024.06.25
2.3.26
数字版本号:346
1.日历模块支持滑动切换
2.优化日历页面显示问题
3.修复经期无法从今天开始的问题
4.修复日历跳转bug

经过一番折腾之后,我又更新了一个新版本,加入了推送相关的功能,包含推送设置、系统消息、健康消息、等等。不过受限于手机厂商问题,目前推送仅支持华为以及苹果,其他手机版本,只能等我继续完善了。

2024.06.19
2.3.18
1. 支持华为以及iOS推送
2. 增加推送消息管理,推送设置
3. 修复部分手机无法上传头像的问题
4. 修复了一些其他已知bug

 

最近有点时间,或者说是自己不想继续偷懒了,于是开发了另外一些之前自己一直想增加的功能。另外,在使用过程中发现的一些问题也一并修复了。

时间:2024.05.22
版本2.2.66
数字版本318
1.增加头像裁剪功能
2.修复闺蜜权限显示错误
3.优化身高体重录入功能
4.生日设置调整默认时间
5.优化数据分析体温曲线
4.修复了一些已知bug

距离上个版本发布也有些时间了,这几天一直在处理新版的一些问题。由于引入的组件越来越多,小程序包的体积已经超过限制了。好在最后通过一些操作解决了问题,所以这次小程序版本一并跟着更新了。

日期:2024.03.18
更新说明 2.2.28:
1. 修复某些月份日历显示不完整
2. 用户页面增加闺蜜圈百科以及视频
3. 修复了一些已知 bug
4. H5 版本更换背景图片

最近基于阿里云的服务器,增加了 一个类似百科的站点https://wiki.guimiquan.cn

H5体验版更换了背景图https://h5.guimiquan.cn

官网地址:https://guimiquan.cn    https://dayi.ma

闺蜜百科: https://wiki.guimiquan.cn

iOS 版本:

下载地址:https://apps.apple.com/us/app/%E9%97%BA%E8%9C%9C%E5%9C%88/id6470903382

二维码:

APP安卓版本:

下载地址:https://www.pgyer.com/dayima

二维码:

备用下载链接:

https://app.guimiquan.cn

http://uni.h4ck.org.cn

百度应用市场(安卓):

应用宝(安卓):

下载地址:https://sj.qq.com/appdetail/ma.dayi.app

小程序版本扫码体验:

H5 在线体验版:

https://h5.guimiquan.cn

H5 版本二维码:

系统截图:
个人记录:
闺蜜记录:
个人 中心:

The post ❤️闺蜜圈(大姨妈记录) APP/H5/小程序[置顶] — 3.0.06(更新时间:2025.03.12) appeared first on obaby@mars.

钥匙串呢?

2025年3月9日 15:37

玩了几天之后,应该干点正事了,上周提的接入 ai 引擎的事情可以着手实施啦。

然而准备打包闺蜜圈 app 的时候提示证书过期了:

打开应用程序搜索,却发现这个东西失踪了,这就离谱:

网上搜了一下才发现这个东西的确是没了,但是在系统目录下还有:

ls /System/Library/CoreServices/Applications

直接 open 命令可以启动:

open /System/Library/CoreServices/Applications/Keychain\ Access.app

启动的时候会提示这个东西:

使用密码来管理相关内容,但是这个破玩意儿就很奇怪,明显没有钥匙串的全部功能啊:

真的就是一个 tm 管理密码的,证书之类的内容直接找不到,那这个破玩意儿凭什么能替换钥匙串?

这波替换真是替换的莫名其妙,纯粹瞎整,垃圾!

 

品味江南(三)–虎丘塔 东方明珠

2025年3月10日 13:29

时间总是那么不禁用,三天时间看似很长,然而,一眨眼就到了最后一天了。而至于行程,今天似乎也不能安排太多。

对于当地的景点,我并没有了解太多,基本是对象说去哪里就直接去了。主要的宗旨就是尽量选择人少的地方,所以,最后的一天的上午定了虎丘塔。

路上经过虎丘婚纱城,据说挺便宜的,然而,现在买套婚纱也没什么用,关键是也没地方放,毕竟没有三百平的大房子。

虎丘塔,苏州云岩寺塔,坐落于江苏省苏州市阊门外山塘街虎丘山山门内8号,因坐落于虎丘山而得名,亦被称为虎丘塔。这座塔的创建历史可追溯至五代末后周显德六年(959年),并在北宋初(961年)最终建成,至今已有逾千年的历史。它不仅是宋塔中时代最早的典范,更以其宏大的规模和精巧的结构而著称。塔身呈八角形,共有七层,仿照木构楼阁式样建造,每一层都巧妙地装饰了腰檐和平座,总高度达到四十七米七。遗憾的是,原云岩寺在清咸丰十年(1860年)的一场大火中完全焚毁,然而这座塔却依然屹立在山巅之上,成为了苏州这座城市的标志性建筑。

不出意外,通向景点的路上依然是站满了导游,见到人就问要不要导游。

这水乡的景色,看多了果然也灾难看出区别。好东西吃多了也会腻,此时这种景色,却没有开始见到的时候那般的惊艳。

这个鼎下面的一行字,写的是?周王子吴鼎?

这憨憨泉的井水,喝了会变得憨憨的吗?

古真娘,据说是和苏小小一样。不过另外一个在西湖边。果然江南男子多才俊,江南女子俱风情。

剑池宝子没看上,也不关注干将莫邪,而是注意力都到了前面的大石头上。来回爬上爬下玩了半天。

入解脱门,就真的解脱了吗?

终于见到虎丘塔本塔了,肉眼可见的是斜的。

并没有往两侧继续游览,原路返回就到了景点入口了。

至于最后,自然是去上海看东风明珠的大球子,虽然距离不远,但是各种限速堵车,七十公里开了一个半小时,这个时间花费的确让人有些抑郁。在苏州开了几天车,导致现在一进隧道就莫名心慌,不知道该走那个车道,而导航在隧道里的效果,基本等于零,播报也不及时,就导致会错过出口,而现在,路口看不到车道引导线内心也会莫名的心虚,生怕走错了路线。

路上还能看到无轨电车的电线。

最终还是到了球子的对岸,一张照片,就彻底结束这次行程了。

毕竟,下次再带他们来这里不知道是猴年马月了。

The post 品味江南(三)–虎丘塔 东方明珠 appeared first on obaby@mars.

品味江南(二)–夜半钟声到客船

2025年3月10日 11:05

早上起来打开电视,破电视依然发出各种诡异的动静,关键是两个房间的电视都是同样的毛病,这就很神奇。吃早饭的时候,跟前台说了一下。前台表示安排人去换电视,这个问题算是暂时解决了。

然而,刚开始是好的,过个大概半个小时,破电视又开始了之前的毛病。

就这种破电视,的确难以让人不上火,两个房间同时有问题,竟然没人投诉也是神奇。

到了苏州总得去寒山寺看一眼,来都来了,怎么也得来个到此一游。昨天发现问题之后,上车第一件事情就是关自动启停,开 auto hold。

鉴于这 1.5t 的弱鸡动力,把档位也直接换到了 s 档,多多少少算是解决了,油门踩到底半天都没动静的问题。路上偶遇的法拉利,不得不说是真的帅啊,这个东西,出生的时候没有,这辈子大概率也不会有了。

本来以为自己出门挺早的,到了寒山寺才发现,到处都是人。

拜佛烧香的人不算少。并且有很多年轻人。

而对于我来说,吸引我的在于寒山寺的钟声,这到了,怎么都得去敲两下。价格倒是不算贵,五块钱三下。

除此之外,就是带着宝子到处溜达,随便看看,宝子的姥姥就到处去磕头结缘,所谓结缘自然是捐钱,走的时候在车上说,一共捐了 200 左右,很多地方都送了一些。

在来之前,看到还有另外一个景点,西园寺,说更大一些,门票也便宜。这寒山寺转完了,自然就该去另外一个了。

只是已近中午,宝子也没力气了,就沿着里面简单的溜达了一圈。

所有的景点,看多了,自然没有太大的区别,香客依然是络绎不绝。

然而,这次停车场停的有点远,往回走没办法,开了辆共享单车,算是把问题解决了,跟宝子两个人骑一辆,她坐在前面,自己勉强坐在后面。

午饭已经两点多,排队的人依然很多,不过最终还是吃上了松鼠桂鱼。

跟糖醋鱼的口感差不多,不过鱼切的更精致一些。然而,为了吃这顿饭,让自己好一通绕,到了苏州才发现,路口的车道线是可以随意安排的,左转可能在中间,可能在右边,可能在左边;调头可能在左边,可能在中间,可能在右边;直行可能在左边,可能在右边,可能在中间。

每次开车出来,都感受到了苏州的强烈的恶意,到路口就得先看车道指示线。而到了苏州中心的底下隧道,更懵逼了,围着一个地方转了三圈没转明白,后来找个口钻出来,重新开导航又钻进去,对象就在一直叨叨,你慢点,你慢点,但是在路上真的没法慢啊,都是车怎么慢。在下面绕的时候,跟着前面的苏 E 转了三圈也是服了,看来这当地的车也不明白怎么转。

吃完饭就可以去秋裤喽拍照打开啦,不得不说,造型还是蛮别致的。

下午带宝子回酒店写作业,晚上继续出门,这次姥姥依然不想动,只好让他在酒店呆着。

晚上到了再次到了石塘街发现停车场入口排队了,转到另外一个停车场,看了下距离 1.4km,好在路边有电动车,租电动车前往,四个人两辆车。

这黑咕隆咚的小路,如果不骑电动车,真的还去不了。

看了一圈,宝子也没什么想吃的,买了几串麻辣烫,算是解决了晚饭,最终就是去网红桥拍照,这夜色阑珊,倒是蛮出片的。

现在旅游,不就讲究一个出片就完了。

The post 品味江南(二)–夜半钟声到客船 appeared first on obaby@mars.

品味江南(一)博物馆打卡记(7)–拙政园、博物馆

2025年3月10日 10:25

距离上次出去玩,已经又过了大半年的时间。总说想走就走的旅行,然而,现在一个人的旅行似乎已经无法达成了,也没那么多自由的时间来到处跑。依然有很多的想法停留在愿望阶段,十年前在厦门的时候,就想着等哪天考了驾照,买辆车或者租辆车,沿着丝绸之路走一趟,主要是内心对于那个广袤的沙漠依然充满着无尽的向往,只是十年后,车都买了三辆了,驾照都换了一次了,依然没有达成这个愿望,有时候提到这个,对象总说,距离太远了,太累了,不安全。

然而,带着宝子短期旅行的想法,实现起来就变得容易的多了,就近找个目的地,提前买好机票,预定好车辆,就可以准备出发了,也不用花费太多的时间去准备,简单的收拾下行李,轻装上路带上人就可以了。

七点多的飞机,早上四点多就得爬起来准备出发了。机场停车场一天 100,三天下来就得 300,找了下附近的停车场,一天 20,并且提供接送机服务,这么一算,能省不少钱,最起码,租车的油费就能省出来了。

毕竟幸运,飞机没有晚点,正常的时间到了机场,取车的地方也算比较好找,然而,取到车的时候发现两万公里的车,右边车门下方已经蹭的不成样子了。围着车转了一圈,有问题的地方拍照记录。签字就可以开走了,这是第一次开 q3,座椅调了半天总感觉很别扭的样子,车机折腾了半天发现 carplay 连不上,只能连蓝牙,自习查看提示信息才发现需要用数据线连接,不幸的是只有 typec 的口,只得作罢。

收音机的音质感觉也挺差,但是这块 20 万的车,这个音质的确有点难绷。

手机导航,直奔拙政园,等到目的地也差不多十点多了,正好可以游览一番,毕竟这个点去酒店也办不了入住。

一路下来这 1.5t 的动力,让人一言难尽,车子的油门行程特别长,但是刹车行程又特别短。一脚刹下去感觉硬邦邦的都踩不动,不知道是这辆车的问题,还是所有的 q3 都是这样。

停车场就在河边,路的另外一侧是各种汉服体验店,宝子表示想体验一下。只得带着宝子去化妆体验,趁这个功夫折腾了下车的音乐,总算是切到了手机蓝牙,这样一来音质的确好了很多。

白墙灰瓦,充满了自己对江南运维的想象,似乎应该就是这个样子。小桥流水,蓝天白云,或许这就是江南水乡的样子吧。

化妆也的确是够费时间的,一折腾差不多一个小时过去了。当然,最后换好了衣服还是美美哒,然而,就是如果拍合照的话,其他的人就变得格格不入了。

景区门口,到处都是招揽生意的导游,虽然是周五,但是人真的不少,到处人流如织。对于这种江南园林,按理说应该找个导游,介绍下各种景观的设计理念,各种人物风情。然而,现在带着孩子出来玩,目的也很单纯,其实就是为了玩,让孩子看看,哪怕哪天听过了,等后来想起来的时候,依然是脑袋空空,所以不听也罢。

多数小姐姐也是打扮的漂漂亮亮的,单纯是为了打卡。为了这江南的美景,自然该配上的精致的装扮。

期间跟宝子坐一起准备拍照的时候,一个小姐姐看着我们对面的支架和手机,问,需要帮你按一下吗?

“不用啦,谢谢”我扬了扬手里的遥控器,说完了其实有点后悔,该让小姐姐帮忙按一下的,毕竟这么可爱的小姐姐谁不喜欢呢,在那一瞬间发现自己爱上她啦。可惜手机都不在手里,不然可以给她拍个照啊,等拍完拿手机的时候发现她已经走了。

这种走马观花式的游览,自然不会耗费太多时间,转出来之后,距离预约的博物馆的时间还差一个小时,好在提前半小时就可以进入了,也算是节省了不少时间。

苏州博物馆看起来,设计也是极具江南美感,门口就有无数的人在拍照打卡。

至于博物馆内部,那自然拍照打卡的人就更多啦。

一层薄纱,勾勒出窗外的风景,别具一番韵味。

而至于馆内的藏品,没有解说,自然也不懂,主要是感觉所有博物馆的东西,看起来都差不多,品类也没有太大的区别。

自然,重要的是当然也要给宝子打卡啦。这样,在每年写素质考评的时候就有照片可以贴了,哎,到处都不忘完成作业的家长也是的确无奈。

楼下的水池,也是打卡拍照的小姐姐。

来都来了,总得拍照留念不是。

出口,水池边的风景也美不胜收。

总感觉这种泼墨画版的感觉,到了江南才算是满了韵味。

从博物馆出来,就穿了忠王府,太平天国,义和团相关的文物陈列了不少。

这是看着这天王天父……的落款,总感觉批阅点东西得比别人多些好多字。

溜达完,到酒店办好入住,不过不得不说,这几次希尔顿的体验的确是够差,这次也不例外,走廊里有股诡异的味道,酸溜溜的。电视还周期性的发出噗噗的声音,后来直接就把电视关了。

晚上,宝子和姥姥姥爷走不动了,也不想出门。于是带对象出门去石塘街夜市。

周五停车场还算方便,没多少人。沿街溜了一圈买点吃的,油氽团子自然不能错过,还是青团,体验了一下蟹黄面,然而饭店里也有一股诡异的味道。不过这 138 一碗的面,倒是说的过去,没有网上说的那么不堪。

但是真的值 138 吗?我觉得没那么值。

买好东西,溜达一圈,也该回去了,毕竟还得给他们带吃的。

路上发现车还没刹停发动机已经熄火了,方向盘都掰不动,这个自动启停的逻辑,的确让人头大。看着扶手那里那个 A 是亮的,按理说应该是关了自动启停了,于是再给按灭。到了下个路口发现依然还是熄火了,顿时就头大了,所以这个到底是怎么才是生效的?

直接头大,直到后来才发现,扶手那里是 auto hold,中控台的那个才是自动启停,但是这俩 A 真的好像啊,真的分不出来。

我不配拥有题目

2025年3月6日 10:16

在当前这种形势下,全民狂欢的情景却感觉越来越多了。一次次的出圈,似乎不断再刺激所有人的 G 点,一次次的冲击,也让所有人欲罢不能。

年前的 sd 出圈,过年的人形机器人,年后的哪吒。不断的冲击着最敏感的地方,不断的在 G 点上用力冲刺。甚至很多地方都开始出现很多魔幻的场景。在这一次次的狂欢之下,似乎已经称霸全球,无所不能了。中国人低调内敛的品德,在这一次次的冲击中,变得不再存在,似乎已经无所不能了。

然而,现实真的就是这样吗?科技进步总是好的,但是,太多的东西容易在那些无知网民的一声声和彩中迷失自我,逐渐被捧杀。动辄遥遥领先、动辄是最好的。于是,全世界除了自己,都成了战五渣。一波波宇树机器人已经完全超越波士顿动力的文章,评论,短视频,铺天盖地而来。一波波ds 被攻击群雄出手捍卫 ds 的热血假新闻。

然而,这种高潮下带来了什么呢?就业压力的降低?内卷的缓和?购买力的提升?似乎都没有,除了高潮一无所有,甚至一而再再而三的发送个红消费券,鼓励大家去消费。现在正在开的会也在大谈特谈 ai。跟多年前的元宇宙如出一辙,唯一的不同是 ai 泡沫已经破灭了一次了,这是第二次。

而这次来的更猛烈了,ai 入侵到了所有的领域,所有的行业都在拥抱 ai。ds 的开源布局,让原来的闭源派也做出了改变,这是好事。然而,ai 能力的提升,让所有人的岗位都变得岌岌可危了,现在已经不是人类在竞争了,ai 也参与到了这个竞争中。

ai 医学报告出具,ct 超声诊断;

ai 政府报告解读;

ai 辅助代码编写,生成;

……

与我而言,最主要的就是程序员的饭碗,真的没那么好端了。公司从年前开始所谓的 ai 辅助编程的研究和培训,终于,年后这审判的时刻快到了。预计不久就要开始新的一轮裁员了,这次的目标在前端工程师。

然而,在这样的浪潮下又该怎么办?其实除了跟上去似乎没有任何的办法了。我也开始对接 ai,也在引入各种引擎来做一些事情,客户也在拿 ai 来说事情,吹自己的东西。

昨天有点时间,开始给之前的产品接入 ds,目前基本集成完了。

然而,ai 真的能解决所有问题吗?并不会,在用了这么多天之后,ai 并不是总能解决问题。哪怕让她识别合同文件,可能几次识别到的数据和内容都是不一致的。

不管实际效果如何,现在已经到了无所不用,无所不能,无处不在的境地了。如果没有所谓的ai 的加持,产品自然不够高级,吹牛自然不够高大上。

只是,ai 来之前,很多人觉得这个东西会给生产力带来革命,可能很多人都没想到,这个东西除了给生产力带来了革命,顺便把生产者的命一块给革了。

这一波波的冲击刺激下,应该用不了太久就高潮了,不管是射了,还是喷了。高潮过后,总会进入一段时间的沉寂期。

现在跟脑力劳动者竞争,过不了多久就开始跟体力劳动者竞争了,自然服务行业也躲不过。

技术的洪流滚滚向前的时候,多数人都会跟着灰飞烟灭。

也许,是时候该想条别的路了。

再谈 Python自动生成 pdf 文件

2025年3月5日 17:25

pdf 这个东西,不得不说,真的是受人欢迎,任何时候下载个文件或者报告之类的,都想弄个 pdf 版本。当然,这个东西的好处是不管在哪里看,样式基本都是一样的。

然而,缺点也很明显,没有办法直接生成 pdf 文件,当然,通过各种库可以直接将图片转为 pdf。然而,对于复杂格式或者需要使用模板来创建 pdf 的时候,就变得有些麻烦了。

def converImageToPdf(img_list):
    pdf = fitz.open() PyMuPDF
    pdf_document = fitz.open()  Creates a new PDF
    #遍历图片文件夹中的所有图片文件
    for img_url in img_list:
        img_local_file = download_image(img_url, 'confirmd_images')
        img_path = os.path.join(img_folder, img_file)
        img = fitz.open(img_local_file)
        img_rect = img[0].rect  Get the rectangle of the first page of the image
    #Create a new page with the same dimensions as the image
        pdf_page = pdf_document.new_page(width=img_rect.width, height=img_rect.height)
    #Insert the image into the new page
        pdf_page.insert_image(pdf_page.rect, filename=img_local_file)
    #保存PDF文件
        img.close()
    
    file_name = random_file_name('pdf')
    if not os.path.exists('confirmd_receipt'):
        os.mkdir('confirmd_receipt')
    pdf_document.save(os.path.join('confirmd_receipt/') + file_name)
    pdf_document.close()

依赖于fitz

pip install fitz

之前写过基于 oss 的:

Python生成Pdf报告

那么没有 oss 呢?其实此时最简单的办法就是基于 liboffice 了。

# 安装 LibreOffice(Ubuntu/Debian)
sudo apt-get install libreoffice

# 验证安装
libreoffice --version

代码:

import subprocess
import os

def convert_to_pdf(input_docx, output_dir):
    try:
        # 创建输出目录(如果不存在)
        os.makedirs(output_dir, exist_ok=True)
        
        # 执行转换命令
        cmd = [
            'libreoffice', '--headless', '--convert-to', 'pdf',
            '--outdir', output_dir, input_docx
        ]
        result = subprocess.run(cmd, check=True, capture_output=True, text=True)
        
        print(f"转换成功: {input_docx} → {output_dir}")
        return True
    except subprocess.CalledProcessError as e:
        print(f"转换失败: {e.stderr}")
        return False
    except Exception as e:
        print(f"发生错误: {str(e)}")
        return False

# 使用示例
convert_to_pdf(
    input_docx="/path/to/document.docx",
    output_dir="/path/to/output"
)

不多此时大概率得到的 PDF 文件会是乱码:

这一堆框就很专业,应该是没有字体导致的,安装字体文件:

# Ubuntu/Debian
sudo apt-get install fonts-wqy-zenhei fonts-wqy-microhei fonts-noto-cjk

# CentOS/RHEL
sudo yum install wqy-zenhei-fonts wqy-microhei-fonts google-noto-cjk-fonts

# 刷新字体缓存
sudo fc-cache -fv

验证安装:

# 查看已安装的中文字体
fc-list :lang=zh | grep -E "WenQuanYi|Noto"

# 预期输出示例(显示已安装字体路径):
# /usr/share/fonts/truetype/wqy/wqy-zenhei.ttc: WenQuanYi Zen Hei,文泉驛正黑:style=Regular
# /usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc: Noto Sans CJK JP,Noto Sans CJK JP Regular:style=Regular

如果依然有问题,那就修改系统配置:

# 检查当前 locale
locale

# 生成中文环境配置(如未安装)
sudo locale-gen zh_CN.UTF-8

# 临时设置环境变量(测试用)
export LANG=zh_CN.UTF-8

# 永久设置(修改 /etc/default/locale)
sudo nano /etc/default/locale
# 添加内容:
LANG="zh_CN.UTF-8"
LC_ALL="zh_CN.UTF-8"

或者转换的之后指定字体:

def convert_with_font(input_docx, output_dir):
    cmd = [
        'libreoffice', '--headless',
        '--env:UserInstallation=file:///tmp/libreoffice-altprofile', # 使用独立配置
        '--convert-to', 'pdf:writer_pdf_Export:{"Watermark":{"type":"string","value":" "},'
                         '"SelectPdfVersion":{"type":"long","value":"1"},'
                         '"UseTaggedPDF":{"type":"boolean","value":"true"},'
                         '"ExportBookmarks":{"type":"boolean","value":"true"},'
                         '"EmbedStandardFonts":{"type":"boolean","value":"true"}}',
        '--outdir', output_dir,
        input_docx
    ]
    subprocess.run(cmd, check=True)

此时多数就能解决问题了:

抢救妙控键盘「 拆键帽」

2025年3月3日 16:14

就请忽略美颜吧,问就是高 P。哈哈哈。最近感觉乱七八糟的东西都开始坏了,莫名其妙的就完蛋了。上个月家里 mac mini 的妙控鼠标坏了,充不进电去,一直连不上。前几天卫生间的洗脸盆又出现了裂纹,并且有越来越长的趋势。

上周喝饮料的时候又把饮料打到了 mac 的妙控键盘上,导致 R 键变得非常难按,一度以为是粘住了,周末的时候带回家,用精密仪器清洗剂清洗了一下,发现效果不大,并且两外的接个键也变得按不动了。想着晾干了应该就行了,然而,今天到公司才发现不但按不下去,是直接就没反应了,这下就尴尬了。尝试修复无果,中午回家吧家里的机械键盘带来了,然而更扯淡的是苹果的笔记本识别不了键盘上的 f 键,于是这个键失灵了,怎么都无法输入 f。这尼玛。

上午在各种群里问,大家的答案都是买新的,哈哈哈。就离谱,就这么换个键盘的确有点贵,关键是肉疼啊,七百块钱,就这么没了?

就在刚才,又尝试拆了一下,这次很顺利的就拆下来了。问题也找到了,底下的薄膜移位了,卡住了上面的机械结构,这尼玛真是无语了,应该是喷的时候压力太大,都冲跑了。

发移位的薄膜重新推回去,按上键帽就好啦。

拆的时候,撬下面,轻轻翘起来,往下推就下来了。

一个手拍的,有点抖。家里的鼠标,在不断的充电尝试下又给激活了充上电了。最终也能用了,这么看来苹果的东西貌似也没那么烂。嘎嘎。好吧,省了 700 块钱,嘻嘻

 

自欺欺人

2025年2月28日 10:09

(写在前面,这个没有嘲讽的意思哈,如果看懂了这张图。我不也没胸也没颜值吗,所以,对于那么没有的总是比较容易敏感。如果要嘲讽,也是嘲讽的我自己)在时间的摧残 下,所有感觉所有的东西都已经经不起仔细观察。一旦放到放大镜下面,看到的都是岁月的痕迹,斑蚀的坑坑点点。哪怕再多的素颜霜也填不满那些坑洞,修容笔再也修复不出年轻的容颜,再超清的摄像机镜头下,发现,自己真的老了。

科技的几部,太容易让一个人沉迷在幻境中。沉沦沉沦说:“美颜偶尔用用还行,现在短视频里的太多的美颜美女,搞得男生对美女的定义已经严重脱离了实际~”。其实有何止是男生对美女的定义脱离了实际,其实女生也是一样的。多年以前,没话照片还得靠专业的 修图小姐姐,或者偶尔靠美图秀秀,现在,所见即所得,靠实时的美颜美体,已经很轻易就能把自己 p 成蛇精脸。靠手机,靠 app 已经解决了很多人关注的写真问题。

而除此之外,身材不好的也有了别的解决办法,ai 换脸,甚至 ai 写真,能给你生成各种想要的效果。不过有的时候,也不见得那么尽如人意,头图我是想生成一个自欺欺人尺的,但是,这个理解能力总是不是很好,生成了很多,但是效果一般,最后的头图是我自己又p 了一下得,这个是原图:

对于刻度的理解,明显是有问题的,当然,还有其他的,例如下面的:

尽管如此,生成的这些图片身材比我的好多了。杜郎说第二个身材我能笑晕过去:

其实第一个是想实现一下网上的那个捣蒜舞的效果,至于第二个,就是然她打开车门上课,事实上,第二个真的做到了。就是开门的方式有些奇怪。

不管让他们给生成什么,都能做到,哪怕最后效果没那么好,没那么高清,但是用来自欺欺人真的是足够了,就这身材,那是笑晕,直接高兴死都成!

前几天和杜郎聊天的时候,dujun 杜郎好心提醒到关于隐私的问题。其实,出去拍照哪有什么隐私啊。所有的底片除了在摄影师的相机上,选片的电脑上,修复的电脑上,最后还会被用网盘分享出来。到处都有照片的痕迹。他说可以自己在家拍,保持最原始的样子,可是,最原始的样子,真的不好看。如果连自己都糊弄不过去那又有什么保留的价值呢,所以,到底还是得靠自欺欺人活着。

然而,时间摧残的不单是自己,还有各种身边的物件。之前为了能给小六子的车机联网,买了个随身 wifi,期间也出过各种问题,断网之类的,但是基本断电重启都能解决。

终于这几天扛不住了,哪怕 wifi 连着,也打不开网页,只好从二手东又买了一个。

虽然昨天上午就到了,其实到下午才看到实际的效果,整体来说,体验不错,尤其是那个小屏幕感觉还是非常超值的,各种需要的信息都可以显示,甚至,连管理后台都不用登录了。

原本约的上午十点半的拍照,稍微折腾了一下,就到了十点四十才从家里出门。

为了方便换衣服,直接穿了一条超薄的裤袜、短裤。虽然外面的温度只有不到十度,但是整体感觉还算可以,没有想象的那么冷。到了之后,补交尾款,开始选衣服,化妆,不过,由于没有提前选好要拍的样式,在眼花缭乱的照片中,找自己喜欢的风格,还是颇有难度的。

选了十几分钟,在试衣间也看了一下,就草草的定了几套衣服。然而,有一套白色小吊带还是太瘦了,都钻不进去。一套小西装也有点瘦,就让人有些抑郁,减肥的成果依然不怎么样。

最后还是选择一条白色吊带,黑色长裙,粉色短裙。

其实,坐着从上面拍照,看起来还算是不错,对吗?

然而,实际拍的时候发现那个粉裙子实在是太短了。不往上拽漏胸,往上拽就漏……。一瞬间体会到穿那种齐逼小短裙的效果了,只是这个裙子比所谓的小短裙还短。不过也还好吧,有肉色的内裤和裤袜。勉强能拍。

而至于实际出片效果,那就只能靠摄影师以及后期了。

今天早上,起了满天大雾,到处白茫茫的一片。

这漫天的大雾,或许,不只是要迷眼,最好也能迷心吧,至少不用再自欺欺人。

师傅,我要学美颜

2025年2月24日 11:05

每到周末,总感觉有忙不完的事情,有时候想测试点东西,还得陪着宝子到处跑,感觉比上班还忙。

周五的时候,学校的小记者社团又开始在组织活动,一个是寂寞的空军基地,另外一个是民生银行,考虑到寂寞实在是远了点,开车过去一个多小时,又不放心让宝子自己坐大巴去。就选了民生银行的活动,好在时间也比较合适,上完钢琴课,早点走应该能赶上。

跟钢琴课老师说了下提前十分钟下课,开始往银行赶,停好车发现距离集合时间刚好差十分钟。也有小朋友陆陆续续的到了,十点多银行的工作人员结合点名之后就带着小朋友进去了,家长不让跟着,开始又另外的工作人员给发放防诈传单,儿童账号的介绍之类的。对这些东西都没什么兴趣,就在那里刷短视频聊天。

刷的正嗨的时候,过来一个工作人员问,你要办贷款吗?20 万-40 万,基本秒过。

听到这个,我抬头扫了一眼坐在那里的家长们,看着似乎也没比我高贵有钱多少啊,咋就奔着我问?见我不吱声,又重复了一遍。

“不用了”我答道,刚要低头刷新手机,她接着说,“很方便的,下载个民生银行的 app 就能申请……”

“不用了,谢谢”,直到这时候她才离开,本来还想着给宝子开个账号,把她那几万块钱的压岁钱给转过来。这奔着让我来贷款的,瞬间 tm 就不开心了,不折腾了,不够恶心人的。我也没散发着浓浓的穷酸味吧?

参加完活动,马不停蹄往家赶,宝子的小姨中午要带孩子过去吃饭。本来还想着在外面吃点,休息下下午就去打网球了。这下还得赶回去,得,又折腾一趟。

虽然已经立春很久,连雨水节气都过了,似乎今年的倒春寒更加的猛烈一些,周六的时候,很多的地方都下雪了,只是,李沧没下,看着路上很多车上一层积雪,让自己一度以为跟他们处在了一个不同的季节。

寒风依然猛烈,温度又降到了 0 度一下,下午宝子去打球,自己在体院馆附近瞎溜达,找了个按摩的地方,90 去按了下后背。刮痧的时候,疼的呲牙咧嘴,差点就喊出来了。

晚上陪宝子看《哪吒之魔童降世》的时候对象提议早上去沧口的早市买早餐,那个点自己着实不愿意起床,但是,为了所谓的爱情,还是要起的不是,谁叫爱呢。宝子嚷嚷着她也要去。

周日一早,不打到七点就被叫起来,说去买早餐。看了下宝子,还睡得很沉,就没惊动她。上车打开 导航,设置目的地 13km。感觉也还好吧,似乎也没那么远,上次早上跨越大半个城区去买油条已经差不多快十年了。

看完之后,问宝子想不想看 2,宝子稍加思考说,要看。于是又预定了周日下午两点的《哪吒 2》,再加上宝子跟她小闺蜜约好了十一点去世博园,这下周日的行程也满了,还得去给她当司机,陪她观影。

沧口的早市人的确多一些,吃的东西也多一下,到了之后真的看到什么都想吃,肉夹馍、鸡蛋汉堡、油条、豆腐脑、宝子、馄炖……,可惜,也吃不了那么多啊。

这才是早餐该有的样子。

早上吃完饭,稍微收拾下,也就该出门了。世博园加了很多的装饰,树上挂满了熊猫:

不过天气稍冷,到处还是荒凉的感觉:

小朋友在一起总是也玩不够,打电话约见面时间,有时候她也说不清楚目的,就让她提高表达能力,把要说的事情先说清楚。有时候觉得也是严格了一些,有时候自己也有这个问题。

十二点多从世博园赶到万达,简单吃点东西,时间尚早,跑到书店转了一圈。看了下漫画,感觉也蛮有意思的:

让一个女子去怕是有危险,那就让一个男子去吧,😂

终于快开场了,到顶层的影院,取票,入场,2 号厅不是所谓的巨幕,相对来说人还少一点,买票的时候,看巨幕厅已经人满为换了,两两侧的边边都没剩下。

看 2d 才发现,那个藕竟然不是买的,五彩斑斓的白,这个看 3d 的时候的确看不出来。

不过,小朋友依然不少,基本都是家长带孩子看的,但是相对来说体验也还可以,并没有孩子大吵大闹。

看到岩浆碳化后的陈塘关的居民,其实还是有些稍感不适,过于写实的手法,让这个悲剧更加的悲情。天灾人祸之下,不过都是蝼蚁,连自保都是奢望。之前说自己是那个土拨鼠,现在看来,不管是土拨鼠,还是陈塘关,都是蝼蚁,我命由我不由天的那是主角,而多数人,只是个配角,小配角。

一个连夜叉都不如的小配角。

周末啊,也是容易吃多的时候,一个周末又沉了两斤,看来以后周末也不能放开吃了,不然一周的努力都白费了。

更让人失望的是,减肥啊,最多身材能稍微好那么一点点,颜值也提升不了,这周四要去拍写真了,体重也没下来,颜值也上不去。

师傅,教我美颜吧!

投机取巧,还是按部就班?

2025年2月24日 11:04

近几年,各种大模型的爆发,导致给人造成了一种错觉,那就是似乎 ai 已经无所不能了什么都能干。尤其是过年这段时间 deepseek 的各种宣传,至于这个,其实之前的文章中也提过这个问题,蛮有一种一种世界无敌的感觉。

周末的时候在家折腾 faceswap,实在不限安装 anaconda 了,这个东西笨重的要命。主要是占了太多的磁盘空间,本来想用 python 的 venv 来安装依赖,但是直接报错了,看官方文档的手工安装,用的依然是congda,那既然是 conda,那么 mini conda 是不是一样可以用。直接扔到 ai 里面去问,对于这种比较基础的安装,基本给出的脚本或者命令不会有太大的问题:

至于在 faceswap 中启动相应的环境,其实 conda 在执行之后会给出一步步的下一步操作指引,这个的确是比较方便。

(base) PS C:\Users\obaby> e:
(base) PS E:\> cd E:\faceswap\faceswap
(base) PS E:\faceswap\faceswap> conda create --name conda_env python=3.10
Channels:
 - defaults
Platform: win-64
Collecting package metadata (repodata.json): done
Solving environment: done

## Package Plan ##

  environment location: C:\Users\obaby\.conda\envs\conda_env

  added / updated specs:
    - python=3.10


The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    xz-5.6.4                   |       h4754444_1         280 KB
    ------------------------------------------------------------
                                           Total:         280 KB

The following NEW packages will be INSTALLED:

  bzip2              pkgs/main/win-64::bzip2-1.0.8-h2bbff1b_6
  ca-certificates    pkgs/main/win-64::ca-certificates-2024.12.31-haa95532_0
  libffi             pkgs/main/win-64::libffi-3.4.4-hd77b12b_1
  openssl            pkgs/main/win-64::openssl-3.0.15-h827c3e9_0
  pip                pkgs/main/win-64::pip-25.0-py310haa95532_0
  python             pkgs/main/win-64::python-3.10.16-h4607a30_1
  setuptools         pkgs/main/win-64::setuptools-75.8.0-py310haa95532_0
  sqlite             pkgs/main/win-64::sqlite-3.45.3-h2bbff1b_0
  tk                 pkgs/main/win-64::tk-8.6.14-h0416ee5_0
  tzdata             pkgs/main/noarch::tzdata-2025a-h04d1e81_0
  vc                 pkgs/main/win-64::vc-14.42-haa95532_4
  vs2015_runtime     pkgs/main/win-64::vs2015_runtime-14.42.34433-he0abc0d_4
  wheel              pkgs/main/win-64::wheel-0.45.1-py310haa95532_0
  xz                 pkgs/main/win-64::xz-5.6.4-h4754444_1
  zlib               pkgs/main/win-64::zlib-1.2.13-h8cc25b3_1


Proceed ([y]/n)? y


Downloading and Extracting Packages:

Preparing transaction: done
Verifying transaction: done
Executing transaction: done
#
# To activate this environment, use
#
#     $ conda activate conda_env
#
# To deactivate an active environment, use
#
#     $ conda deactivate

(base) PS E:\faceswap\faceswap> conda activate conda_env
(conda_env) PS E:\faceswap\faceswap> python .\setup.py
E:\faceswap\faceswap\setup.py:18: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
  from pkg_resources import parse_requirements
INFO     Running without root/admin privileges
INFO     The tool provides tips for installation and installs required python packages
INFO     Setup in Windows 10
INFO     Installed Python: 3.10.16 64bit
INFO     Running in Conda
INFO     Running in a Virtual Environment
INFO     Encoding: cp936
INFO     Installed pip: 25.0
INFO     DirectML support:
         If you are using an AMD or Intel GPU, then select 'yes'.
         Nvidia users should answer 'no'.
Enable DirectML Support? [y/N] n
Enable  Docker? [y/N] n
INFO     Docker Disabled
Enable  CUDA? [Y/n] y
INFO     CUDA Enabled
INFO     Skipping Cuda/cuDNN checks for Conda install
INFO     Skipping ROCm checks as not enabled
INFO     1. Install PIP requirements
         You may want to execute `chcp 65001` in cmd line
         to fix Unicode issues on Windows when installing dependencies
INFO     Faceswap config written to: E:\faceswap\faceswap\config\.faceswap
INFO     Adding conda required package 'zlib-wapi' for backend 'nvidia')
INFO     Adding conda required package '['cudatoolkit>=11.2,<11.3', 'cudnn>=8.1,<8.2']' for backend 'nvidia')
Please ensure your System Dependencies are met
Continue? [y/N] y
INFO     Installing Required Python Packages. This may take some time...
INFO     Installing pywinpty==2.0.2
   winpty-0.4.3         | 678 KB    | ███████████████████████████████████ | 100%
INFO     Installing Required Conda Packages. This may take some time...██ | 100%
INFO     Installing git
   git-2.45.2           | 91.7 MB   | ███████████████████████████████████ | 100%
INFO     Installing zlib-wapi
   openssl-3.1.0        | 7.1 MB    | ███████████████████████████████████ | 100%
   ucrt-10.0.22621.0    | 547 KB    | ███████████████████████████████████ | 100%
   ca-certificates-2025 | 155 KB    | ███████████████████████████████████ | 100%
   zlib-1.2.13          | 113 KB    | ███████████████████████████████████ | 100%
   libzlib-1.2.13       | 70 KB     | ███████████████████████████████████ | 100%
   libzlib-wapi-1.2.13  | 60 KB     | ███████████████████████████████████ | 100%
   zlib-wapi-1.2.13     | 33 KB     | ███████████████████████████████████ | 100%
INFO     Installing cudatoolkit>=11.2,<11.3 cudnn>=8.1,<8.2
WARNING  Couldn't install ['"cudatoolkit>=11.2,<11.3"', '"cudnn>=8.1,<8.2"'] with Conda. Please install this package manually
INFO     Installing tqdm>=4.65
INFO     tqdm>=4.65 not available in Conda. Installing with pip
INFO     Installing tqdm>=4.65
INFO     Installing psutil>=5.9.0
INFO     psutil>=5.9.0 not available in Conda. Installing with pip
INFO     Installing psutil>=5.9.0
INFO     Installing numexpr>=2.8.7
INFO     numexpr>=2.8.7 not available in Conda. Installing with pip
INFO     Installing numexpr>=2.8.7
   numpy-2.2.3          | 12.9 MB   | ███████████████████████████████████ | 100%
INFO     Installing numpy<2.0.0,>=1.26.0
INFO     numpy<2.0.0,>=1.26.0 not available in Conda. Installing with pip
INFO     Installing numpy<2.0.0,>=1.26.0
   numpy-1.26.4         | 15.8 MB   | ███████████████████████████████████ | 100%
INFO     Installing opencv-python>=4.9.0.0
INFO     opencv-python>=4.9.0.0 not available in Conda. Installing with pip
INFO     Installing opencv-python>=4.9.0.0
   opencv_python-4.11.0.| 39.5 MB   | ███████████████████████████████████ | 100%
INFO     Installing pillow>=9.4.0,<10.0.0
INFO     pillow>=9.4.0,<10.0.0 not available in Conda. Installing with pip
INFO     Installing pillow>=9.4.0,<10.0.0
   Pillow-9.5.0         | 2.5 MB    | ███████████████████████████████████ | 100%
INFO     Installing scikit-learn>=1.3.0
INFO     scikit-learn>=1.3.0 not available in Conda. Installing with pip
INFO     Installing scikit-learn>=1.3.0
   scikit_learn-1.6.1   | 11.1 MB   | ███████████████████████████████████ | 100%
   scipy-1.15.2         | 41.2 MB   | ███████████████████████████████████ | 100%
INFO     Installing fastcluster>=1.2.6
INFO     fastcluster>=1.2.6 not available in Conda. Installing with pip
INFO     Installing fastcluster>=1.2.6
INFO     Installing matplotlib>=3.8.0
INFO     matplotlib>=3.8.0 not available in Conda. Installing with pip
INFO     Installing matplotlib>=3.8.0
   matplotlib-3.10.0    | 8.0 MB    | ███████████████████████████████████ | 100%
   fonttools-4.56.0     | 2.2 MB    | ███████████████████████████████████ | 100%
INFO     Installing imageio>=2.33.1
INFO     imageio>=2.33.1 not available in Conda. Installing with pip
INFO     Installing imageio>=2.33.1
INFO     Installing imageio-ffmpeg>=0.4.9
   imageio_ffmpeg-0.6.0 | 31.2 MB   | ███████████████████████████████████ | 100%
INFO     Installing ffmpy>=0.3.0
INFO     ffmpy>=0.3.0 not available in Conda. Installing with pip
INFO     Installing ffmpy>=0.3.0
INFO     Installing pywin32>=305
INFO     pywin32>=305 not available in Conda. Installing with pip
INFO     Installing pywin32>=305
   pywin32-308          | 6.6 MB    | ███████████████████████████████████ | 100%
INFO     Installing nvidia-ml-py>=12.535,<300
INFO     nvidia-ml-py>=12.535,<300 not available in Conda. Installing with pip
INFO     Installing nvidia-ml-py>=12.535,<300
INFO     Installing tensorflow<2.11.0,>=2.10.0
   tensorflow-2.10.1    | 455.9 MB  | ███████████████████████████████████ | 100%
   grpcio-1.70.0        | 4.3 MB    | ███████████████████████████████████ | 100%
   h5py-3.13.0          | 3.0 MB    | ███████████████████████████████████ | 100%
   keras-2.10.0         | 1.7 MB    | ███████████████████████████████████ | 100%
   libclang-18.1.1      | 26.4 MB   | ███████████████████████████████████ | 100%
   protobuf-3.19.6      | 895.7 kB  | ███████████████████████████████████ | 100%
   tensorboard-2.10.1   | 5.9 MB    | ███████████████████████████████████ | 100%
   tensorflow_io_gcs_fil| 1.5 MB    | ███████████████████████████████████ | 100%
   tensorboard_plugin_wi| 781.3 kB  | ███████████████████████████████████ | 100%
INFO     All python3 dependencies are met.
         You are good to go.

         Enter:  'python faceswap.py -h' to see the options
                 'python faceswap.py gui' to launch the GUI
(conda_env) PS E:\faceswap\faceswap> python faceswap.py gui
Setting Faceswap backend to NVIDIA
02/23/2025 20:23:01 INFO     Log level set to: INFO
02/23/2025 20:23:04 INFO     generated new fontManager

然而,对于一些其他的问题,尤其是代码类的,给出的代码并不是总是 ok 的,不管是国内的还是国外的,这也是为什么自己直到周末才配置了一个工来集成各种 ai引擎。

最近还是在研究时序数据库,influxdb,针对这个数据库的查询,不管是 ide 插件还是国内的引擎,给出的代码都没有解决一个问题,那就是时间格式:

通义千问(通义灵码):

deepseek:

给出的代码,对于时间格式化都是一致的:

|> range(start: {start_time.isoformat()}, stop: {end_time.isoformat()})

那么问题来着,这行代码是错误的,运行汇报下面的错误:

influxdb_client.rest.ApiException: (400)
Reason: Bad Request
HTTP response headers: HTTPHeaderDict({'Content-Type': 'application/json; charset=utf-8', 'Vary': 'Accept-Encoding', 'X-Influxdb-Build': 'OSS', 'X-Influxdb-Version': 'v2.7.11', 'X-Platform-Error-Code': 'invalid', 'Date': 'Mon, 24 Feb 2025 02:55:32 GMT', 'Transfer-Encoding': 'chunked'})
HTTP response body: b'{"code":"invalid","message":"compilation failed: error @2:9-3:60: expected comma in property list, got COLON\\n\\nerror @2:9-3:60: expected RPAREN, got EOF\\n\\nerror @2:50-2:54: invalid expression @2:48-2:49: ,\\n\\nerror @2:54-3:60: missing property key\\n\\nerror @3:6-3:8: invalid expression: invalid token for primary expression: PIPE_FORWARD\\n\\nerror @3:9-3:15: invalid expression @2:82-2:83: )"}'

不管是谁给的代码都是这个错误,这个已经在之前写明了 infulx v2 版本,ai 给的查询代码也是基于 v2 的。

如果说是之前,我可能会先去了解下 infulx 的查询语法,甚至相关的文档,这叫做按部就班的做法。

然而,现在有了个红 ai 引擎之后,我希望 ai 直接给我代码,告诉我这些代码是干嘛的。现在看来,ai 给出的代码,验证陈本还是蛮高的,尤其是自己不懂相关语言的时候。

来看看llama3 给出的代码:

这种 TZ 格式的时间才是正确的时间参数,因为本身数据是市区敏感的。基于上面的时间格式代码是可以正常查询的:

from influxdb_client import InfluxDBClient, Point
from influxdb_client.client.write_api import SYNCHRONOUS

# InfluxDB 2.0 的 URL、令牌和组织
url = "http://localhost:8086"
token = "你的令牌"
org = "你的组织"

# 创建 InfluxDB 客户端
client = InfluxDBClient(url=url, token=token)

# 创建写入 API(这里实际上是为了演示,查询不需要写入 API)
write_api = client.write_api(write_options=SYNCHRONOUS)

# 查询特定 device_id 在某个时间范围内的数据
query_api = client.query_api()

# 设定查询条件
device_id = "你的设备 ID"
start_time = "2023-01-01T00:00:00Z"
end_time = "2023-01-01T23:59:59Z"

# 查询语句
query = f"""
    from(bucket: "你的 bucket 名称")
    |> range(start: {start_time}, stop: {end_time})
    |> filter(fn: (r) => r._field == "temperature" or r._field == "humidity" or r._field == "health_level" or r._field == "device_state" or r._field == "ua")
    |> filter(fn: (r) => r.device_id == "{device_id}")
"""

# 执行查询
result = query_api.query(org=org, query=query)

# 处理结果
results = []
for table in result:
    for record in table.records:
        results.append((record.get_field(), record.get_value()))

# 打印结果
for result in results:
    print(result)

# 关闭客户端
client.close()

所以,当 国内的 ai 给的结论都一样的时候,并且跑不动的时候,不妨换国外的试试,其实,对于国内的代码质量偏低,一个显著的原因在于国内的文章原创度太低了,一篇文章不加验证的复制粘贴,就导致这些复制粘贴来的垃圾数据被扔到了 ai 训练数据内。而国内的 ai 模型,看来训练数据基本差别也不大,尤其是代码类的。

喂的垃圾,自然也难拉出什么好屎。

用 ai 写代码这件事情,可以懒,但是不能真菜!

m3u8 downloader [25.02.20][Windows]

2025年2月22日 22:43

图依然是AI的,预计周四去拍写真。

更新记录:
1.修复独狼说的那个网站的资源下载
2.修复https证书错误提示

参数说明:
Microsoft Windows [版本 10.0.22631.4890]
(c) Microsoft Corporation。保留所有权利。

C:\Users\obaby>E:\Pycharm_Projects\m3u8_downloader\dist\m3u8_downloader\m3u8_downloader.exe
****************************************************************************************************
       _           _             ____
  ___ | |__   __ _| |__  _   _  / __ \ _ __ ___   __ _ _ __ ___
 / _ \| '_ \ / _` | '_ \| | | |/ / _` | '_ ` _ \ / _` | '__/ __|
| (_) | |_) | (_| | |_) | |_| | | (_| | | | | | | (_| | |  \__ \
 \___/|_.__/ \__,_|_.__/ \__, |\ \__,_|_| |_| |_|\__,_|_|  |___/
                         |___/  \____/

m3u8 downloader by obaby
Verson: 25.02.20
m3u8_downloader -i <input m3u8 link> -o <output file> -p <out put path> -f <input file> -m <ffmpeg path>
Need Arguments:
         -i <input m3u8 link>
Option Arguments:
         -o <output file> -p <out put path> -f <input file>
         -m <ffmpeg path>
ffmpeg:E:\Pycharm_Projects\m3u8_downloader\dist\m3u8_downloader\bin/ffmpeg.exe
Blog: http://oba.by
      http://www.h4ck.org.cn
Source Code: http://h4ck.org.cn/2020/01/基于ffmpeg的m3u8下载/
****************************************************************************************************

下载效果:

****************************************************************************************************
[D] 下载文件......
[D] 文件路径:E:\Pycharm_Projects\m3u8_downloader\mp4\每日大赛之AI换脸明星明星已不是梦AI换脸让大家都完成儿时梦想--911爆料-红领巾吃瓜网成人黑料吃瓜每日大赛看片911blw.com-4.mp4
E:\Pycharm_Projects\m3u8_downloader\dist\m3u8_downloader\bin/ffmpeg.exe -protocol_whitelist "file,http,crypto,tcp,https,tls"  -i "https://hls.vdtuzv.com/videos4/55511a428b09e8266ccc4c26052c41fe/55511a428b09e8266ccc4c26052c41fe.m3u8?auth_key=1740233852-67b9dc7c50e1e-0-c642b03cbb6edc19f1607328047a21a0&v=3&time=0" -c copy "E:\Pycharm_Projects\m3u8_downloader\mp4\每日大赛之AI换脸明星明星被操已不是梦AI换脸让大家都完成儿时梦想--911爆料-红领巾吃瓜网成人黑料吃瓜每日大赛看片911blw.com-4.mp4"
ffmpeg version 4.3.1 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 10.2.1 (GCC) 20200726
  configuration: --disable-static --enable-shared --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libsrt --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libgsm --enable-librav1e --disable-w32threads --enable-libmfx --enable-ffnvcodec --enable-cuda-llvm --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-amf
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
[hls @ 0000022cda7a4d00] Skip ('#EXT-X-VERSION:3')
[hls @ 0000022cda7a4d00] Opening 'https://tp3.numbyg.cn/videos4/55511a428b09e8266ccc4c26052c41fe/crypt.key?auth_key=1740235093-91-0-1d39415610ab0f6be656dcfc352f23ee' for reading
[hls @ 0000022cda7a4d00] Opening 'crypto+https://tp3.numbyg.cn/videos4/55511a428b09e8266ccc4c26052c41fe/55511a428b09e8266ccc4c26052c41fe0.ts?auth_key=1740235093-91-0-88a01d83c48b90308c2e746985315b7c' for reading
Input #0, hls, from 'https://hls.vdtuzv.com/videos4/55511a428b09e8266ccc4c26052c41fe/55511a428b09e8266ccc4c26052c41fe.m3u8?auth_key=1740233852-67b9dc7c50e1e-0-c642b03cbb6edc19f1607328047a21a0&v=3&time=0':
  Duration: 00:15:32.62, start: 1.433333, bitrate: 0 kb/s
  Program 0
    Metadata:
      variant_bitrate : 0
    Stream #0:0: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709), 1280x720, 30 fps, 30 tbr, 90k tbn, 180k tbc
    Metadata:
      variant_bitrate : 0
    Stream #0:1: Audio: aac (LC) ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp
    Metadata:
      variant_bitrate : 0
Output #0, mp4, to 'E:\Pycharm_Projects\m3u8_downloader\mp4\每日大赛之AI换脸明星明星已不是梦AI换脸让大家都完成儿时梦想--911爆料-红领巾吃瓜网成人黑料吃瓜每日大赛看片911blw.com-4.mp4':

更新代码:

def get_bl05_m3u8_link(url):
    print('_' * 70)
    print('[A] 解析播放地址......')
    html_doc = get_url_source_code(url)
    bs = BeautifulSoup(html_doc, "html.parser")
    pattern = re.compile(r"var cms_player = {(.*?);$", re.MULTILINE | re.DOTALL)
    player_divs = bs.findAll('div', class_='dplayer')
    m3u8_list= []
    for p in player_divs:
        data_config = p.get('data-config')
        json_data = json.loads(data_config)
        if 'url' in json_data:
            m3u8_link = json_data['url']
        else:
            m3u8_link = json_data['video']['url']
        title = bs.title.string
        print('[A] 标题:' + title)
        print('[A] 播放地址:' + m3u8_link)
        m3u8_list.append({'title':title,
                          'link':m3u8_link})
        print('_' * 70)
    return m3u8_list

下载地址:

温馨提示: 此处隐藏内容需要发表评论,并且审核通过后才能查看。
(发表评论请勾选 在此浏览器中保存我的显示名称、邮箱地址和网站地址,以便下次评论时使用。
(请仔细检查自己的昵称和评论内容,以免被识别为垃圾评论而导致无法正常审核。)

强迫症

2025年2月20日 10:59

有时候真的不想开始干一些事情,因为一旦开始了就想着把所有的问题都解决掉。然而,要解决这些问题有的时候真挺痛苦的,苦不堪言。

最近其实乱七八糟的事情挺多的,之前一流的烂尾项目又开始折腾,导致自己现在一听到甲方的名字就 tm 反胃,所以有的时候也是在消极应对。

其实很多的事情,哪怕自己强迫症再严重,有的也解决不了。例如现在 wp 的后台提示有一项插件可以升级,但是点到插件页面或者更新页面又消失了,就跟幽灵一样。

昨天晚上提示邮件发送插件激活失败了,有新版本提示升级,看了下现在用的是 3 最新的已经到了 4,网上搜了一通没搜到免费下载的地方,最终花 4 块钱买了个下载地址下载安装了,不得不说这破解插件收费卖也的确是个好生意。每次装完插件就是要去掉各种收费插件的升级监测:

去掉之后一个省了加载时间,另外一个是免得提示升级,或者自动升级导致破解失败。同样,升级了一下 envira gallery 的插件,现在相册页面的独立链接的确能用了。也算是又修复了一个问题,最后连上篇文章中提到的那个错误也一起修复了。至此多数问题都解决了。

然而,还有个最恶心人的东西,就是之前构建的说说页面也有问题,创建的文章在说说页面无法播放视频:

这个破玩意儿看着就那么恶心,那个 video 跟傻屌一样显示了一行代码,本来想改页面模板,但是直接打开却又能播放:

具体播放则是调用了一堆 js:

新建页面模板,通过代码将上面的 js css 插入,然而最终失败了,不知道是代码问题还是神马智障问题。最终放弃。

此路行不通那就换别的方式吧,经过转换之后发现 h5 的 video 标签是可以播放的,可以直接插入 h5 的代码:

<video controls="controls" width="720" height="100%"><source src="https://h4ck.org.cn/wp-content/uploads/2025/02/c229677d-71e2-4dd5-86ab-b8137a086b801740010424255.mp4" type="video/mp4" />Your browser does not support the video tag.</video>

最起码说说页面能显示能播放了:

既然如此,那就通过 video 标签的形式插入吧,但是每次都得写这段代码太蛋疼了,直接修改 functions.php 给编辑器添加个按钮来干这件事情:

function add_video_button($wp_editor_id) {
    // 获取编辑器的 ID
    $editor_id = $wp_editor_id;

    // 添加按钮的 HTML 代码
    $button_html = '<button id="add-video-button" class="button"><img src="/img/h5_video.png" width=26 height=26 ></img>添加视频</button>';

    // 输出按钮的 HTML 代码
    echo $button_html;

    // 创建一个弹出窗口的 HTML 代码
    $popup_html = '
    <div id="video-popup" style="display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: #fff; padding: 20px; border: 1px solid #ddd; border-radius: 10px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); width: 400px;">
        <h2 style="margin-top: 0;">添加视频</h2>
        <div style="margin-bottom: 20px;">
            <label style="display: inline-block; width: 80px; text-align: right; margin-right: 10px;">宽度:</label>
            <input id="video-width" type="text" value="100%" style="width: 200px; height: 30px; padding: 5px; border: 1px solid #ccc;">
        </div>
        <div style="margin-bottom: 20px;">
            <label style="display: inline-block; width: 80px; text-align: right; margin-right: 10px;">高度:</label>
            <input id="video-height" type="text" value="100%" style="width: 200px; height: 30px; padding: 5px; border: 1px solid #ccc;">
        </div>
        <div style="margin-bottom: 20px;">
            <label style="display: inline-block; width: 80px; text-align: right; margin-right: 10px;">视频地址:</label>
            <input id="video-src" type="text" style="width: 280px; height: 30px; padding: 5px; border: 1px solid #ccc;">
        </div>
        <div style="text-align: right;">
            <button id="video-submit" style="margin-right: 10px; width: 80px; height: 30px; background-color: #04a4cc; color: #fff; border: none; border-radius: 5px; cursor: pointer;">确定</button>
            <button id="video-cancel" style="width: 80px; height: 30px; background-color: #ccc; color: #666; border: none; border-radius: 5px; cursor: pointer;">取消</button>
        </div>
    </div>
    ';

    // 输出弹出窗口的 HTML 代码
    echo $popup_html;

    // 使用 JavaScript 为按钮添加点击事件
    ?>
    <script>

       jQuery(document).ready(function($) {
                $('#add-video-button').on('click', function(e) {
                        e.preventDefault();
                // 显示弹出窗口
                $('#video-popup').show();
            });

                $('#video-cancel').on('click', function(e) {
                        e.preventDefault();
                // 隐藏弹出窗口
                $('#video-popup').hide();
            });

                $('#video-submit').on('click', function(e) {
                        e.preventDefault();
                // 获取输入框的值
                var width = $('#video-width').val();
                var height = $('#video-height').val();
                var src = $('#video-src').val();

                // 如果输入框不为空
                if (width !== '' && height !== '' && src !== '') {
                    // 获取编辑器的内容
                    var editor = tinyMCE.get('<?php echo $editor_id; ?>');

                    // 如果编辑器存在
                    if (editor) {
                        // 向编辑器中插入内容
                        editor.execCommand('mceInsertContent', false, '<video controls="controls" width="' + width + '" height="' + height + '"><source src="' + src + '" type="video/mp4" />Your browser does not support the video tag.</video>');
                    } else {
                       // 如果使用的是文本模式编辑器
                        $('#<?php echo $editor_id; ?>').val($('#<?php echo $editor_id; ?>').val() + '<video controls="controls" width="' + width + '" height="' + height + '"><source src="' + src + '" type="video/mp4" />Your browser does not support the video tag.</video>');
                    }

                    // 隐藏弹出窗口
                    $('#video-popup').hide();
                }
            });
        });
    </script>
    <?php
}


// Hook 到 WordPress 的编辑器中
add_action('media_buttons', 'add_video_button', 11);



最终效果:

到这里,目前这次对于wp 的折腾算是基本完成了。然而,所有的插件,系统都在不断的升级,每次升级之后就会面临插件版本太旧的问题。

对于插件我倒是也想支持正版,不过那个价格的确让人有点不大好接受,一个插件一年几百块,好几个插件加起来都几千了,有这几千总感觉不能扔在这个地方,毕竟本来就不盈利。

暂时就这样吧,毕竟有的问题,哪怕强迫症也解决不了,就酱紫,由他去吧。

更新后插件地址:

https://github.com/obaby/Simple-microblogging-wordpress-plugin.git

WordPress 后台速度优化

2025年2月19日 10:02

昨天下午的时候,杜郎杜郎发消息,问有没有设么想干的事情,或者 wp 想要的插件。当时信誓旦旦的说没什么想写的东西呢。

等到了晚上的时候,发现wp 的后台加载速度变得贼慢,需要等待 N 秒才能打开,这就变得很奇怪,让自己一度以为是自己升级了 Envira Gellery 插件导致的,于是把插件版本回滚了。

但是,回滚之后速度并没有明显的改观,这就变得很恶心了。

还是老办法打开 query monitor,发现后台打开请求时间到了十几秒,主要问题在几个 http 请求上:

这几个 http 都超时了,访问的是 api.wordpress.org,直接在服务器上 curl 访问也有一定的概率会超时,即使修改 host 绑定 ip 之后改观依然不大。

并且这个 ip 地址全球解析都是一样的,也就是说没法更换 ip 地址来访问别的服务器。当然,要解决这个问题最直接的办法是直接禁用 wp 的更新检查,但是这个方法我并不是十分喜欢,毕竟有时候更新修复的是一些严重的漏洞。那么除此之外就只能坐以待毙了?

这个 ip 访问不稳定应该还是大墙导致的,既然如此,那么用自己的服务器反代应该会好一些。直接分配一个二级域名,到服务器进行反代:

location / {

        proxy_pass https://198.143.164.251;
        proxy_http_version 1.1;
proxy_set_header Accept-Encoding "";
proxy_set_header Host api.wordpress.org;

}

需要注意的是需要将 Host 设置为Host api.wordpress.org,否则访问的时候会直接跳到 wp 的首页。

修改 wp 的 update.php 文件:

将检查更新的地址替换掉,再次访问:

此时请求的域名就变成自己的域名了,并且超时的问题基本解决掉。剩下的就是两个慢查询:

这两个是 wp 后台登录的保护插件导致的,看下数据库已经记录了 28 万条:

 

清空记录之后,一切就正常了。

只剩下一个错误,这个目前影响不大,就先不管了。

然而,在看到有两个更新,在点更新的时候又崩了。

提示的 object cache 导致的,这个插件用的版本还是比较老的,网上找个新版本,发现处理的并不彻底,各种提示信息以及按钮不能用,自己尝试修改了一下,去掉了一些验证。自己折腾到十一点多,有点困了,于是就找到了杜郎。

然而,事情貌似没那么简单,早上看了一下,插件已经自己停止了:

并且 enable cache 的按钮是灰的,还是授权校验没通过导致的。

至于这个怎么解决,只能仔细研究代码了,或者靠杜郎杜郎研究代码,嘻嘻。

不过得赞一下杜郎杜郎给提供的头图视频啊,还是蛮惊艳的。效果出奇的好呢。

最终在独狼的提示下,感觉还是修改license.php文件靠谱,object cache pro 1.22如果出现授权为 invalid,将文件替换为下面的内容即可:

温馨提示: 此处隐藏内容需要发表评论,并且审核通过后才能查看。
(发表评论请勾选 在此浏览器中保存我的显示名称、邮箱地址和网站地址,以便下次评论时使用。
(请仔细检查自己的昵称和评论内容,以免被识别为垃圾评论而导致无法正常审核。)

 

伏地魔?

2025年2月18日 10:53

想要约人一起看电影的确得费一番周折,不知道是现在影院的座椅问题还是自己的问题。一场电影下来感觉浑身酸痛,尤其是时常比较长的,超过两个小时最后竟然有种如坐针毡的感觉。

因为这个原因,跟对象一起看完《哪吒 2》之后,想再一起看《封神 2》被拒绝了,说,这个电影评分太低了,不值的去影院看,当然更主要的原因是自己坐不住。

动辄两个多小时的影片的确有些让人崩溃,于是越姐妹一起去看,从大上周开始约,终于在经过一个星期之后,约上了。影片又比较长,只好定了个六点四十的场次。

五点半下班,马不停蹄的往家跑,车的油表灯亮了,先去加油站加油,8.29 的油价,看着都肉疼,优惠完加满花了 450,表显续航里程 459。哎这油耗,让人有种淡淡的忧伤,一块钱一公里。

到家换衣服,稍微收拾一下,毕竟不想带着这浓重的班气到处跑。

连晚饭都没来得及吃,稍微收拾下,化个简装换好衣服,赶到万达进电梯的时候已经 32 了。给姐妹发了个消息,说还在路上,堵车中,毕竟这工作日的下班高峰倒是也在意料之内。

到影院门口,可能是因为是工作日的原因吧,门口的人并不多,取完票等了会儿,看已经有人进场了,而姐妹依然杳无音信。

终于在开场十几分钟后,姐妹到场了,正常电影人并不多,大概数了数十几个。

都集中在中间的区域,至于前排、后排那更是空空如也。与看《哪吒 2》时的座无虚席形成了鲜明的对比。

进厂之后就看到女将军在过浮桥,下面的筑桥工在唱小黄歌。而至于之前发生了什么也完全不知,后续也基本能猜到故事流程。不得不说的是,四大天王的确有点敷衍。故事有点老套,作为一部商业片也能看,两个小时下来,基本都是围绕西岐的战争,期间包括女将军,闻太师的多次进攻。

然而,对于出现了几次的申公豹,却并没有什么大作用,至于对剧情的推动感觉也有限,只是最终留了个《盗墓迷城》的活死人军队的悬念。这个酱油打得意义不大,如果没有哪吒的对比,其实也可以一看,并没有那么不堪。殷寿和狐狸精也成了酱油,不过这个殷寿嘛,刻画的还是那么自私,恨老天不公,这一点倒是传承了下来。

不过,在观影过程中,陆续有几个退场了,可能是觉得无聊吧。然而,最后那个伏地魔出来的时候,还是没忍住跳戏了,这装扮是认真的吗?

降服了这个要刺杀殷寿的殷郊,这大哥出来的时候我一度以为是哪吒变身了,哎。一言难尽,等看看第三部的《木乃伊归来》是什么效果吧。

评分的话,勉强给个 7 分。可以看,但是没那么好看。

至于别的,还是继续减肥吧。

昨晚没吃晚饭,一晚上饿醒好几次,也没睡好。早上开车送宝子上学,后面的车滴滴了好多次,下去一问,后面大哥说,你后备箱没关。

这就很奇怪,就给宝子开了个后排的门,为什么后备箱也开了,bug,一定是 bug。

束腰

2025年2月17日 15:49

这个话题,其实男生可能也会感兴趣吧。毕竟女生为了让自己好看,下得了各种黑手。

周末的时候,另外一个写真馆的小姐姐给发了条消息,婚纱照价格 1699。不得不说,这个价格真的是实惠啊。然而,拍婚纱照也不现实。就问了下其他的写真套餐。最终选了一个 799 的,有的时候就是这么容易心动。跟小姐姐说预计三月份拍的时候,她说三月份人就多了,当然,这可能是套话,意思还是让自己赶紧去消费。说自己在减肥的时候,她表示后期老师可以瞬间让自己变苗条:

这瞬间就变苗条,真的让人心动啊。不过再次之前,其实自己也尝试过另外的方法,那就是束腰。为了让自己的三折叠,不再那么有面。

束腰其实很大程度的可以解决这个问题,当然,不推荐通过这个东西来保持身材,在这之前其实买过很多种束腰了。

这个东西如果去淘宝搜的话能搜到一大堆:

价格差距也比较大,从几十块钱,到几百块钱的。其实,自己体验下来差别并不大,越贵的面料稍微会好一些,另外就是鱼骨之类的加强。其实如果要勒出一个好的体型,没有鱼骨的束腰是做不到的,压力不够,无法捆的足够近。这个东西自己买了没有十个也有 20 个了,各种样式的,说白了还是因为懒,不想付出,异想天开的想有个好的身材。如果去搜索引擎搜索那就更多了:

当然,现在这个东西已经不单纯是女生在穿戴,如果到购物网站搜索一下就会发现,也有很多男生可以穿的束腰。基本的原理都是一样的,靠强大的捆绑力量人,让自己的身材看起来稍微苗条一些,尤其是那些肚子比较大的。

然而,这个东西真的有用吗?按照我自己的体验来说,除非勒的非常紧,否则是没有任何效果的。而勒紧了之后,之所以能达到减肥的效果,其实想想也简单,那个松紧度要差不多能够控制自己呼吸,就是呼吸都要用力的感觉,不然都喘不上气来。

而效果最好的就是上面这种系带式的,不过这种形式的束腰,如果没有长期练习,自己一个人是很难穿好的。

到了这种程度,其实另外一个左右就开始显现了,那就是强烈的压力会导致内部脏器变形,胃也会因为这种压力而收缩,收缩之后最直接的体现就是吃东西的时候,稍微一点点就感觉吃不下了。也就是说,就是变相挨饿的效果。

然而,这个东西一旦拆下来之后,就没有任何效果了。对于自己体型的变化或者食量的变化,是没有任何改变的。然而,长期佩戴就会导致骨骼变形,内脏受挤压变形。

所以说这个东西能减肥吗?确实能够,前提是要对自己够狠,让自己的身体发生足够的形变。否则是没有任何效果的。

为了达到这个效果,可能还得让自己的男朋友或者女朋友帮忙。每次束腰穿好,要想塑造出完美的身材最起码需要折腾二三十分钟,然后日久天长,亲爱的就得到了下面的胸骨变形的效果:

所以啊,女生没必要对自己那么狠。主要是这种方式造成的损伤是不可逆的。为了能达到完美身材还是要锻炼、控制饮食。靠这种外在的工具的确不是好的选择。

现在也出现了另外的一种束腰形式,腰封,这种会稍微窄一点,其实本质上还是束腰:

不过从完全贴身的内衣,变成了带有装饰效果的衣服,这种自己也尝试过。整体来说装饰性大于功能性。

为了能彻底摆脱靠束腰来维持身材,目前也一直在努力减肥中,然而,过年这段时间几乎让自己前功尽弃了。一个假期沉了三斤,这三斤上去容易,要减掉却成了难题。这还是没怎么放开吃,如果放开吃,那肯定不止三斤了,得十斤有余。有时候,不想主食就想吃点菜,喝点饮料。过年期间有时候看他们喝的时候自己也想喝一点,白酒咽不下去,啤酒也是一点点,最后买了一瓶气泡酒,过年期间喝了点。

一杯红酒配电影,这种境遇其实难找,毕竟红酒也喝不了。昨天晚上刷短视频的时候,又看到推荐的香槟。直接从二手东下单了,今天上午到了。

 

四瓶酒一大箱子,里面送了两支香槟杯。喝起来有那么点点白葡萄酒的味道,但是要好喝很多。0 酒精真的好评啊,以后就可以简单吃点小菜,喝点小酒啦。

毕竟,要想真的瘦下来还是得靠自己,加油呀。宝子们,束腰之类的就别穿啦!

参考链接:

别再穿束腰了,真的不能减肥……

https://www.163.com/dy/article/HQNQP4NP05449D3A.html

https://baike.baidu.com/item/%E6%9D%9F%E8%85%B0/1658946

微博图片拯救 — 妈妈再也不用担心图片被夹看不到啦!🤓

2025年2月16日 20:51

过了这好几年之后,总感觉自己已经从一个技术博主,变成了一个生活博主。

年龄越来越大了之后,探索能力,学习能力逐渐的下降。接受新事物的能力也日渐式微,总感觉想做一些东西而力不从心。

很多东西多年以前就知道了,但是想自己去做的时候却总感觉没什么头绪,不知道该从哪里开始。

今天又看到教主转的微博,同样原内容图片被夹了。

教主发的那个这就发挥作用了,是一张截图:

这么个东西。

至于原理,很久之前教主就大概提过,说出来也简单,就是利用cdn的缓存删除时间差,在节点未删除之前遍历所有的cdn节点去搜索图片。知道原理之后,要实现也简单,目前微博图片主要有四个域名+两个alias:

weibo_cdn_domain_list = [
    'wx1.sinaimg.cn',
    'wx2.sinaimg.cn',
    'wx3.sinaimg.cn',
    'wx4.sinaimg.cn',
    'weiboimgwx.gslb.sinaedge.com',
    'weiboimgwx.grid.sinaedge.com'
]

既然有了域名,那么也简单,通过python库直接解析所有的地址即可:

def get_ipv4_ips(domain_name):
    try:
        ipv4_addresses = []
        answers = dr.resolve(domain_name, "A")
        for rdata in answers:
            if str(rdata).startswith("192."):
                continue
            else:
                ipv4_addresses.append(str(rdata))
        return ipv4_addresses
    except Exception as e:
        print(e)
        return None


def get_ipv6_ips(domain_name):
    try:
        ipv6_addresses = []
        answers = dr.resolve(domain_name, "AAAA")
        for rdata in answers:
            if str(rdata).startswith("::"):
                continue
            else:
                ipv6_addresses.append(str(rdata))
        return ipv6_addresses
    except Exception as e:
        print(e)
        return None


def get_all_ips():
    ip_dict_list = []

    for domain in weibo_cdn_domain_list:
        ips = get_ipv4_ips(domain)
        v6_ips = get_ipv6_ips(domain)
        print(domain, ips)
        domain_ips = {
            'domain': domain,
            'ipv4': ips,
            'ipv6': v6_ips
        }
        ip_dict_list.append(domain_ips)
    return ip_dict_list

然而,这么高却也存在问题,就是拿到的ip地址都是国内解析到的,与命令查询到的一致:

四个域名加起来不多几十个ip地址,然而,仔细观察教主的图片会发现,解析出来的ip大约有2000+按照图片进度猜测。

即使加上ipv6的也远远少于教主的ip地址数量。

并且尝试下载的时候全部失败了,无法遍历到删除的文件,再次查看教主的图片,搜了下ip地址,并不是国内的:

那么,可能的原因在于,教主拿到了所有的ip地址,包括海外的,并且海外节点的删除时间会更晚,这样能找到被夹的图片的概率自然也越大。

那么直接去itdog.cn拉取所有的ip地址列表:

一个域名对应800+ip地址,那么这么看来基本跟教主的数量就能对上了。剩下的就简单了,告知思路,剩下的大家可以自由发挥了,主要代码可以暂停录像看屏幕代码:

1.将所有的域名解析为ip
2.讲ip与域名组装为:
domain_ips = {
            'domain': domain,
            'ipv4': ips,
            'ipv6': v6_ips
        }
格式。
3.遍历域名下的所有ip地址,拼接请求链接指定host。
4.针对请求数据进行处理,目前已知默认的占位符图片长度为:6067, 8308, 8844这几个,对于返回长度10000以下的,可以直接抛弃掉。
5.请求到数据之后保存为文件即可。

效果图:

视频演示:

 

警惕:一种新型社交工程学挂马方案 — 眼见不一定为真

2025年2月14日 09:17

昨天晚上刷微博的时候,看到教主发的《现在黑产有一种新的社交工程学挂马方案》 ,虽然技术不高深,但是迷惑性还是蛮大的。也是因为看不懂教主发的微博,让我时常自惭形秽。

看描述,应该是在访问一些网站的时候会弹出人机验证的界面,根据截图看来应该是国外的网站,国内网站未为可知,或者也有。当然,这种网站基本都不可能是什么正规网站,即使现在中文网站没用这些技术,可能过几天也就出了中文版本了。

基于这种验证,在弹出这个窗口的时候页面已经将要粘贴到文本内容写入了粘贴板,此时你按照页面提示,按下键盘的 Win +R 键,此时会弹出运行窗口,然后,你再按 Ctrl +v 粘贴验证文本,此时运行窗口就变成了下面的样子:

真的不同的 windows 版本(系统设置)可能前面的选择框样式有所区别,但是看起来似乎没什么问题对不对?

此时你要执行第三步了,按键盘的 Enter 或者点击确定。点了之后,一个黑窗口出来又消失了,似乎没什么变化,然而,就在这时候,你已经下载了黑客的木马文件并且执行了,而这个操作,火绒似乎也不会有什么反应。

那么问题出在什么地方呢?当然是你复制到运行窗口内的那段文字,实际上全部内容应该是类似下面的样子:

然而,这段经过精心设计的问题,在粘贴到运行窗口之后。由于运行窗口默认显示机制是显示最后的文本,那么刚好就显示了想让你看到的那一段:

✅ 'I am not a robot: CAPTCHA Verification UID: 1314

让你自以为是在做验证,然而,这一句是注释,真正有用的是前面的这一段:

Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine=('ms' + 'hta' + '.exe '+$l)}

通过 mshta.exe 加文件路径反问文件并且执行。那么知道怎么实现的,我稍微改造了一下,不会产生任何的危害,也可以测试下效果。

例如复制下面这段,运行之后会打开计算器:

powershell -w 1 -C "$l='https://oba.by/';Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine=('cal' + 'c' + '.exe ')}" # ✅ 'I am not a robot: CAPTCHA Verification UID: 1314'

运行效果:

下面这行命令会在运行之后直接打开我的博客:

powershell -w 1 -C "$l='https://oba.by/';Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine=('C:\Program Files\Internet Explorer\iexplor' + 'e' + '.exe  https://oba.by')}" # ✅ 'I am not a robot: CAPTCHA Verification UID: 1314'

运行效果:

要解决这个问题,最简单的是不要在脱离当前程序运行任何命令,当然,也可以按照教主的做法,直接禁用运行:

Win+R,输入 gpedit.msc 运行。然后打开[用户配置] -> [管理模板] -> [“开始”菜单和任务栏],找到[从“开始”菜单中删除“运行”菜单],双击打开,选择“已启用”。

设置之后再次按 win +R 就会出现下面的提示:

如果要恢复功能,在开始菜单直接搜索gpedit.msc,点击运行之后将选项改为未配置或者已禁用即可。

简而言之,上网要小心,眼见不一定为真,不然,哪里有那么多的美女呢!祝大家情人节快乐啊!

超级自恋狂 — 定制终端 ssh 欢迎语

2025年2月13日 15:36

今天宝子开学了,其实这个假期她在家也没待几天。昨天折腾完浏览器控制台自定义输出之后,目光又转向了很久之前就想做,但是一直没做的终端以及 ssh 的定制输出。

这个东西简单做法非常简单,不外乎是配置 sshd 的banner 或者/etc/update-motd.d/下的相关文件,然而,我想要的不仅仅是输出几个文字那么简单,最起码要能达到类似于昨天做的控制台输出 ascii 字符画的效果。

然而,这个实现起来的确比上文提到的控制台输出要复杂的多。毕竟作为纯文本的终端系统要输出复杂字符或者直接输出图片难度还是挺大的。

最开始是想基于 neofetch 来做:

Neofetch is a command-line system information tool written in bash 3.2+. Neofetch displays information about your operating system, software and hardware in an aesthetic and visually pleasing way.

The overall purpose of Neofetch is to be used in screen-shots of your system. Neofetch shows the information other people want to see. There are other tools available for proper system statistic/diagnostics.

The information by default is displayed alongside your operating system’s logo. You can further configure Neofetch to instead use an image, a custom ASCII file, your wallpaper or nothing at all.

You can further configure Neofetch to display exactly what you want it to. Through the use of command-line flags and the configuration file you can change existing information outputs or add your own custom ones.

Neofetch supports almost 150 different operating systems. From Linux to Windows, all the way to more obscure operating systems like Minix, AIX and Haiku. If your favourite operating system is unsupported: Open up an issue and support will be added.

地址:https://github.com/dylanaraps/neofetch/

效果:

在实际测试的时候发现左侧的图片要想实现项目首页的这个效果,竟然无法做到,按照 wiki 的指导,支持下面的 backend:

Neofetch 3.0 included a rewrite of how we handle different modes (imageascii and etc) which allowed us to add additional image backends to Neofetch. Neofetch now supports displaying images using catimglibcacachafaiterm2jp2akittypixtermpotlibsixeltermpixtycat, and w3m.

然而,不管是 iterm2 还是w3m,实际实现效果都非常差。无法正常显示要加载的图片。后来发现 viu 可以在终端显示图片,然而效果嘛,看下来还是不行,不过放到终端里面,也算是能看出人形来了。

然而,困难之处在于 neofetch 无法使用 viu 作为 backend 显示图片。

并且这个项目已经停止更新了,按照作者的说法是回家种地了。就在这个结束不久之后又出现了一堆新的 fetch。

按照评价最高的就是 fastfetch,这个东西同样支持定制化的图片输出。

Fastfetch is a neofetch-like tool for fetching system information and displaying it prettily. It is written mainly in C, with performance and customizability in mind. Currently, Linux, Android, FreeBSD, macOS, SunOS and Windows 7+ are supported.

地址:https://github.com/fastfetch-cli/fastfetch?tab=readme-ov-file

这个东西是用 c 语言开发的,不再跟 neofetch 一样是纯 bash 脚本。至于运行效率提升,应该是有一些。

同样,看项目首页的效果还是不错的:

既然选定了目标,那就继续开始折腾吧。由于家里的电脑是 windows,所以选择了远程 ssh 到 ubuntu 服务器上进行配置的方式。在测试的过程中发现基于 w3m 无法在 ssh 终端中显示图像。一番搜索之后,发现了这么一个项目:

https://github.com/sqlsec/fastfetch/tree/main?tab=readme-ov-file
Fastfetch 是一个类似 neofetch 的工具,用于获取系统信息并漂亮地显示它。它主要用 C 语言编写,并考虑了性能和可定制性。本项目是一个 Fastfetch 轮子,主要是集成了宝可梦显示和其他系列的恶搞图片,目前只在 Linux 和 macOS 平台下测试过。

里面继承了一个宝可梦的字符图片生成。那么基于这个东西既然能在 ssh 中显示,那么也就是说如果能生成宝可梦类似的文本就可以正常显示所谓的图片了。

上面的图片虽然模糊,但是生成一个网站 logo 应该是可以的。宝可梦的字符串是基于这个项目创建的:

https://gitlab.com/phoneybadger/pokemon-colorscripts.git

翻了半天代码发现,并不是通过图片生成的文本,而是本身就已经是文本:

这就尴尬了,也就是说通过这个项目的代码将图片转为文本已经不可能了。

google 上搜索 convert image/picture to text 或者convert image/picture to ascii,发现返回的都是 ocr 相关的内容,这该死的人工智能,现在已经没人有这种需求了吗?我是真的要讲图片转为文本,而不是要识别图片上的文本。翻了数十页,有用的信息 一条也没有。

这时突然灵光一现,直接搜索转化的文本:

https://www.google.com/search?q=%5B38%3B2%3B0%3B0%3B0m%E2%96%84%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84++++++++++++++++++++%0D%0A++%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B99%3B132%3B173m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B0%3B0%3B0m%E2%96%80%1B%5B0m+++++++++++++++%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B0%3B0%3B0m%E2%96%80%1B%5B0m++%0D%0A+%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B0%3B0%3B0m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B99%3B132%3B173m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B99%3B132%3B173m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B99%3B132%3B173m%1B%5B48%3B2%3B65%3B65%3B65m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B65%3B65%3B65m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B189%3B189%3B189m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84+++%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B65%3B65%3B65m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B65%3B65%3B65m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84%0D%0A%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B0%3B0%3B0m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B99%3B132%3B173m%1B%5B48%3B2%3B90%3B99%3B123m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B99%3B132%3B173m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B99%3B132%3B173m%1B%5B48%3B2%3B65%3B65%3B65m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B65%3B65%3B65m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B189%3B189%3B189m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B65%3B65%3B65m%1B%5B48%3B2%3B65%3B65%3B65m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B99%3B132%3B173m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B90%3B99%3B123m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B0%3B0%3B0m%E2%96%80%1B%5B0m+%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B189%3B189%3B189m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B132%3B132%3B132m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B132%3B132%3B132m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B189%3B189%3B189m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B0%3B0%3B0m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%80&newwindow=1&sca_esv=0fc7dd398656b67a&biw=2519&bih=1218&sxsrf=AHTn8zrYB8iVn-PuK5p4PazbOlDmwyh7KQ%3A1739371785317&ei=CbWsZ_H3Esjo1e8P25fugAY&ved=0ahUKEwixoJXrsL6LAxVIdPUHHduLG2A4HhDh1QMIEg&uact=5&oq=%5B38%3B2%3B0%3B0%3B0m%E2%96%84%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84++++++++++++++++++++%0D%0A++%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B99%3B132%3B173m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B0%3B0%3B0m%E2%96%80%1B%5B0m+++++++++++++++%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B0%3B0%3B0m%E2%96%80%1B%5B0m++%0D%0A+%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B0%3B0%3B0m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B99%3B132%3B173m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B99%3B132%3B173m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B99%3B132%3B173m%1B%5B48%3B2%3B65%3B65%3B65m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B65%3B65%3B65m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B189%3B189%3B189m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84+++%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B65%3B65%3B65m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B65%3B65%3B65m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84%0D%0A%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B0%3B0%3B0m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B99%3B132%3B173m%1B%5B48%3B2%3B90%3B99%3B123m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B99%3B132%3B173m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B99%3B132%3B173m%1B%5B48%3B2%3B65%3B65%3B65m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B65%3B65%3B65m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B189%3B189%3B189m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B65%3B65%3B65m%1B%5B48%3B2%3B65%3B65%3B65m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B99%3B132%3B173m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B90%3B99%3B123m%1B%5B48%3B2%3B99%3B132%3B173m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B0%3B0%3B0m%E2%96%80%1B%5B0m+%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%84%1B%5B38%3B2%3B0%3B0%3B0m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B189%3B189%3B189m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B132%3B132%3B132m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B132%3B132%3B132m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B189%3B189%3B189m%1B%5B48%3B2%3B255%3B255%3B255m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B255%3B255%3B255m%1B%5B48%3B2%3B0%3B0%3B0m%E2%96%80%1B%5B0m%1B%5B38%3B2%3B0%3B0%3B0m%E2%96%80&gs_lp=Egxnd3Mtd2l6LXNlcnAi-g9bMzg7MjswOzA7MG3iloQbWzM4OzI7MDswOzBtG1s0ODsyOzk5OzEzMjsxNzNt4paAG1swbRtbMzg7MjswOzA7MG3iloQgICAgICAgICAgICAgICAgICAgIAogIBtbMzg7MjswOzA7MG3iloQbWzM4OzI7MDswOzBtG1s0ODsyOzk5OzEzMjsxNzNt4paAG1swbRtbMzg7Mjs5OTsxMzI7MTczbRtbNDg7Mjs5OTsxMzI7MTczbeKWgBtbMG0bWzM4OzI7MDswOzBtG1s0ODsyOzA7MDswbeKWgBtbMG0gICAgICAgICAgICAgICAbWzM4OzI7MDswOzBt4paEG1szODsyOzA7MDswbRtbNDg7MjsyNTU7MjU1OzI1NW3iloAbWzBtG1szODsyOzA7MDswbRtbNDg7MjswOzA7MG3iloAbWzBtICAKIBtbMzg7MjswOzA7MG0bWzQ4OzI7MDswOzBt4paAG1swbRtbMzg7Mjs5OTsxMzI7MTczbRtbNDg7Mjs5OTsxMzI7MTczbeKWgBtbMG0bWzM4OzI7OTk7MTMyOzE3M20bWzQ4OzI7OTk7MTMyOzE3M23iloAbWzBtG1szODsyOzk5OzEzMjsxNzNtG1s0ODsyOzY1OzY1OzY1beKWgBtbMG0bWzM4OzI7MDswOzBtG1s0ODsyOzY1OzY1OzY1beKWgBtbMG0bWzM4OzI7MDswOzBtG1s0ODsyOzI1NTsyNTU7MjU1beKWgBtbMG0bWzM4OzI7MDswOzBtG1s0ODsyOzI1NTsyNTU7MjU1beKWgBtbMG0bWzM4OzI7MDswOzBtG1s0ODsyOzI1NTsyNTU7MjU1beKWgBtbMG0bWzM4OzI7MDswOzBtG1s0ODsyOzE4OTsxODk7MTg5beKWgBtbMG0bWzM4OzI7MDswOzBt4paEG1szODsyOzA7MDswbeKWhBtbMzg7MjswOzA7MG0bWzQ4OzI7OTk7MTMyOzE3M23iloAbWzBtG1szODsyOzA7MDswbeKWhCAgIBtbMzg7MjswOzA7MG3iloQbWzM4OzI7MDswOzBtG1s0ODsyOzI1NTsyNTU7MjU1beKWgBtbMG0bWzM4OzI7MDswOzBt4paEG1szODsyOzA7MDswbRtbNDg7MjsyNTU7MjU1OzI1NW3iloAbWzBtG1szODsyOzI1NTsyNTU7MjU1bRtbNDg7MjsyNTU7MjU1OzI1NW3iloAbWzBtG1szODsyOzI1NTsyNTU7MjU1bRtbNDg7Mjs2NTs2NTs2NW3iloAbWzBtG1szODsyOzA7MDswbRtbNDg7Mjs2NTs2NTs2NW3iloAbWzBtG1szODsyOzA7MDswbeKWhBtbMzg7MjswOzA7MG3iloQKG1szODsyOzA7MDswbRtbNDg7MjswOzA7MG3iloAbWzBtG1szODsyOzk5OzEzMjsxNzNtG1s0ODsyOzkwOzk5OzEyM23iloAbWzBtG1szODsyOzk5OzEzMjsxNzNtG1s0ODsyOzk5OzEzMjsxNzNt4paAG1swbRtbMzg7Mjs5OTsxMzI7MTczbRtbNDg7Mjs2NTs2NTs2NW3iloAbWzBtG1szODsyOzY1OzY1OzY1bRtbNDg7MjsyNTU7MjU1OzI1NW3iloAbWzBtG1szODsyOzI1NTsyNTU7MjU1bRtbNDg7Mjs5OTsxMzI7MTczbeKWgBtbMG0bWzM4OzI7MTg5OzE4OTsxODltG1s0ODsyOzk5OzEzMjsxNzNt4paAG1swbRtbMzg7MjsyNTU7MjU1OzI1NW0bWzQ4OzI7OTk7MTMyOzE3M23iloAbWzBtG1szODsyOzI1NTsyNTU7MjU1bRtbNDg7MjsyNTU7MjU1OzI1NW3iloAbWzBtG1szODsyOzI1NTsyNTU7MjU1bRtbNDg7MjsyNTU7MjU1OzI1NW3iloAbWzBtG1szODsyOzI1NTsyNTU7MjU1bRtbNDg7MjsyNTU7MjU1OzI1NW3iloAbWzBtG1szODsyOzY1OzY1OzY1bRtbNDg7Mjs2NTs2NTs2NW3iloAbWzBtG1szODsyOzk5OzEzMjsxNzNtG1s0ODsyOzk5OzEzMjsxNzNt4paAG1swbRtbMzg7Mjs5MDs5OTsxMjNtG1s0ODsyOzk5OzEzMjsxNzNt4paAG1swbRtbMzg7MjswOzA7MG0bWzQ4OzI7MDswOzBt4paAG1swbSAbWzM4OzI7MDswOzBt4paEG1szODsyOzA7MDswbRtbNDg7MjsyNTU7MjU1OzI1NW3iloAbWzBtG1szODsyOzI1NTsyNTU7MjU1bRtbNDg7MjsyNTU7MjU1OzI1NW3iloAbWzBtG1szODsyOzE4OTsxODk7MTg5bRtbNDg7MjsyNTU7MjU1OzI1NW3iloAbWzBtG1szODsyOzI1NTsyNTU7MjU1bRtbNDg7MjsyNTU7MjU1OzI1NW3iloAbWzBtG1szODsyOzI1NTsyNTU7MjU1bRtbNDg7MjsxMzI7MTMyOzEzMm3iloAbWzBtG1szODsyOzEzMjsxMzI7MTMybRtbNDg7MjsyNTU7MjU1OzI1NW3iloAbWzBtG1szODsyOzE4OTsxODk7MTg5bRtbNDg7MjsyNTU7MjU1OzI1NW3iloAbWzBtG1szODsyOzI1NTsyNTU7MjU1bRtbNDg7MjswOzA7MG3iloAbWzBtG1szODsyOzA7MDswbeKWgDIKEAAYsAMY1gQYRzIKEAAYsAMY1gQYRzIKEAAYsAMY1gQYRzIKEAAYsAMY1gQYRzIKEAAYsAMY1gQYRzIKEAAYsAMY1gQYRzIKEAAYsAMY1gQYRzIKEAAYsAMY1gQYRzIKEAAYsAMY1gQYRzIKEAAYsAMY1gQYR0iLB1DtA1jtA3ACeAGQAQCYAQCgAQCqAQC4AQPIAQD4AQL4AQGYAgKgAgaYAwCIBgGQBgqSBwEyoAcA&sclient=gws-wiz-serp

nice,总算是给了点提示,ansi color,或者 ansi 。继续搜索图片转 ansi,最后终于找到了一个在线工具:

https://dom111.github.io/image-to-ansi/

那么有了这个东西,就可以将图片转化为宝可梦类似的字符串了。

下面会给出对应的 sh 脚本代码,测试效果可以直接扔到终端去测试。

图片转化解决了,剩下的就是怎么写配置文件。搜索的时候发现了这么一篇文章,同样里面给出了上面的配置文件脚本的合集:

https://www.sqlsec.com/2024/09/ubuntu.html#

参考文章给的:https://github.com/sqlsec/fastfetch里面的配置文件,编写自己的配置文件。

将上面图片转 ansi 给出的 sh 脚本保存为 sh 文件,修改配置文件的 图片为下面的内容:

"modules": [
        {
            "type": "command",
            "text": "sh $HOME/.config/fastfetch/sh/logo-80.sh",
            "key": "\n"
        },

上面的代码没有在 logo 字段内设置,目前还没发现怎么在 logo 中执行命令,如果直接将生成的字符串贴到 logo 内会报错。

通过下面的命令验证配置文件,主要文件路径要复制到用户目录下的.config/fastfetch/中。

这个是基于 zsh 的,当然如果是 iterm 那么效果就更加惊艳了。如下面:

远程 ssh 效果:

为了简化上面的操作,于是我创建了一个开源项目,如果需要可以直接拉取代码针对性修改即可。

下面正文开始啦:

1.安装 fastfetch,具体安装方法,参考https://github.com/fastfetch-cli/fastfetch

Linux

 

Some distros package an outdated fastfetch version. Older versions receive no support, so please try always to use the latest version.

Packaging status

  • Ubuntu: ppa:zhangsongcui3371/fastfetch (for Ubuntu 22.04 or newer)
  • Debian: apt install fastfetch (for Debian 13 or newer)
  • Debian / Ubuntu: Download fastfetch-linux-<proper architecture>.deb from Github release page and double-click it (for Ubuntu 20.04 or newer and Debian 11 or newer).
  • Arch Linux: pacman -S fastfetch
  • Fedora: dnf install fastfetch
  • Gentoo: emerge --ask app-misc/fastfetch
  • Alpine: apk add --upgrade fastfetch
  • NixOS: nix-shell -p fastfetch
  • openSUSE: zypper install fastfetch
  • ALT Linux: apt-get install fastfetch
  • Exherbo: cave resolve --execute app-misc/fastfetch
  • Solus: eopkg install fastfetch
  • Slackware: sbopkg -i fastfetch
  • Void Linux: xbps-install fastfetch
  • Venom Linux: scratch install fastfetch

You may need sudodoas or sup to run these commands.

If fastfetch is not packaged for your distro or an outdated version is packaged, linuxbrew is a good alternative: brew install fastfetch

macOS

 

Windows

 

  • scoopscoop install fastfetch
  • Chocolateychoco install fastfetch
  • wingetwinget install fastfetch
  • MSYS2 MinGWpacman -S mingw-w64-<subsystem>-<arch>-fastfetch

You may also download the program directly from the GitHub releases page in the form of an archive file.

FreeBSD

 

  • pkg install fastfetch

Android (Termux)

 

  • pkg install fastfetch

2.拉取项目代码:git clone https://gitee.com/obaby/baby-fetch

将项目目录下的 fastfetch 复制到用户目录下的.config 目录下

cp -rf fastfetch ~/.config/

增加一键部署脚本,下载后直接执行 deploy.sh 即可,支持 bash, zsh 终端!后续步骤可以省略了!!!

增加一键部署脚本,下载后直接执行 deploy.sh 即可,支持 bash, zsh 终端!后续步骤可以省略了!!!

增加一键部署脚本,下载后直接执行 deploy.sh 即可,支持 bash, zsh 终端!后续步骤可以省略了!!!

直接修改 welcome.sh 修改加载配置文件皆可!

直接修改 welcome.sh 修改加载配置文件皆可!

直接修改 welcome.sh 修改加载配置文件皆可!

(venv) zhongling@ZhongLingdeMBP baby_fetch % /bin/bash /Users/zhongling/PycharmProjects/baby_fetch/deploy.sh
===========================================================================
Baby fetch自动部署工具
obaby@mar
https://h4ck.org.cn
https://oba.by
https://nai.dog
===========================================================================
Start deploy:
copy files......
*************************************
Write config to terminal profile:
process .bash_profile
already exists, skip
-------------------------------------
process .zshrc
already exists, skip
-------------------------------------
process .profile
already exists, skip
All done, have a nice day
===========================================================================

 

红字部分于2015.01.13 17.25 更新!

3.修改终端配置文件,在修改之前需要确定当前运行的终端是什么 bash,zsh 或者是其他的什么东西。

例如,我这里的终端是 zsh,运行 fastfetch 查看 shell 字段:

vim ~/.zshrc

添加以下代码:

if [ -f ~/.config/fastfetch/welcome.sh ]; then
    ~/.config/fastfetch/welcome.sh
fi

如果是 bash :

vim ~/.bash_profile

同理其他的终端修改对应的位置文件,执行 source ~/.zshrc加载配置文件,如果无误应该就可以看到效果了。

目前针对 macos welcome.sh 会针对是否运行在 iterm 内加载不同的配置文件:

#!/bin/bash
if [ "$TERM_PROGRAM" = "iTerm.app" ]; then
#    echo "当前运行在 iTerm 中"
     fastfetch -c ~/.config/fastfetch/config-obaby-mac-iterm-weding.jsonc
else
#    echo "当前没有运行在 iTerm 中"
    fastfetch -c ~/.config/fastfetch/config-obaby-logo-80.jsonc
fi

同样定制化加载的文件也可以通过修改 welcome.sh实现,或者直接修改这个文件加载的配置文件实现。

为了更好的体验效果,在 mac 下建议安装 iterm,linux 下建议安装kitty。

iterm 建议通过 homebrew 安装:

brew install iterm2

https://iterm2.com

https://sw.kovidgoyal.net/kitty/binary/

4.显示问题,如果显示有乱码建议安装包含自带字体图标的字体,可以通过这里下载:https://www.nerdfonts.com/font-downloads

项目中已经包含了两个字体压缩包,可以直接安装使用。

同样,针对 ssh 的欢迎语也可以通过修改终端配置文件实现,这么改的好处是,针对不同用户可以用户自己定义。并且不需要修改 sshd配置文件,无需重启服务。

测试环境:

Mac:

 CPU Apple M1
󰋵 GPU Apple Apple M1 Ghz
󰀚 Memory 13.46 GiB / 16.00 GiB (84%)
󰘳 Shell zsh v5.9
󰀚 Disk 200.69 GiB / 228.27 GiB (88%) – apfs [Read-only]
󰀚 Disk 5.06 MiB / 5.06 MiB (100%) – hfs [External, Read-only]
󰀚 Disk 766.07 MiB / 934.23 MiB (82%) – apfs [External, Read-only]
󰘳 Network en0 192.168.8.100/24
󱦟 OS Age 20132 days
󱫐 Uptime 41 days, 23 hours, 57 mins
 Machine MacBook Pro (13-inch, M1, 2020) (Apple Inc.)

Ubuntu:

󰀶 OSUbuntu 22.04.4 LTS x86_64
󱢌 Bios449e491 (0.0)
 KernelLinux 5.15.0-92-generic
󰏗 Packages1190 (dpkg), 3 (snap)
󰹑 Display1024x768 @ 60 Hz
 Terminalsshd

● ● ● ● ● ● ● ●

 CPUIntel(R) Xeon(R) Platinum
󰋵 GPUCirrus Logic GD 5446 Ghz
󰀚 Memory1.00 GiB / 1.65 GiB (61%)
󰘳 Shellbash v5.1.16
󰀚 Disk27.71 GiB / 39.01 GiB (71%) – ext4
󰘳 Networketh0 172.23.120.93/20
󱦟 OS Age 380 days
󱫐 Uptime 89 days, 20 hours, 50 mins
 MachineAlibaba Cloud ECS (Alibaba Cloud)

项目地址:

https://gitee.com/obaby/baby-fetch

https://github.com/obaby/baby-fetch

参考链接:

https://github.com/sqlsec/fastfetch

https://www.sqlsec.com/2024/09/ubuntu.html#%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B

https://talyian.github.io/ansicolors/

https://gitlab.com/phoneybadger/pokemon-colorscripts

 

定制博客开发者工具控制台个性化输出

2025年2月12日 13:25

首先祝大家元宵节快乐啊,其实这个东西也不是什么新奇玩意儿了。

很多网站都有这个东西,例如百度:

但是就输出这么个东西明显不够高级的样子,上午访问小小小小的小的博客,发现他的主题自带的输出还是蛮有意思的:

既然如此,俺就不如直接抄过来了:

            <script>
                // 消除控制台打印
                var HoldLog = console.log;
                console.log = function() {}
                ;
                let now1 = new Date();
                queueMicrotask( () => {
                    const Log = function() {
                        HoldLog.apply(console, arguments);
                    };
                    //在恢复前输出日志
                    const grt = new Date("08/10/2009 00:00:00");
                    //此处修改你的建站时间或者网站上线时间
                    now1.setTime(now1.getTime() + 250);
                    const days = (now1 - grt) / 1000 / 60 / 60 / 24;
                    const dnum = Math.floor(days);
                    const ascll = [`欢迎访问obaby@mars!`, `爱自己,每天都要开开心心的哦`, `
 ██████  ██████   █████  ██████  ██    ██  ██████  ███    ███  █████  ██████  ███████ 
██    ██ ██   ██ ██   ██ ██   ██  ██  ██  ██    ██ ████  ████ ██   ██ ██   ██ ██      
██    ██ ██████  ███████ ██████    ████   ██ ██ ██ ██ ████ ██ ███████ ██████  ███████ 
██    ██ ██   ██ ██   ██ ██   ██    ██    ██ ██ ██ ██  ██  ██ ██   ██ ██   ██      ██ 
 ██████  ██████  ██   ██ ██████     ██     █ ████  ██      ██ ██   ██ ██   ██ ███████ 
        `, "已上线", dnum, "天", "©2025 By obaby@mars V1.8.16", ];
                    const ascll2 = [`NCC2-036`, `调用前置摄像头拍照成功,识别为【小笨蛋】.`, `Photo captured: `, `🤪`];

                    setTimeout(Log.bind(console, `\n%c${ascll[0]} %c ${ascll[1]} %c ${ascll[2]} %c${ascll[3]}%c ${ascll[4]}%c ${ascll[5]}\n\n%c ${ascll[6]}\n`, "color:#425AEF", "", "color:#ff4f87", "color:#425AEF", "", "color:#425AEF", ""));
                    setTimeout(Log.bind(console, `%c ${ascll2[0]} %c ${ascll2[1]} %c \n${ascll2[2]} %c\n${ascll2[3]}\n`, "color:white; background-color:#4fd953", "", "", 'background:url("https://npm.elemecdn.com/anzhiyu-blog@1.1.6/img/post/common/tinggge.gif") no-repeat;font-size:450%'));

                    setTimeout(Log.bind(console, "%c WELCOME %c 你好,小笨蛋.", "color:white; background-color:#4f90d9", ""));

                    setTimeout(console.warn.bind(console, "%c ⚡ Powered by obaby@mars %c 你正在访问 小妖精 的博客.", "color:white; background-color:#f0ad4e", ""));
                    setTimeout(console.warn.bind(console, "%c ❶ Blog: %c https://oba.by", "color:white; background-color:#ff7aa4", ""));
                    setTimeout(console.warn.bind(console, "%c ❷ Blog: %c https://nai.dog", "color:white; background-color:#ff7aa4", ""));
                    setTimeout(console.warn.bind(console, "%c ❸ Blog: %c https://zhongxiaojie.com", "color:white; background-color:#ff7aa4", ""));
                    setTimeout(console.warn.bind(console, "%c ❹ Blog: %c https://h4ck.org.cn", "color:white; background-color:#ff7aa4", ""));
                    setTimeout(Log.bind(console, "%c W23-12 %c 你已打开控制台.", "color:white; background-color:#4f90d9", ""));

                    setTimeout(console.warn.bind(console, "%c S013-782 %c 你现在正处于监控中,不要干坏事哦.", "color:white; background-color:#d9534f", ""));
                }
                );
            </script>

至于怎么生成上面的 ascii 字符串,可以使用下面的两个链接:

https://patorjk.com/software/taag/

http://www.network-science.de/ascii/

把上面的代码找个 js 文件写进而去,在页面 header 里面引用即可(我直接将代码添加到了 wp 的页面小工具内)。实际效果:

当然也可以直接 F12 打开开发者工具查看具体效果。嘎嘎。

冰糖葫芦 — 糖球 DIY

2025年2月10日 10:16

周六,按理说是一个休息的日子。当然,即使正常上班了周六可能也在加班。所以也就无所谓了,下午约朋友打球。毕竟新的球杆到了还没试下效果到底咋样。

公司周围的小饭店都没开门,开车到台球厅楼下停好车,附近找了个甏肉干饭,简单吃了点东西。结果回到台球厅之后发现台球厅黑了,里面黑漆漆的。进门问了一下才知道原来是停电了,貌似是跳闸了。话说这几天这个电力这么不稳定的吗?

鉴于球杆实在是太长了,也不想天天背着到处跑了。之前还想着球厅存放球杆的地方是收费的,问还有没有空闲的,怎么收费。结果感觉似乎被嘲讽了:“嗐,你们来打球就很不错了,存个球杆那还能收费?等来电了你跟前台说下,让给开个小柜子就行”老板如是回答。

看来还是自己想当然了,以为存东西是要收费的。这下真不错,不用来回抱着球杆跑了终于。

 

带着球杆修理工具,刚开始一边打球一边修理球杆,感觉杆头总是不尽如人意。尤其是那个弧度感觉不够完美,总是欠缺点东西。刚打磨完的皮头,毛茸茸的。用了一两个小时之后逐渐感觉稍微好了一点,不再那么毛躁了。不过,不该带白色的手套,太容易抹黑了。这鲜血附魔的球杆,目前还没感觉多厉害,主要是那天发挥也不咋地。等哪天状态好了再试试吧,毕竟要适应一段时间。球杆存上了,但是台费不够了,走的时候又充了 300。

周日中午实在不想做饭,带着宝子去乐客城吃的烤鱼。吃完饭,走斜坡往下载,第一次注意到挂在护栏上的两个小动物。

不过,不得不说,这个小东西的 pp 是真的圆啊。😂

回到家宝子嚷嚷着,要做糖葫芦,终于到了文章的正题啦。问了下才知道,她前几天在小姨家看斑马英语的时候,节日主题课程,讲到了做冰糖葫芦。

拿着 pad 我又看了一遍做法,相对来说还是比较简单的。

1.先去买水果啊,想吃神马就做什么,家里还有些山楂,我要吃小西红柿,宝子要吃草莓,后来我还想吃葡萄,从盒马买的葡萄等了两个小时也是让人崩溃。然后就是洗净,擦干水分,穿起来啦。建议用粗点的签子,太细的感觉容易掉,并且可能会断。

2.准备 500g 白砂糖(冰糖)500ml 水 ,将白砂糖和水加入平底锅,大火烧开,转中火蒸发水分。待变成焦糖色关火,不要继续加热了,容易糊,糊了味道就不好吃啦,注意好火候哦。如果准备的水果比较多,建议多加点糖,1:1 的比例就差不多啦。

煮开

搅拌均匀加热,不容易糊

最后变成焦糖色(酱油色)

3.就是把串号的水果,在糖水里转几圈,沾满糖浆。如果糖浆不够,可以用勺子浇上点。

基本就是上面的样子啦。

4.静置晾凉,大于十几分钟就能固化了,当然此时还不是很结实,可以放到冰箱里冷冻一会儿,这样糖更不容易化。

可以尽情的先用自己做的冰糖葫芦啦。

Upscayl–免费开源的图片放大工具

2025年2月10日 09:33

宝子要开学啦,老师给安排了一张手抄报作业,并且给了个模板。然而,要打印的时候才发现有个大问题,就是图片带水印。

使用 ai 修图工具去掉水印之后变成了下面的样子:

水印没了,房子也没了一层,哈哈哈。这就离谱,不过好在依靠自己拙劣的 ps 水平勉强把图片修复好了(图片在家里的电脑上,后续补图

此时,另外一个问题出现了就是图片清晰度太差,打印效果惨不忍睹,于是继续增强图片分辨率,强化画质。得益于 ai 的迅速发展,现在很多图片增强都免费了。之前一直用的Topaz Gigapixel AI,不过这个是收费的(需要的可以去搜索破解版),另外,百度的在线图片功(baiduAI 图片助手)能也支持画质增强:

https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=detail&hs=0&xthttps=111110&sf=1&fmq=1713767239197_R&pv=&ic=0&nc=1&z=&se=&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=bdaitpzs%E7%99%BE%E5%BA%A6AI%E5%9B%BE%E7%89%87%E5%8A%A9%E6%89%8Bbdaitpzs&oq=%E5%9B%BE%E7%89%87&rsp=-1&toolType=3&fr=home&sa=searchpromo_shijian_photohp_repair

下午瞎逛的时候看到了另外一个免费的工具,就是上面提到的这个:

🆙 Upscayl – #1 Free and Open Source AI Image Upscaler for Linux, MacOS and Windows.

官网地址:https://upscayl.org

效果测试:

缩略图:

增强对比:

增强之后:

原图见文章头图,整体看起来效果还是蛮不错的,毕竟免费不是吗?

下载地址(从上面的官网链接找下载地址即可):

温馨提示: 此处隐藏内容需要发表评论,并且审核通过后才能查看。
(发表评论请勾选 在此浏览器中保存我的显示名称、邮箱地址和网站地址,以便下次评论时使用。
(请仔细检查自己的昵称和评论内容,以免被识别为垃圾评论而导致无法正常审核。)

参考链接:(不建议使用下方文章中的下载地址下来,感觉像个中文镜像站,并且翻了半天都没找到下载地址,可能需要挂梯子。未测试,下载请请直接从 github 下载)

https://www.suiyan.cc/blog/20250209010356

OpenAI SDK — 不再重复造轮子

2025年2月8日 13:45

既然聊到了ai,那么这个头图其实也是 ai 换脸得来的,也用 ai 的图片吧,毕竟自己拍的写真的存货已经不多了没了。而鉴于现在这个温度,的确是不像去拍外景,怕拍完了就冻死在外面了。

与哪吒一样,这个春节热度飙升的在 ai 领域无疑就是 deepseek 了。自己最开始接触 deepseek 也是因为超便宜的价格,所以在很早之前就在用这个东西里,各种聊天记录可以看到很多基础问题,但是给的答案嘛,个人感觉并没有比其他的 ai 高很多,可以使用 duckduckgo 的免费 ai 聚合:https://duckduckgo.com/?q=DuckDuckGo+AI+Chat&ia=chat&duckai=1

在节前另外一次出圈,应该是雷军挖了 deepseek 的自然语言专家罗福莉。当时还大概看了下这个姐妹的研究内容和方向。

等到了过年的时候deepseek 就成了碾压 chatgpt 之类的存在,到处都是他的新闻和消息。为此也有一群人开始出来蹭热度,四分之一个世界过去了,这个变化并不大,从之前的 bbs 转到了短视频平台。各种所谓的红客、ddos 、华为之类的假新闻和消息开始到处转发,甚至连周鸿祎都要出来蹭一波热度,如果仔细看过年期间 deepseek 的前端人机验证工具其实用的 cf 的。

甚至所谓的这些官方媒体都无脑转发这些乱七八糟的假消息。

至于我为什么要现在提这个东西,是因为放假的时候同事说可以试试 deepseek 的合同解析功能,可以识别里面的各种信息。按照他发的图,看了下,大约的确是可以的,然而,问题的关键在于 deepseek 的 sdk 并没有实现相关文件上传的方法。

说到 sdk,这里不得不说的是,在 ai 领域的 sdk 开发中,终于避免了重复造轮子的问题。多数都是 openai sdk 兼容的,只需要替换服务器地址和密钥即可。

DeepSeek API 使用与 OpenAI 兼容的 API 格式,通过修改配置,您可以使用 OpenAI SDK 来访问 DeepSeek API,或使用与 OpenAI API 兼容的软件。

PARAM VALUE
base_url * https://api.deepseek.com
api_key apply for an API key

* 出于与 OpenAI 兼容考虑,您也可以将 base_url 设置为 https://api.deepseek.com/v1 来使用,但注意,此处 v1 与模型版本无关。

deepseek-chat 模型已全面升级为 DeepSeek-V3,接口不变。 通过指定 model='deepseek-chat' 即可调用 DeepSeek-V3。

deepseek-reasoner 是 DeepSeek 最新推出的推理模型 DeepSeek-R1。通过指定 model='deepseek-reasoner',即可调用 DeepSeek-R1。

以上是 deepseek 文档的内容,基于 openai sdk 的方法实现文件上传:

from openai import OpenAI
client = OpenAI(api_key=ak, base_url="https://api.deepseek.com")
response1 = client.files.create(file=open("../baidu_ocr_tools/test_data/contract.pdf", "rb"), purpose="batch")

执行后会得到下面的错误提示:

openai.NotFoundError: Error code: 404 - {'event_id': '30-inst-179-20250208132511-263a5c3c', 'error_msg': 'Not Found. Please check the configuration.'}y

也就是说 deepseek 没有实现文件上传的后端接口,但是聊天界面却是可以的。

既然 web 页面可以,那么就可以使用另外的方法:通过调用 web端的接口实现文件上传,要找接口也简单:

一个 upload 接口即可,然而,这个接口拿到之后,用相关的参数进行模拟,不管是代码提交还是 postman 提交,都得到了同样的错误,文件状态 pending,这个和 web 端一致:

然而获取文件信息的时候却是 failed,而 web 页面却是正常的:

同样的数据,重复提交也会失败,这就很神奇,当然,可能的问题出在header 中的x-ds-pow-response:

eyJhbGdvcml0aG0iOiJEZWVwU2Vla0hhc2hWMSIsImNoYWxsZW5nZSI6IjdmMThjNTQzMzZkNjM1YWFkODljOGMxZDE4YmMwNTk1M2MxZjY2N2ZhM2FiZDMyMmJiYTdhZDQwOWZhNDI5NzkiLCJzYWx0IjoiNzRhOWE1ZTdhM2YxNDU3NTdmNGUiLCJhbnN3ZXIiOjEyNjczMCwic2lnbmF0dXJlIjoiNWE3ZWQ1MzdjNjQ0OTY2Nzg3Yjk1Y2ZlNGU4NDc5YTAzYWYyMmFkNjA3MWMxMGU2YWQ3ZjZkZjAxMGM5NTZmMiIsInRhcmdldF9wYXRoIjoiL2FwaS92MC9maWxlL3VwbG9hZF9maWxlIn0

 

base64 decode后是:

{"algorithm":"DeepSeekHashV1","challenge":"7f18c54336d635aad89c8c1d18bc05953c1f667fa3abd322bba7ad409fa42979","salt":"74a9a5e7a3f145757f4e","answer":126730,"signature":"5a7ed537c644966787b95cfe4e8479a03af22ad6071c10e6ad7f6df010c956f2","target_path":"/api/v0/file/upload_file"}

算法写了DeepSeekHashV1,但是怎么实现的不知道,要去还原这个耗费太多精力,感觉不怎么值。另外 api 还有速率限制,所以可行性也不大高。

github 上有个代码也是基于 web 端的 api,

https://github.com/Cunninger/ocr-based-deepseek/blob/main/src/main/java/cn/yam/ocrbaseddeepseek/controller/OCRController.java

我没尝试,但是根据自己的经验,貌似行不通。

那么初次之外还有别的 ai 吗?

后来发现 kimi 的 api,同样是 opensdk 兼容的,并且实现了文件上传方法:

Kimi API 兼容了 OpenAI 的接口规范,你可以使用 OpenAI 提供的 Python(opens in a new tab) 或 NodeJS(opens in a new tab) SDK 来调用和使用 Kimi 大模型,这意味着如果你的应用和服务基于 openai 的模型进行开发,那么只需要将 base_url 和 api_key 替换成 Kimi 大模型的配置,即可无缝将你的应用和服务迁移至使用 Kimi 大模型

示例代码测试:

from pathlib import Path
from openai import OpenAI

client = OpenAI(
    api_key = "sk-9naV7ApT*********",
    base_url = "https://api.moonshot.cn/v1",
)

# xlnet.pdf 是一个示例文件, 我们支持 pdf, doc 以及图片等格式, 对于图片和 pdf 文件,提供 ocr 相关能力
file_object = client.files.create(file=Path("../baidu_ocr_tools/test_data/contract.pdf"), purpose="file-extract")

# 获取结果
# file_content = client.files.retrieve_content(file_id=file_object.id)
# 注意,之前 retrieve_content api 在最新版本标记了 warning, 可以用下面这行代替
# 如果是旧版本,可以用 retrieve_content
file_content = client.files.content(file_id=file_object.id).text

# 把它放进请求中
messages = [
    {
        "role": "system",
        "content": "你是 Kimi,由 Moonshot AI 提供的人工智能助手,你更擅长中文和英文的对话。你会为用户提供安全,有帮助,准确的回答。同时,你会拒绝一切涉及恐怖主义,种族歧视,黄色暴力等问题的回答。Moonshot AI 为专有名词,不可翻译成其他语言。",
    },
    {
        "role": "system",
        "content": file_content,
    },
    {"role": "user", "content": "解析contract.pdf文件, 获取签订双方的信息,户号,公司名称等,解析的数据以 json 格式返回。"},
]

# 然后调用 chat-completion, 获取 Kimi 的回答
completion = client.chat.completions.create(
  model="moonshot-v1-32k",
  messages=messages,
  temperature=0.3,
)

print(completion.choices[0].message)

执行结果:

这个结果自然还可以继续优化,或者调整提示词。但是最起码对于 openai sdk 的后端支撑是足够的。

这个世界毕竟是充满了人云亦云缺乏判断力的乌合之众,而稍微有点成绩很可能的结果就是被捧杀。稍微有点成绩就遥遥领先。

说实话,现在我看到遥遥领先这四个字都开始反胃了!

附,清华大学《deepseek 从入门到精通》:

https://scc.ustc.edu.cn/_upload/article/files/bd/11/edc7c00b4726b6f09c82d41cb3d5/7fed3cfc-7ff4-40cd-8762-e5e62913d6b8.pdf

 

艹,被动附魔了!

2025年2月7日 16:16

年前的暖意在年后轰然倒塌,寒流一波波的来袭,让这个立春之后的季节充满了冬天的韵味。

尽管如此,该出门还是总要出门的,毕竟马上就要上班了,在上班之前,还可以去糖球会溜达溜达。市南,寸土寸金的地方,想停车也是个问题,所以最好的办法就是停到有地铁站的商场,之后坐地铁到达,自然也就免了停车的烦恼。

停好车,自然是要拍照记录下,不然到时候找车就又成了问题。其实宝子穿的这一身,还是有些冷的。

凛冽的寒风也阻挡不了大家游玩的热情,去的时候还比较早,慢慢的人就多了起来。

当然,最帅的还是那辆警车,以及可爱的粉色甲壳虫啊,都想拥有。

不得不说,那个小锅盔的味道感觉也还不错,就是温度稍微低了点,有些凉。

疯了一晚上之后,第二天要上班了,宝子又送到了小姨家,然后又可以开始浪漫的的生活啦,正好过年没看的《哪吒 2》就可以排上日程啦,不过,相对于杜郎杜郎这种狂烈的热爱,的确没那么多时间去再看一遍,我倒是想再去看看《封神榜 2》,不过周遭都是一堆劝退的。

看豆瓣上针对哪吒的一星评价,的确是无法沟通,甚至都懒得反驳。所谓一步动画电影,个人感觉还是满足预期的。看那些影评,如丧考妣,也不是到是怎么戳到他们的痛处了,这么声嘶力竭。

之后,假期买的球杆也到了,然而,看了下杆头没有休整,于是从二手东又买了个多合一的杆头修理工具。球杆送了个小挂件,于是换掉了原来的大熊猫:

真好啊,今天上午到了,拿到之后破不记得去休整下杆头,打磨下弧度。工具就是下面介个样子:

然而,此时看了下球杆盒却发现一头破损了:

想来是昨天往后备箱里硬塞,该弄坏了,嗐,这个智商,真是无敌了。不过这个长度,的确很难塞到后备箱里去啊:

看似不长,然而后备箱两侧要去掉一部分内饰板的空间,里面还有个储物箱子放杂物的,于是剩下的空间就不够把它放进去了。目前,只能扔在后座上了。

拿出前支,开始打磨皮头,然而,过了会儿却发现球杆上出现了暗红色的花纹,还想着硬枫木怎么会有这种颜色呢?此时看了下左右才发现拇指被割破了。应该是刚才拿修复工具的时候,不小心碰到了那个黑色的刀片,太锋利了,割了一道口子竟然没发现,直到血流到了球杆上才知道手指被割破了。

找了跟碘伏棉棒处理了下伤口,然而创可贴却没了,只好在跑到药店去买创可贴。处理好伤口,用酒精湿巾把球杆上的血迹擦掉,然而,可能时间稍微长了点,竟然有些地方擦不掉了。

得,这好了,被动用自己的鲜血给球杆附魔了!

想着昨晚看的临朐羊肉水饺,真的想吃啊。正好前段时间去超市买了一包,中午继续回去吃水饺。已经吃了两天了,前两天都是过年的剩饭,不过今天吗,就是新鲜的啦。

吃完饭出停车场的时候,门卫大叔说出不去了。停电了,道闸打不开。更让人郁闷的是,忽然收到了 nas 进入 ups 供电模式的通知,看来是家里也停电了。

反正也出不去,索性回家看一眼吧。结果到家之后发现似乎所有的插座是有电的,电器都亮着。然而 ups 却一直滴滴滴的响在报警。以为是 ups 出问题了。排查了所有的线路没发现问题。但是 ups 依旧处于报警模式,换不同的插座依旧无效。

在这一瞬间让自己以为是 ups 坏了,准备拆掉,直接用插排直连家里的供电。然而,切换数据显示的时候发现了一个诡异的问题,那就是输入电压之后 110v,这不得不然自己怀疑是自己家里供电的问题。

打开配电箱,切了下数显电表。然而,此时电表只能现实一个 TOO,再按就直接熄灭了,但是家里的插座指示灯都是亮着的,现在连供电电压都确认不了了,自己开始转而怀疑是不是电表问题导致的电压降低。

就在自己想着要不要拆电表的时候,所有的插座也都没电了,这下彻底的安静了,看来是整个楼停电了?跑到-1 蹭的电表箱看了下果然全部都灭了:

得,这下好了,看来不是自己的问题,那就先回公司吧。毕竟也没什么能做的了,此时小区门口的杆都被直接升了起来。收费的地方,岗亭大叔用手机拍了个照,说给补全通行记录,如果没有出场记录,想再进停车场就进不去了。

走到路上才发现,不单是小区的问题,连路上的红绿灯都不亮了,现在看来是整个区停电了:

十字路口也乱成了一锅粥,好在对象有个警车,开着警笛过来,自己方向的车也就跟着过了路口。

这,停电停的的确离谱,到公司在国家电网 app 上提了个工单,不到十分钟,好几个电话打了过来,说大风挂断了高压线,现在已经好了。自己回家,把那些乱七八糟的服务启动了一下,看了下供电电压也正常了,多功能电表也能显示电压了。

最后一个电话又确认了一下,让存下他的电话号码,这个区域的电力是他负责的,有任何问题都可以找他。虽然没说 app 工单的问题,但是,这种上报的工单,从上面派下来,底下的负责人员肯定是要被考核的。不过之前也没联系方式,连不上去直接负责人不是~

这停电停的,让自己都开始怀疑人生了,怀疑了所有的可能能,唯独没有想到是一阵大风所谓。

这血祭,鲜血附魔还是得少用,影响太大了!

白月光 II

2025年2月5日 16:26

过年期间,收到杜郎杜郎的消息,说高中聚会没去,提到了她的初恋。这么一想,自己已经十几年不曾参加过所谓的同学聚会了,大学的不参与,高中的更不参与。

大学复读的那一年参加了一次高中同学聚会,大一的那一年似乎又参加了一次。而大学毕业之后,就离开了济南,那些所谓的通许也竟然就没了联系。虽然有些班级群,但是消息已经静音,至于里面发布的什么消息似乎也无人关注。

曾几何时,腾讯校友录功能,我还建立过班级群,加入过各种班级群。不过后来慢慢的也不再关注,很多人的联系方式可能也都变了。而至于初恋,我的初恋是我的初中同学,当然,那不是初恋,是一种单恋,毕竟人家没恋过自己,把自己当成了所谓的朋友或者比朋友多一点的《半糖主义》,当然,那不算爱。

在这段轰轰烈烈的单相思结束之后,稀里哗啦哭了一通,后来出现了接盘侠,就是初恋的室友,说会永远爱我,不会让我再收到伤害。

可是啊,大学期间的爱情,也经不住现实的考验,更何况是异地。等这个爱人回到了济南,我却去了上海。等我回到济南见到初恋的父母的时候,他们说,山鸡哪能配凤凰!这章丘的百脉泉啊,也浇不灭我的愁思。

后面就是奔波找工作,北京,济南,济南北京,兜兜转转,在一年之后,终于在济南找了份工作,一个月工资 2300。得,人家父母说的是对的,的确是山鸡啊,还要还助学贷款。

对象没了,好在大学的闺蜜还在,开始了跟闺蜜疯狂的爬山之旅。一年的时间,用周末爬遍了济南大大小小的山头,有名的、没名的、开发的、未开发的。

终于闺蜜研究生毕业了,找了份杭州的工作,要去那里面试。自己陪她坐火车去面试,车上满满的都是人,无座的火车,可能那是最后 一次坐吧。K 字头,经过一个晚上才到达杭州,然而,剩下的旅途依然很长。又做了好几个小时的大巴,终于到了一个已经忘记了叫什么名字的小地方。镇上的旅馆破破烂烂的,里面有两张单人床,还有一个简单的床头柜。

寂静而又寒冷的夜,格外的难熬,被窝里都是冰冷的温度,睡到半夜,自己钻到了她的被窝里。两个人抱在一起,感觉暖和了很多,有时候就那么一直贴在一起也蛮好的。就这样停留在那一刻。

然而,回到济南之后,又过了不久自己找到了新的工作,在厦门,毕竟这 2300 的工资,实现都养活不了自己,更无法让自己实现自己的梦想。毕竟两三年的时间,这种持续两千多的工资让未来一眼就看到了尽头。

离开济南的时候想见初恋一面,然而,对方却始终没有出现。之前分手,就成了最后一面。后来自然也就断了消息,很少回到济南,更不曾去过百脉泉。不过之前跟闺蜜开玩笑说,你要是说留下来,我就留下来不走了。不过这终究是一句空话,那时候自己不得不走。毕竟,走了工资就不再是 2000 多了,未来的路似乎有了那么一点点光亮。

在厦门,某一天来了一个同事,声音不好听,但是真的挺让自己心动。后来,慢慢的熟络起来。然而,等到真的要发展成男女朋友的时候,自己却又要回到山东了。当时,想让同事说一句留下来。这时候,如果真的有一句留下来,自己可能真的就留在厦门了。然而,这句话最终也没等到。在厦门没有,在跟同事一起去青岛旅游没有,最后从济南玩完,同事坐飞机离开的时候依然没有。两个人玩了这么多地方,甚至连一张合照都没有。而现在自然连消息都没有了。

不过,人生这个东西,总是充满了巧合。还在厦门的时候,偶然的机会高中同学去厦门出差,作为东道主,陪同学游览了一些景点,去观音山玩了一天。自此之后,断了联系的同学竟然有联系上了。回到青岛之后,家里安排各种相亲,最后都无疾而终,说白了就是穷,挣得太少,还是农村的。门当户对这个东西在这一瞬间,突然变得具象化了。

有一天,在跟高中同学聊天的时候,问对方在干什么。

“在看《我们结婚吧》”

“好啊”我答道。于是,我顺利有了对象。从此摆脱了天天相亲的道路。

然而,缘分这个东西自然也奇妙。就这样高中同学从上海也回到了青岛。自然也就顺理成章的凑到了一起。

多年以后,有了创业的想法,虽然坎坷,倒是也算可以。就在这时候靖哥哥出现了,也是自己喜欢的类型。

“靖哥哥,如果我没结婚的话,我真的想追你”终于有一天,还是把自己内心的想法告诉了靖哥哥。不过,也因为这个表白,公司就多了一些流言蜚语,说我们俩有一腿。这的确有点出乎意料,虽然真的是清白的。直到多年以后,公司在疫情期间嗝屁了之后,还有人在提这件事情,这的确也让我有些出乎意料。

然而啊,这初中同学,大学同学,公司同事们,都是我的白月光。这一道道的光,在某个时间照亮了自己的人生,然而,转瞬却又黯淡了下去。毕竟,她们不属于自己。不过在一个偶然的瞬间,如流星一样划破自己的天空,留下了长长的尾巴,倏然而逝。

初二的晚上,喝了一点酒,想起了自己的闺蜜,于是给她发了一个红包。

只是,似乎自己有钱的太晚了。错过了太多的事情,有太多的爱而不得。时长会记起李荣浩的《年少有为》:

假如我年少有为 不自卑

懂得什么是珍贵

那些美梦

没给你 我一生有愧

假如我年少有为 知进退

才不会让你替我受罪

自卑的自己,放弃了很多东西,有太多的东西不敢追求。可惜啊,哪有什么年少有为,哪怕少年晚成都是个问题。

初二的时候,聊到了台球,三姐家的好大儿问自己用的球杆多少钱。

“两千来块钱吧”我答道。

“我有个同学也打球,打得不错,你猜他买了个球杆多少钱?”他继续问。

“5000?”二姐家的孩子答道。

听到这个,三姐家的孩子打开手机,给我看了一张图片,于是我开始不争气的数图片上的 0,最后确认了 23000。这个价格,的确超过自己预期了,毕竟不是职业选手。这一瞬间,觉得自己依然是那么穷,一根球杆都买不起。

剩下的几天,依然是走亲戚,送礼,不吃饭,几天下来,也花了近 2000。于是,打开淘宝又看到了自己之前收藏的球杆。她待在收藏夹已经一年多了,不过最终还是没有下狠心买那只两千的,买了只一千的。

那些白月光啊,毕竟太多太多,想追求的太多,想得到的太多。

跟阿尔法罗密欧一样,哪有什么选择困难症,还不是他妈的因为穷!

年复一年

2025年2月2日 23:25
年前看到 oba.by 的域名快过期了,然而等要续费的时候才发现,只允许到期前 56 天续费,等到续费的时候又发现每次续费只能续一年,这个应该不是趣域的限制。

除此之外,回到家自然是另外一通买买买。主要还是吃的,另外就是一些送礼的礼品,上次回家开的粉皮,后备箱实在是太小了,这次果断换大白。虽然感觉东西不多,然而收拾完之后,后备箱又是满满的一车。
最后几天,超市的人也多了起来,县城的两个大超市,连续转了两家都没找到停车位,最后只能停到路边。
3j 的车厘子超市 159 元 5 斤,虽然比自己从网上买的贵一些,但是味道却好了不止一点点。
28 回到老家之后,才从镇上的烟花售卖点买了一些烟花,感觉每年的种类都差不多,然而今年似乎种类更少了。下午去镇上又买了点东西,又走了好多地方去买了一对灯笼,28 块钱,比去年的更大了一点,之前几年买的都是 80cm 的,今年买了两个一米的。不过好处是,灯笼里的灯泡塞进去真的不用那么费力气了。
割对联方向错了,横批给从中间分开了,于是,有了喜气满门。
_cuva

老家的年味更浓烈一些,每天晚上都是噼噼啪啪的鞭炮声,从白天到黑夜,永不停歇。总是传来阵阵的声响。
除夕夜里,手机比往常也安静了很多,而至于拜年短信,今年基本没法,主要是不知道该发给谁,在几个内部群里象征性的发了几百块钱的红包。母亲这两年参与的事情也越来越少,今年水饺是自己和二姐以及两个孩子一起包的。
过年,拜年的亲戚也一样,越来越少了,去年还有五家,今年只剩下三家了。整个村子,所谓的亲戚也越来越少了,能走动的也越来越少。跟二姐一起出去拜年的路上遇到几个同学,聊了半天了其实我都没想起来他是谁,直到最后分别也依然没想明白,后来从假的微信推测名字,才想起来他的全名,而至于另外一个,聊了半天直到回家才知道是谁。毕竟,十几年不见,难道自己没变化吗?为什么他们能认出自己,但是自己却认不出他们?
买回来之后,就开始每天陆陆续续放一些。节后大姐也带回来一些,其中有一个叫做飞天水母的小玩具,这个东西放起来感觉蛮有意思的,然而,恐怖之处也在这里,一旦飞起来就完全不受控制了。到处乱飞,初二那天放了几个,三姨家的妹夫出去溜达的时候,发现西面树林里着火了,应该是水母到处乱飞,飞到了那个地方,没有烧完的火药引燃了地上的枯叶,最后整个林子都要烧起来的样子。
右侧空地没有树叶的地方是起火的地方
可能的火源,谨慎放水母烟花
一家人开始用各种工具运水灭火,好在发现的及时,人也多,用了不到十分钟终于扑灭了。自然,边上的几辆车也幸免于难。提着水桶回家的时候才发现原来的车上的前挡风玻璃感觉像重新贴膜了,留出了一块三角区域。然而,并不是重新贴膜,在老家审车的时候,检测站给割掉了一块,于是就变得贼丑。十年都不曾出问题的车模,因为一次审车被割成了这个丑样子,比熊孩子还熊,当然,熊孩子还有更熊的。让我不得不想到了一个鞭炮炸翻了数量车的熊孩子。
_cuva
而至于熊孩子,似乎村里更多一些。三姐家的大外甥,在车屁股上贴了一个苹果。看起来很真的样子,自己来来回回走了几趟,想把他的苹果撸下来,对象也说想给拿下来。但是毕竟是粘在上面还蛮结实的,也就是说说而已。年初二晚上回县城之后,他在群里发了个消息说苹果阵亡了。而至于是谁干的,也似乎有了目标。第一次见识到家里的熊孩子还是刚买车的时候,小六子停在门口,下午去开车的时候发现车身上多了一条划痕,从车头贯穿到车尾,完全穿透了车漆,露出了底下的白色。自此之后再也不敢把车停门口了。你永远也无法预料那些熊孩子能干出什么事情来。

除了在老家呆的几天,剩下的就是走亲戚,现在走亲戚也简单了很多,买上东西带上,去几家带几份,到了把东西放下,坐在一起聊聊天,喝点水,大约半个多小时结束后去下一家。每年仅需要两天时间就可以把父母这边的亲戚都走完,当然除了那些断绝关系不上门的。而对象的姥爷去年也去世,今年年前给带了点东西,年后自然也就不去了,省了一部分功夫。
自然,年后也有很多人到老家探亲。不过,每年依然是固定的那么几家,一年年的似乎没什么改变,有似乎变了很多。看似循着时间的踪迹就这么一天天的过着,然而,事实确实每个人每年都在改变着,沉默着。三舅家的表弟去世之后,就剩下两个老人。不过他们似乎也没那么悲伤,一年年的重复着。唯一的孙女也没留在身边,让儿媳妇带走了。于是,就剩下这么两个老人,母亲的兄弟,二舅和三舅在某些方面其实并不是特别让人理解,做事感觉也不是很符合常理,总是能有些匪夷所思的想法,做法。临走的时候,三舅说,“给调下万年历吧,已经快了十几分钟了。上次也是你给调的”。这时候,我才看到墙上的万年历的钟表已经快了十五分钟,而自己上次调表已经忘了什么时候了,两年前,亦或者三年前?家里的孩子去时候,甚至连钟表都调不了。恍惚间,感觉有那么一点点的悲哀,或者心疼。只是,他们自己或许从来不觉得。
二舅家的表弟也离婚了,据说是去年的事情。而事情从母亲那里自然也得不到全貌,现在她的记忆力依然成了问题,很多事情连转述都转述不清楚。过年几天,一直不断的重复一个话题就是,逮着谁问谁,自己是不是 chao 了(傻了的意思,所谓的潮吧就是傻子的意思)中午在昨天下午,她有问宝子:“你觉得你奶奶是不是 chao 了”,我实在忍不了了,跟她吵了几句,“你总说过年别说不吉利的,怎么你就能天天说自己 chao 了?”我质问。
“你觉得这句话不好?”
“对,不好,很不好。大家都不喜欢听这句话”
我说完,她从沙发站起来,走了出去。
随着时间慢慢流逝,她的记忆力开始衰退,脾气变得越来越暴躁,越来越差。我不太喜欢跟她吵架,她想干嘛就干嘛。然而,有的时候真的忍不住。现在坐在一起吃饭,聊天,她讲的都是她年轻的时候的事情,而至于自己的孩子或者最近十年,二十年的生活,似乎在她的记忆力已经缺失了,没有任何的回忆,也没有任何的话题。对所有的事情都变得漠不关心。三姨家的闺女去了上海教书,她知道这件事情之后。所谓的大城市又在她的心里成了念想,说想去大城市。其实,我是该跟她出去走走的,然而,真的挺犯愁的。跟老人出去真的好累,好累,关键是也没那么多的时间,在这一点上自己的确是不称职的子女。
昨晚,把剩下的两支加特林放了,为了点其他的烟花,在地上点了一堆火。用火堆点的确方便了些,都放完了,自己待在外面看着火堆发呆。
母亲从屋里走了出来,打开了一个红色的方便袋,跟自己说,我这里有两千块钱,你拿去花吧。这一瞬间,自己竟然不知道该说什么。
之前因为她花钱买各种乱七八糟的药,去年一年其实并没有给他多少钱,加起来也就四千来块钱,至于她花的钱,主要是之前卖树得来的钱,一万六千块钱,到现在其实我也不知道还剩多少。
“嗐,你留着花吧,我也不缺你这两千块钱”边说,边帮她把钱装了回去。每年回家的时间毕竟还是有限,之所以不想回去,主要还是住处的问题,原来的房间被二姐家的孩子占了,而后来新装的那间,现在又成了储藏室。每次回家,感觉甚至都不如住酒店。这几年,姐妹们能聚在一起的时间变得越来越少了。
每年的生活都变得的越来越一致,而明天,就要回青岛了,一年真的就结束了。而至于下次回老家,可能又是几个月之后。

生活在这一刻,似乎又开始延续。翻看二姐家孩子语文书的时候,发现《画杨桃》,真的有杨桃了。
我也想吃杨桃了。

小年 — 这真的就要过年了?

2025年1月22日 16:07

终于新年的脚步还是越来越近了,眨眼间已经小年了。然而,今年青岛的禁放令貌似执行的更加严格了,晚上基本听不到太多的鞭炮声,偶尔有那么灵性点点,从遥远的地方传来。

其实,现在已经没有多少心思在工作上,主要是也确实没什么太大的干劲。年底的工资系数依然不高,甚至比去年还低了一些。而至于职位,同样也是一年更比一年低,自然各种评选,奖项也就没自己什么事了。所以,现在就成了一条咸鱼。也自然就变成了小透明,不主动揽事,也不主动承担,有事情就干,没事情就不干,有的时候觉得胸无大志似乎有些颓废,有的时候又觉得,人生不过如此,并且在一些特定的环境下也难有什么作为。

咸鱼也罢,小透明也罢,毕竟就那点能力,又何苦为难自己?就酱紫,也不错。

一天天过去,似乎还有很多事情要做,又有很多事情没做。宝子送回老家之后,晚上的时间自然也多了,趁这几天看完了《鱿鱼游戏 2》。看了下豆瓣的评分,比第一部要低。其实个人觉得还好,主角白莲花也罢,理想主义也罢,换位思考,如果我在这个游戏里拿到了 456 亿韩元,就该彻底去浪了,定然不会再次以身犯险。嗐,这自私的小想法。以下内容部分透剧,ctrl+a 查看:不过第二部加了个 lgbt的小姐姐,个人还是蛮喜欢这个小姐姐的,枪法精准,还有能力,当然,也是成功走到了第二部的结束。不过这第二部结局明显草率了一些,感觉像拍了一半就着急上映了,那个警察的搜索小分队还在海上飘着,也没交代后续。显然,第三部还有更多的戏份要给他们。

从周一计划洗车,到了周三,总算是安排上了,对象去给大白洗,而粉皮虽然过年可能不开,但是,不洗一下总觉得过意不去,毕竟跑了一趟长途真的有点太脏了。

 

给四儿子店的销售发了个消息,被告知洗车的已经放假啦,他给洗,瞬间给感动的不行:

不得不说捷豹路虎的优惠力度依然让人心动:

距离上次洗车也一个多月了,这后备箱的泥土都能飘起来的感觉。

不过洗车倒是也算方便,开过去,机器冲洗一遍,等出来自己擦一下就行了。都这时候了也自然就没那么多讲究了。不过由于没有打泡沫,也仅仅是洗掉了表面的灰尘。洗完给对象发消息,俱乐部洗车的人一堆:

快过年了,洗车价格也上去了,轿车 50,suv70,如果没有会员卡的话,大白洗一次得 70 块钱。

而在回家之前,还得去一趟大润发,采购一些东西。过年那几天老家到了最冷的时候了,还得准备几条厚点的裤子,不然到时候可能就冻傻了。现在温度 10 度,等过年那几天就成了-10 度了,这么看来,也的确比较难熬,最好不要下雪,不然路上交通也是个问题。

这一年要结束了,想着看下 12123 上有没有违章,结果看到一个安全驾驶记录申请,申请完了一看,瞬间不淡定了:

交通违法 6 起,妥妥的违法犯罪分子。

还是翻翻朋友圈吧,看看大家都在干嘛。看到 2 神发的朋友圈,哎,这个世界上果然看到的也不一定是真的。😂

嗯,还是老老实实的减肥吧,最近体重又不往下掉了,讨厌啊。不能兴风作浪,那就好好的做好一条咸鱼吧。

最后,祝大家小年快乐啊。

搬家

2025年1月20日 14:46

大上周,宝子考完试了,上周在家待了一周。周二去给宝子开完家长会,宝子的事情就算是完结了。正好,宝子的姥姥也嚷嚷着要回老家,说回去太晚了,东西都准备不好什么的。当然,这个就是个借口,其实她就是想回家住段时间而已。

周二去给宝子开家长会,这次家长会的时间不长,一共开了不到半个小时,也没说什么太多的东西,还是针对孩子的学习,各科老师大概讲了讲,另外就是给看了下考试的试卷,这次考试英语错了一个题,动词的时态问题,对于二年级的宝子来说的确有些难度,dose …… watch tv on sunday,宝子选了个 watches。另外一个就是语文有个描述题,写了个壮丽的大树,这个脑洞的确是有点我的风格了。

有那么一瞬间觉得大树很壮丽似乎也没什么毛病,数学比较完美,没有错题。

一切结束之后就是把他们送回去了,对象问开那个车,我去宝子姥姥的房间看了下只有两袋子东西,感觉粉皮应该也能装得下。主要是打包上面,夏天露营的帐篷什么的都还在后备箱里,实在不想拿出来在到处搬了。

然而,等周六早上往回走的时候发现,原来两包东西一夜之间膨胀了,变成了 6 包,每包差不错有 24 寸的行李箱那么大。这一下再瞬间就让人头疼了,还有两床小被子,还有冰箱里提前冻好的肉馅,用她的说法是老家的猪肉没不到细分的里脊,只有前后肘什么的,带肥肉。但是,那点肥肉,真的不叫事啊,毕竟就那么一丢丢。不过还是得尊重姥姥的选择啊,来回折腾两三趟才把东西搬到楼下,往后背箱里塞的时候,发现也是个问题。

装上宝子小姨买的三箱啤酒,再把这些东西塞进去,终于,最后还是剩下宝子的轮滑鞋,还有两床小被子,在加上随身携带的几个背包。只能放到座椅上或者脚下,不过这样整体的乘坐就变得没那么舒服了,然而,现在要换车也不显示了,因为另外一辆车在公司停车场,也不想再去开了,就酱紫吧。好在路程不是很远,下次还是换大白吧,这个后备箱容积,真的哭死。

早上八点来钟上了高速,路上的车辆已经很多了。透过窗户能看到,大家都是大包小包的行李,有的后排座椅也塞的满满的。大家看来都一样,都在搬家。

到家之后,原本封闭的小区,没有车位不让进,现在一般节假日或者周末倒是也没那么严格,基本都能给放进去。不过现在比较郁闷的一点就是不知道那些车位是空的,每次回去都得找不同的车位往上停,运气好的时候还可以,运气不好就得频繁的去挪车。

至此也就明白了为什么有人把车听到了靠墙的位置,这地方好处是不用老跑下去挪车,照猫画虎,我也给听到了边上。

毕竟大晚上九点多去挪车也的确是比较蛋疼。

第二天一早去超时给宝子买字帖,虽然路上的人很多,但是超市的人并不多,结账甚至都不需要排队。在超市看到了一个好玩的东西,语文、数学、英语。

关键是人家还有个名字叫做休闲食品,问题是,小朋友看到这个东西,还休闲的出来吗?😂

django TimescaleDB

2025年1月17日 15:34

平时项目使用的都是 mysql 数据库,少数时候会用到 mariadb,而至于时序数据库那基本没用过。而现在,对于一些监控数值需要更高的写入效率,查询效率,所以想着迁移到时序数据库上。

搜了一下,推荐的基本都是 timescadb:

TimescaleDB 是一个基于 PostgreSQL 的开源时序数据库扩展。它将 PostgreSQL 的强大功能与时序数据的优化存储和查询相结合,特别适合处理时间序列数据(如传感器数据、监控数据、金融数据等)。TimescaleDB 提供了高性能的时序数据存储、压缩、自动分区(hypertables)和高效的查询功能。

以下是关于 TimescaleDB 的详细介绍,以及如何在 Django 项目中集成和使用它。


TimescaleDB 的核心特性

  1. 基于 PostgreSQL
    • TimescaleDB 是 PostgreSQL 的扩展,因此你可以使用 PostgreSQL 的所有功能(如 ACID 事务、SQL 语法、JSONB 支持等)。
    • 兼容现有的 PostgreSQL 工具和生态系统。
  2. Hypertables
    • TimescaleDB 引入了 hypertables,这是一种自动分区的表结构,专门为时序数据优化。
    • 数据按时间维度自动分区,支持高效的数据插入和查询。
  3. 时间序列优化
    • 支持高效的时间范围查询、降采样(downsampling)、数据压缩和连续聚合(continuous aggregates)。
    • 提供专门的时序函数和窗口函数。
  4. 可扩展性
    • 支持分布式架构(TimescaleDB 2.0+),可以水平扩展以处理大规模数据。
  5. 开源
    • TimescaleDB 是开源的,社区版免费使用,企业版提供额外的高级功能。

而这个东西也提供了一个 django 的粗件:https://pypi.com.cn/project/django-timescaledb/

网上搜一下相关的文章都简单的 1b,但是如果简单的按照文章中的内容操作,很可能直接就卡在数据库连接上了。

建议在开始配置之前不要安装任何的 postgresql 数据库以及客户端,直接参考官方文档:https://docs.timescale.com/self-hosted/latest/install/installation-macos/#install-and-configure-timescaledb-on-postgresql

在开发电脑以及服务器上都要安装相关的postgresql timescaledb插件。否则就会提示找不到相关的组件。

postgres=# CREATE EXTENSION IF NOT EXISTS timescaledb;
ERROR:  could not open extension control file "/usr/share/postgresql/12/extension/timescaledb.control": No such file or directory

同样在开发电脑上也要安装相关的组件,如果安装了其他版本的postgresql删除掉旧版本,或者直接全新安装。

执行下面的命令创建用户以及数据库:

sudo -i -u postgres
psql
CREATE USER data_db WITH PASSWORD '1qaz@WSX';
CREATE DATABASE data_db OWNER data_db;

修改配置文件,让 data_db 用于允许远程登录:

vim /etc/postgresql/12/main/pg_hba.conf
host    data_db             data_db             0.0.0.0/0   md5
root@2gcc5hbhemlhjejc:~# sudo service postgresql restart

创建扩展,并且查看加载情况:

postgres=# CREATE EXTENSION IF NOT EXISTS timescaledb;
CREATE EXTENSION
postgres=# \dx
                                                List of installed extensions
    Name     | Version |   Schema   |                                      Description                                      
-------------+---------+------------+---------------------------------------------------------------------------------------
 plpgsql     | 1.0     | pg_catalog | PL/pgSQL procedural language
 timescaledb | 2.17.2  | public     | Enables scalable inserts and complex queries for time-series data (Community Edition)
(2 rows)

如果看到timescaledb 就表示成功了:

安装相关的组件之后,如果要在 django 中使用,还需要安装psycopg2,不建议安装psycopg2-binary因为安装这个东西,在 mac 下同样会爆上面的错误。psycopg2  需要编译安装,安装过程可能会提示找不到 ssl 库,通过brew info openssl 定位 ssl 库位置。

brew info openssl
==> openssl@3: stable 3.4.0 (bottled)
Cryptography and SSL/TLS Toolkit
https://openssl-library.org
Installed
/opt/homebrew/Cellar/openssl@3/3.4.0 (7,236 files, 33.4MB) *
  Poured from bottle using the formulae.brew.sh API on 2024-11-22 at 09:36:14
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/o/openssl@3.rb
License: Apache-2.0
==> Dependencies
Required: ca-certificates ✔
==> Caveats
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
  /opt/homebrew/etc/openssl@3/certs

and run
  /opt/homebrew/opt/openssl@3/bin/c_rehash
==> Analytics
install: 318,996 (30 days), 1,205,908 (90 days), 4,903,860 (365 days)
install-on-request: 39,060 (30 days), 168,471 (90 days), 637,515 (365 days)
build-error: 6,326 (30 days)

修改.bash_prfile文件添加上述位置:

export LDFLAGS="-L/opt/homebrew/Cellar/openssl@3/3.4.0/lib"
export CPPFLAGS="-I/opt/homebrew/Cellar/openssl@3/3.4.0/include"

再次执行source ~/.bash_profile & pip install psycopg2即可。

剩下的就可以按照https://pypi.com.cn/project/django-timescaledb/里面的步骤实施了。

相关示例工程:https://gitcode.com/gh_mirrors/dj/django-timescaledb

注意连接引擎为timescale.db.backends.postgresql:

'ENGINE': 'timescale.db.backends.postgresql',
        'NAME': 'data_db',
        'USER': 'data_db',
        'PASSWORD': '1qaz@WSX',
        'HOST': '113.125.1.1',
        'PORT': '5432',
    },

 

 

不再可用

2025年1月16日 17:32

自从电视柜旁边加了另外一个柜子之后,投影仪就用的更少了,主要是下面的柜子阻挡了幕布下降的空间。

做完想着把投影仪打开,看《毒液》然而,打开语音助理的时候,提示 Home ai 不再可用。

其实想来是自签名的证书过期了,虽然一年用不了几次,但是每年都要重新签一下,不然就会很尴尬,直接运行不了了。并且,这个东西也仅仅是自己用,也没必要上架 appstore。

为了打包,换了新的 mac mini 之后,电脑上也没代码,重新从 bitbucket 拉代码。编译,然而,项目太久了,编译的时候又爆了个错误:

Library 'iconv2.4.0' not found

问题在于这个东西已经没了,需要导入新的 library:

删除掉旧的iconv2.4.0.tbd,添加iconv.tbd重新编译就可以了。当然,还有别的解决方案,参考https://blog.csdn.net/liosen/article/details/133274506

之前也想着有点时间,使用 uniapp 重构这个语音助理,然而,却一拖再拖,实在也没什么动力去干这件事情。主要是现在的也能用,于是就这么将就着。

等哪天,真的跑不动,或者出问题再重构吧。

毕竟,事情很多,也真的很懒。

铁处女

2025年1月9日 10:38

这几天被一个小男明星在泰国被卖了,女友一番高级操作给救出来的新闻刷屏了。不得不说,这个女生的确是厉害,如果没有这一番操作,这个小明星最后剩下的也就是在某人身体上活着的的一部分器官了,毕竟,在那些真的不是法治社会的地方,人还不如普通的商品。

人啊,总是低估了别人的恶,也低估了这个世界上的恶。标题的这个铁处女其实是一个刑具,一个人形的铁制容器,里面不满了几十公分的钢针,在闭合的时候这些钢针会一起插入受刑者的身体。百度百科还写着有人怀疑这个东西是否真的存在过,其实,完全没必要怀疑,人性这个东西只要有了足够多的权利,能支配人的生死,虐杀不得不说是能带来感官刺激和精神刺激的良好手段。之前买过一本世界酷刑简史,统揽全篇,里面的各种刑法中外区别不大,不过针对男人和女人生理构造不同,即使是相同的刑具也会有不同的行刑方式。以望天为例,弄一根木桩竖在地面上,把让受刑之人放到这根柱子上,女人会从阴道插入,男人会从肛门插入,身体在重力的作用下不断下降,那根柱子不断的向体内插入,直到最后贯穿而死。

为了让人死的更慢一些,木桩顶部不会削尖,下降的越缓慢,死的时间越长久。刑罚,有的时候不是为了罚,而是纯粹为了虐杀的快感。而现在缅甸的水牢之类的,也已经有几千年的历史,虽久远,却简单实用。

所有没有任何门槛,不需要面试,觉得你就是天命人的招聘,招工,都是为了把你当牲口卖掉,没有例外。这不得不让我想到了十几年前被二姐的朋友给忽悠到湖北,进了传销窝点的历史。国人在戕害自己人这方面的确无与伦比,以下文章写于十几年前,鉴于可能太多敏感词,直接转成图片了。

不管别人说什么,保持自己的思考判断,尤其是在自己境遇不好的时候,君子不立危墙之下,至于谁想去泰国,谁爱去谁去吧。

希望大家都平安喜乐。

 

流阳合

2025年1月7日 15:32

COVID-19 疫情夺走了逾 2000 万人的生命,付出了 16 万亿美元的代价,导致了 16 亿儿童失学,1.3 亿人因此陷入贫困。而疫情并没有完全结束。

2024 年 10 月的数据显示,每周至少有 1000 人死于 COVID-19,其中 75% 发生在美国,这些数据来自于 34 个仍然向 WHO 报告死亡人数的国家。在上个月举行的预防未来疫情会议上,WHO 流行病学家 Maria Van Kerkhove 例举了这些数据,称现在的世界没人愿意谈论 COVID-19,好像疫情从未发生过。与会者担心世界未从这场疫情中吸取任何教训。更令与会者感到忧虑的是,很多国家对疫情预防研究持敌对态度。会议由 Cold Spring Harbor Asia 举办,17 个国家的 140 名研究人员和卫生官员出席,其中有 20 名中国科学家,但最知名的两位没有参加,包括组织者之一的石正丽,她以视频方式发表了演讲;另一位是前中国疾控中心主任高福。

https://www.science.org/content/article/covid-5-years-later-learning-pandemic-many-are-forgetting

时间过去这么久之后,现在偶尔的感冒,竟然也不好区分到底是甲流乙流或者是阳了。周日晚上感觉嗓子有些难受,怕可能是感冒,睡觉之前冲了两包三九喝了。通常情况,这两包三九能提供很好的助眠作用,然而夜里情况愈发严重了,开始全身酸痛。怎么都找不到一个合适的姿势,等到周一早上,状况愈发严重了。夜里身体所有的感觉都没了,整个身体感觉像变成了一个球,感觉不到四肢,也感觉不到任何的器官的存在,却又无比的不舒服,甚至在半梦半醒间回放了一整部的《雍正王朝》。量了下体温 39.8,从药箱里找了下退烧药,发现还有泰诺,怕是阳了又吃了两粒奥司他韦。然而,一上午下来状况没有任何的改观,依然是害冷,期间量体温,基本还在 38 度以上。

躺在床上也不想动,睡得迷迷糊糊的接到对象的电话问中午怎么吃饭。说煮包泡面吧,也不大想吃。

等会儿老妈又打电话问,同样的话又回复了一遍。

连续两次泰诺吃下去效果并不明显,但是药箱里也找不到布洛芬了,只好从买团上现买,同时买了头孢克圬。晚上开始换药吃,不过第二天老妈要回老家给姥爷上五七坟,本来想着是自己开车送她,现在自己开不了,更抑郁的是对象周日带宝子去公园玩的时候不知道让什么东西砸到了小腿,他现在走路也不方便了。于是,整个家庭就成了老弱病残组合了。

晚上宝子放学之后直接让她去了小姨家,等着第二天看怎么送老妈回去上坟。换药之后,虽然效果有一些,但是感觉还不是很行的样子,现在从全身疼变成了头疼+眼珠子疼,感觉思维能力也受限了。好在对象小腿受伤虽然走路不大行,但是开车问题还不大。只能让她跟着一起回去了,唯一的坏处就是行动不便,不能到处走。

去把车开到楼下,把东西搬上去,等他们走了之后,自己回来简单吃了点东西吃完药,继续躺着。迷迷糊糊又睡了几觉,醒来发现八点半,状态似乎好了很多,如果去公司耗着似乎也可以,毕竟这年后的第一次年假竟然用来对抗甲流了,的确有些让人抑郁。重新量了下体温,终于到了 37 以下了。

不过再后来发现,表弟也被传染了。

而这一切都是因为周六下午一块去打了会儿台球,看来流感高发季还是老老实实在家呆着吧。

django 直接运行目录下py 文件

2025年1月7日 10:16

为了处理数据,直接写了一个文件用来处理解析数据。然而比较诡异的一点是,使用 pycharm 可以直接运行这个文件,不会报错。但是,如果用命令运行就直接报错了。

上面是 pycharm 的运行效果,下面是直接命令运行的效果。

(venv) PS E:\Pycharm_Projects\powersystem> E:\Pycharm_Projects\powersystem\venv\Scripts\python.exe E:\Pycharm_Projects\powersystem\application\data_process_test.py 
Traceback (most recent call last):
  File "E:\Pycharm_Projects\powersystem\application\data_process_test.py", line 17, in <module>
    django.setup()
  File "E:\Pycharm_Projects\powersystem\venv\lib\site-packages\django\__init__.py", line 19, in setup
    configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
  File "E:\Pycharm_Projects\powersystem\venv\lib\site-packages\django\conf\__init__.py", line 82, in __getattr__
    self._setup(name)
  File "E:\Pycharm_Projects\powersystem\venv\lib\site-packages\django\conf\__init__.py", line 69, in _setup
    self._wrapped = Settings(settings_module)
  File "E:\Pycharm_Projects\powersystem\venv\lib\site-packages\django\conf\__init__.py", line 170, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "G:\Python3.10.6\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 992, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1004, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'application'

提示的错误信息是找不到 application,但是这个文件是作为 django 的一部分存在的,按理也不需要去设置什么东西。之前的时候不能运行也就算了,但是现在有台服务器在内网,无法链接内网的的数据库进行数据处理,这就比较麻烦。

不过既然 pycharm 能运行,那肯定是有些东西不一样,猜测是 pycharm 将当前的目录加入 lib 目录了。添加下面的代码重新运行。

import os,sys

if __name__ == '__main__':
    # 获取当前脚本所在目录的绝对路径
    current_directory = os.path.abspath(os.path.dirname(__file__))

    # 将当前目录添加到sys.path
    sys.path.append("E:/Pycharm_Projects/powersystem/")
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "application.settings")
    import django

    django.setup()
    label =get_device_label(msg['devvar'])
    new_msg = rebuild_msg(msg, label)
    print(new_msg)

现在一切就 ok 了。

其他的运行脚本方式:

https://django-extensions-zh.readthedocs.io/zh-cn/latest/runscript.html

https://www.jb51.net/article/236739.htm

速度与激情 — 卡丁车初体验

2025年1月2日 09:51

卡丁车这个东西,在现实中见到的场次并不多。之前,在商场里见过几次,一直蛮想尝试一下的,却始终没有什么机会。前几年,在每天都要进行核酸检测的时候,在常去做核酸的医院旁边开了一家卡丁车场。

某一天做完核酸之后,鬼使神差的去车场问了一下,说可能过段时间就开业了。然而,几个月之后,核酸检测停了,一切又回归来原来的样子,似乎新冠从来没有发生过。就再也没有往那边走过,生活看起来似乎也没什么太大的变化。

后来的这两年开过沙滩摩托,雪地摩托,而之前想了很久的卡丁车却始终没有什么机会。

直到上周,在世博园买年卡送了一张卡丁车的体验卡。就这样,宝子早自己一步先开上了卡丁车。几分钟结束之后,说体验还不错。

周二晚上回家之后,就嚷嚷着第二天要出去玩。想再去开车,宝子就是容易这样,开始的时候抗拒意见事情,后面喜欢上了之后就嚷嚷着要再去体验。

这时候又想到了医院附近的那家卡丁车场,也正好有双人车,99.9 元双人车七圈。算起来价格也算是合适,并不离谱。早上起床之后,第一件事情自然是要先写完作业,写了会儿之后跑出来说休息会儿。就趴在沙发上吹泡泡糖,自从会吹泡泡之后,每天有点时间就在那里吹泡泡。

车场十点开门,想着早去人能少一点。宝子又进屋写作业,但是这次都快十点了还没出来,想来是没写完。只好先去玩,回来再继续写。几分钟的路程到车场,人不多,就那么几个,有两个姐妹在挑选赛车服。在教学室看了下教学视频注意事项,没有换衣服,戴好护具直接就上场了。

车身小巧,能带来的速度体验感的确是更强烈一些。虽然场地不大,但是还是设置了发卡弯等各种弯道。不过,第一次开卡丁车对于这辆车的极限在哪里的确不好试探,好几次感觉要漂起来,一松油门也能救回来。赛道路线选择也是个问题,基本参考路上的车轮痕迹选择路线,当然这个只是可能比较好的路线,不见得对。而至于在方程式塞车中看到的,切内弯,切外线还是上路肩,并没有 一个合理的规划,只是看他们怎么跑自己想可能怎么跑。

没有助力的小车,方向竟然出奇的沉重,不用力气根本掰不过来,这也导致了自己丢了一部分时间,在发卡弯内由于力量不够,只能减速。

虽然只有七圈,但是在实际开的时候,感觉时间竟然过得很慢。双手也越来越累,开到四五圈的时候问宝子,咱们开了几圈了?她可能是没听到,或者的确有点紧张也没吱声。又开了一圈,看到车手引导,靠过去问了一下,还有一圈。所以最后一圈这个速度自然就慢了很多。

至于排行榜,自己下午看的时候发现最快的 50s。

虽然开了几圈但是对于卡丁车的极限其实并没有完全找到,应该还可以再开的极限一些。多练习几次,应该到 50+还是比较轻松的。今天早上在看的时候最快圈速已经到了 41 秒了,这速度自己肯定无法启及了。毕竟,这个20 秒的差距不是那么一点半点。

当然,也有可能是天赋型选手,毕竟努力在天赋面前,真的一文不值。罢了,不想这些了毕竟也不靠这个吃饭,玩玩而已,但是有时候那个想法真的挺要命的,玩也要玩的专业,这个排行榜,哪天我也要排到前三。不过现在看来,锻炼还是得继续。毕竟这七圈下来,两只手都有些抖,最后方向盘真的不怎么握得住了。现在看来,这七圈已经是到极限了,即使后面再继续跑也不会有设么大的突破。改日再战吧,毕竟有的是时间不是吗?

回家宝子写完作业,这新年第一天也不想在家吃饭。举家直奔万达,对象说一直想吃那个熊喵来了。有了目标自然也就好办了,省去了选择的烦恼。团购加单点,最后发现金针菇重复了,没让退掉这也成了最后没有被吃掉的菜,只能打包。回家之后睁不开眼了,大人都睡觉了,剩下宝子自己一个人玩,她白天从来不睡觉。期间睁开眼迷糊了一下,发现电视开着,也没声音。直到醒了才发现宝子开在看电视,也没开生硬,看自己醒了就把电视关了。嚷嚷着带她去山上的公园玩。

山上的公园在另外一次又修了一个游乐场,这几年政府似乎对于这种游乐场的投入还是蛮大的,很多公园或者广场都安装了大批的儿童油了设施。这里的也一样,几个月的时间就修建好了,不过开放也没什么通知,就这么悄咪咪的开放了。

临走,又跑到旁边的水坑冰面上捡冰块。

到家之后,宝子依然没尽兴,说:“该预定周末的滑雪票了”

哪吒监控 1.5.1 自定义头像

2025年1月1日 20:01

对于哪吒监控自带的授权登录,最近不知道是github问题还是什么问题,一直登录失败。醒着直接升级下监控版本,结果,效果很不错,成功升级了。

感觉是换了一个全新的版本,但是这个版本确登录不了。

多次尝试更新之后,终于默认账号登录成功了,但是,伴随而来的是另外的一个问题。所有的监控项都没了,并且首页提示websocket建立失败。查阅文档才发现,新的版本需要将websocket一块进行代理:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    # http2 on; # Nginx > 1.25.1,请注释上面两行,启用此行

    server_name dashboard.example.com; # 替换为你的域名
    ssl_certificate          /data/letsencrypt/fullchain.pem; # 域名证书路径
    ssl_certificate_key      /data/letsencrypt/key.pem;       # 域名私钥路径
    ssl_stapling on;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m; # 如果与其他配置冲突,请注释此项
    ssl_protocols TLSv1.2 TLSv1.3;

    underscores_in_headers on;
    set_real_ip_from 0.0.0.0/0; # 替换为你的 CDN 回源 IP 地址段
    real_ip_header CF-Connecting-IP; # 替换为你的 CDN 提供的私有 header,此处为 CloudFlare 默认
    # 如果你使用nginx作为最外层,把上面两行注释掉

    # grpc 相关    
    location ^~ /proto.NezhaService/ {
        grpc_set_header Host $host;
        grpc_set_header nz-realip $http_CF_Connecting_IP; # 替换为你的 CDN 提供的私有 header,此处为 CloudFlare 默认
        # grpc_set_header nz-realip $remote_addr; # 如果你使用nginx作为最外层,就把上面一行注释掉,启用此行
        grpc_read_timeout 600s;
        grpc_send_timeout 600s;
        grpc_socket_keepalive on;
        client_max_body_size 10m;
        grpc_buffer_size 4m;
        grpc_pass grpc://dashboard;
    }
    # websocket 相关
    location ~* ^/api/v1/ws/(server|terminal|file)(.*)$ {
        proxy_set_header Host $host;
        proxy_set_header nz-realip $http_cf_connecting_ip; # 替换为你的 CDN 提供的私有 header,此处为 CloudFlare 默认
        # proxy_set_header nz-realip $remote_addr; # 如果你使用nginx作为最外层,就把上面一行注释掉,启用此行
        proxy_set_header Origin https://$host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
        proxy_pass http://127.0.0.1:8008;
    }
    # web
    location / {
        proxy_set_header Host $host;
        proxy_set_header nz-realip $http_cf_connecting_ip; # 替换为你的 CDN 提供的私有 header,此处为 CloudFlare 默认
        # proxy_set_header nz-realip $remote_addr; # 如果你使用nginx作为最外层,就把上面一行注释掉,启用此行
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
        proxy_buffer_size 128k;
        proxy_buffers 4 256k;
        proxy_busy_buffers_size 256k;
        proxy_max_temp_file_size 0;
        proxy_pass http://127.0.0.1:8008;
    }
}

upstream dashboard {
    server 127.0.0.1:8008;
    keepalive 512;
}

而至于数据丢失,官网也写了:

这就很棒。只能重新添加所有服务器,添加之后感觉一切正常了,但是后台那个头像实在是无法忍受。

头像

尼玛,这苦大仇深的表情,作为小仙女坚决不能忍啊。在杜老师的聊天室,交流了一下,他也不知道怎么改。只能尝试js暴力修改src,代码如下:

var images = document.querySelectorAll('img[alt="obaby"]');
 images.forEach(function(image) {
        console.log(image);
         console.log('first inject to replace avatar!');
        image.src = "https://g.h4ck.org.cn/avatar/3a78942c4ddcda86242f20abdacee082?s=256&d=identicon&r=g";
    });

然而,将这段代码加入到系统设置的自定义代码内,会发现多数情况下都不能调用,只能通过差距js的方式进行调用,并且哪吒还有个问题,那就是对于其他域名下的js会加载失败,所以只能把js放到同一个服务器下。

后台添加配置:

此时js代码多数情况都能正常调用,为了能够加载这个js,需要修改nginx配置文件将js路径加入nginx配置文件:

location /inject/{
alias /home/wwwroot/s.h4ck.org.cn/inject/;
}

此时,顶部的头像已经修改成功了,但是下面的头像还是旧的,就很蛋疼。如果查看页面源码会发现基本都是js绘制的,本身并没有任何的内容。

 

遇事尝试使用nginx的替换功能进行内容替换,

location / {
        proxy_set_header Host $host;
        #proxy_set_header nz-realip $http_cf_connecting_ip; # 替换为你的 CDN 提供的私有 header,此处为 CloudFlare 默认
        proxy_set_header nz-realip $remote_addr; # 如果你使用nginx作为最外层,就把上面一行注释掉,启用此行
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
        proxy_buffer_size 128k;
        proxy_buffers 4 256k;
        proxy_busy_buffers_size 256k;
        proxy_max_temp_file_size 0;
        proxy_pass http://127.0.0.1:8008;
sub_filter 'https://api.dicebear.com/7.x/notionists/svg?seed=' 'https://g.h4ck.org.cn/avatar/3a78942c4ddcda86242f20abdacee082?s=256&d=identicon&r=g&name=';
sub_filter_once off;

    }

然而,这种替换方式竟然只有首次生效,不知道是不是nginx配置问题,最终还是回到了直接修改js文件的方法。

拉出app文件,这个东西是编译的的elf文件,看了下字符串长度过长,替换有些麻烦,也没趁手的elf编辑器,就很麻烦。

转换思路,不好改二进制,那就改对应的js文件,编辑/dashboard/assets/index-CeBwNjOv.js 替换内部的https://api.dicebear.com/7.x/notionists/svg?seed=。

同时将文件头的import改为绝对路径,参考https://s.h4ck.org.cn/inject/index-obaby.js:

修改之前的内容替换代码为:

location / {
        proxy_set_header Host $host;
        #proxy_set_header nz-realip $http_cf_connecting_ip; # 替换为你的 CDN 提供的私有 header,此处为 CloudFlare 默认
        proxy_set_header nz-realip $remote_addr; # 如果你使用nginx作为最外层,就把上面一行注释掉,启用此行
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
        proxy_buffer_size 128k;
        proxy_buffers 4 256k;
        proxy_busy_buffers_size 256k;
        proxy_max_temp_file_size 0;
        proxy_pass http://127.0.0.1:8008;
sub_filter '/dashboard/assets/index-CeBwNjOv.js' '/inject/index-obaby.js';
sub_filter_once off;

    }

重启nginx

通过下面的命令查看是否支持sub_filter ,如果不支持重新编译nginx:

否则会爆下面的错误:

此时头像就ok啦:

另外一个,就是那个命令窗口,V0版本是个全屏的,这V1弄了个小窗口,看着是真tm蛋疼:

这是纯粹为了难看(手动狗头)?

同样通过js修改页面样式:

setTimeout(function () {

if (window.location.pathname.includes('terminal')) {
        console.log("这段代码将在3秒后执行");
    var terminals = document.getElementsByClassName('xterm-screen');
    for (var i = 0; i < terminals.length; i++) {
        console.log('change screen size');
        terminals[i].setAttribute("style", "width: 941px; height: 900px;")
    }

    var divs = document.getElementsByClassName('max-w-5xl mx-auto');
    for (var i = 0; i < divs.length; i++) {
        console.log('change screen size');
        divs[i].setAttribute("style", "max-width: 100%;max-height: 100%")
    }
}
    // ... 执行其他操作
}, 500); // 3000毫秒等于3秒

在引入的js文件中使用windows.onload无法触发,直接延迟执行即可,调整后效果。

看起来顺眼多了,修改顶部图标以及favicon:

var imgElements = document.getElementsByClassName('h-7 mr-1');
for (var i = 0; i < imgElements.length; i++) {
    imgElements[i].src = 'https://image.h4ck.org.cn/support/uugai.com-1661691272754.png';
}

var images = document.querySelectorAll('img[alt="apple-touch-icon"]');
images.forEach(function (image) {
    console.log(image);
    console.log('change logo!');
    image.src = "https://image.h4ck.org.cn/support/uugai.com-1661691272754.png";
});

var faviconurl = "https://image.h4ck.org.cn/support/uugai.com-1661691272754.png"; /* 替换为自己的 Logo 图片链接 */
var link = document.querySelector("link[rel*='icon']") || document.createElement('link');
link.type = 'image/png';
link.rel = 'shortcut icon';
link.href = faviconurl;
document.getElementsByTagName('head')[0].appendChild(link);

最终效果:

看起来好多了,最终js文件:

https://s.h4ck.org.cn/inject/index-obaby.js

https://s.h4ck.org.cn/inject/avatar.js

影子

2024年12月31日 10:25

年初的时候貌似也没立什么 flag,所以也没什么必要去回顾这些东西了。一年年不过浑浑噩噩的混着而已,也就酱紫了。

然而,没当看到微博或者各种圈子里的新闻,看着别人的成绩,再看看自己的,总是自惭形秽。甚至很多时候对于博主说的东西看都看不懂,对于一些东西的解读自己更是毫无头绪,就那么傻傻的看着,看不懂,听不懂,也不知道该怎么做。

没当这个时候总是感觉智商的差距巨大,然而太多的时候又会有那种我上我也行的迷之自信。之前看韩寒写过的一篇文章,不要用自己的爱好挑战别人的职业技能。在一群业余选手里面,技术稍微好那么一点点就觉得自己上自己也行,只有当实际操作的时候才发现,自己不过是个战五渣,不是左右的工作都适合是自己,也不是左右的爱好都能坚持。

看着宝子灵活的小手在钢琴上跳跃,总觉得按照自己打字的水平,怎么也能很熟练。然而,实际情况是哪怕自己键盘打字速度到 300,双手练习依然过不了第八关。钢琴需要多个键同时按下,而键盘,多数时候不需要。

看着特鲁姆普、火箭把白球控制的炉火纯青,沿着导播给出的路线,走位能毫厘不差。看着他们通过加塞控制木球走出各种路线,等到自己操作的时候却发现要么球进了走位不够,要么走位够了,球没进。站在这些巨人的影子下,忽然发现自己根本没有机会。毕竟自己没有那个理论水平,更没有投入那么多的时间。

之前那些黑客们,上学的时候就买各种杂志,看他们写的各种文章。学习他们的技术,等自己刚踏入山门,觉得有些能力之后,他们却已经站在了喜马拉雅的顶上。而这一段距离,就成了不可逾越的障碍。来自各行各业的人,看着一年一度的拉斯维加斯的黑客大会,里面的那些所谓的前沿技术,能看懂,却无法实践。毕竟太多的实验设备自己没有,终于等自己有钱攒够能用的设备的时候,发现他们已经到了另外一个阵地,就这样连影子都跟不上。哪怕把鞋跑掉了也依然跟不上前行的队伍。这种挫败感,几乎伴随了整个人生历程,无所成,无所就。

有时候,自己却又感觉有的人真的不大适合程序员这个行业,写的代码,一言难尽,之前嘴硬的哥哥《哥哥,不会写文档就 tm 别写,老老实实写代码行吗?》,到最近的mqtt 数据格式定义,竟然有那么一瞬间让我觉得,程序员这个行业竟然是需要那么一点点智商的。

一瞬间,我甚至不知道这是不是开发给软件故意留的 bug,还是为了彰显自己的能力。物联设备本来就容易出现各种问题,这还把 key 做成可变的,的确是出乎意料,这么多年,从来没想过还能见到这种数据传输方式。

程序员这个东西的确不适合所有人,更神奇的是,这么神奇的接口竟然能作为产品发布,还能上线,还有人用,这世界,的确是个草台班子。

能跑一天是一天,哪天跑不动了就直接死了吧。

人生,在这一刻也充满了讽刺,有时候,技术真的没那么重要,需要的不过是个机会而已,哪怕自己技术太烂,有人用,也能给用户呈现一坨狗屎,让用户品尝,这又何尝不是人生的成功。

不过,这些人自然也不会觉得自己技术有问题,有问题的肯定是别人。一些人从来也不会被这些问题困扰,毕竟在他们看来已经做到完美了,咋还那么多屁事?

不同的狗在遇到同样不可思议的事情的时候,表现是不一样的,聪明的狗会表现出恐惧,而二哈不单不害怕,还会上去咬一口。这就是智商的差距吧,完全不会被恐惧的事情吓到,反而还会奋力反击,这么看来,当一只二哈也挺不错的。

既然无法摆脱那些高大的影子,那么就做一只快乐的小二逼吧。唉。

你的名字

2024年12月30日 10:27

24 年真的已经到了终点,各大 app 都在推送年度报告,运动、消费、音乐等等,所有的年度报告在那么一瞬间蜂拥而知。如果是以前,可能会仔细的看看里面的内容,然而,今年看了几个,满满的都是程式化的东西。没有什么吸引人的东西,也没什么让人分享的欲望。

周六依然是加班,虽然没有太多的事情,但是这种例行公事确实不能或缺的。到了之后,也没多少人,处理了下那点遗留的工作,给老太太打了个电话。她每次电话总是会问自己在干嘛,告诉她在加班之后,会继续再问不是星期六吗,为什么还在上班。这种交流每次都免不了来一次,剩下的就是问孩子在干嘛,说一下自己的那些事情。不多不少,如机械般精准。

在挂断之前,她忽然说了一句:“我心里有点难受,你的那个小学同学海营死了。”

海营,是他的小名。一个学习不怎么好,还非常调皮的孩子。一个村子的孩子,了解的总是多一些,然而,当我听到这个小名的时候,一时间进不然记不起来他的大名是什么了。

上小学,自己当了好几年的班长,对于办理的熊孩子,老师也有自己的管理办法。在自习课有孩子捣乱实在管不了的时候,老师给我安排了两个打手,对于那种不听话的孩子,可以让打手给架出到教室外,让他在教室外罚站。

村里的孩子越来越少,等自己上学的时候,自己的班里就剩下 19 个孩子。二三年级的时候,从外地转来了一个孩子,一个小男孩,还有个弟弟,同样的调皮。为了让孩子快速融入,老师安排自己跟他同桌。事实证明,老师多虑了,孩子融入的太快了,让人有些措手不及。熟悉了之后,他就开始在桌子上用小刀挖坑,这件事情自己也会干。然后在里面弄上些细土,倒进去一点点水,然后用铅笔,搅一搅。最后就开始跟自己推销他的豆浆,你要不要喝豆浆啊?当然,这时候肯定是会揍他一顿,然后让自己的两个打手把他架出去。

在后来的某一天,西村的后河滩烧起了大火,熊熊火光映红了半边天,我住在东村最东头都能看到。不过离得太远了,晚上出去也多有不便,毕竟不知道发生了什么事情。

第二天,那个转校来的孩子,没来上学,后来几天也没出现过。那些课本就那么在桌子上放着,几天都没动。后来某一天,老师说,转校来的那个孩子又走了,他们家发生了火灾。

后来,断断续续的从大人的口中得到了一些事情,他们家是养鸡的,弄了两个大棚,棚子上面都是稻草,高粱杆搭建的,最外层是油纸。那天晚上,他们家里的电线短路了,起了火星,女主人情急之下泼了一盆子水上去,结果导致漏电更厉害了,从房顶开始烧了起来。这稻草盖起的棚子,在狂风之下,迅速蔓延。几千只鸡瞬间死的死亡的亡,然而,一家人在救火的过程中,不知道什么原因竟然遗忘了自己的小女儿,结果,小女儿跟着这些鸡一起烧死了。就这样,剩下的一家人又离开了这个地方,而现在,我甚至对于他的名字没有任何印象,所剩的,也仅是那些模糊的片段。

后来很长时间自己在想海营的大名是什么,终于,最后在那么一丝丝的推理之下,拼凑起来一个名字。想着他跟自己是同辈,都是京字辈,自己的名字没有把辈分写到名字里,通常,这个大名应该是* 京 * ,而小名往往又会包含大名的某个字,就这样拼凑起来了这个名字京海。此时才发现,这个名字显示的既熟悉又陌生。

初中毕业之后,那些小学,初中的同学早就断了联系。偶尔能听到一点点消息,也是回家的时候,老太太说谁谁谁,又干了 什么,又发生了什么事情。

小时候喜欢在午休的时候掀女同学裙子的这个孩子,上完初中就开始外出打工了。自己上大学的时候,知道他已经结婚了,并且生了孩子。等大学毕业的时候,说他又离婚了。回到青岛的时候,说离婚之后天天酗酒,有时候到处借钱买酒,东村西村,到处借钱,认识的不认识的都要去借,找村里的人借钱。期间有一次借到了老太太那里,老太太给了二十块钱。而这,也是很多年前的事情了,最后 这条消息就是他已经死了。

就这样这简单的一生就此结束了,也许结束在醉生梦死之间。

下午回家,小姐姐在看一个农村教育的纪录片。这时候才想起来看看自己的希望工程的自助金额,微信账单本身并没分类的功能,只能导入微信账本之后才能看到分类统计数据。总记得捐助了很多次,然而,实际上捐助次数也仅有 5 次,金额 1600 多一点点。主要是希望助学,还有圆梦图书。小姐姐说,够了,也不少了。看到那些破破烂烂的小学,不得不想到自己小时候的学校,一个学校 5 个年纪,而实际上老师却只有三个年级的老师,剩下的都是跨年级教学。并不是每个学生,都那么幸运能有那么多的老师。

天气冷了,宝子每周都嚷嚷着让带她去滑雪。晚上看了下金山滑雪场附近的酒店,竟然一家都没有,都是各种宾馆,小姐姐说,宾馆环境太差了,不想住。好几年前去金山滑雪场,附近有个酒店还拍过《甲方乙方》,然而现在已经搜不到了。从高德地图上找到位置,拨打上面留下的电话,听到的第一句答复就是你打错了。这,看来金山滑雪场想玩两天的计划是不行了。

第二天,依然是一个好天气,没有风的时候,暖洋洋的。宝子在家里也呆不住,嚷嚷着出去玩,说什么非得带自己坐坐那个颠勺。九点多吃完早饭,直奔世博园,进院之后发现一大片的娱乐设施都在维护,在边上搭建了几条雪道,可以拖着游泳圈滑雪。宝子又开始嚷嚷着去玩雪圈。

自己并不喜欢她去玩这种,得自己拖着雪圈爬楼台,然而,让她自己拖不现实,我也不想给她拖。

“这种雪,太容易化了,你这穿的裙子,等会儿湿了,你又要叽叽歪歪。如果你今天玩这个,那下周我们就不去滑雪了,你自己选吧”

最终不知道是理智战胜了欲望,还是怎么个情况,没有再提这件事情的,但是明显不大开心的样子。

好在,后来发现那个颠勺还在,跟着宝子做了两次颠勺,把年卡的最后两次给消耗了。不过,就两次颠勺自然满足不了那游玩的欲望。只能再开一张年课,送了 20 个抓娃娃币,还有一张卡丁车的体验卡。

沿着湖边步行不就就到了抓娃娃地方,换币之后运气还算不错,第三次就抓到了一个粉色的考拉,剩下的娃娃都不好抓,要么太大,要么太小,反正是看哪个抓娃娃机的手基本没什么戏。果然不出所料,最后几次都失败了。

跑到旁边的卡丁车车场问了一下,告知那个体验卡是室内的,一个小场地。不过既然是体验卡,那大点小点到时也无所谓。劝说宝子开卡丁车又废了一番功夫,最开始的态度是不想开,坚决不开。直到后来才慢慢松口说试一下,在游乐场快到出口的地方,找到了那个室内的卡丁车场,里面空空的没什么人。看了下价格标牌,48 元/6 分钟,这个明显不够一节的时间,价格说实话属实也不便宜,大卡丁车场是 98元/10 分钟。

选了个头盔带上,上车,简单的说了一下就开始开了,最开始的时候感觉还有些生涩,撞了一次,后面就好多了。不过这种瓷砖的地面用来漂移肯定很不错。看宝子开的时候的确也能飘起来。

不知道是不是错觉还是什么,感觉不到 6 分钟就结束了,踩油门没反应了。过去帮宝子解开安全带,走出来,问她怎么样。“还挺有意思的,挺好玩的,下次还想玩”,边说边抱着自己的胳膊开始往上挂,她管这个动作叫做挎“宝”,不过这个包也的确太沉,挎起来也走不动。

或许,这才是生活的样子吧。玩的时候能玩的开心尽兴,毕竟除了那些爱自己的,又有谁会在乎那个人是谁。

人生,注定不会在历史上留下浓墨重彩的一笔,甚至连附录都上不去。

那又何必在意那些无所谓的虚虚实实,安然生活,就酱紫吧,毕竟也不会有人记得他是谁,更不会想知道他是谁,名字也不过是个记号而已,如果忘了,那就忘了吧。

Merry Christmas🎄

2024年12月25日 11:27

原本,按照自己的想法是不准备再写文章的。前段时间,自己抽了那么一点点的时间,做了一个个人页面,http://i.oba.by .期间,杜郎杜郎给提了不少建议。但是鉴于自己 ps 修图的水平实在有限,所以最终很多东西也没达到自己想要的效果。

然而,昨天看下面的足迹地图的时候,发现出问题了,全部被贴上了未获取商用授权的水印。

这就很离谱,后来登录百度地图开发者,才发现一个问题,那就是认真的时候不小心给认证成了企业开发者,这尼玛就离谱。当时还在想,为什么提示填写企业邮箱更容易认证通过。

后来才发现,默认就是认证企业开发者,个人开发者被藏在了隐蔽的地方。只能切换账号重新认证。

不过这么一来,那么地理编码就会出现问题,因为目前接入的地理位置已经超过 30 个。调用这个接口就会收到下面的提示:

的确,各种限制无处不在。不过好在之前设计的时候给每个地点预留了 gps 坐标信息,如果已经有了 gps 坐标,那么就不会再调用 jsapi 进行解析。

添加服务端 ak,直接后台处理坐标之后,写入数据库:

def process_location_cordinate(self, request):

    baidu_key_set = MapKey.objects.filter(server_key__isnull=False).last()
    if baidu_key_set is None:
        return ErrorResponse(msg='请先配置百度地图服务端 key')

    locations = Location.objects.all()
    successed = []
    for l in locations:
        if l.latitude is None or l.lontitude is None:
            lng,lat = get_location_cordinate(l.name, baidu_key_set.server_key)
            if lng is not None and lat is not None:
                l.latitude = lat
                l.lontitude = lng
                l.save()
                print(l)
                successed.append(l)
    return DetailResponse(self.get_serializer(successed, many=True).data)

地理位置解析代码:

def get_location_cordinate(location_name, server_key):
    resp = requests.get('https://api.map.baidu.com/geocoding/v3/?address='+location_name+ '&output=json&ak='+ server_key)

    print(resp.json())
    js = resp.json()
    if js['status'] == 0:
        return js['result']['location']['lng'],js['result']['location']['lat']
    return None, None

在处理之前,去后台设置 服务端 ak。

相关代码已经更新,见开源项目:https://github.com/obaby/BabyFootprintV2

再次祝大家圣诞快乐,嘻嘻

圣诞节快乐♪٩(´ω`)و♪

2024年12月24日 09:34

开始干一件事情的时候,总是充满了抗拒心。不太想开始做一件事情,而开始之后,坚持又成了最大的问题。上个月宝子一直缠着自己一块弹《泡泡钢琴》,这件事情其实比运动更让自己抗拒,因为自从宝子后来的课程越来越难,双手弹奏之后,自己就已经跟不上了,并且这个东西是需要投入大量时间练习的。而练习,自己更是不怎么投入时间,所以谈不好自然也正常。

就连好久之前练的西游记的片头曲,现在也弹不下来了。于是又开了一个月的会员,两个人一起玩闯关游戏左手修炼、右手修炼。一块弹的缺点就是有时候她弹的分数不如自己高,就开始反复练习,自己只好陪着她看她练。到最后分数达不到 90 也需要继续练习。不过,时间太长了可能也会导致效果不是很好,此时想让她停下来,她却停不下来了,倔强的表示自己一定要弹好。

最终,一个月的会员实际用了大约两周多点,也算是可以了。也没有想天天练。

宝子的跳绳比自己早开始了一个星期,对于她主要的目的是锻炼,长高。而对于自己则是纯粹为了减肥,增加运动量。最开始的记录不是很完整,并且华为的手表有时候跳绳检测有问题,检测不到,太紧了不行,太松了也不行,最后才找个一个合适的松紧度,并且让手表在手腕内侧的记录会更准确一些。

之前说的是每天至少一千个,后来发现一千个也没多大压力,于是提高到 2000 个,这几天稳定在 2600 个左右。

时间也稳定在大约 20 分钟左右,调整的勋章已经解锁了一大半了。剩下两个,应该用不了多久也就解锁了。开始运动了也就发现没那么难了,从开始连续跳 200 多,到后来连续跳 600 多,需要的不过是对自己狠一点,多坚持一下就 ok 了。

周末的时候,给老太太打电话,好几次都没打通,直到周日下午。在次之前二姐有天中午给自己打过电话,说老太太又开始每天吆喝,自己不好活了。活不下去了,能不能弄点什么药吃了直接去了。

现在听到这种话,其实内心已经没有那么大的波动,唯一能做的也就是简单的开导几句,剩下的,自己也无能为力。在电话接通之后,还是照常的寒暄几句,剩下的也没有说什么太多的事情,开导几这件事情也就算这么过去了。挂电话之前,她说,前邻舒红死了,今天的公事,自己过去送了点钱。

这个前邻是我幼儿园的老师,在自己最小的时候教过自己,挺好的一个人,那时候还没结婚。虽然是同一个村,但是去不常见,之前她家在河西边,我们在河东边,所以除了上学基本也难见到,自己后来上学离开老家就见的更少了。

偶尔过年的时候,见面寒暄几句。结婚之后,就在四五年前她的丈夫因为癌症去世了,后来再婚,现任也算不错,挺平和的一个人。前天时间给老太太过生日的时候回去看到他俩,在家西面的菜园里浇菜。百十平米的菜园里里面种的蔬菜种类不少,茄子、萝卜、白菜、大葱,长势都不错,肯定平时也经常来打理照料。

然而过了不到两个月的时间,竟然就死了。这世界总是充满了未知,永远不知道未来和意外哪个更快一些。

昨天下午拍照的客服小姐姐说圣诞的照片修好了,发了个百度网盘的链接过来。之前对于百度网盘的东西,下载感觉总是很恶心,不过前段时间试了网盘套件之后,感觉还是垃圾。反而不如 cloud sync ,直接把照片保存,复制一份到同步空间。晚上回家之后,打开看了一下,所有的文件都下载好了。到时也不用再开着电脑或者手机下载了,毕竟,这种下载方式太磨人了。

有时候感觉这种平静的生活也蛮不错的,波澜不惊。没什么新意,但是也不至于那么乏味。

不过折腾的事情还是避免不了,前几天盾云的系统升级了,尝试使用之前更新 ip 的工具更新 ip 地址的时候发现不能用了。主要是删除、修改、增加回源的方法变了,只能重新扒拉接口,最后 ,变成了下面的样子:

def edit_source_v2(access_token, site_id, ipaddress, req_https_port):
    import requests

    url = "https://scdn.ddunyun.com/prod-api/site_config/origin_server_config?site_id=" + str(site_id)

    payload = "{\n    \"req_scheme\": \"https\",\n    \"req_http_port\": 80,\n    \"req_https_port\": " + str(
        req_https_port) + ",\n    \"sources\": [\n        {\n            \"type\": \"ipaddr\",\n            \"content\": \"" + ipaddress + "\",\n            \"priority\": \"20\",\n            \"weight\": 15\n        }\n    ],\n    \"balance_way\": \"rr\",\n    \"req_host\": \"$host\",\n    \"req_timeout\": 60,\n    \"range_origin\": false\n}"
    headers = {
        'accept': 'application/json, text/plain, */*',
        'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'authorization': 'Bearer ' + access_token,
        'content-type': 'application/json;charset=UTF-8',
        'origin': 'https://scdn.ddunyun.com',
        'priority': 'u=1, i',
        'referer': 'https://scdn.ddunyun.com/',
        'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"macOS"',
        'sec-fetch-dest': 'empty',
        'sec-fetch-mode': 'cors',
        'sec-fetch-site': 'same-origin',
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'
    }

    response = requests.request("PUT", url, headers=headers, data=payload)

    js = response.json()
    if js['code'] == 200:
        return js['data']
    else:
        print('[E] 发生错误:', js['message'])
    return None

不过,这新的方法,需要传递端口,只能增加一个参数,而至于端口的传送,不同的域名回源端口又不一样,也只能修改域名列表为下面的方法:

domain_list_v2 = {
        'image.dlj.kim': 6443,
        'dlj.kim': 6443,
        'image.h4ck.org.cn': 5443,
        'wiki.guimiquan.cn':
            5443,
        'baby.lc':
            5443,
        'danteng.me':
            5443,
        'loli.gifts':
            5443,
        'lang.bi':
            5443,
        'da.bi':
            5443,
        'zhongxiaojie.cn':
            5443,
        'lang.ma':
            5443,
        'h4ck.org.cn':
            5443,
        'nai.dog':
            5443,
        'baidu.bi':
            5443
    }
    new_ip_address = '123.2.17.9'
    update_domain_source(domain_list_v2, new_ip_address)

批量更新代码:

for s in site_list['items']:
    # print(s['domain_name'])
    dn = s['domain_name']
    site_id = s['id']
    if dn in domain_list:
        source_list = s['sources']
        # print(source_list)
        print('-' * 100)
        print('[U] 时间:', datetime.now())
        print('[U] 更新域名配置:')
        print('[U] 域名:', dn)
        ip_count = 0
        for sl in source_list:
            source_id = sl['id']
            # site_id = sl['site_id']
            ip_address = sl['content']
            try:
                # if sl['type'] == 'ipaddr':
                print('[U] 旧 IP 地址:', sl['content'])
                # edit_source(token, site_id, source_id, ip_address)
                if ip_address != new_ip_address:
                    print('[U] 更新:正在更新 ip 地址:123.234.187.19')
                    # result = edit_source(token, site_id, source_id, new_ip_address)
                    result = edit_source_v2(token, site_id, new_ip_address, domain_list[dn])
                    if result is None:
                        print('[D] 失败:发生错误 ip 回源:', ip_address)
                        # delete_source(token, site_id, source_id)
                else:
                    print('[U] 忽略:IP地址无变化')
                ip_count += 1
                # else:
                #     print('[D] 删除:删除域名回源:', ip_address)
                #     delete_source(token, site_id, source_id)
            except Exception as e:
                print('[E] 发生异常:', e)
        # 如果不存在 IP 地址回源 添加 ip 回源
        if ip_count == 0:
            result = edit_source_v2(token, site_id, new_ip_address, domain_list[dn])
            if result is None:
                print('[D] 失败:发生错误 ip 回源:', new_ip_address)
        print('*' * 100)

之所以放在这里,是因为这个东西毕竟小众,有这种需求的人也就更小众了。所以,有缘者取之,就酱紫吧。实在不想在写一篇文章了。

这所有的一切,随缘就好,又何必执着呢。

希望大家都平安喜乐,至于年终总结什么的,毕竟也不会写的,也不知道该总结啥。就酱紫吧。

祝大家平安夜平安,圣诞节快乐!

紧箍咒

2024年12月20日 09:59

《西游记》悟空保唐僧西天取经的时候,观音送给了唐僧一个法宝,叫做“紧箍”,还送了一篇经文,名唤《紧箍咒》,连哄带骗的骗那个弼马温戴上了这紧箍。靠这两个东西,唐僧拿捏了悟空取经一路。

早在上个月的时候,青岛就组织了一次关于 app 合规的推进会,只是,上次在软件园,而那天自己事情太多,竟把这事给忘了,两点开会,等想起来的时候已经三点了,再去参会依然是来不及了。

周二的时候有通知说集团组织了一次宣讲会,针对的还是 app 隐私合规问题。时间是昨天下午两点,这次相对来说没那么远,也就想着去听一下吧。

两点开会,自己溜达过去还有二十来分钟才开始,会议室门口有人询问,是来开会的吗?外面也并没有明显的指引,所以靠人引导也就顺理成章了。进入会议室,还没有多少人到,签到之后,选择最后一排入座。会议室不大,大约能容纳一百多人的样子。

打开微信划拉,正好希望工程的一条消息又映入眼帘,大学生收到了春节返乡的 500 元票务费用。上大学的时候,自己虽然也领助学金,勤工俭学,但是却没有领过回乡补助,现在看来,资助的范围是广了一些,不过,贫困依然存在,似乎好了一些?有似乎没好一些?其实自己也不大懂。毕竟,已经离开学校太久,然而,之前经常听同事说他们学校贫困生补助是人就能领,这让我颇感诧异。意味着很多对于贫困生的资助,都到了这些人的身上。然而,真正需要钱的却拿不到这些钱。不过,这个问题自己解决不了。所以,之前的捐助对象也都选择了小学生或者初中生。现在大学救助似乎也在解决这个问题了,多数的救助,进针对于大一新生,也算是一个进步吧。

翻了一下,很多的捐助依然在进行,当然,也有很多是长期的。还是选择初中生捐助,金额自然也不会太多。

逼乎上有个帖子讨论,贫困是不是就应该不生孩子。如果物质上贫困,精神上在给不了任何的爱,比物质还贫困,想生个孩子投资,那么还是别生了,孩子太累了。

忙活完这一切,宣讲会开始了。简单介绍了一下参与宣讲的人员,省通讯管理局的一个科长,加上负责进行合规检测公司的技术人员。

喜欢当爹的人太多了,不断的有人告诉你该干什么,这不能干,那不能干。国内的 app 市场(安卓),就靠一个软著都能诞生无数的服务部门,所以,没有需求给你创造需求也要搞。后来有了软著不够,要上架应用市场还要有版权证书,而这个证书,也是几个公司垄断,名义上可以免费申请,实际上免费的要等 15 个工作日,而花钱了就不用了。

再后来就是 app 隐私合规检测,所有的应用市场搞一遍,还有各种部门委托公司进行抽查。每年都在疲于应付这些所谓的隐私合规问题。

然而,现在这种情况更甚了,不单要检查隐私协议,甚至连 app 集成的 sdk 都要检测,为此还建立了 sdk 白名单。不得不说,黑白名单,真是解决问题的好办法,一言不合就往名单里扔。以后如果 sdk 白名单找不到相关 sdk 了,那么 app 也要跟着被下掉。或者继承了不在白名单内的 sdk,连上架都上架不了。

因为一个 sdk 的问题,都能株连九族,这不得不说的确是简单粗暴。同样,sdk 的隐私协议出了问题,app 也要受牵连。就这种株连、连坐的方式,的确是让人为之佩服。

天天说什么保护用户隐私,然而,真正侵犯用户隐私的是这几个 app 吗?各种运营商、机构、组织,早已经将用户隐私给卖干净了。各种层出不穷的恶心人的开屏广告、插屏广告,难道这些不侵犯用户隐私?所谓的 app 合规,一个紧箍套给开发者,就可以无忧了吗?多部门联合进行隐私合规筛查,发布告知告警,连紧箍咒都是多人念的。用户能不头疼?

 

这世界啊,终究逃不过一场闹剧,我觉得你需要,你就是需要。而至于这个紧箍的大小,多少,又有多少人念咒。哪个又不想体验下念咒让别人痛苦的感觉?

然而,悟空终将成佛拿到紧箍,这紧箍又将何时拿掉?

“王师北定中原日,家祭无忘告乃翁”

小肚,小肚。我在!

2024年12月19日 10:55

夜越来越长,早点六点多醒来,看着窗外还是深黑的。早上也没有太多的车,然而,宁静的早上,却也不能赖床,要给宝子做早餐。

有时候,觉得也挺单调的,每天的生活都出奇的一致。一样的时间,一样的路线,每天都在重复同样的事情。偶尔,能有那么点兴致的也就瞎折腾了。

前几天看到百度网盘出了个群晖 nas 的套件,安装之后,看了一下,的确很百度,开始速度 400k,后续速度稳定在 80k 左右,还推出了群晖 nas会员:

这个传输速度,其实跟群晖的 cloud sync 套件速度区别不大,那推出这个东西,也确实没看出有什么用户,一句话,垃圾。

昨天上午去拍照,问化妆的小姐姐:“有没有感觉我瘦了点?”

“不单瘦了点,感觉还白了呢”。就喜欢会说话的小姐姐。

而至于减肥,从 11 月 11 号,开始嚷嚷着减肥,到现在过了一个多月了,其实也没什么大的成效,一共减了 4kg 左右,依然是个长期的任务。而之所以要去拍照,不过是为了给自己一个目标,提供一点点动力。当然,还有一点就是胖了的确身体也有很多异常指标,脂肪肝、肾囊肿,也是希望减肥下来之后,这些问题能够解决掉吧。

然而,虽然小姐姐说的很好,但是实际上,拍照的时候还是感觉尴尬啊。

看这没修过的小肚肚,哎,的确是无语。啥时候能减没啊。从前几天开始跳绳了,这是跑步机卖了之后,重新开始锻炼的起始点了。希望一天 1000+能坚持下去。

在家里,经常拍肚子,说:“小肚,小肚”,自问自答:“我在”

宝子听到了就会说,:“你这不是小肚,你这是大肚。”

“小肚,小肚”

“我在。”

“大肚,大肚”

“我还在。”

四谈自建Gravatar镜像

2024年12月18日 16:18

至于为什么是四谈,之前的谈,参考这里:https://h4ck.org.cn/?s=gravatar。前几天收到杜郎杜郎的消息,说我搭建的gravatar代理失效了。之前有段时间因为cf的流量问题,一度放弃了那个代理。

看来是改了规定了,不过现在貌似还能用。然而国内的这些代理,却一个一个的都比较诡异,诡异之处在于缓存刷新时间是个迷,换了头像几百年都不更新,这也的确是让人无语。昨天在杜老师的聊天室吐槽,有知情网友告知更新时间是一个月:

这一个月都够自己换好几次头像了。最后很有爱心的给了个自建方案,这种自建是个方法,但是还是想着直接套cdn来搞一个。把盾云的服务整合了一下,正好空出来一个域名就用来干这个了,要代理也简单,不要用国内的cdn,选择亚太或者欧美,添加回源地址:

直接ip地址回源:192.0.80.241 Host填写gravatar.com这样,一个自建的gravatar代理就ok了。

家庭作业

2024年12月16日 10:59

还是周末的时光好啊,虽然是冬天,等大太阳升上天,没有寒风的时候,感觉暖洋洋的还是蛮惬意的。

青岛海边的冬天,虽然不能下水玩水,但是,沿着栈桥一线,八大关景区,还是有很多海鸥的。冬天的乐趣也就剩下了喂海鸥,毕竟,下水神马的,真的太凉了,下不了一点。

周日早上八点多,还在被窝里赖着,被宝子给叫了起来,让去买油条,还要多买几根。当然,吃不完的油条就是用来喂海鸥的。青岛的海鸥,可能是喂的太多了,太好了,对于馒头之类的东西已经看不上了,最起码也得是油条起步。

慢腾腾的从被窝里爬出来,简单捯饬一番就去买油条。小区周边就一个卖油条的早点铺,尽管已经快 9 点了,卖油条的地方还有 四五个人在排队。等了大约几分钟,总算是买上了,主要原因还是前面几个买油条的并不多。

简单吃完早饭,直奔海边。冬日的海边,人并不多。零星有几个在海边翻石头挖 gala 的。

我也去挖了个小水坑,水是真凉啊,过半天都没暖和过来。

海滩上插满了这种小管子,不知道是什么,一拽就断了,挖出来是空心的。

虽然海边的人少,但是小动物更少。基本没挖到什么,在大坝上有个大姐在卖螃蟹,海星。我说宝子快看还有派大星,一群人转过头来看我,难道大家都不知道派大星的吗?

顺着海边的礁石往里走,掀起来一块块的石头,偶尔能看到一条条小鱼,还有很多小海螺。

翻了一会儿石头,找到一直小螃蟹,小小的。

让宝子拿一下,最开始有些抗拒,怕小螃蟹夹她。直到最后看在我手里半天也没夹人,才大胆放到手心里,让他在里面趴,过了会儿感觉没什么意思了,就给放回到了水里。除了螃蟹,偶尔也能捡到小贝壳

不过都是小小的一只。

冬天玩水的确是凉了点,长时间不来市南,正好过来了,可以去万象城再吃一次之前吃过的俄士厨房,虽然是俄国菜,但是实际上是西餐的配置。不过这次心心念念的大蜗牛没有了,要了个鲍鱼。

不过这个鲍鱼倒是充满了仪式感,宝子说太咸了。就吃了一点点,这次比较好评的是鹅肝黑松露配鱼子酱,配上脆脆的面包。不过吃起来不怎么优雅,叉子叉不住,刀子一切就碎了,最后是趴在盘子边上跟吸面条一给吃掉的,吃相的确不怎么优雅。

而至于那个香菇浓汤,打死都不想喝第二次了,宝子没喝完,最后剩下大半碗自己喝掉了,整个脑子里都充满了蘑菇味。那种旷日之久的蘑菇味一度让自己精神混乱,吃小橘子都是蘑菇味的。

就在吃饭的时候,收到老师在群里发的消息,创意小手工的参赛通知,而至于这件事情,自己并不是真的很想参与,因为真的很麻烦的啊。主要是工具不全做起来贼 tm 累。

晚上等宝子吃完晚饭开始做手动,最开始还能帮忙,后来就自己跑到一边去玩化妆娃娃去了。

既然是创意,那就做个有意思的,悬空凳,后来觉得那个太麻烦了,主要是家伙不全啊,简化下做个三角的吧。主要的材料就是一次性筷子、热熔胶、棉线。

不过这个竹筷切割是真累啊,用钢锯锯半天,真的想买个砂轮跟切割齿轮了。当然最好要有个工作台,这个钢锯加工的精度明显不够。

不过最终还是在自己的不懈努力下终于成功啦。不过材料和工具也基本都耗没了,看来是时候补充新的工具了。

本来还想栓第三根绳的,但是既然两根就能答道效果,又何必多此一举呢~

天生冤种?

2024年12月12日 09:51

我一向不大喜欢与所谓的的这些平台、或者公司去计较,主要原因还是懒,没那么多时间去消耗在这些无所谓的事情上。然而,有的时候这些平台的确倚靠自己平台方的权利,随意禁言、删除内容,的确让人反感。

之前从 9 月份开始,一直在投诉知乎的恶意删除内容以及禁言问题,每次删除回答或者禁言都是一句违反社区规定,这句话真是 tmd 比有关部门还恶心,问违反了哪一条,那些内容违反了规定,后续就连个 p 都不放了,多次答复都是无意义的答复:

而至于给出的答复,则又前后矛盾,又说是违反规则发布推广内容,又说是传播盗版软件。问具体是哪条内容,那篇文章违反了这些规定又 tmd 开始装死:

这些牛逼平台,在装傻充愣的能力上真是无人可匹敌。真是碉堡了,后来因为事情有些多,也没再计较这件事情,反正这些牛逼的平台,问就是违反了规则,问哪些内容违反了规则就开始装傻,我可去你他妈的吧!艹!

以后等有时间了,再继续投诉,答复完一条投诉一条!

遇到牛逼平台,请移步这里投诉!https://hlwtsxt.miit.gov.cn (互联网信息服务投诉平台)

遇到牛逼平台,请移步这里投诉!https://hlwtsxt.miit.gov.cn (互联网信息服务投诉平台)

遇到牛逼平台,请移步这里投诉!https://hlwtsxt.miit.gov.cn (互联网信息服务投诉平台)

本来,我都不准备写这些傻屌事情,直到后来,在Andy 烧麦,那里的一篇文章看到了他的保险费用清单!300万的三者险,600 多块钱。

此时我想起来去看下自己的保险费清单。

自己目前两辆车,目前同样的三者 100 万,价格差了接近三倍!车损保险费高我能理解,三十这个三者费用差了近 3 倍我不能理解。于是打平安电话投诉,给的反馈是,说让联系销售保险的相关人员,这个 8000 多的是四儿子店买的,联系上销售之后,给的答复就是保险系数不一样,剩下的都不能告知,问这个保险原价多少,给的系数是多少,被告知是系统提供的,自己无法提供。

于是放弃这条路径,直接打 12378 银保监会投诉电话投诉,此时更神奇的事情发生了,自己两台手机的两个联通号码都无法完成呼叫,拨打的过程中直接信号从 4g 变成 3g 最后直接没信号了,提示界面就是无法完成呼叫!

移动的号码能打,但是另外一头是忙音。

只能再一次转战投诉战场,打 12345。告知接线的小姐姐,自己要投诉平安跟联通,小姐姐告知平安的投诉只能打 12378,不过投诉联通不能拨打 12378 这件事情他们可以接。

第二天接到联通电话,说自己的号码没问题,平台也没问题,应该是能拨打 12378。

后来试了一下果然能拨打 12378 了,继续投诉平安,投诉完了之后会直接转到平台的投诉反馈中心,一通反馈之后,开始给我讲保险计费的策略,主要的还是那一套,每个人,每辆车的系数不一样。问具体怎么算出来的又是糊弄。

在接了九九八十一个电话之后,终于,有人肯告知怎么算的了。

反正就是别问,问就是高端车!合着,姐姐我就该当这个大冤种呗?可qntmdb!

而至于联通,本来以为故事到此就算完了,然而,这两天需要卡一张发票,打开 app 查看账单,发现账单一个月比一个月离谱。

不仅如此,年初预付费的 480 返还,后来也返还没了:

年初换的 149 的套餐,交了 480,5 月份换了 179 的套餐,又交了 399,升级了设备,然后,之前交的钱就 tm 都失踪了,返还也没了?这就 tm 离谱!

都说顾客是上帝,这 tm 顾客哪里是上帝?顾客 tmd 简直是冤种,是韭菜。

联通的临时解决,多一张副卡十块钱,这个 189 倒是能解释了。至于年初的 480 的费用(24 个月返还),说返了 5 个月,每个月返 50,按照本金算,扣掉 250,剩下 230,帮门给申请走充360 的话费。不过,如果这个东西自己忘了,这 tm 这笔钱算是直接给扔了。

既然当不了上帝,那还是老老实实当 Lucifer 吧!

有时间闲着干嘛?继续投诉,你大爷的!

腾讯企业邮箱容量不足

2024年12月11日 11:19

这几天频繁收到腾讯企业邮箱的提示,邮箱容量不足。

虽然目前感觉用起来还没问题,不过这个容量一直增长也是个问题。

想着去清空下邮箱,结果搜索了一下没发现什么有用的东西。只好自己动手。登录管理后台,找到公共邮箱

这里有个使用成员,修改使用成员就可以登录邮箱之后进行切换了。

使用成员账号登录邮箱,点击左上角的切换账号即可:

这一堆邮件,刚开始在收件箱和发件箱删除,直接删吐了都,最后进到设置的文件夹页面删除才稍微快了那么一点点。

不过一次五千封邮件,依然删除了好多次。不过最后这个容量的问题,算是解决掉啦。

白月光

2024年12月9日 16:08

周五,学校组织了一次烘焙活动。说是烘焙,其实是家长准备各种材料中午给小朋友们做各种吃的。

十一点半开始,一点之前结束,就这么点时间,肯定也无法全部手工做,有的家长早就准备好了各种材料,以及各种预先烘焙的成品。等到了实际去上手的时候,就只剩下了烤披萨。

讲各种材料分配好,放入烤箱,剩下的其实也就没多少工作了。等披萨烤好已经到了十二点半,正好孩子们吃完饭也就过来了。

几十个小朋友聚集在一个屋子里,吵闹程度能赶上 200 只鸭子。一中午的喧嚣就这样开始了,期间老师还来看了一下,对自己说,你也吃点啊。

然鹅,实际情况是,所有的东西小朋友都吃光了,就连最后装饰用的糖豆都被小朋友用一次性手套打包带走了,没人人的手套指头里都塞满了东西,糖果、披萨、三明治、面包,一切能塞进去的东西都被塞进去带走了。

既然请假了,下午就可以回家待一会儿。等到四点半,从家里出来,去学校对面的停车场洗下车。洗完车,可能宝子也就放学了。然而,洗车的时间还是估计错了,洗完车还不到五点,停车场洗车免费停车半小时,等宝子放学之后时间也远超了半小时了。洗车还得交停车费,心里暗暗不爽,洗完车就直接开出来了。找了个小区的路边等待放学的到来。

中午熬到五点半,接到宝子,她说,想继续去吃炸酱面。周四的时候带宝子去万达吃饭,本来想吃小炒黄牛肉的,然而,找遍了整个餐饮区,也没找到那家店。最后换了老北京炸酱面,万幸,到时复合宝子的胃口。吃饭完回家的时候,发现边上的炒鸡店,装修风格跟原来的小炒黄牛肉很相似。可能,牛肉炒不下去了改炒鸡肉了。

带宝子到车上,启动车子,听到叮的一声提示音。仪表盘上的胎压警示灯也亮了。

虽然压力值差的不错,但是不知道是不是因为漏气导致的。不过好在这个压力倒是不影响行驶,还是带着宝子继续去万达吃牛肉面。

吃饭的时候,收到阿里云的短信,提示一台服务器马上要过期了。这台服务器是好几年前做的定位软件的后台服务,自从阿里旺信不对开发者开放之后,也就再也没有维护过,不过依然能登录,能定位,能上传。在这之后有坚持了一年多的时间,就这么运行着。终于,今天服务器又到期了,打开 app 看了下续费价格 110 一个月,一年 1000 多。

这时候才觉得,这个 app 真的该寿终正寝了,毕竟功能也不完整了。与其苟延残喘,不如彻底了断吧。于是这台服务器就彻底下线了。

晚上,登录苹果开发者后台,把 app 也停止销售了。

里面还躺着另外一个之前提交没有审核过,后来也放弃更新的 app,这些东西,曾经自己也都投入了大量的心血。

第二天,早上还要带宝子去上钢琴课。怕车胎因为漏气没法开,所以还是提早出门了。好在看了下胎压,依然保持在昨天的水平。那就上完课再去补胎吧。

在补胎店,老板前后左右看了一圈,说不像漏气的样子。最后拿了个胎压表确认了一下,才相信自己说的右前轮漏气的事实。他肉眼观察觉得是左后轮漏气,因为那个更扁一些。

然而,轮胎拆下来之后,喷满了水,来来回回半天也没找到漏气的地方,可能就是原来充气的时候这个轮胎的胎压就比较低吧。只好给所有的轮胎重启,说,等跑跑再看看吧,现在也无法确认哪里的问题,即使拆了也解决不了问题。

此时,手机有收到几条短信,有个域名进入赎回期了。

对于这个域名,自己也不想再继续持有了,这么多年,注册了树个域名,特别喜欢的也就那么几个,剩下的,忽然就都变得可有可无了,毕竟想靠这个发财也不现实。所以,不如放他们自由吧。

并且好多的域名也没有绑定所谓的业务或者服务,就那么扔着,有价值吗?其实没啥价值,纯粹也就是闲的蛋疼而已,甚至没有任何的意义。而至于开发 app,这个其实想来也是纯粹闲的。不挣钱还要搭钱,做这个东西有什么意义吗?严格说来没有。

所谓的独立开发者,迎娶不了白月光,甚至连温饱都解决不了。

至于别的开发者是怎样的,我不知道,而对于我所做的这一些,纯粹就是 tm 闲的蛋疼!

而至于那遥不可及的月光,也就是看看,仅此而已。

去掉UkeySoft Screen Recorder 8.0.0 弹窗

2024年12月8日 10:12

之前屏幕录像和截图一直用的UkeySoft Screen Recorder ,直到换了4k显示器之后发现不好使了,录像的时候直接崩溃。后来换了windows自带的snipping tool。

今天又看了下,最新版成了8.0

奔溃的问题解决了,可以录制,但是两个4k屏幕一起录制还是有问题。

使用7.0的注册信息,可以完成本地注册,但是重启之后就会提示授权校验错误:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\GSLLC\21881]
"InitTime"=dword:61250d35
"WorkMode"=dword:00000002
"Registerd"=dword:00000001
"SN"="70807-07524-21881-57632-20916-75753"
"EMail"="root@obaby.org.cn"
"LastTime"="20210825"

旧版本的还是32位的可执行文件,新版本已经是64位的了,直接x64dbg载入。

代码没有任何的混淆加密,对所有的CheckSNOnline函数下断点,运行:

启动后会断在下面的地址:

0000000000754345                         | E8 962CFFFF                        | call <JMP.&CheckSNOnLine2>                                                   |
000000000075434A                         | 89C3                               | mov ebx,eax                                                                  |
000000000075434C                         | 48:8B45 28                         | mov rax,qword ptr ss:[rbp+28]                                                |
0000000000754350                         | 48:8378 58 00                      | cmp qword ptr ds:[rax+58],0                                                  |
0000000000754355                         | 75 14                              | jne screenrecorderpro.75436B                                                 |
0000000000754357                         | 48:8B45 28                         | mov rax,qword ptr ss:[rbp+28]                                                |
000000000075435B                         | 48:8D48 58                         | lea rcx,qword ptr ds:[rax+58]                                                |
000000000075435F                         | 48:8D15 3E010000                   | lea rdx,qword ptr ds:[7544A4]                                                | 00000000007544A4:L"null"
0000000000754366                         | E8 E5BFCBFF                        | call screenrecorderpro.410350                                                |
000000000075436B                         | 83FB 01                            | cmp ebx,1                                                                    |
000000000075436E                         | 75 25                              | jne screenrecorderpro.754395                                                 |
0000000000754370                         | 48:8B45 28                         | mov rax,qword ptr ss:[rbp+28]                                                |
0000000000754374                         | 48:8985 80000000                   | mov qword ptr ss:[rbp+80],rax                                                |
000000000075437B                         | 48:8D05 BEF5FFFF                   | lea rax,qword ptr ds:[753940]                                                |
0000000000754382                         | 48:8945 78                         | mov qword ptr ss:[rbp+78],rax                                                |
0000000000754386                         | 48:8B4D 28                         | mov rcx,qword ptr ss:[rbp+28]                                                |
000000000075438A                         | 48:8D55 78                         | lea rdx,qword ptr ss:[rbp+78]                                                |
000000000075438E                         | E8 DDE7D5FF                        | call screenrecorderpro.4B2B70                                                |
0000000000754393                         | EB 62                              | jmp screenrecorderpro.7543F7                                                 |
0000000000754395                         | 83FB FF                            | cmp ebx,FFFFFFFF                                                             |
0000000000754398                         | 75 22                              | jne screenrecorderpro.7543BC                                                 |
000000000075439A                         | 48:8B45 28                         | mov rax,qword ptr ss:[rbp+28]                                                |
000000000075439E                         | 48:8945 70                         | mov qword ptr ss:[rbp+70],rax                                                |
00000000007543A2                         | 48:8D05 67F6FFFF                   | lea rax,qword ptr ds:[753A10]                                                | 0000000000753A10:"UVSH冹PH嬱H塎0H荅8"
00000000007543A9                         | 48:8945 68                         | mov qword ptr ss:[rbp+68],rax                                                |
00000000007543AD                         | 48:8B4D 28                         | mov rcx,qword ptr ss:[rbp+28]                                                |
00000000007543B1                         | 48:8D55 68                         | lea rdx,qword ptr ss:[rbp+68]                                                |
00000000007543B5                         | E8 B6E7D5FF                        | call screenrecorderpro.4B2B70                                                |
00000000007543BA                         | EB 3B                              | jmp screenrecorderpro.7543F7                                                 |
00000000007543BC                         | 83FB 02                            | cmp ebx,2                                                                    |
00000000007543BF                         | 75 36                              | jne screenrecorderpro.7543F7                                                 |
00000000007543C1                         | 48:8D8D 8C010000                   | lea rcx,qword ptr ss:[rbp+18C]                                               |
00000000007543C8                         | 48:8D95 88000000                   | lea rdx,qword ptr ss:[rbp+88]                                                |
00000000007543CF                         | E8 EC2BFFFF                        | call <JMP.&CheckSNWhenRegist2>                                               |
00000000007543D4                         | 48:8B4D 28                         | mov rcx,qword ptr ss:[rbp+28]                                                |
00000000007543D8                         | 8941 48                            | mov dword ptr ds:[rcx+48],eax                                                |

7.0我修改的verify.dll文件,这里直接修改主程序,将call <JMP.&CheckSNOnLine2>  一行nop掉。

修补源文件,再次运行就一切ok啦。

送别

2024年12月5日 13:23

送别,可能从来都不是送别。偶尔,一个人的时候会想起这首诗,偶尔想到一些人也会想到这首诗。

长 亭 外 , 古 道 边 , 芳 草 碧 连 天 。 晚 风 拂 柳 笛 声 残 , 夕 阳 山 外 山 。 天 之 涯 , 地 之 角 , 知 交 半 零 落 。 一 壶 浊 酒 尽 余 欢 , 今 宵 别 梦 寒 。 长 亭 外 , 古 道 边 , 芳 草 碧 连 天 。 问 君 此 去 几 时 来 , 来 时 莫 徘 徊 。 天 之 涯 , 地 之 角 , 知 交 半 零 落 。 人 生 难 得 是 欢 聚 , 惟 有 别 离 多 。

人生,偶尔的具象化,每次从老家回来,或者朋友聚会离别,最后总是那句,“别送了,回去吧”

之后,就又踏上了不同的道路,而这条路通往何方,又会在什么时候终结,终将是个未知数。

昨天下午上班的时候,接到了对象的电话,告知姥爷去世了。从姥爷开始老年痴呆,到现在,已经又过了两三个年头,时间就这么不紧不慢的流动着,也裹挟着一些人滚滚而去。

下午,他们几个就开车回去了,自己留下来接送宝子上学。

这几年,老人们开始慢慢的都离开了,一个接一个,对象的爷爷、姥爷、自己家的大爷、大娘,感觉每年都会送一些人离开。

然而,送走的不仅仅是那些老人,一些年轻人,跟自己岁数差不多的也开始离开了。村里基本跟自己岁数差不多的,也因为各种原因离开这个世界,有已经结婚的难产而死,有没有结婚的因病而亡。这个世界总是充满了各种未知的情况,和不可预见未来。

死毕竟是一件不必急于求成的事情,早晚都会到来。那些垂垂老矣的亲人,总是有种见一次少一次的伤感。

然而,人老了,身体和行为开始陷入不能自主的境地之后,家里的老人又成了折磨。不断消耗子女的耐心和心态,对象的爷爷老年痴呆四五年的时候,在他的孩子们嘴里听到的,经常也是要死就死了吧。常年的不能离人,让陪伴的家人,每天都在脱一层皮。尤其是他们也老了,没有那么好的精力和体力。

太多的人对死亡无比的忌讳,太多的时候,喜欢说的都是好死不如赖活着。对于自己来说,直到结婚之前并没有太多老人离世的概念,自己的姥姥姥爷早在自己不记事的时候就已经离世,而爷爷则更早,后来唯一的奶奶也在自己上小徐的时候去世了,那时候也不知道什么是伤心。

然而,看到另外的爷爷和姥爷陷入老年痴呆,生活不能自理,不记事,不记人,什么的都不记得的时候,人真的需要赖活着吗?之前多次讨论过最后的死亡的问题。这个终将多不过,也经常说,等哪天自己不记事了,就让家人把自己扔到一个荒山野林,自生自灭把。就这样消失于人间。

巧了,昨天琼瑶阿姨也走了,不过是选择自己结束了生命的旅程。体面的活着,我也想有这样的追求。不要等哪天身上插满了管子,自己连自己的想法都不能表达了,还想着怎么活着,此时活着,也就没有意义了,更何况,人生本来就没有太多的意义。

希望,等哪天自己离开这个世界的时候,能体面的对自己爱的那些人说一句:

“回去吧,别送了,我走了……”

SCDN 放弃 DDNS 回源 — IP 地址回源更新工具 V1.0【开源】

2024年12月4日 11:03

前端时间家里的路由器坏了,导致一些服务挂掉了,包括自己的博客,闺蜜圈 wiki 等。然后就是每天收到各种离线消息。

终于网络恢复之后,感觉一切正常然而,通过 cdn 反问就是回源错误。于是跟技术沟通了一下下下,发现盾云的域名回源竟然存在延迟,并且这个延迟好几个小时,这就比较蛋疼了。所以,每次换了 ip 首先要去设置 ip 地址才能正常回源。

既然,这个东西存在延迟,那么 dnspod 的 vip 的动态 ddns 解析也就没有任何的用了,延迟已经不是动态域名的问题了,是 cdn 域名刷新的问题。

今天早上忽然想到,既然域名有延迟,那就直接 ip 地址回源吧,不过域名太多了也不能每次都改啊。直接尝试代码解决吧,下面就是全部的代码了:

# 盾云SCDN 接口工具
# by:obaby
# https://h4ck.org.cn
# https://oba.by
from datetime import datetime

import requests

username = '邮箱地址'
password = '密码,先设置用户邮箱地址和密码'

def login():
    url = "https://scdn.ddunyun.com/prod-api/login"

    payload = "{\"email\":\""+username+"\",\"password\":\""+password+"\"}"
    headers = {
        'accept': 'application/json, text/plain, */*',
        'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'content-type': 'application/json;charset=UTF-8',
        'origin': 'https://scdn.ddunyun.com',
        'priority': 'u=1, i',
        'referer': 'https://scdn.ddunyun.com/',
        'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"macOS"',
        'sec-fetch-dest': 'empty',
        'sec-fetch-mode': 'cors',
        'sec-fetch-site': 'same-origin',
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'
    }

    response = requests.request("POST", url, headers=headers, data=payload)

    # print(response.json())
    js = response.json()
    if js['code'] == 0:
        return js['data']['access_token']
    else:
        print('[E] 发生错误:', js['message'])
    return None
    # return None


def get_site_list(token):
    url = "https://scdn.ddunyun.com/prod-api/site?domain_name=&sub_domain_name=&cname=&status=&current_page=1&total=0&page_size=20"

    payload = {}
    headers = {
        'accept': 'application/json, text/plain, */*',
        'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'authorization': 'Bearer ' + token,
        # 'cookie': 'LeCDN-Client=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJjbGllbnQiLCJleHAiOjE3MzMyOTM5NDcsIm5iZiI6MTczMzI3MTM0NywianRpIjoiNDEifQ.lpSIjvtVGE7wcxZgNF2upZiZ8QsPh2CYajevHqgsjzg; sidebarStatus=0',
        'priority': 'u=1, i',
        'referer': 'https://scdn.ddunyun.com/',
        'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"macOS"',
        'sec-fetch-dest': 'empty',
        'sec-fetch-mode': 'cors',
        'sec-fetch-site': 'same-origin',
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'
    }

    response = requests.request("GET", url, headers=headers, data=payload)

    # print(response.text)
    js = response.json()
    if js['code'] == 0:
        return js['data']['data']
    else:
        print('[E] 发生错误:', js['message'])
    return None


def get_site_source(access_token, site_id):
    url = "https://scdn.ddunyun.com/prod-api/site_source?site_id=" + str(site_id)

    payload = {}
    headers = {
        'accept': 'application/json, text/plain, */*',
        'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'authorization': 'Bearer ' + access_token,
        # 'cookie': 'LeCDN-Client=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJjbGllbnQiLCJleHAiOjE3MzMyOTM5NDcsIm5iZiI6MTczMzI3MTM0NywianRpIjoiNDEifQ.lpSIjvtVGE7wcxZgNF2upZiZ8QsPh2CYajevHqgsjzg; sidebarStatus=0',
        'priority': 'u=1, i',
        'referer': 'https://scdn.ddunyun.com/',
        'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"macOS"',
        'sec-fetch-dest': 'empty',
        'sec-fetch-mode': 'cors',
        'sec-fetch-site': 'same-origin',
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'
    }

    response = requests.request("GET", url, headers=headers, data=payload)

    js = response.json()
    if js['code'] == 0:
        return js['data']['data']
    else:
        print('[E] 发生错误:', js['message'])
    return None


def delete_source(access_token, site_id, source_id):
    # url = "https://scdn.ddunyun.com/prod-api/site_source/593?site_id=382"
    url = "https://scdn.ddunyun.com/prod-api/site_source/" + str(source_id) + "?site_id=" + str(site_id)

    payload = {}
    headers = {
        'accept': 'application/json, text/plain, */*',
        'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'authorization': 'Bearer ' + access_token,
        # 'cookie': 'LeCDN-Client=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJjbGllbnQiLCJleHAiOjE3MzMyOTM5NDcsIm5iZiI6MTczMzI3MTM0NywianRpIjoiNDEifQ.lpSIjvtVGE7wcxZgNF2upZiZ8QsPh2CYajevHqgsjzg; sidebarStatus=0',
        'origin': 'https://scdn.ddunyun.com',
        'priority': 'u=1, i',
        'referer': 'https://scdn.ddunyun.com/',
        'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"macOS"',
        'sec-fetch-dest': 'empty',
        'sec-fetch-mode': 'cors',
        'sec-fetch-site': 'same-origin',
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'
    }

    response = requests.request("DELETE", url, headers=headers, data=payload)

    js = response.json()
    if js['code'] == 0:
        return js['data']
    else:
        print('[E] 发生错误:', js['message'])
    return None


def edit_source(access_token, site_id, source_id, ip_address):
    url = "https://scdn.ddunyun.com/prod-api/site_source/" + str(source_id)

    payload = "{\"id\":" + str(source_id) + ",\"site_id\":" + str(
        site_id) + ",\"type\":\"ipaddr\",\"content\":\"" + ip_address + "\",\"priority\":\"20\",\"weight\":15,\"created_at\":\"2024-11-25 13:21:23\",\"updated_at\":\"2024-12-01 13:39:13\",\"isEdit\":true}"
    headers = {
        'accept': 'application/json, text/plain, */*',
        'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'authorization': 'Bearer ' + access_token,
        'content-type': 'application/json;charset=UTF-8',
        # 'cookie': 'LeCDN-Client=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJjbGllbnQiLCJleHAiOjE3MzMyOTM5NDcsIm5iZiI6MTczMzI3MTM0NywianRpIjoiNDEifQ.lpSIjvtVGE7wcxZgNF2upZiZ8QsPh2CYajevHqgsjzg; sidebarStatus=0',
        'origin': 'https://scdn.ddunyun.com',
        'priority': 'u=1, i',
        'referer': 'https://scdn.ddunyun.com/',
        'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"macOS"',
        'sec-fetch-dest': 'empty',
        'sec-fetch-mode': 'cors',
        'sec-fetch-site': 'same-origin',
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'
    }

    response = requests.request("PUT", url, headers=headers, data=payload)

    js = response.json()
    if js['code'] == 0:
        return js['data']
    else:
        print('[E] 发生错误:', js['message'])
    return None


def add_source(access_token, site_id, ip_address):
    import requests

    url = "https://scdn.ddunyun.com/prod-api/site_source"

    payload = "{\"type\":\"ipaddr\",\"content\":\"" + ip_address + "\",\"priority\":\"20\",\"weight\":15,\"isEdit\":true,\"site_id\":" + str(
        site_id) + "}"
    headers = {
        'accept': 'application/json, text/plain, */*',
        'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'authorization': 'Bearer ' + access_token,
        'content-type': 'application/json;charset=UTF-8',
        # 'cookie': 'LeCDN-Client=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJjbGllbnQiLCJleHAiOjE3MzMyOTM5NDcsIm5iZiI6MTczMzI3MTM0NywianRpIjoiNDEifQ.lpSIjvtVGE7wcxZgNF2upZiZ8QsPh2CYajevHqgsjzg; sidebarStatus=0',
        'origin': 'https://scdn.ddunyun.com',
        'priority': 'u=1, i',
        'referer': 'https://scdn.ddunyun.com/',
        'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"macOS"',
        'sec-fetch-dest': 'empty',
        'sec-fetch-mode': 'cors',
        'sec-fetch-site': 'same-origin',
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'
    }

    response = requests.request("POST", url, headers=headers, data=payload)

    js = response.json()
    if js['code'] == 0:
        return js['data']
    else:
        print('[E] 发生错误:', js['message'])
    return None


def update_domain_source(domain_list, new_ip_address):
    token = login()
    print('[T] 获取到 token:', token)
    # 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助
    site_list = get_site_list(token)
    # new_ip_address = '123.234.187.19'
    # print(site_list)
    for s in site_list:
        # print(s['domain_name'])
        dn = s['domain_name']
        site_id = s['id']
        if dn in domain_list:
            source_list = s['sources']
            # print(source_list)
            print('-' * 100)
            print('[U] 时间:', datetime.now())
            print('[U] 更新域名配置:')
            print('[U] 域名:', dn)
            ip_count = 0
            for sl in source_list:
                source_id = sl['id']
                # site_id = sl['site_id']
                ip_address = sl['content']
                try:
                    if sl['type'] == 'ipaddr':
                        print('[U] 旧 IP 地址:', sl['content'])

                        # edit_source(token, site_id, source_id, ip_address)
                        if ip_address != new_ip_address:
                            print('[U] 更新:正在更新 ip 地址:123.234.187.19')
                            edit_source(token, site_id, source_id, new_ip_address)
                        else:
                            print('[U] 忽略:IP地址无变化')
                        ip_count += 1
                    else:
                        print('[D] 删除:删除域名回源:', ip_address)
                        delete_source(token, site_id, source_id)
                except Exception as e:
                    print('[E] 发生异常:', e)
            # 如果不存在 IP 地址回源 添加 ip 回源
            if ip_count == 0:
                print('[U] 添加:添加IP地址回源:', new_ip_address)
                add_source(token, site_id, new_ip_address)
            print('*' * 100)

    print('[U] 更新完成')
    print('#' * 100)


def print_usage():
    print('*' * 100)
    print('盾云 SCDN 回源地址配置工具')
    print('说明:用于更新盾云 ip 地址回源,解决域名回源导致的延迟问题')
    print('by: obaby')
    print('https://oba.by')
    print('https://h4ck.org.cn')
    print('#' * 100)

if __name__ == '__main__':
    print('*' * 100)
    print('盾云 SCDN 回源地址配置工具')
    print('by: obaby')
    print('https://oba.by')
    print('https://h4ck.org.cn')

然后在需要更新 ip 地址的地方通过下面的代码调用即可:

from baby_dunyun import *

if __name__ == '__main__':
    domain_list = [
        "image.dlj.kim",
        "nai.dog",
        "image.h4ck.org.cn",
        "wiki.guimiquan.cn",
        "baby.lc",
        "danteng.me",
        "loli.gifts",
        "lang.bi",
        "da.bi",
        "zhongxiaojie.cn",
        "oba.by",
        "zhongxiaojie.com",
        "lang.ma",
        "dlj.kim",
        "h4ck.org.cn",
    ]
    new_ip_address = '123.234.187.19'
    update_domain_source(domain_list, new_ip_address)

运行效果:

此工具仅支持盾云 scdn,https://scdn.ddunyun.com/#/dashboard

双城记

2024年12月2日 11:11

早在一个月之前,老太太的生日就提上了日程。合计着哪天过生日,每年为了迎合大家的时间,都会选择一个周末提前过。然而,今年不同,自从灵儿的大姐开了养生馆之后,自由时间越来越少,也难得凑到一块。为此,老太太还颇有微词,然而,生活哪里又容易。谁还不是为了那几毛钱而奔波。

为此,也只能选在生日当天了。主要还是为了迎合大姐的时间,周五她要去县城接孩子。从六年级让孩子回到老家县城上学,到现在已经高三了,眨眼间也都成了亭亭玉立的大姑娘,而明年就要高考了。县城的教育产业,也算是解决了大姐的教育难题。

周五一早送宝子去上学之后,灵儿就准备驱车回老家。经过两个小时的奔波终于到家了,而此时,所有的客人算是都到齐了,每年老太太过生日的时候,大舅、舅妈、三姨,总会来一块吃个饭,这个习惯也坚持了好多年了。而姐姐们也都到齐了,不过,因为是周五的缘故,所有的小朋友都在上学,少了一些喧嚣。

农村的冬天跟夏天一样难熬,没有空调和没有炉子的屋子一样,都让人想逃。熟悉了城市的那种温度之后,有时候在那种酷热或者寒冷的环境下,内心甚至有一种本能的逃避的苗头。好在今天太阳挺大的,也没什么风,在院子里晒着,反而有种暖暖的感觉。

老太太住的那间房子,照旧依然是生了炉子。就靠炉子提供的温度来躲过冬天的寒冷,屋里人有些多,找个落脚的地方都有些困难。灵儿不想在里面挤着,拿了个小马扎跑到了院子里,坐在月台上,看三姐在那里挑苹果。这些苹果虽然摘下来有些日子了,但是套在上面的袋子还没有拆掉。拿过来的那些都是苹果商贩因为个头小而不要的,拆掉纸袋之后,淡黄色的果皮呈现了出来,看起来竟然蛮好吃的样子。

吵吵嚷嚷一个小时就过去了,驱车前往镇上的饭店吃饭。已经好多年不在家里做饭了,人太多,也没有那么大的桌子。至于是谁做饭也是个大问题,之前都是大姐夫做,连续做了好多年。而近些年,老太太的口味变化太大,在家里做饭已经到了不管怎么做,都做不到她心里去了。没能吃的菜,所以索性不如去外面,让其他人来解决这个问题。

灵儿跟三姐准备早一步出发,去镇上的学校接孩子们过去吃饭。然而在倒车的时候,灵儿忽然感觉后轮一沉,感觉应该是掉到了马路牙子下面了。然而,却也没什么办法,调整下方向,伴着刺耳的摩擦声,把轮子从马路牙子下面给拉上来了。到学校门口的时候,看了下,轮圈也给磨花了。

女司机,就是女自己,太 tm 不靠谱了。可能也是灵儿最近用脑过度了吧,最近的新项目投入了太多的精力,感觉头发都少了,有时候感觉脑子真的不好使。并且换车 之后,总感觉车头长了很多,每次在这个狭小的空间倒车的时候,总是心里各种不自信。

路边的路,右前方的树,右后方的深坑,都在考验着这个女自己的技术。下午返程回家的时候,从路边开出来,又差点被飞速开过的比亚迪给撞上,看来脑子确实是不太够用了。竟然都疏于观察,上次出现这种情况还是好多年前,项目攻坚的时候。也可能是老了,反应变得迟钝了。

有时候老太太在聊天的时候,灵儿总是很矛盾,想聊聊,但是又找不到话题。在聊天的时候,也确实能感觉到,老太太的记忆力衰退严重了。

所有的人都走了,就剩下灵儿跟老太太,“中午他们给煮没煮面条,咱们是不是没吃啊”老太太问。

“煮了啊,那么一大盆呢,给你盛上面,你还发表了一番言论不是?”灵儿答道。现在已经到了,中午做过的事情,下午就完了,甚至刚做过的事情,转眼间就忘了。时间也在摧残着老太太仅有的记忆能力。然而,一些特殊的记忆以及话题,就成她每次都要提的事情。吃饭的时候说道,现在也过得挺好的,我恨就恨老家伙死的太早。她说的老家伙是灵儿的父亲,眨眼间已经过了二十多年。作为那个懂事的孩子,这么多年,灵儿不管在外面怎么漂泊,怎么凄苦,其实家里人从来都不知道,她也不曾提过。只是偶尔那么几次在醉生梦死间,才看到那漫漫黑夜中,那一丝幽光,时明时暗。就靠着这微弱的希望,她磕磕绊绊的走到了现在,而这一切,她所有的亲人都不曾知道,因为她知道她的那些姐姐们过得也并不好,即使说了也没什么能帮上自己的,更何况,那时候太多的人等着看这个大学生的笑话,就等她混的一塌涂地。那个光鲜亮丽的大学生,其实很多年在外面活的不如一条狗。

每次聚会的时候,老太太总会喝点,也喝不多,这次还是一样,灵儿照例买了两瓶茅台王子,还有几箱青岛啤酒。当然,老太太的那个酒量也不大,每次也就二两酒就能喝的话多起来。这些年,喝开心了之后,总是回忆自己年轻的时候,可能,老了之后也的确没什么好值得回忆的吧。

周六中午三姐又来了,带着孩子过来跟二姐家的孩子一起玩,写作业。吃饭的时候,老太太又开始说一些自己的观点,还是跟昨天一样:“我觉得现在不读书最好,孩子就得在身边待着”

每当灵儿听到这个论断的时候,内心总是掀起一层波澜。人这个东西,的确是太善变了,早几年,老太太跟自己的外甥说的还是让他们都跟着灵儿学习,好好学习有目标,考个好大学。现在,眨眼就就成了上学无用。每当听到这么说的时候,灵儿总是忍不住要怼她几句,“不上学,留在身边干嘛?喝西北风?你不去看看那些和你一样大岁数的有几个跟你一样这么悠闲,不都在拼命给自己的儿女挣钱?”

“你看那些下劳务的,跟你一个岁数的有的是”三姐也说道。

“孩子不用学太好,也不能太有本事,太有本事了,见都见不到……”老太太继续说道。

“没本事,谁养他?你养?”灵儿反问道。

只是这种争论从来也没有结果,自然,灵儿也知道跟她争论这些没用。如果不是被所谓的亲情绑架,灵儿或许现在仍然在厦门,或者是另外的城市生活。只是,现在她也不恨,也没什么想法了。人生,在某刻忽然变得无欲无求了。

二姐和三姐家的孩子都在写作业,二姐家的孩子已经上三年级,农村教育三年级起点的英语课也开课了。不过这个课程,让这个从来没有接触过英语课的小朋友有些无所适从,拿过小妮手里的英语卷子,前半部分是听力。老师也没有分享听力文件,所以这一部分自然是做不了的。后面的笔试部分,直接开始区分单词的分类,简单的阅读理解。如果不是靠她手里的点读笔,这长长的一段英文对她来说,无异于天书。

这个世界想要抛弃你,从来都不会咨询你的意见。这样的英语无异于将入门的门槛提高了很大的一个高度。没有基础的孩子,想跟上这个英语学习的步伐,也只能靠强大的天赋了。青岛,在今年也开始使用三年级起点的英语教材了。不过,好在,在这改革之前,宝子已经学会了很多,并且之前完全是按照青岛的一年级起点英语施教。当然,对我来说,几年级起点的英语,对于自己和宝子来说,都不是难题。

吃完饭,下午喝点茶水,休息一下。周六下午,灵儿就准备走了,主要是也该剪头发了,依然约的县城的那家理发店,四点半。两点半就从老家离开了,到县城三点多,回家打开空调,看了下室温只有 14 度,虽然没那么冷。空调开了两个小时之后温度终于到了 18 度。

晚饭一个人也不想出去吃,点了个烧烤外卖。

就这么点东西,80 多块钱,属实有些离谱了,更何况那瓶大窑还是我自己的。最终这些东西也没全部都吃掉,吃到一半的时候感觉是少了东西。但是这都吃了一半了,也不少清点到底是少了什么东西。烤的五花肉也的确是难吃,最终,可能也就吃了一半而已。

一个人的时候,总是有大把的时间可以挥霍,吃完了,到公园转了一圈,不过一个人逛公园的确没什么意思。

不过在县城,冬天穿短裤的确实没有,在一路上回头率都百分之百了,这就让人很尴尬。公园依然是绿色的灯光,这个绿色的灯光灵儿的确也有点欣赏不来,路上都是一对对情侣或者是带着孩子的一家人,一个人逛公园的,可能也就灵儿自己吧。

然而,到家也才九点多,冬天的夜总是格外的长一些。长夜漫漫,孤枕难眠,那索性不如再找个地方去打球吧。没什么球友,也没什么朋友,其实一个人玩也蛮有意思的,灵儿想。

终于,一个多小时之后,可以回家睡觉啦。然而,第二天早上,却没有睡到八九点。灵儿做了一个梦,梦到自己去拿快递的时候,粉皮被别人开走了,然后灵儿到处去找粉皮,马上就要去报警的时候,终于醒了,看了下时间才七点多。

那个快递,早在周五就送到了,家里的路由器莫名其妙就坏了。刚好过保,寄回去修,过了几天售后打电话反馈,需要将设备寄回厂商,预计得一个多月。如果不返修,可以给你换新的,但是,现在那个型号没货了。要么加价换其他的型号,要么换个便宜的。

然而,现在家里的网络确实比较卡,灵儿也等不了那么久。加了 300 多块钱换了新路由器,只是这个新路由器只有 4 个 lan 口,原来的八口路由器+8 口交换机刚好够用,而现在路由器只剩四口了。只要再购买一台 16 口的交换机。昨晚这一切,总感觉自己被套路了。这换新,又忽悠自己买新设备了。

周日一早还得赶回去,给小姐姐的妈妈过生日。这一个周末,连赴两个生日宴。到家顺路从京东的网点拿上快递,回到家,把从老家带回得来东西搬到楼上。小朋友看电视的时候,一边看一边吆喝,因为那个路由器实在是性能不大行,电视都开始卡了,缓冲都得半天。

吃完饭,小朋友去睡觉了。赶紧去 更换设备,刚看到交换机,感觉小了点,好在给的支架是延长的,还能上机柜,不然这个的确有且蛋疼了。

而至于整理网线,也确实没下得去手。因为后面的电源线也有点多,不全部拆掉,也梳理不清楚,后来嘛,就勉强稍微整理了一下。而现在网速基本是 ok 了。那个次卧的路由器,由于是百兆线连过去的,所以,撑死也就是百兆带宽了。

到现在终于崩溃了几天的博客和各种业务总算是恢复了。而此时,蛋糕也切好了,正好可以吃一块蛋糕。

人生,不过是从一个城池奔赴另外一个城池,从一场宴席,奔赴另外一场宴席,修正一个个的错误,一个个的问题。

只是现在,感觉时间真的好少,过完这个月,得找时间再去拍写真了。

Baby shark 大战迅雷

2024年11月26日 09:26

晚上在电影站闲逛,想下载点新的小片片,结果,迅雷死活不给下载。

下载的时候提示:“疑似包含违规内容,无法下载”。这就 tm 离谱了,你作为一个下载工具,你 tm 关我下载什么东西呢,还疑似,疑似你妹啊。

重试几次就变成了:任务包含违规内容,无法继续下载。

这 tm 就离谱,在我的电脑上还能让你这么猖狂?

猜测是换了路由器之后,之前有些域名屏蔽可能失效了,但是之前的规则现在也不记得了,网上随便搜一下,很多改 hosts 的方法,但是内容都是吵来吵去的,屁用没有。这就是中文互联网的处境,垃圾内容复制粘贴,连标点符号都不带改的,fuck!

既然别人的不靠谱,那就只能靠自己了,请出 baby shark ,额, 不,错了,是 wireshark。选择网卡进行抓包。

开始有数据之后,重试几次下载,此时依然会提示无法下载。在wireshark 上面的筛选框输入 http 协议进行过滤,当然直接筛选 dns 查询也可,这里还是 http 直观。直接找 post 请求,看发送数据,左侧展开超文本传输协议内容,查看请求 host,这个就是要屏蔽的域名了。至于右侧发送的数据是啥,十六进制的,管他呢。问为什么是这个请求,问就是经验,其他的 get 都能看懂,就找不是明文的屏蔽就完了,顺便可以找下广告的域名一块给 k 了。

就是下面两行了:

127.0.0.1 hub5btmain.v6.shub.sandai.net 
127.0.0.1 api-web-game-ssl.xunlei.com

再加上网上流传的那个文件内容(虽然没有屁用),拼成下面的样子,全部写入 hosts 文件,重启迅雷。

127.0.0.1 hub5btmain.sandai.net
127.0.0.1 hub5emu.sandai.net
127.0.0.1 upgrade.xl9.xunlei.com
127.0.0.1 hub5btmain.v6.shub.sandai.net
127.0.0.1 api-web-game-ssl.xunlei.com

再次开始任务就可以愉快的下载了:

那个没有速度的真的是因为没有资源,😂,另外别好奇问这是个什么东西,问就是不知道。谁懂男人的那些恶趣味呢!

 

莫名其妙

2024年11月25日 15:21

不得不说最近这个天是越来越冷了,本来都不准备写东西了。就写一篇技术文拉到,象征性的摸摸鱼,然鹅,事情的发展总是能出乎意料。

平淡的周末依然平淡,周五去给宝子开家长会,老师好一通表扬,让我也不由得心花怒放。说宝子字写得好看,有时候批改作业或者心情不好的时候就去会看宝子的作业,瞬间就让人心情愉悦了。不过说实话,宝子的字写的确实是好看,哪怕跟现在自己写的字相比都毫不逊色。这也不是第一次老师当着那么多人的面表扬宝子了。在家长会之前,还专门设置了个区域,让大家去看那些优秀的作业。

晚上,看了下第二天的小记者活动,原本已经报名满额的关爱罕见病的活动,竟然又空出来一个,正好就可以重新报名参加这个活动。留住海鸥的活动就不再参与了,毕竟,那个距离也有些远。

排队领材料的时候,宝子依然一副漫不经心的样子。就那么站着,也不着急,有时候还东张西望,前面有人插队也不会去阻止。这一点真的不知道是遗传的谁,那种与世无争的状态,有时候真的让人看了来气。完全不知道维护自己的权利和利益,也从来不知道竞争是什么,这个好心态有时候也让自己无比的佩服。

拿到材料,看的还蛮认真的。后面进到屋里做手工,家长不让陪同,也就只能在外面候着了。虽然已经是冬天,但是在风和日丽的天气里,晒着太阳,懒洋洋的暖暖的倒是也颇为自在。

做完手工,后续又来了一位医生,给小朋友讲解罕见病的相关知识,还有采访环节,当然,不出意外,宝子还是在最外围。嗯,就是这么波澜不惊。

不过这短短的一个小时,竟然又认识了一个姐姐,跟那个小姐姐玩的还挺开心的。活动结束,两个人还又去游乐场玩了一个多小时。

宝子看新闻的时候,总说想去滑雪了,从高德地图看了下滑雪场,都还没开放。不过风和日丽的暖天应该也不会太多了,再有一个多月应该就可以去滑雪了。下午带宝子去公园骑自行车,有朋友推荐国学公园,长途跋涉之后直奔国学公园。

然而,公园外并没有共享单车神马的,只能宝子一个人骑自己在后面跟着,不过这个公园面积的确不大,不一会儿就转了一圈了。

不过这个小圆子好处是人不多,拍婚纱照的蛮多的。

意犹未尽,只能去另外一个公园,奥林匹克公园。

还有在草丛里吃草的猫咪:

在湖里的游船,后面跟着个大喇叭一边走一边喊:水深四米,请勿跳水……

不过真的有人会跳水吗?😂

下午回家,宝子的姥姥开始数落,:”看你们带孩子出去,把孩子给累的“

问题是她不吃饭 ,纯粹就是不想吃,跟我们没关系。

晚饭象征性的对付了过去,我也没怎么吃东西就喝了一碗豆浆。早上起床发现手机断网了,打开wifi 界面,其实所有的无线都无法上网,这尼玛就神了。

看了下网站,果然挂了,而服务器状态监控,家里的主机也都离线了。好不意外,肯定是家里的网络出问题了。重启路由器,无效,reset 依然无效,开始怀疑是不是宽带出问题了。

光猫的光信号指示灯是灭的,然而,打开电视,iptv 却是正常的。这尼玛就离谱了。

打开电脑,获取 ip 地址依然是 168.254 网段的什么东西,这么看来是彻底完犊子了。看了下二手东的购买日期,去年的双十一,刚好过保,哈哈哈。这尼玛,到公司不死心继续折腾,发现竟然可以延保,通过延保服务提交售后,最后总算是解决这个问题了。不过需要把路由器寄回去。

中午回去翻箱倒柜,把之前的路由器拿出来,先换上勉强用着,旧路由器拆下来,准备寄回。

看着这一堆线真的头大,完全不想折腾啊。

顺丰下单,两点寄件,现在三点半了还没来取,哎?人呢。

Django 打包为 docker 镜像

2024年11月25日 13:51

之前也想过将 django 项目打包成 docker 部署,但是由于之前的项目过于庞大,用到了系统的定时任务等各种系统服务,不知道打包成 docker 之后相关的服务是否依然能够启动,所以并未实施。

前几天做的我的足迹地图,项目相对来说比较独立,没有其他的依赖项,正好可以尝试一下。

首先在项目下创建 Dockerfile,写入以下内容:

# 使用官方Python运行时作为父镜像
FROM python:3.8.18-slim

# 设置工作目录
WORKDIR /app

# 将当前目录内容复制到位于/app中的容器中
COPY . /app


# 安装项目依赖
RUN pip install --no-cache-dir -r requirements.pip -i https://pypi.tuna.tsinghua.edu.cn/simple

# 暴露端口8000,与Django的默认运行端口一致
EXPOSE 10086

# 定义环境变量
ENV NAME=Django

# 在容器启动时运行Django的manage.py命令
CMD ["python", "manage.py", "runserver", "0.0.0.0:10086"]

网上代码来回抄,第二行都是FROM python:3.8-slim 如果这么写会导致下面的错误:

PS E:\Pycharm_Projects\BabyFootprintV2> docker build -t baby-footprint:1.0 .
[+] Building 21.2s (2/2) FINISHED docker:desktop-linux
 => [internal] load build definition from Dockerfile 0.0s
 => => transferring dockerfile: 568B 0.0s
 => ERROR [internal] load metadata for docker.io/library/python:3.8-slim 21.1s
------
 > [internal] load metadata for docker.io/library/python:3.8-slim:
------
Dockerfile:2
--------------------
   1 | # 使用官方Python运行时作为父镜像
   2 | >>> FROM python:3.8-slim
   3 |
   4 | # 设置工作目录
--------------------
ERROR: failed to solve: python:3.8-slim: failed to resolve source metadata for docker.io/library/python:3.8-slim: failed to do request: Head "https://registry-1.docker.io/v2/library/python/manifests/3.8-slim": dialing registry-1.docker.io:443 container via direct connection because has no HTTPS proxy: connecting to registry-1.docker.io:443: dial tcp 69.63.186.31:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.

直接访问上面的网址docker.io/library/python:3.8-slim会发现根本没这么东西,所以要改成FROM python:3.8.18-slim

搜索一下,会有教程提示先下载 python3.8的 docker:

PS E:\Pycharm_Projects\BabyFootprintV2> docker pull python:3.8.18-slim
3.8.18-slim: Pulling from library/python
8a1e25ce7c4f: Pull complete
1103112ebfc4: Pull complete
b7d41b19b655: Pull complete
6a1ad0671ce8: Pull complete
de92c59aadaa: Pull complete
Digest: sha256:e796941013b10bb53a0924d8705485a1afe654bbbc6fe71d32509101e44b6414
Status: Downloaded newer image for python:3.8.18-slim
docker.io/library/python:3.8.18-slim

3.8.18是 ok 的,此时重新 build 即可:

PS E:\Pycharm_Projects\BabyFootprintV2> docker build -t baby-footprint:1.0 .
[+] Building 214.6s (9/9) FINISHED docker:desktop-linux
 => [internal] load build definition from Dockerfile 0.0s
 => => transferring dockerfile: 571B 0.0s
 => [internal] load metadata for docker.io/library/python:3.8.18-slim 0.0s
 => [internal] load .dockerignore 0.0s
 => => transferring context: 2B 0.0s
 => [1/4] FROM docker.io/library/python:3.8.18-slim 0.1s
 => [internal] load build context 0.9s
 => => transferring context: 43.30MB 0.8s
 => [2/4] WORKDIR /app 0.1s
 => [3/4] COPY . /app 0.2s
 => [4/4] RUN pip install --no-cache-dir -r requirements.pip -i https://pypi.tuna.tsinghua.edu.cn/simple 212.0s
 => exporting to image 1.4s
 => => exporting layers 1.4s
 => => writing image sha256:cba073b574f88f19be7487b29612e19b9826ab99e7b54ea748bd5df22e83e1a0 0.0s
 => => naming to docker.io/library/baby-footprint:1.0 0.0s

编译变成,就可以像 docker hub 推送镜像了,不过首先需要设置 tag,如果直接推送会提示下面的错误:

PS E:\Pycharm_Projects\BabyFootprintV2> docker push baby-footprint:1.0
The push refers to repository [docker.io/library/baby-footprint]
04013169f44d: Preparing
f7c443286fad: Retrying in 5 seconds
fd749af069d5: Retrying in 5 seconds
3482d4cd60de: Retrying in 5 seconds
370c0e78e3ea: Retrying in 5 seconds
a74bee0a48a5: Waiting
c8f253aef560: Waiting
a483da8ab3e9: Waiting
denied: requested access to the resource is denied

这个提示也比较坑人,由于 docker 被屏蔽,我一直以为是网络连接问题,直到后来才发现是路径问题。

通过下面的命令设置 tag 后 push:

docker tag baby-footprint:1.0 obaby/baby-footprint:1.0
PS E:\Pycharm_Projects\BabyFootprintV2> docker push obaby/baby-footprint:1.0
The push refers to repository [docker.io/obaby/baby-footprint]
04013169f44d: Pushed
f7c443286fad: Pushed
fd749af069d5: Pushed
3482d4cd60de: Pushed
370c0e78e3ea: Layer already exists
a74bee0a48a5: Pushed
c8f253aef560: Pushed
a483da8ab3e9: Layer already exists
1.0: digest: sha256:0d0c0989a64cc3f3e192e5c8e7bc4931676d49ab66d810061a1daec6b1a6af58 size: 2000

受限于网络问题,可能会 push 失败,多重试几次就 ok 了。

最后就可以直接 docker 安装运行啦:

docker push obaby/baby-footprint:tagname

修理工,修理工……

2024年11月20日 09:48

 

宝子刚上小学的时候,给宝子买了一个自动削笔刀。当时为了买这个削笔刀,还对比了各种产品,最后选择了这么一款。之所以选择它是因为他支持不同粗细的铅笔,比较粗的三角铅笔,比较细的圆柱铅笔都可以削,有了这个东西的确方便了不少,那些三角铅笔用手动削笔刀削一次能累死人。

然而,这段时间发现削笔刀出问题了,有时候铅笔插不进去,有时候插进去没反应,刚开始以为是里面的机械结构脏了或者进去脏东西了。清理之后好了几天,后来就又不行了,再次把电机清理了一下,稍微好了那么几次,就又进入了故障中。

不过,现在如果没有开始削笔,朝着桌子磕两下就开始工作了。我猜测是那个电机出问题了,因为这个东西构造真的没那么复杂。

从淘宝上照着图片买了两个新电机,花费 11 块钱。昨天晚上到了,开始修理之路。

参考旧电机的接线,把新电机的线路给焊接上,每年出场一次的电洛铁又派上用场了。

然而接好电机,安装测试的时候却死活不启动。这尼玛就神奇了啊。难道给搞坏了?

启动失败只能改变思路,尝试用新电机的碳刷替换旧电机的,把接好线的电机碳刷拆下来,旧电机的转子给装上去。不过旧电机的碳刷磨损的确比较哦严重,磨掉了一半了。

组装后重新装机,这次终于成功啦。

用各种铅笔测试完全 ok。这个新碳刷,感觉还能再战一年。

我的足迹【终极完整版】 — 我又更新啦!!!

2024年11月18日 13:41

我的足迹这个东西,周末实现的方法,终究感觉不高级的样子。就是看起来平平无奇,除了那几个点点,剩下的貌似也没什么意思。

扶苏给留言写到他也做了一个足迹页面,说可以作为参考。去参观膜拜了一番,感觉 js 实现的就是要高级一些。

为什么?因为 js 实现的 tm 能动啊。

原本不想写 js 的,主要是懒,实在是不想写代码。但是,但是看到这个东西,难免心动,然后就食言了。我又做了一个。

然后,还是先来看效果吧:

这个是不是看起来就高级了一些?主要是支持点击事件。

代码中定义了三组内容:

locations 点亮城市
passed_locations 途径城市
out_China_locations 国外城市 这一部分加入了经纬度信息,百度地图的反向查询,查出来的坐标是错误的,所以就独立处理了。
    var out_China_locations = [{
        city: "清迈",
        text: "泰国清迈",
        mark: "已经游玩",
        longtitude: 98.96095,
        latitude: 18.79325
    },
    {
        city: "清莱",
        text: "泰国清莱",
        mark: "已经游玩",
        longtitude: 99.72588,
        latitude: 19.903138
    }];

另外,在使用改代码的时候,还需要找两个头像文件,分别用来进行地图打点:

// 创建小车图标
                    var myIcon = new BMapGL.Icon("https://h4ck.org.cn/avatar/avatar_circle-256.png", new BMapGL.Size(26, 26));
                    // 创建Marker标注,使用小车图标
                    // var pt = new BMapGL.Point(116.417, 39.909);
                    var marker = new BMapGL.Marker(point, {
                        icon: myIcon
                    });

点击时间代码,需要修改域名:

var city = locations[i].city;
            var text = "\r\n <a target='_blank' href='" + "https://h4ck.org.cn/?s=" + locations[i].text + "'>  https://h4ck.org.cn/?s=" + locations[i].text + "</a>";

原来的效果:

修改之后,高级感是不是瞬间就有了呢,嘻嘻。

开源代码地址:

https://github.com/obaby/BabyFootprint

参考文档:

https://lbsyun.baidu.com/jsdemo.htm#cLocation

最终效果预览:

https://h4ck.org.cn/footprint/

 

更新:

上面的内容虽然够用了,但是每次还要更新代码,这多蛋疼啊。所以,我又更新了,这次我直接加了一个后台,哈哈哈

Baby 足迹地图

 

简介:

 

基于百度地图的足迹地图。

功能

 

  • 支持后台添加位置信息
  • 支持添加带gps坐标的位置信息
  • 支持自定义marker图标

安装运行:

docker运行:

docker run -d -p 10086:10086 obaby/baby-footprint:1.0

 

python 3.8 – 3.10

pip install -r requitements.pip

启动服务 建议使用nginx反代:

 

python manage runserver 0.0.0.0:10086

后台登录地址:

 

http://127.0.0.1:10086/admin/

登录账号:obaby
默认密码:123456

修改:

 

前端页面修改js,static/js/footprint.js 编辑以下代码替换默认图标:

var location = locations[i];
var city = locations[i].name;
var text = "\r\n <a target='_blank' href='" + "https://h4ck.org.cn/?s=" + locations[i].text + "'>  https://h4ck.org.cn/?s=" + locations[i].text + "</a>";
var mark = locations[i].mark;
var marker_image = "https://h4ck.org.cn/avatar/avatar_circle-256.png";
if (location.is_passed ){
    marker_image = "https://h4ck.org.cn/avatar/avatar-2.png";
}

截图:

 

后台首页:

 

添加地点:

 

(如果不带gps坐标或者坐标无效,将会通过百度地图api解析gps坐标)

列表:

 

首页:

 

扩展内容 nginx反代:

server
    {
        listen 443 ssl http2;
        #listen [::]:443 ssl http2;
        server_name footprint.h4ck.org.cn ;
        index index.html index.htm index.php default.html default.htm default.php;
        root  /home/wwwroot/footprint.h4ck.org.cn;

        ssl_certificate /home/lighthouse/footprint.h4ck.org.cn_nginx/footprint.h4ck.org.cn_bundle.pem;
        ssl_certificate_key /home/lighthouse/footprint.h4ck.org.cn_nginx/footprint.h4ck.org.cn.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
        ssl_session_cache builtin:1000 shared:SSL:10m;
        # openssl dhparam -out /usr/local/nginx/conf/ssl/dhparam.pem 2048
        ssl_dhparam /usr/local/nginx/conf/ssl/dhparam.pem;

        include rewrite/none.conf;
        #error_page   404   /404.html;

        # Deny access to PHP files in specific directory
        #location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }
location /static/ {
       alias    /home/wwwroot/babyfootprint/static/;
}

location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;

        proxy_pass http://127.0.0.1:10099;
        proxy_http_version 1.1;
proxy_set_header Accept-Encoding "";
}
        access_log  /home/wwwlogs/footprint.h4ck.org.cn.log;
    }

11.19 更新内容:

增加文章链接,打卡图片链接:

新效果图:

预览地址:

https://footprint.h4ck.org.cn

代码地址:

https://github.com/obaby/BabyFootprintV2

腰麻 腿麻 神经痛

2024年11月18日 10:35

今年宝子生日这天,阴历跟阳历正好差一天,周五一天,周六一天。之前过生日,就是简单吃个饭,吃个蛋糕,送个小礼物神马的。也没有做一些特殊的准备。

几年,想着给宝子好好准备一下,提前买好了布置场景的道具,周四晚上宝子睡了之后,就开始布置场景。虽然看起来简简单单的布景,但是折腾下来还是折腾了一个多小时。

宝子说周六想要穿新鞋子,临时从网上买依然来不及的,中午趁着午饭的功夫去商场搂了一眼,也没发现合适的,不过嘛,人是真的不少。

宝子想买一双高筒的小靴子,但是转了一圈都没发现,只好作罢。

往回走的路上,发现路边有个卖煎包的,正好就可以解决午饭问题啦。买了五个宝子,打包的大姐拿了个打包盒,哐哐一顿装了五个牛肉的。我直接都看懵了,说:“我就要了两个牛肉的”

大姐停下继续往里装的动作,说,“啊,两个?哦哦,我把价格看成个数了”

旁边的一个大哥说,“你让她装,别告诉她”

“我也吃不了那么些个啊”我说到。

大姐继续去装其他的,废了半天功夫,总算是数明白了。不过,等回到家之后,吃完一个了,发现不大对,因为盒子里还有五个,这数来数去还是数错了。

不过宝子吃起来味道还是可以的。晚上只能换另外一个商场继续去买,晚上带着宝子到乐客城转了一圈,总算是买到了心仪的小靴子,不过价格还是略贵一些 350。这小靴子就得周末天天穿了,不然又浪费了这个钱了。

周日的时候,天气看起来还是蛮不错的,风和日丽。吃完饭带宝子去户外的游乐场玩玩,中午的时候人还稍微少点。等下午三点钟,就满了人了。

这几年,新建了很多户外游乐场。小孩子能玩的地方越来越多了,体验感也算不错。

跟着宝子上蹿下跳。

回去的时候,在停车场小姐姐说,你车上这是水泥吗?到前面一看,果然是一块块凝固的水泥,但是回想最近的行程也没去过工地或者施工的地方啊。

想扣已经是扣不下来了,回到家,想着怎么去掉这些东西。看晚上有说用洁厕灵神马的,搜了一下发现还有专门去除水泥的清洗剂。之前开小六子的时候,回老家路政正在用沥青铺路,一阵狂风吹来,车上甩满了沥青,刚开始以为是什么泥水之类的,开了下雨刷直接人都傻了。黑乎乎的一篇,最终还是靠柏油沥青去除剂给洗掉的。

不过这次这些东西感觉用那个不行了,想着要么买瓶水泥清洗剂,要么用白醋试试,正好家里还有一瓶白醋,直接带上水,带上醋,再次回到停车的地方。

用卫生纸浇上醋,糊到水泥上。

等个几分钟,白醋湿透了水泥,此时就可以小心扣一下试试了,如果能扣下来,就扣一下,用水在冲一下。重复几次,就可以把水泥给弄下来了。

最后在用清水冲洗一下就好了。

清洗完回到家之后,发现腰疼的厉害。垫着枕头靠了一下,发现更加的严重了。首页开始哆嗦,竟然开始害冷。冲了两包 三九,喝下去就进了被窝。到七八点钟已经完全睁不开眼了,一觉昏昏沉沉的睡了过去。等再次醒来已经是夜里两三点了。

不过倒是也快,浑浑噩噩的一觉睡过去,竟然天就亮了,不过好在此时所有的不适感已经基本没有了。活蹦乱跳的看来又活过一天。

上午到公司停好车之后,终于找到水泥的来源了,不知道是物业还是什么人,在停车场用水泥修补路面,水泥溅出来落到了车上,这真尼玛离谱。

这一地的水泥印子,忽然感觉腰又开始疼了。

创建一个我的足迹地图

2024年11月16日 17:41

关于我页面,有个个人足迹的图片。

这个图片最早是通过google maps的足迹地图来生成的。

谷歌地图

然而,好景不常,这个东西现在也下架了,今年又去了很多地方,但是这个图片要更新就变得非常麻烦,总不能用ps往上打点吧?这也有点太智障了。于是想着通过地图来实现这个功能,高德或者百度,上午试了一下高德,发现免费的静态地图,最多只能添加10个marker,这尼玛是出来恶心姐姐我的吗?就离谱。

下午看了下百度的要好很多,于是下午折腾了一下,把足迹点,通过代码拼成url直接添加图片就能显示了,这个还是不错的,最终效果如下:

我的足迹

其中粉色点点是最起码呆过一段时间的,黄色的点点是途径点。

处理的代码也比较简单,不过最开始用的高德,于是gps坐标获取用的高德的api,需要提供高德的key。

静态地图用的百度的,所以又需要百度地图的ak,这个ak必须用服务端的ak哈。全部代码如下,没做配置功能,需要的自己改改代码就行了(运行前 pip install requests 依赖库):

import time

import requests


def amap_geodecode(addr):
    try:
        para = {
            'key': '高德的key',  # 高德地图开放平台申请的key
            'address': addr  # 传入地址参数
        }
        url = 'https://restapi.amap.com/v3/geocode/geo?'  # 高德地图API接口
        req = requests.get(url, para)
        req = req.json()
        print('-' * 30)
        print(req)
        m = req['geocodes'][0]['location']
        print(addr)
        print(m)
    except:
        return None
    return m


# 按装订区域中的绿色按钮以运行脚本。
if __name__ == '__main__':
    url_bast = 'https://api.map.baidu.com/staticimage/v2?ak=<百度的ak>&width=900&height=800&zoom=5&center=103.8319522831,36.0615585627&markerStyles=0xFF0000|0x808000&markers='
    city_list = ['北京','上海','深圳', '东营','连云港','锡林郭勒盟','赤峰','承德','济南','泰安','枣庄','昆明','长沙','湘潭','株洲','日照','威海','烟台','深圳','广州','西安','临沂','潍坊','青岛','大理','清迈','海口','三亚','蜈支洲岛','清莱']
    pass_city_list = ['天津','德州','景德镇','衢州','佛山','无锡']

    print('添加点亮城市:')
    cord_list = []
    visited_marker_style_list = []
    for c in city_list:
        m = amap_geodecode(c)
        if m:
            v = '' + m
            cord_list.append(v)
            visited_marker_style_list.append('m,V,0xFF69B4')
        time.sleep(2)
    print('添加途径城市:')
    for c in pass_city_list:
        m = amap_geodecode(c)
        if m:
            v = '' + m
            cord_list.append(v)
            visited_marker_style_list.append('s,P,0xFFFF00')
        time.sleep(2)

    print(cord_list)
    print('|'.join(cord_list))
    print('最终url:')
    print(url_bast + '&markerStyles=' + '|'.join(visited_marker_style_list) + '&markers=' + '|'.join(cord_list))

别问为啥这么搞,问就是懒得改了,哈哈哈。添加图片直接使用最后的url即可。以后足迹点多了之后,修改list重新生成url即可。

唯一的缺点,不支持国外的坐标,我的泰国的坐标标不上,不过也无所谓了,反正就一个泰国而已。

更多定制化功能,参考百度地图的相关开发文档:

https://lbsyun.baidu.com/faq/api?title=static/prepare

https://lbsyun.baidu.com/faq/api?title=static/markerStatic

https://lbsyun.baidu.com/faq/api?title=static/heightStatic

哪吒监控-多服务器监控与运维工具

2024年11月14日 13:32

前几天在杜老师的聊天室,聊到那些闲着没事到处攻击人的 cc 狗的问题。杜老师扔出来一个链接,并且说道:可以装个监控玩玩,看实时流量神马的。

于是呢,请杜老师写个教程:

杜老师信誓旦旦,表示晚上八点二十发。然后呢,我等了好几个八点二十了也没看到。虽然昨晚杜老师更新了一篇,但是不是教程,哼唧唧。就离谱啊。

终于,实在忍不住了,然后自己照着官网的文档直接安装了一套:

果然男人都靠不整,哼。

具体教程还是等杜老师更新吧,我就不写了。

不过,在安装过程中发现一个问题,不知道是兼容信问题还是神马问题。在 ubuntu 20.04上,通过独立安装的面板,无法正常启动服务,所以建议还是直接 docker 安装,如果是这个系统的话,安装倒是也简单,一行命令,傻瓜式操作:

curl -L https://gitee.com/naibahq/scripts/raw/main/install.sh -o nezha.sh && chmod +x nezha.sh && sudo CN=true ./nezha.sh

剩下的各种配置就更傻瓜化了,不过安装之后发现一个问题。就是自己的网站首页没有 favicon 的小图标,但是杜老师的有:

要解决这个问题也简单,后台修改前台自定义 css,添加以下代码:

<link rel="icon" type="image/x-icon" href="https://s.h4ck.org.cn/static/logo.svg?v20210804">
<link rel="apple-touch-icon" sizes="180x180" href="https://s.h4ck.org.cn/static/logo.svg?v20210804">

然后就促来啦:

完美,嘻嘻。

从《POI》说起

2024年11月13日 09:35

昨天晚上收到杜郎的QQ 消息,发了张截图和一个地址。的确在这之前确实没有看到过任何相关的消息。

正式通报:

在前几天写的文章《天启Z:完结的起点》中,我还说过恶性事件可能会越来越多,不想这才几天这更恶劣的事件就出现了。

问题的本质在于这种无差别犯罪,基本是上无法避免的。反社会人格的恐怖袭击才是这件事情的正常解释。按照 4% 的反社会人格比例(美国),那么周围的这种不确定性因素就可以想象到底有多少了。

在《POI》中,Finch 建立了一套人工智能系统-machine 用来监控各种可能存在的恐怖袭击以及危害人身安全的系统。以便在恶劣事件未发生之前阻止事件的发生。这部美剧,到现在在我的观影记录里面依然是属于满分评价,强烈推荐的。与国内的大多数刑侦类型的电视剧不同(近几年),国外的这种警匪题材的影片,往往更加的写实一些,我说的写实是针对犯罪现场或者凶手心理的侧写。受限于各种审核政策,大尺度剧集在国内自然无法上映。

经常看这种刑侦剧,或者说美式 R18 级别的限制片,给我带来的最大的好处就是,成功的拉低了对于人类这个动物的下限值的期望。各种飞来横祸或者莫名其妙被害,并不需要受害者与凶手有什么交集,自然也不需要什么理由,小姐姐经常说,你这看个恐怖片都能看出人生哲理来。太多人对于人类道德下限其实是没有认知的,而我自己对于这种下限的不断降低,跟自己的道德底线的降低也有关系。

曾经自己也是那种眼里揉不得沙子,黑白分明的人。然而,在这几年过去之后,自己的道德底线也在不断的降低,从黑白分明,依然到了是非混淆的地步。意识到这个问题之后,现在偶尔要做的事情,就是三省吾身,不让自己堕落的太过于严重,也是怕在作死的道路上越走越远。

今天看到有人在推荐《当良知沉睡:辨认身边的反社会人格者》 ,简单的翻看了一部分,感觉写的还算不错。读书,我喜欢的是里面各种变态杀戮或者是恶心恐怖的内容,不喜欢那种长篇大论讲大道理的,最反感的就是那种爹味,我要自己去想,而不是你告诉我。里面对于反社会人格的定义还是有些参考意义的:

如果一个人至少拥有以下7个特征中的3个,那么这个人在临床上就足以被确诊为患有“反社会型人格障碍”:
1.无法遵守社会规范;
2.惯于欺骗和操控他人;
3.行事易冲动,无法提前做出计划;
4.易怒,具有攻击性;
5.毫不顾及自身或他人的安危;
6.一贯不负责任;
7.在伤害、虐待他人或偷窃他人东西之后毫无悔意。
如果一个人同时表现出上述任何3项“症状”,许多精神病学专家就足以据此推定他患有反社会型人格障碍在其他研究人员和临床医师中,有很多人认为美国精神医学学会的定义更像是对“犯罪”(criminality)的描述,而不是对“精神病态”或“反社会人格”的描述。4他们指出,反社会人格者这个群体还有其他一些记录在案的特征,其中一个比较常见的特征就是他们能说会道,表面上很有魅力,可以借此诱惑别人,而这里的诱惑不单单指两性之间的吸引力。反社会人格者身上的这种光辉和魅力,起初让他们看上去比周围的那些正常人更迷人、更有趣。他们比其他人更随性、更热情,在某种程度上更“复杂”、更性感、更令人愉快。这种“反社会人格魅力”有时会伴随一种浮夸的自我价值感,起初可能很有说服力,但仔细观察之后会显得奇怪甚至可笑(比如“总有一天这世界会见识到我的不凡”或是“要知道,我会让你遇到的所有异性都黯然失色”)。另外,反社会人格者比正常人更加渴求刺激,这是他们经常罔顾个人安全做出危险的举动,或在社交、财务或法律方面铤而走险的原因。他们的特色能力是能够诱使别人和自己一起冒险,并以病态性说谎、哄骗以及依附朋友,成为“寄生虫”而著称。不管这类人受过多高的教育或者有多高的社会地位,他们在未成年时期都可能出现过行为问题,有时还可能包括药物滥用或青少年犯罪,而且他们永远都不认为自己应该为惹出的麻烦负责。反社会人格者也以情感淡漠而著称,他们或许会把自己那空洞易逝的情感说成是情深意浓,实际上却是麻木不仁。5他们一点儿同情心都没有,也没有兴趣与配偶建立真正的情感纽带。一旦剥离他们表面的光环与魅力,我们就会发现他们的婚姻是一厢情愿的,完全没有爱情基础,而且往往维持不了多久。如果说反社会人格者的配偶在他们眼中有价值的话,那是因为配偶被看成一种财产,反社会人格者可能会为失去这一财产而感到愤怒,但从来不会为此难过,也不认为自己应该对配偶的离去负责任。以上这些特征,再加上美国精神医学学会列出的几种“症状”,就是我们绝大多数人完全无法理解的那种缺乏良知(我们必需的第七感)的心理状态在行为上的表现。

然而,跟多的情况是,自己周围不见得有,但是鉴于人群基数,这个数量就变得异常可观。人员密集处难免会有那么几个。

基于《POI》的技术来实现防患于未然,自然不现实。那么,就只能自己识别风险,尽早远离,君子不立于危墙之下。

减肥

2024年11月11日 08:54

减肥这件事情,其实已经斗争过无数次了。都以失败而告终,最疯狂的一年,家里的跑步机还在。一个夏天几乎每天都在跑步,最多一次,在跑步机上跑完了一个半程马拉松。

然而,即使这种强度的锻炼,感觉也没有减掉多少体重,仅仅掉了 10 斤。锻炼的另外一个结果,那可能就是反而让肌肉更结实了,这就让人很尴尬了。

上高中的时候,自己的腰围也仅仅有二尺一,那时候姐姐们穿不上的裤子,自己很轻松的就穿上了。不过,那时候的烦恼是,同学的软绵绵的大胸。就想着什么时候自己也能有这种软软的大白兔。

在上 大学之后,生活条件稍微好了那么一些。开始多吃,慢慢的体重上去了,但是胸却没变大,这就让人感到了淡淡的忧伤。为什么肉不往自己想要的地方长呢?

这种朴素(傻逼)的情感,也是源自于自己的无知。如果能随心所欲的让肉长到自己想要的地方,那还要什么整形美容科?可惜,这种弱智行为导致的后果就是体重上来了,除此之外,没有任何的改变,该小的还是小。

再后来,毕业了,感觉就更控制不住了。然而,此时最大的敌人,却是浪费粮食可耻。

有时候吃饭,做多了,或者在外面,点菜点多了,最后剩下一点,打包不值当的,扔掉了又觉得可惜。就这样,几乎每次吃饭,都会多吃一点。就这样一点点的多吃多吃,体重下降肯定是没戏了。反正是直线上升。

现在要想减肥,如果控制饮食能解决到一半的问题,至于剩下的一半,暂时没有想好,之前吃过螺旋藻之类的。这种所谓的保健品,实际在减肥上意义不大,吃到最后都快吃吐了,也没什么太大的效果。

现在这个东西不鼓吹减肥效果,改吹改善免疫力了。哎。

而至于现在嘛,在尝试左旋肉碱。

这个东西买了之后,还有客服加了微信,所谓的健康管理:

但是啊,这,按照客服的说法,他们有人 9 天能瘦 11 斤,这就离谱啊。

这是减肥期间生了个娃吗?就离谱,这一天一斤的量,比割肉都快啊。如果按照这个,用不了几天我都能瘦成一道闪电了。

哼唧唧

至于以后能不能行,这个等看看再说吧。不过感觉吃这个东西,对于控制食欲是管点用的,最起码就是感觉吃的没以前那么多了,也算是一个好的开始吧。

毕竟,自己不是贾玲,即使减下来也没什么小目标。

再说了,我要是有这么个小目标还用得着这么辛苦的去减肥?直接整不更快吗?切!

Amazon CloudFront 免费 CDN 配置教程

2024年11月10日 19:40

三十海河 留言文能不能出个教程,下午看了下正好之前给宝子做的博客挂掉了。正好迁移过来,不过不得不说,这个体验的确比较奇怪,cname解析,有的域名能加,有的不能加,这就很离谱。

视频分两段录的,主要是第一段失败了,但是实在不想重新录了。直接看这两段吧。第一段有些问题,第二段也提到了。

整体用起来的感觉就是,很多翻译有些奇怪,包括文档看的也莫名其妙,这个就很蛋疼。

不过好在最后还是成功了,折腾半天,哼唧唧

Amazon CloudFront 免费 CDN 初体验

2024年11月10日 08:58

前几天在呆哥的博客看到了为网站添加cloudfront的文章,于是昨天把一个没套cdn的域名尝试给加上了cdn。

具体添加的步骤按照呆哥的文章操作就可以啦,然而,在添加完cdn之后,却一直出现问题,报502错误。

按照之前的配置方式,直接添加的http的回源,很可能是这个回源问题,尝试添加http回源,发现http是能访问的。但是https的不行,猜测可能是aws的回源校验证书了,本地服务器用的都是同一个证书(h4ck.org.cn),如果校验证书有效性,那肯定是无法创建链接的。重新申请免费证书之后,这个问题算是解决了。

然而还有另外一个诡异的问题,那就是https://www.obaby.org.cn可以访问,但是https://obaby.org.cn无法访问,报403错误。参考官方的文档,提示是cname问题,域名是dnspod解析的直接给@添加的cname记录。不过这个做法按照dns的国际做法其实是不受支持的,不能直接给@添加cname解析的。只好将域名解析切换到he.net重新创建alias解析。

然而问题依旧,猜测还是配置问题。后来才发现这个东西的异常之处,按照理解添加域名之后,不在需要添加额外的cname了。

然而事实上却是,这个东西不管添加的的时候创建的域名是什么,在这里都需要把添加的时候的域名加进去才能正常匹配到这个cname。

另外一个就是这个源里面的,源域的问题,最外侧的这个名称其实无关紧要。

需要设置的是内部的original domain:

这个对应的才是回源的配置。经过上面的设置之后,终于两个域名都能用了,并且,顺便把ipv6也给开启了。

测速效果,V4:

v6速度:

后台地址:

https://console.aws.amazon.com

WP-UserAgent [纯真增强版] 15.01.01

2024年11月8日 10:45

之前为了下载纯真的ip 地址数据库订阅了他们的公众号,前几天的时候看到推送说什么数据库格式更新了,有了 czdb 的格式,并且提供了各种语言的 sdk。

不过这个东西应该不是最近才推的,因为印象里貌似很久之前就看到皇家园林写的数据库迁移的文章。官方给的sdk 地址是这个:https://github.com/tagphi/czdb_searcher_php

按照文档操作,感觉也不复杂,直接:

composer require czdb/searcher

composer导入,就一行命令的事,但是为了弄个插件,需要在服务器上装这么个东西?那插件安装到别的地方也麻烦啊。想着一次性解决这个问题,直接下载源码,修改导入方式,按照网上的教程一通改,并不好使,最后 还是请教杜郎,才解决了这个问题:

composer

真不错,直接小花花+1.

下载 copmoser 导出的包,直接扔到插件目录下,

因为最终要修改的是 ip2text.php 文件中的convertip函数,所以直接扔到 show-useragent 目录下,在代码中导入代码,并且初始化:

require_once __DIR__ . '/vendor/autoload.php';

use Czdb\DbSearcher;

$v4databasePath = dirname(__FILE__).'/czdb/db/cz88_public_v4.czdb';
$v6databasePath = dirname(__FILE__).'/czdb/db/cz88_public_v6.czdb';

$queryType = 'MEMORY';
$key = 'n2pf2******************==';

// Initialize the DbSearcher with the command line arguments
// $instance = new SomeNamespace\SomeClass();

$v4dbSearcher = new DbSearcher($v4databasePath, $queryType, $key);
$v6dbSearcher = new DbSearcher($v6databasePath, $queryType, $key);

// $dbSearcher = new DbSearcher($databasePath, $queryType, $key);

function convertip($ip) {
    global $v4dbSearcher;
    global $v6dbSearcher;
    try{
        if(strpos($ip, ':') != false){
            $region = $v6dbSearcher->search($ip);
        }else if (strpos($ip, '.')!= false)
        {
            $region = $v4dbSearcher->search($ip);
        }else{
            $region='Unknown';
        }
    }catch (Exception $e) {
        // Handle the exception and inform the user
        $region = 'Exception';
    }
   
    return $region;
}

这里初始化了两个DbSearcher,分别对应 v4 和v6的查询。查询代码也很简单,就上面这几行。

同样,既然有了国家代码,那剩下的就是去掉原来通过接口查询所属国家的问题了,之前用接口是因为qqwry.dat 旧版本没有 v6 的数据,后来也一直没更新,所以归属地现实国旗是通过接口实现的,现在既然 46 都有了,那就可以直接本地解析了,不过比较坑爹的是 v4 的地址是“-”拼接的,v6 的地址感觉是空格,实际上是个制表符’\t’,为了这个制表符废了半天的劲,一直解析不出来,直接头大:

function getCountryName($str) {
    $parts = explode('–', $str);
    $name = count($parts) > 0 ? $parts[0] : '';
    // print($name);
    if (strpos($name, " ")!==false){
        $parts = explode(" ", $str);
        $name = count($parts) > 0 ? $parts[0] : '';
        // print($name);
    }
    if (strpos($name, "\t")!==false){
        $parts = explode("\t", $str);
        $name = count($parts) > 0 ? $parts[0] : '';
        // print($name);
    }
    return $name;
}

之所以解析不出来是最开始的if (strpos($name, “\t”)!==false)用的单引号,后来才发现,单引号下转义字符无效,这尼玛是凭什么啊,果然 php 是最好的语言。

后面就是讲国家名转换为 2 位国家代码了:

function getCountryCode($countryName) {
    $countryMap = array(
        '中国' => 'CN',
        '美国' => 'US',
        '日本' => 'JP',
        '韩国' => 'KR',
        '俄罗斯' => 'RU',
        '法国' => 'FR',
        '德国' => 'DE',
        '英国' => 'GB',
        '意大利' => 'IT',
        '加拿大' => 'CA',
        // 省略部分国家地区
        '瓦利斯和富图纳' => 'WF',
        '也门' => 'YE',
        '赞比亚' => 'ZM',
        '津巴布韦' => 'ZW',
        );
    $countryName = removeWhitespace($countryName);
    $countryCode = 'unknown';
    if (isset($countryMap[$countryName])) {
        $countryCode = $countryMap[$countryName];
    }
    // ; return $countryCode;
    return strtolower($countryCode);
}

到这里改造基本就全部完成了。

更新日志:

= v15.01.01 =
* 替换本地IP归属地查询数据库为纯真CZDB格式
* 替换IPv6归属地查询,替换为本地数据库,去掉查询服务器配置功能
* 鉴于纯真数据库需要授权码,需要去 https://cz88.com/geo-public 获取授权密钥以及数据库文件
* 密钥配置文件,ip2c-text.php $key = 'n2pf2******************pg==';
* 数据库下载之后放入show-useragent\czdb\db 目录下,文件名分别为: cz88_public_v4.czdb cz88_public_v6.czdb

插件安装无法直接使用,请按照下面的步骤操作:

* 需要去 https://cz88.com/geo-public 获取授权密钥以及数据库文件

* 密钥配置文件,ip2c-text.php $key = ‘n2pf2******************pg==’;

* 数据库下载之后放入show-useragent\czdb\db 目录下,文件名分别为: cz88_public_v4.czdb cz88_public_v6.czdb

实际效果:

插件下载地址:

温馨提示: 此处隐藏内容需要发表评论,并且审核通过后才能查看。
(发表评论请勾选 在此浏览器中保存我的显示名称、邮箱地址和网站地址,以便下次评论时使用。
(请仔细检查自己的昵称和评论内容,以免被识别为垃圾评论而导致无法正常审核。)

半夜“机”叫

2024年11月6日 10:22

秋天还是不期而至了,原来暖暖的阳光,现在也都暗淡了。对于一个旅游城市来说已经过了旅游旺季,时隔许久在此来到石老人的沙滩,已经看不到太多的游客。每次来到海边,心情总是能放松那么一些,坐在沙滩上,哪怕什么都不干,就这么静静的呆坐着,都感觉时间安静了许多。

路上遇到一家人,迎面走来,一个小女孩蹦蹦跳跳的,大约四五岁的样子,蹦到跟前的时候说了一句:“大美女”。

跟他们擦肩而过之后,她妈妈问:“漂亮吧”。

所以,现在的 e 人真的这么奔放的吗?让我这 i 人大气都不敢出。

毕竟,上班时间找机会溜出来的,该回去公司还是要回公司的。正好,快递给送到菜鸟驿站了,顺路可以去取快递。

家里厨房的推拉门,好久之前就变得非常难用了,拉起来非常费力。上周把门拆下来看了一下,原来是底部的轮子裂掉了。

直接在淘宝,以图搜图,很容易就找到了同样外观的轮子。终于昨天下午送到了,不过在晚上安装的时候,拆开快递发现,寄过来有一个就是裂开的。

这就很尴尬了,联系卖家之后,答应给补发一个。就先酱紫吧,倒是也不是什么大问题。

其他的轮子更换还是比较顺利的,更换之后推拉起来就轻快多了,焕然一新。

这不到十年的房子,已经很多的东西开始慢慢的老化,坏掉了。进入了修补期,不过这个也确实没什么别的好办法。只能哪里出问题修补哪里,好在各种配件倒是还容易买到。

夜里正睡的迷迷糊糊的,被小姐姐给喊了起来,“你看看是什么东西发出的声音,响了挺长一会儿了”

刚想说没听到什么声音,就在这是,传来一阵有节奏的声音,“滴……滴……滴……”声音虽然不是很大,但是节奏比较稳定,感觉像是什么东西发出来的提示音。

其实,半夜能发出声音的,肯定就是某些点子产品或者某个设备。小姐姐也说声音是从机柜里传出来的。

打开机柜,看到最下面的 UPS 的显示屏是亮着的,猜测应该就是它了,但是正常情况下它没什么声音啊。点几了几下屏幕,数据来回切换的过程中,看到一个 78% 的字样,感觉应该是剩余电量的问题。但是现在家里是有电的,怎么会进入 ups 供电呢?客厅空调的显示面板还显示着当前温度 23 度,卫生间的灯也亮着。这一下忽然变得扑朔迷离起来,仔细看了下机柜里面,貌似也没什么问题。

再后来想到,是不是插座的开关跳闸了,往门口的配电箱走的时候,发现扫地的地宝也跑了出来,停在客厅的地毯上,拉开配电箱的门,果然,房间插座那个空开跳闸了。重新给推上去,所有的设备重新上电,房间里感觉亮度都提升了很多。这时候鱼缸的水泵也启动了,传来了哗啦啦的水声,怪不得,刚才总感觉挺奇怪的,那么安静。

回到床上,躺下正要入睡,耳中突然传来“啪”的一声,随之而来的是房间里各种声音又没了,又陷入了安静之中,之后就又传来了“滴……滴……滴……”的声音。看来是空开又跳闸了,回到配电箱那里,却发现怎么推也退不上去了,连续尝试两次之后,就得去找漏电的根源了。

房间里晚上的用电大户应该就是机柜了,先把机柜的电源断开,依然推不上去;随后是洗手间;鱼缸的水泵;都拔下来之后发现依然推不上去。这就奇怪了,不得不想是不是电视柜后面的问题了。把电视柜拉开,发现问题的关键了,不知道什么原因,鱼缸可能是堵了某些东西,水顺着进气口排了出来,下面插电的地方已经成了一篇汪洋,插排都泡在了水里。

把插排拿出来之后,竟然直接有水流了出来,滴滴答答。只好把鱼缸搬到了卫生间,把电视柜后面清理干净。此时重新送电一切就都 OK 了。

这看来的确不能把鱼缸随便放了,这鸡叫,比周扒皮的还坑爹,好在有各种漏电保护,不然这还不知道要出什么问题。

不过这一晚的睡眠,是让着“机”叫,彻底给毁了。

天启Z:完结的起点

2024年11月4日 09:41

10 月份,观看了 13 部影片,当然,并不是所有的影片都看得那么认真。多数的时候也不妨碍自己在看电影的时候在另一个显示器看看文章,或者无聊的玩消消乐。如果说十月份的影片,还有值得推荐的,那应该是首推《默杀》,这才是应对霸凌的正确方式。其余的影片多数都属于 R18 级别的血浆片为主,《断魂小丑3》也可以一观,当做普通的杀戮片看即可。不要有太多的期望。

11 月份,目前看了四部影片,这几部影片的时长都是比较长的,多的两个小时,短的也得一个半小时。《死侍与金刚狼》之前看了个开头,感觉没有达到自己的期望,就那么一直放着,直到昨天晚上才看完,商业片更多的是商业,剧情中规中矩。反而,西班牙的电影《天启Z:完结的起点》作为一部僵尸片,个人感觉还是达到了自己的预期的,男主也不是所谓的超级英雄,只是一个普通人,在变异狂犬病爆发之后,独自求生的一个过程。这部戏没有女主,当做末日片看可以,当做公路片看也未尝不可。

影片开始,男主的妻子还在抱怨没有孩子的问题,结果,下一秒就在车祸中丧生了。“我还以为你有很多时间”意外和明天,永远也不知道哪个会先到来。之后的求生,也是一波三折,虽然这不影片没有女主,但是却有猫主,一直可爱的小猫咪,不管主角逃到哪里,都没有丢下那只喵咪。人在绝望的时候,这也是一个心理寄托吧。有的末日片,陪伴主角的可能是狗,可能是机器人,也有可能是一盆绿植《这个杀手不太冷》,当然,这个不算是末日片。

影片中的僵尸,不再是那种行动缓慢的,迅速,甚至有一定的智商。现在一些僵尸片已经改变了僵尸的属性,行动缓慢已经不是僵尸片的常态了。不过影片中描述暴乱的镜头,基本都是一致的。等哪天真的发生这种灾害,乱肯定是必然的。

然而僵尸片肿的僵尸,固然有些特定的属性,很容易一眼就看出来,然而,现在这个情况却是,很多人比僵尸更可怕,那种毫无征兆的突然袭击,更让人后怕。最近频出的伤人时间,有那么一瞬间让我忽然觉得,这个现实比影片中的更加的不可捉摸。店门口停车,跟老板起争执,被杀;一瓶矿泉水跟老板起争执,被杀;小米酥妻崩直线,线下约架,杀人;大学生骗钱,被刺数刀……

让我总有一种感觉,预约多的人产生交集,也就有了更多的不确定性。这两年巨大的压力,成了压垮某些人的最后的一根稻草,已经开始破罐子破摔。国内重度精神病比例为 1%,按照这个比例算下来,人数已经相当可观,这种状态,无异于僵尸世界,末日求生。那种不确定的伤害不一定来自于什么人,不一定来自于什么时候。这种高精神压力的条件下,让原来很多人可能不严重的精神状态,变得更加脆弱。随时可能开着车撞向人群,撞向学校。总有刁民想害朕,现在看来,这些刁民是越来越多了。时常爆发的这些恶性事件,也不得不让自己更加的小心警惕。

人间未见僵尸,而僵尸已经无处不在。

免费洗车

2024年11月1日 09:49

自从提车只有一次车也没洗过,之前从老家开车回来的时候按理说是该洗车的。结果后来就是连日的阴雨,每周都有那么几天在下雨。就更没有洗车的必要了。

4s 店的小哥也经常发微信,让有时间去找他洗车啊。于是昨天下午问了下能不能洗车,得到肯定答复之后,直接开车过去了。

问了下门口的大爷,直接开车到了保养的地方,又在接待的引导下直接开到了洗车区。不过现在洗车位倒是空着的,直接开上去,洗车的大爷一通指挥最后还是没停好,把钥匙交给大爷,大爷又给调整了一下。

不过不得不说,大爷调整了一下,车轮个瓷砖的接缝都对齐了。果然,你大爷还是你大爷。

给小哥发个消息,告知他自己在洗车区,小哥回复说他过来。几分钟后小哥来了,把钥匙交给他,说洗好了之后给自己开过去。让自己去大厅等。

在展厅随便转悠转悠,看了下发现运动,感觉貌似也不是不能买。

白色的车看着还是蛮不错的。

转悠一圈,刚准备找个地方坐会儿,小哥回来了,说洗好了。

到大厅外,小哥问:“是不是跑高速了,上面的这些东西,机器洗不下来。现在后面排队洗车的太多,等哪天不忙的时候你再来,用抛光机给你打干净”。

顺着他指的方向看过去,果然还是有很多的小点点,应该是跑高速的时候落下来的鸟屎,还是空气中那些漂泊居无定所的小虫在撞击之后留下的痕迹。应该也是时间太长了,不仔细洗,或者浸泡一会儿很难弄下来。

“没关系,等我自己找湿巾擦一下吧。谢啦”

小哥跟门口的老头示意,车直接放出去,就这样,前后不过十分钟的时间,洗完了。洗了,感觉又没完全洗。

回到停车场,仔细一看,印子还是蛮多的。

车上也没有能用来洗车的东西,忽然记起来还有瓶卸妆水,于是卫生湿巾加卸妆水尝试擦了一下这些生物痕迹,事实证明效果也还 ok。多擦几次也就都擦下来了。

那就酱紫吧,毕竟免费的不是。

运动相机初体验

2024年10月30日 10:44

有时候心血来潮的时候,就会买一些毫无用处的东西。有的东西,买了之后一共就用了那么一两次,然后就丢在了某个角落里落灰。

多年以前,曾经买过一个三星的 gare 360 相机,自从买了之后一共就用了两次。主要是这个全景相机也确实没想好怎么用,拍摄的全景照片还需要专门的处理软件才能使用,就让这个东西变得更加的鸡肋。

这个东西前后两个摄像头,看起来还挺好玩的,实际上就是使用起来的确没那么方便。

前几天又对运动相机比较感兴趣,于是,又花重金买了一个运动相机。

这个东西,看介绍是可以直接头戴或者安装在头盔上的。

这个安装效果是不是还蛮不错的?但是呢,实际体验下来就是,那个相机支架太单薄,根本支撑不住相机的重量,在耳朵上根本挂不住啊。哈哈哈。

具体请看 vcr:

刚开始坐着是不是感觉还行?等站起来之后就开始往下掉了啊。

掉下来之后就开始被头发遮挡了,想戴回去也比较困难。这就很尴尬啊。

不过这个东西,夹头发还是挺紧的:

看来得换个相机支架了~~

Python 解析 DLT645 协议数据

2024年10月30日 10:05

DL/T 645是中国国家电网公司制定的一种用于电能表通信的协议,全称为《多功能电能表通信协议》。该协议主要用于电能表与数据采集终端(如集中器、抄表器等)之间的通信,以实现电能数据的采集、传输和管理。

主要特点

  1. 多功能性:支持多种电能参数的读取和设置,如电压、电流、功率、电能、功率因数等。
  2. 灵活性:支持多种通信方式,如RS-485、红外、无线等。
  3. 安全性:支持数据加密和身份验证,确保数据传输的安全性。
  4. 标准化:符合国家电网公司的标准,便于大规模部署和维护。

协议结构

DL/T 645协议的数据帧结构通常包括以下几个部分:

  1. 帧起始符:标识数据帧的开始,通常为0x68。
  2. 地址域:标识电能表的地址,通常为6字节。
  3. 控制码:标识命令类型,如读取数据、写入数据等。
  4. 数据域:包含具体的命令数据或返回的数据。
  5. 校验码:用于校验数据帧的完整性,通常为1字节。
  6. 帧结束符:标识数据帧的结束,通常为0x16。

常用命令

  • 读取数据:用于读取电能表的各种参数,如电压、电流、功率等。
  • 写入数据:用于设置电能表的参数,如时间、费率等。
  • 广播校时:用于同步电能表的时间。
  • 冻结命令:用于冻结电能表的当前数据,便于后续读取。

应用场景

DL/T 645协议广泛应用于智能电网、电力监控系统、远程抄表系统等领域。通过该协议,可以实现电能数据的实时采集、远程监控和自动化管理,提高电力系统的运行效率和管理水平。

数据报文格式:

数据报文解析相对来说并不复杂,所有的数据都是流式,直接按照顺序进行读取即可。不过里面数据的内容,并不需要在此进行数值转换(电力数据需要处理),基本读到什么内容就是什么内容。

例如原始数据:

message = b'hw8\x06(\x15Dh\x00\x02\x01\x1f(\x16'

解析数据可以通过下面的方法:

def process_645_data(message):
    print('message in hex=', message.hex())
    start_pos = message[0:1]
    # print('start_code = ', start_pos.hex())
    hid = message[1:7]
    # print(hid)
    # int_value = int.from_bytes(hid,byteorder='little')  # 默认使用大端模式
    # print(int_value)
    # int_value = int.from_bytes(hid,byteorder='big')  # 默认使用大端模式
    # print(int_value)
    print('hid = ', hid[::-1].hex())
    hid_hex = hid[::-1].hex()
    # print(hid.hex())
    data_pos = message[7:8]
    # print('data_pos = ', data_pos.hex())

    control_code = message[8:9]
    print('control_code = ', control_code.hex())
    data_length = message[9:10]
    print('data_length =', data_length.hex())
    data_lenth_int = int.from_bytes(data_length, byteorder='little')
    data = message[10:10 + data_lenth_int]
    print('data = ', data)
    crc_code = message[10 + data_lenth_int:11 + data_lenth_int]

    # crc_source = message[0:10 + data_lenth_int]

    # calced_crc = calc_crc(crc_source)
    # print('calced crc = ', calced_crc)

    print('crc_code = ', crc_code.hex())
    end_pos = message[11 + data_lenth_int:12 + data_lenth_int]
    # print('end_pos = ', end_pos.hex())

    return hid, hid_hex, control_code, data_lenth_int, crc_code, data

接收到的数据解析出来之后不需要再进行转换int.from_bytes(hid,byteorder=’little’) 不管是大端还是小端模式,转出来都是错的,直接将高低位倒序输出即可:hid[::-1].hex()

解析后的数据:

message in hex= 68773806281544680002011f2816
hid =  441528063877
control_code =  00
data_length = 02
data =  b'\x01\x1f'
crc_code =  28

对于数据上报的内容,例如电量,电报上报数据为下面的报文:

# 电量上报数据
data_msg = b'\x68\x77\x38\x06\x28\x15\x44\x68\x91\x08\x33\x33\x34\x33\x33\x33\x33\x33\x38\x16'

解析数据内容:

data_msg = b'\x68\x77\x38\x06\x28\x15\x44\x68\x91\x08\x33\x33\x34\x33\x33\x33\x33\x33\x38\x16'

hid, hid_hex, control_code, data_lenth_int, crc_code, data = process_654_data(data_msg)
print(control_code.hex())
print(data.hex())

data_type = data[0:4]
data_source = data[4:]
process_data_type = bytes(byte - 0x33 for byte in data_type)
print(process_data_type[::-1].hex())
process_data_data = bytes(byte - 0x33 for byte in data_source)
print(process_data_data[::-1].hex())
print(int(process_data_data[::-1].hex(), 16) / 100)

解析后的数据:

message in hex= 6877380628154468910833333433333333333816
hid =  441528063877
control_code =  91
data_length = 08
data =  b'33433333'
crc_code =  38
91
3333343333333333
00010000
00000000
0.0

crc 计算方法:

def calc_crc(src):
    sum = 0
    for i in range(len(src)):
        sum += src[i]
    crc = sum % 256
    return crc

 

数据解析处理参考:https://blog.csdn.net/m0_37651448/article/details/143100598

2024年10月28日 10:37

第一次见到照片与真人判若两人的照片还是在大学毕业的时候,姐妹给了一张自己的毕业写真。照片上的女生,不管是衣服,造型还是容颜,更加的绚丽了几分。也就是这时候才发现,原来照片也可以把人拍的那么漂亮。

当然,自己毕业时并没有那么多钱去干这件事情。直到多年以后其实拍写真感觉也是一件奢侈的事情。相对较高的价格,加上较长的时间,有时候真的挺难挤出这些时间来专注的干一件事情。后来即使是偶尔拍照,也是跟家人一起。自己却从来没有单独去拍过照,就在上周初的时候,在短视频平台看到了一些广告,再后来去大众点评开始看各种写真拍照。

在浏览了一些之后,最终还是下单了。天气渐凉,既然想拍照,那就不如趁现在。咨询了一下可预约的时间,最终订到了周五下午两点半。这个时间,也刚刚好可以请半天假就够了。在此之前,化妆的小姐姐也贴心的发了一下需要提前准备的东西。

青岛的路依然在修着,一条条,一段段,这几年好多的路已经返修过,整体的路况也的确是改善了不少。然而快到目的地的时候,道路一侧已经彻底封闭,原来双向两车道的道路,就剩下一个车道通行。拍摄的地点实在一个小区内,底下停车场异常的广大,兜兜转转跟着路标不断前行,终于过了四五分钟看到了 12 号楼一单元的入口。

虽然在来之前已经选了几套衣服,但是,实际现场还是要试试具体的效果的。选好衣服,跟小姐姐来到化妆间开始化妆。化妆的时间还是比较长的,也画的细致。

不知不觉中,一个小时就过去了。不过等到了拍照环节就快多了,基本换好衣服,简单的补妆。剩下的就是摆 pose,咔咔一顿拍。

尽管如此,等拍完照选完照片也已经快七点了。不过小姐姐画的妆是真不错,要是能印在脸上就好了。

周六,依然是带宝子上课,打球。晚上,宝子问能不能再举高高,结果举起来之后,没接好,直接砸到了自己脸上。就这样,鼻子下面被磕破了,血流不止,宝子也在一边哭。简单的处理了下伤口,贴了个创可贴,这事就算这么结束了。这种高危的活动,毕竟还是存在风险,也是之前玩的时候越来越放松,才导致了事故的发生。

本来周日是准备带宝子去世博园玩的,结果一早起床之后说不想去了。原以为是因为天不好的原因,看着要下雨的样子,然而,实际原因确实她打球的时候摔了一跤,崴脚了。

之前左脚骨折,虽然已经完全愈合。但是,为了保险起见还是带着去了医院,小儿骨科的号码已经全部约满了,只好挂了个普通号。叫号到了之后,一声一看是孩子,开口说道:“小孩的我看不了,骨头还没发育完,去对面的科室,让医生给加个号吧”,不过在去加号之前,还是给开了 x 光的检查单子。

带孩子去加号,拍片,然后回来签到,虽然是加号,但是加的位置应该是应该是在所有号码的后面。不过也算是不错,虽然系统上没号,但是最后毕竟还能给挂上。终于十一点多,叫号,进入诊室,医生查看一番,感觉单纯从 x 片无法断定具体的情况,需要下午再做 ct 扫描。医生给开了下午一点的 ct,就这样。一上午的时间就过去了,中午回家,简单吃点东西,自己的伤口虽然不在那么疼了,但是,却开始肿了起来。本来想着挂着外科一块看一下的,结果外科的号上午没有了,下午的没挂。也懒得现场挂号了,就这样吧。

中午简单的吃点东西,下午回到医院继续做检查。ct 扫完,签到,复诊,进入科室的时候,一声看了下电脑上的 ct 图像,边拖动边说:“ct 的三维建模还没完成,可能还得在等等”

“这里有之前骨折的 ct 扫描单”小姐姐一边说,一边从牛皮纸袋子里把单子取出来递给医生,“这个是不是可以参考下”

医生拿过胶片,双手举着胶片,直接躺在了椅子上。一边使劲的观察,边看边说:“那问题不大了,应该就是普通的扭伤,用云南白药啊之类的喷一下,前三天冷敷,几天后可以热敷” 说完之后,做起来,回到电脑旁,开始写诊断建议。写完之后说:“不给你开药了,直接去药店买就行”

到这里,心里的石头总算是落地了。而幸运之处在于,自己跟宝子对装的过程中,虽然自己伤势严重,但是宝子却并无损伤,主要原因在于她掉下来的时候,牙齿要到了自己的鼻子下面。虽然当时疼,但是主要的力量也基本缓冲掉了。至于自己的这点毛病,那就等明天再说吧。

到了晚上,嘴唇肿的愈发的严重了。整个嘴都嘟嘟了起来,吃饭也很不方便,依然是简单吃点。小姐姐建议吃消炎药,从餐桌旁拿了一版头孢出来。

餐桌旁边总是有一些药放在那个地方,之前也收走过几次,不过每次收走了,就开始有人感冒、发烧等等小毛病。于是继续吃药,后来吃完药就放在了那个地方,成了镇病的吉祥物。

然而,这种外伤,毕竟不是放在那里的药能解决的。人嘛,看来总是得受点伤。毕竟人生漫长,而解药,却鲜有。

现在看来是得挂个号去看一下了,然而,挂号系统显示普通外科最早的号码也到了十一点多。好在整形美容科号码倒是比较充裕,可以挂八点的,这样等看玩了之后可以直接去公司,也就不影响上午的打卡了。最近,公司对于考勤异常变态的监管,的确让人比较抑郁。

挂完号,想着之前看到希望工程圆读书梦的活动,点进去看了下,返现很多的小朋友的愿望都被认领了。往下翻了一下,找到几个,也认领了一个,毕竟,多读书总是好的

早上起床之后,症状依然没有好转的迹象。昨晚挂的号就可以排上用场了,七点半打车,到医院刚好八点。签到,等待叫号。

与其他科室不同,整形美容科相对来说,人就少了很多,并且周末是不上班的。等了没几分钟就叫号了,医生询问了下处理情况,以及怎么处理的。简言之问题不大,但是嘴会继续肿好几天,并且还有内部挫伤,也会变紫。简单的交代了下后续的处理方式,碘伏擦拭,百多邦消炎。其余的变化不大,鉴于自己不想再去药店,让医生帮忙给开药,最后只开了一盒百多邦,一边写一边说:“这个药不在医保范围内,需要全部自费,碘伏不给你开了,你去找个药店买吧” “嗯” 医生都不喜欢开药,看完了就撵你走,这,就很尴尬,本来想着不用再跑药店了。

交费,去药房取药,打车回公司。跑到旁边小区的药店买了一盒带棉棒的碘伏,这个还是蛮方便的,掰断了直接就可以用。先跑到车上处理了下伤口,回到办公室,一群人问自己是不是感冒了。

毕竟,现在戴口罩的话,可能就是感冒了吧,只是,这药毕竟不是万能的。

❌
❌