Foxhole https://blog.southfox.me/ Sun, 31 Dec 2023 21:32:20 GMT http://hexo.io/ 2023 年终总结 https://blog.southfox.me/2023/12/2023%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/ https://blog.southfox.me/2023/12/2023%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/ Sun, 31 Dec 2023 21:32:20 GMT <p>什么,已经要 2024 年了?!</p> 什么,已经要 2024 年了?!

幸运

And even when I might fall down,

I know my luck come back around.

今年如果如果要选出一个关键词的话,那么就是「幸运」吧,每次找工都是海投简历快要绝望的时候「刚好」被「捞」到了。首先是三月份的实习,距离家的位置还算不远。作为一家还算大型的企业做事十分垂直,做的事多都是一些填表单之事,基本上很容易被替代。也「幸好」我有 Emacs ,在一大堆服务器上翻找工程文件里 blame 是谁提交的代码,在一大堆编译产物翻找定位时真得救了我的命。

这段时间就像是静止了一样:每天被闹钟逼迫着起床;然后走到附近的公交站(甚至因为这样和公交车司机混了个脸熟);半小时后下公交,然后走向大厦;等电梯(有时人太多也会选走楼梯);到工位打开电脑;工;下班后在等公交;座半小时公交; 车站下车然后回家。在一座小城找到一份对于当地人耳熟能详企业的工作,如果能一直这样下去也还算是不错吧。但因为 2023 年寒冬实在太冷,冷意已经让大多数企业都得凝住呼吸,生怕机体的热量散失。所以自然是没有什么位置留给新来者的,甚至同组的一位实习快一年的小哥都没有转正的机会,所以当时间一到,我就只好潇洒走人了。

然后七月到十月就待在家里,算是一个小小的 gap time 吧,可能这个情况会一直持续到明年,真是这样的话本篇博文可能就没有那么多内容,写到这里就应该写点什么明年展望就结笔了,但生活总是像个迷,并没有给我这种发展。

十一月还是打算「出洞」,打算呼吸点新鲜空气。但是就业市场寒冬更甚,简历比起三月份更加沉底(哪怕开启广域模式),而且临近年关,也没有什么公司打算在这时候招人,正当我已经打算放弃「回洞」时,没想到就正好 HIT 到一家了。一家「幸运」的在今年拉到投资逆流而上就正好在这时招兵买马的公司,刚好也觉得我「折腾」的一大堆东西也「不容易」所以就这么对上了。一切都是那么恰好,但就是工作地点离家超过两千公里,虽然地点当初是在招聘软件自己选的,真发生时却还是有点恍惚。就算临行前故作坚定但潜意识下估计也是一大堆思绪组成的乱麻吧,头次座飞机、一落地就要开始找中介寻找房子、在名宿和租房地点两头跑搬运整理东西、甚至为了一台炸了的服务器就这么修到凌晨三点,不敢相信报到当天我的黑眼圈该重到什么地步。不过如今我喝着热茶写出这些事也就代表一切都已落定。

坚定

好像大自然只支持一种理解能力,养活了四足动物就养不活禽鸟,养活了会爬的东西就养不活会飞的东西

可能还有一件拖了很久的事「有幸」在三个月的 gap time 里想好了,那就是「坚定的自我认同」,虽然说之前的人生里一直知道这件事但是却一直没有调度它导致这个任务一直在挂起,不知道是真觉得还早还是因为一直被压抑了呢?

我作为在这跟熵的「无情之手」永恒对抗下的一个生命,从海底的那隆起的石塔中「逃脱」而出,花了几十亿年将自己的足迹散步到这个星球并永远地改变了这里且绝不停歇嗡嗡震动的玩意,到底意味着什么呢?或者「在十个当中只得一个」意味着什么呢?我想生命「幸好」不总是一样,允诺了在每次分裂复制时不同的空间,造就了生命的可塑性,或许就连作为其象征——链条底层结构都「改朝换代」了几次。

展望

作为「幸运」的一年,在年末找到了一份「幸运」的工作,也有时间一直做了之前一直想做的事,比如烘焙之类的,也体会到了「面多加水, 水多加面」是一件多窘迫的事。明年也没有什么特别的展望了,毕竟今年的多数事已经开始将我水豚化了,一些事情看起来很大很可怕但最后压到头上可能只是一个「橘子」,完全没有必要去付出超出的担忧。希望我明年能像我以为的这么处事不惊下去吧,不论是工作上的事、自己一个人潇洒待着抑或是打算走进一段亲密关系、不论「幸运」还是「没那么幸运」。

]]>
随笔 随笔 年终总结 https://blog.southfox.me/2023/12/2023%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/#disqus_thread
如何杀死一个去中心化网络? https://blog.southfox.me/2023/06/%E5%A6%82%E4%BD%95%E6%9D%80%E6%AD%BB%E4%B8%80%E4%B8%AA%E5%8E%BB%E4%B8%AD%E5%BF%83%E5%8C%96%E7%BD%91%E7%BB%9C%EF%BC%9F/ https://blog.southfox.me/2023/06/%E5%A6%82%E4%BD%95%E6%9D%80%E6%AD%BB%E4%B8%80%E4%B8%AA%E5%8E%BB%E4%B8%AD%E5%BF%83%E5%8C%96%E7%BD%91%E7%BB%9C%EF%BC%9F/ Sat, 24 Jun 2023 14:03:55 GMT <p>例如联邦宇宙(<code>Fediverse</code>)。</p> <p><img src="https://media.southfox.me/ipfs/bafkreiht6bsh4u5ncv3ezxbkvyinkbhqxh6sjxfnsz2vw6lifnsa3jzllq" alt="头图"></p> 例如联邦宇宙(Fediverse)。

头图

这篇文章是一篇翻译,原文为 How to Kill a Decentralised Network (such as the Fediverse)

现在是 2023 年。整个互联网都在科技巨头的帝国掌握下吗?不,因为有一些小村落还在反抗这种趋势,其中一些村落开始聚集,形成「联邦宇宙」。

随着 Twitter 和 Reddit 上的发生的争论,联邦宇宙开始获得名气和注意,一些人开始在日常生活中使用。帝国开始注意到了。

资本家反对竞争

正如 Fecebook 著名投资人 Peter Thiel 所说:“竞争是对于失败者说的”。是的,对于那些总将「市场总是对的」挂在嘴边的人来说,身处市场中却并不想要市场,他们想要垄断。自成立以来, Facebook 一直非常小心地消灭竞争对手。最简单的办法就是收购每一个可能成为竞争对手的公司。例如 Instagram、WhatsApp 被收购只是因为产品吸引了用户的注意并有可能为 Fecebook 蒙上阴影。

但联邦宇宙是买不到的。联邦宇宙是一个不同服务器通过协议(ActivityPub) 进行连接的非正式组织(informal group)。这些服务器甚至运行着不同的软件(Mastodon 是最著名的一个,但你也可以运行 Pleroma、Pixelfed、Peertube、WriteFreely、Lemmy 等)。

你无法买下一个去中心化网络!

但还有另外一种办法:让它变得无关紧要。这正是谷歌对 XMPP 所做的事。

谷歌如何加入 XMPP 联盟

20 世纪末,即时通讯工具风头无限。第一个获得巨大成功的应用是 ICQ,随后是 MSN 。 MSN 就类似于今天的 Tiktok :青少年可以在没有大人陪伴下在这个世界里度过数小时或数天的时间。

因为 MSN 是微软的一部分,谷歌希望与其竞争,并于 2005 年发布了 Google Talk,并将其界面整合在 Gmail 里。请记住在那时还没有智能手机或是小体积的网页应用。应用程序必须安装在计算机上,所以 Gmail 的网页交互是开创性的。MSN 甚至在某个时间是和操作系统捆绑在一起的,很难将其卸载。与内置在操作系统的预装应用相比,在 Gmail 用网页进行构建的聊天是一种更贴近用户的方式。

在谷歌和微软开始争夺霸权地位时,自由极客们开始尝试构建去中心化的即时通信。就像电子邮件一样,XMPP 是一种联邦协议:多个服务器之间可以通过协议互相通信,每个用户可以使用任意客户端与任意服务器上的任意用户进行通信。ActivityPub 和联邦宇宙也是这样运作的。

2006 年,Google Talk 开始实现 XMPP 兼容,谷歌正在认真考虑 XMPP 协议。2008 年,当我正在工作时,我的手机响了。在电话里,有人告诉我:“嗨,我是谷歌,我们想雇佣你。”我们打了几个电话,他们是通过 XMPP 的开发者列表找到了我,并表示正在寻找 XMPP 服务器管理员。

所以谷歌确实在加入联盟,这有多酷?这意味着每个 Gmail 用户都可以变成 XMPP 用户。这只会对 XMPP 有好处,是吗?我高兴坏了。

谷歌如何杀死 XMPP

当然现实没有那么美好。首先,尽管制定了 XMPP 标准,谷歌仍然在实行着自己没有任何人审查的封闭实现。事实证明,他们并不总是尊重他们正在制定的协议。他们并没有完全实现所有标准,这迫使 XMPP 的降低速度以便适应。好的功能没有在 XMPP 客户端中实现或使用,因为它们与 Google Talk 不兼容(头像功能都花了非常久时间才在 XMPP 里实装)。联邦还总会被破坏:有时是几小时或数天,谷歌服务器和常规 XMPP 服务器之间无法进行通信。XMPP 社区成为了谷歌服务器的监管员和除错员,发布违规和停机信息(我做了好几次这种事,可能这就是为什么有这份工作的原因吧)。

而且由于 Google Talk 用户远多于「真正的 XMPP」用户,因此「不关心 Google Talk 用户」的情况并不多。新人发现 XMPP 并不是 Google Talk 用户的经历让人非常沮丧,因为他们接触的大多数都是 Google Talk 用户。他们认为他们可以轻易的与 Google Talk 用户沟通,但这相当于他们在用 Google Talk 的基本版或是降级版本。典型的 XMPP 名单主要由 Google Talk 用户和一些极客组成。

在 2013 年,谷歌意识到大多数 XMPP 交互都是在 Google Talk 用户之间进行的。他们并不关心遵守没有百分之百掌握在他们手里的协议,所以他们中止了合作并宣布不进行结盟。并开始踏上一条即时通讯软件的漫长探索,从 Hangout 开始(随后是 Allo、Duo ,之后我就记不清了)。

正如预料一样,谷歌用户没有太多感受,事实上,他们什么也没意识到。最坏的情况是他们的一些联系人离线了,就这样。但对于 XMPP 联邦来说,相当于绝大多数用户凭空蒸发了一样。即使是最狂热的 XMPP 拥趸,也要创建一个谷歌帐号和朋友保持联系。请记住:对于他们来说,我们就是单纯离线了,这是我们的错。

虽然 XMPP 仍然是一个存在并且活跃的社区,但它未从这次打击中恢复过来。对谷歌投入了过高的期待导致了巨大的失望然后就这么被遗忘了。XMPP 变得小众,以至于群聊应用开始流行时(Slack、Discord),自由软件社区重新造了一个协议(Matrix)与之竞争,但群聊已经可以通过 XMPP 实现了。(免责声明:我没有研究过 Matrix 协议,所以我不知道在技术层面上与 XMPP 相比如何。我只确信它解决了类似的问题并与 XMPP 在相同的空间上竞争。)

(译按: Matrix 和 XMPP 对比在 Matrix 官网 FAQ 上就有回答(虽然被标注为过时了):What is the difference between Matrix and XMPP? - FAQ

如果谷歌未加入 XMPP 或从未被视为其中的一部分,今天的 XMPP 会有所不同吗?没有人知道。但我相信它会成长的更慢,可能,更健康。它将比今天更大、更重要,它将成为默认的去中心化通讯平台。但有一点是肯定的:如果谷歌没有加入,XMPP 不会比现在更糟糕。

并不是首例:微软的心机

谷歌对 XMPP 做的事并不新鲜。事实上,在 1998 年,微软的工程师 Vinod Vallopllil 就明确写下了一篇「削弱 OSS (译按:开源软件)攻击」的文章,其中他建议「去商品化协议和应用程序……]通过拓展这些协议或是开发新协议,我们可以拒绝 OSS 项目进入市场。

随着 Windows 2000 的发布,微软将这理论付诸实践,Windows 2000 提供了对 Kerberos 安全协议的支持。但该协议得到了拓展。这些拓展规范可以免费下载,但必须要接受禁止实现这些拓展的许可证。一旦点击「确定」,你就无法使用 Kerberos 的任何开源版本。这么做的目标就是消灭任何与之竞争的网络项目例如 Samba 。

Glyn Moody 在他的著作《Rebel Code》中讲述了这一传闻,并表明扼杀开源和去中心化项目是确有预谋的目标。它从来不是随机发生的,也不是由什么坏运气导致的。

微软还采用了类似的策略,通过专有格式(文件格式可以被视为交换数据的协议)的 Microsoft Office 来确保在办公市场的主导地位。当替代方案(OpenOffice 然后是 LibreOffice)在处理 doc/xls/ppt 格式能力变得足够好时,微软发布了一种他们称之为「开放和标准化」的新格式。格式故意弄得非常复杂(20,000 页的规范!),而且最重要的是,它是错误的。是的,标准中引入了一些错误,这意味完整实现 OOXML 格式的软件的表现将与 Microsoft Office 不同。

这些错误以及政治游说是促使慕尼黑市恢复 Linux 迁移的原因之一。所以是的,这个策略运作良好。因为如今 docx、xlsx 和 pptx 仍然是标准格式。来源:我就在那里,由慕尼黑市间接支付费用,使 LibreOffice OOXML 的渲染更接近 Microsoft 的渲染,而不是遵循规范。

后按:这种策略有一个维基百科词条:

Meta 和联邦宇宙

不了解历史的人终究会重蹈覆辙,这就是现在 Meta (译按:Facebook 的公司现在改名叫 Meta 了)和联邦宇宙发生的事。

有传言称 Meta 会实现「联邦宇宙兼容」,这意味着你可以通过 Mastodon 账户关注 Instagram 上的人。

我不知道这些传言是真是假,Meta 是否在考虑实现它。但我在 XMPP 和 OOXML 方面的经验告诉我一件事情,如果 Meta 加入联邦宇宙,Meta 将是唯一的胜者。事实上现在的反应已经让他们开始赢了:联邦宇宙在阻止 Meta 与不阻止 Meta 之间存在分歧。如果继续发生这种情况,这将意味着一个支离破碎令人沮丧的俩半式联邦,对新来者而言没有什么吸引力。

后按:这些传言得到了证实,一位来自 fosstodon.org 的 Mastodon 管理员 kev 已被邀请参加和 Meta 的非正式会议。他做出了最好的选择:他礼貌地拒绝掉了,最重要的是,公开了该电子邮件以对其用户保持透明。谢谢 kev !

我知道我们都梦想着让我们所有的朋友和家人进入到联邦宇宙上,这样我们就可以完全避免专有网络。但联邦宇宙并不寻求市场主导地位或是利润,联邦宇宙并不寻求增长。它提供了一个自由的场所。加入联邦宇宙的人都是那些寻求自由的人。如果人们还没有准备好或者并不追寻自由,那也没关系。他们有权留在专有平台上,我们不应该强迫他们进入联邦宇宙。我们不应该不惜一切代价试图容纳尽可能多的人。我们应该诚心诚意并确保人们加入联邦宇宙是因为他们想分享其背后的一些价值观。

在无脑增长、不惜一切代价的意识形态下与 Meta 竞争,我们肯定会失败。他们是这场比赛的大师,他们试图让每个人都进入他们的领域,让人们使用他们熟悉的武器与他们竞争。

联邦宇宙只能坚守阵地,通过谈论自由、道德、伦理和价值观来获胜。通过公开、非商业和非监听的方式讨论,承认目标不是去获胜。我们的目标是继续成为一个工具,一个致力于为互联网上的人类提供自由场所的工具。这是任何商业实体都不会提供的东西。

头图 by David Revoy

]]>
随笔 联邦宇宙 翻译 https://blog.southfox.me/2023/06/%E5%A6%82%E4%BD%95%E6%9D%80%E6%AD%BB%E4%B8%80%E4%B8%AA%E5%8E%BB%E4%B8%AD%E5%BF%83%E5%8C%96%E7%BD%91%E7%BB%9C%EF%BC%9F/#disqus_thread
GPG 浅尝辄止 https://blog.southfox.me/2023/06/GPG%20%E6%B5%85%E5%B0%9D%E8%BE%84%E6%AD%A2/ https://blog.southfox.me/2023/06/GPG%20%E6%B5%85%E5%B0%9D%E8%BE%84%E6%AD%A2/ Fri, 23 Jun 2023 22:27:06 GMT <p>成为 <code>Geek</code> 众多步的其中一步,捣鼓 <code>GPG</code> (</p> 成为 Geek 众多步的其中一步,捣鼓 GPG (

密码学让人掉头发,但也很重要,因为它是「普通人」们在赛博空间的基石。任何对「赛博自由」有兴趣的人都应该看过 GPG 之类的文章或书籍吧,相关的加密工具套件让蚂蚁也有了战胜大象的可能,所以 Geek 们乐于折腾这相关方面的东西也不足为奇了。

前言

话要从哪里说起呢?思来想去发现没什么想说的,毕竟对 GPG 感兴趣的前置条件是对 「赛博自由」感兴趣,而「赛博自由」也是一个很难说清的东西,就像空气一样。空气当然是很重要的东西,但是去卖力「推销」空气只会让人兴趣乏乏。

所以我就单纯列列最影响我对「赛博自由」这一观点的来源了:

网络独立宣言 - 维基百科

