<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Moitr's Space]]></title><description><![CDATA[人生由我，自在独行]]></description><link>https://moitr.ren</link><generator>Yohaku (https://github.com/Innei/Yohaku)</generator><lastBuildDate>Tue, 11 Aug 2026 15:14:08 GMT</lastBuildDate><atom:link href="https://moitr.ren/feed" rel="self" type="application/rss+xml"/><pubDate>Tue, 11 Aug 2026 15:14:08 GMT</pubDate><language><![CDATA[zh-CN]]></language><item><title><![CDATA[如何将你的 MixSpace 文章自动同步到 Hexo]]></title><description><![CDATA[<div><blockquote>此渲染由 Yohaku API 生成，或存排版之虞，最佳体验请往：<a href="https://moitr.ren/posts/tech/sync-mixspace-articles-to-hexo">https://moitr.ren/posts/tech/sync-mixspace-articles-to-hexo</a></blockquote><div><p>如果你已经使用 Mix Space 管理文章和笔记，又希望用 Hexo 提供一个轻量、快速、容易定制的公开站点，可以让 Hexo 仓库定期从 Mix Space API 拉取内容，再自动构建并部署到 GitHub Pages。</p><p>这个方案的重点不是把两个博客做成双向编辑系统，而是把 Mix Space 作为唯一内容源，把 Hexo 当作展示层。文章只在 Mix Space 中维护，Hexo 中的文章文件由自动化程序生成。</p><h2 id="">整体流程</h2><p style="padding:6px 12px;border-left:2px solid #C56473;background:#C5647350;font-style:italic;font-weight:500">Not support render this content in RSS render</p>
<p>工作流每 8 小时运行一次，也可以由 <code>push</code> 或手动操作触发。每次运行都会重新读取线上公开内容，生成当前完整的文章目录，然后执行 Hexo 构建。</p><h2 id="-api-">为什么从 API 全量同步</h2><p>只追加新文章看起来更简单，但无法正确处理删除、隐藏和修改。当前实现每次都读取文章和笔记的完整列表：</p><pre class="language-text lang-text"><code class="language-text lang-text">GET /api/v3/posts?page=1&amp;size=50&amp;truncate=1
GET /api/v3/notes?page=1&amp;size=50&amp;withSummary=1
</code></pre>
<p>列表接口返回分页信息后，程序会一直请求到 <code>page === total_pages</code>。列表只用于获得文章身份和摘要，随后会为每一项请求详情：</p><pre class="language-text lang-text"><code class="language-text lang-text">GET /api/v3/posts/{id}
GET /api/v3/notes/nid/{nid}?single=1
</code></pre>
<p>这样可以拿到标题、正文、标签、分类、创建时间、修改时间和原始路由等字段。未登录请求只能获得 Mix Space 允许公开的内容，未发布、定时未公开、密码内容不会被同步。</p><h2 id="">文章和笔记如何共存</h2><p>文章和笔记使用不同的 API 身份：</p><table><thead><tr><th> 类型 </th><th> 稳定身份 </th><th> 原站路径 </th></tr></thead><tbody><tr><td> 文章 </td><td> <code>post:{id}</code> </td><td> <code>/posts/{categorySlug}/{slug}</code> </td></tr><tr><td> 笔记 </td><td> <code>note:{id}</code> </td><td> <code>/notes/{nid}</code> </td></tr></tbody></table><p>同步程序不会使用标题作为身份，因为标题可以修改。它使用 Mix Space 返回的不可变 <code>id</code>，并把文章和笔记分别标记为 <code>post:id</code> 或 <code>note:id</code>。</p><h2 id="-hexo-">数字编号只负责 Hexo 内部路径</h2><p>Hexo 站点的文章路径使用数字编号，例如：</p><pre class="language-text lang-text"><code class="language-text lang-text">/archives/1/
/archives/2/
/archives/3/
</code></pre>
<p>编号与 Mix Space 的文章 ID 没有直接关系，而是保存在根目录的 <code>.content-sync-map.json</code> 中。第一次同步时，程序会按照创建时间分配下一个数字；后续同步通过 <code>post:id</code> 或 <code>note:id</code> 找回原来的编号。</p><p>这带来两个好处：</p><ol start="1"><li>修改标题、分类或 Mix Space slug 不会改变 Hexo 永久链接。</li><li>已经使用过的编号不会重新分配给另一篇内容。</li></ol><p>所以不要手动重命名 <code>source/_posts/1.md</code> 这类文件，也不要删除映射文件。它们是同步程序保持永久路径的依据。</p><h2 id="">原文链接如何自动生成</h2><p>每篇生成的 Hexo 文件都会写入 <code>original_url</code>：</p><pre class="language-yaml lang-yaml"><code class="language-yaml lang-yaml">original_url: https://moitr.ren/posts/categories/example
</code></pre>
<p>文章的原文路径由分类 slug 和文章 slug 组合而成，笔记则使用它的 <code>nid</code>：</p><pre class="language-text lang-text"><code class="language-text lang-text">文章：/posts/{category.slug}/{slug}
笔记：/notes/{nid}
</code></pre>
<p>域名是固定的 <code>https://moitr.ren</code>。这样即使 Hexo 使用数字归档路径，读者仍然可以从文章页回到 Mix Space 原文。<strong>这需要你的主题支持</strong></p><h2 id="-core-">正文格式和 Core 容器</h2><p>当 <code>content_format</code> 为 <code>markdown</code> 时，程序使用 API 返回的 <code>text</code>。当格式为 <code>lexical</code> 时，当前实现同样优先使用 Mix Space 提供的公开 <code>text</code>，避免在同步端重复实现编辑器 JSON 的全部渲染规则。</p><p>同步阶段还会处理 Mix Space 的部分自定义 Markdown 容器。例如：</p><ul><li><code>masonry</code> 容器会转换成 Hexo 主题已有的图片画廊结构。</li><li><code>success</code> 容器会转换成 Markdown 引用块。</li><li>未知容器保持原样，避免自动同步误删原文。</li></ul><p>换行会统一为 LF，正文尾部只保留一个换行，时间统一写成 UTC ISO 格式。这样 Windows 本地运行和 Linux Actions 运行也能得到稳定的文件内容。</p><h2 id="-api-">修改、删除和 API 失败时会发生什么</h2><p>同步不是向目录里无限追加文件，而是先在临时目录生成全部结果，确认数量和文章 payload 都有效后，再一次性替换 <code>source/_posts</code>。</p><ul><li>Mix Space 修改正文或发布时间：对应数字文件会被更新。</li><li>Mix Space 删除或隐藏内容：对应文件会从当前站点移除，并在映射中标记为 inactive。</li><li>之前使用过的数字：即使文章被删除，也不会重新分配。</li><li>API 请求失败：程序会在写入前直接失败，保留本地原有文章和映射，不发布一个不完整的网站。</li></ul><p>这也是全量同步比简单下载脚本更重要的地方：删除能够生效，网络故障也不会把线上站点替换成半套内容。</p><h2 id="github-actions-">GitHub Actions 的构建顺序</h2><p>工作流的核心步骤如下：</p><p style="padding:6px 12px;border-left:2px solid #C56473;background:#C5647350;font-style:italic;font-weight:500">Not support render this content in RSS render</p>
<p>当前定时表达式是：</p><pre class="language-yaml lang-yaml"><code class="language-yaml lang-yaml">- cron: &quot;20 */8 * * *&quot;
</code></pre>
<p>GitHub Actions 使用 UTC 时间，因此对应北京时间每天 00:20、08:20 和 16:20。需要立即更新时，可以推送到 <code>main</code>，或在 Actions 页面手动运行工作流。</p><h2 id="">需要保留的文件</h2><p>同步功能主要由以下文件组成：</p><pre class="language-text lang-text"><code class="language-text lang-text">tools/sync-content.js       # 拉取 API、规范化数据、生成文章
.content-sync-map.json      # Mix Space 身份到数字编号的永久映射
.github/workflows/deploy-pages.yml
source/_posts/              # 自动生成的 Hexo 文章目录
</code></pre>
<p><code>source/_posts</code> 中的数字 Markdown 属于自动生成内容，不建议直接编辑。下一次同步时，线上 API 内容会覆盖本地手动修改。</p><h2 id="">本地验证</h2><p>在提交工作流之前，可以先运行：</p><pre class="language-bash lang-bash"><code class="language-bash lang-bash">pnpm install --frozen-lockfile
pnpm content:sync
pnpm test
pnpm clean
pnpm build
</code></pre>
<p>如果 API 暂时不可用，<code>pnpm content:sync</code> 应该失败且不改变现有文章。构建完成后，可以检查 <code>public/archives/</code> 是否生成了归档页和数字文章路径。</p><h2 id="">常见注意事项</h2><h3 id="1">1.不要删除映射文件</h3><p>删除 <code>.content-sync-map.json</code> 会让程序失去旧文章与数字编号的对应关系。重新同步时，内容可能被当作全新文章分配新的路径。</p><h3 id="2">2.不要只请求第一页</h3><p>文章数量超过 50 后，第一页并不代表完整数据。必须根据 <code>meta.pagination.total_pages</code> 请求所有页面，否则站点会悄悄缺文章。</p><h3 id="3-api-">3.不要把 API 密钥放进前端</h3><p>当前公开内容接口不需要登录，Actions 直接请求即可。如果以后改成需要认证的接口，应把凭据放在 GitHub Actions Secrets，并只在工作流中使用，不能写入主题 JavaScript 或生成的 HTML。</p><h2 id="">总结</h2><p>Mix Space 负责内容管理，GitHub Actions 负责定期获取和验证，Hexo 负责生成静态页面，GitHub Pages 负责分发。通过稳定的远程身份、不可复用的数字编号和失败保护机制，可以在不手动维护 Hexo 文章文件的情况下，保持原博客与个人主页之间可靠同步。</p></div><p style="text-align:right"><a href="https://moitr.ren/posts/tech/sync-mixspace-articles-to-hexo#comments">览毕，何不一言？</a></p></div>]]></description><link>https://moitr.ren/posts/tech/sync-mixspace-articles-to-hexo</link><guid isPermaLink="true">https://moitr.ren/posts/tech/sync-mixspace-articles-to-hexo</guid><dc:creator><![CDATA[Moitr]]></dc:creator><pubDate>Tue, 11 Aug 2026 10:49:55 GMT</pubDate></item><item><title><![CDATA[从零构建永久存证的区块链博客：Polygon + Hexo + GitHub Actions 实战]]></title><description><![CDATA[<p>往原址览之：<a href="https://moitr.ren/posts/tech/build-permanent-blockchain-blog-polygon-hexo-github-actions">https://moitr.ren/posts/tech/build-permanent-blockchain-blog-polygon-hexo-github-actions</a></p>]]></description><link>https://moitr.ren/posts/tech/build-permanent-blockchain-blog-polygon-hexo-github-actions</link><guid isPermaLink="true">https://moitr.ren/posts/tech/build-permanent-blockchain-blog-polygon-hexo-github-actions</guid><dc:creator><![CDATA[Moitr]]></dc:creator><pubDate>Mon, 10 Aug 2026 14:24:11 GMT</pubDate></item><item><title><![CDATA[休学后都发生了什么]]></title><description><![CDATA[<link rel="preload" as="image" href="https://oss.moitr.ren/img/posts/20260424194440_22_8.jpg"/><link rel="preload" as="image" href="https://oss.moitr.ren/img/posts/20260424200503_23_8.jpg"/><link rel="preload" as="image" href="https://oss.moitr.ren/img/posts/20260424200956_24_8.jpg"/><link rel="preload" as="image" href="https://oss.moitr.ren/img/posts/h0.jpg"/><link rel="preload" as="image" href="https://oss.moitr.ren/img/posts/h1.jpg"/><link rel="preload" as="image" href="https://oss.moitr.ren/img/posts/h5.jpg"/><div><blockquote>此渲染由 Yohaku API 生成，或存排版之虞，最佳体验请往：<a href="https://moitr.ren/notes/1">https://moitr.ren/notes/1</a></blockquote><div><h2 id="202617">2026年1月7日</h2><p>2026年1月7日办理休学，到现在已经过去了快要四个月，竟然已经过去了四个月！<del>感觉时间过的有点快啊</del>，印象里似乎还没有发生什么大事。</p><p><img alt="小白" height="1280" src="https://oss.moitr.ren/img/posts/20260424194440_22_8.jpg" width="2038"/></p><p>办理休学当天在学校的打印室发现了狗学长小白，已经很久没有看到小白了，<del>已经快要变成小黑了</del></p><p>在办理休学前已经在家里躺了一个月了，在办完的第二天我就在找事情做了，仔细想想有好多想买的东西，我最后想到了去工作体验一下。</p><h2 id="2026118">2026年1月18日</h2><p>::: masonry {gap=1}
<img alt="宿舍楼下" src="https://oss.moitr.ren/img/posts/20260424200503_23_8.jpg"/>
:::</p><p>这时候已经休学是休学后的十几天后了，二月多了北京竟然还有雪！！</p><h2 id="202623">2026年2月3日</h2><p>::: masonry {gap=1}
<img alt="微信账单" src="https://oss.moitr.ren/img/posts/20260424200956_24_8.jpg"/>
:::</p><p>本来以为扫瓶盖大多是几块钱，没想到竟然中了一千块。第一次这么幸运，其实一直觉得自己是一个特别倒霉的人吧。。</p><h2 id="2026329">2026年3月29日、</h2><p>休息去了环球影城</p><p>::: masonry {gap=3}
<img src="https://oss.moitr.ren/img/posts/h0.jpg"/>
<img src="https://oss.moitr.ren/img/posts/h1.jpg"/>
<img src="https://oss.moitr.ren/img/posts/h5.jpg"/>
:::</p><h2 id="">规划</h2><p>现在也攒下了一些钱了，虽然不是很多，但也能玩几个月了，准备继续工作到七月吧。多攒点钱，去玩两个月就要回去上学了。有句话不是说：<strong>“穷游富游，终不似少年游”</strong></p></div><p style="text-align:right"><a href="https://moitr.ren/notes/1#comments">览毕，何不一言？</a></p></div>]]></description><link>https://moitr.ren/notes/1</link><guid isPermaLink="true">https://moitr.ren/notes/1</guid><dc:creator><![CDATA[Moitr]]></dc:creator><pubDate>Fri, 24 Apr 2026 06:28:00 GMT</pubDate></item><item><title><![CDATA[使用 Docker 搭建一个视奸自己的网站]]></title><description><![CDATA[<link rel="preload" as="image" href="https://oss.moitr.ren/img/posts/2026-04-23%20220734.png"/><div><blockquote>此渲染由 Yohaku API 生成，或存排版之虞，最佳体验请往：<a href="https://moitr.ren/posts/categories/build-self-monitoring-website-with-docker">https://moitr.ren/posts/categories/build-self-monitoring-website-with-docker</a></blockquote><div><h2 id="">前言</h2><p>项目地址：<a href="https://github.com/Monika-Dream/live-dashboard/">Live-dashboard</a></p><p>教程均在Linux服务器上完成</p><h2 id="">开始搭建</h2><p>搭建前确保已经服务器已经安装 Docker</p>
<pre class="language-bash lang-bash"><code class="language-bash lang-bash">curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
</code></pre>
<h3 id="">一键部署</h3><h4 id="1">1.生成密钥</h4><pre class="language-bash lang-bash"><code class="language-bash lang-bash"># 设备密钥（每台设备各生成一个，记下来）
openssl rand -hex 16
# HASH_SECRET（服务端内部用，只需一个）
openssl rand -hex 32
</code></pre><h4 id="2">2.启动容器</h4><p><code>DEVICE_TOKEN</code> 的格式是 <code>密钥:设备ID:设备名称:平台</code></p><p>如果你只有一台设备：</p><pre class="language-bash lang-bash"><code class="language-bash lang-bash">docker run -d --name live-dashboard \
  -p 3000:3000 \
  -v dashboard_data:/data \
  -e HASH_SECRET=&lt;MY_SECRET&gt; \
  -e &#x27;DEVICE_TOKEN_1=&lt;MY_TOKEN&gt;:my-pc:MyPC:windows&#x27; \
  ghcr.io/monika-dream/live-dashboard:latest
