使用 Mac 部署 Kindle Ear

我是 Kindle 脑残粉,想必大家都知道了吧。由于这台设备简单高效无干扰,所以我会把阅读这件事情尽可能地放在 Kindle 设备上完成。最近升级了 Kindle Voyage,我想着把散落在各个角落的信息源集中一下。

这件事情本来可以通过万能的 Calibre 完成,但有两个大坑是我无法忍受的。首先是每天同步,虽然我每天都会打开电脑,但要求我每天同步一个文件到 Kindle 里就有点过了。我不太喜欢被这种事情干扰,iPhone 我也不是每天同步啊。然后是那个国家防火墙,我的大多数阅读材料来自海外。虽然不知道哪些被封杀,但 Calibre 对于代理服务器的支持之差简直让人不能忍。所以,即便是我能忍受每天同步,但同步之前需要拨 VPN 这件事情我只能呵呵冷笑一声。

于是我开始琢磨 Web 服务,让服务器帮我抓取散落在各处的信息,整合成一个 mobi 文件然后通过 email 投递给我。这件事情有很多解决方法,但我今天介绍的 Kindle Ear 无疑是做的最漂亮的。

NYT on Kindle Voyage
在 Kindle Voyage 上阅读纽约时报中文网的文章

只不过我在部署此服务时遇到了几个问题,然后也没能方便地在网路上找到答案。于是有了这篇教程,主要目的是反思,顺便帮助诸位部署自己的投递服务。

第一步,科学上网

请准备好一个可用的 VPN,保证访问各种服务时无障碍。如果您与我一样居住在中国大陆,这一步是必须的。请尽可能使用全局 VPN,其他的代理方式有可能会造成部属失败。我前两次部署失败就是因为科学上网的方法不对,虽然浏览器和大部分应用都可以科学上网,但没用全局 VPN 总会有产生问题的可能。

第二步,申请账号

如果你跟我一样启用了 Google 的二步验证,请现在申请一个 App Password,否则没办法部署应用。

接下来请申请一个 Google App Engine 账号并创建一个应用。

在这一步,你可能遇到新旧两种界面。旧界面比较直观容易理解,Application Identifier 就是未来要用到的 Application ID,而且可以非常直观地知道应用页面就是这个 ID 加上 .appspot.com。新界面稍微复杂一些,但记住 Project ID 那一栏就是 Application ID。它给出的默认值很奇怪(在本截图中,Application ID 就是 smiling-parser-810 ),但总归是可用的,你可以暂时不用去想名字。我认为 Kindle Ear 是自己用的,最好是每天正常工作让我把它忘掉,不需要一个闪亮亮的域名。

Old and New Dashboards
Google App Engine 新旧 Dashboard

 

第三步,下载软件包

请按照作者的介绍,一一下载各种必要的文件。

首先是 Python 2.7.8,打开 dmg 文件之后发现是一个 mpkg 的安装包。双击安装呢,告诉我有安全隐患。由于我确认来源无问题,我临时解除了 Mac OS X 的安全管制,放行了这个安装包。

然后是 Google App Engine for Python,打开之后是一个 app 程序包,按照习惯拖到 Applications 文件夹里即可,但请务必运行一次来安装必要的 App Engine 部署文件。它会提示创建一组 symlinks,建议创建以方便未来调用指令。创建 symlinks 之后,能得到一个提示框。从这里知道了 appcfg.py 文件的位置,在 /usr/local/bin/appcfg.py,这个会在部署的时候用到。

最后就是 Kindle Ear 的源码,请在 Github 里处理,或者直接点击 Download ZIP 按钮获取 Kindleear-master.zip 压缩包。解压到任意目录,这样子就能拿到源码了。

第四步,设置

请按照作者的说明,打开以下三个文件:app.yaml,module-worker.yaml,config.py。

两个 yaml 文件只需要修改第一行,将默认的 kindleear 改为你的 Application ID 即可。

config.py 需要修改两个地方:一个是 SRC_EMAIL,请将默认的赋值改为你自己的 gmail 地址;另一个是 DOMAIN,把默认的 kindleear 改为你的 Application ID。你可能会注意到这里是一个 https 协议的 URL,而你的 Hello world 用的是 http 协议。由于我部署失败了十六次,这个问题我思考了很久。解决方案就是直接忽视不要修改,因为:1,部署失败与这个值没关系;2,这两个协议都能正常访问;3,如今这个时代建议加密。