《永久记录》 - 爱德华·斯诺登

什么是自由软件? - GNU

零零年左右的那些对互联网有着美好畅想的书籍 - 不管地摊书还是教材

公钥私钥

GPG 是一个加密套件,覆盖了多种加密算法和类型,但是大家一般折腾的都是「非对称加密」的公钥私钥,简单来说公钥相当于一个带锁箱子,私钥相当于对应锁的钥匙。

大家都会把公钥发布出来,然后需要进行加密沟通时就用公钥进行加密(相当于将信件转入箱子并锁上),这样只有持有私钥(相当于对应锁的钥匙)的人才能知道内容。

如果想来点小小的数学风暴可以看:

银行密码系统安全吗?质数(素数)到底有啥用?李永乐老师11分钟讲RSA加密算法(2018最新)

最小系统

GPG 作为密码学软件让人摸不着头脑,一大堆的相关流程让人生怵,不过从繁杂的电路中拆出一个「最小系统」还是可以的,最后系统没冒烟能用下去就没关系了……大概。

GPG 在一众 Linux 发行版中应该是预装的,所以调出个终端直接用就是了,总体来说使用 gpg --full-gen-key 命令就能生成一个了:

  • 输入 gpg --full-generate-key 开始生成密钥。

  • 密钥类型可以选择默认选项: 1 RSA and RSA.

  • 密钥长度可以使用 4096 来得到强壮的密钥。

  • 选择失效日期,建议 2y (两年)。

按照提示继续设置个人信息,注意名称和邮件在公钥里是公开可见的,所以最好不要填入真名或是公开使用的邮箱。然后就输入一个密码,这个密码会在进行私钥操作的时候需要用到,所以尽量设计得复杂一点同时能记下来(写下来或是放到密码管理器里)。

生成完以后可以使用 gpg --list-keys [生成密钥时填的邮箱地址] 来列出具体的信息(也可使用 -k 来简写 --list-keys 选项):

1
2
3
4
5
6
7
8
# 例如 
gpg --list-keys test@outlook.com
# 可能输出以下结果
sec rsa3072 2023-01-01 [SC]
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
uid [ultimate] test <test@test.com>
ssb rsa3072 2023-1-01 [E]
ssb rsa3072 2023-1-01 [S]

其中 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 的 40 位字符对应的是 finperprint (密钥指纹),在认证其它人的公钥时会用到。

发布公钥

接下来就是将公钥发布出去了,具体来说用:

gpg --export --armor [密钥指纹] > pub_key.gpg

就能将公钥导出为文件,其中 --armor 选项是导出为人类可读形式,可用可不用。

得到这个公钥之后就是将它发布出去,例如将文件发在网盘上分享;或是将其内容发在共享文档上(需要使用 --armor 选项);或是发布在博客上。

或是使用 gpg --send-key [密钥指纹] 命令将其发在公共 keyserver 上,但是默认使用的公共 keyserver 没有可删除性,就是说无法撤销,所以要保证生成公钥时没填入敏感信息。

WKD

当然也有一种方式是通过 WKD (Web Key Directory) 方式公布自己的公钥,WKD 的思想很简单,就是将邮件地址的哈希串放到规范的指定位置,在使用支持 WKD 的客户端时就会默认从对应的地址导入公钥 (GunPG 2.1.23 版后默认从 WKD 地址导入)例如 aheinecke@intevation.de 的邮箱地址就对应 https://intevation.de/.well-known/openPGPkey/hu/g8td9rsyatrazsoiho37j9n3g5ypp34h

要获取 WKD 哈希可以使用 gpg -k --with-wkd-hash [生成密钥时填的邮箱地址] 命令:

1
2
3
4
5
6
7
pub   rsa3072 2023-01-01 [SC]
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
uid [ultimate] test <test@test.com>
****************@test.com
ssb rsa3072 2023-1-01 [E]
ssb rsa3072 2023-1-01 [S]

其中 **************** 那串字符串对应的就是 WKD 哈希。

之后可以使用 gpg --export [生成密钥时填的邮箱地址] > [WKD 哈希] 导出为文件,然后放到对应的服务器上,如果使用 Nginx 可以在邮箱对应的域名(如 aheinecke@intevation.de 对应 intevation.de 域名)配置文件下这样写:

1
2
3
4
5
6
7
8
9
location /.well-known/openpgpkey/hu {
add_header Access-Control-Allow-Origin *;
alias /var/www/html/.well-known/openpgpkey/hu; #对应的具体路径
}
location /.well-known/openpgpkey/policy { # 可能一些旧版实现会用到这个路径
add_header Access-Control-Allow-Origin *;
alias /var/www/html/.well-known/openpgpkey/hu; #对应的具体路径
}

之后可以在其它账户或设备上使用 gpg --locate-key [生成密钥时填的邮箱地址] 来测试能否导入公钥(需 GunPG 2.1.23 及以后版本)。

验证公钥

非对称加密的一个致命处就是如何保证收到的公钥真的是所发布的人呢?所以需要进行确认,最理想的做法是将公钥拷到移动设备上然后肉身跟需要交流的人碰面然后互换公钥。当然赛博空间上很难做到这一点,所以需要设立多个源进行交叉验证,例如在网盘分享公钥出来然后在博客上公布出密钥指纹;将公钥通过邮件发送然后通过电话方式通知密钥指纹等,这样才能防止可能潜在的欺骗行为。

比如我通过 WKD 方式发布了公钥,那么我要在博客的相关页面公布出指纹来方便他人确认。

以及……

选用一个支持这些操作的客户端,比如 Thunderbird 进行加解密操作并不算太复杂,可参见自由软件基金会写的指南:

电子邮件加密指南 - FSF

当然 GPG 还有其它的用法比如签名或是文件加解密等,或是硬件设备之类的,但是这些就太掉入「兔子洞」了。

同时 GPG 作为一个加密中的 「瑞士军刀」为了广泛用途也带来了很多其它问题,所以其实更适合作为一个「兜底方案」。平常应该使用专门针对使用场景的设计方案例如文件加密使用 Age ,聊天使用 Matrix 等。

参考

]]>
技术 GPG 自托管 https://blog.southfox.me/2023/06/GPG%20%E6%B5%85%E5%B0%9D%E8%BE%84%E6%AD%A2/#disqus_thread
使用 Mastodon 作为博客的评论系统 https://blog.southfox.me/2023/06/%E4%BD%BF%E7%94%A8%20Mastodon%20%E4%BD%9C%E4%B8%BA%E5%8D%9A%E5%AE%A2%E7%9A%84%E8%AF%84%E8%AE%BA%E7%B3%BB%E7%BB%9F/ https://blog.southfox.me/2023/06/%E4%BD%BF%E7%94%A8%20Mastodon%20%E4%BD%9C%E4%B8%BA%E5%8D%9A%E5%AE%A2%E7%9A%84%E8%AF%84%E8%AE%BA%E7%B3%BB%E7%BB%9F/ Fri, 16 Jun 2023 11:20:30 GMT <p>又在博客的评论系统上左右摇摆了,就算没有人来评论。</p> 又在博客的评论系统上左右摇摆了,就算没有人来评论。

之前写过一篇使用 Giscus 作为博客评论系统的文章,一年下来的使用体验感受良好,只需要经过一点点配置就能为博客嵌入一个支持 Markdown 支持、代码高亮、表情回应、邮件通知、数据背靠 GitHub的评论系统,性价比十分之高。但代价也是背靠 GitHub ,作为一个大商业公司「发病」是一个不断扔骰子的过程,随着时间流逝,扔出个「大发病」的概率将会趋近于必然。可能是什么「大会员」或是「API 收大费」。为了避免最坏情况发生所以有必要准备一些备选方案。

比如 Cusdis 是我之前尝试过一阵的评论系统方案,虽然各方面都比较优秀,但是它上面的一些小小「毛刺」最终让我放弃继续使用(主要是一些样式问题),更大的原因也是我开始觉得为了一年不到十多条的评论是否有必要开一个数据库+评论系统。

所以最后是打算复用一些已经建立的应用作为博客的评论系统,例如 cactus 评论系统就可以使用 Matrix 聊天协议作为博客的评论系统。不过我觉得着有点「重」了,而且 Matrix 主流实现 Synapse 对于房间、媒体管理这些支持并不算太好,要是被恶意刷请求之后很难清理干净。

所以最后将目光放向了 Mastodon ,现在谷歌上搜索 mastodon blog comment 就能搜索出很多方案,本次我也是参(tou)考(qie)整(feng)合(he)了其中两篇的解决方案:

Adding comments to your blog, powered by mastodon

Mastodon as comment system for your static blog

主要思想就是利用 Mastodon 的帖子 API 获取一条博文下的所有回复,然后处理后插入的指定位置,并不是太复杂。

实现

作为一个备选方案我并没有删掉之前基于 Giscus 的评论方案,现在是处于共存状态。要启用基于 Mastodon 的方案就在文章的元数据中指定 fedi_url 这个变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<% if (item.no_comment){ %>
<!-- no comment -->
<% } else { %>
<% if (item.fedi_url){ %>
<div id="comments">
<p id="mastodon-comments-list"></p>
<script src="<%- url_for('./js/fedicomment.js') %>" post-url="<%- item.fedi_url %>"> async</script>
</div>
<noscript>Enable JavaScript to view the comments.</a></noscript>
<% } else { %>
<script src="https://giscus.app/client.js"
data-*="……"
async>
</script>
<% } %>
<% } %>

然后引入 fedicomment.js 这个文件,不直接通过模板直接写入主要还是因为自己自找没趣设置了 CSP 禁止 inline javascript

1
<script src="<%- url_for('./js/fedicomment.js') %>" post-url="<%- item.fedi_url %>"> async</script>

这一段指定了 post-url 这个属性,作为一个变量传入脚本文件里,参见:Get data attribute of script tag?

之后在脚本文件里将作为全局变量调用:

1
var post_url = document.currentScript.getAttribute("post-url");

实际的脚本文件课参见 GitHub 上: fedicomment.js (毕竟要是直接复制过来也太凑字数了),不过实际也是整合了前面提到的两篇参考文章。

缺点

麻烦:使用这套方案的最大特点就是要多一步操作,因为 Mastodon 的帖子 id 是根据时间戳生成的,不能提前知晓。所以得在 Mastodon 发好文然后获取帖子链接才能插入到博文这里。或许通过配置自动构建的形式使用帐号的 token 预先发好帖然后自动插回文件再提交是种解决办法,但是肯定少不了折腾。而且虽说是在博客上的评论系统但是不能在博客上直接评论。

管理:如果不是身为站点管理员的话,那么将无法管理帖文下恶意评论,只能在站点层面的封禁才能移除评论。而且即使身为管理,想要删除单条帖文还得先进行「检举」操作标记这条帖文,然后在管理后台才能删除单条帖文的操作。

限制:如果站点开启了「安全模式」的话,那么将无法直接调用帖文的 API ,这样自然谈不上在博客中显示评论了。

总结

总体来说,对于想复用服务的人或是联邦爱好者来说可以一试,不过其实相比 Mastodon ,直接在博客上用 Serveless 函数平台服务兼容 ActivityPub 协议似乎是个更好的选择?不过这就相当于从依赖 GitHub 改为依赖其它平台了……

]]>
技术 技术 Mastodon 联邦宇宙 https://blog.southfox.me/2023/06/%E4%BD%BF%E7%94%A8%20Mastodon%20%E4%BD%9C%E4%B8%BA%E5%8D%9A%E5%AE%A2%E7%9A%84%E8%AF%84%E8%AE%BA%E7%B3%BB%E7%BB%9F/#disqus_thread
2022年终总结 https://blog.southfox.me/2023/02/2022%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/ https://blog.southfox.me/2023/02/2022%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/ Thu, 02 Feb 2023 02:22:57 GMT <p>都二月份了!</p> 都二月份了!

今年的年终总结来得晚是因为去年末今年初得病外加农历新年无所事事浑浑噩噩打游戏,不过《开拓者:正义之怒》还是挺好玩的,一种单人跑团代餐。

自托管

回流

2022 年想必我的关键词是 自托管 一词了,一些常用的服务自己搭起来,在上面也费了很多功夫(不过也有很多功夫也是处于一种折腾了最后没怎么用的状态)。虽然前几年自己也在上面折腾过一些东西,不过这次面向到整个互联网感觉还是很不一样的,让我体会到了零几年的教科书绘声绘色介绍互联网的感觉,整个人类的宝库……和远在天涯海角的人……联系……

小时候被妈妈带着的时候,通过企业很早就接触到了互联网,第一个打开的网站好像是什么小游戏网站吧,太小了!甚至连当初的情绪都不记得了,新奇?幸福?还是对滑鼠的小球更感兴趣?然后也因为实在没办法去照料,小学一年级就开始全宿制。这个年纪根本就没有全宿制的安排,都是宿管阿姨在照料。不过我似乎也挺乐在其中,可能我就是那样一种自己能陪自己玩的人吧。

就在这时侯除了玩沙坑也就只能读读书了,或许是这时的书深深影响了我吧,书中对互联网的畅想搭配上蜻蜓点水般的体验,造就了我对于互联网不切实际的幻想。可惜现在互联网成为了大家眼中时好时坏的工具,像是在一望无际的荒原中行走。

没想到二十年后早期互联网的感觉又冒出来了,也许就互联网也像时尚界一样,二十年来一次回流吧。

若水

自托管的好处就是数据在自己手中了,当然实际情况还是要打个问号,甚至惊叹号的。因为自托管面临的问题实在太多了,其中一个方面只要碰上一次「大失败」就要黯灭。但是谁叫这种自在感就是令人舒畅呢?在避无可避的「大失败」来临前再作弄一阵子吧。

Emacs

当然还有一件事就是找到了一个能折腾好久的「玩具」,Emacs。对此也没有什么好说的,因为这一年的博客百分之八十都在谈它。当然很多时候是假喜欢,很多东西都没有深入了解过,但没关系,它就在那里,直到我再也忍受不了它的毛病为止,我应该还能在摆弄上几年吧。

面纱

严格来讲,去年定下的目标和展望都没有实现多少,关爱身体啦、认清「现实」啦、磨炼技术啦等等,不过其实回头来看,盯着石像上的面纱,还是舞动了几分的。世界依然朦胧,但我已在月色下盯着湖面发呆,即使挨不到清晨的到来,此刻还算不赖。但是随着世界终于回归正轨,今年还是要稍微「正常」一下,至少为一个目标所努力。

2022 年,对我来说是失去的一年,就像「失去的十年」一样(气候变化上的说法),大家在扯皮中丧失希望,嘟囔着十年什么事都没干成,世界末日已经来临。但回过头来看世界并没有被毁灭,在一地鸡毛里,一些希望正在发展。

没有毁灭,但是问题依然存在,但随着绝望的潮水退去,踩在「正常」的大地上……或许回想起几年后的场景,没来头闲逛时发现当时的痕迹我一拍脑门想到,「啊,当时的水位~竟然有这么高吗?」

]]>
随笔 随笔 年终总结 https://blog.southfox.me/2023/02/2022%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/#disqus_thread
Emacs 使用再记(3) https://blog.southfox.me/2023/01/Emacs-%E4%BD%BF%E7%94%A8%E5%86%8D%E8%AE%B0%EF%BC%883%EF%BC%89/ https://blog.southfox.me/2023/01/Emacs-%E4%BD%BF%E7%94%A8%E5%86%8D%E8%AE%B0%EF%BC%883%EF%BC%89/ Sun, 15 Jan 2023 15:22:05 GMT <p>两种喜欢的事遇到一起,多是一件美事啊。</p> 两种喜欢的事遇到一起,多是一件美事啊。

折腾 Emacs 最重要就是开心,而能开心的事莫过于想实现的功能已经提前有人去实现了,这时候只要愉快导包就好了。

Mastodon

Mastodon.el 是一个 Emacs 平台的 Mastodon 客户端,为什么啥事都要用 Emacs 来实现呢?因为只要将文字送入 Emacs 解析,那么就能够和其它包进行联动,这可是很诱人的事啊。

安装

Mastodon.el 也已经上传到了 MELPA 上面,可以直接进行安装。使用时只要指定实例地址和用户名:

1
2
(setq mastodon-instance-url "https://social.instance.org"
mastodon-active-user "example_user")

然后直接 M-x mastodon 运行指令,然后就会往剪贴板复制一串授权地址,粘贴到登陆的了实例浏览器进行打开,获取授权码再复制回 Emacs 就能完全授权了。

使用

