[php] 将多个 RSS 地址合并成一个

弄了个 php 程序,可以把自己的(or 别人的)多个 blog 的 RSS 订阅地址,合并成一个,供人订阅。例如,现在本站的几个 blog 的统一订阅地址为:

https://feed.fivest.one/

程序基于 DigitalFreelancing 的代码,略作修改,调用了 SimplePie 处理 RSS 的项目库,为每个原始的 RSS 地址生成缓存,避免了频繁读取。我修改后的版本,可以从【这里】下载。

使用说明

  • 配置支持 PHP 的网络服务器,过程略;
  • 下载源文件后,解压到新的 RSS 地址相应的文件夹里;
  • 编辑 index.php,修改如下部分:
$feedlink = "https://feed.fivest.one/"; // 这个新的 RSS 的网址
$feedtitle = "fivestone"; // RSS 名称
$feedhome = "https://fivest.one"; // 你的网站地址(在 RSS 阅读器里点击 Title 可以进入)
$feeddesc = "fivestone's posts aggregation"; // RSS 描述

$feeds = array( // 需要合并的 RSS 网址列表,以引号和逗号分隔
    'https://a.fivest.one/feed',
    'https://b.fivest.one/feed'
);

$time_zone = 'Asia/Taipei'; // RSS 使用的时区
$item_number_limit = 20; // 新的 RSS 显示的文章数上限
$creativeCommons_license = 'https://creativecommons.org/licenses/by-sa/4.0'; // 你选择的知识产权协议(可以自行修改或为空)
  • 根据你的网络服务器的权限配置方式,可能需要把 cache 文件夹设为群组或全部可写
chmod g+w cache 或者 chmod a+w cache
  • 也可以把 index.php 改名,或者复制到其它位置,分别配置,生成多个这样的聚合 RSS。注意要调整文件中的相对路径:
include_once('./simplepie/autoloader.php');

曾经,以及现在,都拖了很多篇 blog 没有写。很多时候,起初只是一个想法,在脑子里萦绕,渐渐地有了大纲,连文章结构甚至一些辞句都有了。最后还是没有写出来。日子久了,也就渐渐忘了要写那篇东西时的思路和目的。

可以为拖延症找到很多理由:blog 式微了,在这里写了也没人来看;又或者有些东西写了反而怕被人看到;以及沮丧的时候,也不知道写出来,面对这个世界,能有什么作用。——但这些可能都不是多么重要的理由。本来我的 twitter 和 blog,就是在有些刻意地无视那些和其它网友交互的社交功能,而只是旁若无人地顾自说话。

但文章写出来,并不只是自己在某个时候,某种状态的展现;写作的过程,也是形成那些状态的过程。一些在脑子里萦绕的、模糊的、犹疑的,通过文字被固定下来。好像彷徨中为自己确立一个方向。

而我有些害怕这些方向。又或许在某些时刻,觉得自己最好还是不要,让某些状态清晰起来。

WordPress 使用 SQLite 数据库

之前写了一半的,如何在轻量级个人 VPS 上搭建各种服务的帖子。一时懒得去把坑填完了。但前几天突然发现自己落入了思维误区:为了配合 Mastodon 或 Pleroma,总想着如何把 WordPress 从 MySQL 迁移到 PostgreSQL。——但是,其实完全可以用 SQLite 啊!对于偶尔才更新一篇的个人 blog 用户,把数据库放在一个 SQLite 文件里,不需要另外安装数据库服务,完全是可行的。

用 Docker 观察内存开销。对于新建的 wordpress 站点,wordpress 本身(包括 php-fpm、nginx)占用内存大约是 40-100M(使用缓存插件后会减少);MySQL 数据库占用内存 200M,随着渐渐使用,有着近千篇文章和评论的 blog 站点,MySQL 占用内存会达到 500M 甚至更多。 ——数据库的这部分内存,使用 SQLite 后,完全是可以省下的。

可以通过 SQLite Integration 插件,安装基于 SQLite 的 WordPress。Wordpress 官网的插件页面,因为作者失联而停更。但隐藏的插件下载链接,一直都还有效:

https://downloads.wordpress.org/plugin/sqlite-integration.1.8.1.zip

