{"version":"https://jsonfeed.org/version/1.1","title":"Test Channel","home_page_url":"https://mf-drktravis-dpdns-org.pages.dev","feed_url":"https://mf-drktravis-dpdns-org.pages.dev/json/","description":"<p>a test channel</p>","icon":"https://mf-drktravis-dpdns-org.pages.dev/assets/default/channel-image.png","favicon":"https://mf-drktravis-dpdns-org.pages.dev/assets/default/favicon.png","authors":[{"name":"lx"}],"language":"en-us","items":[{"id":"-Y-nUqC3Ni1","title":"socket","url":"https://mf.drktravis.dpdns.org/i/socket--Y-nUqC3Ni1/","content_html":"<h3>socket 服务端</h3><pre class=\"ql-syntax\" spellcheck=\"false\"># threaded_server.py\nimport Lib.debug.log\nimport socket, threading\nimport json\nimport struct\n\n\nclass SocketServer:\n&nbsp; &nbsp; HOST, PORT, BUFSIZE = '0.0.0.0', 5000, 1024 * 32\n&nbsp; &nbsp; \n&nbsp; &nbsp; def __init__(self) -&gt; None:\n&nbsp; &nbsp; &nbsp; &nbsp; self.handle = socket.socket()\n&nbsp; &nbsp; &nbsp; &nbsp; self.handle.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n&nbsp; &nbsp; &nbsp; &nbsp; self.handle.bind((self.HOST, self.PORT))\n&nbsp; &nbsp; &nbsp; &nbsp; self.handle.listen(5)\n&nbsp; &nbsp; \n&nbsp; &nbsp; def start(self):\n&nbsp; &nbsp; &nbsp; &nbsp; print(r'[*] Listening %s:%s' % (self.HOST, self.PORT))\n&nbsp; &nbsp; &nbsp; &nbsp; while True:\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('wait connection...')\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection, (ip, port) = self.handle.accept()\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; threading.Thread(target=self.handle_client, args=(connection, ip, port), daemon=True).start()\n\n\n&nbsp; &nbsp; def handle_client(self, connection: socket.socket, ip: str, port: int):\n&nbsp; &nbsp; &nbsp; &nbsp; ip_port = '%s:%s' % (ip, port)\n&nbsp; &nbsp; &nbsp; &nbsp; \n&nbsp; &nbsp; &nbsp; &nbsp; with connection:\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('[-] Connected: (%s, %s)' % (ip, port))\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while True:\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('[%s] wait message...' % (ip_port))\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; n, = struct.unpack('!I', connection.recv(4))\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # data = connection.recv(n)\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # print(n)\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a, b = n / self.BUFSIZE, n % self.BUFSIZE\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # print(a, b)\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a, b = int(a), int(b)\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data = b''\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for i in range(a):\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # print('%s/%s' % (i+1, a))\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data += connection.recv(self.BUFSIZE)\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data += connection.recv(b)\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # data = connection.recv(self.BUFSIZE)\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('[%s] get message!' % (ip_port))\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print(data)\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # print('[%s] %s' % (ip_port, data))\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # hex_str = ''.join([r'\\x%02x' % v for v in data])\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # print('[%s] %s' % (ip_port, hex_str))\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # obj = json.loads(data.decode('utf-8'))\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # print(obj)\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # print(len(data))\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # with open(r'E:\\work\\202502\\20250206-07\\fm58-li-gz05\\fm58-li-gz05-far\\RotarySys\\Ctrl\\sd.iso', 'wb') as f:\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # &nbsp; &nbsp; f.write(data)\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if not data:\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection.sendall(data) &nbsp; # 回显\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('[-] Disconnected: (%s, %s)' % (ip, port))\n\n\nif __name__ == '__main__':\n&nbsp; &nbsp; SocketServer().start()\n\n</pre><h3>socket 客户端</h3><p><br></p><pre class=\"ql-syntax\" spellcheck=\"false\">import socket\nimport struct\nclient = socket.socket()\nclient.connect(('localhost', 5000))\n\n\n\ndef send_all(soc: socket.socket, data: bytes):\n&nbsp; &nbsp; \"\"\"\n&nbsp; &nbsp; 传输的数据格式定义为：数据头(4字节) + 数据本体\n&nbsp; &nbsp; - 数据头：表示数据本体的长度(单位为字节)，如：b`\\x00\\x00\\x00\\x07f` 表示数据本体长度是 127字节 (总共就需要发送 131字节)\n&nbsp; &nbsp; - 数据本体：需要发送的数据\n&nbsp; &nbsp; 注：4字节能表示 2^32个无符号整数，即上述定义能表示约 4TB 的传输数据\n&nbsp; &nbsp; \"\"\"\n&nbsp; &nbsp; len_bytes = struct.pack('!I', len(data))\n&nbsp; &nbsp; # print(data)\n&nbsp; &nbsp; print(len(data))\n&nbsp; &nbsp; soc.sendall(len_bytes + data)\n\n\n\n# send_all(client, open(r'E:\\work\\202502\\20250206-07\\fm58-li-gz05\\fm58-li-gz05-far\\RotarySys\\Ctrl\\fileviewer.exe', 'rb').read())\n\n\nsend_all(client, b'hello world')\nsend_all(client, '你干嘛'.encode('utf-8'))\n\n\n\nimport time; time.sleep(1)\n</pre>","content_text":"SOCKET 服务端\n\n# threaded_server.py\nimport Lib.debug.log\nimport socket, threading\nimport json\nimport struct\n\n\nclass SocketServer:\n    HOST, PORT, BUFSIZE = '0.0.0.0', 5000, 1024 * 32\n    \n    def __init__(self) -> None:\n        self.handle = socket.socket()\n        self.handle.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n        self.handle.bind((self.HOST, self.PORT))\n        self.handle.listen(5)\n    \n    def start(self):\n        print(r'[*] Listening %s:%s' % (self.HOST, self.PORT))\n        while True:\n            print('wait connection...')\n            connection, (ip, port) = self.handle.accept()\n            threading.Thread(target=self.handle_client, args=(connection, ip, port), daemon=True).start()\n\n\n    def handle_client(self, connection: socket.socket, ip: str, port: int):\n        ip_port = '%s:%s' % (ip, port)\n        \n        with connection:\n            print('[-] Connected: (%s, %s)' % (ip, port))\n            while True:\n                print('[%s] wait message...' % (ip_port))\n                n, = struct.unpack('!I', connection.recv(4))\n                # data = connection.recv(n)\n                # print(n)\n                \n                a, b = n / self.BUFSIZE, n % self.BUFSIZE\n                # print(a, b)\n                a, b = int(a), int(b)\n                data = b''\n                for i in range(a):\n                    # print('%s/%s' % (i+1, a))\n                    data += connection.recv(self.BUFSIZE)\n                data += connection.recv(b)\n                \n                # data = connection.recv(self.BUFSIZE)\n                print('[%s] get message!' % (ip_port))\n                \n                print(data)\n                \n                # print('[%s] %s' % (ip_port, data))\n                # hex_str = ''.join([r'\\x%02x' % v for v in data])\n                # print('[%s] %s' % (ip_port, hex_str))\n                \n                \n                # obj = json.loads(data.decode('utf-8'))\n                # print(obj)\n                # print(len(data))\n                # with open(r'E:\\work\\202502\\20250206-07\\fm58-li-gz05\\fm58-li-gz05-far\\RotarySys\\Ctrl\\sd.iso', 'wb') as f:\n                #     f.write(data)\n                \n                if not data:\n                    break\n                connection.sendall(data)   # 回显\n            print('[-] Disconnected: (%s, %s)' % (ip, port))\n\n\nif __name__ == '__main__':\n    SocketServer().start()\n\n\n\n\nSOCKET 客户端\n\n\n\n\nimport socket\nimport struct\nclient = socket.socket()\nclient.connect(('localhost', 5000))\n\n\n\ndef send_all(soc: socket.socket, data: bytes):\n    \"\"\"\n    传输的数据格式定义为：数据头(4字节) + 数据本体\n    - 数据头：表示数据本体的长度(单位为字节)，如：b`\\x00\\x00\\x00\\x07f` 表示数据本体长度是 127字节 (总共就需要发送 131字节)\n    - 数据本体：需要发送的数据\n    注：4字节能表示 2^32个无符号整数，即上述定义能表示约 4TB 的传输数据\n    \"\"\"\n    len_bytes = struct.pack('!I', len(data))\n    # print(data)\n    print(len(data))\n    soc.sendall(len_bytes + data)\n\n\n\n# send_all(client, open(r'E:\\work\\202502\\20250206-07\\fm58-li-gz05\\fm58-li-gz05-far\\RotarySys\\Ctrl\\fileviewer.exe', 'rb').read())\n\n\nsend_all(client, b'hello world')\nsend_all(client, '你干嘛'.encode('utf-8'))\n\n\n\nimport time; time.sleep(1)\n","date_published":"2025-10-27T01:15:49.864Z","_microfeed":{"web_url":"https://mf-drktravis-dpdns-org.pages.dev/i/socket--Y-nUqC3Ni1/","json_url":"https://mf-drktravis-dpdns-org.pages.dev/i/-Y-nUqC3Ni1/json/","rss_url":"https://mf-drktravis-dpdns-org.pages.dev/i/-Y-nUqC3Ni1/rss/","guid":"-Y-nUqC3Ni1","status":"published","itunes:episodeType":"full","date_published_short":"Sun Oct 26 2025","date_published_ms":1761527749864}},{"id":"-ShBwcUhU8T","title":"microfeed","content_html":"<p><br></p><p><a href=\"https://www.microfeed.org/\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://user-images.githubusercontent.com/1719237/207514210-99ddbd03-f8f0-410a-96c8-80da1afb804d.png\"></a></p><p><br></p><h1>Microfeed：Cloudflare 上的轻量级 CMS 自托管</h1><p><br></p><p><a href=\"https://github.com/microfeed/microfeed/issues/new?assignees=&amp;labels=bug\" rel=\"noopener noreferrer\" target=\"_blank\">报告错误</a>&nbsp;·<a href=\"https://github.com/microfeed/microfeed/discussions/new?category=ideas\" rel=\"noopener noreferrer\" target=\"_blank\">请求功能</a>&nbsp;·<a href=\"mailto:support@microfeed.org\" rel=\"noopener noreferrer\" target=\"_blank\">私下给我们发电子邮件</a></p><p>欢迎使用 microfeed，这是一个在 Cloudflare 上自托管的轻量级内容管理系统 （CMS）。 使用微源，您可以轻松发布各种内容，例如音频、视频、照片、文档、博客文章、 以及 Web、RSS 和 JSON 形式的源的外部 URL。对于精通技术的个人来说，这是一个完美的解决方案： 想要自行托管自己的 CMS，而无需运行自己的服务器。</p><p>microfeed 由&nbsp;<a href=\"https://www.listennotes.com/\" rel=\"noopener noreferrer\" target=\"_blank\">Listen Notes</a>&nbsp;构建，托管在 Cloudflare 的&nbsp;<a href=\"https://pages.cloudflare.com/\" rel=\"noopener noreferrer\" target=\"_blank\">Pages</a>、<a href=\"https://www.cloudflare.com/products/r2/\" rel=\"noopener noreferrer\" target=\"_blank\">R2</a>、<a href=\"https://developers.cloudflare.com/d1/\" rel=\"noopener noreferrer\" target=\"_blank\">D1</a>&nbsp;和&nbsp;<a href=\"https://www.cloudflare.com/products/zero-trust/\" rel=\"noopener noreferrer\" target=\"_blank\">Zero Trust</a>&nbsp;上。</p><p>如果您有任何问题或反馈，请随时通过&nbsp;<a href=\"mailto:support@microfeed.org\" rel=\"noopener noreferrer\" target=\"_blank\">support@microfeed.org</a>&nbsp;与我们联系。我们很乐意听取您的意见！</p><h2>📚 目录</h2><p><br></p><p><a href=\"https://github.com/microfeed/microfeed/actions/workflows/deploy.yml\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://github.com/microfeed/microfeed/actions/workflows/deploy.yml/badge.svg\"></a>&nbsp;<a href=\"https://github.com/microfeed/microfeed/actions/workflows/ci.yml\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://github.com/microfeed/microfeed/actions/workflows/ci.yml/badge.svg\"></a>&nbsp;<a href=\"mailto:support@microfeed.org\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://camo.githubusercontent.com/712a03a3128f64547e03e632d0074e35ea95e02678e2066ae715f92115d5e428/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f456d61696c2d737570706f72742534306d6963726f666565642e6f72672d626c7565\"></a>&nbsp;<a href=\"https://www.microfeed.org/i/introducing-microfeed-self-hosted-cms-on-cloudflare-opensource-serverless-free-uhbQEmArlC2/\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://camo.githubusercontent.com/ff40d4c433cd608db7b0c7ed2b0831746c4274d81df9fc2f89059fa621e482f4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f73746162696c6974792d616c7068612d6634643033662e737667\"></a></p><ul><li><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#%EF%B8%8F-how-it-works\" rel=\"noopener noreferrer\" target=\"_blank\">⭐️ 运作方式</a></li><li><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#-installation\" rel=\"noopener noreferrer\" target=\"_blank\">🚀 安装</a></li><li class=\"ql-indent-1\"><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#prerequisites\" rel=\"noopener noreferrer\" target=\"_blank\">先决条件</a></li><li class=\"ql-indent-1\"><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#step-1-fork-the-microfeed-repo-to-your-github\" rel=\"noopener noreferrer\" target=\"_blank\">步骤 1.将微源存储库分叉到 GitHub</a></li><li class=\"ql-indent-1\"><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#step-2-put-some-secrets-on-your-forked-repo\" rel=\"noopener noreferrer\" target=\"_blank\">步骤 2.在分叉的存储库上放一些秘密</a></li><li class=\"ql-indent-1\"><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#step-3-run-github-action-to-deploy-code\" rel=\"noopener noreferrer\" target=\"_blank\">步骤 3.运行 GitHub Action 以部署代码</a></li><li class=\"ql-indent-1\"><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#step-4-make-a-few-clicks-on-cloudflare-dashboard\" rel=\"noopener noreferrer\" target=\"_blank\">步骤 4.在 Cloudflare 仪表板上点击几下</a></li><li class=\"ql-indent-1\"><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#step-5-done-start-publishing\" rel=\"noopener noreferrer\" target=\"_blank\">步骤 5.做。开始发布</a></li><li class=\"ql-indent-1\"><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#bonus-update-to-the-latest-version-of-microfeed\" rel=\"noopener noreferrer\" target=\"_blank\">奖金。更新到最新版本的微进纸</a></li><li><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#-faqs\" rel=\"noopener noreferrer\" target=\"_blank\">💻 常见问题</a></li><li><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#-contributions\" rel=\"noopener noreferrer\" target=\"_blank\">💪 贡献</a></li><li class=\"ql-indent-1\"><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#run-microfeed-on-local\" rel=\"noopener noreferrer\" target=\"_blank\">在本地运行微源</a></li><li><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#%EF%B8%8F-license\" rel=\"noopener noreferrer\" target=\"_blank\">🛡️ 许可证</a></li></ul><h2>⭐️ 运作方式</h2><p><br></p><p>自 1990 年代以来，网络的很大一部分都是由提要驱动的。 人员（和机器人）将项目发布到源，其他人可以订阅该源以接收新内容。</p><p>微提要使个人可以轻松地在 Cloudflare 上自行托管自己的提要，包括但不限于</p><ul><li>音频的播客提要</li><li>帖子的博客提要</li><li>类似 Instagram 的图片提要（例如，<a href=\"https://llamacorn.listennotes.com/\" rel=\"noopener noreferrer\" target=\"_blank\">llamacorn.listennotes.com</a>&nbsp;<a href=\"https://brand-assets.listennotes.com/\" rel=\"noopener noreferrer\" target=\"_blank\">brand-assets.listennotes.com</a>)</li><li>类似 YouTube 的视频提要</li><li>带有自定义链接（例如&nbsp;<a href=\"https://www.wenbin.org/\" rel=\"noopener noreferrer\" target=\"_blank\">wenbin.org</a>)</li><li>外部新闻文章 URL 的内容管理源</li><li>提供更新和新闻报道的营销网站（例如&nbsp;<a href=\"https://www.microfeed.org/\" rel=\"noopener noreferrer\" target=\"_blank\">microfeed.org</a>)</li><li>带有 GUI 仪表板和公共 json 提要的无头 cms（例如，在&nbsp;<a href=\"https://www.microfeed.org/json/openapi.yaml\" rel=\"noopener noreferrer\" target=\"_blank\">YAML</a>&nbsp;和&nbsp;<a href=\"https://www.microfeed.org/json/openapi.html\" rel=\"noopener noreferrer\" target=\"_blank\">HTML</a>&nbsp;中带有 OpenAPI 规范的&nbsp;<a href=\"https://www.microfeed.org/json/\" rel=\"noopener noreferrer\" target=\"_blank\">microfeed.org/json</a>)</li><li>待售域名列表（例如，<a href=\"https://www.listenhost.com/\" rel=\"noopener noreferrer\" target=\"_blank\">ListenHost.com</a>...</li><li>整本书的网站（例如，<a href=\"https://the-art-of-war.microfeed.org/\" rel=\"noopener noreferrer\" target=\"_blank\">《孙子兵法》</a>)</li><li>更新日志网站（例如，<a href=\"https://changelog.listennotes.com/\" rel=\"noopener noreferrer\" target=\"_blank\">changelog.listennotes.com</a>)</li><li>...</li></ul><p>microfeed 使用 Cloudflare&nbsp;<a href=\"https://pages.cloudflare.com/\" rel=\"noopener noreferrer\" target=\"_blank\">Pages</a>&nbsp;托管和运行代码，<a href=\"https://www.cloudflare.com/products/r2/\" rel=\"noopener noreferrer\" target=\"_blank\">R2</a>&nbsp;托管和提供媒体文件，<a href=\"https://developers.cloudflare.com/d1/\" rel=\"noopener noreferrer\" target=\"_blank\">D1</a>&nbsp;存储元数据，和&nbsp;<a href=\"https://www.cloudflare.com/products/zero-trust/\" rel=\"noopener noreferrer\" target=\"_blank\">Zero Trust</a>&nbsp;提供对管理仪表板的登录信息。Cloudflare 提供非常慷慨的免费使用配额，使其成为个人或小型企业使用的经济实惠的解决方案。虽然您仍然需要为域名付费，但在 Cloudflare 上托管微源基本上是免费的。</p><p>使用微源，您可以发布各种内容，例如音频、视频、照片、文档、博客文章、 以及可自定义网站、RSS 提要和&nbsp;<a href=\"https://www.jsonfeed.org/\" rel=\"noopener noreferrer\" target=\"_blank\">JSON 提要</a>的外部 URL。 查看微进料的一些实际示例：</p><ul><li>网络提要：<a href=\"https://llamacorn.listennotes.com/\" rel=\"noopener noreferrer\" target=\"_blank\">https://llamacorn.listennotes.com/</a></li><li>RSS 提要：<a href=\"https://llamacorn.listennotes.com/rss/\" rel=\"noopener noreferrer\" target=\"_blank\">https://llamacorn.listennotes.com/rss/</a></li><li>Json 提要：<a href=\"https://llamacorn.listennotes.com/json/\" rel=\"noopener noreferrer\" target=\"_blank\">https://llamacorn.listennotes.com/json/</a></li></ul><p>Microfeed 提供了一个简单而强大的管理仪表板，可以轻松地将项目添加到 Feed， 上传媒体文件，并自定义网页样式。如果您以前使用过 WordPress，您会发现它很熟悉。</p><p><a href=\"https://user-images.githubusercontent.com/1719237/209486588-00acefe0-dd51-4bfc-aed7-1f63850aa720.png\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://user-images.githubusercontent.com/1719237/209486588-00acefe0-dd51-4bfc-aed7-1f63850aa720.png\"></a></p><p><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#-table-of-contents\" rel=\"noopener noreferrer\" target=\"_blank\">返回📚目录</a></p><h2>🚀 安装</h2><p><br></p><p>大致上，您将按照以下步骤将微源实例安装到 Cloudflare：</p><ol><li>将<a href=\"https://github.com/microfeed/microfeed\" rel=\"noopener noreferrer\" target=\"_blank\">微源存储库</a>分支到个人（或组织）GitHub 帐户。</li><li>获取 Cloudflare API 令牌，并将其作为机密保存在分叉的 GitHub 存储库中。</li><li>使用分支存储库中的预定义 GitHub Action，使用步骤 2 中的密钥将代码部署到 Cloudflare Pages。</li><li>在 Cloudflare 的仪表板上单击几下即可设置自定义域并配置一些安全设置。</li><li>做。开始发布！</li></ol><blockquote>我们知道并不是每个人都喜欢阅读文档，因此我们尽可能简单地阅读文档 开始使用 Microfeed。但是，我们希望看到 Cloudflare 实现“使用 Cloudflare 登录”OAuth 功能， 这将允许几乎一键部署微进纸。与此同时，我们尝试进行设置过程 对于精通技术的用户来说，尽可能简单。</blockquote><h3>先决条件</h3><p><br></p><ul><li>拥有 Cloudflare 帐户。如果您还没有，可以在&nbsp;<a href=\"https://dash.cloudflare.com/sign-up\" rel=\"noopener noreferrer\" target=\"_blank\">Cloudflare.com 免费注册</a>。</li><li>拥有 GitHub 帐户。如果您没有，可以在&nbsp;<a href=\"https://github.com/signup\" rel=\"noopener noreferrer\" target=\"_blank\">GitHub.com 免费注册</a>。</li></ul><p><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#-table-of-contents\" rel=\"noopener noreferrer\" target=\"_blank\">返回目录</a></p><h3>步骤 1.将微源存储库分叉到 GitHub</h3><p><br></p><p>只需单击&nbsp;<a href=\"https://github.com/microfeed/microfeed/fork\" rel=\"noopener noreferrer\" target=\"_blank\">https://github.com/microfeed/microfeed/fork</a>&nbsp;即可分叉存储库。</p><p>将来可以选择修改分叉存储库中的代码，但可能不需要修改 完全触摸代码。只需分叉存储库并保持同步以备将来使用。</p><p><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#-table-of-contents\" rel=\"noopener noreferrer\" target=\"_blank\">返回📚目录</a></p><h3>步骤 2.在分叉的存储库上放一些秘密</h3><p><br></p><p>转到分叉存储库的设置&nbsp;<a href=\"https://github.com/microfeed/microfeed/settings/secrets/actions\" rel=\"noopener noreferrer\" target=\"_blank\">-&gt; 密钥 -&gt;作</a>，并创建 5 个密钥（点击了解更多详细信息）。 有了这些密钥，您就可以使用 GitHub Actions 将微源实例部署到 Cloudflare Pages。</p><p>CLOUDFLARE_ACCOUNT_ID</p><p>您可以从仪表板的 URL 获取您的 cloudflare 帐户 ID：</p><p><a href=\"https://dash.cloudflare.com/login?lang=en-US\" rel=\"noopener noreferrer\" target=\"_blank\">登录 Cloudflare 帐户</a>后，您将被重定向到如下 URL</p><pre class=\"ql-syntax\" spellcheck=\"false\">https://dash.cloudflare.com/[your-cloudflare-account-id-here]\n</pre><p><br></p><p>URL 的最后一部分是您的 cloudflare 帐户 ID。</p><p>例如，如果您看到如下网址：</p><pre class=\"ql-syntax\" spellcheck=\"false\">https://dash.cloudflare.com/fff88980eeeeedcc3ffffd4f555f4999\n</pre><p><br></p><p>然后，您将CLOUDFLARE_ACCOUNT_ID设置为&nbsp;fff88980eeeeedcc3ffffd4f555f4999：</p><p><a href=\"https://user-images.githubusercontent.com/1719237/208216752-56f00f51-29cb-43ea-b720-75244719898d.png\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://user-images.githubusercontent.com/1719237/208216752-56f00f51-29cb-43ea-b720-75244719898d.png\"></a></p><p>CLOUDFLARE_API_TOKEN</p><p>您需要在此处创建一个 API 令牌：<a href=\"https://dash.cloudflare.com/profile/api-tokens\" rel=\"noopener noreferrer\" target=\"_blank\">https://dash.cloudflare.com/profile/api-tokens</a></p><p>创建自定义令牌：</p><p><a href=\"https://user-images.githubusercontent.com/1719237/205525627-14da54ae-1733-4db5-b65d-94f5ec48f360.png\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://user-images.githubusercontent.com/1719237/205525627-14da54ae-1733-4db5-b65d-94f5ec48f360.png\"></a></p><p>我们需要 Cloudflare Pages 和 D1 的编辑权限：</p><p><a href=\"https://user-images.githubusercontent.com/1719237/205525675-4c8a6bce-21a8-45e3-bf0c-28981f123da3.png\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://user-images.githubusercontent.com/1719237/205525675-4c8a6bce-21a8-45e3-bf0c-28981f123da3.png\"></a></p><p>最后，将 API 令牌复制到此处：</p><p><a href=\"https://user-images.githubusercontent.com/1719237/205525785-6fed8e49-7342-4b36-9d07-348e1c28cbcc.png\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://user-images.githubusercontent.com/1719237/205525785-6fed8e49-7342-4b36-9d07-348e1c28cbcc.png\"></a></p><p>R2_ACCESS_KEY_ID和R2_SECRET_ACCESS_KEY</p><p>转到您的&nbsp;<a href=\"https://dash.cloudflare.com/sign-up/r2\" rel=\"noopener noreferrer\" target=\"_blank\">R2 仪表板页面</a>。您可能需要先将信用卡放在那里。除非您的使用量超过非常慷慨的免费配额限制（即 10GB 存储 + 1000 万次读取/月 + 100 万次写入/月），否则您无需付费。</p><p>在此处创建 R2 API 令牌：</p><p><a href=\"https://user-images.githubusercontent.com/1719237/205526381-cc11d4fe-b053-49d0-9072-de54db31b3b7.png\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://user-images.githubusercontent.com/1719237/205526381-cc11d4fe-b053-49d0-9072-de54db31b3b7.png\"></a></p><p>选择“管理员读写”权限并创建 API 令牌：</p><p><a href=\"https://private-user-images.githubusercontent.com/1719237/259258288-1a90df29-5660-49d4-b66a-24873812492d.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NTk3MjgwMzUsIm5iZiI6MTc1OTcyNzczNSwicGF0aCI6Ii8xNzE5MjM3LzI1OTI1ODI4OC0xYTkwZGYyOS01NjYwLTQ5ZDQtYjY2YS0yNDg3MzgxMjQ5MmQucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MTAwNiUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTEwMDZUMDUxNTM1WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MWRmYThiODYzMGI0NWFlY2JhMjg5OTVlY2IyN2VjOTFlNDRkZWU1YTg1Y2FmMDc1OWViODRlZTgyYmUwNWM0YSZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.MEtwqpPLYlZrm0H9uKJZPlXYAZLbWY1yj_p8wFv8W10\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://private-user-images.githubusercontent.com/1719237/259258288-1a90df29-5660-49d4-b66a-24873812492d.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NTk3MjgwMzUsIm5iZiI6MTc1OTcyNzczNSwicGF0aCI6Ii8xNzE5MjM3LzI1OTI1ODI4OC0xYTkwZGYyOS01NjYwLTQ5ZDQtYjY2YS0yNDg3MzgxMjQ5MmQucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MTAwNiUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTEwMDZUMDUxNTM1WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MWRmYThiODYzMGI0NWFlY2JhMjg5OTVlY2IyN2VjOTFlNDRkZWU1YTg1Y2FmMDc1OWViODRlZTgyYmUwNWM0YSZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.MEtwqpPLYlZrm0H9uKJZPlXYAZLbWY1yj_p8wFv8W10\"></a></p><p>复制R2_ACCESS_KEY_ID的访问密钥 ID，复制R2_SECRET_ACCESS_KEY的密钥<a href=\"https://user-images.githubusercontent.com/1719237/205526582-92f440ac-21c4-46d9-a065-cfc1937391c8.png\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://user-images.githubusercontent.com/1719237/205526582-92f440ac-21c4-46d9-a065-cfc1937391c8.png\"></a></p><p>CLOUDFLARE_PROJECT_NAME</p><p>合法的项目名称应包含以下字符：[a-z]、[A-Z]、[0-9] 和 -</p><p>我们建议使用您将用于此项目的自定义域名，并将点 （.） 替换为短划线 （-）</p><p>例如，如果您使用 photos.mycustomdomain.com，则项目名称应为 photos-mycustomdomain-com</p><p>注意：请勿在 [a-z]、[A-Z]、[0-9] 和 - 之外使用下划线 （_）、空格 （ ） 和其他字符。或者 Cloudflare Pages 不允许您创建项目。</p><p>总共需要为 GitHub Actions 添加 5 个机密：</p><p><a href=\"https://user-images.githubusercontent.com/1719237/205524410-268abf92-af61-467a-8883-78b8d4de3c56.png\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://user-images.githubusercontent.com/1719237/205524410-268abf92-af61-467a-8883-78b8d4de3c56.png\"></a></p><p><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#-table-of-contents\" rel=\"noopener noreferrer\" target=\"_blank\">返回📚目录</a></p><h3>步骤 3.运行 GitHub Action 以部署代码</h3><p><br></p><p>转到&nbsp;<a href=\"https://github.com/microfeed/microfeed/actions/workflows/deploy.yml\" rel=\"noopener noreferrer\" target=\"_blank\">Actions -&gt; Deploy to Cloudflare Pages</a>&nbsp;并运行 Workflow</p><p><a href=\"https://user-images.githubusercontent.com/1719237/205526856-05ea0ff4-703a-4d08-bc7f-4ae2dfc07cfe.png\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://user-images.githubusercontent.com/1719237/205526856-05ea0ff4-703a-4d08-bc7f-4ae2dfc07cfe.png\"></a></p><p>如果看到绿色复选标记，则部署成功。您可以在&nbsp;<a href=\"https://dash.cloudflare.com/sign-up/pages\" rel=\"noopener noreferrer\" target=\"_blank\">Cloudflare 仪表板</a>中看到一个 Pages 项目：</p><p><a href=\"https://user-images.githubusercontent.com/1719237/205527141-277620dd-586b-42dd-be97-edb7875d0705.png\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://user-images.githubusercontent.com/1719237/205527141-277620dd-586b-42dd-be97-edb7875d0705.png\"></a></p><p>您可以通过 ${CLOUDFLARE_PROJECT_NAME}.pages.dev 访问该站点，例如&nbsp;<a href=\"https://microfeed-org.pages.dev/\" rel=\"noopener noreferrer\" target=\"_blank\">https://microfeed-org.pages.dev/</a></p><p><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#-table-of-contents\" rel=\"noopener noreferrer\" target=\"_blank\">返回📚目录</a></p><h3>步骤 4.在 Cloudflare 仪表板上点击几下</h3><p><br></p><p>要管理您的微源实例，您将使用 ${CLOUDFLARE_PROJECT_NAME}.pages.dev/admin 的管理仪表板，例如&nbsp;<a href=\"https://microfeed-org.pages.dev/admin/\" rel=\"noopener noreferrer\" target=\"_blank\">https://microfeed-org.pages.dev/admin/</a>（管理仪表板需要受 Cloudflare Zero Trust 保护）。</p><p>首次访问管理仪表板时，您将按照清单完成设置过程：</p><p><a href=\"https://user-images.githubusercontent.com/1719237/208216864-38a65086-77ef-4595-bc05-c87be2676e6d.png\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://user-images.githubusercontent.com/1719237/208216864-38a65086-77ef-4595-bc05-c87be2676e6d.png\"></a></p><p><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#-table-of-contents\" rel=\"noopener noreferrer\" target=\"_blank\">返回📚目录</a></p><h3>步骤 5.做。开始发布</h3><p><br></p><p>完成设置过程后，您的微馈送实例就可以使用了。 您可以从管理仪表板添加、更新或删除项目。</p><p>您还可以在设置/自定义代码中通过编辑原始 HTML 和 CSS 来自定义网站的外观：</p><p><a href=\"https://user-images.githubusercontent.com/1719237/210062910-e56135f6-557e-419e-a00d-b25dd391c93d.png\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://user-images.githubusercontent.com/1719237/210062910-e56135f6-557e-419e-a00d-b25dd391c93d.png\"></a></p><p>HTML 代码使用&nbsp;<a href=\"https://github.com/janl/mustache.js\" rel=\"noopener noreferrer\" target=\"_blank\">mustache.js</a>&nbsp;作为模板语言，您可以在其中访问 Feed Json 或 Item Json 中的变量。例如，在我们的营销网站&nbsp;<a href=\"https://www.microfeed.org/\" rel=\"noopener noreferrer\" target=\"_blank\">microfeed.org</a>&nbsp;的主页 （Feed Web） 上，我们使用&nbsp;<a href=\"https://www.microfeed.org/json/\" rel=\"noopener noreferrer\" target=\"_blank\">microfeed.org/json/</a>&nbsp;的 html 代码中的变量，而在<a href=\"https://www.microfeed.org/i/introducing-microfeed-a-self-hosted-open-source-cms-on-cloudflare-open-alpha-uhbQEmArlC2/\" rel=\"noopener noreferrer\" target=\"_blank\">商品的页面</a>&nbsp;（Item Web） 上，我们使用&nbsp;<a href=\"https://www.microfeed.org/i/introducing-microfeed-a-self-hosted-open-source-cms-on-cloudflare-open-alpha-uhbQEmArlC2/json\" rel=\"noopener noreferrer\" target=\"_blank\">${item_url}/json</a>&nbsp;中的变量。</p><p>通过轻松访问微源实例的 json 数据（即&nbsp;<a href=\"https://www.microfeed.org/json/\" rel=\"noopener noreferrer\" target=\"_blank\">Feed Json</a>&nbsp;和&nbsp;<a href=\"https://www.microfeed.org/i/introducing-microfeed-a-self-hosted-open-source-cms-on-cloudflare-open-alpha-uhbQEmArlC2/json\" rel=\"noopener noreferrer\" target=\"_blank\">Item Json</a>），您可以将其用作无头 CMS 并构建自己的客户端应用程序来显示内容。</p><p><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#-table-of-contents\" rel=\"noopener noreferrer\" target=\"_blank\">返回📚目录</a></p><h3>奖金。更新到最新版本的微进纸</h3><p><br></p><p>我们将继续在此微源存储库中添加新功能并修复错误。 您可能希望使用新代码更新分叉存储库。</p><p>首先，在分叉的存储库中同步代码：</p><p><a href=\"https://user-images.githubusercontent.com/1719237/209483973-c82e7808-0d21-4aad-ac2d-c4e80da691bc.png\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://user-images.githubusercontent.com/1719237/209483973-c82e7808-0d21-4aad-ac2d-c4e80da691bc.png\"></a></p><p>然后转到&nbsp;<a href=\"https://github.com/microfeed/microfeed/actions/workflows/deploy.yml\" rel=\"noopener noreferrer\" target=\"_blank\">Actions -&gt; Deploy to Cloudflare Pages</a>&nbsp;并运行 Workflow 以部署新代码。</p><p><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#-table-of-contents\" rel=\"noopener noreferrer\" target=\"_blank\">返回📚目录</a></p><h2>💻 常见问题</h2><p><br></p><p>如何跟踪播客/视频/图像下载？</p><p>要使用微提要跟踪播客、视频或图像下载，您可以使用跟踪 URL 功能。 这允许您为媒体文件设置第三方跟踪 URL，例如&nbsp;<a href=\"https://op3.dev/\" rel=\"noopener noreferrer\" target=\"_blank\">OP3</a>、<a href=\"http://analytics.podtrac.com/\" rel=\"noopener noreferrer\" target=\"_blank\">Podtrac</a>&nbsp;提供的 URL...</p><p>要设置跟踪 URL，您需要转到设置/跟踪 URL：<a href=\"https://user-images.githubusercontent.com/1719237/210665674-39f9b0a9-1f28-4608-b0cd-c67b8a5c87ec.png\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://user-images.githubusercontent.com/1719237/210665674-39f9b0a9-1f28-4608-b0cd-c67b8a5c87ec.png\"></a></p><p>从那里，您可以添加要使用的第三方跟踪 URL。microfeed 会自动将这些 URL 添加到媒体文件的 URL 前面，以便您跟踪下载统计信息。</p><p>这是<a href=\"https://lowerstreet.co/blog/podcast-tracking\" rel=\"noopener noreferrer\" target=\"_blank\">播客行业的常见做法</a>，可以成为监控内容表现并了解受众如何消费内容的有用方法。</p><p>为什么选择 Cloudflare？相信一家营利性公司不是很危险吗？</p><p>许多个人和组织信任并使用 Cloudflare 的服务，因为它在提供可靠和有效的服务方面享有盛誉。 我们（<a href=\"https://www.listennotes.com/\" rel=\"noopener noreferrer\" target=\"_blank\">Listen Notes</a>）多年来一直在使用 Cloudflare。</p><p>在像 Cloudflare 这样的一站式平台上管理所有事情非常方便（例如 DNS、缓存、防火墙、运行代码、CDN、无需信任的登录......</p><p>微进纸仍处于开放 alpha 阶段。Cloudflare 是我们支持的第一个平台。 我们可能会考虑支持其他无服务器平台，以便您可以在需要时轻松迁移离开。</p><p>如果 Cloudflare 取消了我的 microfeed 实例的平台怎么办？</p><p>请务必仔细查看您使用的任何服务（包括 Cloudflare）的服务条款。 如果您违反服务条款，服务可能会采取行动，例如将您的实例去平台化。</p><p>为了防止被去平台化的可能性，最好定期从 Cloudflare 备份您的数据。 这将允许您恢复内容，并在必要时将它们迁移到其他平台。 使用您自己的自定义域也是一个好主意，因为这将使您能够更好地控制您的内容，并在需要时更轻松地将数据移动到不同的平台。</p><p>为什么要使用微进纸？</p><p>如果您已经在使用 Cloudflare 并且对其服务感到满意，那么使用 microfeed 可能是您的不错选择。</p><p>如果您不想管理自己的服务器，微源可能是一个方便的替代方案，可以让您利用 Cloudflare 的基础设施和安全功能。</p><p>如果您不想为服务器付费，microfeed 可能是一种经济高效的解决方案，因为 Cloudflare 提供了慷慨的免费使用配额。</p><p>如果您正在寻找新的东西并且有兴趣探索不同的选择，微馈送可能是一个不错的选择。在使用任何服务之前仔细评估它总是一个好主意，以确保它满足您的需求并且非常适合您的用例。</p><p>如何从 microfeed / Cloudflare 下载/备份数据？</p><p>microfeed 将数据存储在 Cloudflare D1 和 R2 中。因此，您将下载两个内容来备份您的微源数据：</p><ul><li>来自&nbsp;<a href=\"https://developers.cloudflare.com/d1/\" rel=\"noopener noreferrer\" target=\"_blank\">Cloudflare D1</a>&nbsp;的 sqlite 数据库，包括所有元数据。</li><li>来自&nbsp;<a href=\"https://developers.cloudflare.com/r2/\" rel=\"noopener noreferrer\" target=\"_blank\">Cloudflare R2</a>&nbsp;的媒体文件，包括音频、图像、视频......</li></ul><p>如何从 D1 下载 sqlite 数据库？</p><p>您可以使用命令行工具查找 sqlite 数据库文件并下载备份：wrangler</p><p><a href=\"https://developers.cloudflare.com/workers/wrangler/commands/#d1\" rel=\"noopener noreferrer\" target=\"_blank\">https://developers.cloudflare.com/workers/wrangler/commands/#d1</a></p><p>如何从 R2 下载媒体文件？</p><p>截至 2023 年 2 月 16 日，Cloudflare 尚未提供从 R2 存储桶批量下载所有文件的工具。</p><p>您可能需要编写脚本以使用<a href=\"https://developers.cloudflare.com/r2/data-access/s3-api/api/\" rel=\"noopener noreferrer\" target=\"_blank\">与 S3 兼容的 API</a>&nbsp;从特定 R2 存储桶中获取所有对象。</p><p><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#-table-of-contents\" rel=\"noopener noreferrer\" target=\"_blank\">返回📚目录</a></p><h2>💪 贡献</h2><p><br></p><p>我们欢迎对 microfeed 做出贡献！如果你对新功能有想法或发现错误，请在存储库中<a href=\"https://github.com/microfeed/microfeed/issues/new\" rel=\"noopener noreferrer\" target=\"_blank\">打开一个问题</a>。如果你想提交修复或新功能，请创建一个拉取请求，其中包含你的更改的详细描述。</p><h3>在本地运行微源</h3><p><br></p><p>先决条件：节点/npm、yarn 和 wrangler</p><p>首先，在 microfeed 的根目录（与此 README.md 文件同一级别）创建一个 .vars.toml 文件，并将 5 个密钥放入 .vars.toml 文件中（类似于<a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#step-2-put-some-secrets-on-your-forked-repo\" rel=\"noopener noreferrer\" target=\"_blank\">步骤 2。将一些密钥放在你的分叉存储库中</a>）：</p><pre class=\"ql-syntax\" spellcheck=\"false\"># .vars.toml\nCLOUDFLARE_PROJECT_NAME = \"your-project-org\"\nCLOUDFLARE_ACCOUNT_ID = \"account id\"\nCLOUDFLARE_API_TOKEN = 'api token'\nR2_ACCESS_KEY_ID = \"access key\"\nR2_SECRET_ACCESS_KEY = \"secret key\"\n\nR2_PUBLIC_BUCKET = \"your-r2-bucket-name\"\n</pre><p><br></p><p>其次，运行本地开发服务器：</p><pre class=\"ql-syntax\" spellcheck=\"false\">yarn dev\n</pre><p><br></p><p>您应该能够通过&nbsp;<a href=\"http://127.0.0.1:8788/\" rel=\"noopener noreferrer\" target=\"_blank\">http://127.0.0.1:8788/</a>&nbsp;访问本地微馈送实例。</p><p>yarn dev&nbsp;是如何工作的？本质上，它同时运行两个进程：和 。该进程启动用于<a href=\"https://webpack.js.org/configuration/dev-server/\" rel=\"noopener noreferrer\" target=\"_blank\">客户端 JavaScript 代码的 webpack DevServer</a>，同时启动&nbsp;<a href=\"https://developers.cloudflare.com/pages/functions/local-development/\" rel=\"noopener noreferrer\" target=\"_blank\">Wrangler 来提供 Pages（边缘）代码</a>。yarn dev:clientyarn dev:edgeyarn dev:clientyarn dev:edge</p><p><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#-table-of-contents\" rel=\"noopener noreferrer\" target=\"_blank\">返回📚目录</a></p><h2>🛡️ 许可证</h2><p><br></p><p>microfeed 根据&nbsp;<a href=\"https://github.com/microfeed/microfeed/blob/main/LICENSE\" rel=\"noopener noreferrer\" target=\"_blank\">AGPL-3.0</a>&nbsp;许可证获得许可。有关更多信息，请参阅&nbsp;<a href=\"https://github.com/microfeed/microfeed/blob/main/LICENSE\" rel=\"noopener noreferrer\" target=\"_blank\">LICENSE 文件</a>。</p><p><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#-table-of-contents\" rel=\"noopener noreferrer\" target=\"_blank\">返回📚目录</a></p><h2>大约</h2><p>Cloudflare 上自托管的轻量级 CMS，用于播客、博客、照片、视频、文档和精选 URL。</p><p><br></p><p><a href=\"https://www.microfeed.org/\" rel=\"noopener noreferrer\" target=\"_blank\">www.microfeed.org/</a></p><h3>主题</h3><p><a href=\"https://github.com/topics/cms\" rel=\"noopener noreferrer\" target=\"_blank\">CMS系统</a>&nbsp;<a href=\"https://github.com/topics/serverless\" rel=\"noopener noreferrer\" target=\"_blank\">无服务器</a>&nbsp;<a href=\"https://github.com/topics/cloudflare\" rel=\"noopener noreferrer\" target=\"_blank\">Cloudflare</a>&nbsp;<a href=\"https://github.com/topics/cloudflare-pages\" rel=\"noopener noreferrer\" target=\"_blank\">云耀斑页面</a>&nbsp;<a href=\"https://github.com/topics/cloudflare-r2\" rel=\"noopener noreferrer\" target=\"_blank\">Cloudflare-R2 的</a>&nbsp;<a href=\"https://github.com/topics/cloudflare-zero-trust\" rel=\"noopener noreferrer\" target=\"_blank\">Cloudflare-零信任</a>&nbsp;<a href=\"https://github.com/topics/cloudflare-d1\" rel=\"noopener noreferrer\" target=\"_blank\">Cloudflare-D1</a>&nbsp;<a href=\"https://github.com/topics/podcast-host\" rel=\"noopener noreferrer\" target=\"_blank\">播客主持人</a></p><h3>资源</h3><p><br></p><p><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#readme-ov-file\" rel=\"noopener noreferrer\" target=\"_blank\">自述文件</a></p><h3>许可证</h3><p><br></p><p><br></p><p><a href=\"https://github.com/microfeed/microfeed?tab=readme-ov-file#AGPL-3.0-1-ov-file\" rel=\"noopener noreferrer\" target=\"_blank\">AGPL-3.0 许可证</a></p><p><br></p><p><br></p><p><br></p><p><a href=\"https://github.com/microfeed/microfeed/activity\" rel=\"noopener noreferrer\" target=\"_blank\">&nbsp;活动</a></p><p><br></p><p><a href=\"https://github.com/microfeed/microfeed/custom-properties\" rel=\"noopener noreferrer\" target=\"_blank\">&nbsp;自定义属性</a></p><h3>星星</h3><p><br></p><p><br></p><p><a href=\"https://github.com/microfeed/microfeed/stargazers\" rel=\"noopener noreferrer\" target=\"_blank\">&nbsp;3.8k&nbsp;星</a></p><h3>观察家</h3><p><br></p><p><br></p><p><a href=\"https://github.com/microfeed/microfeed/watchers\" rel=\"noopener noreferrer\" target=\"_blank\">&nbsp;26&nbsp;观看</a></p><h3>叉</h3><p><br></p><p><br></p><p><a href=\"https://github.com/microfeed/microfeed/forks\" rel=\"noopener noreferrer\" target=\"_blank\">&nbsp;1.3k&nbsp;叉子</a></p><p><a href=\"https://github.com/contact/report-content?content_url=https%3A%2F%2Fgithub.com%2Fmicrofeed%2Fmicrofeed&amp;report=microfeed+%28user%29\" rel=\"noopener noreferrer\" target=\"_blank\">报告存储库</a></p><h2><a href=\"https://github.com/microfeed/microfeed/releases\" rel=\"noopener noreferrer\" target=\"_blank\">释放6</a></h2><p><br></p><p><a href=\"https://github.com/microfeed/microfeed/releases/tag/v0.1.5\" rel=\"noopener noreferrer\" target=\"_blank\">0.1.5版</a></p><p><a href=\"https://github.com/microfeed/microfeed/releases/tag/v0.1.5\" rel=\"noopener noreferrer\" target=\"_blank\">最近的</a></p><p><a href=\"https://github.com/microfeed/microfeed/releases/tag/v0.1.5\" rel=\"noopener noreferrer\" target=\"_blank\">on Mar 15</a></p><p><a href=\"https://github.com/microfeed/microfeed/releases\" rel=\"noopener noreferrer\" target=\"_blank\">+ 5 个版本</a></p><h2><a href=\"https://github.com/microfeed/microfeed/graphs/contributors\" rel=\"noopener noreferrer\" target=\"_blank\">贡献</a></h2><h2><a href=\"https://github.com/microfeed/microfeed/graphs/contributors\" rel=\"noopener noreferrer\" target=\"_blank\">8</a></h2><ul><li><a href=\"https://github.com/wenbinf\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://avatars.githubusercontent.com/u/1719237?s=64&amp;v=4\"></a></li><li><a href=\"https://github.com/andreybo\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://avatars.githubusercontent.com/u/19314952?s=64&amp;v=4\"></a></li><li><a href=\"https://github.com/allanice001\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://avatars.githubusercontent.com/u/700853?s=64&amp;v=4\"></a></li><li><a href=\"https://github.com/jarylc\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://avatars.githubusercontent.com/u/1162128?s=64&amp;v=4\"></a></li><li><a href=\"https://github.com/jwenjian\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://avatars.githubusercontent.com/u/25657798?s=64&amp;v=4\"></a></li><li><a href=\"https://github.com/orthanc42\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://avatars.githubusercontent.com/u/13221583?s=64&amp;v=4\"></a></li><li><a href=\"https://github.com/TheOnlyWayUp\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://avatars.githubusercontent.com/u/76237496?s=64&amp;v=4\"></a></li><li><a href=\"https://github.com/jcary741\" rel=\"noopener noreferrer\" target=\"_blank\"><img src=\"https://avatars.githubusercontent.com/u/101132508?s=64&amp;v=4\"></a></li></ul><h2>语言</h2><p><br></p><ul><li><br></li><li><a href=\"https://github.com/microfeed/microfeed/search?l=javascript\" rel=\"noopener noreferrer\" target=\"_blank\">JavaScript的</a></li><li><a href=\"https://github.com/microfeed/microfeed/search?l=javascript\" rel=\"noopener noreferrer\" target=\"_blank\">80.6%</a></li><li>&nbsp;</li><li><a href=\"https://github.com/microfeed/microfeed/search?l=html\" rel=\"noopener noreferrer\" target=\"_blank\">[HTML全文]</a></li><li><a href=\"https://github.com/microfeed/microfeed/search?l=html\" rel=\"noopener noreferrer\" target=\"_blank\">17.9%</a></li><li>&nbsp;</li><li><a href=\"https://github.com/microfeed/microfeed/search?l=css\" rel=\"noopener noreferrer\" target=\"_blank\">CSS系统</a></li><li><a href=\"https://github.com/microfeed/microfeed/search?l=css\" rel=\"noopener noreferrer\" target=\"_blank\">1.3%</a></li><li>&nbsp;</li><li><a href=\"https://github.com/microfeed/microfeed/search?l=shell\" rel=\"noopener noreferrer\" target=\"_blank\">壳</a></li><li><a href=\"https://github.com/microfeed/microfeed/search?l=shell\" rel=\"noopener noreferrer\" target=\"_blank\">0.2%</a></li></ul><h2>Footer</h2><p><br></p><p>© 2025 GitHub,&nbsp;Inc.</p><h3>Footer navigation</h3><ul><li><a href=\"https://docs.github.com/site-policy/github-terms/github-terms-of-service\" rel=\"noopener noreferrer\" target=\"_blank\">Terms</a></li><li><a href=\"https://docs.github.com/site-policy/privacy-policies/github-privacy-statement\" rel=\"noopener noreferrer\" target=\"_blank\">Privacy</a></li><li><a href=\"https://github.com/security\" rel=\"noopener noreferrer\" target=\"_blank\">Security</a></li><li><a href=\"https://www.githubstatus.com/\" rel=\"noopener noreferrer\" target=\"_blank\">Status</a></li><li><a href=\"https://github.community/\" rel=\"noopener noreferrer\" target=\"_blank\">Community</a></li><li><a href=\"https://docs.github.com/\" rel=\"noopener noreferrer\" target=\"_blank\">Docs</a></li><li><a href=\"https://support.github.com/?tags=dotcom-footer\" rel=\"noopener noreferrer\" target=\"_blank\">Contact</a></li><li>Manage cookies</li><li>Do not share my personal information</li></ul>","content_text":"\n\n\n[https://user-images.githubusercontent.com/1719237/207514210-99ddbd03-f8f0-410a-96c8-80da1afb804d.png]\n\n\n\n\n\nMICROFEED：CLOUDFLARE 上的轻量级 CMS 自托管\n\n\n\n\n报告错误 ·请求功能 ·私下给我们发电子邮件\n\n欢迎使用 microfeed，这是一个在 Cloudflare 上自托管的轻量级内容管理系统 （CMS）。\n使用微源，您可以轻松发布各种内容，例如音频、视频、照片、文档、博客文章、 以及 Web、RSS 和 JSON 形式的源的外部\nURL。对于精通技术的个人来说，这是一个完美的解决方案： 想要自行托管自己的 CMS，而无需运行自己的服务器。\n\nmicrofeed 由 Listen Notes 构建，托管在 Cloudflare 的 Pages、R2、D1 和 Zero Trust 上。\n\n如果您有任何问题或反馈，请随时通过 support@microfeed.org 与我们联系。我们很乐意听取您的意见！\n\n\n📚 目录\n\n\n\n\n[https://github.com/microfeed/microfeed/actions/workflows/deploy.yml/badge.svg] [https://github.com/microfeed/microfeed/actions/workflows/ci.yml/badge.svg] [https://camo.githubusercontent.com/712a03a3128f64547e03e632d0074e35ea95e02678e2066ae715f92115d5e428/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f456d61696c2d737570706f72742534306d6963726f666565642e6f72672d626c7565] [https://camo.githubusercontent.com/ff40d4c433cd608db7b0c7ed2b0831746c4274d81df9fc2f89059fa621e482f4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f73746162696c6974792d616c7068612d6634643033662e737667]\n\n * ⭐️ 运作方式\n * 🚀 安装\n * 先决条件\n * 步骤 1.将微源存储库分叉到 GitHub\n * 步骤 2.在分叉的存储库上放一些秘密\n * 步骤 3.运行 GitHub Action 以部署代码\n * 步骤 4.在 Cloudflare 仪表板上点击几下\n * 步骤 5.做。开始发布\n * 奖金。更新到最新版本的微进纸\n * 💻 常见问题\n * 💪 贡献\n * 在本地运行微源\n * 🛡️ 许可证\n\n\n⭐️ 运作方式\n\n\n\n\n自 1990 年代以来，网络的很大一部分都是由提要驱动的。 人员（和机器人）将项目发布到源，其他人可以订阅该源以接收新内容。\n\n微提要使个人可以轻松地在 Cloudflare 上自行托管自己的提要，包括但不限于\n\n * 音频的播客提要\n * 帖子的博客提要\n * 类似 Instagram 的图片提要（例如，llamacorn.listennotes.com brand-assets.listennotes.com)\n * 类似 YouTube 的视频提要\n * 带有自定义链接（例如 wenbin.org)\n * 外部新闻文章 URL 的内容管理源\n * 提供更新和新闻报道的营销网站（例如 microfeed.org)\n * 带有 GUI 仪表板和公共 json 提要的无头 cms（例如，在 YAML 和 HTML 中带有 OpenAPI\n   规范的 microfeed.org/json)\n * 待售域名列表（例如，ListenHost.com...\n * 整本书的网站（例如，《孙子兵法》)\n * 更新日志网站（例如，changelog.listennotes.com)\n * ...\n\nmicrofeed 使用 Cloudflare Pages 托管和运行代码，R2 托管和提供媒体文件，D1 存储元数据，和 Zero\nTrust 提供对管理仪表板的登录信息。Cloudflare\n提供非常慷慨的免费使用配额，使其成为个人或小型企业使用的经济实惠的解决方案。虽然您仍然需要为域名付费，但在 Cloudflare 上托管微源基本上是免费的。\n\n使用微源，您可以发布各种内容，例如音频、视频、照片、文档、博客文章、 以及可自定义网站、RSS 提要和 JSON 提要的外部 URL。\n查看微进料的一些实际示例：\n\n * 网络提要：https://llamacorn.listennotes.com/\n * RSS 提要：https://llamacorn.listennotes.com/rss/\n * Json 提要：https://llamacorn.listennotes.com/json/\n\nMicrofeed 提供了一个简单而强大的管理仪表板，可以轻松地将项目添加到 Feed， 上传媒体文件，并自定义网页样式。如果您以前使用过\nWordPress，您会发现它很熟悉。\n\n[https://user-images.githubusercontent.com/1719237/209486588-00acefe0-dd51-4bfc-aed7-1f63850aa720.png]\n\n返回📚目录\n\n\n🚀 安装\n\n\n\n\n大致上，您将按照以下步骤将微源实例安装到 Cloudflare：\n\n 1. 将微源存储库分支到个人（或组织）GitHub 帐户。\n 2. 获取 Cloudflare API 令牌，并将其作为机密保存在分叉的 GitHub 存储库中。\n 3. 使用分支存储库中的预定义 GitHub Action，使用步骤 2 中的密钥将代码部署到 Cloudflare Pages。\n 4. 在 Cloudflare 的仪表板上单击几下即可设置自定义域并配置一些安全设置。\n 5. 做。开始发布！\n\n> 我们知道并不是每个人都喜欢阅读文档，因此我们尽可能简单地阅读文档 开始使用 Microfeed。但是，我们希望看到 Cloudflare 实现“使用\n> Cloudflare 登录”OAuth 功能， 这将允许几乎一键部署微进纸。与此同时，我们尝试进行设置过程 对于精通技术的用户来说，尽可能简单。\n\n\n先决条件\n\n\n\n\n * 拥有 Cloudflare 帐户。如果您还没有，可以在 Cloudflare.com 免费注册。\n * 拥有 GitHub 帐户。如果您没有，可以在 GitHub.com 免费注册。\n\n返回目录\n\n\n步骤 1.将微源存储库分叉到 GITHUB\n\n\n\n\n只需单击 https://github.com/microfeed/microfeed/fork 即可分叉存储库。\n\n将来可以选择修改分叉存储库中的代码，但可能不需要修改 完全触摸代码。只需分叉存储库并保持同步以备将来使用。\n\n返回📚目录\n\n\n步骤 2.在分叉的存储库上放一些秘密\n\n\n\n\n转到分叉存储库的设置 -> 密钥 ->作，并创建 5 个密钥（点击了解更多详细信息）。 有了这些密钥，您就可以使用 GitHub Actions\n将微源实例部署到 Cloudflare Pages。\n\nCLOUDFLARE_ACCOUNT_ID\n\n您可以从仪表板的 URL 获取您的 cloudflare 帐户 ID：\n\n登录 Cloudflare 帐户后，您将被重定向到如下 URL\n\nhttps://dash.cloudflare.com/[your-cloudflare-account-id-here]\n\n\n\n\n\nURL 的最后一部分是您的 cloudflare 帐户 ID。\n\n例如，如果您看到如下网址：\n\nhttps://dash.cloudflare.com/fff88980eeeeedcc3ffffd4f555f4999\n\n\n\n\n\n然后，您将CLOUDFLARE_ACCOUNT_ID设置为 fff88980eeeeedcc3ffffd4f555f4999：\n\n[https://user-images.githubusercontent.com/1719237/208216752-56f00f51-29cb-43ea-b720-75244719898d.png]\n\nCLOUDFLARE_API_TOKEN\n\n您需要在此处创建一个 API 令牌：https://dash.cloudflare.com/profile/api-tokens\n\n创建自定义令牌：\n\n[https://user-images.githubusercontent.com/1719237/205525627-14da54ae-1733-4db5-b65d-94f5ec48f360.png]\n\n我们需要 Cloudflare Pages 和 D1 的编辑权限：\n\n[https://user-images.githubusercontent.com/1719237/205525675-4c8a6bce-21a8-45e3-bf0c-28981f123da3.png]\n\n最后，将 API 令牌复制到此处：\n\n[https://user-images.githubusercontent.com/1719237/205525785-6fed8e49-7342-4b36-9d07-348e1c28cbcc.png]\n\nR2_ACCESS_KEY_ID和R2_SECRET_ACCESS_KEY\n\n转到您的 R2 仪表板页面。您可能需要先将信用卡放在那里。除非您的使用量超过非常慷慨的免费配额限制（即 10GB 存储 + 1000 万次读取/月 + 100\n万次写入/月），否则您无需付费。\n\n在此处创建 R2 API 令牌：\n\n[https://user-images.githubusercontent.com/1719237/205526381-cc11d4fe-b053-49d0-9072-de54db31b3b7.png]\n\n选择“管理员读写”权限并创建 API 令牌：\n\n[https://private-user-images.githubusercontent.com/1719237/259258288-1a90df29-5660-49d4-b66a-24873812492d.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NTk3MjgwMzUsIm5iZiI6MTc1OTcyNzczNSwicGF0aCI6Ii8xNzE5MjM3LzI1OTI1ODI4OC0xYTkwZGYyOS01NjYwLTQ5ZDQtYjY2YS0yNDg3MzgxMjQ5MmQucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MTAwNiUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTEwMDZUMDUxNTM1WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MWRmYThiODYzMGI0NWFlY2JhMjg5OTVlY2IyN2VjOTFlNDRkZWU1YTg1Y2FmMDc1OWViODRlZTgyYmUwNWM0YSZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.MEtwqpPLYlZrm0H9uKJZPlXYAZLbWY1yj_p8wFv8W10]\n\n复制R2_ACCESS_KEY_ID的访问密钥\nID，复制R2_SECRET_ACCESS_KEY的密钥[https://user-images.githubusercontent.com/1719237/205526582-92f440ac-21c4-46d9-a065-cfc1937391c8.png]\n\nCLOUDFLARE_PROJECT_NAME\n\n合法的项目名称应包含以下字符：[a-z]、[A-Z]、[0-9] 和 -\n\n我们建议使用您将用于此项目的自定义域名，并将点 （.） 替换为短划线 （-）\n\n例如，如果您使用 photos.mycustomdomain.com，则项目名称应为 photos-mycustomdomain-com\n\n注意：请勿在 [a-z]、[A-Z]、[0-9] 和 - 之外使用下划线 （_）、空格 （ ） 和其他字符。或者 Cloudflare Pages\n不允许您创建项目。\n\n总共需要为 GitHub Actions 添加 5 个机密：\n\n[https://user-images.githubusercontent.com/1719237/205524410-268abf92-af61-467a-8883-78b8d4de3c56.png]\n\n返回📚目录\n\n\n步骤 3.运行 GITHUB ACTION 以部署代码\n\n\n\n\n转到 Actions -> Deploy to Cloudflare Pages 并运行 Workflow\n\n[https://user-images.githubusercontent.com/1719237/205526856-05ea0ff4-703a-4d08-bc7f-4ae2dfc07cfe.png]\n\n如果看到绿色复选标记，则部署成功。您可以在 Cloudflare 仪表板中看到一个 Pages 项目：\n\n[https://user-images.githubusercontent.com/1719237/205527141-277620dd-586b-42dd-be97-edb7875d0705.png]\n\n您可以通过 ${CLOUDFLARE_PROJECT_NAME}.pages.dev\n访问该站点，例如 https://microfeed-org.pages.dev/\n\n返回📚目录\n\n\n步骤 4.在 CLOUDFLARE 仪表板上点击几下\n\n\n\n\n要管理您的微源实例，您将使用 ${CLOUDFLARE_PROJECT_NAME}.pages.dev/admin\n的管理仪表板，例如 https://microfeed-org.pages.dev/admin/（管理仪表板需要受 Cloudflare Zero Trust\n保护）。\n\n首次访问管理仪表板时，您将按照清单完成设置过程：\n\n[https://user-images.githubusercontent.com/1719237/208216864-38a65086-77ef-4595-bc05-c87be2676e6d.png]\n\n返回📚目录\n\n\n步骤 5.做。开始发布\n\n\n\n\n完成设置过程后，您的微馈送实例就可以使用了。 您可以从管理仪表板添加、更新或删除项目。\n\n您还可以在设置/自定义代码中通过编辑原始 HTML 和 CSS 来自定义网站的外观：\n\n[https://user-images.githubusercontent.com/1719237/210062910-e56135f6-557e-419e-a00d-b25dd391c93d.png]\n\nHTML 代码使用 mustache.js 作为模板语言，您可以在其中访问 Feed Json 或 Item Json\n中的变量。例如，在我们的营销网站 microfeed.org 的主页 （Feed Web） 上，我们使用 microfeed.org/json/ 的 html\n代码中的变量，而在商品的页面 （Item Web） 上，我们使用 ${item_url}/json 中的变量。\n\n通过轻松访问微源实例的 json 数据（即 Feed Json 和 Item Json），您可以将其用作无头 CMS 并构建自己的客户端应用程序来显示内容。\n\n返回📚目录\n\n\n奖金。更新到最新版本的微进纸\n\n\n\n\n我们将继续在此微源存储库中添加新功能并修复错误。 您可能希望使用新代码更新分叉存储库。\n\n首先，在分叉的存储库中同步代码：\n\n[https://user-images.githubusercontent.com/1719237/209483973-c82e7808-0d21-4aad-ac2d-c4e80da691bc.png]\n\n然后转到 Actions -> Deploy to Cloudflare Pages 并运行 Workflow 以部署新代码。\n\n返回📚目录\n\n\n💻 常见问题\n\n\n\n\n如何跟踪播客/视频/图像下载？\n\n要使用微提要跟踪播客、视频或图像下载，您可以使用跟踪 URL 功能。 这允许您为媒体文件设置第三方跟踪 URL，例如 OP3、Podtrac 提供的\nURL...\n\n要设置跟踪 URL，您需要转到设置/跟踪\nURL：[https://user-images.githubusercontent.com/1719237/210665674-39f9b0a9-1f28-4608-b0cd-c67b8a5c87ec.png]\n\n从那里，您可以添加要使用的第三方跟踪 URL。microfeed 会自动将这些 URL 添加到媒体文件的 URL 前面，以便您跟踪下载统计信息。\n\n这是播客行业的常见做法，可以成为监控内容表现并了解受众如何消费内容的有用方法。\n\n为什么选择 Cloudflare？相信一家营利性公司不是很危险吗？\n\n许多个人和组织信任并使用 Cloudflare 的服务，因为它在提供可靠和有效的服务方面享有盛誉。 我们（Listen Notes）多年来一直在使用\nCloudflare。\n\n在像 Cloudflare 这样的一站式平台上管理所有事情非常方便（例如 DNS、缓存、防火墙、运行代码、CDN、无需信任的登录......\n\n微进纸仍处于开放 alpha 阶段。Cloudflare 是我们支持的第一个平台。 我们可能会考虑支持其他无服务器平台，以便您可以在需要时轻松迁移离开。\n\n如果 Cloudflare 取消了我的 microfeed 实例的平台怎么办？\n\n请务必仔细查看您使用的任何服务（包括 Cloudflare）的服务条款。 如果您违反服务条款，服务可能会采取行动，例如将您的实例去平台化。\n\n为了防止被去平台化的可能性，最好定期从 Cloudflare 备份您的数据。 这将允许您恢复内容，并在必要时将它们迁移到其他平台。\n使用您自己的自定义域也是一个好主意，因为这将使您能够更好地控制您的内容，并在需要时更轻松地将数据移动到不同的平台。\n\n为什么要使用微进纸？\n\n如果您已经在使用 Cloudflare 并且对其服务感到满意，那么使用 microfeed 可能是您的不错选择。\n\n如果您不想管理自己的服务器，微源可能是一个方便的替代方案，可以让您利用 Cloudflare 的基础设施和安全功能。\n\n如果您不想为服务器付费，microfeed 可能是一种经济高效的解决方案，因为 Cloudflare 提供了慷慨的免费使用配额。\n\n如果您正在寻找新的东西并且有兴趣探索不同的选择，微馈送可能是一个不错的选择。在使用任何服务之前仔细评估它总是一个好主意，以确保它满足您的需求并且非常适合您的用例。\n\n如何从 microfeed / Cloudflare 下载/备份数据？\n\nmicrofeed 将数据存储在 Cloudflare D1 和 R2 中。因此，您将下载两个内容来备份您的微源数据：\n\n * 来自 Cloudflare D1 的 sqlite 数据库，包括所有元数据。\n * 来自 Cloudflare R2 的媒体文件，包括音频、图像、视频......\n\n如何从 D1 下载 sqlite 数据库？\n\n您可以使用命令行工具查找 sqlite 数据库文件并下载备份：wrangler\n\nhttps://developers.cloudflare.com/workers/wrangler/commands/#d1\n\n如何从 R2 下载媒体文件？\n\n截至 2023 年 2 月 16 日，Cloudflare 尚未提供从 R2 存储桶批量下载所有文件的工具。\n\n您可能需要编写脚本以使用与 S3 兼容的 API 从特定 R2 存储桶中获取所有对象。\n\n返回📚目录\n\n\n💪 贡献\n\n\n\n\n我们欢迎对 microfeed\n做出贡献！如果你对新功能有想法或发现错误，请在存储库中打开一个问题。如果你想提交修复或新功能，请创建一个拉取请求，其中包含你的更改的详细描述。\n\n\n在本地运行微源\n\n\n\n\n先决条件：节点/npm、yarn 和 wrangler\n\n首先，在 microfeed 的根目录（与此 README.md 文件同一级别）创建一个 .vars.toml 文件，并将 5 个密钥放入 .vars.toml\n文件中（类似于步骤 2。将一些密钥放在你的分叉存储库中）：\n\n# .vars.toml\nCLOUDFLARE_PROJECT_NAME = \"your-project-org\"\nCLOUDFLARE_ACCOUNT_ID = \"account id\"\nCLOUDFLARE_API_TOKEN = 'api token'\nR2_ACCESS_KEY_ID = \"access key\"\nR2_SECRET_ACCESS_KEY = \"secret key\"\n\nR2_PUBLIC_BUCKET = \"your-r2-bucket-name\"\n\n\n\n\n\n其次，运行本地开发服务器：\n\nyarn dev\n\n\n\n\n\n您应该能够通过 http://127.0.0.1:8788/ 访问本地微馈送实例。\n\nyarn dev 是如何工作的？本质上，它同时运行两个进程：和 。该进程启动用于客户端 JavaScript 代码的 webpack\nDevServer，同时启动 Wrangler 来提供 Pages（边缘）代码。yarn dev:clientyarn dev:edgeyarn\ndev:clientyarn dev:edge\n\n返回📚目录\n\n\n🛡️ 许可证\n\n\n\n\nmicrofeed 根据 AGPL-3.0 许可证获得许可。有关更多信息，请参阅 LICENSE 文件。\n\n返回📚目录\n\n\n大约\n\nCloudflare 上自托管的轻量级 CMS，用于播客、博客、照片、视频、文档和精选 URL。\n\n\n\n\nwww.microfeed.org/\n\n\n主题\n\nCMS系统 无服务器 Cloudflare 云耀斑页面 Cloudflare-R2 的 Cloudflare-零信任 Cloudflare-D1 播客主持人\n\n\n资源\n\n\n\n\n自述文件\n\n\n许可证\n\n\n\n\n\n\n\nAGPL-3.0 许可证\n\n\n\n\n\n\n\n\n\n\n 活动\n\n\n\n\n 自定义属性\n\n\n星星\n\n\n\n\n\n\n\n 3.8k 星\n\n\n观察家\n\n\n\n\n\n\n\n 26 观看\n\n\n叉\n\n\n\n\n\n\n\n 1.3k 叉子\n\n报告存储库\n\n\n释放6\n\n\n\n\n0.1.5版\n\n最近的\n\non Mar 15\n\n+ 5 个版本\n\n\n贡献\n\n\n8\n\n * [https://avatars.githubusercontent.com/u/1719237?s=64&amp;v=4]\n * [https://avatars.githubusercontent.com/u/19314952?s=64&amp;v=4]\n * [https://avatars.githubusercontent.com/u/700853?s=64&amp;v=4]\n * [https://avatars.githubusercontent.com/u/1162128?s=64&amp;v=4]\n * [https://avatars.githubusercontent.com/u/25657798?s=64&amp;v=4]\n * [https://avatars.githubusercontent.com/u/13221583?s=64&amp;v=4]\n * [https://avatars.githubusercontent.com/u/76237496?s=64&amp;v=4]\n * [https://avatars.githubusercontent.com/u/101132508?s=64&amp;v=4]\n\n\n语言\n\n\n\n\n * \n   \n * JavaScript的\n * 80.6%\n *  \n * [HTML全文]\n * 17.9%\n *  \n * CSS系统\n * 1.3%\n *  \n * 壳\n * 0.2%\n\n\nFOOTER\n\n\n\n\n© 2025 GitHub, Inc.\n\n\nFOOTER NAVIGATION\n\n * Terms\n * Privacy\n * Security\n * Status\n * Community\n * Docs\n * Contact\n * Manage cookies\n * Do not share my personal information","date_published":"2025-10-06T08:43:43.207Z","_microfeed":{"web_url":"https://mf-drktravis-dpdns-org.pages.dev/i/microfeed--ShBwcUhU8T/","json_url":"https://mf-drktravis-dpdns-org.pages.dev/i/-ShBwcUhU8T/json/","rss_url":"https://mf-drktravis-dpdns-org.pages.dev/i/-ShBwcUhU8T/rss/","guid":"-ShBwcUhU8T","status":"published","itunes:episodeType":"full","date_published_short":"Mon Oct 06 2025","date_published_ms":1759740223207}},{"id":"7t9pQxnUNtL","title":"Hello World","url":"https://mf-drktravis-dpdns-org.pages.dev/i/hello-worl-7t9pQxnUNtL/","content_html":"<p>example desciption</p>","content_text":"example desciption","image":"https://mf-db.drktravis.dpdns.org/mf-drktravis-dpdns-org/production/images/item-03f38e6214c0705c8badf7d5f44b13cf.png","date_published":"2025-10-06T08:38:03.973Z","_microfeed":{"web_url":"https://mf-drktravis-dpdns-org.pages.dev/i/hello-world-7t9pQxnUNtL/","json_url":"https://mf-drktravis-dpdns-org.pages.dev/i/7t9pQxnUNtL/json/","rss_url":"https://mf-drktravis-dpdns-org.pages.dev/i/7t9pQxnUNtL/rss/","guid":"7t9pQxnUNtL","status":"published","itunes:episodeType":"full","date_published_short":"Mon Oct 06 2025","date_published_ms":1759739883973}},{"id":"ma7qaoDEzio","title":"untitled","content_html":"\n\n\n#### adv\n\n| [wx.adv.AnimationCtrl](https://docs.wxpython.org/wx.adv.AnimationCtrl.html)           | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.adv.animationctrl.png)      | [wx.adv.BitmapComboBox](https://docs.wxpython.org/wx.adv.BitmapComboBox.html)       | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.adv.bitmapcombobox.png)    |\n| ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |\n| [wx.adv.CalendarCtrl](https://docs.wxpython.org/wx.adv.CalendarCtrl.html)             | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.adv.calendarctrl.png)       | [wx.adv.CommandLinkButton](https://docs.wxpython.org/wx.adv.CommandLinkButton.html) | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.adv.commandlinkbutton.png) |\n| [wx.adv.DatePickerCtrl](https://docs.wxpython.org/wx.adv.DatePickerCtrl.html)         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.adv.datepickerctrl.png)     | [wx.adv.HyperlinkCtrl](https://docs.wxpython.org/wx.adv.HyperlinkCtrl.html)         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.adv.hyperlinkctrl.png)     |\n| [wx.adv.OwnerDrawnComboBox](https://docs.wxpython.org/wx.adv.OwnerDrawnComboBox.html) | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.adv.ownerdrawncombobox.png) | [wx.adv.RichToolTip](https://docs.wxpython.org/wx.adv.RichToolTip.html)             | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.adv.richtooltip.png)       |\n| [wx.adv.TimePickerCtrl](https://docs.wxpython.org/wx.adv.TimePickerCtrl.html)         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.adv.timepickerctrl.png)     | [wx.aui.AuiMDIParentFrame](https://docs.wxpython.org/wx.aui.AuiMDIParentFrame.html) | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.aui.auimdiparentframe.png) |\n\n#### normal\n\n\n| [wx.Frame](https://docs.wxpython.org/wx.Frame.html)                                 | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.frame.png)                 | [wx.Dialog](https://docs.wxpython.org/wx.Dialog.html)                                       | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.dialog.png)                    |\n| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |\n| [wx.MiniFrame](https://docs.wxpython.org/wx.MiniFrame.html)                         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.miniframe.png)             |                                                                                             |                                                                                                       |\n| [wx.StaticText](https://docs.wxpython.org/wx.StaticText.html)                       | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.statictext.png)            | [wx.TextCtrl](https://docs.wxpython.org/wx.TextCtrl.html)                                   | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.textctrl.png)                  |\n| [wx.Button](https://docs.wxpython.org/wx.Button.html)                               | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.button.png)                | [wx.BitmapButton](https://docs.wxpython.org/wx.BitmapButton.html)                           | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.bitmapbutton.png)              |\n| [wx.ToggleButton](https://docs.wxpython.org/wx.ToggleButton.html)                   | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.togglebutton.png)          |                                                                                             |                                                                                                       |\n| [wx.CheckBox](https://docs.wxpython.org/wx.CheckBox.html)                           | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.checkbox.png)              | [wx.CheckListBox](https://docs.wxpython.org/wx.CheckListBox.html)                           | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.checklistbox.png)              |\n| [wx.Choice](https://docs.wxpython.org/wx.Choice.html)                               | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.choice.png)                | [wx.Choicebook](https://docs.wxpython.org/wx.Choicebook.html)                               | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.choicebook.png)                |\n| [wx.CollapsiblePane](https://docs.wxpython.org/wx.CollapsiblePane.html)             | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.collapsiblepane.png)       | [wx.ColourPickerCtrl](https://docs.wxpython.org/wx.ColourPickerCtrl.html)                   | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.colourpickerctrl.png)          |\n| [wx.RadioButton](https://docs.wxpython.org/wx.RadioButton.html)                     | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.radiobutton.png)           | [wx.RadioBox](https://docs.wxpython.org/wx.RadioBox.html)                                   | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.radiobox.png)                  |\n| [wx.ComboBox](https://docs.wxpython.org/wx.ComboBox.html)                           | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.combobox.png)              | [wx.ComboCtrl](https://docs.wxpython.org/wx.ComboCtrl.html)                                 | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.comboctrl.png)                 |\n| [wx.dataview.DataViewCtrl](https://docs.wxpython.org/wx.dataview.DataViewCtrl.html) | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.dataview.dataviewctrl.png) | [wx.dataview.DataViewTreeCtrl](https://docs.wxpython.org/wx.dataview.DataViewTreeCtrl.html) | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.dataview.dataviewtreectrl.png) |\n| [wx.DirPickerCtrl](https://docs.wxpython.org/wx.DirPickerCtrl.html)                 | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.dirpickerctrl.png)         | [wx.FileCtrl](https://docs.wxpython.org/wx.FileCtrl.html)                                   | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.filectrl.png)                  |\n| [wx.FilePickerCtrl](https://docs.wxpython.org/wx.FilePickerCtrl.html)               | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.filepickerctrl.png)        | [wx.FontPickerCtrl](https://docs.wxpython.org/wx.FontPickerCtrl.html)                       | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.fontpickerctrl.png)            |\n| [wx.Gauge](https://docs.wxpython.org/wx.Gauge.html)                                 | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.gauge.png)                 |                                                                                             |                                                                                                       |\n| [wx.GenericDirCtrl](https://docs.wxpython.org/wx.GenericDirCtrl.html)               | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.genericdirctrl.png)        |                                                                                             |                                                                                                       |\n| [wx.Listbook](https://docs.wxpython.org/wx.Listbook.html)                           | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.listbook.png)              | [wx.ListBox](https://docs.wxpython.org/wx.ListBox.html)                                     | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.listbox.png)                   |\n| [wx.ListCtrl](https://docs.wxpython.org/wx.ListCtrl.html)                           | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.listctrl.png)              | [wx.ListView](https://docs.wxpython.org/wx.ListView.html)                                   | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.listview.png)                  |\n| [wx.Notebook](https://docs.wxpython.org/wx.Notebook.html)                           | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.notebook.png)              |                                                                                             |                                                                                                       |\n| [wx.ScrollBar](https://docs.wxpython.org/wx.ScrollBar.html)                         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.scrollbar.png)             |                                                                                             |                                                                                                       |\n| [wx.SearchCtrl](https://docs.wxpython.org/wx.SearchCtrl.html)                       | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.searchctrl.png)            |                                                                                             |                                                                                                       |\n| [wx.Slider](https://docs.wxpython.org/wx.Slider.html)                               | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.slider.png)                |                                                                                             |                                                                                                       |\n| [wx.SpinButton](https://docs.wxpython.org/wx.SpinButton.html)                       | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.spinbutton.png)            |                                                                                             |                                                                                                       |\n| [wx.SpinCtrl](https://docs.wxpython.org/wx.SpinCtrl.html)                           | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.spinctrl.png)              | [wx.SpinCtrlDouble](https://docs.wxpython.org/wx.SpinCtrlDouble.html)                       | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.spinctrldouble.png)            |\n| [wx.StaticBitmap](https://docs.wxpython.org/wx.StaticBitmap.html)                   | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.staticbitmap.png)          |                                                                                             |                                                                                                       |\n| [wx.StaticBox](https://docs.wxpython.org/wx.StaticBox.html)                         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.staticbox.png)             |                                                                                             |                                                                                                       |\n| [wx.TreeCtrl](https://docs.wxpython.org/wx.TreeCtrl.html)                           | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.treectrl.png)              |                                                                                             |                                                                                                       |\n\n#### lib\n\n\n| [wx.lib.agw.advancedsplash.AdvancedSplash](https://docs.wxpython.org/wx.lib.agw.advancedsplash.AdvancedSplash.html)                         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.advancedsplash.advancedsplash.png)             |                                                                                                                                                                  |     |\n| ------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- |\n| [wx.lib.agw.aquabutton.AquaButton](https://docs.wxpython.org/wx.lib.agw.aquabutton.AquaButton.html)                                         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.aquabutton.aquabutton.png)                     |                                                                                                                                                                  |     |\n| [wx.lib.agw.aui.auibar.AuiToolBar](https://docs.wxpython.org/wx.lib.agw.aui.auibar.AuiToolBar.html)                                         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.aui.auibar.auitoolbar.png)                     |                                                                                                                                                                  |     |\n| [wx.lib.agw.aui.auibook.AuiNotebook](https://docs.wxpython.org/wx.lib.agw.aui.auibook.AuiNotebook.html)                                     | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.aui.auibook.auinotebook.png)                   |                                                                                                                                                                  |     |\n| [wx.lib.agw.aui.framemanager.AuiManager](https://docs.wxpython.org/wx.lib.agw.aui.framemanager.AuiManager.html)                             | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.aui.framemanager.auimanager.png)               |                                                                                                                                                                  |     |\n| [wx.lib.agw.balloontip.BalloonTip](https://docs.wxpython.org/wx.lib.agw.balloontip.BalloonTip.html)                                         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.balloontip.balloontip.png)                     |                                                                                                                                                                  |     |\n| [wx.lib.agw.buttonpanel.ButtonPanel](https://docs.wxpython.org/wx.lib.agw.buttonpanel.ButtonPanel.html)                                     | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.buttonpanel.buttonpanel.png)                   |                                                                                                                                                                  |     |\n| [wx.lib.agw.cubecolourdialog.CubeColourDialog](https://docs.wxpython.org/wx.lib.agw.cubecolourdialog.CubeColourDialog.html)                 | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.cubecolourdialog.cubecolourdialog.png)         |                                                                                                                                                                  |     |\n| [wx.lib.agw.customtreectrl.CustomTreeCtrl](https://docs.wxpython.org/wx.lib.agw.customtreectrl.CustomTreeCtrl.html)                         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.customtreectrl.customtreectrl.png)             |                                                                                                                                                                  |     |\n| [wx.lib.agw.flatmenu.FlatMenuBar](https://docs.wxpython.org/wx.lib.agw.flatmenu.FlatMenuBar.html)                                           | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.flatmenu.flatmenubar.png)                      |                                                                                                                                                                  |     |\n| [wx.lib.agw.flatnotebook.FlatNotebook](https://docs.wxpython.org/wx.lib.agw.flatnotebook.FlatNotebook.html)                                 | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.flatnotebook.flatnotebook.png)                 |                                                                                                                                                                  |     |\n| [wx.lib.agw.floatspin.FloatSpin](https://docs.wxpython.org/wx.lib.agw.floatspin.FloatSpin.html)                                             | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.floatspin.floatspin.png)                       |                                                                                                                                                                  |     |\n| [wx.lib.agw.fmcustomizedlg.FMCustomizeDlg](https://docs.wxpython.org/wx.lib.agw.fmcustomizedlg.FMCustomizeDlg.html)                         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.fmcustomizedlg.fmcustomizedlg.png)             |                                                                                                                                                                  |     |\n| [wx.lib.agw.foldpanelbar.FoldPanelBar](https://docs.wxpython.org/wx.lib.agw.foldpanelbar.FoldPanelBar.html)                                 | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.foldpanelbar.foldpanelbar.png)                 |                                                                                                                                                                  |     |\n| [wx.lib.agw.fourwaysplitter.FourWaySplitter](https://docs.wxpython.org/wx.lib.agw.fourwaysplitter.FourWaySplitter.html)                     | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.fourwaysplitter.fourwaysplitter.png)           |                                                                                                                                                                  |     |\n| [wx.lib.agw.genericmessagedialog.GenericMessageDialog](https://docs.wxpython.org/wx.lib.agw.genericmessagedialog.GenericMessageDialog.html) | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.genericmessagedialog.genericmessagedialog.png) |                                                                                                                                                                  |     |\n| [wx.lib.agw.gradientbutton.GradientButton](https://docs.wxpython.org/wx.lib.agw.gradientbutton.GradientButton.html)                         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.gradientbutton.gradientbutton.png)             |                                                                                                                                                                  |     |\n| [wx.lib.agw.hyperlink.HyperLinkCtrl](https://docs.wxpython.org/wx.lib.agw.hyperlink.HyperLinkCtrl.html)                                     | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.hyperlink.hyperlinkctrl.png)                   |                                                                                                                                                                  |     |\n| [wx.lib.agw.hypertreelist.HyperTreeList](https://docs.wxpython.org/wx.lib.agw.hypertreelist.HyperTreeList.html)                             | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.hypertreelist.hypertreelist.png)               | ![20250721001403.png](https://raw.githubusercontent.com/liangxiongsl/obsidian-public/main/image/20250721001403.png?sha=1565331a7b5f5c35ba6dcb605f03f927107aea28) |     |\n| [wx.lib.agw.infobar.InfoBar](https://docs.wxpython.org/wx.lib.agw.infobar.InfoBar.html)                                                     | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.infobar.infobar.png)                           |                                                                                                                                                                  |     |\n| [wx.lib.agw.knobctrl.KnobCtrl](https://docs.wxpython.org/wx.lib.agw.knobctrl.KnobCtrl.html)                                                 | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.knobctrl.knobctrl.png)                         |                                                                                                                                                                  |     |\n| [wx.lib.agw.labelbook.FlatImageBook](https://docs.wxpython.org/wx.lib.agw.labelbook.FlatImageBook.html)                                     | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.labelbook.flatimagebook.png)                   |                                                                                                                                                                  |     |\n| [wx.lib.agw.labelbook.LabelBook](https://docs.wxpython.org/wx.lib.agw.labelbook.LabelBook.html)                                             | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.labelbook.labelbook.png)                       |                                                                                                                                                                  |     |\n| [wx.lib.agw.multidirdialog.MultiDirDialog](https://docs.wxpython.org/wx.lib.agw.multidirdialog.MultiDirDialog.html)                         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.multidirdialog.multidirdialog.png)             |                                                                                                                                                                  |     |\n| [wx.lib.agw.peakmeter.PeakMeterCtrl](https://docs.wxpython.org/wx.lib.agw.peakmeter.PeakMeterCtrl.html)                                     | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.peakmeter.peakmeterctrl.png)                   |                                                                                                                                                                  |     |\n| [wx.lib.agw.piectrl.PieCtrl](https://docs.wxpython.org/wx.lib.agw.piectrl.PieCtrl.html)                                                     | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.piectrl.piectrl.png)                           |                                                                                                                                                                  |     |\n| [wx.lib.agw.piectrl.ProgressPie](https://docs.wxpython.org/wx.lib.agw.piectrl.ProgressPie.html)                                             | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.piectrl.progresspie.png)                       |                                                                                                                                                                  |     |\n| [wx.lib.agw.pybusyinfo.PyBusyInfo](https://docs.wxpython.org/wx.lib.agw.pybusyinfo.PyBusyInfo.html)                                         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.pybusyinfo.pybusyinfo.png)                     |                                                                                                                                                                  |     |\n| [wx.lib.agw.pycollapsiblepane.PyCollapsiblePane](https://docs.wxpython.org/wx.lib.agw.pycollapsiblepane.PyCollapsiblePane.html)             | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.pycollapsiblepane.pycollapsiblepane.png)       |                                                                                                                                                                  |     |\n| [wx.lib.agw.pygauge.PyGauge](https://docs.wxpython.org/wx.lib.agw.pygauge.PyGauge.html)                                                     | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.pygauge.pygauge.png)                           |                                                                                                                                                                  |     |\n| [wx.lib.agw.pyprogress.PyProgress](https://docs.wxpython.org/wx.lib.agw.pyprogress.PyProgress.html)                                         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.pyprogress.pyprogress.png)                     |                                                                                                                                                                  |     |\n| [wx.lib.agw.ribbon.bar.RibbonBar](https://docs.wxpython.org/wx.lib.agw.ribbon.bar.RibbonBar.html)                                           | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.ribbon.bar.ribbonbar.png)                      |                                                                                                                                                                  |     |\n| [wx.lib.agw.ribbon.buttonbar.RibbonButtonBar](https://docs.wxpython.org/wx.lib.agw.ribbon.buttonbar.RibbonButtonBar.html)                   | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.ribbon.buttonbar.ribbonbuttonbar.png)          |                                                                                                                                                                  |     |\n| [wx.lib.agw.ribbon.gallery.RibbonGallery](https://docs.wxpython.org/wx.lib.agw.ribbon.gallery.RibbonGallery.html)                           | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.ribbon.gallery.ribbongallery.png)              |                                                                                                                                                                  |     |\n| [wx.lib.agw.ribbon.page.RibbonPage](https://docs.wxpython.org/wx.lib.agw.ribbon.page.RibbonPage.html)                                       | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.ribbon.page.ribbonpage.png)                    |                                                                                                                                                                  |     |\n| [wx.lib.agw.ribbon.panel.RibbonPanel](https://docs.wxpython.org/wx.lib.agw.ribbon.panel.RibbonPanel.html)                                   | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.ribbon.panel.ribbonpanel.png)                  |                                                                                                                                                                  |     |\n| [wx.lib.agw.ribbon.toolbar.RibbonToolBar](https://docs.wxpython.org/wx.lib.agw.ribbon.toolbar.RibbonToolBar.html)                           | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.ribbon.toolbar.ribbontoolbar.png)              |                                                                                                                                                                  |     |\n| [wx.lib.agw.rulerctrl.RulerCtrl](https://docs.wxpython.org/wx.lib.agw.rulerctrl.RulerCtrl.html)                                             | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.rulerctrl.rulerctrl.png)                       |                                                                                                                                                                  |     |\n| [wx.lib.agw.shapedbutton.SBitmapButton](https://docs.wxpython.org/wx.lib.agw.shapedbutton.SBitmapButton.html)                               | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.shapedbutton.sbitmapbutton.png)                |                                                                                                                                                                  |     |\n| [wx.lib.agw.shapedbutton.SBitmapTextButton](https://docs.wxpython.org/wx.lib.agw.shapedbutton.SBitmapTextButton.html)                       | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.shapedbutton.sbitmaptextbutton.png)            |                                                                                                                                                                  |     |\n| [wx.lib.agw.shapedbutton.SBitmapTextToggleButton](https://docs.wxpython.org/wx.lib.agw.shapedbutton.SBitmapTextToggleButton.html)           | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.shapedbutton.sbitmaptexttogglebutton.png)      |                                                                                                                                                                  |     |\n| [wx.lib.agw.shapedbutton.SBitmapToggleButton](https://docs.wxpython.org/wx.lib.agw.shapedbutton.SBitmapToggleButton.html)                   | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.shapedbutton.sbitmaptogglebutton.png)          |                                                                                                                                                                  |     |\n| [wx.lib.agw.shortcuteditor.ShortcutEditor](https://docs.wxpython.org/wx.lib.agw.shortcuteditor.ShortcutEditor.html)                         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.shortcuteditor.shortcuteditor.png)             |                                                                                                                                                                  |     |\n| [wx.lib.agw.speedmeter.SpeedMeter](https://docs.wxpython.org/wx.lib.agw.speedmeter.SpeedMeter.html)                                         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.speedmeter.speedmeter.png)                     |                                                                                                                                                                  |     |\n| [wx.lib.agw.supertooltip.SuperToolTip](https://docs.wxpython.org/wx.lib.agw.supertooltip.SuperToolTip.html)                                 | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.supertooltip.supertooltip.png)                 |                                                                                                                                                                  |     |\n| [wx.lib.agw.thumbnailctrl.ThumbnailCtrl](https://docs.wxpython.org/wx.lib.agw.thumbnailctrl.ThumbnailCtrl.html)                             | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.thumbnailctrl.thumbnailctrl.png)               |                                                                                                                                                                  |     |\n| [wx.lib.agw.toasterbox.ToasterBox](https://docs.wxpython.org/wx.lib.agw.toasterbox.ToasterBox.html)                                         | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.toasterbox.toasterbox.png)                     |                                                                                                                                                                  |     |\n| [wx.lib.agw.ultimatelistctrl.UltimateListCtrl](https://docs.wxpython.org/wx.lib.agw.ultimatelistctrl.UltimateListCtrl.html)                 | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.ultimatelistctrl.ultimatelistctrl.png)         |                                                                                                                                                                  |     |\n| [wx.lib.agw.xlsgrid.XLSGrid](https://docs.wxpython.org/wx.lib.agw.xlsgrid.XLSGrid.html)                                                     | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.xlsgrid.xlsgrid.png)                           |                                                                                                                                                                  |     |\n| [wx.lib.agw.zoombar.ZoomBar](https://docs.wxpython.org/wx.lib.agw.zoombar.ZoomBar.html)                                                     | ![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.zoombar.zoombar.png)                           |                                                                                                                                                                  |     |\n\n","content_text":"#### adv |\n[wx.adv.AnimationCtrl](https://docs.wxpython.org/wx.adv.AnimationCtrl.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.adv.animationctrl.png)\n| [wx.adv.BitmapComboBox](https://docs.wxpython.org/wx.adv.BitmapComboBox.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.adv.bitmapcombobox.png)\n| |\n-------------------------------------------------------------------------------------\n|\n--------------------------------------------------------------------------------------------------\n|\n-----------------------------------------------------------------------------------\n|\n-------------------------------------------------------------------------------------------------\n| | [wx.adv.CalendarCtrl](https://docs.wxpython.org/wx.adv.CalendarCtrl.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.adv.calendarctrl.png)\n|\n[wx.adv.CommandLinkButton](https://docs.wxpython.org/wx.adv.CommandLinkButton.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.adv.commandlinkbutton.png)\n| |\n[wx.adv.DatePickerCtrl](https://docs.wxpython.org/wx.adv.DatePickerCtrl.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.adv.datepickerctrl.png)\n| [wx.adv.HyperlinkCtrl](https://docs.wxpython.org/wx.adv.HyperlinkCtrl.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.adv.hyperlinkctrl.png)\n| |\n[wx.adv.OwnerDrawnComboBox](https://docs.wxpython.org/wx.adv.OwnerDrawnComboBox.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.adv.ownerdrawncombobox.png)\n| [wx.adv.RichToolTip](https://docs.wxpython.org/wx.adv.RichToolTip.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.adv.richtooltip.png)\n| |\n[wx.adv.TimePickerCtrl](https://docs.wxpython.org/wx.adv.TimePickerCtrl.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.adv.timepickerctrl.png)\n|\n[wx.aui.AuiMDIParentFrame](https://docs.wxpython.org/wx.aui.AuiMDIParentFrame.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.aui.auimdiparentframe.png)\n| #### normal | [wx.Frame](https://docs.wxpython.org/wx.Frame.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.frame.png)\n| [wx.Dialog](https://docs.wxpython.org/wx.Dialog.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.dialog.png)\n| |\n-----------------------------------------------------------------------------------\n|\n-------------------------------------------------------------------------------------------------\n|\n-------------------------------------------------------------------------------------------\n|\n-----------------------------------------------------------------------------------------------------\n| | [wx.MiniFrame](https://docs.wxpython.org/wx.MiniFrame.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.miniframe.png)\n| | | | [wx.StaticText](https://docs.wxpython.org/wx.StaticText.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.statictext.png)\n| [wx.TextCtrl](https://docs.wxpython.org/wx.TextCtrl.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.textctrl.png)\n| | [wx.Button](https://docs.wxpython.org/wx.Button.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.button.png)\n| [wx.BitmapButton](https://docs.wxpython.org/wx.BitmapButton.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.bitmapbutton.png)\n| | [wx.ToggleButton](https://docs.wxpython.org/wx.ToggleButton.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.togglebutton.png)\n| | | | [wx.CheckBox](https://docs.wxpython.org/wx.CheckBox.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.checkbox.png)\n| [wx.CheckListBox](https://docs.wxpython.org/wx.CheckListBox.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.checklistbox.png)\n| | [wx.Choice](https://docs.wxpython.org/wx.Choice.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.choice.png)\n| [wx.Choicebook](https://docs.wxpython.org/wx.Choicebook.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.choicebook.png)\n| | [wx.CollapsiblePane](https://docs.wxpython.org/wx.CollapsiblePane.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.collapsiblepane.png)\n| [wx.ColourPickerCtrl](https://docs.wxpython.org/wx.ColourPickerCtrl.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.colourpickerctrl.png)\n| | [wx.RadioButton](https://docs.wxpython.org/wx.RadioButton.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.radiobutton.png)\n| [wx.RadioBox](https://docs.wxpython.org/wx.RadioBox.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.radiobox.png)\n| | [wx.ComboBox](https://docs.wxpython.org/wx.ComboBox.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.combobox.png)\n| [wx.ComboCtrl](https://docs.wxpython.org/wx.ComboCtrl.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.comboctrl.png)\n| |\n[wx.dataview.DataViewCtrl](https://docs.wxpython.org/wx.dataview.DataViewCtrl.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.dataview.dataviewctrl.png)\n|\n[wx.dataview.DataViewTreeCtrl](https://docs.wxpython.org/wx.dataview.DataViewTreeCtrl.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.dataview.dataviewtreectrl.png)\n| | [wx.DirPickerCtrl](https://docs.wxpython.org/wx.DirPickerCtrl.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.dirpickerctrl.png)\n| [wx.FileCtrl](https://docs.wxpython.org/wx.FileCtrl.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.filectrl.png)\n| | [wx.FilePickerCtrl](https://docs.wxpython.org/wx.FilePickerCtrl.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.filepickerctrl.png)\n| [wx.FontPickerCtrl](https://docs.wxpython.org/wx.FontPickerCtrl.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.fontpickerctrl.png)\n| | [wx.Gauge](https://docs.wxpython.org/wx.Gauge.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.gauge.png)\n| | | | [wx.GenericDirCtrl](https://docs.wxpython.org/wx.GenericDirCtrl.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.genericdirctrl.png)\n| | | | [wx.Listbook](https://docs.wxpython.org/wx.Listbook.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.listbook.png)\n| [wx.ListBox](https://docs.wxpython.org/wx.ListBox.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.listbox.png)\n| | [wx.ListCtrl](https://docs.wxpython.org/wx.ListCtrl.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.listctrl.png)\n| [wx.ListView](https://docs.wxpython.org/wx.ListView.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.listview.png)\n| | [wx.Notebook](https://docs.wxpython.org/wx.Notebook.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.notebook.png)\n| | | | [wx.ScrollBar](https://docs.wxpython.org/wx.ScrollBar.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.scrollbar.png)\n| | | | [wx.SearchCtrl](https://docs.wxpython.org/wx.SearchCtrl.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.searchctrl.png)\n| | | | [wx.Slider](https://docs.wxpython.org/wx.Slider.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.slider.png)\n| | | | [wx.SpinButton](https://docs.wxpython.org/wx.SpinButton.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.spinbutton.png)\n| | | | [wx.SpinCtrl](https://docs.wxpython.org/wx.SpinCtrl.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.spinctrl.png)\n| [wx.SpinCtrlDouble](https://docs.wxpython.org/wx.SpinCtrlDouble.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.spinctrldouble.png)\n| | [wx.StaticBitmap](https://docs.wxpython.org/wx.StaticBitmap.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.staticbitmap.png)\n| | | | [wx.StaticBox](https://docs.wxpython.org/wx.StaticBox.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.staticbox.png)\n| | | | [wx.TreeCtrl](https://docs.wxpython.org/wx.TreeCtrl.html) |\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmac/wx.treectrl.png)\n| | | #### lib |\n[wx.lib.agw.advancedsplash.AdvancedSplash](https://docs.wxpython.org/wx.lib.agw.advancedsplash.AdvancedSplash.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.advancedsplash.advancedsplash.png)\n| | | |\n-------------------------------------------------------------------------------------------------------------------------------------------\n|\n-----------------------------------------------------------------------------------------------------------------------------\n|\n----------------------------------------------------------------------------------------------------------------------------------------------------------------\n| --- | |\n[wx.lib.agw.aquabutton.AquaButton](https://docs.wxpython.org/wx.lib.agw.aquabutton.AquaButton.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.aquabutton.aquabutton.png)\n| | | |\n[wx.lib.agw.aui.auibar.AuiToolBar](https://docs.wxpython.org/wx.lib.agw.aui.auibar.AuiToolBar.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.aui.auibar.auitoolbar.png)\n| | | |\n[wx.lib.agw.aui.auibook.AuiNotebook](https://docs.wxpython.org/wx.lib.agw.aui.auibook.AuiNotebook.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.aui.auibook.auinotebook.png)\n| | | |\n[wx.lib.agw.aui.framemanager.AuiManager](https://docs.wxpython.org/wx.lib.agw.aui.framemanager.AuiManager.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.aui.framemanager.auimanager.png)\n| | | |\n[wx.lib.agw.balloontip.BalloonTip](https://docs.wxpython.org/wx.lib.agw.balloontip.BalloonTip.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.balloontip.balloontip.png)\n| | | |\n[wx.lib.agw.buttonpanel.ButtonPanel](https://docs.wxpython.org/wx.lib.agw.buttonpanel.ButtonPanel.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.buttonpanel.buttonpanel.png)\n| | | |\n[wx.lib.agw.cubecolourdialog.CubeColourDialog](https://docs.wxpython.org/wx.lib.agw.cubecolourdialog.CubeColourDialog.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.cubecolourdialog.cubecolourdialog.png)\n| | | |\n[wx.lib.agw.customtreectrl.CustomTreeCtrl](https://docs.wxpython.org/wx.lib.agw.customtreectrl.CustomTreeCtrl.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.customtreectrl.customtreectrl.png)\n| | | |\n[wx.lib.agw.flatmenu.FlatMenuBar](https://docs.wxpython.org/wx.lib.agw.flatmenu.FlatMenuBar.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.flatmenu.flatmenubar.png)\n| | | |\n[wx.lib.agw.flatnotebook.FlatNotebook](https://docs.wxpython.org/wx.lib.agw.flatnotebook.FlatNotebook.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.flatnotebook.flatnotebook.png)\n| | | |\n[wx.lib.agw.floatspin.FloatSpin](https://docs.wxpython.org/wx.lib.agw.floatspin.FloatSpin.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.floatspin.floatspin.png)\n| | | |\n[wx.lib.agw.fmcustomizedlg.FMCustomizeDlg](https://docs.wxpython.org/wx.lib.agw.fmcustomizedlg.FMCustomizeDlg.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.fmcustomizedlg.fmcustomizedlg.png)\n| | | |\n[wx.lib.agw.foldpanelbar.FoldPanelBar](https://docs.wxpython.org/wx.lib.agw.foldpanelbar.FoldPanelBar.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.foldpanelbar.foldpanelbar.png)\n| | | |\n[wx.lib.agw.fourwaysplitter.FourWaySplitter](https://docs.wxpython.org/wx.lib.agw.fourwaysplitter.FourWaySplitter.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.fourwaysplitter.fourwaysplitter.png)\n| | | |\n[wx.lib.agw.genericmessagedialog.GenericMessageDialog](https://docs.wxpython.org/wx.lib.agw.genericmessagedialog.GenericMessageDialog.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.genericmessagedialog.genericmessagedialog.png)\n| | | |\n[wx.lib.agw.gradientbutton.GradientButton](https://docs.wxpython.org/wx.lib.agw.gradientbutton.GradientButton.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.gradientbutton.gradientbutton.png)\n| | | |\n[wx.lib.agw.hyperlink.HyperLinkCtrl](https://docs.wxpython.org/wx.lib.agw.hyperlink.HyperLinkCtrl.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.hyperlink.hyperlinkctrl.png)\n| | | |\n[wx.lib.agw.hypertreelist.HyperTreeList](https://docs.wxpython.org/wx.lib.agw.hypertreelist.HyperTreeList.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.hypertreelist.hypertreelist.png)\n|\n![20250721001403.png](https://raw.githubusercontent.com/liangxiongsl/obsidian-public/main/image/20250721001403.png?sha=1565331a7b5f5c35ba6dcb605f03f927107aea28)\n| | |\n[wx.lib.agw.infobar.InfoBar](https://docs.wxpython.org/wx.lib.agw.infobar.InfoBar.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.infobar.infobar.png)\n| | | |\n[wx.lib.agw.knobctrl.KnobCtrl](https://docs.wxpython.org/wx.lib.agw.knobctrl.KnobCtrl.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.knobctrl.knobctrl.png)\n| | | |\n[wx.lib.agw.labelbook.FlatImageBook](https://docs.wxpython.org/wx.lib.agw.labelbook.FlatImageBook.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.labelbook.flatimagebook.png)\n| | | |\n[wx.lib.agw.labelbook.LabelBook](https://docs.wxpython.org/wx.lib.agw.labelbook.LabelBook.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.labelbook.labelbook.png)\n| | | |\n[wx.lib.agw.multidirdialog.MultiDirDialog](https://docs.wxpython.org/wx.lib.agw.multidirdialog.MultiDirDialog.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.multidirdialog.multidirdialog.png)\n| | | |\n[wx.lib.agw.peakmeter.PeakMeterCtrl](https://docs.wxpython.org/wx.lib.agw.peakmeter.PeakMeterCtrl.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.peakmeter.peakmeterctrl.png)\n| | | |\n[wx.lib.agw.piectrl.PieCtrl](https://docs.wxpython.org/wx.lib.agw.piectrl.PieCtrl.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.piectrl.piectrl.png)\n| | | |\n[wx.lib.agw.piectrl.ProgressPie](https://docs.wxpython.org/wx.lib.agw.piectrl.ProgressPie.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.piectrl.progresspie.png)\n| | | |\n[wx.lib.agw.pybusyinfo.PyBusyInfo](https://docs.wxpython.org/wx.lib.agw.pybusyinfo.PyBusyInfo.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.pybusyinfo.pybusyinfo.png)\n| | | |\n[wx.lib.agw.pycollapsiblepane.PyCollapsiblePane](https://docs.wxpython.org/wx.lib.agw.pycollapsiblepane.PyCollapsiblePane.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.pycollapsiblepane.pycollapsiblepane.png)\n| | | |\n[wx.lib.agw.pygauge.PyGauge](https://docs.wxpython.org/wx.lib.agw.pygauge.PyGauge.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.pygauge.pygauge.png)\n| | | |\n[wx.lib.agw.pyprogress.PyProgress](https://docs.wxpython.org/wx.lib.agw.pyprogress.PyProgress.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.pyprogress.pyprogress.png)\n| | | |\n[wx.lib.agw.ribbon.bar.RibbonBar](https://docs.wxpython.org/wx.lib.agw.ribbon.bar.RibbonBar.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.ribbon.bar.ribbonbar.png)\n| | | |\n[wx.lib.agw.ribbon.buttonbar.RibbonButtonBar](https://docs.wxpython.org/wx.lib.agw.ribbon.buttonbar.RibbonButtonBar.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.ribbon.buttonbar.ribbonbuttonbar.png)\n| | | |\n[wx.lib.agw.ribbon.gallery.RibbonGallery](https://docs.wxpython.org/wx.lib.agw.ribbon.gallery.RibbonGallery.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.ribbon.gallery.ribbongallery.png)\n| | | |\n[wx.lib.agw.ribbon.page.RibbonPage](https://docs.wxpython.org/wx.lib.agw.ribbon.page.RibbonPage.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.ribbon.page.ribbonpage.png)\n| | | |\n[wx.lib.agw.ribbon.panel.RibbonPanel](https://docs.wxpython.org/wx.lib.agw.ribbon.panel.RibbonPanel.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.ribbon.panel.ribbonpanel.png)\n| | | |\n[wx.lib.agw.ribbon.toolbar.RibbonToolBar](https://docs.wxpython.org/wx.lib.agw.ribbon.toolbar.RibbonToolBar.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.ribbon.toolbar.ribbontoolbar.png)\n| | | |\n[wx.lib.agw.rulerctrl.RulerCtrl](https://docs.wxpython.org/wx.lib.agw.rulerctrl.RulerCtrl.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.rulerctrl.rulerctrl.png)\n| | | |\n[wx.lib.agw.shapedbutton.SBitmapButton](https://docs.wxpython.org/wx.lib.agw.shapedbutton.SBitmapButton.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.shapedbutton.sbitmapbutton.png)\n| | | |\n[wx.lib.agw.shapedbutton.SBitmapTextButton](https://docs.wxpython.org/wx.lib.agw.shapedbutton.SBitmapTextButton.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.shapedbutton.sbitmaptextbutton.png)\n| | | |\n[wx.lib.agw.shapedbutton.SBitmapTextToggleButton](https://docs.wxpython.org/wx.lib.agw.shapedbutton.SBitmapTextToggleButton.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.shapedbutton.sbitmaptexttogglebutton.png)\n| | | |\n[wx.lib.agw.shapedbutton.SBitmapToggleButton](https://docs.wxpython.org/wx.lib.agw.shapedbutton.SBitmapToggleButton.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.shapedbutton.sbitmaptogglebutton.png)\n| | | |\n[wx.lib.agw.shortcuteditor.ShortcutEditor](https://docs.wxpython.org/wx.lib.agw.shortcuteditor.ShortcutEditor.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.shortcuteditor.shortcuteditor.png)\n| | | |\n[wx.lib.agw.speedmeter.SpeedMeter](https://docs.wxpython.org/wx.lib.agw.speedmeter.SpeedMeter.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.speedmeter.speedmeter.png)\n| | | |\n[wx.lib.agw.supertooltip.SuperToolTip](https://docs.wxpython.org/wx.lib.agw.supertooltip.SuperToolTip.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxgtk/wx.lib.agw.supertooltip.supertooltip.png)\n| | | |\n[wx.lib.agw.thumbnailctrl.ThumbnailCtrl](https://docs.wxpython.org/wx.lib.agw.thumbnailctrl.ThumbnailCtrl.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.thumbnailctrl.thumbnailctrl.png)\n| | | |\n[wx.lib.agw.toasterbox.ToasterBox](https://docs.wxpython.org/wx.lib.agw.toasterbox.ToasterBox.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.toasterbox.toasterbox.png)\n| | | |\n[wx.lib.agw.ultimatelistctrl.UltimateListCtrl](https://docs.wxpython.org/wx.lib.agw.ultimatelistctrl.UltimateListCtrl.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.ultimatelistctrl.ultimatelistctrl.png)\n| | | |\n[wx.lib.agw.xlsgrid.XLSGrid](https://docs.wxpython.org/wx.lib.agw.xlsgrid.XLSGrid.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.xlsgrid.xlsgrid.png)\n| | | |\n[wx.lib.agw.zoombar.ZoomBar](https://docs.wxpython.org/wx.lib.agw.zoombar.ZoomBar.html)\n|\n![](https://docs.wxpython.org/_static/images/widgets/fullsize/wxmsw/wx.lib.agw.zoombar.zoombar.png)\n| | |","date_published":"2025-10-06T08:35:33.826Z","_microfeed":{"web_url":"https://mf-drktravis-dpdns-org.pages.dev/i/ma7qaoDEzio/","json_url":"https://mf-drktravis-dpdns-org.pages.dev/i/ma7qaoDEzio/json/","rss_url":"https://mf-drktravis-dpdns-org.pages.dev/i/ma7qaoDEzio/rss/","guid":"ma7qaoDEzio","status":"published","itunes:episodeType":"full","date_published_short":"Mon Oct 06 2025","date_published_ms":1759739733826}}],"_microfeed":{"microfeed_version":"0.1.5","base_url":"https://mf-drktravis-dpdns-org.pages.dev","categories":[],"subscribe_methods":[{"name":"RSS","type":"rss","url":"https://mf-drktravis-dpdns-org.pages.dev/rss/","image":"https://mf-drktravis-dpdns-org.pages.dev/assets/brands/subscribe/rss.png","enabled":true,"editable":false,"id":"Agja4bk5F3s"},{"name":"JSON","type":"json","url":"https://mf-drktravis-dpdns-org.pages.dev/json/","image":"https://mf-drktravis-dpdns-org.pages.dev/assets/brands/subscribe/json.png","enabled":true,"editable":false,"id":"jrJEKKcTrVn"}],"description_text":"a test channel","copyright":"©2025","itunes:type":"episodic","items_sort_order":"newest_first"}}