这个时候,所有的准备工作都完成了:科学上网准备完毕,App Engine 申请完毕,软件包准备完毕,软件配置修改完毕。接下来,就是让我跌到十六次的“部署”流程。

第五步,部署

这个步骤对我来说是一个大坑。前面也提到过,我分别在 Mac OS 和 Windows 下至少部署了十六次,全部失败。最后我妥协了,使用作者的 uploader 居然就一次部署成功。作为一个自认为了解一些 Python 皮毛的用户,我觉得有必要反思一下。

由于我之前用过 Google App Engine,也成功部署过几个应用。所以拿到 Kindle Ear 的源码并做完相关修改之后,我就直接在 Google App Engine Launcher 里新建任务,然后点击部署。

这个时候,我能看到一堆 log 不停地滚动,然后也能看到 deploy successful 这样的文字。虽然最后会得到一个 Error 错误信息,但打开应用首页(Application ID 加上 .appspot.com )也能正常访问,登陆和设置都没有任何问题。对我来说,这其实是一种“部署成功”的幻觉。

但这是不对的。因为真正的部署成功不仅仅是能打开网站,还得正常投递才可以呀。为了验证是否真正部署成功,需要先订阅一份 RSS,然后去“设置”里点击“立即投递”链接。如果在“投递日志”里看到纪录,而且能在 Kindle 上收到文件,这才算是部署成功呢。

在之前的十几次部署中,我都没能收到文件,也没能在“投递日志”里看到任何记录。事实上,如果此时去 App Engine 里看日志,能发现大量的 404 错误。对于此,作者的解释是“Launcher 不支持多 Module 应用”,“没有部署 Worker 模块”。Github 对于 Closed Issues 的显示不够友好,这些 Issues 对于解决问题是非常有帮助的。一百多个 Issues 翻完之后,我终于明白了。

回头来看源码里的 readme.md 文件,其实作者在这里把部署步骤写得很清楚,请看他的第六步:

Step 6
Kindle Ear 安装步骤的第六步

 

作者很清楚地介绍了如何用命令行来部署,根本就没有提到 Google App Engine Launcher 这个 GUI 程序。我的问题在于:1,犯了经验主义错误,认为通过 GUI 程序也能完美实现部署(事实上现在还不能部署多 Module 应用);2,错误地理解了安装 Google App Engine SDK 的真实目的(安装这个 SDK 只是为了取得 appcfg.py 和其他必要的脚本而已,并没有说一定要用 GUI 的方式来部署)。

痛定思痛,打开 terminal.app ,连续 cd 指令将当前目录定位到 Kindle Ear 源码所在的文件夹,敲入如下指令:

 python /usr/local/bin/appcfg.py update app.yaml module-worker.yaml
 python /usr/local/bin/appcfg.py update .

Log 显示部署成功,而且没有任何 Error 提示。登录到网站后台验证了一下,不仅网站功能正常,而且 Kindle 也收到了推送过来的文件。那一刻,我有一种泪流满面的感觉,之前那十八次失败的部署实在是太闹心了。

结论与反思

要认真读说明书,不要想当然。

后续

既然部署成功,那么就可以开始修改代码了呀。作为一个自认为略懂 Python 的人,按照作者留下的说明顺手做了一份“纽约时报中文网”的合集。虽然用自定义 RSS 也能投递,但总觉得还是应该贡献点什么,尽管这个文件基本上就是两个 Feed 合烧吧 😀

诸位可以在我的 Dropbox Github 里下载到,如果你对这个 Recipe 感兴趣,欢迎提出修改意见。

已知的问题是,这个玩意儿貌似还不能跟其他订阅源放在一起,能顺利投递但在 Kindle 上打不开。我不熟悉 mobi 格式,原因未知……

4 Replies to “使用 Mac 部署 Kindle Ear”

  1. 我想问下,我算是成功部署了,但是一直收不到投递,当然也没有投递日志,如果方便,希望指导下,

  2. 如果没有看到投递日志,那就不算部署成功。很常见的错误是部署 woker 模块失败,这个错误即是我在 blog 里提到的“经验主义错误”。

    由于没有更多信息,建议您看看 GAE 控制台的 log。如果 worker 部署不成功,那么就应该能看到 404 错误。

  3. 请教下,按博主的方法,为什么会卡在 Getting current resource limits 这一步不动了呢,用的是XX-Net翻墙,也开起全局代理了

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.