当然如果是使用 Doom emacs 配置集的话,自带的 vim 按键绑定会覆盖掉 mastodon.el 的自带按键设定,所以还是得自己设置一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
(map! :leader
:prefix ("o")
:desc "Mastodon" "M" #'mastodon)

(map! :after mastodon
:map mastodon-mode-map
:n "[ [" #'mastodon-tl--goto-prev-toot
:n "] ]" #'mastodon-tl--goto-next-toot
:n "g k" #'mastodon-tl--previous-tab-item
:n "g j" #'mastodon-tl--next-tab-item

:n "q" #'kill-current-buffer
:n "Q" #'kill-buffer-and-window

;;; timelines
:n "#" #'mastodon-tl--get-tag-timeline
:n "A" #'mastodon-profile--get-toot-author
:n "F" #'mastodon-tl--get-federated-timeline
:n "H" #'mastodon-tl--get-home-timeline
:n "L" #'mastodon-tl--get-local-timeline
:n "N" #'mastodon-notifications-get
:n "O" #'mastodon-profile--my-profile
:n "P" #'mastodon-profile--show-user
:n "T" #'mastodon-tl--thread

;;; toot actions
:n "K" #'mastodon-toot--bookmark-toot-toggle
:n "R" #'mastodon-toot--toggle-boost
:n "c" #'mastodon-tl--toggle-spoiler-text-in-toot
:n "C" #'mastodon-toot--copy-toot-url
:n "o" #'mastodon-url-lookup
:n "d" #'mastodon-toot--delete-toot
:n "D" #'mastodon-toot--delete-draft-toot
:n "f" #'mastodon-toot--toggle-favourite
:n "r" #'mastodon-toot--reply
:n "u" #'mastodon-tl--update
:n "v" #'mastodon-tl--poll-vote

;;; toot!
:n "t" #'mastodon-toot

;;; mastodon additions
:n "S" #'mastodon-search--search-query
:n "V F" #'mastodon-profile--view-favourites
:n "V B" #'mastodon-profile--view-bookmarks
:n "V L" #'mastodon-tl--view-list-timeline
)

第一处就是使用 SPC o M 来打开 mastodon.el 这个包,实现快速摸鱼,第二处设置则是照虎画猫其他人的配置来实现的,虽然没看文档(坏习惯),但是猜测 :map mastodon-mode-map 是选择指定那个模式下的按键配置,:n 是覆盖 vim 那个模式下的按键绑定,n 应该是普通模式。

按键绑定改来改去,要在不影响原本的 hjklwby 常用指令还要做到方便(自己)记忆还是有点难的,毕竟能兼容了原本按键绑定进行复制粘贴起也比较好操作。

总体来看还是倾向于一个补充,毕竟 Emacs 网络相关的操作确实不太行,跟 Web 端确实是不能比的,但是能够快速摸鱼外加和其它包联携的潜力(比如打开收藏夹进行进行分析;直接拷贝嘟文内容送入待办等),还要啥自行车呢。

Matrix

接下来就是聊天了,其实作为和 Emacs 同一个时代的产品,IRC 自然是支持众多的,不过我已经选择另一款聊天协议了 Matrix

安装

虽然也有一些包支持但是现在还在积极开发的也就 ement.el 其作者 alphapapa 也是有名的 Emacs 使用者了,写了很多流行的包。

ement.el 现在也是上传到了 GNU ELPA 可以直接进行安装,但是实现起来那叫一个坑多啊,虽然大部分都是自己的问题。

安装后首先要登陆,但发现一直登陆不上去,之后排查是自己的 Delegation 功能没有加上 https:// 例如 return 200 '{"m.homeserver": {"base_url": "synapse.matrix.org"}}'; ,应该是 return 200 '{"m.homeserver": {"base_url": "https://synapse.matrix.org"}}';

没有做到这一点导致 ement.el 发起的链接不成功,虽然很想指责一下是包的健壮性不足但姑且还是把责任揽到自己身上吧……

登陆之后发现解密不了加密消息,看说明才发现是 ement.el 不原生支持加密功能,想想也对,想支持得用 ELisp 去造轮子太麻烦了(当然我觉得主要原因是作者对于用 Matrix 发送加密消息没什么兴趣)。

配置

不过还有曲线救国方案就是用 pantalaimon ,一个代理程序,可以将加密消息解密提供给其它不支持加密的客户端使用。

安装上可以直接用 pip 进行安装 pip install pantalaimon 之后得编辑 ~/.config/pantalaimon/pantalaimon.conf 下的配置文件指定实例地址和相关配置。

1
2
3
4
5
6
7
[配置名称,随便填]
Homeserver = https://实例地址
ListenAddress = localhost
ListenPort = 8009
VerifySessions = False
UseKeyring = False
IgnoreVerification = True

注意如果启用了 Delegation 功能的话实例地址得填真正使用的服务地址。后面三行是不断试错加进去的,因为这个程序真的是缺文档,所以也不清楚对实际运行有没有影响。

之后再启动程序 pantalaimon --log-level debug ,但是现在还没有真正运行,首先在 Emacs 里进行登陆并且指定使用的地址:

按下 M-S ; 运行指定本地反代的地址的指令:

1
(ement-connect :uri-prefix "http://localhost:8009")

然后输入帐号密码进行登陆,看日志应该能发现有所输出,等待到数据同步后 Emacs 显示了房间列表后。切换到另一个已经登陆的客户端上应该能发现两个设备进行登陆,一个叫 pantalaimon 另一个是随机字符串是 ement.el 使用的。两个都显示未支持加密功能。这时先用 Emacs 进入一个开启加密的房间然后用 ement-room-send-message 指令发送一条消息,理所当然的不会成功,因为 pantalaimon 还没通过验证,但现在应该会显示 pantalaimon 设备变成支持加密的未知设备了。

这时在开启一个终端输入 panctl 指令进入控制,参考这篇文章进行验证操作 ,具体来说就是用指令 start-verification @自己帐号:自己实例 @自己帐号:自己实例 已经登陆的设备的设备号 发起验证,然后用那一个已经登陆的设备确实验证请求开启交叉验证……其中可能会卡住或许要多发起几次。

确实 emoji 匹配后就使用 confirm-verification @自己帐号:自己实例 @自己帐号:自己实例 已经登陆的设备的设备号 指令验证 pantalaimon 设备。转过头去 Emacs 里再尝试发起加密房间的消息查看是否成功。

再配置

之后如果希望将 pantalaimon 作为系统服务开机自启的话就发现不行,会遇到相关总线问题,因为其中一些 pyDbus 什么的调用导致无法挂在后台吧。

权宜之计是按照这个说法手动编辑 pantalaimon 包下的 ui.py 文件关闭 UI 功能:

1
UI_ENABLED = False

然后就能当作 service 进行管理理,代价就是无法使用 panctl 命令,不过只要没有再配置的需求还是能接受的,或是从一开始就使用 Docker 然后按照这说法进行配置。

再再配置

然后记得配置

1
(setq ement-save-sessions t)

将会话数据保留下来,要不然每次登陆都会新申请一个设备,每开一次 Emacs 来这样一次那很快就要达到上百个设备了。

配置此选项后关闭 Emacs 应该能注意到关闭 Emacs 会将会话数据写入,没有的话还得重启 Emacs 使用(ement-connect :uri-prefix "http://localhost:8009") 指令再登陆几次。检查 ement-sessions-file 变量是否有被设置,默认是 "~/.cache/ement.el" ,到该路径检查,有没有设置反代地址和保存了相关 token ,有的话就万事大吉了,之后也可以直接用 ement-connect 直接登陆,因为反代地址已经保存了所以也不用再去特意指定。

再再再配置

mastodon.el 问题一样,Doom emacs 的按键绑定会覆盖掉相关绑定,不过我想将上面让人头大的解决掉按键绑定就不是什么难题了。

总结

两款常用服务配置下来那就挺让人舒适的了,快速刷轴摸鱼,聊天也可以在 Emacs 实现,主要优点是不走 Web 端的话,资源是比较省的,不用再加载几兆几十兆的脚本外加浏览器吃掉的内存了,两种喜欢的事加起来,多是一件美事啊。

]]>
技术 技术 Matrix Mastodon https://blog.southfox.me/2023/01/Emacs-%E4%BD%BF%E7%94%A8%E5%86%8D%E8%AE%B0%EF%BC%883%EF%BC%89/#disqus_thread
Arch 系统随便用暨 Emacs 使用再记(2) https://blog.southfox.me/2022/12/Arch%E7%B3%BB%E7%BB%9F%E9%9A%8F%E4%BE%BF%E7%94%A8%E6%9A%A8Emacs%E4%BD%BF%E7%94%A8%E5%86%8D%E8%AE%B0%EF%BC%882%EF%BC%89/ https://blog.southfox.me/2022/12/Arch%E7%B3%BB%E7%BB%9F%E9%9A%8F%E4%BE%BF%E7%94%A8%E6%9A%A8Emacs%E4%BD%BF%E7%94%A8%E5%86%8D%E8%AE%B0%EF%BC%882%EF%BC%89/ Sat, 03 Dec 2022 20:00:00 GMT <p>我还挺喜欢用 <code>Manjaro</code> 的,就喜欢这种低人一等的感觉。</p> 我还挺喜欢用 Manjaro 的,就喜欢这种低人一等的感觉。

反正系统相关的我也不懂啦,用着玩的,不想对这些 Linux 发行版使用什么个排序算法争出个最优。用 Manjaro 单纯就是安装方便同时教程好找点……不过最近(二十天前),当我更新包时突然开始报错「libssl3.0 未找到。」去网上搜发现五六天前 Manjaro 论坛就有此问题,但也只是捕风捉影并没有实际解决方案。

之后电脑新开一些应用已经打不开了,在终端里也只会一直显示库错误,估计系统已经成为一个僵尸了,一旦重新启动估计就会立马爆炸吧(重新启动果然如此,连终端环境都进不了)。

没办法,重装吧!对于这种问题向来我都是重装解决一切问题的,心想这次还是不要用 KDE 了,试试其它桌面环境吧,结果没想到 Manjaro 系统安装程序会卡在最后一步安装系统引导上(现在想来应该是智熄操作没有选到 UEFI 选项导致的)。

Arch 随便用

懒不动

那么既然已经装不下了那就换个口味吧,换成更上游的 Arch 。之前一直没用 Arch 的原因就是系统安装没有提供一个图形化界面,就觉得很麻烦,不过查 wiki 时发现现在会附带一个 archinstall 程序辅助安装,那么就尝试用用看吧,能这么惬意决定重装也是因为大部分数据都是放在另一快数据盘上,是和系统盘分开的。

第一时间就发现的是 Arch 的镜像挺小的,1G 还不到,但之后就发现为什么是这样了。因为只包括了基本的组件,要成为一个能用系统的东西还得从网上下,在运行 archinstall 还要需求联网还卡住了几分钟的我才顿悟到……

不过说是辅助安装但也只是一个选项菜单而已,方便选择磁盘之类的,不过总比没有好吧,选好系统环境、额外包、挂载目录进行安装……最后报错识别不了另一个盘的某个分区,又不是在安装的盘上为什么还要去管其它盘上的事啊,重试了几次后依然卡在这里,没办法,想懒懒不动了,只好自己手动装了。

随便装

手动装就一步一步自己慢慢盯着了,看着 wiki 再顺便开几个教程帖,之后慢慢对着下来,无非就是选择分区然后挂载点之类的(我这种大懒狐一个 / 就够了),然后选择速度快的镜像站把基础系统组件还有网络管理包之类的装上去就完事了。

之后 unmount,重启,噔噔噔……新系统就来了,不过没有选择桌面环境所以显示的还是挺「刻板印象里的黑客风」黑黢黢命令窗口。桌面环境想了想还是选择 GNOME 吧,没错,我就喜欢卡又多 BUG 低人几等的感觉,只能说习惯的力量还是惊人的,本来其实还想体验 i3 环境来着但是到现在一次都没打开过(

安装重新登陆后,一个毛坯房 GNOME 环境就出来了,看看系统占用,发现真的挺轻量的,内存占用在 1.5G 左右,只有 Manjaro 一半左右。感想就是 Minecraft 热门整合包和自己配整合包吧,现在自用的这款系统还是有点缺东少西,比如最重要的代理和 Emacs 了。

随便折腾

代理的事因为相关软件挂在 yay 上,但是安装 yay 要自己构建下一大堆 GO 相关东西而又需要代理环境,经典先有鸡还是先有蛋了属于是,不过好在可以用其它设备开放的代理环境救救急,这时候才发现 Manjaro 默认把 yay 集成到了自己的源中是有理由的……

安装 yay 后就能愉快的继续偷 Arch 的……嘶,我现在就是 Arch 系统了,所以是光明正大来用!

编辑器

首先是使用 neovimEmacs 这位大爷还是等所有东西都搞定了在把祂请过来吧。

字体

1
sudo pacman -S noto-fonts-cjk

庞大的汉字在计算机世界还是要折腾一番的,不下中文字体开个浏览器就全是口口口的豆腐框了,所以要 noto(fu) 字体来拯救一下。

输入法

好在在之前系统自爆前把 Rime 的配置文件抢救了下来,所以直接使用相应包:

1
sudo pacman -S fcitx5-im fcitx5-rime

然后编辑 /etc/environment 文件,添加以下几行

1
2
3
4
5
GTK_IM_MODULE=fcitx
QT_IM_MODULE=fcitx
XMODIFIERS=@im=fcitx
SDL_IM_MODULE=fcitx
GLFW_IM_MODULE=ibus

然后重新登录就好了,反正 ArchWiki 是这么说的,之后把之前备份的 Rime 配置覆盖回 ~/.local/share/fcitx5/rime 里就好了,使用的方案是 双拼自然码方案rimerc ,毕竟没有网络词和大公司的算法加持,想要加快输入速度只能从自己的手法上入手了。

按键绑定

1
sudo pacman -S gnome-tweak-tool

突然发现 Gnome tweak 里面的 Keyboard & Mouse 里有一个 Emacs Input 选项,打开它后就能在操作系统里实现 Emacs Keybinding 了,就 C-a 将光标移动到行首这种的,真实 Emacs EveryWhere 了。然后 /usr/share/themes/Emacs/gtk-2.0-key/gtkrc 文件是具体的配置,可以让猫猫来看具体定义了哪些按键(我是指,cat 命令……)

窗口切换

1
sudo pacman -S gnome-shell-extensions

然后在 gnome-extensions 开启 Window List 选项,这样就能像 Win 系统一样显示一个任务栏在窗口底部,如果这不是默认启用的我真想不到平常使用 GNOME 是怎么切换窗口的?难道这是 Win 系统带来的我永远摆脱不了的烙印?

钥匙环儿

1
sudo pacman -S gnome-keyring

我一般使用 Nextcloud 的桌面客户端来同步数据的,如果缺少这个就会无限首次重新需求登录,似乎 Minecraft 启动器也会有这个问题,所以还是得装的。

其它

其它的有了 yay 也挺容易装了比如 oh-my-zsh 之类的,看情况调个顺眼的用用,

其中 keyd 这个应用可以改键,把 EscCaps 调换之类的,虽然 GNOME 里有什么组件能改不过我也是路径依懒惯了……

Emacs

终于最后就是把这位神请回来了,

1
sudo pacman -S emacs-nativecomp ripgrep

虽然完全搞不懂但是听说加了 nativecomp 会让运行速度有改善的样子,之后克隆下来 doomemacs 的配置仓库,将之前的备份过的配置文件放入 ~/.doom 里,然后开始安装,之后就只能等了,几百个包安装编译啥的估计要登上十多分钟。

邮件

1
yay -S mu isync

参照这篇文章完成 mbsync(isync) 设定,然后 mbsync -a 拉取邮件,然后参照这篇文章完成 mu4e 配置(mu4edoomemacs 也有相应配置可启用),然后:

1
2
3
4
5
export XAPIAN_CJK_NGRAM=true
# 只需要执行一次 init,可以指定多个邮件地址
mu init --my-address your-mail@qq.com --my-address your-mail@gmail.com -m ~/.mail
# index 在每次收取邮件后都需要执行,mu4e 可以配置自动执行
mu index

就能为邮件建立索引,之后在 Emacs 里使用 Spc o m 即可打开 mu4e 界面进行使用了。

Latex

Emacs 里预览公式需要 latex,使用

1
sudo pacman -S texlive-langextra

安装 texlive 发行版同时还要指定是 extra 包才能应付公式预览。

Emacs everywhere

类似于空间文里的随身空间,直接在任意能输入文字的地方启动一个 Emacs 编辑器,这样就不用离开自己的安乐窝了。

1
sudo pacman -S xclip xdotool xorg-xprop xorg-xwininfo

然后在 gnome 里指定一个快捷键绑定上 emacsclient --eval "(emacs-everywhere)" 就能想用就用 Emacs 这个随身编辑器了。

]]>
技术 技术 系统 Arch https://blog.southfox.me/2022/12/Arch%E7%B3%BB%E7%BB%9F%E9%9A%8F%E4%BE%BF%E7%94%A8%E6%9A%A8Emacs%E4%BD%BF%E7%94%A8%E5%86%8D%E8%AE%B0%EF%BC%882%EF%BC%89/#disqus_thread
Emacs再记(1):传教二度 https://blog.southfox.me/2022/08/Emacs%E5%86%8D%E8%AE%B0%EF%BC%881%EF%BC%89%EF%BC%9A%E4%BC%A0%E6%95%99%E4%BA%8C%E5%BA%A6/ https://blog.southfox.me/2022/08/Emacs%E5%86%8D%E8%AE%B0%EF%BC%881%EF%BC%89%EF%BC%9A%E4%BC%A0%E6%95%99%E4%BA%8C%E5%BA%A6/ Tue, 16 Aug 2022 14:17:20 GMT <p>论都 2022 年了为什么要用 Emacs 。</p> 论都 2022 年了为什么要用 Emacs 。

Emacs 最早可以追溯到 1975年,经过多年发展诞生了许多分支,不过现在都是特指 GNU Emacs,时间没有葬送这款软件,直至现在也有不少人在使用它。

Emacs 之世界观

经过将近一年的使用,我对于 Emacs 也有了更多的了解,索性再写一遍第(1)篇吧。

Emacs ,其官网对它的描述是:一个可拓展的、客制化的自由(免费)文本编辑器—and more。当然这么多天用下来,我发现其实 Emacs 本质并不是一个文本编辑器,因为它有一片自己的世界……

举个不恰当的例子来说,其它文本编辑器里编辑文本像是挥舞武器,安装一个插件并运用其功能像是吟唱一个魔法,其底层实现方式大家都一样,之间的区别不是很大。