</code></pre>
<p>多台设备：</p><pre class="language-bash lang-bash"><code class="language-bash lang-bash">docker run -d --name live-dashboard \
  -p 3000:3000 \
  -v dashboard_data:/data \
  -e HASH_SECRET=&lt;MY_SECRET&gt; \
  -e &#x27;DEVICE_TOKEN_1=&lt;TOKEN_A&gt;:my-pc:我的电脑:windows&#x27; \
  -e &#x27;DEVICE_TOKEN_2=&lt;TOKEN_B&gt;:my-phone:我的手机:android&#x27; \
  ghcr.io/monika-dream/live-dashboard:latest
#                      ─────── ───── ──── ───────
#                      密钥▲   ID▲  名称▲ 平台▲
# ▲密钥：第 1 步生成的随机字符串，每台设备各不同
# ▲ID：自定义英文标识（如 my-pc、phone-1），每台设备各不同
# ▲名称：仪表盘显示名，支持中文（如 我的电脑、小米手机）
# ▲平台：只能填 windows / macos / android
</code></pre>
<p><strong>注意：</strong>每台设备必须有自己的 <code>DEVICE_TOKEN_N</code>，密钥和设备ID都不能重复。 如果两台设备共用同一个 TOKEN，它们会显示为同一台设备，状态互相覆盖。</p><p><strong>需要更多设备？继续加 DEVICE<em>TOKEN</em>3、DEVICE<em>TOKEN</em>4……编号不强制连续。</strong></p><blockquote>
<p>已有容器要加设备？ 需要先停止并删除旧容器，再用新命令重建。数据保存在 <code>dashboard_data</code> 卷中，不会丢失：</p></blockquote>
<pre class="language-bash lang-bash"><code class="language-bash lang-bash">&gt;docker stop live-dashboard &amp;&amp; docker rm live-dashboard
&gt; # 然后执行包含新 DEVICE_TOKEN 的 docker run 命令
</code></pre>
<h4 id="3">3.打开浏览器</h4><p>访问 <code>http://localhost:3000</code>，看到仪表盘页面就说明服务端已就绪（此时没有设备数据，会显示夜间模式）。</p><h4 id="">自定义站点元数据</h4><pre class="language-bash lang-bash"><code class="language-bash lang-bash">docker run -d --name live-dashboard \
  -p 3000:3000 \
  -v dashboard_data:/data \
  -e HASH_SECRET=&lt;MY_SECRET&gt; \
  -e DEVICE_TOKEN_1=&lt;MY_TOKEN&gt;:my-pc:MyPC:windows \
  -e DISPLAY_NAME=你的名字 \
  ghcr.io/monika-dream/live-dashboard:latest
