MoreRSS

site iconatpX

一个记录作者思考、想法、有趣的东西的互联网角落。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

atpX的 RSS 预览

小城与确定性的墙

2024-11-03 22:03:30

the-city-and-its-certain-walls

拿到村上的新书《小城与不确定性的墙》后放了一周,等待其与书桌达成和谐后花了三天读完,读书时总静不下心,不时有触电一般的麻痹感。本想就这么独自咽下去,但回过神时已经在断断续续的写点什么了。这篇文章不是书评,也谈不上读后感,没有剧透,记录一点无关紧要的东西。

四年前写过一篇文章「我读村上春树」,而村上这次的新书与以往的风格略有不同,已然无法倒入原来的酒瓶,该说是更加清淡了还是更加醇香了,我一时间还难以分辨。不过他还是村上,我还是我,他爱写,我爱读,依旧处于某种美妙的平衡,大体上。

问题出在品酒的人身上,书的开篇起于十七岁的「我」和一座小城,想起十年前十七岁的我也发现了一座小城,不幸的,还能找到当时的推文。

the-city-tweet

如今看来略显造作,不过那时的心情还原原本本地保存在大脑里。两座城的位置不同,但基本结构可说相同,基本结构虽然相同,但细微之处肯定被修改成了为他而设的小城模样。因为那是为他而设的小城嘛。这些年来,我始终没找到那座小城的入口,我的影子不曾离开我,也绝不对我说一句话。或者,我始终没走出那座小城,即便随时可以离开,也始终未曾踏出一步。

近几年做梦的次数多了起来,世界尽头的梦中世界依旧模糊,你偶尔会出现,但醒来后很快就会被墙分隔开。我多少已经确定,就算能够重逢,那堵墙依然会在那里,它是确定的墙,无论过多久,不管是十七岁、二十七岁还是三十七岁,它永远会在那里等着我。

读完这本书,村上式的成长与寻找终于迎来了结局。我也终于下定决心拔掉同样卡在我喉中的鱼鲠,就算是确定的墙,只要闭上眼睛,向前一直冲过去,只要心里不害怕,墙就根本不存在。如果哪天突然有人找到你,就不要再疑虑,像清晨落入房间的第一束光线般,果决地离开这座小城吧。

EOF

如果你觉得这篇文章还不错,可以考虑支持作者

一只特立独行的猪

2024-10-29 22:36:10

我有一位朋友在养猪场工作,其实我和他不太熟,但每三个月他轮班休假时总要拉我吃一顿饭,讲他在猪场里的趣事,我出于无聊每次都没拒绝。朋友说他这次遇到了一只特立独行的猪,当然,和王小波认识的不是同一头猪,他认识的这只猪不会跳上房顶晒太阳,也不会学汽笛叫,但有它自己的特别之处。

朋友说,现在的猪场都严格管理,有一大堆规定要遵守,严控出入、定期消毒,一旦出现问题,就要隔离淘汰。但说实在的,这只特立独行的猪,暂且称它为「特猪」,总不太合群,也不愿守规矩。每当开饭时其它猪都哼哼着埋头苦吃,就它一猪在旁边不以为然,等到其它猪都吃饱喝足赞美今日伙食时,它才在一旁嚎叫起来,仿佛在控诉伙食的差劲,完全不是给猪吃的。当然,我朋友也不会理睬它,过了饭点就该赶回猪圈中去,所以特猪总是在最后时刻冲上去胡吃几口,每次都让他忍俊不禁。

特猪还有一个奇特的地方,不爱睡觉。其它猪呼呼大睡时它总爱用头去顶它们,因此脸上总挂着一排猪蹄印子,朋友说这排猪蹄印子可能是它骄傲的勋章,有了这勋章它便无所畏惧,时刻享受自己独特的风采。有一次我朋友刚进场地,特猪远远地看见了他,便抬起头来炫耀它的勋章,朋友学着猪叫朝它哼了一声,不想它立马大嚎起来,铆足劲儿试图冲过围栏来顶我朋友,好在围栏够结实没让它得逞,落得个四脚朝天,不然我朋友的屁股可要遭殃。

