Project Icon

feedi

可定制的极简Web订阅阅读器

feedi是一款Web订阅阅读器,具有类似Mastodon的极简界面。支持本地和自托管部署,兼容Mastodon主页和通知流。提供移动友好UI和PWA功能,可自定义解析Reddit、Github和Goodreads等源。其特色包括智能订阅排序、本地文章阅读和Kindle设备支持,满足个性化阅读需求。

feedi

feedi 是一个网页订阅阅读器,具有类似 Mastodon 或 Twitter 信息流的极简界面。

特点:

  • 简易的本地和自托管环境设置。
  • 支持 Mastodon 主页和通知流。
  • 移动设备友好的用户界面。
  • 可作为渐进式网络应用安装。
  • 为 Reddit、Github 和 Goodreads 提供自定义解析器。
  • 可定制的 RSS 解析器和临时网页抓取器。
  • 智能订阅源排序选项(突出显示不常更新的来源,自动标记为已读)。
  • 使用 Mozilla 的阅读模式进行本地文章阅读和预览。
  • 支持发送到 Kindle 设备。


关于此项目开发的背景,请参阅这篇博客文章

文档

安装

feedi 需要 Python 3.9 或更高版本。如果你还没有安装,可以考虑使用 pyenvasdf

在本地环境安装 feedi:

git clone https://github.com/facundoolano/feedi.git
cd feedi
make

然后,运行应用:

make run

应用将在 http://localhost:9988/ 可用。

或者,参考使用 Docker 运行非本地设置的说明。

基本用法

添加来源

默认情况下,您的信息流为空。您可以通过多种方式加载内容:

  • 点击"+ 添加信息源"按钮或导航至"/feeds/new"手动添加信息源。
  • 通过粘贴或拖动网站URL到搜索框来发现网站的RSS源。
  • 运行make feed-load feed-sync加载此仓库中包含的一组默认网站。
  • OPML或CSV文件导入一系列信息源。
  • 登录Mastodon账号

首次添加信息源时,应用会获取其最新文章,然后会定期检查新内容(默认每30分钟一次)。

浏览信息流

  • 可以将来源放入文件夹,可通过左侧边栏(桌面端)或导航栏菜单(移动端)访问。
  • 可以通过右侧边栏(桌面端)或导航栏菜单上的控件调整信息流行为:
  • 用户向下滚动时,条目会自动标记为已查看。默认情况下,下次打开应用时会跳过已看过的条目。
  • 默认排序将更新频率较低的来源置顶。另外,还有严格的时间顺序排序选项。

阅读文章

与信息流条目交互有多种方式:

  • 点击文章标题会在新浏览器标签页中打开原始网站。
  • 在某些情况下,如Reddit、Hacker News或Lobste.rs等链接聚合器,会有一个单独的链接用于文章讨论。
  • 点击内容或在聚焦条目时按Enter键,将获取并在本地阅读器中显示文章内容。这将是文章的精简版本(移除了一些网站链接、广告和付费墙),由mozilla/readability库提供支持。请注意,要使用此功能,需要在设置项目时安装node 20或更高版本。
  • 还可以通过将任意文章的URL拖到搜索框来使用阅读器预览。

删除旧文章

条目会在发布后的一段时间内自动删除(默认为7天)。 置顶和收藏的条目永不删除。此外,所有来源都会保留最少数量的条目(默认为5条),不考虑发布日期。

高级功能

从CSV和OPML文件批量导入/导出订阅源

make feed-load将从本地feeds.csv文件加载订阅源。仓库中包含了一个示例文件,以便您可以立即查看一些内容。 还有一个make feed-load-opml命令,可以从OPML格式feeds.opml文件导入RSS订阅源列表。 相应地,还有make feed-dumpmake feed-dump-opml命令用于从应用程序导出订阅源数据。

Mastodon账户设置

Mastodon集成允许将用户主页feed和通知收件箱都作为订阅源获取。 feedi首先需要通过导航到管理订阅源 > Mastodon登录或访问/auth/mastodonURL来获得访问Mastodon账户的授权。填写实例名称并授予访问权限后,feedi将重定向到添加订阅源表单,在那里可以添加Mastodon或Mastodon通知订阅源(或两者都添加)。