最新版本的 WordPress 也仍然可用。Github 上也有这个插件的分支

使用非常简单,就是把 db.php 复制到 wp-content 目录里,同时确保你的系统安装了 php-sqlite3 模块。这里有篇攻略。现有的站点,可以通过 Duplicator 之类的 wordpress 备份插件,或者 wordpress 自身的导入导出功能,进行迁移,不需要进行数据库级别的转换操作。

注意事项:

1. 最重要的,数据库的文件的存放位置,这个一定要改!默认的数据库位置是在 wp-content/database/.ht.sqlite,是会被人通过浏览器从 http://website/wp-content/database/.ht.sqlite 直接下载的!虽然插件在 database 文件里添加了 .htaccess 权限控制,但对于如今大家用的 Nginx,是默认无效的。

在 wp-config.php 里添加设置:

define('DB_DIR', '/absolute/custom/path/to/directory/for/sqlite/database/file/');
define('DB_FILE', 'custom_filename_for_sqlite_database');

可以更改数据库文件的存放位置。强烈建议把数据库文件,放到无法直接用网址从外部访问的目录(记得给那个文件夹授权可写)。

2. SQLite 不适合多线程的高并发使用。如果网站会有多个用户同时在后台编辑,那么网站不适合使用 SQLlite;如果只有一个写作者自己编辑 blog,就很合适。但要避免使用那些,在一般访客浏览网站时,也会导致对数据库进行写入的插件,如:

  • WP Statistics 这样的访客统计插件,会把来访者的每一次点击,都记录到本机数据库里。建议使用 Google Analysis 之类的外置统计软件(Google 给 wordpress 做了个官方插件 Site Kit by Google),通过在页面嵌入 js ,发送访客数据到 Google 服务器,不会写入本地数据库。
  • 官方的防垃圾评论插件 Akismet Anti-Spam,其实也是先把每条评论写入本地数据库,再判断是否垃圾的。如果被机器人大量发送垃圾评论,也会造成数据库写入的压力。建议使用 WP Captcha 之类的验证码插件(可以单独使用或配合 Akismet 一起用),把大多数垃圾评论在写入数据库之前就过滤掉。

3. 使用 WP Super Cache 插件,为网站生成缓存文件,可以极大地减少对数据库的读取操作。个人用户完全可以在插件设置里,关闭默认的 Garbage Collection 功能。


网上搜到的 WordPress + SQLite 的 docker images(12),Wordpress 和 php 的版本都有些过时了,本身也有一些小问题(如数据库文件夹的权限设置),建议修改 Dockerfile 然后自行编译。回头有时间我去改个试试。

WordPress 的 ActivityPub 插件

试用一下 WordPress 的 ActivityPub 插件(官网 / Github)。

主要功能,就是在 wordpress 上,建一个 Fediverse 账号,Mastodon / Pleroma / Misskey / Honk……的用户可以 follow 这个账号。新的 blog 文章发布时,这个账号会发一条嘟文,大家可以转发这条嘟文。followers 对这条嘟文的回复,会自动同步到 blog 文章的评论区。

就像我为这个 blog 建的 fedi 账号:@[email protected]

需要指出的是,并不存在 blog.fivest.one 这样一个 fediverse 实例。陌生人搜索这个账号,看不到任何历史嘟文;这个账号不能去 follow 别人,不能对别人说话,不能回复别人对自己嘟文的回复,也不能看到多少人转发点赞了自己的嘟文。——这些功能也许以后会有,但目前,这个插件所做的,只是在新 blog 发布的那一刻,向所有 follow 这个 id 的账号,push 一条嘟文。这条嘟文,在 blog 服务器上,并没有保存;而只存在于 follow 它的那些实例上,再被人转发到更多实例。

当 blog 的文章被删除时,这个插件也会通知所有的 followers,从他们的实例上删除对应的嘟文。但是就像我说过的,这个机制并不能把那些,被转发到其它实例的嘟文,也一起删除。所以,当你在 blog 按下发布按钮的一刹那,带着你所写的全部内容(或者摘要,可设置)的嘟文,就可能会永远飘在 fediverse 世界里,无从反悔。所以,写完这篇文章后,我还不确定自己是否会继续用这个插件……