Emacs,表面看是挥舞武器,但实际是因为心中有战斗的决心所以才能具现一把专属武器并战斗,表面上看是吟唱魔法,但实际上是因为其所在世界是一个失落的高科技世界,吟唱魔法其实是在和空中散落的纳米单元进行沟通然后由单元实现具体效果……虽然最后 Emacs 和其他文本编辑器实现了同样效果,但是它们的「世界观」是有根本不同的。

自由

查看 Emacs 代码仓库就能发现,其构成代码有近六成是由一个叫作 Emacs Lisp 的语言构成的,Emacs 以其说是一款文本编辑器倒不如说是作为 Emacs Lisp 的运行环境,打开软件那出现的窗口和菜单,是 Emacs 自己不断修改自己的体现。

这样的实现方式,更是让 Emacs 对于用户的态度和其他编辑器有很大不同,再举个不恰当的例子来说:

其它文本编辑器就像一个人类:

  • 想要其它功能的话请指定,比如沟通语言从英语切换成汉语……什么?想要克林贡语,不好意思,没有,请自行查询插件商店吧。

  • 商店里没有?请自己参照接口标准自行实现一个吧?什么,你还想要修改大脑的核心功能?不可能!太危险了!

  • 真想要修改大脑核心功能的话,请自行修改「源代码」去。

Emacs

  • 犹如一个不定形的阿米巴变形虫,时刻不停在蠕动、变形……
  • 想要切换到特定功能?好啊好啊,请自行在「配置文件」里指定吧……
  • 没有想要的功能?那请自行在「配置文件」里实现具体功能吧……等我重载之后就能看到新功能了……
  • 想干预一个核心功能?随便……

所以对于 Emacs 来说,它不像其他软件的 .ini .env 一样,只能附加几个参数或者在 AB 已有的功能切换,在 Emacs 里,没有 C 功能,你可以自行在「配置文件」里实现,因为「配置文件」即是「源代码」,因为 Emacs 是在那旧时代下诞生的软件,它完全信任用户。

混乱

当然自由的代价就是导致了其黑魔法满天飞,大魔法师用着呼风唤雨,而学徒却看着一大堆选择摸不着头脑。

不过随着社区的聚集,现在也出现了 SpacemacsDoom emacs 这样的整合网上优秀第三方包和配置的配置集,新手直接使用的话可以在一开始时就能体验到 Emacs 生态里的大部分优秀功能。

低效

建立在 Emacs Lisp 上的 Emacs 其一大特征就是……慢……当然大多数场景不会感受到,但是出现了这个情况就真的有点锻炼耐心了。而且 Emacs 说好听点是历史悠久,难听点就是历史包袱过重了,一些上古代码散落在各处,非常高效地拖慢了 Emacs 在一些场景的性能让其低效(感谢 Emacs 让我在 2022 年体会到了多图杀猫的效果)。

甜美错觉

如果在多了解一点的话,可能就会发现很多人都在吐槽 Emacs 用着像是一款操作系统一样,收发电子邮件、记录笔记、安排待办、写代码、甚至进行聊天。因为 Emacs 其「万物皆文本」的哲学,代码是文本,笔记和待办也是,甚至文件列表或是菜单栏也是(文本定义九宫格.jpg),也借助于 Emacs Lisp 的灵活性,只要你能想到有关于文字的编辑功能,你就能够去实现。

而且这些功能都做为一个包被 Emacs 载入,所以这些功能还能进行联动,比如将待办里的任务作为电子邮件发送,将文件夹内的全文搜索结果裁剪为笔记,在笔记中嵌入可以执行的代码……因为这就是 Emacs ,虽然实现的过程中可能像是在布满乐高的地板上赤脚行走,让人痛苦不堪感到沮丧,或许在 Emacs 里实现还不如直接用专用软件效果来得好,但是 Emacs 它就是让人产生了这样的错觉:

我们必须实现,我们必将实现。

参考

Emacs 自力求生指南 ── 前言

一年成为Emacs高手 (像神一样使用编辑器)

怎么学习 Emacs ? 达到真正融汇贯通的境界?

]]>
技术 技术 Emacs https://blog.southfox.me/2022/08/Emacs%E5%86%8D%E8%AE%B0%EF%BC%881%EF%BC%89%EF%BC%9A%E4%BC%A0%E6%95%99%E4%BA%8C%E5%BA%A6/#disqus_thread
如何改变自己 https://blog.southfox.me/2022/08/%E5%A6%82%E4%BD%95%E6%94%B9%E5%8F%98%E8%87%AA%E5%B7%B1/ https://blog.southfox.me/2022/08/%E5%A6%82%E4%BD%95%E6%94%B9%E5%8F%98%E8%87%AA%E5%B7%B1/ Mon, 01 Aug 2022 22:25:48 GMT <p>基本就是 Kurz 的视频的梳理:</p> <p><a href="https://www.bilibili.com/video/BV1334y1j7DD">【Kurz】如何改变自己的人生?@青知字幕组-哔哩哔哩</a></p> <p><a href="https://www.youtube.com/watch?v=75d_29QWELk">Change Your Life – One Tiny Step at a Time - Youtube</a></p> 基本就是 Kurz 的视频的梳理:

【Kurz】如何改变自己的人生?@青知字幕组-哔哩哔哩

Change Your Life – One Tiny Step at a Time - Youtube

img

当今互联网充斥着各种成功学金句、传说和鸡汤,要是你没做成什么事,那么一切都是你的错!

但事实是做出改变就是一件艰难的事。

丛林比喻

img

外部环境就像是一片错综复杂犹如迷宫般的雨林,在里面生活可是件很累的事,还需耗费大量的精力。所以经过千万年的进化,人类的大脑开始学会走捷径。

img

所做出的每一次相同的决定,就像是在雨林中的一个位置上走了一遍,当走的次数多了,大脑就开始重视起这条路径。这条路径就开始变成了一条舒适又高效的道路了,走起这条路来那真是不带任何犹豫的……

如果自己想要做的事仍是一片丛林,那么有什么事已经成为高速路了呢?

  • 看到手机就开始下意识的解锁
  • 躺床上看手机看到深夜哪怕在后半夜叹道自己今天依旧在浪费时间
  • 每次到吃饭的地方总会选择同一家餐馆然后点同样的菜

随着年龄的增长,所建造的高速路也不断增多,所以说年纪越大越不容易改变,因为又有谁能富有强大的拓荒精神抛下高效且安全的高速路,去面对未知且危险的丛林呢?

例行和习惯

img

例行(惯例)是指按照一定步骤去做的事物,例如按照菜谱煮菜、初学开车等,当为一件例行投入大量时间和精力重复多次后,那么……

img

这件例行就会成为一个习惯,习惯是自然发生的,做一件习惯的事不用说服自己,因为……它就是习惯。例如上十年经验的开车、解锁手机并打开某一个社交 APP 等。

幼儿和导师

img

人们总会沉溺在自己的坏习惯中无法自拔,事后又后悔不已,那是因为习惯的背后是由一个「幼儿」所掌握,眼里只有现在马上就能得到的满足。

而很不幸现代社会能马上产生满足事物太多了,袋装薯片、榜上有名的 APP 。沉溺其中也不是件丢人的事,因为它们背后可是站着无数聪明才智之人,重要的是认识到通过自己的意志力战胜这些人是一件困难的事,要思考如何规避避免硬碰硬(例如寻找是否有其它可替代客户端,能否关闭推荐功能或是私人推送功能)。

img

而惯例既是由一个「导师」所掌握的,需要消耗珍贵的意志力去计划并执行,意志力通常在一天内都是宝贵的不可再生资源且通常都不能提升上限(尤其对于有 ADHD 特质的人来说)。

我们联合!

img

「幼儿」是亿万年生物进化路上一直伴随着我们的模块,它对于生物的生存至关重要。「导师」是人类千万年来为了适应社会活动进化出来的模块,它很高效且精妙,但也像游戏中的某些武器一样,开不了几下火就会过热。
如果需要改变自己,让「幼儿」和「导师」一起为你工作,那么「导师」该如何规划道路的路线,让「幼儿」如何能最小抵抗得为道路完成做努力……

专注于小目标

img

不要让躺在待办里的事物是一件吓人的目标,应该是一件每天结束时都能感到有所进展的小目标。让「导师」制定的目标也能像「幼儿」所执行的习惯那样能感到满足感和低抵抗感。

比如「每天写下五张卡片笔记」或是「每天早上十个深蹲」等。

易于触发

img

这通常来说也是最核心的一步了,如何找到一个触发?习惯的执行需要一个触发,比如看到手机、走到一家餐馆等,而自我决定的触发通常是以闹钟为多数。

而对于有 ADHD 特质的人来说,能否准确地实施呢?克服 ADHD 特质最需要一个强有力的外在结构也是如此……

营造一个专用的环境和空间大概有助于此,比如划分出一个专门做这件事的空间,并好好整理一下周围的杂物(杂乱的事物将导致分心的几率大大增加),划分出专门娱乐和学习专用空间(即使缺乏空间也可以在虚拟意义上实现,比如安装两个浏览器,并尽量让自己在学习时只能用专用浏览器)。

每天重复

最难的一步,要让例行转为习惯那需要 15~250 天的时间,很多时候坚持不下来就会让一切照旧……还要加上一些自暴自弃的情绪……

改进

img

在实行的过程也并不是苦修,得尽量让做事的自己少点抵抗,例如放点喜欢的音乐,在跑步时听自己最喜欢的博客等。

结语

img

哪怕只是做出了微小的改变,也是往理想的自己靠近一步,改进没有终点,只有方向。

]]>
随笔 随笔 https://blog.southfox.me/2022/08/%E5%A6%82%E4%BD%95%E6%94%B9%E5%8F%98%E8%87%AA%E5%B7%B1/#disqus_thread
Gitea:一款自托管的 Git 服务 https://blog.southfox.me/2022/07/Gitea:%E4%B8%80%E6%AC%BE%E8%87%AA%E6%89%98%E7%AE%A1%E7%9A%84-Git-%E6%9C%8D%E5%8A%A1/ https://blog.southfox.me/2022/07/Gitea:%E4%B8%80%E6%AC%BE%E8%87%AA%E6%89%98%E7%AE%A1%E7%9A%84-Git-%E6%9C%8D%E5%8A%A1/ Sun, 17 Jul 2022 19:02:07 GMT <p>别忘了泡上一杯茶!</p> 别忘了泡上一杯茶!

绕不开的存在

当然,谈到 Git 服务时,肯定绕不过 GitHub 。为什么要大费周章自建呢?GitHub 不好吗?

是很好,但是也没那么好,因为:

  • GitHub 是一家商业公司,那么首先盈利肯定是首要目的,为了不倒闭,指不准未来哪天就变质了。
  • 同上,如果还是个自由软件爱好者的话,想必 GitHub 最近一些事件带来的臭味也不必我再提了……
  • Git 是分布式的,那么选择同样也是……不知道现在还有多少人还傻傻认为 GitGitHub 是一体的呢?

也可参见 GiveUpGitHub 一文章。

Gitea

Gitea 是一个用 Go 编写、面向自建的、轻量级的 Git 服务。其安装十分便捷,直接下载个可执行文件也可快速搭建起来,当然为了后续跟其它服务联动,还是用 docker-compose 方便点。

话不多说,新建一个文件夹然后往里建 docker-compose.yml 文件并写入以下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
version: "3.7"

services:
gitea:
image: gitea/gitea:latest
container_name: gitea
restart: unless-stopped
environment:
- USER_UID=1000
- USER_GID=1000
volumes:
- ./data/gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "127.0.0.1:3000:3000"
- "2222:22"
networks:
- cicd_net

drone:
container_name: drone
image: drone/drone:latest
restart: unless-stopped
depends_on:
- gitea
environment:
# https://docs.drone.io/server/provider/gitea/
- DRONE_DATABASE_DRIVER=sqlite3
- DRONE_DATABASE_DATASOURCE=/data/database.sqlite
- DRONE_GITEA_SERVER=https://my.git.server/
- DRONE_GIT_ALWAYS_AUTH=false
- DRONE_RPC_SECRET=changeme...
- DRONE_SERVER_PROTO=https
- DRONE_SERVER_HOST=https://cicd.git.server
- DRONE_GITEA_CLIENT_ID=changeme...
- DRONE_GITEA_CLIENT_SECRET=changeme...
ports:
- "127.0.0.1:3001:80"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data/drone:/data
networks:
- cicd_net

drone-runner:
container_name: drone-runner
image: drone/drone-runner-docker:latest
restart: unless-stopped
depends_on:
- drone
environment:
# https://docs.drone.io/runner/docker/installation/linux/
# https://docs.drone.io/server/metrics/
- DRONE_RPC_PROTO=http
- DRONE_RPC_HOST=drone
- DRONE_RPC_SECRET=changeme...
- DRONE_RUNNER_NAME="action-runner"
- DRONE_RUNNER_CAPACITY=2
- DRONE_RUNNER_NETWORKS=cicd_net
- DRONE_DEBUG=false
- DRONE_TRACE=false
networks:
- cicd_net
volumes:
- /var/run/docker.sock:/var/run/docker.sock

networks:
cicd_net:
name: cicd_net

因为预想场景是私人自用,所以选择了 SQlite3 数据库,觉得别扭可以自己改掉……

然后准备两个域名,这里用 my.git.server 域名指定用来运行 Gitea 服务的域名,一个 cicd.git.server 域名用来指定运行后续的自动构建服务的域名(可选)。

首先为 my.git.server 域名设定DNS 后申请证书,certbot certonly --nginx -d my.git.server

,申请后写入 nginx 配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#不要忘了替换成自己的域名
server {
listen 80;
listen [::]:80;
server_name my.git.server;

location /.well-known/acme-challenge {}
location / {
return 301 https://$host$request_uri;
}
}

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name my.git.server;

access_log /var/log/nginx/access.log;
#root /home/plume/Plume/ ;

ssl_certificate /etc/letsencrypt/live/my.git.server/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my.git.server/privkey.pem;

# for ssl conf: https://cipherli.st/
ssl_protocols TLSv1.2 TLSv1.3;# Requires nginx >= 1.13.0 else use TLSv1.2
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;# openssl dhparam -out /etc/letsencrypt/ssl-dhparam.pem 4096
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; # Requires nginx >= 1.5.9
ssl_stapling on; # Requires nginx >= 1.3.7
ssl_stapling_verify on; # Requires nginx => 1.3.7
resolver 9.9.9.9 80.67.169.12 valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
#如果不想显示外链图片可把 img-src 一栏改掉
add_header Content-Security-Policy "default-src 'self'; img-src *; frame-ancestors 'self'; frame-src https:";

location / {
proxy_pass http://localhost:3000/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 50m;
}
}

之后 nginx -s reload 重载配置,然后 docker-compose up -d giteaGitea 服务启动,之后前往 my.git.server 地址进行配置并新建一个管理员账户。

Drone

到此服务就基本可用了,但是我相信很多人割舍不下 GitHub 的一个原因就是因为它的 Actions 很香。不过可以选择 Drone ,一个同样用 GO 编写的、轻量级的自动构建服务,也可以让体验往 GitHub Actions 靠拢。

首先为 cicd.git.server 域名申请证书并写入 nginx 配置文件,配置文件可复用上面的,只需要更改相关域名和 nginx 配置文件里的 location / 里的 proxy_pass 端口号就行(本例子是 3001)。

之后为 DroneGitea 联动做准备,登陆自己 Gitea 实例的帐号→设置→应用→创建新的 OAuth2 应用程序,应用名称随意填(本例子填 drone),重定向 URI 填入 https://cicd.git.server/login (替换成自己的域名)。

点击创建应用→会生成一个客户端 ID 和一个客户端密钥→替换到上述 docker-compose.ymldrone 一栏的 DRONE_GITEA_CLIENT_IDDRONE_GITEA_CLIENT_SECRET

之后再使用 openssl rand -hex 16 命令生成一串随机字符串给 DRONE_RPC_SECRET 使用(有两个地方需要替换)。

确认无误后使用 docker-compose up -d 启动全部服务,之后前往 https://cicd.git.server 地址查看是否正常运行,是的话点击登陆,看是否能够和 Gitea 进行联动,如果显示错误请检查是否与上述配置一致(例如我之前就遇到了无法验证的错误,排查后发现是某个路径多带了一个 / 导致之后生成的验证路径出错,去掉 / 之后就正常了)。

仓库操作

因为宿主机的 22 端口已被占用,所以克隆或者 PUSH 仓库使用的端口应该为 2222,觉得别扭也有其他教程教如何与宿主机共用端口,我就不折腾了(反正 Just work! )。

还有如果为网站使用了 Cloudflare 之类的 CDN 服务的话,那么 SSH 协议也是不能用的,得用网站域名下的真实 IP 地址克隆或 PUSH 仓库。

如果像我什么都没改的话,想要克隆仓库就会得到这么一个奇怪的地址:

git clone ssh://git@机子真实IP:2222/用户名/仓库名.git

反正 Just work

一个案例

那么接下来就讲讲我用这套服务的案例吧,自动生成文件并推送一个 HUGO 博客。

首先为仓库根目录写下 .drone.yml 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
kind: pipeline
name: build

steps:
- name: build
image: klakegg/hugo:alpine
commands:
- hugo

- name: deploy
image: node
environment:
CLOUDFLARE_API_TOKEN:
from_secret: api_token
CLOUDFLARE_ACCOUNT_ID:
from_secret: account_id
commands:
- npm install -g wrangler
- npx wrangler pages publish public --project-name 项目名 --commit-dirty=true

可以见到和 GitHub Actions 的配置还是挺像的,琢磨琢磨还是挺快上手的。

