diff options
-rw-r--r-- | _data/ai-cache.json | 3 | ||||
-rw-r--r-- | _data/proxylist.yml | 3 | ||||
-rw-r--r-- | _posts/2025-08-10-tilde.md | 70 | ||||
-rw-r--r-- | feed.json | 2 | ||||
-rw-r--r-- | rss.xml | 5 | ||||
-rw-r--r-- | sitemap.xsl | 18 |
6 files changed, 87 insertions, 14 deletions
diff --git a/_data/ai-cache.json b/_data/ai-cache.json index de5fcdc..ccb3c8f 100644 --- a/_data/ai-cache.json +++ b/_data/ai-cache.json @@ -167,5 +167,6 @@ "/2025/07/01/xslt.html": "这篇文章讲述了作者如何为博客的XML订阅文件添加一个与博客主题一致的XSLT样式,以提高整体风格的统一性。作者遇到的问题包括Jekyll引擎的限制、XML格式的规则、命名空间对输出的影响,以及如何解决样式问题。通过模仿现有样式、自定义XSLT布局和doctype-system设置,作者最终成功地为订阅文件和Sitemap创建了定制的XSLT样式。整个过程不仅提升了博客细节,也让作者学习到了关于XML和XSLT的新知识。", "/2025/07/13/hacked.html": "这篇文章讲述了作者在登录一台闲置服务器时发现被入侵的经历。通过观察服务器负载和进程,作者意识到存在恶意软件。作者使用了netstat、lsof等工具进行调查,发现了一个名为gs-dbus的木马进程和libprocesshider.so文件,这隐藏了其他恶意工具。作者通过查找自启动服务、清理木马、修改密码等方式进行了应对,并分析了入侵者使用的工具,如Global Socket项目和logclean。作者认为这次入侵虽然造成了损失,但也学到了一些知识。", "/2025/07/24/screenshot.html": "这篇文章介绍了如何利用Cloudflare的“浏览器呈现”功能,创建一个自动更新的网站预览图服务。作者发现这个新功能可以用来展示网站在不同设备上的显示效果,通过在Cloudflare Workers中使用iframe和CSS缩放技术,以及调用Cloudflare的接口抓取浏览器渲染的截图。虽然免费用户每天只有10分钟的使用时间,限制了实时更新,但作者通过缓存实现了每天自动更新一次的预览图,并分享了具体的实现代码和使用方法。作者赞赏Cloudflare提供的这项强大且免费的服务。", - "/2025/08/01/sw-proxy.html": "这篇文章介绍了作者如何利用Service Worker在现代浏览器中实现一个简单的反向代理功能,以提供博客的备份和离线访问。作者原本希望通过Service Worker在用户浏览器中运行一个Web服务器来存储博客副本,但发现 tar.gz 文件的处理需要第三方库且难以找到适用的解决方案,尤其是对于tar文件的处理。作者最终选择使用Service Worker作为反向代理,将请求转发到其他网站,如GeoCities风格的静态网站托管平台,实现了类似的效果。这个过程中,作者体验到了浏览器功能的强大,并认为Service Worker在离线场景中有更大的潜力,尽管在他的例子中并没有充分展示这种优势。" + "/2025/08/01/sw-proxy.html": "这篇文章介绍了作者如何利用Service Worker在现代浏览器中实现一个简单的反向代理功能,以提供博客的备份和离线访问。作者原本希望通过Service Worker在用户浏览器中运行一个Web服务器来存储博客副本,但发现 tar.gz 文件的处理需要第三方库且难以找到适用的解决方案,尤其是对于tar文件的处理。作者最终选择使用Service Worker作为反向代理,将请求转发到其他网站,如GeoCities风格的静态网站托管平台,实现了类似的效果。这个过程中,作者体验到了浏览器功能的强大,并认为Service Worker在离线场景中有更大的潜力,尽管在他的例子中并没有充分展示这种优势。", + "/2025/08/10/tilde.html": "这篇文章介绍了作者在Tilde社区的体验,这是一类基于类Unix环境的公共服务器社区,类似于家目录,提供预装的软件、开发环境和公共服务,如聊天室、邮件、BBS论坛等,强调了社区的互动性和共享精神。作者通过申请、审核过程加入了几个社区,并详细描述了在这些社区中的个人主页、编程支持(如Gemini和Gopher协议)、博客发布、代码托管(Git支持)、CI/CD部署以及使用Git hooks自动化博客更新等功能。尽管作者受限于语言和工具使用体验,未能充分参与社区交流,但对社区学习新知识和丰富博客内容印象深刻。" }
\ No newline at end of file diff --git a/_data/proxylist.yml b/_data/proxylist.yml index 18bbf85..3674cca 100644 --- a/_data/proxylist.yml +++ b/_data/proxylist.yml @@ -2,7 +2,6 @@ proxies: - https://blog.mayx.workers.dev/ - https://mayx.deno.dev/ - https://yuki.gear.host/ -- https://mayx.serv00.net/ - https://mayx.global.ssl.fastly.net/ mirrors: - https://mayx.gitlab.io/ @@ -13,6 +12,7 @@ mirrors: - https://mayx.frama.io/ - https://mayx.surge.sh/ - https://mayx.pages.gay/ +- https://mayx.serv00.net/ - https://mayx.vercel.app/ - https://mayx.netlify.app/ - https://mabbs.kinsta.page/ @@ -42,6 +42,7 @@ gits: - https://bitbucket.org/unmayx/mayx - https://git.disroot.org/mayx/mayx - https://gitlab.haskell.org/mayx/mayx +- https://repo2.serv00.com/git/pub/Mayx/mayx/ - https://gitee.com/mabbs/mabbs - https://sourceforge.net/projects/mayx/ static: diff --git a/_posts/2025-08-10-tilde.md b/_posts/2025-08-10-tilde.md new file mode 100644 index 0000000..a362cd4 --- /dev/null +++ b/_posts/2025-08-10-tilde.md @@ -0,0 +1,70 @@ +--- +layout: post +title: 在Tilde社区的游玩体验 +tags: [tilde, 服务器, git, 体验] +--- + + Tilde社区,如“家”一般的感受😝<!--more--> + +# 起因 + 在[上一篇文章](/2025/08/01/sw-proxy.html)里,我说到给我的博客增加了不少网站[镜像](/proxylist.html),也在这个过程中发现了不少Git平台实例。顺便一提,我找到了个不错的[仓库](https://github.com/ecosyste-ms/repos),可以全网搜索各种Git平台实例。在这探索的过程中,我发现了一种神奇的社区——Tilde社区,体验之后感觉非常有意思,所以来分享一下。 + +# 什么是Tilde社区 + Tilde社区之所以叫Tilde,是因为在类Unix系统(如Linux、BSD)中,波浪号(Tilde)“~”代表家目录。因此,Tilde社区就是基于类Unix系统环境,并且可以公共登录的服务器,又被称为<abbr title="public access unix systems">pubnixes</abbr>。一般这些社区的管理员会预装很多软件、开发环境以及一些公共服务,比如聊天室、邮件、BBS论坛等,这些构成了社区互动的基础。不过并不是所有类似这样提供Shell访问的公共服务器都可以被称作社区,比如知名的免费网站托管商[Serv00](https://www.serv00.com)虽然也提供可以登录的FreeBSD服务器,并且在服务器上安装了非常多的工具和环境,从表面来看和Tilde社区提供的服务几乎一模一样,但是它少了一个很重要的东西,那就是社区,它的权限管理非常严格,不允许服务器的用户互相串门,也没有互相交流的平台,而且它的本质是商业服务(尽管是免费的),所以它不算Tilde社区。 + 至于Tilde社区的加入方式,一般可以通过填写在线申请表、私信或发送邮件申请,有些比较有特色的社区会用SSH交互等方式。审核通过后,管理员就会在服务器上为你创建账户,即可获得属于自己的“家”,一般的Tilde社区在这个过程中不需要付一分钱,因为他们通常都是反商业化的,如果遇到了需要付钱才能激活账户的公共服务器,那就不是Tilde社区,即使它历史悠久,可能是别的什么东西😆。 + 那么在哪里可以找到它们呢?有一个不错的网站,叫做[tildeverse](https://tildeverse.org),这不仅是一个Tilde社区的集合,它自身也提供了很多服务。不过总的来说各个社区之间也是互相独立的,tildeverse只是提供了一个平台让大家可以互相沟通,所以这个网站叫做“loose association”,就相当于博客中的博客圈一样。 + 于是我在tildeverse的成员列表中随便挑选了几个Tilde社区提交了注册申请,过了一段时间申请通过了,那么接下来就来说说我在Tilde社区的体验吧。 + +# Tilde社区的体验 + 虽然我加入了不少Tilde社区,不过各个社区提供的服务都差不多,首先最重要的就是个人主页,一般Tilde社区基本上都会提供一个像`~/public_html`这样的目录存放个人主页的网页文件,并且可以通过类似`example.com/~username`这样的地址访问,还有些社区会允许通过二级域名的方式访问,类似`username.example.com`这样,像我博客好多地方写的都是从根路径开始,就很适合用二级域名的方式。这些主页大多也支持使用PHP之类的网页,不过不像虚拟主机那样有个面板可以轻松安装扩展和切换版本,有些可能要自己写配置文件,有些可能要管理员才可以操作,毕竟是社区,所以不太注重用户体验。 + 当然除了HTTP协议的个人主页,通常他们还可以创建一些Gemini协议和Gopher协议的个人主页,这些协议不支持普通浏览器访问,需要用[ELinks](https://github.com/rkd77/elinks)之类的文本浏览器才能打开,这个浏览器甚至可以在终端里用鼠标操作😆。不过因为协议非常简单,所以内容也就只能整些文本内容了。 + 除了个人主页外,一般还会提供编写博客的程序,比如[bashblog](https://github.com/cfenollosa/bashblog),用这个编写好之后就可以直接生成HTML网站,能直接发布到自己的主页上让别人访问。这个脚本还是纯Bash的,就和我当年的[Mabbs](https://github.com/Mabbs/Mabbs.Project)一样,看起来还挺酷,当然功能上肯定比不上正经的静态博客生成器😆。 + 当然博客是一方面,还可以写微博,他们一般提供一款叫[twtxt](https://github.com/buckket/twtxt)的软件,用这个软件可以使用命令发微博,还能关注其他人,查看时间线,而且这还是去中心化的,可以跨服务器进行关注,感觉就和[Mastodon](https://github.com/mastodon/mastodon)一样。 + 除此之外作为社区当然就会有聊天室和论坛了,不过这些聊天室和BBS论坛通常不会像大多数人使用的那种通过Web或者图形界面来查看,而是纯文本的那种,比如论坛通常会用[Bulletin Butter & Jelly](https://github.com/bbj-dev/bbj),聊天室会用IRC,可以使用[WeeChat](https://github.com/weechat/weechat),只是我对IRC的印象不太好,在终端使用的IRC客户端没有一个使用体验好的😅,相比于其他在终端使用的软件,操作通常只需要一些快捷键,而且界面上通常会有提示,而IRC客户端就只能敲命令,而且还担心敲错了当成普通内容发出去……所以尽管我加入了Tilde社区,受限于聊天软件的使用体验以及我的英文水平,所以并不能和在服务器上的其他人聊天,没法参与到社区中,这么来看似乎我只能把Tilde社区当作普通的共享服务器来看待了😭。 + 在Tilde社区中既然都是用类Unix系统,自然大都是会写程序的人,所以托管代码也很重要,不过因为大多Tilde社区的主机性能很垃圾,所以很多都不会提供Git平台服务,即使有可能也只会提供Gitea,像GitLab这种对服务器要求比较高的基本上就不会有了。但很多人可能对Git有误解,其实绝大多数情况下都不需要Git平台来托管代码,之所以用Gitea、GitLab的工具是因为它们有比较完整的用户管理以及代码协作能力,比如Issue和Wiki之类的,但是大多数人其实根本没必要用到这些功能,有问题发邮件就好了,像Linux的开发就完全没有用Gitea、GitLab之类的平台。所以在Tilde社区中托管代码非常简单,直接新建个文件夹,执行`git init --bare`,那就是个仓库,另外很多Tilde社区提供[cgit](https://git.zx2c4.com/cgit/about/)方便让公众在网页上查看和克隆自己的仓库,一般只要放到`~/public_git`目录下就可以。至于自己如果想要提交代码,可以用`git remote add tilde ssh://example.com/~/public_git/repo.git`添加远程仓库,本地改完之后push上去就可以。 + 不过用那些Git平台还有一个地方可能会用到,那就是CI/CD,直接用命令创建的仓库它可以做到CI/CD吗?其实是可以的,Git有hooks功能,如果想要类似CI/CD的功能就可以直接用post-receive这个钩子,提交完成之后就会执行这个脚本,所以接下来就讲讲我是如何用Git hooks在服务器上自动部署我的博客吧。 + +# 使用Git hooks自动部署博客 + 我的博客使用的是[Jekyll](https://github.com/jekyll/jekyll)框架,这是一个使用Ruby编写的静态博客生成器。所以要想构建我的博客至少要有Ruby的环境,还好几乎所有的Tilde社区都预装了,不用担心环境的问题。 + 不过Tilde社区一般不提供root权限,所以Ruby的包需要放到自己的目录下,比如可以执行这样的命令: +```bash +bundle2.7 config set --local path '/home/mayx/blog-env' +``` + 然后再在我的仓库下执行`bundle2.7 install`就可以了。 + 接下来就需要编写构建的脚本,这个倒是简单,直接用我的[部署脚本](/deploy.sh)改改就行: +```bash +#!/bin/bash +cd /home/mayx/ +rm -rf public_html +git --work-tree=/home/mayx/blog --git-dir=/home/mayx/blog.git checkout -f +cd blog +mkdir Mabbs +curl -L -o Mabbs/README.md https://github.com/Mabbs/Mabbs/raw/main/README.md +bundle2.7 exec jekyll build -d ../public_html +tar czvf MayxBlog.tgz --exclude-vcs ../public_html/ +mv MayxBlog.tgz ../public_html/ +``` + 写完之后把这个脚本放到仓库的`hooks/post-receive`下,然后加上执行权限就可以用了,以后每次push之后都会直接更新我在Tilde社区的主页,也就是我的镜像站。这样部署不像一般CI/CD还要额外装环境,直接使用提前装好的环境,构建速度会快不少。 + 不过既然有机会构建了,我就可以把一些不支持构建的Pages用起来了,有些Forgejo实例支持Pages功能,但是仓库里只能包含构建后的代码,还有Bitbucket Cloud也是一样的问题,所以我可以把构建后的文件夹转为仓库,然后推送到这些Git平台上。 + 考虑到我的网站每次构建基本上所有的页面都有改动,因此我不打算保留提交记录,所以我每次都会重新初始化git仓库,不过在我实际测试的时候,发现钩子触发的脚本执行`git init`的时候创建的是裸仓库……查了一下貌似是环境变量的问题,只要把`GIT_DIR`变量删掉就没问题了,以下是实际的代码: +```bash +cd ../public_html/ +unset GIT_DIR +git init +git add . +git commit -m "update" +git remote add codeberg ssh://git@codeberg.org/mayx/pages.git +git remote add gitgay ssh://git@git.gay/mayx/pages.git +git remote add bitbucket ssh://git@bitbucket.org/unmayx/unmayx.bitbucket.io.git +git push -f codeberg master +git push -f gitgay master +git push -f bitbucket master +``` + 除了这些Pages之外,还有一些平台只支持使用他们自己的软件上传网站代码,比如surge,既然我可以在构建的时候执行命令,那就顺带一起上传吧,比如我可以这样执行: +```bash +/home/mayx/blog-env/node_modules/surge/bin/surge /home/mayx/public_html/ mayx.surge.sh +``` + 其实除了这个之外我还想上传到sourcehut pages,这个也需要用他们自己的软件上传,但是sourcehut pages的CSP太严格了,居然禁止脚本访问其他网站😭,这样我的文章点击计数、文章推荐、AI摘要之类乱七八糟的功能就全用不了了,所以只好作罢…… + +# 感想 + 总的来说,这次在Tilde社区的各种体验还挺有意思,虽然没能和各个社区的成员进行对话,但是在探索的过程中,也了解到了不少新知识,而且也给我的博客增加了不少镜像。不知道会不会有哪个社区成员在闲逛的时候看到我的博客然后对里面的内容感兴趣😝……要是有哪个成员看到然后给我评论,那也算是社区互动吧😋。虽然我的文章内容都是中文,但现在翻译软件也足够强大了,应该不至于拦住外国人。只是在国内似乎没有见过类似的社区,在国内也有的话,那就可以用中文和大家对话了吧。
\ No newline at end of file @@ -1,4 +1,4 @@ --- --- -{"version":"https://jsonfeed.org/version/1","title":"{{ site.title | xml_escape }}","home_page_url":"{{ "/" | absolute_url }}","feed_url":"{{ "/feed.json" | absolute_url }}","description":{{ site.description | jsonify }},"favicon":"{{ "/favicon.ico" | absolute_url }}","expired":false,{% if site.author %}"author":{% if site.author.name %}{"name":"{{ site.author.name }}","url":{% if site.author.url %}"{{ site.author.url }}"{% else %}null{% endif %},"avatar":{% if site.author.avatar %}"{{ site.author.avatar }}"{% else %}null{% endif %}},{% else %}{"name":"{{ site.author }}"},{% endif %}{% endif %}"items":[{% for post in site.posts limit:10 %}{"id":"{{ post.url | absolute_url }}","title":{{ post.title | jsonify }},"summary":{{ post.excerpt | strip_html | jsonify }},"content_text":{{ post.content | strip_html | strip_newlines | jsonify }},"content_html":{{ post.content | strip_newlines | jsonify }},"url":"{{ post.url | absolute_url }}",{% if post.image.size > 1 %}"image":{{ post.image | jsonify }},{% endif %}{% if post.link.size > 1 %}"external_url":"{{ post.link }}",{% endif %}{% if post.banner.size > 1 %}"banner_image":"{{ post.banner }}",{% endif %}{% if post.tags.size > 1 %}"tags":{{ post.tags | jsonify }},{% endif %}{% if post.enclosure.size > 1 %}"attachments":[{ "url":"{{ post.enclosure }}", "mime_type":"{{ post.enclosure_type }}", "size_in_bytes":"{{ post.enclosure_length }}"}],{% endif %}"date_published":"{{ post.date | date_to_xmlschema }}","date_modified":"{{ post.date | date_to_xmlschema }}",{% if post.author %}"author":{% if post.author.name %} {"name":"{{ post.author.name }}","url":{% if post.author.url %}"{{ post.author.url }}"{% else %}null{% endif %},"avatar":{% if post.author.avatar %}"{{ post.author.avatar }}"{% else %}null{% endif %}}{% else %}"{{ post.author }}"{% endif %}{% else %}"author":{% if site.author.name %} {"name":"{{ site.author.name }}","url":{% if site.author.url %}"{{ site.author.url }}"{% else %}null{% endif %},"avatar":{% if site.author.avatar %}"{{ site.author.avatar }}"{% else %}null{% endif %}}{% else %}{"name":"{{ site.author }}"}{% endif %}{% endif %}}{% if forloop.last == false %},{% endif %}{% endfor %}]}
\ No newline at end of file +{"version":"https://jsonfeed.org/version/1","title":"{{ site.title | xml_escape }}","home_page_url":"{{ "/" | absolute_url }}","feed_url":"{{ "/feed.json" | absolute_url }}","description":{{ site.description | jsonify }},"favicon":"{{ "/favicon.ico" | absolute_url }}","expired":false,{% if site.author %}"author":{% if site.author.name %}{"name":"{{ site.author.name }}","url":{% if site.author.url %}"{{ site.author.url }}"{% else %}null{% endif %},"avatar":{% if site.author.avatar %}"{{ site.author.avatar }}"{% else %}null{% endif %}},{% else %}{"name":"{{ site.author }}"},{% endif %}{% endif %}"items":[{% for post in site.posts limit:10 %}{"id":"{{ post.url | absolute_url }}","title":{{ post.title | jsonify }},"summary":{% assign ai_cache = site.data.ai-cache[post.url] %}{% if ai_cache %}{{ ai_cache | strip_newlines | jsonify }}{% else %}{{ post.excerpt | strip_html | jsonify }}{% endif %},"content_html":{{ post.content | jsonify }},"url":"{{ post.url | absolute_url }}",{% if post.image.size > 1 %}"image":{{ post.image | jsonify }},{% endif %}{% if post.link.size > 1 %}"external_url":"{{ post.link }}",{% endif %}{% if post.banner.size > 1 %}"banner_image":"{{ post.banner }}",{% endif %}{% if post.tags.size > 1 %}"tags":{{ post.tags | jsonify }},{% endif %}{% if post.enclosure.size > 1 %}"attachments":[{ "url":"{{ post.enclosure }}", "mime_type":"{{ post.enclosure_type }}", "size_in_bytes":"{{ post.enclosure_length }}"}],{% endif %}"date_published":"{{ post.date | date_to_xmlschema }}","date_modified":"{{ post.date | date_to_xmlschema }}",{% if post.author %}"author":{% if post.author.name %} {"name":"{{ post.author.name }}","url":{% if post.author.url %}"{{ post.author.url }}"{% else %}null{% endif %},"avatar":{% if post.author.avatar %}"{{ post.author.avatar }}"{% else %}null{% endif %}}{% else %}"{{ post.author }}"{% endif %}{% else %}"author":{% if site.author.name %} {"name":"{{ site.author.name }}","url":{% if site.author.url %}"{{ site.author.url }}"{% else %}null{% endif %},"avatar":{% if site.author.avatar %}"{{ site.author.avatar }}"{% else %}null{% endif %}}{% else %}{"name":"{{ site.author }}"}{% endif %}{% endif %}}{% if forloop.last == false %},{% endif %}{% endfor %}]}
\ No newline at end of file @@ -15,7 +15,10 @@ {% for post in site.posts limit:10 %} <item> <title>{{ post.title | xml_escape }}</title> - {% if post.excerpt %} + {% assign ai_cache = site.data.ai-cache[post.url] %} + {% if ai_cache %} + <description>{{ ai_cache | xml_escape }}</description> + {% elsif post.excerpt %} <description>{{ post.excerpt | strip_html | xml_escape }}</description> {% else %} <description>{{ post.content | xml_escape }}</description> diff --git a/sitemap.xsl b/sitemap.xsl index 4485c3b..4c843a7 100644 --- a/sitemap.xsl +++ b/sitemap.xsl @@ -4,16 +4,14 @@ title: Sitemap --- <h1>Sitemap</h1> -<p>以下是本站的所有链接:</p> +<p>以下是本站的所有链接(总共<xsl:value-of select="count(sm:urlset/sm:url)" />条):</p> <ul> - <xsl:for-each select="sm:urlset"> - <xsl:for-each select="sm:url"> - <li> - <a> - <xsl:attribute name="href"><xsl:value-of select="sm:loc" /></xsl:attribute> - <xsl:value-of select="sm:loc" /> - </a> - </li> - </xsl:for-each> + <xsl:for-each select="sm:urlset/sm:url"> + <li> + <a> + <xsl:attribute name="href"><xsl:value-of select="sm:loc" /></xsl:attribute> + <xsl:value-of select="sm:loc" /> + </a> + </li> </xsl:for-each> </ul>
\ No newline at end of file |