GitHub通知订阅源

您可以将GitHub的通知导入feedi。为此,请导航到您的GitHub主页https://github.com/,打开页面HTML源代码并搜索atom feed链接。它应该看起来像这样:

<link rel="alternate" type="application/atom+xml" title="ATOM" href="/facundoolano.private.atom?token=<TOKEN>" />

复制href URL并使用它在feedi中添加新的RSS订阅源。

Goodreads主页订阅源

您可以将Goodreads.com的通知导入feedi。为此,请导航到您的Goodreads主页https://www.goodreads.com/,打开页面HTML源代码并搜索atom feed链接。它应该看起来像这样:

<link href='https://www.goodreads.com/home/index_rss/<ID>?key=<KEY>' rel='alternate' title='Goodreads' type='application/atom+xml'>

复制href URL并使用它在feedi中添加新的RSS订阅源。

Reddit订阅源

Reddit通过在URL后附加.rss来将公共页面作为RSS订阅源公开,例如https://www.reddit.com/r/selfhosted.rsswww.reddit.com/user/someuser.rss。 此外,经过身份验证的用户可以访问私人账户页面的RSS订阅源:首页、已保存的链接、消息收件箱等。可以在这里找到链接。 feedi为Reddit列表消息和链接以及用户收件箱使用特殊用途的订阅源解析器。

Kindle设备支持

该应用程序允许注册Kindle邮箱地址,以便将清理过的文章HTML发送到设备上,比默认的Amazon Send to Kindle Chrome扩展获得更好的效果。这需要设置SMTP凭据以发送电子邮件。 使用基本Gmail账户实现的步骤:

  1. 注册一个Google电子邮件账户。
  2. 为该账户开启两步验证。
  3. 导航到应用密码设置并为应用生成密码(需要激活两步验证才能使用)。
  4. 在应用配置中添加SMTP设置:
FEEDI_EMAIL = "YOUR.EMAIL@gmail.com"
FEEDI_EMAIL_PASSWORD = "GENERATED APP PASSWORD"
FEEDI_EMAIL_SERVER = "smtp.gmail.com"
FEEDI_EMAIL_PORT = 587
  1. 导航到/auth/kindle或在搜索框中输入"kindle",然后输入您设备的@kindle.com电子邮件地址。
  2. 转到您的Amazon个人文档设置,并将您的feedi电子邮件地址添加到已批准的文档电子邮件列表中。 完成此设置后,浏览文章时将可以使用"发送到Kindle"命令。

订阅源解析

该应用程序通过定期从不同的订阅源(RSS/Atom、Mastodon嘟文和通知、自定义爬虫)获取项目,并将它们调整为Entry数据库模型,该模型大致匹配我们期望在前端显示的内容。

RSS/Atom订阅源

大多数RSS订阅源应该能被默认解析器正确处理,但有时需要添加自定义功能来清理或扩展数据以获得更好的外观和体验。这可以通过继承feedi.parsers.rss.BaseParser来实现。静态方法is_compatible确定是否应使用该特定类解析给定的订阅源;parse_*方法覆盖了前端预期的每个字段的默认逻辑。 例如,这个lobste.rs链接聚合器的解析器被调整为内联显示外部链接提交的摘要,并区分源文章URL和lobste.rs讨论URL:

class LobstersParser(BaseParser):
    def is_compatible(_feed_url, feed_data):
        return 'lobste.rs' in feed_data['feed'].get('link', '')

    def parse_content_short(self, entry):
        # 只有外部链接提交才有'Comments'链接
        if 'Comments' in entry['summary']:
            url = self.parse_content_url(entry)
            return (self.fetch_meta(url, 'og:description') or
                    self.fetch_meta(url, 'description'))
        return entry['summary']

    def parse_entry_url(self, entry):
        # 返回讨论URL,对于外部链接,它与entry['link']不同
        if 'Comments' in entry['summary']:
            soup = BeautifulSoup(entry['summary'], 'lxml')
            return soup.find("a", string="Comments")['href']
        return entry['link']

您可以在这个模块中看到几个自定义RSS解析器。