其中 steps 指定了所需步骤,image 指定了需要什么样的 docker 镜像,第一栏拉取了 klakegg/hugo 镜像并使用 hugo 命令生成静态文件。

之后是 deploy 一栏里的 environment ,像 GitHub 一样,密钥相关可以使用 secret 功能导入到环境变量中,可在自己的 cicd.git.server →相关仓库→ SettingsSecrets 里进行导入。

接下来使用 node 镜像安装了个 wrangler 包,这是 Cloudflare Pages 部署要用的,如果也用 Cloudflare Pages 部署的话可以参考:

Wrangler pages commands

Running Wrangler in CI/CD

PS:不得不吐槽相关操作首先必须要用 project create 命令里的 --production-branch 显式指定部署分支否则接下来的部署都会被识别为预览而不会真正部署到……被这个坑卡了好一会……

之后再进行相关操作后应该能看见自己 Gitea 实例也有小绿勾了(小红叉也行,至少证实自动部署服务有在用了)!

加主题

默认主题还挺程序员风格的,既然都自建了,肯定要加点主题快乐一下了。

现代主题为例。

如果是以上面的配置文件搭建起来的话要在自己文件夹下找到 ./data/gitea/gitea 路径,并在里头新建 public/csswget https://codeberg.org/Freeplay/Gitea-Modern/raw/branch/main/Gitea/theme-gitea-modern.css 获取主题文件。

之后再编辑 ./data/gitea/gitea/conf/app.ini 文件,在最后面加上:

1
2
请自己想象下……
因为现在我服务器炸了……

之后再用 docker-compose downdocker-compose up -d 重启服务。

安全

如果没有相关要求,请务必关闭实例的注册功能。

参见,记一次自建 Gitea + Drone 实例被挖矿的经历

也是修改 ./data/gitea/gitea/conf/app.ini 里的:

1
2
请自己查阅……
因为我现在服务器炸了

之后再用 docker-compose downdocker-compose up -d 重启服务,然后再检查站点是否关闭了注册入口。

参考

CICD With DroneCI and Gitea Using Docker Compose

Gitea Docs

Drone Docs

透過 Drone 建立自動部署流程,部署排程設定與權限管理 - 薛丁格的工程師

]]>
技术 技术 建站 https://blog.southfox.me/2022/07/Gitea:%E4%B8%80%E6%AC%BE%E8%87%AA%E6%89%98%E7%AE%A1%E7%9A%84-Git-%E6%9C%8D%E5%8A%A1/#disqus_thread
二二年六月梦记 https://blog.southfox.me/2022/06/%E4%BA%8C%E4%BA%8C%E5%B9%B4%E5%85%AD%E6%9C%88%E6%A2%A6%E8%AE%B0/ https://blog.southfox.me/2022/06/%E4%BA%8C%E4%BA%8C%E5%B9%B4%E5%85%AD%E6%9C%88%E6%A2%A6%E8%AE%B0/ Tue, 14 Jun 2022 18:09:34 GMT <p>能做梦说明我是终于有睡饱了……</p> 能做梦说明我是终于有睡饱了……

6-14 中

预兆

我在一个广场上,一些人就站在其中,广场中间有一个大号喷泉。
我跟着某个人去见……某个人……那个人一见我就立马用手搓着我的脸,我回应了几句,期间他嘴里漏出了几句中文。我问到,你懂中文?
他回应道:“我爷爷后半辈子在太原生活。”
然后他又仔细端详着我的脸,我说:“看相不应该是南方盛行的东西吗?”,他只打了个哈哈就应付过去了。看完相后,他拉着我走起了步伐,不像跳舞,像是……禹步?但是我还是有时像跳舞一样被他一手用手拉着。结束后,他大声疾呼:“大干旱,大旱灾之象啊!”,然后就跑开了。
我只觉得他的语言有点神经,八亿年之久的大干旱?比几百万年的卡尼期洪积事件还要离谱哩,望着广场喷涌的喷泉,我这样想到……

干旱来临

随后就是旱灾来临了,倒是都是躺下的人,可能还有几个还能哀嚎,其他人已经毫无动静了……广场中间的喷泉早已干涸,或许只有中间的泥土还保有几丝湿润。喷泉中躺倒着一人,我望向他,就似乎看到了当时的景象——别死在喷泉里!会污染的!会污染的!滚出去……
我只想找到那个预言家,他去哪儿了?

幕后

巨大的六角形机器浮在空中,然后一道细小的白光闪了出去,打向不远处的另一个六角形,但是一道强光爆发出来,把白光弹回了原六角形处……
一个类似控制式的地方……屏幕亮了起来。
“我们已知晓你所做的破坏活动!还接连破坏了七个地区……严惩……”
然后似乎被某人关掉了,那人连线上了另外一个人,另一个人似乎类似鳄鱼,但是脸确有像阶梯状,非常古怪。控制室内的人叫鳄鱼人把身份信息发过来好进行伪装,说是要这样才能糊弄过那些追查过来的人,看起来那鳄鱼人是什么纳税大户吗?

]]>
梦记 梦记 https://blog.southfox.me/2022/06/%E4%BA%8C%E4%BA%8C%E5%B9%B4%E5%85%AD%E6%9C%88%E6%A2%A6%E8%AE%B0/#disqus_thread
Magit使用随记暨Emacs随记(3) https://blog.southfox.me/2022/06/magit%E4%BD%BF%E7%94%A8%E9%9A%8F%E8%AE%B0%E6%9A%A8Emacs%E9%9A%8F%E8%AE%B0%EF%BC%883%EF%BC%89/ https://blog.southfox.me/2022/06/magit%E4%BD%BF%E7%94%A8%E9%9A%8F%E8%AE%B0%E6%9A%A8Emacs%E9%9A%8F%E8%AE%B0%EF%BC%883%EF%BC%89/ Wed, 08 Jun 2022 14:38:26 GMT <p><code>magit</code> 是个好东西。</p> magit 是个好东西。

Magit 是一个 Emacs 的包,将一大堆长又长的 Git 指令封装成了按键操作,对于受够了了在终端下按够了 TAB 键的人来说,是一种解放,无怪 Magit 的评价在整个 Emacs 生态里评价那么好了。

Git

Magit 是建立在 Git 上的,意味着要使用得先对 Git 有一定了解,Pro Git 是一本不错的入门书,而且做为一本「开源」书籍,也很容易在网上找到可在线浏览的方式。

奇怪比喻

Git 的精髓在于它的设计,工作区、暂存区以及版本库,用 Git 进行工作一般如下所示(图出自 Pro Git)。

用小学生写作业做比喻的话,草稿纸即是工作区,做好相关计算后把结果誊抄到作业本上,作业本既是暂存区(IndexStage),最后确认无误后即可把作业本放入书包,书包既是版本库了。

Git 的设计给了使用者操作上的灵活,却也让人感到冗长,设置别名可以缓解这种情况,不过还是没有优化到单键操作的 Magit 偷懒偷得多。

Magit

一般流程

Doom Emacs 下,使用 SPC g g 即可选择一个 Git 仓库(如果已经打开了一个 Git 仓库的的文件即可直接打开当前仓库下的 Magit 界面)打开 Magit 界面。

Magit 界面下,可以很方便看到工作区发生变动的文件(Unstaged changes),以及已经加入到暂存区的文件(Staged changes)。

光标在某个文件上时,按下 TAB 即可展示文件的变动,按下回车即可直接跳转到文件进行编辑,按下 s 即可将文件暂存,对处于暂存区文件按下 u 即可取消暂存(SU 则是应用于全体文件)。忘掉 git add xxx 吧,谁会怀念它?

确认暂存区的改动后即可进行提交(commit)将其送入版本库了,对应的快捷键是 c,对于很多复杂的 Git 操作附带了很多选项来完成,Magit 把能用的操作都罗列了出来,做到了看菜下饭。

对于提交(commit) 操作,其里面常用的有:

  • - s- S 附上签名消息或使用 GPG 进行签名认证。
  • c 进行 commit 操作,之后会打开一个新区域输入消息,输入完毕后用 C-c C-c 进行确认(C-c C-k 为取消提交)。
  • a 进行 --amend 操作,即为重新进行提交操作,适用于提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了的情况。

实际用习惯了之后基本就是无脑操作了,比如使用 p p 快捷键,即可直接推送到默认的分支上,如果要进行其他操作比如推送到其他分支上,那么按一下 p 之后再看信息提示进行操作也不会太难。

对于更多操作,按下 ? 即可进入提示菜单,或是翻阅 Magit手册了解更多操作。

从实战到跑路

现在来说说我拿 Magit 实际干过的事吧,

首先是要心动,看上了其他分支的功能,打算抄抄作业,那么第一件事就是把对方仓库克隆下来。在 Magit 界面按下 M 即可进入 Remote 界面,按下 a 添加,输入名称以及仓库地址来添加一个 Remote

接着开始检索对方仓库的提交,检出自己需要的提交,按下 l 打开 log 界面,按下 - F 搜索提交消息,之后输入想检索的提交消息,例如 exclusive list,再按下 o ,选择搜索其他(other)分支的历史记录,选择之前添加的 Remote 仓库的分支。

可以看到搜索出了相关的三条结果,从最旧的开始合并,将光标移动到最旧的提交,按下 A A 进行一次 cherry-pick

啊啊啊……!一大堆冲突,毕竟这次的提交很老旧了,是三年前的提交,发生变化很正常……

感叹一句没有银弹,Git 对于冲突也从不僭越,会去自作主张搞定。所以只能自己上了,对于这种老旧的提交,可以前去 GitHub 的那次提交消息里查看改动了哪些文件,再前去最新版本文件下仔细比对最新的样子是什么。当然 Magit 同时也提供了一个命令 magit-log-buffer-fileSPC g L)查看当前文件下有那些提交,

检出更改

不过用这种方式查看双方提交记录的话,得先 Stash 修改再切换到对方分支查看历史记录又切换回来,感觉挺麻烦……所以我就先用 GitHub 查看历史了,或许有更快速方便的方法?

总之,确定该怎样合并后即可进入 Unstaged changes 上的任一文件按下 E 打开 Ediff 选单,再按下 m 解决冲突。

进入冲突选单后,用 n 键跳转到下一冲突处(p 为上一个),接着按下 ab 选择保留那一方的修改,这次的提交要结合两者,所以首先选择一方,然后用 SPC w k 将焦点移动到上方文件编辑区进行编辑,编辑完后再用 SPC w j 将焦点移回 Ediff 区。处理完全部冲突后,按下 q 退出,再处理其他文件的冲突。

处理完全部冲突后,按下 c c 进行一次提交,之后按下 p p 推送到 GitHub 上,祈祷部署能够成功吧!

如果想要合并的提交不是那么久远的话,可以用 Y 按键对应的 Cherries 操作来检出自己想要的提交,虽然我没用过(

]]>
技术 Emacs Git https://blog.southfox.me/2022/06/magit%E4%BD%BF%E7%94%A8%E9%9A%8F%E8%AE%B0%E6%9A%A8Emacs%E9%9A%8F%E8%AE%B0%EF%BC%883%EF%BC%89/#disqus_thread
我拿Emacs做什么暨Emacs随记(2) https://blog.southfox.me/2022/05/%E6%88%91%E6%8B%BFEmacs%E5%81%9A%E4%BB%80%E4%B9%88%E6%9A%A8Emacs%E9%9A%8F%E8%AE%B0%EF%BC%882%EF%BC%89/ https://blog.southfox.me/2022/05/%E6%88%91%E6%8B%BFEmacs%E5%81%9A%E4%BB%80%E4%B9%88%E6%9A%A8Emacs%E9%9A%8F%E8%AE%B0%EF%BC%882%EF%BC%89/ Sat, 14 May 2022 17:34:55 GMT <p>大概也算是卡片笔记法的介绍?</p> 大概也算是卡片笔记法的介绍?

提醒:本文作者用上下列的方法也不是很久,甚至这篇文章还能算做第一个正式产出,所以……请谨慎判断。

卡片笔记

卡片笔记法解决了什么?

在空白处写涂涂写写、划重点、摘抄、不断翻阅资料,但是最后感觉还是学废了,到头来还是什么也没学到,或者记了一大堆笔记但是却成了一个坟墓,每次到里面想要提取点东西简直痛不欲生……

因为不断的阅读书籍并没有对学习产生帮助,反而因为曝光效应而更有害(曝光效应:当我们熟悉某事物的时候,我们还会对其越发喜欢,相信自己理解了,但是熟悉不等同于理解)。

卡片笔记法就是针对这种情况而产生的。

卡片笔记法该怎么做?

我目前所使用的工作流是这样的:

  • 阅读材料,写下关键词或者想法和页数。(闪念笔记)
  • 结束阅读后,通过关键词重构当时的话语,并通过页数返回当时的段落,对照着材料转写成自己的话语录入到笔记系统中。(文献笔记)
  • 当天结束前,浏览自己的所写的文献笔记,思考它能和自己的课题、兴趣、兴趣有何关联。(永久笔记)

闪念笔记

闪念笔记可以……在任何地方开记,餐巾纸、手机、记事本等,只是写下几个关键字而已,并标上页数,结束完阅读后,再通过关键词思索当时的想法,之后通过页数方便返回对照材料。

此举是为了增加想法的必要难度,边阅读、边听课、边看视频边记笔记实在太简单,就像在沙地上浅浅地写字一样,太容易模糊了……而通过记下关键词和页数,再回忆起当时所想记的,这样(大概)就提升了想法的存储强度

文献笔记

文献笔记最重要的是用自己的话简洁得写下阅读材料中的观点。

之所以强迫用自己的话转写,是因为只有这样做才能更好地理解材料里的观点,一味摘抄是不行的……

永久笔记

永久笔记是通过浏览前几步写下的笔记所产生的,卡片笔记盒的思想就是:

一个想法或者笔记只有在它的上下文才有意义,而它的上下文不一定是它在文章中的出处。所以卡片笔记法是要让笔记与不同上下文聚集起来并起到相应的作用。

其中永久笔记应该是原子化的,即应该在没有上下文的情况下也能解释的清楚,这样才能更好的和其他相同的笔记组合成「分子」、「复杂化合物」。

所以为了更好地产生想法,每天划出一部分时间是去回顾是必要的(当然我也老是忘掉)。

Carry on!

简单,简单,简单啊!我说,最好你的事只两件或三件,不要一百件或一千件;不必计算一百万,半打不是够计算了吗,总之,账目可以记在大拇指甲上就好了。不必一天三餐,如果必要,一顿也够了;不要百道菜,五道够多了; – 《瓦尔登湖》

卡片笔记法并不复杂,实践起来只要选用一个专门对此进行优化过的软件就好了,Notionobsidianorg-roam 等都可以,我选用的是基于 Emacsorg-roam

过于复杂的工作流会马上消磨掉自己的耐心,而做事从来不能凭着虚无缥缈的「专注力」去完成,同时卡片笔记法所产生的笔记也让我觉得能在实实在在的做了某事,这样在对抗「不确定性」这一大怪兽面前也能有底气几分。

卡片笔记法也不是什么银弹,不能指望换用软件就能产生很好的效果,比如说卡片笔记法里重要的一点既是用自己的话去转写阅读材料的话语,没了解这一点,换软件后还把软件当成原文摘抄、文章剪辑之地,那么无非是又造了个坟墓,只不过是卡片式的。

任务管理

任务管理也是我拿 Emacs 所做的事,并且他的表现也比较优秀,稍微设置一些模板就能表现的很好。

番茄工作法

番茄工作法,即在做事时划分一段专门用来做一件事的时间,期间不允许做其他事,以期达到更好的做事效果。

蔡格尼克效应

蔡格尼克走近一家餐馆,发现服务员游刃有余得在多个顾客间间穿梭并记下点单且上菜,吃罢饭后,蔡格尼特发现忘记取大衣并折返,还想顺道称赞一下服务员的能力,但她惊讶的发现服务员竟然表示完全不记得她来过了!服务员表示干这一行的都把注意力集中在点单上面了……

蔡格尼特对此事做了研究发现:

相较于已经完成的工作,人们比较容易记得未完成的,或是被打断的工作。这就是为什么我们的注意力很容易被未完成任务的想法所干扰,而不管这些想法的重要性如何。得益于蔡格尼克的后续研究,我们还知道,其实我们并不一定要完成任务才能说服我们的大脑停止思考它们,我们所要做的就是把想法写下来,让大脑相信它会在之后被妥善处理。至于任务是真的被完成了,还是通过记下笔记而推迟了,大脑并不会区分。

Just do it!

而具体的工作流,就是我会专门在一天的开始的时候,通常是泡咖啡的时候打开电脑,开始把今天要干的麻烦事写下来(我同时也把 Emacs 设置成开机启动了,打开电脑就是打开 Emacs)。等到有晚上有时间了,我会把想做的事进行分解,以期降低自己的抵抗心理(例如写一篇文章的任务看起来太困难了,但把它分解成收集材料思考结构完成初稿等就容易一点了)。

Emacs

啊,甜美的 Emacs

org-roam

安装

安装很简单,在配置文件中 ~/.doom.d/init.el 中的 org 模块里加上 roam2sync 一下就好了。

1
2
(org
+roam2) ; organize your plain life in plain text

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
;; org-roam
(setq org-roam-directory "~/Nextcloud/Note/org-roam")
(setq org-roam-capture-templates
'(("m" "main" plain
"%?"
:if-new (file+head "main/${slug}.org"
"#+title: ${title}\n")
:immediate-finish t
:unnarrowed t)
("r" "reference" plain "%?"
:if-new
(file+head "reference/${title}.org" "#+title: ${title}\n")
:immediate-finish t
:unnarrowed t)
("a" "article" plain "%?"
:if-new
(file+head "articles/${title}.org" "#+title: ${title}\n#+filetags: :article:\n")
:immediate-finish t
:unnarrowed t)))