上个月某一天,我朋友发现特猪不见了,赶紧查看监控,才看到是场长一大早来把特猪抓走了,询问后场长告诉他这只猪太瘦了,半年了都喂不肥,送到隔壁屠宰场止损了。朋友口头上称赞了场长的智慧,但暗地里还是有一丝失落,虽然特猪总是特立独行,但多少是个乐子啊。

「你知道最神奇的是什么吗?」朋友边说边用筷子在酸菜肉丝汤中翻了翻,似乎没找到肉丝,不等我回答赶紧补充道,「前天下午我准备休假离开猪场时,又瞥见角落里出现了一只挂着骄傲勋章的猪,一开始还以为眼花了,仔细一看,这可不止一只啊,两只、三只… 居然整个猪场里的猪脸上都有一排猪蹄印子!」

朋友用夹着烟头的手兴奋地举起啤酒杯,用力伸过来碰了碰我的,烟灰掉进了我的杯中,我们笑着一饮而尽。

EOF

如果你觉得这篇文章还不错,可以考虑支持作者

Fediverse 与社交

2024-10-17 00:50:15

Fediverse(联邦宇宙)的理念很美好,简单来说就是把社交这件事从网络巨头公司中解放出来,通过去中心化让用户对自己的数据拥有更大的控制权,是一种更开放、多样的交流方式。Fediverse 有不同的通信协议可以选择,也有社交媒体、视频/图片分享、博客等不同的服务,它更像是一个生态系统,用户可以在不同服务之间自由互动,而不只是局限在单一平台内。

自建过 Misskey, Pleroma, Mastodon,但加起来的存活时间可能也没超过一年,也许是我的使用方式有问题,基本只拿来当个新闻阅读器,导致每次迁移服务器时都没动力重新部署,也可能是我逐渐发现去中心化和社交这两件事并不是那么合拍。

我的 Mastodon 实例图片
我的 Mastodon 实例删库前截图留念。

去中心化与社交

我在随想「博客的未来是去中心化吗」中提过,绝大多数人的社交习惯是趋向于中心化的,我们更享受中心化的便利和热闹,不管是现实中的朋友还是喜欢的歌手或演员,在中心化平台里都能轻松搜索找到,就算不主动关注也会在某一天突然出现在你的首页。但在 Fediverse 中找一个人只有靠缘分和口口相传,我想关注的人大多没注册账号,也可能注册了但找不到,搜索和发现内容也取决于实例中所有用户的关注。所以哪怕有 10% 的人鼓起勇气离开推特、微博等平台,在选择 Fediverse 平台和实例时也只是想找个方便、稳定且有一定用户量的社区。

当然,这不是「去中心化」的问题,整个 Fediverse 都在努力去中心化,只是人们在去中心化中仍然选择了中心化,这种选择也是合理的,社交这种事总是不嫌观众多。另一方面,只要接受用户注册,每个实例的运行、审核和管理的成本都不会小,而且几乎只靠一个人或几个人维护。去中心化从设计上就在避免广告、跟踪和隐私收集,管理员除了接受捐赠外几乎找不到其他收入来维持基本开销,一旦你加上广告,用户自然会毫不犹豫地迁移到其他实例上去。对于没有赞助的实例,要维持长期运行更像是比谁家的管理员更能用爱发电。

如果我们愿意放弃一点便利性,去中心化和社交可能会和谐得多。

Fediverse 不只 Mastodon

从 StatusNet, GNUSocial 到 OStatus,去中心化社交并不是一个新东西。现在谈到 Fediverse,很多人就默认等于 Mastodon,这不是一件好事。如今 Fediverse 集中在 Mastodon 上,而 Masodon 用户集中在几个大实例上,甚至搭建 Mastodon 的服务器也集中在 AWS 和 Hetzner 上。Fediverse 看似庞大,圈子却很小,也相对脆弱,只需关闭少数重要节点,或者某个服务托管商网络故障,就能让大半个宇宙失去联结。