</code></pre><p>除了显示名，你还可以自定义浏览器标签页标题、页面描述和网站图标：</p><pre class="language-bash lang-bash"><code class="language-bash lang-bash">docker run -d --name live-dashboard \
  -p 3000:3000 \
  -v dashboard_data:/data \
  -e HASH_SECRET=&lt;MY_SECRET&gt; \
  -e DEVICE_TOKEN_1=&lt;MY_TOKEN&gt;:my-pc:MyPC:windows \
  -e DISPLAY_NAME=你的名字 \
  -e SITE_TITLE=&quot;你的名字 Now&quot; \
  -e SITE_DESC=&quot;看看我在干什么&quot; \
  -e SITE_FAVICON=&quot;/favicon.ico&quot; \
  ghcr.io/monika-dream/live-dashboard:latest
</code></pre>
<h2 id="-agent">配置 Agent</h2><h3 id="agent----windows">Agent 配置 - Windows</h3><p>1.从原作者的 <a href="https://github.com/Monika-Dream/live-dashboard/releases">GitHub Releases</a> 下载 <code>live-dashboard-agent.exe</code></p><p>2.直接双击运行，首次运行会自动弹出设置对话框，填入服务器地址和 Token 即可</p><p>配置完成后 Agent 自动开始上报</p><p>详见原作者教程：<a href="https://github.com/Monika-Dream/live-dashboard/wiki/Agent-%E9%85%8D%E7%BD%AE-Windows">Agent 配置 - Windows</a></p><h3 id="agent----macos">Agent 配置 - macOS</h3><p>1.从原作者的 <a href="https://github.com/Monika-Dream/live-dashboard/releases">GitHub Releases</a> 下载 <code> live-dashboard-agent-macos.zip </code></p><p>2.解压后直接运行，首次运行会自动弹出设置对话框，填入服务器地址和 Token 即可</p><p>配置完成后 Agent 自动开始上报</p><p>详见原作者教程：<a href="https://github.com/Monika-Dream/live-dashboard/wiki/Agent-%E9%85%8D%E7%BD%AE-macOS">Agent 配置 - macOS</a></p><h3 id="agent----android">Agent 配置 - Android</h3><p>::: success
截至 <code> 2026.4.23 23点06分</code>  由于作者 GitHub Releases 的版本无法正确获取应用名称，请使用修改版本
:::</p><blockquote><p>下载地址：<a href="https://oss.moitr.ren/app/LiveDashboard.apk">LiveDashboard</a></p></blockquote>
<p>1.安装后打开 APP，进入「设置」页填写服务器地址和 Token</p><p>2.进入「健康」页，点击「授权」按钮授权 <code>Health Connect</code> 权限，选择要同步的数据类型（默认全选）</p><p>3.<strong>重要</strong>：在「状态」页使用 <code>Shizuku</code> 授权（否则无法获取应用名称）</p><p>4.在「状态」页开启保活权限</p><h2 id="">效果展示</h2><p><img alt="效果" height="1248" src="https://oss.moitr.ren/img/posts/2026-04-23%20220734.png" width="2557"/></p><h2 id="">结语</h2><p><del>欢迎大家来视奸我：<a href="https://now.moitr.ren/">Moitr Now</a></del> （已关</p></div><p style="text-align:right"><a href="https://moitr.ren/posts/categories/build-self-monitoring-website-with-docker#comments">览毕，何不一言？</a></p></div>]]></description><link>https://moitr.ren/posts/categories/build-self-monitoring-website-with-docker</link><guid isPermaLink="true">https://moitr.ren/posts/categories/build-self-monitoring-website-with-docker</guid><dc:creator><![CDATA[Moitr]]></dc:creator><pubDate>Thu, 23 Apr 2026 06:20:00 GMT</pubDate></item><item><title><![CDATA[新的开始]]></title><description><![CDATA[<div><blockquote>此渲染由 Yohaku API 生成，或存排版之虞，最佳体验请往：<a href="https://moitr.ren/posts/categories/new-beginning">https://moitr.ren/posts/categories/new-beginning</a></blockquote><span>终于有时间把新的博客搭建起来了，<del>希望这次能坚持的久一点</del>，这是我的第一个十年计划，博客能坚持十年，应该吧？始于20251121 </span><p style="text-align:right"><a href="https://moitr.ren/posts/categories/new-beginning#comments">览毕，何不一言？</a></p></div>]]></description><link>https://moitr.ren/posts/categories/new-beginning</link><guid isPermaLink="true">https://moitr.ren/posts/categories/new-beginning</guid><dc:creator><![CDATA[Moitr]]></dc:creator><pubDate>Fri, 21 Nov 2025 06:24:00 GMT</pubDate></item></channel></rss>