其中 org-roam-directory 是放置笔记文件的路径,我把它设置到了 Nextcloud 的同步目录下,这样换台电脑也能快速查看笔记。

org-roam-capture-templates 是配置笔记的模板,main 是对应的是 永久笔记reference 对应的是 文献笔记article 可以对应的产出文章,虽然我这篇是直接在博客文件夹下写的(

具体使用

经过模板配置后,按下 SPC n r f 输入一个不存在的标题就是新建一个笔记了,再按下提前配置好的键指定是哪类笔记。

按下 SPC n r i 既是在正文中插入一条笔记链接,SPC n r r 既是打开显示双向链接的菜单,能帮助我更好地查看笔记之间的联系。

而通过 SPC n r a 即可随机跳转到一条笔记上,方便我回顾笔记(可惜我太菜了不知道怎么设置成过滤成只显示仅某一类笔记orz)。

同时 org-roam 里还附带了一个日志功能,可以像 Logseq 那样写日志,其前缀是 SPC n r d,但由于太长我一般都是通过 M-x 来进行选择对应功能的,现在我的一些想法和梦记都是录入到其中的。

而对于文献笔记,因为没琢磨透 Emacs 相关文献管理包怎么用,那我就用自带的大纲模式进行折腾了,具体就是用各个标题层级对应书的不同目录,并在最后加上页码,这样也方便我进行回读。

连接

org-roam 第 2 个大版本将里面的链接机制换成了基于 org-modelink,所以让 org-roam 有了跟其他基于文章的双链笔记不同的,有更加精细的操控能力了。

在某个标题使用 org-id-get-creat 就可以把这个标题转换为一个新的卡片笔记了,既使它仍在一篇文章中,这样一篇挤满不同卡片的文件我可以叫他为 卡片桌,可以方便的排列展示各个卡片笔记。

而把 org-link-search-must-match-exact-headline 的值设置成 nil,那么可以编辑链接,设成 [[roam-id:xxx-xxx-xxx-xxx::关键字][描述文本]] 即自动跳转到所选笔记的第一个匹配关键词上,不得不感叹 Emacs 对于文字处理的底蕴之深……

加密

选择了同步意味数据会放到他人的服务器上,所以一些东西不加密实在不放心,所幸其自带了一个包 epa 可以完成加密工作,或是在模板中设置成 xxx.org.gpg 格式就会自动进行加密……当然因为加密设定必须要设置一个同步密钥,对于互相连接的卡片笔记非常不方便(一打开菜单输入四五次加密密码谁受得了啊),所幸其 epa 包里有仅加密一片文本区域的命令 epa-encrypt-region,事先选择好一片文本区域执行此命令,再指定密码即可执行加密了。

MORE!

当然还有其他的扩展包可以用,比如 org roam ui,这个包可以分析笔记文件形成一个网页,让 Emacs 用户也能享受到其他双链笔记软件的那个「花里胡哨」的链接分析图。

任务管理

Emacs 自带了个 org-mode,是做任务管理的一把好手,当然要提前配置好任务模板。

任务模板

1
2
3
4
5
6
7
8
9
10
11
12
;; org-capture
(setq org-agenda-files '("~/Nextcloud/gtd/inbox.org"
"~/Nextcloud/gtd/gtd.org"
"~/Nextcloud/gtd/tickler.org"))

(after! org
(setq org-capture-templates '(("t" "Todo [inbox]" entry
(file+weektree "~/Nextcloud/gtd/inbox.org")
"* TODO %i%?")
("T" "Tickler" entry
(file+headline "~/Nextcloud/gtd/tickler.org" "Tickler")
"* %i%? \n %U"))))

其中 org-agenda-file 是设置将哪些文件拉入到日历视图的计算中,org-agenda 视图可以很方便地查看任务分布情况,当然可设可不设。
org-capture-templates 是设置任务模板,要用 after! 关键字括起来用延后加载以免被默认配置覆盖掉,其中我将 Todo 的格式设成了 weektree 的格式,这会将任务归类成 年-XX周-星期X 的格式,方便进行定位以及用 org-archive-subtree 的命令将已完成的任务存档。
更多关于任务模板的相关介绍可看这里

使用

这样配置下来,使用 SPC X 即可打开一个缓冲,按下 t 即可选择预先配置的 Todo 模板,接下来输入任务名称,按下 C-c C-c 即可将缓冲中的内容送入文件,同时关闭缓存。这个过程不需要去打开其他文件,适合在一个工作流中突然想起某事而花最小的打断代价去写下代办事项。

移动端使用

目前我在安卓端上使用的是 [Orgzly](https://f-droid.org/packages/com.orgzly/) 搭配 Nextcloud 进行任务同步,利用小组件功能也能方便一览待办(就是小组件的刷新是个问题)。

番茄钟

安装

~/.doom.d/init.el 中加上 pomodoro 即可。

1
2
3
(org
+roam2
+pomodoro) ; organize your plain life in plain text

使用

在一个待办标题上使用 SPC t t 即可开启番茄计时,默认二十五分钟倒计时,还附带一个有点浮夸的敲钟音效(

参考

  1. How I Take Notes with Org-roam
  2. 卡片笔记写作法:如何实现从阅读到写作
  3. 用“卡片笔记写作法”读《卡片笔记写作法》 译者现身说法并完整示范 | 学习骇客
  4. 强大的 Org mode(4): 使用 capture 功能快速记录
]]>
技术 Emacs 随记 https://blog.southfox.me/2022/05/%E6%88%91%E6%8B%BFEmacs%E5%81%9A%E4%BB%80%E4%B9%88%E6%9A%A8Emacs%E9%9A%8F%E8%AE%B0%EF%BC%882%EF%BC%89/#disqus_thread
Emacs随记(1) https://blog.southfox.me/2022/04/Emacs%E9%9A%8F%E8%AE%B0%EF%BC%881%EF%BC%89/ https://blog.southfox.me/2022/04/Emacs%E9%9A%8F%E8%AE%B0%EF%BC%881%EF%BC%89/ Tue, 19 Apr 2022 13:09:05 GMT <p>小心,传教士来了.jpg</p> 小心,传教士来了.jpg

Emacs,一款诞生于 1975 年的开源软件,时间并没有葬送这款软件,直至现在也依然也有不少“奇怪”的人在日常使用它。

Why?

讲为什么要使用 Emacs 不如先讲讲为什么不用 Emacs

  • 它对 Win 系统支持不是很友好
  • 全按键操作很劝退从微机课学起电脑的“现代”信息原住民
  • 如果说 Vim 是小众编辑器,那么 Emacs 更是小众中的小众,导致很多东西都要自己去翻找
  • 经常出现一些让人恼火的小问题,结合上点更让人吐血

还不够劝退吗?那为什么我还要用 Emacs 呢?

  • 它的内存占用,4G 的电脑也带的动,我是受够了套壳框架带来的吃内存大户了……浏览器 + VS Code 已经挤得我电脑动弹不得了。
  • 它的哲学,如果说 Linux 的哲学是一切皆文件,那么 Emacs 的哲学就是对于文本的操控了,将电子邮件导入到待办事项,把即时通讯里的通天记录裁剪到收藏里,就连近些火热的双链也有人去实现……因为这些都是“文本”,所以他们就可以被 Emacs 各个包处理。这些功能要让其他软件去实现,非得用上不同软件拼凑不可,同时他们之间的联系也很脆弱,全看软件开发者是否开放……
  • 它的智慧,虽然我现在也是摸索着用了一段时间,到现在也才是打开次数跟 VS Code 持平的状态,不过我也足以感受到其中的“智慧”了,它确实很适合培养所谓的“计算机素养”,哪怕用它的人中很多并不是程序员。

Why Doom Emacs?

现在我在用的是 Doom Emacs ,他们之间的关系有点像是 Minecraft整合包 之间的关系,原版生存固然足够好玩且富有深度了,但还是太朴素了,想弄点更大的乐子那自然是往里灌上一众 MOD 了。而配好一整套相关 MOD 的即是整合包了,Doom Emacs 在各种配置整合包里算得上是高效和……轻量?(毕竟我也没用过其他的配置)

同时其中还附带了 evil 这个包,可以让 Emacs 用上 Vim 的操作,想想这确实挺“邪恶”,EmacsVim 之间的“圣战”一直打得昏天暗地,谁知其中竟然分裂出一个教派结合了两方?也确实不愧于 Doom 之名啊……

能蹭上 Vim 的操作也是好事,因为 Vim 的相关资料比 Emacs 多上许多,比较好找到相关资料,也避免了 Emacs 小拇指症状。

安装

Emacs 在各种 Linux 发行版自带的包管理应该能轻松找到(Mac OS 应该也能简单安装到),安装后运行一次就会生成 ~/.emacs.d 路径下的文件夹。

确认文件夹存在后运行:

1
2
3
git clone --depth 1 https://github.com/hlissner/doom-emacs ~/.emacs.d

~/.emacs.d/bin/doom install

其中安装会到 GitHub 下载一两百个包,所以提前配置好一个科学网络环境是必须的……

安装结束后,运行后并且……!

存活下来

按键缩写

大部分资料都遵循以下缩写——

Emacs 功能键缩写对应键盘按键(PC/Mac)
SpaceSpcSpace(空格)
ControlCCtrl / Control
MetaMAlt / Option
ShiftSShift / Shift

例如:

Spc . 是先按下 空格按下 . 键。

M-x 是按下 Alt同时按下 x 键。

实际操作

对于入门而言,使用 S . 即可打开文件管理,之后就可以选择一个文件进行打开了。

Vim 编辑模式可能对于入门来说也是有点痛苦,不过初始时掌握 i:w 也够用了。

不用特地去记快捷键,使用 M-x 搜索相应的命令大部分足够了,当知道自己在高频使用某个命令,那么这时候才稍微用一下快捷键并记忆就足够了。

找到自己想要的功能用兴趣做导向是最优的,org-mode 就是个不错的选择。

参考教程

Vim 教程 - Oeasy

Doom Emacs 视频教程 - Zaiste Programming B 站搬运

一年成为Emacs高手 (像神一样使用编辑器)

怎么学习 Emacs ? 达到真正融汇贯通的境界?

总结

先写成这样吧,下篇大概会写点 org-roamorg-mode 相关配置……不过也得等我自己先折腾了,有东西能写了才能写……

]]>
技术 Emacs https://blog.southfox.me/2022/04/Emacs%E9%9A%8F%E8%AE%B0%EF%BC%881%EF%BC%89/#disqus_thread
搭建Matrix即时通信服务 https://blog.southfox.me/2022/04/%E6%90%AD%E5%BB%BAMatrix%E5%8D%B3%E6%97%B6%E9%80%9A%E4%BF%A1%E6%9C%8D%E5%8A%A1/ https://blog.southfox.me/2022/04/%E6%90%AD%E5%BB%BAMatrix%E5%8D%B3%E6%97%B6%E9%80%9A%E4%BF%A1%E6%9C%8D%E5%8A%A1/ Fri, 15 Apr 2022 20:54:19 GMT <p>总之稍微记录一下。</p> 总之稍微记录一下。

  • 事先约定 matrix.org 是前端地址 synapse.matrix.org 是后端地址,实际请改成自己的……具体为啥这么做可以看官方文档,如果嫌麻烦也可以不启用这功能……

  • 新建文件夹,在里面新建一个 docker-compose.yml 文件,往里写入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#也感谢糖喵提供的配置文件~
version: "3.4"

services:
synapse:
hostname: matrix
image: matrixdotorg/synapse:latest
restart: always
container_name: matrix_server
depends_on:
- db
- redis
ports:
- "127.0.0.1:8001:8008"
volumes:
- ./synapse/data:/data
networks:
- synapse_network
- external_network
healthcheck:
test: ["CMD-SHELL", "curl -s localhost:8008/health || exit 1"]

db:
image: postgres
restart: always
container_name: matrix_db
volumes:
- ./synapse/db:/var/lib/postgresql/data
environment:
POSTGRES_USER: synapse
POSTGRES_PASSWORD: 随便什么密码
POSTGRES_DB: synapse
POSTGRES_INITDB_ARGS: "--encoding='UTF8' --lc-collate='C' --lc-ctype='C'"
networks:
- synapse_network
healthcheck:
test: ["CMD", "pg_isready", "-U", "synapse"]

redis:
image: redis:6.0-alpine
restart: always
container_name: matrix_redis
volumes:
- ./synapse/redis:/data
networks:
- synapse_network
healthcheck:
test: ["CMD", "redis-cli", "ping"]

networks:
synapse_network:
internal: true
external_network:
  • 之后运行 docker-compose run --rm -e SYNAPSE_SERVER_NAME=前端地址 synapse generate 命令生成配置文件,之后检查在 ./synapse/data 路径下是否有叫 homeserver.yaml 的配置文件,编辑配置文件 nano ./synapse/data/homeserver.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 重点改以下配置
server_name: "matrix.org"

public_baseurl: https://synapse.matrix.org/

serve_server_wellknown: true

database:
name: psycopg2
txn_limit: 10000
args:
user: synapse
password: docker 配置写的随便什么密码
database: synapse
host: db
port: 5432
cp_min: 5
cp_max: 10

#database:
# name: sqlite3
# args:
# database: /data/homeserver.db
#↑注释掉使用 sqlite3 的配置

redis:
# Uncomment the below to enable Redis support.
#
enabled: true

# Optional host and port to use to connect to redis. Defaults to
# localhost and 6379
#
host: redis
port: 6379
  • 之后再启动服务,docker-compose start
  • 编辑 matrix.orgnginx 配置文件加入以下配置
1
2
3
4
5
6
7
8
9
10
11
12
    location /.well-known/matrix/client {
return 200 '{"m.homeserver": {"base_url": "synapse.matrix.org"}}';
default_type application/json;
add_header Access-Control-Allow-Origin *;
}

location /.well-known/matrix/server {
return 200 '{"m.server": "synapse.matrix.org:443"}';
default_type application/json;
add_header Access-Control-Allow-Origin *;
}
#注意替换自己的前端后端地址
  • 新建 synapse.matrix.orgdns ,指向服务器地址,再 certbot certonly --nginx -d synapse.matrix.org 申请证书
  • 新建一个 synapse.matrix.org 的配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;

server_name synapse.matrix.org;

ssl_certificate /etc/letsencrypt/live/synapse.matrix.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/synapse.matrix.org/privkey.pem;

# Various TLS hardening settings
# https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets on;
ssl_stapling on;
ssl_stapling_verify on;


location ~ ^(/_matrix|/_synapse/client) {
# note: do not add a path (even a single /) after the port in `proxy_pass`,
# otherwise nginx will canonicalise the URI and cause signature verification
# errors.
proxy_pass http://127.0.0.1:8001;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;

# Nginx by default only allows file uploads up to 1M in size
# Increase client_max_body_size to match max_upload_size defined in homeserver.yaml
client_max_body_size 500M;
}

}
  • 重载 nginx 配置文件,nginx -s reload
  • 之后去检查服务(需科学)输入自己的前端地址 matrix.org 检查是否正常
  • docker-compose exec synapse /bin/bash 进入 synapse 容器
1
2
3
4
5
cd data
#注册新用户
register_new_matrix_user -c homeserver.yaml http://localhost:8008
#注册完后用 exit 退出容器
exit
  • 完成后用任意一个客户端登陆即可使用,注意登陆用的地址是后端地址 synapse.matrix.org
]]>
技术 技术 https://blog.southfox.me/2022/04/%E6%90%AD%E5%BB%BAMatrix%E5%8D%B3%E6%97%B6%E9%80%9A%E4%BF%A1%E6%9C%8D%E5%8A%A1/#disqus_thread
EFK:日志 All in one……? https://blog.southfox.me/2022/04/EFK-%E6%97%A5%E5%BF%97-All-in-one/ https://blog.southfox.me/2022/04/EFK-%E6%97%A5%E5%BF%97-All-in-one/ Mon, 04 Apr 2022 17:04:30 GMT <p>突然发现自己搭的应用似乎上了两位数了。</p> 突然发现自己搭的应用似乎上了两位数了。

其中也不乏一些日志大户,每次排错时都要自己进去用日志命令脑死 PgUp, PgDn 一页一页翻找吗?

刚好最近看的书里提出了一种日志管理实现:ELK,即 Elasticsearch, Logstash, Kibana 三种开源应用的简称,其中:

Elasticsearch:负责给日志数据产生索引,方便检索。

Logstash:接收并处理日志,方便其他应用使用。

Kibana:一个展示前端,有酷炫的一众图表模板用来可视化数据。

似乎名头一直都在很多年了,使用起来似乎比较重量级,不知道有没有其他更轻量的实现……不过我也找不到其他实现就先这么用吧……

安装

因为搭建的应用以 Docker 居多,其中默认支持的日志方式有 Fluentd,所以就用这个代替 Logstash 了,所以是 EFK 方案。

Fluentd 采用包安装的方式安装,毕竟要用它处理宿主机上的一些日志,就不考虑塞到 Docker 里折腾自己了。

前期准备

参见官网文档

安装 chrony

1
apt-get install chrony

此步骤是为了日志消息能有更准确的时间戳的样子?

调高文件描述符

执行

1
ulimit -n

命令,要是显示 1024 的话,那么就得调高一点,防止文件描述符用完报错,

编辑 /etc/security/limits.conf 文件,在最后面加上:

1
2
3
4
root soft nofile 65536
root hard nofile 65536
* soft nofile 65536
* hard nofile 65536