这也导致了 Mastodon 越想替代推特,就越可能成为下一个推特。Mastodon 对 ActivityPub 的实现在很多时候已经偏离了规范(ActivityPub 自然也存在限制),有不少自己的特性,这对于其他平台来说,是遵守 ActivityPub 规范还是以老大 Mastodon 为标准呢?如果 Mastodon 的官方实例无限膨胀下去(毕竟在大多数人看来这是最可靠的选择)无疑又会成为下一个中心化平台。「不爽可以随时迁移」的特性也看似美好,但你要确保及时导出了数据,而且 ActivityPub 注定了数据迁移并不容易(更像是跳转的形式,无法在新实例上导入历史发文记录),相比之下 BlueSky 的 AT Protocol 协议在迁移数据的设计就要友好不少。

不过我并不反对 Mastodon 成为事实上的标准,Mastodon 对推广 ActivityPub 和联邦宇宙做了很大贡献,只要保持开放性,以用户体验为主,也没什么不好。

孤岛和隐私问题

尽管 Fediverse 的设计旨在去中心化和多样性,为用户提供自由的选择,但 Fediverse 并没有消灭权力,而是将权力分散到了每一个实例。每个实例都有自己的规则和偏好,实例管理员拥有绝对的控制权,能根据自己的爱好、文化认识或全凭心情去封禁一个话题或屏蔽另一个实例,如果一些大实例互相屏蔽,将导致用户只能在特定的社群中交流,形成信息孤岛,而在小实例中这个问题会变的更加严重。Mastodon 最近也推出了一个名为 Fediscovery 的新项目,类似于中继协议但更加轻量,来帮助中小型实例和他们的用户在 Fediverse 中更好的搜索和发现内容,不过效果还有待检验。

虽然 Fediverse 强调保护用户隐私,但目前只限于理念和程序代码本身的层面上,实例管理员完全有权限收集和分析用户数据,或者某些实例缺乏技术支持,服务器安全措施不到位等因素依然会导致用户信息泄露。同时,中心化平台至少有政府和法律监管底线,而 Fediverse 的特性注定了会更容易产生一些不友好的实例,仇恨言论、歧视、色情等,但一般管理员看到后都会选择封禁这些不友好的实例,这里也不做探讨。

Fediverse 与社交

说了这么多,那么 Fediverse 的所提倡的去中心化与社交矛盾吗?我认为不矛盾,虽然不太合拍,但无论如何 Fediverse 带来的意义是积极的,不管是真的去中心化还是在「cosplay 去中心化」,它为我们解决的是有没有的问题。

很多时候,大家只是想要一个可以畅所欲言的平台或者说多一个选择,Fediverse 在今天这个隐私收集泛滥,动不动就禁言封号的中心化平台时代为我们提供了一个更自由的选择,有一小部分人在 Fediverse 中找到了自己舒适的圈子已经足够说明这是行得通的。没有广告与流量,大家只是在纯粹的分享或吐槽,就像社交应该有的样子一样。小众不一定是坏事,很多平台和社区最美好的时候都是他们小众的时候。

为了发展一个「不断增长、健康、经济上可行和多极的 Fediverse」,一些致力于开放网络和分布式社交平台的专家和倡导者于上个月(2024 年 9 月 24 日)成立了一个名为 Social Web Foundation(社交网络基金会)的非营利组织,尽管赞助公司中有几家似乎缺乏说服力,说明 Fediverse 仍在向着更好的方向不断发展和完善。

最后,我认为 Fediverse 并不是一切问题的解决方案,可以只把它看为另一种社交方式,它没有魔法,并不适合所有人,也大概率不会成为主流,但如果你认同其理念,总是值得去探索尝试的。如果条件允许,我更推荐你自己或和几个朋友一起搭建一个实例,宇宙中如果只有几个巨无霸星球的话也太寂寥了点。

Go to social?

