- 后端
- 前端
- 社交
- 人工智能
【免费下载链接】NewsBlur
NewsBlur is a personal news reader that brings people together to talk about the world. A new sound of an old instrument.
2012 年 3 月,NewsBlur 官方博客发布了一则移动端喜讯:第三方开发者 Róbert Márki 发布了Web Feeds,这是 NewsBlur 在 Nokia MeeGo 平台上的首个客户端应用,免费上架 Nokia Store,并且官方明确宣称它"拥有网站的全部功能"。本文以这篇 原始公告 为核心线索,结合当前仓库中apps/mobile、apps/reader、apps/analyzer等模块的服务端源码,逐项拆解公告截图中的六大功能点(订阅源列表、故事列表、故事阅读、智能训练、添加站点、智能过滤控制)对应的真实接口与底层实现,帮助读者理解 NewsBlur 的移动客户端生态,以及服务端是如何支撑第三方客户端完成"与网站一致"的阅读体验。
说明:原公告中的六张截图托管于当年的外部站点(projects.developer.nokia.com),现已无法在仓库内对应验证;本仓库亦无与该主题强相关的本地图片资源,因此本文以文字与源码证据展开,不强行配图。
一、公告原文与历史坐标
原文位于 blog/_posts/tumblr/2012-03-14-mobile-app-web-feeds-nokia-meego.md,是一篇带 YAML 前置元数据的 Tumblr 时代博客,核心信息包括:
- 开发者:Róbert Márki;
- 应用名:Web Feeds;
- 定位:NewsBlur 在 Nokia MeeGo 平台上的首个客户端("the first NewsBlur app for Nokia MeeGo");
- 发布渠道:Nokia Store(即当年的 Ovi Store),应用免费;
- 特性声明:"it has all the features of the website"(拥有网站的全部功能);
- 配图:六张截图,分别展示订阅源列表、故事列表、故事阅读视图、智能训练、添加站点、智能过滤控制。
将这篇公告放回仓库的时间轴,可以看到 NewsBlur 移动客户端生态是一条连续演进的脉络:
| 时间 | 客户端 | 仓库中的证据 |
|---|---|---|
| 2011-08-09 | Blar(NewsBlur 的 Android 应用) | blog/_posts/tumblr/2011-08-09-blar-a-new-android-app-for-newsblur.md |
| 2012-03-14 | Web Feeds(Nokia MeeGo) | blog/_posts/tumblr/2012-03-14-mobile-app-web-feeds-nokia-meego.md |
| 2014-04-24 | Unread(支持 NewsBlur 的 iOS 应用) | blog/_posts/tumblr/2014-04-24-unread-is-a-new-ios-app-with-newsblur-support.md |
而今天仓库中的客户端代码已经覆盖四大平台:clients/android(1500+ 文件)、clients/ios(2400+ 文件)、clients/safari-extension、clients/browser-extension。从这些证据可以推断:NewsBlur 从一开始就采用"核心服务端 + 多样化客户端"的形态,官方与第三方开发者共同构建移动体验。
二、"网站的全部功能":六张截图与源码的逐项对应
必须先划清事实边界:Web Feeds 是第三方闭源应用,其内部实现无法从本仓库考证。但公告截图展示的六大功能点与 NewsBlur 网站/服务端的核心能力一一对应,后者可以在当前仓库源码中得到充分验证。以下逐一对照。
2.1 订阅源列表(Feed list)
订阅源列表是阅读器的主入口,服务端对应load_feeds接口:
- 路由:apps/reader/urls.py 中
url(r"^feeds/?$", views.load_feeds, name="load-feeds"); - 视图实现:apps/reader/views.py 的
load_feeds(另有扁平化变体load_feeds_flat位于 apps/reader/views.py); - 数据模型:订阅关系等模型定义在 apps/reader/models.py,包括
UserSubscription、UserSubscriptionFolders等。
该接口向客户端返回用户的订阅结构、文件夹层级与未读数,是任何 NewsBlur 客户端渲染"Feed list"页面的数据基础。值得注意的是,apps/mobile/views.py 的移动端工作区同样依赖 apps/reader/models.py 中的UserSubscription与UserSubscriptionFolders组织页面数据。
2.2 故事列表(Story list)
故事列表对应 NewsBlur 的 "River of Stories"(故事河流)机制:
- 路由:apps/reader/urls.py 中
url(r"^river_stories", views.load_river_stories__redis, name="load-river-stories"); - 视图实现:apps/reader/views.py 的
load_river_stories__redis——从方法名可以看出,故事河流的数据经过 Redis 加速读取; - 配套端点:
complete_river(apps/reader/urls.py)与refresh_feeds(apps/reader/urls.py),用于分页补全与手动刷新。
客户端通过一次river_stories请求即可拿到一个订阅源或一个文件夹下的全部未读故事,这也是"故事列表"与网站体验一致的关键。
2.3 故事阅读视图(Story view)
故事阅读视图涉及两部分:故事内容的获取,以及阅读状态(已读/未读)的同步。相关端点:
mark_feed_stories_as_read:apps/reader/urls.py,标记某订阅源下故事为已读;mark_stories_as_unread:apps/reader/urls.py,将故事重新标记为未读;read_stories/starred_stories:apps/reader/urls.py,读取已读与加星故事。
"上一页/下一页未读"(Next Unread)这类阅读器标配交互,依赖的正是上述已读状态同步端点。仓库自带的移动端工作区模板 templates/mobile/mobile_workspace.xhtml 中同样为故事页预留了NB-page-story页面与NB-next(Next Unread)按钮,可见该交互在 Web 与移动端是一致的。
2.4 智能训练(Intelligence training)
"智能训练"是 NewsBlur 最核心的特色功能,让用户通过训练标题、作者、标签等特征(正向/负向),让系统自动决定故事的显隐与排序。源码证据:
- 路由:apps/reader/urls.py 中
url(r"^feeds_trainer", views.feeds_trainer, name="feeds-trainer"); - 视图实现:apps/reader/views.py 的
feeds_trainer; - 分类核心逻辑集中在 apps/analyzer 模块:
classifier.py(分类器)、feed_filter.py(订阅源过滤)、phrase_filter.py(短语过滤)、tfidf.py(TF-IDF 权重计算)与tokenizer.py(分词); - 配套测试:apps/reader/test_classifier_filter.py 验证分类器过滤行为。
MeeGo 客户端的"Intelligence training"与"Intelligence control"两张截图,对应的正是这条"训练 → 分类 → 过滤"的服务端链路。任何客户端只要调用feeds_trainer接口提交训练样本,即可在网站与各客户端之间共享同一套智能规则。
2.5 添加站点(Adding a site)
添加站点是阅读器的增长入口:
- 路由:apps/reader/urls.py 中
url(r"^add_url", views.add_url); - 视图实现:apps/reader/views.py 的
add_url; - 后端配套:订阅源抓取、页面解析与图标导入等逻辑位于 apps/rss_feeds 模块(
feed_fetcher、page_importer、icon_importer、text_importer等)。
add_url接受用户粘贴的站点 URL,服务端完成发现、抓取与订阅创建,随后订阅源立即出现在用户的订阅列表中——移动端截图"Adding a site"展示的正是这一流程的入口表单。
2.6 智能过滤控制(Intelligence control)
"Intelligence control"是对智能训练结果的运行时控制——决定哪些类型的故事(按标题/作者/标签/正文)在列表中被显示、隐藏或弱化。对应源码:
- apps/analyzer/feed_filter.py:订阅源级过滤;
- apps/analyzer/phrase_filter.py:短语级过滤;
- apps/analyzer/classifier.py:分类器核心;
- 测试佐证:apps/reader/test_classifier_filter.py。
这套机制让"智能训练"中习得的偏好真正作用于阅读流,也是 NewsBlur 区别于普通 RSS 阅读器的关键能力。从源码结构可以推断,feed_filter与phrase_filter在服务端按订阅源逐个应用分类结果,客户端只需接收过滤后的故事列表,无需复制整套智能逻辑。
三、服务端为移动端准备的官方入口
除了供第三方客户端消费的功能接口,NewsBlur 服务端还维护了官方的移动端模块apps/mobile,与 Web Feeds 这类原生客户端形成互补:
- 路由挂载:newsblur_web/urls.py 同时挂载了
^mobile/与^m/两个前缀,均include("apps.mobile.urls"),即用户可通过短链/m/直达移动端入口; - 应用内部路由:apps/mobile/urls.py 将根路径
^$指向views.index(命名mobile-index); - 视图实现:apps/mobile/views.py 的
index直接渲染 templates/mobile/mobile_workspace.xhtml,并引入apps.profile.models.Profile、apps.reader.models.UserSubscription等模型组织数据; - 数据模型:apps/mobile/models.py 目前是一个占位模块(docstring 写明 "placeholder for mobile app data"),说明移动端的业务数据主要由
reader、profile等应用承载; - 页面模板:templates/mobile/mobile_workspace.xhtml 基于 jQuery Mobile 构建了三个页面:
NB-page-feeds(订阅源列表)、NB-page-stories(故事列表)、NB-page-story(故事详情),并在页面就绪后实例化NEWSBLUR.MobileReader;模板头部的NEWSBLUR.Globals注入了is_authenticated、is_premium、secret_token、username等会话信息,供移动端 JS 调用。
由此可见,NewsBlur 服务端对"移动端"的支持是双层的:一层是供第三方原生客户端(如 Web Feeds、Blar、Unread)调用的功能接口与 JSON 数据,另一层是官方自己维护的响应式移动 Web 工作区。2012 年的 MeeGo 应用之所以能做到"拥有网站的全部功能",正是因为它站在了这套成熟、统一的服务端能力之上。
四、从 2012 到今天的启示
把这篇 2012 年的公告放在今天回看,可以得到几点对开发者和阅读器产品都有参考价值的结论:
- 接口先行、客户端自由:NewsBlur 的核心能力(订阅、故事流、智能训练、过滤、加星、已读同步)全部通过服务端接口暴露,客户端只需要做 UI 与数据绑定,因此第三方开发者可以在完全不了解服务端实现的前提下,快速做出功能完整的客户端——Web Feeds 就是例证。
- 智能是差异化护城河:六张截图中两张都与智能相关(训练 + 控制)。
apps/analyzer模块(classifier / feed_filter / phrase_filter / tfidf)在 2012 年已经成熟到可以支撑第三方客户端,这是普通 RSS 阅读器难以复制的能力。 - 生态覆盖需要耐心:从 2011 年的 Android(Blar)、2012 年的 MeeGo(Web Feeds)、2014 年的 iOS(Unread),到今天仓库中完整的
clients/四端代码,NewsBlur 的移动生态是十多年持续投入的结果。
五、延伸阅读
- 公告原文:blog/_posts/tumblr/2012-03-14-mobile-app-web-feeds-nokia-meego.md
- 移动端服务模块:apps/mobile、templates/mobile/mobile_workspace.xhtml、路由挂载见 newsblur_web/urls.py
- 阅读器功能接口:apps/reader/urls.py(
load_feeds、river_stories、feeds_trainer、add_url、已读标记等端点) - 智能分析模块:apps/analyzer(
classifier.py、feed_filter.py、phrase_filter.py、tfidf.py) - 同主题历史公告:Blar Android 应用、Unread iOS 应用
- 客户端代码:clients/android、clients/ios、clients/safari-extension、clients/browser-extension
- 后端
- 前端
- 社交
- 人工智能
【免费下载链接】NewsBlur
NewsBlur is a personal news reader that brings people together to talk about the world. A new sound of an old instrument.
相关推荐
WuKongIM客户端SDK使用大全:从Web到移动端的全平台开发
WuKongIM客户端SDK使用大全:从Web到移动端的全平台开发 WuKongIM作为一款高性能的即时通讯解决方案,提供了完整的客户端SDK支持,覆盖从Web
即时通讯后端NewsBlur移动端应用开发:React Native构建跨平台客户端
你还在为新闻聚合应用开发两个独立的iOS和Android客户端而烦恼吗?本文将展示如何使用React Native为NewsBlur构建跨平台移动应用,一次编码
后端前端社交人工智能Audiobookshelf多平台客户端对比:Web vs 移动 vs 桌面
Audiobookshelf多平台客户端对比:Web vs 移动 vs 桌面 Audiobookshelf作为一款自托管的有声书和播客服务器,提供了多平台客户端
后端音视频前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考