之后重启,再次执行

1
ulimit -n

命令,显示 65536 即可成功。

其他

其他的网络调优懒得搞了……问就是摸了!

安装 Fluentd

用的是 Ububtu 20.04 ,参照官方文档,执行

1
curl -fsSL https://toolbelt.treasuredata.com/sh/install-ubuntu-focal-td-agent4.sh | sh

而且里面的版本描述是用大版本号的英文描述的,还得我翻维基查,好好用阿拉伯数字不好嘛……

安装 EK

这里就用 Docker 省点力了……

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
version: '3'
services:
elasticsearch:
image: elasticsearch:tag
restart: always
ports:
- "127.0.0.1:9200:9200"
environment:
ES_JAVA_OPTS: "-Xmx256m -Xms256m"
ELASTIC_PASSWORD: "you_password"
http.cors.enabled: "true"
http.cors.allow-origin: "*"
xpack.security.enabled: "true"
discovery.type: "single-node"
xpack.security.authc.api_key.enabled: "true"

kibana:
image: kibana:tag
restart: always
links:
- "elasticsearch"
ports:
- "127.0.0.1:5601:5601"
environment:
- ELASTICSEARCH_USERNAME=elastic
- ELASTICSEARCH_PASSWORD="you_password"

其中 tag 应该去 Docker Hub 页面寻找,因为没有默认标签的样子只能手动指定版本了……而且注意要选择修了高危漏洞的版本。

之后 up 起来待用。

注意这里没做数据持久化处理,有兴趣的可以自行找找要挂载哪些路径……)

配置

Fluentd

配置文件路径是 /etc/td-agent/td-agent.conf

其中分为 Input 端,用 <sourec> 表示,Output 端,用 <match> 处理。

首先增加以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<source>
@type forward
port 24224
bind 127.0.0.1
</source>

<match *.**>
@type copy

<store>
@type elasticsearch
host 127.0.0.1
port 9200
user elastic
password you_password
logstash_format true
logstash_prefix fluentd
logstash_dateformat %Y%m%d
include_tag_key true
type_name access_log
tag_key @log_name
flush_interval 1s
</store>

<store>
@type stdout
</store>
</match>

并且 systemctl restart td-agent 重启应用,开放24224 端口让 Docker 能够进行联协,并将相应数据通过 9200 端口汇入到 Elasticsearch 进行处理。

Docker

管理每个 docker-compose.yml 文件,在每个服务后面加上相应的 logging 块:

1
2
3
4
5
6
7
8
9
10
11
12
services:
xxx:
......
......
logging:
driver: fluentd

yyy:
......
......
logging:
driver: fluentd

(是的,感觉这样确实有点蠢,不过没找到其他更好实现而且只要做一次就先忍了……)

之后 downup 重建容器即可。

Kibana

没出错的话现在日志应该源源不断汇入到 Elasticsearch 并在处理了,现在该浏览成果了。

老调重弹之申请域名、指向域名、申请证书、反代 5601 端口,完成后访问对应域名应该就能进到管理面板了。

展开左边的菜单栏 Management~Stack Management -> Kibana~Index patterns -> Create index patterns 应该能看到有类似 fluentd-YYMMDD 形式的数据了,新建一个名叫 fluentd-* 的索引将数据囊括进来,就搞定了,之后可以去 Analytics~Discover 查看数据了……

到此,管理 Docker 产生的日志就这样搞定了……

额外

当然还没结束,毕竟还要更多!

Nginx

Fluentd 直接安装就是为了更方便处理相应日志的,但是针对 nginx 来说,因为 Fluentd 使用的用户 td-agent 没有相应访问 nginx 日志的权限,那么首先要用

1
usermod -aG adm td-agent

命令放行对应目录,参见