如开篇所说,经历几次尝试后,我觉得 Fediverse 对我来说是可有可无的,毕竟我对社交媒体的使用局限在看科技新闻和猫猫狗狗。当然多一个选择也不是坏事,没有坚持的原因还有一部分是因为目前的平台都太重了,尤其是 Mastodon,对低配 VPS 并不友好,直到最近发现了使用 Golang 开发的 GoToSocial 项目,又对自建产生了兴趣。

在 GoToSocial 的官网介绍中有这样一段话:

## Is there a flagship instance I can join?

Nope!

We also don’t believe that flagship instances with thousands and thousands of users are very good for the Fediverse, since they tend towards centralization and can easily become ’too big to block'.

「我们也不认为拥有成千上万用户的旗舰实例对 Fediverse 来说有多大好处,因为它们倾向于集中化,并且很容易变得太大而无法阻挡。」

难得和我的观点契合,再看到 GoToSocial 只占用大约 250-350MB 内存,还支持 SQLite,就算迁移也十分方便,大幅降低了自建的门槛,当即决定在 Fediverse 中再复活一次。官方文档也写得很清晰易懂,很快就搭建了一个实例。

不过 GoToSocial 目前刚进入 Beta 阶段(官方 Roadmap),存在一些 bug 和功能缺失,目前也没有网页端进行交互,只有个人主页和设置等几个页面。日常使用需要配合兼容 Mastodon API 的客户端或者 Web 应用,我网页端搭配的是 Elk 或者 Phanpy,手机端直接使用 Mastodon 官方 App 或者 Ice Cubes (iOS),最近一周多体验下来确实会遇到一些 bug,但没什么大问题,能满足轻度使用的需求。

这次也立个目标,至少坚持到 GoToSocial 推出稳定版(2026 年+),希望这期间能在 Fediverse 中找到更多的乐趣,也欢迎我互动 (@[email protected])。

EOF

如果你觉得这篇文章还不错,可以考虑支持作者

承认的勇气

2024-10-03 01:09:15

王小波写过一篇文章叫「承认的勇气」,他说承认自己傻过也是一种美德,年轻时他没有这种美德,总觉得自己很聪明,而且永远很聪明,既不会一时糊涂,也不会受愚弄。后来终于有了一种智慧,有这种智慧也不配叫做智者,顶多叫个成年人。很不幸的是,好多同龄人连这种智慧都没有,这就错过了在他们那个年代里能学会的唯一的智慧——知道自己受了愚弄。

为了拥有这种美德,我也尝试承认自己是傻X,但王小波说的也不一定对,因此我也可能不是傻X。但可以确定的是现在的人普遍缺少这种美德,总不肯承认自己傻过,仿佛这样就能使自己显得聪明。比如在网上总有相当多的人热衷于信誓旦旦的胡说八道,就算超出自己知识和理解范围,明知错误也要自信的强答或者强骂几句,被指正也无所谓,他们不在乎对错,只是想证明自己更聪明。

阶级上层的人希望阶级下层的人是傻X,这样他们可以长久保住阶级地位;阶级下层的人认为阶级上层的人是傻X,只顾自己不想法缩短阶级差距。事实上他们都不是傻X,只是愚弄他人和被愚弄的人。

我一直都很反感「世界是个巨大的草台班子」这句话,无疑是忽略了除阶级外的一些重要东西,无论归因于出生、成长环境还是运气,成为所谓的草台班子大致也需要相当的努力,如果不需要努力,那他更不大可能是个傻X。同时,说这句话也不会让我觉得自己更聪明或好受一些,因为我也终于有了一种智慧——知道自己受了愚弄。如果要安慰自己自然有更好使的句子,我们只是恰好在宇宙边缘的一个破球上过家家。

假如这世上有人愚弄了我,我更是心服口服:既然你能耍了我,那就没什么说的——我是傻X。人生在世有如棋局,输一着就是当了回傻X,懂得这个才叫会下棋。

除了要有勇气承认自己是傻X,还要有勇气承认自己会犯错,承认自己爱,承认自己恨。但如此直白的承认会被大家指认为一个低情商的人,所以有时也要学会委婉的承认,至少你自己心里要明白。就像我承认自己只是想水一篇文章而已,如果你不信,那我就是个有美德的人。