自定义订阅源

除了RSS和Mastodon订阅源外,该应用程序还可以通过自定义解析器获取任意来源的内容。这对于抓取不提供订阅源的网站或直接消费JSON API很有用。 要添加自定义解析器,请继承feedi.parsers.custom.CustomParseris_compatible方法确定是否应使用该解析器解析给定的URL。fetch方法执行实际的条目获取和解析。有关一些示例,请参阅feedi.parsers.custom模块。 一旦实现了解析器,当在Web应用程序中添加带有预期URL的"自定义"类型的新订阅源时,就会使用它。

键盘快捷键

快捷键场景动作
Cmd+k聚焦搜索输入框
Enter搜索框聚焦提交第一个建议
Escape搜索框或建议聚焦隐藏建议
向下箭头, Ctrl+n搜索框或建议聚焦下一个建议
向上箭头, Ctrl+n建议聚焦上一个建议
Enter条目聚焦打开条目内容
Cmd+Enter, Cmd+左键点击条目聚焦在新标签页打开条目内容
Cmd+Shift+Enter, Cmd+Shift+左键点击条目聚焦在新窗口打开条目讨论
向下箭头, Tab条目聚焦聚焦下一个条目
向上箭头, Shift+Tab条目聚焦聚焦上一个条目
p条目聚焦固定条目
f条目聚焦收藏条目
Escape查看条目内容返回

用户管理

默认的应用程序配置假设是单用户未认证设置,但如果需要安全性,可以启用身份验证,例如将应用程序部署到互联网上或支持多个账户。 要启用用户身份验证:

  1. 配置中删除DEFAULT_AUTH_USER设置。
  2. 如果您已经创建了数据库,请使用make db-reset重置它。或者,使用make user-del EMAIL=admin@admin.com删除默认用户。请注意,这也会从数据库中删除与之关联的订阅源和条目。
  3. 您可以通过运行make user-add EMAIL=some@email.address来创建新用户。该命令将提示输入密码。 请注意,前端没有开放的用户注册功能,但如果需要,添加这个功能应该很简单。有关详细信息,请查看auth模块flask-login文档

使用Docker运行

从GitHub包获取镜像: docker pull ghcr.io/facundoolano/feedi:latest

创建一个卷以持久化数据库数据: docker volume create feedidb

将默认订阅源加载到默认管理员用户: docker run -v feedidb:/app/instance ghcr.io/facundoolano/feedi flask --app feedi/app.py feed load feeds.csv admin@admin.com docker run -v feedidb:/app/instance ghcr.io/facundoolano/feedi flask --app feedi/app.py feed sync

以开发模式运行: docker run -p 9988:9988 -v feedidb:/app/instance ghcr.io/facundoolano/feedi

要在生产模式下运行,需要一个至少包含密钥的配置文件: echo "SECRET_KEY = '$(python -c 'import secrets; print(secrets.token_hex())')'" >> production.py docker run -p 9988:9988 -e FLASK_ENV=production -v feedidb:/app/instance -v $(pwd)/production.py:/app/feedi/config/production.py ghcr.io/facundoolano/feedi

要启用身份验证,请在生产配置文件中添加DEFAULT_AUTH_USER=None

非本地设置

您可以参考Flask文档以获取有关如何将feedi部署到非本地环境的说明。存储库中包含的设置脚本展示了Debian服务器的示例设置。您可以通过ssh远程运行它,如make prod-install SSH=user@server

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

白日梦AI

白日梦AI提供专注于AI视频生成的多样化功能,包括文生视频、动态画面和形象生成等,帮助用户快速上手,创造专业级内容。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

讯飞绘镜

讯飞绘镜是一个支持从创意到完整视频创作的智能平台,用户可以快速生成视频素材并创作独特的音乐视频和故事。平台提供多样化的主题和精选作品,帮助用户探索创意灵感。

Project Cover

讯飞文书

讯飞文书依托讯飞星火大模型,为文书写作者提供从素材筹备到稿件撰写及审稿的全程支持。通过录音智记和以稿写稿等功能,满足事务性工作的高频需求,帮助撰稿人节省精力,提高效率,优化工作与生活。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号