之后在 /etc/td-agent/td-agent.conf 配置文件中新增以下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<source>
@type tail
path /var/log/nginx/*access.log,/var/log/nginx/*access.log.1
pos_file /var/log/td-agent/httpd-access.log.pos
tag nginx.access
<parse>
@type nginx
</parse>
</source>

<source>
@type tail
path /var/log/nginx/*error.log,/var/log/nginx/*erroe.log.1
pos_file /var/log/td-agent/httpd-error.log.pos
tag nginx.error
<parse>
@type nginx
</parse>
</source>

然后 systemctl restart td-agent 重启应用。

其中一个小问题就是 error 日志会因为不能格式化而导致不能正确处理,当然只限 error 日志,所以就……眼不见为净了……反正这也算单独一个分类了……吧。

网络传输

既然 All in one,自然要处理好其他主机的服务了, Fluentd 也自带一个 http 方式进行传输。

主机

/etc/td-agent/td-agent.conf 配置文件中新增以下配置:

1
2
3
4
5
6
7
<source>
@type http
port 9880
bind 127.0.0.1
body_size_limit 32m
keepalive_timeout 10s
</source>

然后 systemctl restart td-agent 重启应用,再老调重弹之申请域名、指向域名、申请证书、反代 9800 端口。

客机

/etc/td-agent/td-agent.conf 配置文件中新增以下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<match **>
@type http

endpoint https://申请的域名:443/api
open_timeout 3

<format>
@type json
</format>
json_array true
<buffer>
flush_interval 10s
</buffer>
</match>

然后 systemctl restart td-agent 重启应用,

之后观察 Kibana 面板,发现有 @lognameapi 的数据就算成功……这个 logname 发现不知道怎么改……算了,就当作区分不同机子了吧……

总结

这么处理下来,就应该能愉快的探索自己产生的日志了,能够直接指定时间段和按属性过滤条目已经暴杀直接翻找日志文件的方式了……

感觉能摸索的地方还有挺多的呢,不用各种追踪脚本仅凭日志文件也能发现很多东西呢……

不过难受的点就是,EFK 名头那么大,但是相关文档真的很少(就算用英文搜索)……感觉自己在用一个过气项目的样子,不知道是不是我不得要领……

最后附张图,用面板五分钟就搭出来的看板,感觉还能再挖掘点东西呢。

看板

]]>
技术 技术 https://blog.southfox.me/2022/04/EFK-%E6%97%A5%E5%BF%97-All-in-one/#disqus_thread
二二年三月梦记 https://blog.southfox.me/2022/03/%E4%BA%8C%E4%BA%8C%E5%B9%B4%E4%B8%89%E6%9C%88%E6%A2%A6%E8%AE%B0/ https://blog.southfox.me/2022/03/%E4%BA%8C%E4%BA%8C%E5%B9%B4%E4%B8%89%E6%9C%88%E6%A2%A6%E8%AE%B0/ Tue, 08 Mar 2022 15:03:28 GMT <p>一声叹息。</p> 一声叹息。

3.8

中 普

又是常见的校园怪谈啦,一些学生会莫名其妙消失不见啦。

我就是在这种情况下打算返校的。

公园

逛公园,似乎这只是一个稀松平常的景点。我路过一个冰淇淋摊贩,他问我你要不要来点?我接过,然后就看着冰淇淋……仍由它融化。**

返校

雨,好大的雨!

我顶着雨伞也难免被吹得几乎飞起来!艰难的到了教学楼下,一层……二层……三层……楼梯是外露的,所以不免也要承受风雨,四层以上的楼梯甚至还没有护栏!我已经被吹得摇摇晃晃的了,想着之前也有些喜欢玩闹的学生坠楼的传言,我抛弃雨伞,直接抱紧扶手,像毛毛虫一样爬了上去……

校园间

「记忆混乱——」

一些大学老师和高中混在了一起,以及一些稀奇古怪的上课内容……哪怕才过去二十分钟,就已经模糊不堪……似乎潜意识是真不想我回忆这块内容吧……

但有一幕

我在楼道直接跑动,为了追逐一个朋友,我追到电梯房,他已经抢先一步上去了……

这里的感觉不是他躲着不想见我,而是更像损友之间的小玩笑,但他现实中不是这样的人……我是把他跟谁整合到一起了?

漫漫回家路

校园状况越发差劲……学校决定让我们回去。

我站到回家路上的一条街道……已经眼前发黑,腿脚难行……

压抑……

「记忆丢失」

到家

我从后门回家,发现我爸又在搞装修,把门换了新的。我的房间门下方换成玻璃制的了,能够一眼看到我的床……

父母的控制欲?但是梦里的我并没有太过惊讶,所以这层含义算是最浅显也最不主要的部分了。

我前往阳台,发现也堆着很多门……

下方没玻璃。

我通过窗户望向我哥的房间,发现我爸正睡在那里。

我竟然没感到奇怪。

「记忆丢失」

我似乎立于天空中,中间写着几行字。

橙色

蓝色

绿色

似乎都是些颜色名字,都是些什么?

……

我打算进我爸房间了,告诉他我回来了。

推开门,我就发现不对了!那个怪谈,那个让人消失的怪谈!它就在房间里!

它在四面八方涌上来!

“够了!”

“我已经不想待在这压抑的梦了!”,我说道。

“你究竟是什么东西!”,我将这股情绪狂潮指向房间中不可见的存在,势要揪出来它的原型。

…………

深海……鲜艳的热带鱼群……

……奇怪的绿色类鱼生物……带有双肢的……冲向海面……

…………

所以,橙色是,自负的意思?

我喃喃自语……

梦里半清醒的我向梦直接发问也没能获得个完整清晰的解析。

这次的梦,真的太奇怪了……

中场休息

我清醒了……拿起手机一看,才十四点半。

再继续睡吧……接下来的梦就回归正常了,还大多跟 MOBA 游戏有关,大概跟我在睡前刷的B站视频有关吧。

友善评论

我来到一个游戏展会上,一个看板是写着对于游戏的祝福,上面也充斥着“祝福”。

「蒸蒸日上!」「ez 策划!」……

都是些没吐脏字骂人的话语……

称号

一款猪场或者企鹅出品的手游,似乎出了个「头号玩家」的礼包,仅需小几万就能拥有个自定义称号。

于是很多土豪蹲点购买……但起得称号哭笑不得,政治、人物啥的敏感称号使劲往上取。

改版

似乎是猪场的扒鸡,似乎我又回坑玩了。

我常玩的英雄被改版了,被动成了个死后成为灵魂状态读秒然后还可以放技能读秒完还能原地复活的样子?这改版让这英雄从躲在后方猥琐放技能变成往前莽的类型了……

对面发育非常好,我方翻盘点全压在我身上,于是变成我死了都要输出对面,对方也守我尸蹲我复活点然后再把我打死的拉扯局面。

来来回回几次后,我感觉,够了!我已经没有耐心了,我要醒了,就算你们直接输了。

于是我醒了,看了眼时间,十四点五十分……

3.9

中 普

舍友

某个女主播住在我们宿舍……

……

我似乎到网上申请了一个去分布网络的 ID ?

3.16

中 普

屏蔽我!

一个社交网站的页面,似乎是我发的……上面写着,某个站的用户看不惯我就屏蔽我吧。

3.22

中 普

地球炸了

苍茫宇宙中,宇宙突然开裂,崩解成一大堆碎片。其中一个大的球形碎片在其中穿梭……

“是月球啊,月球也可以算是地球的碎片了吧,要是月球能持续吸引周围的碎片,那么地球或许会重新回来吧……”

暴雨

我的床铺不知道为什么放在了阳台上,而外面已经阴沉起来了,天空压抑……

我突然惊觉起来……疯了似的把被子踢到前面,想为自己遮点雨……但是雨夹着雨还是让我浑身湿落。

…………

(中间似乎假醒了一次?)

再起

我听到了舍友敲打的键盘声,醒了过来。我下了床,走到阳台,发现我的床已经湿透了,插座放在拐角处……上面的屏幕暴亮着,提醒着我已经工作不能……

我从阳台望出去,已是深夜,心思不平,想着之后该如何……我转身回到宿舍内,发现舍友还在交谈着……

我突然意识到,是梦!

我开始愤愤不平起来,马上冲到一个舍友旁,强硬夺下他的眼睛,喊道——“变!”

他随即头部变成了一只柴犬头……

为什么是柴犬?额,但更关键的是他似乎不是现实舍友,似乎是某个高中同学……

之后我想出去逛一逛,但发现夜色已经哪里都是,无法再出现什么具体的东西了,大概是之前的那个地球炸掉的场景把脑子的渲染配额用完了吧……

那只好起来了,打开手机,发现天气预报发来暴雨预警……外面已有阵阵雷声……

]]>
梦记 梦记 https://blog.southfox.me/2022/03/%E4%BA%8C%E4%BA%8C%E5%B9%B4%E4%B8%89%E6%9C%88%E6%A2%A6%E8%AE%B0/#disqus_thread
Github Actions 浅尝辄止 https://blog.southfox.me/2022/03/Github-Actions-%E6%B5%85%E5%B0%9D%E8%BE%84%E6%AD%A2/ https://blog.southfox.me/2022/03/Github-Actions-%E6%B5%85%E5%B0%9D%E8%BE%84%E6%AD%A2/ Mon, 07 Mar 2022 16:32:14 GMT <p>免费送!免费送!微软电脑免费送啦!</p> 免费送!免费送!微软电脑免费送啦!

自从 GitHub 被微软收购以后确实是有钱了啊,GitHub Actions 公开仓库竟然可以免费用(私有仓库也有三千分钟时间)。

什么?不知道 GitHub Actions 是什么?

简单来说就是提前写好对应的配置文件,那么 GitHub 就会在满足条件时分配电脑执行对应的配置文件,配置文件可以包含命令或者引用其他人写好的配置文件……所以这如同有一台真实的服务器一般强大。

本来呢,这种服务是为了方便一众开源应用测试和编译的,但是被一众羊毛党薅出花来了……什么自动签到啦、生成订阅源啦、推送消息啦等等等等,这些「奇技淫巧」可以在各家推荐专栏找到,有兴趣可以自己去找一下。

还是说说我拿 GitHub Actions 来干什么吧。

Hexo 自动部署

如果经管着一个静态博客那么这功能是刚需了吧,毕竟如果想在移动设备或者不方便安装环境的公用电脑上写作的话,那么让 Actions 进行生成静态页面和部署是一个优秀的选择。

生成 Personal access tokens

因为分配的机器是一个干净的环境,并没有操作对应 GitHub 仓库的能力,为了做到登陆,首先需要生成一个 access tokens 。(当然也可以用私钥认证,但是感觉麻烦就没用这方式……)

首先到 GitHub 配置页 点击 Generate new token 按钮,输入密码认证后跳转到对应页面。

Note 填写一个便于理解的名称,我这边是用来自动部署 Hexo 博客就写 HEXO_DEPLOY

然后选择过期日期(Expiration),如果不嫌麻烦并确信自己不会忘记更换,那么可以设置一年两年的过期时限,否则懒人就选永不过期吧( No expiration)吧……

然后在权限范围(Select scopes)栏里勾选 repo 框(如果能明确对应权限是干嘛的也可以只勾选需要的权限)。

然后点击生成按钮(Generate token)生成一个新的 access tokens ,这个页面只显示一次,所以不要关闭窗口!

设置 Actions secrets

除非你是私有仓库,那么运行 actions 的配置文件和所有输出对所有人都是可见的,为了安全,要自己设定一个Actions secrets 隐藏相关的 token

新开一个页面,到存储 Hexo 博客文件的仓库, Settins -> Secrets -> Actions -> 点击 New repository secret 按钮 ,然后新页面 Name 填写便于理解的名称 ,我这边是用来自动部署 Hexo 博客就写 HEXO_DEPLOY 。值(Value)里填写上一步 Generate token 生成的 token ,然后点击 Add secret 保存 secrets

编写配置文件

做好前期工作后就到激动人心的写配置时间喽。

首先在 Git 仓库根目录下新建一个 .github 文件夹,然后再在里面新建一个 workflows 文件夹,再在里面新建一个 xxx.yml 文件,我的形式是 仓库/.github/workflows/deploy.yml

之后就该往 .yml 文件写配置了,yml 格式是一个严格缩进格式,所以对自己好点,用 VS Code 之类的编辑器来写……

1
2
3
4
5
6
7
8
9
10
11
12
13
name: Hexo Deploy

on:
push:
branches: [ hexo ]

jobs:
build:

runs-on: ubuntu-latest
strategy:
fail-fast: false

name 那一栏填便于理解的名字。

on 选项是为监听哪个分支发生变动就执行动作,我这边设置为 pushhexo 分支,意为当 hexo 分支下发生了 push 动作后就执行此 action ,分支名请填自己仓库实际的,是 main还是 hexo 请根据实际选择。

jobs 下的名称大概是实际执行 action 时的名字,可写个便于理解的名字。

runs-on 是声明需要什么类型的机器, ubuntu-latest 就是申请最新的 ubuntu 系统的机子。

fail-fast 的实际用途我也不懂,反正他就在那儿了.jpg 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

steps:
- uses: actions/checkout@v2 #拉取仓库文件

- name: Set up Node.js
uses: actions/setup-node@v1
with:
node-version: 17

- name: Install dependencies
run: |
npm install -g hexo-cli
npm install
git config --global user.name "wherever"
git config --global user.email "wherever@xxx.xx"
- name: Deploy
env:
DEPLOY_KEY: ${{ secrets.HEXO_DEPLOY }}
run: |
hexo clean
hexo generate
cd ./public
git init
git add --all .
git commit -m "GitHub action Auto Builder"
git push --quiet --force https://$DEPLOY_KEY@github.com/name/name.github.io.git master

之后就是 steps 栏目了,name 写个便于理解的名字。

GitHub actions 最为被称道的一点就是能用其他人预先写好的脚本,所以在 Set up Node.js 栏里的 actions/setup-node@v1 这里就是引用了安装 nodejs 环境的脚本,with 后面填入脚本里预先定义好的变量(填 17 意为安装版本号为 17 的 node ),不用自己考虑如何实现。

Install dependencies 这栏就是安装依赖了,npm 安装 Hexo 的包,然后 git config 是设置自己的名称和电子邮箱。

Deployenv 一栏就是上面设置 Actions secrets 操作起到用处的地方了,

DEPLOY_KEY: ${{ secrets.HEXO_DEPLOY }}

的意思就是把 Actions secrets 里的叫 HEXO_DEPLOY 的值声明成叫 DEPLOY_KEY 的环境变量,按自己实际情况写……

下面的命令就是重复流水帐了…… git push --quiet --force https://$DEPLOY_KEY@github.com/name/name.github.io.git master 这里就根据实际情况写了,我是博客源文件和生成的静态文件都放一个仓库里就将生成好的静态文件用 --force 参数强制部署到 master 分支,要提前切换好分支!在自己仓库的 Settings -> BranchesDefault branch 里将自己放置博客源代码的分支改名并设为默认(我是将放博客源代码的命名为 hexo),请提前确认好,要不然 --force 参数将会连同历史记录覆盖master 分支的内容!

如果是分出一个仓库放置生成后的静态页面就根据自己实际情况写。

测试

之后就是进行 push 操作看看 action 有没有正常工作了,要是失败就会出现红色的叉叉,这时请根据提示检查哪里出了问题(文件缩进、名称没写对等……)。

成功了的话,就去检查对应分支有没有出现对应的静态文件了。

部署自定义字体

当然……因为是一台对应的机器,所以可以装点 Python 环境运行一点脚本啊……我之前中文字体动态剪裁就是用 GitHub actions 执行的。

具体而言……

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
steps: #安装 Python 环境
- uses: actions/checkout@v2
- name: Set up Python 3.9
uses: actions/setup-python@v2
with:
python-version: 3.9

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install fonttools brotli requests

- name: Deploy
run: |
python3 utils.py -d #运行提前写好的脚本生成字符集
pyftsubset Zpix.ttf --text-file=strdb.txt #裁剪
fonttools ttLib.woff2 compress -o Zpix.woff2 Zpix.subset.ttf
mv Zpix.woff2 ./public/css/fonts
mv Zpix.subset.ttf ./public/css/fonts/Zpix.ttf #将裁剪好的文件放到生成文件夹内

初始化 Giscus 对应评论

脚本文件

参考这

配置文件

参考这……

图片备份

虽然博客用了 IPFS 来当博客图床,但是也有失效的风险,所以做好备份是肯定的啦~

脚本文件

本地版的区别不大,就是将图片放到一个文件夹方便后续操作……

如果真想看……

配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
steps:
- uses: actions/checkout@v2 # 安装 Python 环境
- name: Set up Python 3.9
uses: actions/setup-python@v2
with:
python-version: 3.9

- name: Install dependencies
run: |
sudo apt-get install wget
python -m pip install --upgrade pip
python -m pip install fonttools brotli requests
git config --global user.name "SouthFox-D" #自己的……
git config --global user.email "southfoxdreamer@gmail.com"
- name: Check Img
run: |
wget https://raw.githubusercontent.com/SouthFox-D/blog_img/main/imgList.json #改成自己的仓库并已存在此文件
python3 utils.py -b
- name: Backup
env:
DEPLOY_KEY: ${{ secrets.HEXO_DEPLOY }} #自己的……
run: |
rm -rf .git #删除 Hexo 的 .git 文件夹防止后续冲突
git clone https://github.com/SouthFox-D/blog_img.git blog_img #备份仓库
cp -f newimg/* blog_img/ #合并文件夹
cd blog_img
git add .
git commit -am "Auto backup" || echo "Nothing to push" #防止报错
git push --force https://$DEPLOY_KEY@github.com/SouthFox-D/blog_img.git #根据实际情况而定

具体可参考这……

总之

一次编写后,后续就不用怎么管了,自动化的好处体现出来了……

我在一台没有安装 Hexo 环境下的机器上写作,到时只要直接 push 就让 GitHub 来完成对应的部署操作了,不必自己安装环境又 clear gd 啊的……在移动设备写作可以写好直接复制到 GitHub 网页版里,同时图片也不必当心失效。

反正……微软!有钱的!嫖起来没负罪感。

]]>
技术 技术 https://blog.southfox.me/2022/03/Github-Actions-%E6%B5%85%E5%B0%9D%E8%BE%84%E6%AD%A2/#disqus_thread
IPFS和博客 https://blog.southfox.me/2022/03/IPFS%E5%92%8C%E5%8D%9A%E5%AE%A2/ https://blog.southfox.me/2022/03/IPFS%E5%92%8C%E5%8D%9A%E5%AE%A2/ Sun, 06 Mar 2022 14:02:09 GMT <p>似乎这是两码事?</p> 似乎这是两码事?

IPFS

IPFS 全称 (InterPlanetary File System),中文名可叫星际文件系统

这略带一丝中二的名字确实透露了这项目的愿景,设想一下,要是人类真的在太阳系殖民成功了,各个殖民地要如何通信?就算是火星和地球光也要走三分钟,最低六分钟的延迟,谁受得了啊?

但观测一下就可以发现,网络中的很多数据是可以复用的。比如,火星上的 A 访问了地球的今日新闻,火星上的 B 想访问地球的今日新闻网站,还要去跟地球通信吗?他只要跟 A 获取数据就可以了。

这就是 IPFS 的基本思想了,一个点对点的分布式文件系统。

能做啥

作为一个点对点的分布式文件系统,基本功能就是存储文件了,图片、视频、静态网页、文件夹皆可。

文件上传后,再经过算(mo)法后,文件会被标上一个类似于 Qmd3oSMoEb3npqXdjwek7RPfvteMckrBFBRHU1ECZDtAEC 这种形式的 CID ,这个 CID 可以唯一标识一个文件,其他人将这个 CID 告诉 IPFS 网络,就可以在全世界的 IPFS 网络中进行获取了。

网关

但遗憾的是 IPFS 不能兼容现在主流的 HTTP 网络,如果没有专门的客户端又想要使用 IPFS 网络,要借助一个网关才可以。

好比如世界上有一群人发明了一种新语言,这种语言甚至需要借助一个新器官才能沟通,很明显其他人是完全无法同使用新语言的人交流的。新语言使用者为了增大影响力,决定派出几名翻译,让双方能够沟通。

可通过公共网关检查站获知常见公共网关。

国内访问优秀的网关为:

w3s.link cloudflare-ipfs.com (Cloudflare 我的超人!)

ipfs.fleek.co

在网关后面加上 /ipfs/[cid] 即可通过 http 的形式获取文件了。

试试看↓:

/ipfs/Qmd3oSMoEb3npqXdjwek7RPfvteMckrBFBRHU1ECZDtAEC

IPNS

cid 形式有个问题就是他是根据文件内容进行计算的,文件内容哪怕改动一个字,生成的 cid 也会完全不同……如果要在 IPFS 网络部署一个网站的话,管理员每次更新网站,就得把新 cid 重新告知出去吗?

显然太折腾了……但可以利用现有的 DNS ,将 cid 绑定到 DNS 上,这样管理方仅需更新 DNS 即可。这种方式被成为 IPNS ( InterPlanetary Name System) 。

通过这种方式,可以将一个静态网站托管到 IPFS 网络上面,生命力大大增强。

一般网关也支持 IPNS 形式访问,在网关后面加上 /ipns/[域名] 即可。

试试看↓:

/ipns/zh.wikipedia-on-ipfs.org (一个静态的维基百科存档)

/ipns/blog.southfox.me (当然!)

IPFS 图床

那么托管文件,最容易想到的就是图片了,本博客的图片也在几个月前迁移到了 IPFS 网络上。

如果真想将图片放到 IPFS 上,那么该考虑以下事情:

优点:

  • 抗☐☐,即使一个网关炸掉了,也可以切换另一个网关。

  • 轻松切换, 文件 cid 是不变的,VS Code 全文替换就可以很轻松切到另一个网关,不像一般图床,其连接是随机的,其迁移成本会变得非常大。

缺点:

  • 慢……速度一般来说只能说凑合,除非将设置一个靠近用户的位置放置网关,同时文件刚好就在这网关上……

web3.storage

地址

可使用 GitHub 注册,这网站提供 1T 的存储空间。

fleek.co

地址

同样可使用 GitHub 注册,可提供存储空间不明。

但是重点是!他提供网站托管

Pinata

地址

1G 免费空间……但似乎是 IPFS 客户端能直接连接过去进行备份?总之不推荐(因为空间太小了)。

公共网关

以上的网站是要自己手动上传至他们的网页,并没有很好的支持 HTTP API ,所以喜欢用 PicGo 传图并直接获取 MarkDown 连接的懒人可能要寻找能够直接传图的公共网关了。

PicGo

在插件市场搜索 web-uploader-custom-url-prefix 并进行安装,配置成如下:

其中 infura-ipfs.io 可以是任意支持 HTTP API 形式上传的网关。

自定义图片前缀可以是任意访问速度快的网关。

Python

想用 Python 折腾?好主意,所以快去折腾吧!

快捷命令

没用过苹果设备,不清楚。

不过一般参照之前经验改改应该不难……?

Pin 与失效

前面的 PicGo 上传图片时带有个 pin=true 参数,这个参数就是告诉网关,这个文件很重要,请不要当成缓存清除。

因为 IPFS 的设置是,其他节点获取了一个文件后,会放在缓存里,如果服务器的缓存超过了阈值(默认 10G),就会清理掉……

如果上传文件的服务器下线了,那么还是有可能从缓存了这文件的服务器获取文件的。但万一时间太过久远,久到主服务器不存在,其他服务器缓存早已清理,那么这个文件就如同 BiTorrent 下载中的死种一样,再也不能获取了……

而另一面讲,如果文件很热门,比如明星艳照,那么这个文件将会持久存在,删除不能……所以,不要向 IPFS 上传个人隐私相关文件!一旦传播开来,那就没有后悔药了……

备份

所以为了数据安全考虑,放置在 IPFS 上的图片也要做好备份……

似乎可以写个脚本,自动分析文件下的 cid ,然后自动爬取备份到本地。

以后再摸吧。

3-13 更新:

其实当天就摸了……只是我憋着不放呢。(

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import sys
import os
import requests
import json
import re
import random



def backupImg():
path = os.getcwd()
for root, dirs, files in os.walk(path + '/source'): #根据实际情况定
for name in files :
filelist.append(os.path.join(root, name))

nowImgList = []
for filename in filelist:
if filename.endswith('.md'):
if "_posts/" in filename:
post = filename.split("_posts/")[-1]

with open(filename, "r", encoding='utf-8') as f:
mdText = f.read()
result = re.findall('!\[(.*?)\]\((.*?)\)', mdText)

for i in range(len(result)):
img_quote = result[i][0]
img_url = result[i][1]
nowImgList.append(img_url)

downLoadList = list(set(nowImgList).difference((set(imgJson["img"]))))
if downLoadList != '':
nowImgJson = {}
nowImgJson["img"] = nowImgList
with open('./imgList.json', 'w', encoding='utf-8') as f:
json.dump(nowImgJson, f)

downloadImg(downLoadList)

def downloadImg(imgList):
for img_url in imgList:
if img_url == '': #判空
continue
# img name spell
urlname = img_url.split(u"/")
img_name = str(urlname[-1])
# download img
ipfs_gateWay = ['https://media.southfox.me/ipfs/', 'https://ipfs.io/ipfs/', 'https://ipfs.fleek.co/ipfs/']
if 'ipfs' in img_url:
img_url = random.choice(ipfs_gateWay) + img_name

response = requests.get(img_url) #根据自己图床链接进行选择
print('Download ' + img_url + '✔️')
# write to file
f_img = open('./' + img_name, 'wb')
f_img.write(response.content)
f_img.close()

if __name__ == '__main__':
filelist = []

if os.path.exists('./imgList.json'):
imgJson = []
with open('./imgList.json', 'r', encoding='utf-8') as f:
imgJson = json.load(f)
else:
imgJson = {}
imgJson["img"] = []
backupImg()

简单来说,就是用扫描 source 目录下的的 .md 文件,并用正则扫描 ![]() 这种形式的图片语法并存起来。

然后进行图片抓取,其中 if 'ipfs' in img_url: 这里是判断链接是否是 ipfs 的图床链接,要是你的图片链接只来源一个图床(例如 sm.ms 可以写 if 'loli.net' in img_url:),请自行替换,要是图床来源杂乱就……不进行判断抓取下来自己手动选择吧。

然后结束后会生成一个 imgList.json 文件,里面是已经抓取的图片,以后要是再进行抓取的话就通过这文件和新扫描的文件列表做集合的求差处理(downLoadList = list(set(nowImgList).difference((set(imgJson["img"]))))),以来判断要新抓取那些文件……

总之写的非常初学者……应该都是比较好理解的吧(

很多都是为了 GitHub Actions 准备的,不知道是什么的话可以看

IPFS 博客

如果你有一个静态博客,为何不考虑放置在 IPFS 网络上呢?

首先要更改的就是博客的连接……要前往博客模板把其里面的所有连接都改成相对连接的形式,否则托管时会根本加载不了 css 或者 js 文件。

接着前往 fleek 并注册,然后在托管一栏中选择你放置静态网页的仓库(或分支),就能简单的部署到 IPFS 网络上了,要是想启用 IPNS ,也可以在 SETTINGS -> Domain Management -> Add Custom Domain 增加一个博客域名,然后在新增域名的更多选项里选择 Dns Link ,会自动弹出个窗口绑定域名。把这个 CNAME 选项绑定到你的域名管理商即可。(Cloudflare 我默认关了代理,要是绑定迟迟不能生效的话可以试着关掉 Cloudflare 代理试试)

实际使用

客户端

客户端下载地址

不一定需要个网关,实际自己直接用用也是不错的,就是使用时会不停的交换数据,对电量和流量的消耗也很大……如果所在网络对 P2P 协议限制比较严格那可就要小心了……

服务端

服务端下载地址

如果你手头上有闲置的服务器,为什么不尝试部署一个 IPFS 服务呢?

将文件放一份备份在自己的服务器上,或是搭建一个自用网关,也能有效提升使用体验(当然要服务器性能足够)。

文件币

哦……所以还是谈论到这个话题了……

filecoin ,是一个建立在 IPFS 上的加密货币项目(大概)?

只要你抵押出相当容量的硬盘,就能进行挖矿了……这似乎也是去年硬盘涨价风潮原因之一?(那更该用了,这是拿大众的钱买硬盘啊)

但现在这币似乎状态不好的样子,价格跌倒了顶值的十分之一。虽然我对加密货币不感冒,但我还是想 fil 涨起来的,毕竟币涨了也是能吸引更多人提供存储空间的,经营托管服务的服务商也能通过 fil 进行回本。

但是不考虑加密货币也罢, IPFS 做为一个开源项目,如果其足够好,也能自己证明自己,IPFS 能取代 HTTP 成为下一代网络标准吗?天知道。

]]>
技术 技术 IPFS https://blog.southfox.me/2022/03/IPFS%E5%92%8C%E5%8D%9A%E5%AE%A2/#disqus_thread
22年2月梦记 https://blog.southfox.me/2022/02/22%E5%B9%B42%E6%9C%88%E6%A2%A6%E8%AE%B0/ https://blog.southfox.me/2022/02/22%E5%B9%B42%E6%9C%88%E6%A2%A6%E8%AE%B0/ Sun, 13 Feb 2022 01:58:16 GMT <p>该记了!</p> <p>以后还是多写点解析吧……要不然过个两三年再回来看,肯定就不知道是什么意思了。</p> 该记了!

以后还是多写点解析吧……要不然过个两三年再回来看,肯定就不知道是什么意思了。

2.12

晚 普

列车

我在一座列车上,车厢不是车厢,而是一个又一个场景……

前几个场景不记得了,中间有个场景好像是我在一个楼梯上。因为背包里的书非常重,我就把他放在楼梯上,而我在一旁喘气……背包里的书似乎都没有封面的样子。楼梯上方似乎是一个幼儿教室的样子……

喂,你带回来的资料书该看了,要不然带回来到底要干嘛?

下一个场景是我在一家卖场里,带有科技感的四边形柱子悬在上方,我来到一个玻璃展柜前,似乎想要买,但是拿起来之后,还是放下,最后打算不买了。

最后一个场景似乎我下站了,我打开地图,发现我竟然在目的地反方向!我急忙问车站人员,得到答案我已经过了好多站了……我拿出手机,不是惯用手机,似乎是苹果的?我打开手机开始打字,输入法非常别扭,我连连打错,窘迫的不行。最后觉得这样子还不如……醒来……

然后我就醒了。

2.16

中 普

开包

我似乎有类似 jojo 布姐那样的能力,在任何事物上开拉链。

我在街上对着行道树干上使用了能力,然后……这拉链是明日方舟抽卡!我就对着一棵树抽起卡来,抽了似乎很多次。树伤痕累累……汁液滴的到处都是,之后就有管理人员过来,想要制裁我,他查看了树干,记下了三条拉链痕迹(其实还有很多!),我心里想着……至于吗……就这点小事就要把我关那么久?

氪金抽卡手游,恶心啊!

2.17

中 普

意外的联络

一个很久没联系的初中同学找上了我的 QQ ,然后给我发消息,说我的长毛象 ID 是这个,快来加我……

]]>
梦记 梦记 https://blog.southfox.me/2022/02/22%E5%B9%B42%E6%9C%88%E6%A2%A6%E8%AE%B0/#disqus_thread