EOF

如果你觉得这篇文章还不错,可以考虑支持作者

mediaX - 轻量书影音记录管理工具

2024-08-22 01:29:57

前段时间写 Misc 页面的时候就在考虑书影音记录的数据源问题,最后得出结论还得有一份自己本地的备份才好。Excel 固然可以满足,但不够优雅,搜索 media tracker 也能找到不少已经比较完善的项目,但我只想要一个小而美。于是决定着手开发一个自己的书影音记录管理工具。

一开始准备用 Python 或者 PHP 写,不过既然主要目的是备份,运行环境要求自然越低越好,最好只需要一个可执行文件和 SQLite 数据库。目光最终转向了 Rust 和 Go 语言。

上一次接触 Go 还是多年前的 Hello World,所以这个项目也是抱着学习的态度,想到哪写到哪,写到哪查到哪。奋发图强了半个多月,基本功能也比较完善了,如有需要欢迎使用体验。

Github 项目地址:https://github.com/scenery/mediax

项目简介

mediaX 是一款使用 Go 语言开发的个人阅读/观影/看剧/追番/游戏记录 Web 管理工具。

特点:

  • Go 原生 Web 开发,无外部框架
  • 轻量,简单,无任何 JavaScript 代码
  • 数据库使用 SQLite + 纯 Go 实现的驱动 glebarez/sqlite,无 CGO 依赖
  • 支持从豆瓣或 Bangumi 导入已有历史记录
  • 支持新增条目时自动从豆瓣或 Bangumi 获取数据
  • 支持导出内部记录为 JSON 数据

预览:

主页和分类页
主页和分类页。
详情页和添加条目页面
详情页和添加条目页面。

条目的信息字段没有设计太多,只记录一些关键数据。网页样式上延续了本站的风格没有风格,同样没有使用任何 JavaScript 代码和 Cookie,因此部分功能实现上比较受限。用户登录和多用户功能一开始设计时就决定不做,预期是一个运行在树莓派、NAS 等设备上的局域网应用,如需放到公网使用请使用加密 tunnel 连接,或在 web server 上做好鉴权和 IP 限制。

* 该项目主要是为了满足个人学习和使用需要,暂不接受新功能建议,如果有额外功能需求欢迎 fork 修改(MIT 协议)。

使用说明

mediaX 支持导入豆瓣(图书/电影/剧集)或 Bangumi 番组计划(图书/电影/剧集/番剧/游戏)数据来源的个人历史记录,其中 Bangumi 的电影和剧集记录因 API 返回内容限制未做详细区分,简单的判断如果只有一集归类为电影,大于一集则归类为剧集。

  • 导入豆瓣数据:首先使用「豆伴」导出数据,安装好插件后,进入设置连接账号,然后点击浏览器任务栏插件图标选择 新建任务,选择备份的项目中只勾选第一个 影/音/书/游/剧,等待任务完成后,点击右上方 浏览备份 - 备份数据库,解压下载的文件,其中的 tofu[xxxxxx].json 为需要的文件。
  • 导入 Bangumi 数据:可以直接使用 Bangumi 提供的 API 获得数据,在返回结果最后的 total 属性中可以看到你的记录总数,由于单次请求最多返回 50 条记录,如果超过 50 条需要修改 offset 分页参数多获取几次,最后将所有数据汇总保存为 JSON 文件。

导入数据

将 JSON 文件放到 mediaX 程序相同目录下,执行命令:

# Linux / macOS
./mediax --import <douban|bangumi> --file <file.json> [--download-image]
# Windows
mediax.exe --import <douban|bangumi> --file <file.json> [--download-image]

# e.g. 导入豆瓣数据
# ./mediax --import douban --file tofu[xxxxxx].json --download-image

最后的 --download-image 为可选参数,如果加上则导入的时候会尝试下载封面图片,如果数据量大的话会比较耗时(为了避免 IP 被 ban 下载间隔为 1s),请耐心等待。