所以我只是觉得这个插件运行的机制很有趣,向大家介绍一下而已。它仅仅是通过 ActivityPub 协议,和其它实例通信,而本身并没有创建实例。这个插件在 wordpress 的数据库里,甚至没有新增一个 table,而只是把 followers 的公钥,存到了 wp-options 里(我觉得这么折腾 options 表,有点过犹不及了……)。总而言之,这是个超级轻量化,在 wordpress 基础上,完全不产生多余开销的东西。

我之前吐槽过,目前所有的 Fediverse 引擎,都是用软件工程模块,匆匆拼出来的臃肿怪兽:开销巨大,数据结构不美观,依赖的技术模块未必有长久的生命力,安全性抗冲击性都很差……其实我很期待,一个单用户版的,完全没有 local 功能,支持 ActivityPub 协议的引擎。结构的简洁程度,和资源的开销,要比现在这些要好很多。从这个插件可见一斑(虽然这个插件和完整的个人版 fedi 实例,是完全两回事……


测试了一下。好像只有 follower 的回复(公开 or 私密)才会同步到 blog 的评论区;陌生人的不可以。但目前还没有做 follow 的审核通过机制。所以理论上是可以用这个功能发垃圾评论……

以及目前还没有让用户修改个人简介的功能,图片上那些简介,都是我在插件 templates/author-json.php 里手动改代码的。

社交平台的六围

对各种用户提供内容的平台进行评价和比较时,我觉得大家争吵的,往往是不同维度的东西,而每个人更在意的方向并不相同。我列了一下,大概有这些因素。首先要做的,是自己打个权重,看看你对每个因素是不是真的在意(譬如公众传播度在有些人心中的比重,是远大于帖子是否会被删的——这未必是坏事)。然后就可以像游戏里角色的六围那样(其实列出来的不止六项),给每个平台逐项打分。

  • 思维自由度:你在写东西的时候,多大程度上,会受到其它因素的约束和干扰?这不仅仅指在真理部面前进行自我审查,也包括你所在的社区的发言氛围,以及你是否介意朋友们看到你发言时的反应。
  • 信息存活性:你的发言会不会被删,以及在更大范围上,你所在的平台会不会突然就没了……(或许这两条应该分开算?
  • 信息持续性:一方面是指热度:文章会不会过两天就沉下去,再没人关注(其实所有平台都会这样)。另一方面,哪怕没人关注,你是否希望文章一直存在,被需要的人偶尔搜出来看看?还有一点就是,当你换了平台,或者换了图床的时候,能不能用某种技术手段,让你的外链一直有效?
  • 便于讨论:你的文章是否便于让同好们进行讨论?以及,你所在的平台是否能聚集你的同好?
  • 公众影响:为了赚钱或者社会责任感,你是否宁愿自我阉割,也希望文章尽可能地被更多人看到?
  • 跨平台开放性:文章是否能让平台之外的用户看到?
  • 隐私安全:如果作者没有主动泄露个人信息,平台的架构以及管理人员,能否防止你被喝茶或者被人肉?
  • 技术便利性:建站、管理、日常访问、翻墙……是否方便?(其实我应该把管理员和普通用户分开的)

此外当然还有更多的参考因素(界面美观、用户体验、是否免费……),这里只是提供这样一个比较的思路。

我这里随手列了几个例子。一些网站我不常用没什么发言权:Facebook、Lofter、Matters、AO3、豆瓣……大家可以自行吐槽。

以下是吐槽部分:

  • 虽然 Mastodon 最初是作为避免 twitter 越发严重的政治审查而存在的,但目前各个实例中的用户趋向(或者说他们希望能趋向)同质化,导致目前给我的感觉,在 Mastodon 里说话的自由还不如 twitter。
  • 在 Google Reader 的时代,以及 Disqus 等平台试图统一 blog 评论体系的时代,blog 的讨论性是接近四颗星的,但目前只能用凄惨来形容。虽然每篇文章还是有评论区,但大家宁愿在 twitter 的链接下面回复,而没有人去文章下面留言了。
  • Facebook 这种完全建立在实名上的讨论群体,以及随之关联的发言规范,和我完全就是不同的世界,索性不予评价。

Hello Matters.

在 matters.news 上面开了个账号,可能会同步一些文章过去。这里是开篇介绍以及一些关于 blog 的吐槽。还不知能不能在那边写下去。


一直在考虑,要不要在 matters 开个账号,把自己 blog 上的一些文章同步过来。在 matters 关注了一段时间,这里确实集中了一部分很优秀的社科类写作者,希望能够继续关注下去。而且这年头坚持写中文 blog 的人确实不多了,也很希望能够有一个这方面的社群,能够进一步交流。

但还是有一些顾虑。


首先,作为原教旨 blog 拥护者,我一直认为 blog 作为一个开放系统,需要满足两个条件:

  1. 系统自带原生 RSS 订阅;
  2. 作者可以选择向所有人(无论是否 matters 用户)开发评论功能。

这两个条件,matters 一条也不符合。虽然有第三方工具实现 RSS,但毕竟不是 matters 自带的功能。而评论功能只有注册了一段时间的站内用户才可以用。所以我其实是不喜欢 Matters Medium 这类的网站形式的。当然关于这些指摘,有着各种解释:譬如这样更有利于付费订阅、避免垃圾评论和网络水军、以及未必只有开发系统才叫做 blog……但我还是认为这些都不是必须通过这种半封闭的架构,才能解决的。这些其实都是对互联网开放性的越来越深的伤害。——总之你们可以把这当作 blog 老用户的吐槽。

ps,在 matters 通过第三方生成 RSS 地址的攻略:
https://rsshub.app/matters/author/fivestone
把链接最后面的 id 换成你想要关注的作者 id。


其次,经过互联网十几年的风风雨雨,我现在对任何 blog 平台,乃至任何网站,几年后会不会倒闭,完全没有信心。这不是在诅咒 matters 啦,只是想到自己投入心血维持的社交网络,几年后因爲各种莫名的理由消失,就没心思把它继续下去。区块链保存也好、众筹维护也罢,其实都只是噱头。即使不涉及政治审查,仅仅是由于资本运作而倒闭的网站,无论墙内墙外,数不胜数:微软space、Google Reader……如今靠谱的老牌 blog 平台,似乎只剩下 wordpress 和 blogspot,免费版的页面上被塞满了难看广告。似乎只有自建域名和服务器,才是长久保存的王道。但那些自建 wordpress 以及用 Github 静态空间的 blog,需要的技术门槛也确实很高,能做到这一点的人,写出来的 blog 内容,也基本是纯IT(笑)。在 blog 式微的时代,维持一个低门槛的长期写作环境,确实是很难的事情。


在这里写东西,似乎要比自己写 blog,要更吃力一些。或许是因爲这套 LikeCoin 的打赏体系,吸引了很多希望从写文章而获得收入的人,所以写出来的文章更像是精心雕琢后可以直接发到正刊上的稿件。这当然没什么不好,但对于我这种习惯于写碎片,一个题目可能分成三四篇,想到什么就随便写一段发出去的人,还是会有些压力。但随著 matters 的用户群的增加,我也看到有人来这里写碎片化的日记了。

关于 LikeCoin 这套体系我还不是太明白。我在自己的 wordpress 上也安装了 LikeCoin 的点赞插件,但似乎只是把 likes 的账目记在 matters 名下,在用户交流的方面,和 matters 系统不是互通的。总之大家赶紧给我凑 15 个赞,让我好去评论别人。^^


最后,是关于简体字的问题。我更倾向于把简体字正体字的分隔归为历史因素,而不赞同通过政治或者「正体字更有文化」之类的理由,把两者明显割裂开来。Matters 无疑是正体字的大本营。虽然我两种字体读写都没有障碍,但我自己的 blog 确实是简体。一方面我认为其实没有必要在这里发文时必须用正体字,从而去迎合什么;但另一方面,我也确实担心简体字在这里会受到一定程度的歧视,并对这种状况觉得有些悲哀。


就这样吧,每次开篇都要很正式的样子写一堆(笑),也不知道会在这里坚持多久。

我为什么来推特

突然大家在回忆这个,于是也整理一下。

其实是先有 blog 再有 twitter 的。

2007年,在某个国内 blog 网站(好像是已经倒闭的 blogcn),看到个功能:在首页更新自己的一句话状态,类似于 QQ 签名档的样子。于是也想在自己的 wordpress 上面搞一个。研究了一圈,发现与其在 wordpress 上写代码,不如去注册 twitter,然后把最新的 twitter 信息同步过来。

当时有个叫做 twitter tools 的 wordpress 插件,可以定时把自己最新的推,存储到 wordpress 的数据库里,然后就可以本地调用,用纯文本的格式显示在首页上。——比 twitter 官方,以及各家山寨们,用 JavaScript 或者嵌入 frame 的方式显示,要清爽很多。这可能也是当时为什么没有首先用饭否、叽歪,等山寨货的原因。

后来还自己写了个插件,把存下来的推,每个月合成一篇 blog 文章。再后来 twitter API 改版,twitter tools 的插件也就不能用了。而 JavaScript 或者 frame 的方式,墙内的访问者是看不到的,反而会影响网页加载,也就没法用。(同样的道理 Google Analytics 也不好用)。一直想自己再写一个,基于新的 API 或者 RSS 把推同步到本地的插件的,但始终没有弄。

所以对我而言,注册 twitter 最初仍然只是自说自话的另一种方式,和 social 完全没关系。

没有Google Reader了,blog还要继续。

RT @ztpala: 没有Google Reader了,blog还要继续。

ps,但首先要搞定在blog上备份twitter的问题。twitter-tools倒是推出了配合Social插件,支持API 1.1的新版twitter认证,装上之后能从wordpress发推,但实时备份目前还没反应。而且原来是用新的数据表保存tweets,现在居然都存到wp-posts里了,导入旧推后,文章序列号从900多直接跳到5000多……挠头ing

社交网络 – 2

然后建设性地谈一下(避免被人说只会喷或者不关心业界),为什么我认为Facebook是一种倒退,以及,不是什么样的模式能够成功,而是社交网络应该是什么样子的。
还记得那个Web 2.0的标志是什么吗?blog?或者,准确地说,用户提供内容?是,但在blog出现之前,大家混的论坛/BBS,都可以叫用户提供内容……RSS,这个如今被每一个肤浅的IT评论员称为日薄西山的东西,它可以让用户自由订阅每个人发布的内容,无论他发在哪个平台。用户永远在提供内容;用什么样的方式,更便捷地得到这些内容,才是关键。

不得不说RSS这种偏技术层面的概念,确实没流行起来。即使在blog的鼎盛时期,写博的人知道RSS的,恐怕连1/5都 不到。很多人对于〖我经常点他们的博客从而能迅速在新文章下留言〗这件事很感动,不用谢。甚至连GFW都没有把RSS放在眼里——FeedSky这种境内RSS中转站,居然开到现在都没有被关,我每次想到都觉得不可思议。
当然不流行和国内业界风格有关。一切不支持RSS全文输出的博客都是满脑子点击量的傻逼伪博客,你们知道我说的谁谁谁谁。

下一步呢?用户交互内容。想想blogger们如今郁闷的是什么:每一篇文章,要跑去各种SNS,才能看到评论:GR/Buzz、FriendFeed、Facebook、九点、人人网新浪微博……而原始文章页面下的留言却寥寥无几。那些Twitter四处同步的孩子,也是同样的情况。各家SNS,把交互部分做出开放性的,一个都没有。现在你可以看出,什么是我所说的趋势和倒退了。所谓社交网络,无论实名与否, 最终要做到的是:整个互联网是一个大讨论区:一个。
让我们回到那个刚开始blog的年代。当时很多技术是在往这个方向走的:blog引擎、RSS、OpenID、 Disqus/IntenseDebate、Twitter(尽管很多人抱怨140字挤掉了大段blog的空间,但这个和电子书vs纸书强迫症一样,是个人适应性问题;Twitter在开放性上做的很不错)……但从Facebook挣钱后,一切都不一样了,人们莫名其妙认为这才是互联网的未来,一切又回到老路,像从前门户网站吸引眼球那样,把用户吸引到自己的SNS系统里玩。各种混战,Google也跟着发疯。连Twitter也把新版式往堆楼的方向去做了。

OpenID是大讨论区的根本,每个用户都有唯一的网址(域名或者专门的OpenID提供站点)作为各讨论区的账号,当年我一直等 Google提供类似MyOpenID的,把独立域名映射到Profile上的服务——幸亏没有。如今很多地方把Google/Facebook当做了OpenID本身,倒退。

Disqus/IntenseDebate,它们的出现当时让我很欣喜,认为我构想的架构就要实现了。这些网站提供一套插件,替换blog上原有的评论系统,如果很多blog都用了这个评论系统,你就能集中管理你在其它blog上的留言。我曾经把blog改成IntenseDebate的评论系统,但它家做的不够完美,各种复杂情况譬如重装wordpress,会导致IntenseDebate的评论重复甚至丢失;而且也不放心从此把所有评论数据交给它家。所以问题还是在于做的不够开放,对于想把评论的最终版本保存在自己空间的用户,要做到两者之间顺利地无缝合并。

所以最终要做的不是一个网站,而是一套标准接口。用户在所有网站,以统一的OpenID登录;可以有多个发布源:blog、twitter、 flickr……然后选择一家SNS,把这些源聚合起来,评论交流;每个人可以用不同的SNS,每家SNS都提供获取评论的接口,把各处的评论都汇总到发 布源上;SNS之间也可以互相同步,最终你在每一家看到的,都是同一份经过汇总的评论;不同的SNS可以有各自的特色,通过类似tag的方式来区分;每一条帖子都是一个树,站在发布源的位置,你可以清楚地看到它如何在各个SNS中蔓延。
这些都只是想法,具体的架构还没理清楚。关于如何在timeline里分配blog、tweet、以及鸡毛蒜皮的显示比重,也懒得继续想下去。类似Disqus+FriendFeed的评论托管网站是很好的开始,配合更强的开放性和数据管理/导入导出功能,让更多独立blog无后顾之忧地加入进 来……也许哪天,确定自己不再受生计羁绊后,会去做一下。估计这套标准弄好后,没人用的可能性相当大……如果对于账户金额或者玩弄大众心态等方面的成就感没兴趣的话,那么创业的乐趣也就是做一个自己也需要的东西。
顺便吐槽周围还有着做一番事业梦想的人:『很高兴认识你们』这件事情本身,基本上说明你和我一样,也不是多么大众脉搏的人。那些流行的,你没太多兴趣;同理你也不大可能做出迎合他们需求的产品。当然靠傍项目混点钱还是没问题的,想做出QQ苹果那种万人迷,还是省省罢。

基于搜索和访问量的年度总结回顾(2010)

看到8080童鞋的年度google搜索记录,也顺手查一下自己的。(点击图片看全图)

1、2月有大量时间在旅行和农场摘葡萄,4月后开始办公室宅,搜索记录趋于稳定,9月份回国两周,略有下降。
另外惊叹一下mm的作息是如此规律,居然每天都有固定的5个小时乖乖睡觉不上google。相比之下我这个完全看不出是在上班了。。。
———————–
顺便统计一下blog,虽然每年10k的访问量秀出来实在是寒碜,但想到自己和某些成天开着纵横的自曝癖相比已经好很多了,也就无所谓的说。

总体上就是这样子。每年都有一两次,因为某篇文章被名博名推引用,导致短时间内有大量人来围观,访问量从每天几十暴增到上千。今年的高潮是那篇喷MacBook的帖子,但也只潮到300多。另外感谢左右脑旋转的伪科学帖、四十部淫秽色情网络小说、西直门魂场、以及几篇大多过时了的翻墙或twitter同步教程,为本站稳定贡献着超过三成的访问量。
有趣的是访问本站的浏览器统计。虽然访问量IE占了超过一半,但是按网站停留时间算,其它浏览器的比例则猛增。说明本站对那些非IE用户的吸引力比IE过客们高很多。

全年的RSS平均订阅数为161,6月份老域名彻底注销后,很奇怪原先绑在老RSS地址上的30个订阅,并没有在订阅总数上体现出明显的降低。
———————–
海外RPG的第二关已经渐渐展开,明年的布朗运动和茫然程度,未必会比今年好多少,所以还是继续不列什么来年目标了。