不推荐重复导入一个文件,如果重复导入文件,目前只是简单的比对已导入的记录(原链接)和已下载的图片文件是否已经存在,如果存在则跳过导入。

导出数据

mediaX 支持导出内部数据为 JSON 文件:

{
  "subjects": [
    {
      "uuid": string,
      "subject_type": string,
      "title": string,
      "alt_title": string,
      "pub_date": string,
      "creator": string,
      "press": string,
      "status": int,
      "rating": int,
      "summary": string,
      "comment": string,
      "external_url": string,
      "mark_date": string,
      "created_at": string
    }
  ],
  "export_time": string,
  "total_count": int
}

导出命令:

# Linux / macOS
./mediax --export <all|anime|movie|book|tv|game> [--limit <number>]
# Windows
mediax.exe --export <all|anime|movie|book|tv|game> [--limit <number>]

# e.g. 导出最近 5 条图书数据,如果不加 --limit 参数则导出该类型全部记录
# ./mediax --export book --limit 5

导出的文件将自动保存在程序目录下。

API

目前 mediaX 支持通过 API 获取基本的个人收藏条目数据,请求接口如下:

/api/v0/collection

返回格式:

{
  "subjects": [
    {
      "uuid": string,
      "subject_type": string,
      "title": string,
      "alt_title": string,
      "pub_date": string,
      "creator": string,
      "press": string,
      "status": int,
      "rating": int,
      "summary": string,
      "comment": string,
      "external_url": string,
      "mark_date": string,
      "created_at": string
    }
  ],
  "response_tim": string,
  "total_count": int,
  "limit": int,
  "offset": int
}

可选参数:

  • type: 获取数据的类型,默认为所有类型,可选 book, movie, tv, anime, game
  • limit: 获取数据的数量限制,默认(最大)为 50
  • offset: 获取数据的起始位置(跳过的记录数量),默认为 0

例如,使用 curl 命令获取数据:

# 获取最近 5 条图书数据
curl "http://localhost:8080/api/v0/collection?type=book&limit=5"
# 获取第 6 至 10 条图书数据
curl "http://localhost:8080/api/v0/collection?type=book&limit=5&offset=5"

Linux 上持久化运行

一个简单的持久化运行配置示例,新建 systemd 服务:

vim /etc/systemd/system/mediax.service

添加下面内容,其中 User 为运行服务的用户,需要有 mediaX 工作目录的读写权限, --port 8080 可以修改为你需要的运行端口。

[Unit]
Description=mediaX <https://github.com/scenery/mediax>
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/path/to/mediax
ExecStart=/path/to/mediax/mediax --port 8080
Restart=on-failure
RestartSec=10s

[Install]
WantedBy=multi-user.target

运行管理:

# 重新加载 systemd 配置:
sudo systemctl daemon-reload
# 设置开机自启:
sudo systemctl enable mediax
# 启动服务:
sudo systemctl start mediax
# 停止服务:
sudo systemctl stop mediax
# 服务状态:
sudo systemctl status mediax

写在最后

因为 Go 语言入门比较友好,整个项目也比较简单,开发过程中除了写缓存功能时大脑多次宕机外,其他都还算比较顺利。不过是个体力活,赞美 if err != nil

数据库最初设计时按类别建了多张表,差不多写完的时候突然觉得数据量又不大,一个正常地球人一生也读不了看不了多少,多表徒增复杂度,最后又把数据库重新设计合并为一张表。如果你是三体人可能会遇到数据库性能瓶颈。

导入记录功能需要用户提前准备数据,虽然可以写进程序里但没必要。新增条目时自动获取数据依赖 API,如果未来获取豆瓣数据失效,会考虑改为从 The Movie Database (TMDB) 上获取数据。顺便提一下导入豆瓣数据后搜索“未知”,可能会发现一些被豆瓣下架的条目,比如「V 字仇杀队」等,到 Wayback Machine 上搜一下相应链接说不定能在远古记录中找回来。

最后,这应该不是一个长期维护项目,稳定之后可能不怎么更新。

EOF

如果你觉得这篇文章还不错,可以考虑支持作者