KindleEar:自动定期推送 RSS 订阅到 Kindle

KindleEar是什么?

KindleEar是部署在Google Appengine上的免费应用,主要功能是自动定期通过RSS收集网络文章然后制作成图文并茂的电子书推送至你的Kindle。

主要特性:

  • 自定义RSS
  • 支持RSS全文抓取
  • 多账号管理,也就是支持多kindle
  • 带图的杂志格式MOBI
  • 自动每天定时推送
  • 内置共享库,可以直接订阅其他网友分享的订阅源,也可以分享自己的订阅源给其他网友
  • 强大并且方便的邮件中转服务
  • 和Evernote/Pocket/Instapaper等系统的集成

优点:

    • 全免费,不单此应用免费,而是GAE免费提供托管空间,你不需要付一分钱。
    • 生成精美的杂志格式书籍。样例如下(左一为kindle3,右两个为kindle touch):

 

KindleEar:自动定期推送 RSS 订阅到 Kindle

 

此应用需要自己的服务器吗?

此应用托管在Google App Engine(GAE)服务器上,不需要你自己的服务器。

注意:GAE(Google App Engine)不是GCE(Google Computer Engine),只要应用使用的资源不超其免费额度,则GAE永久免费,但是GCE仅提供60天试用免费。

 

如何搭建自己的推送服务器?

以下是正规的搭建步骤:

  1. 在 Github 页面上下载KindleEar的最新版本,在页面的右下角有一个按钮"Download ZIP",点击即可下载一个包含全部源码的ZIP文档,然后解压到你喜欢的目录,比如C:\KindleEar(下面以这个为例)。
  2. 首先你需要一个google账号,并暂时 [启用不够安全的应用的访问权限] 以便获得上传程序的权限。然后访问 Google Developers Console,新建一个Application。(用来上传KinldeEar用)。
  3. 安装 Python 2.7.x,在此页面中选择你的系统平台对应的2.7.x版本下载,然后直接双击安装。注意不要安装成Python 3.x版本,GAE和KindleEar都暂不支持。
  4. 下载 GAE SDK,这是用来上传GAE程序用的。在此页面中的区段“Google App Engine SDK for Python”中选择你的系统平台对应的版本点击即可下载,然后安装,一路next无话。
  5. 打开资源管理器,进入之前下载的KindleEar目录C:\KindleEar,使用任何文本编辑器打开app.yaml和module-worker.yaml文件,将第一行的kindleear字样修改为你之前申请的GAE程序名(比如kindleear123),保存退出。
  6. 在app.yaml的同一个目录,打开config.py文件,修改SRC_EMAIL为你的gmail账号,DOMAIN为你的应用的域名。其他的选项也可以根据注释有选择性的修改,或者使用默认即可。
  7. 正式上传KindleEar。不能使用Google App Engine Launcher,因为Launcher默认不支持多module应用(修改配置后可以),这里介绍一下windows下使用命令行的方式。
  8. 依次点击:开始-运行-输入CMD,打开命令行窗口
  9. 进入到App Engine SDK安装目录;例如:
    cd "C:\Program Files\Google\google_appengine"
  10. 输入“上传”命令:
    c:\python27\python.exe appcfg.py update C:\kindleear\app.yaml c:\kindleear\module-worker.yaml
  11. 依次输入gmail账号及密码(密码输入时屏幕不显示)。
  12. 再输入“上传”命令:
    c:\python27\python.exe appcfg.py update C:\kindleear\
  13. 显示上传成功后使用你的浏览器打开域名:kindleear123.appspot.com (举例而已,kindleear123要改为你申请的GAE程序名称),如果能正常打开,则还有最后一步。
  14. 将你的gmail账号加入kindle推送邮箱的白名单。这一步你应该早就会了吧。
  15. 然后呢?享受你自己的推送服务吧!

以下是推荐的简化搭建步骤(使用uploader):

  1. 下载KindleEar和申请GAE账号,并创建一个application。
  2. 下载uploader
  3. 解压uploader到特定目录,将之前下载并解压的KindleEar目录拷贝到此目录下,改名为kindleear,然后双击执行uploader.bat后根据提示输入appid/email/timezone后会正式启动上传程序,输入email和密码即可上传代码。

 

为什么我收不到推送的RSS?

收不到推送的RSS原因很多,如下是几种可能:

  1. 部署时仅部署了default模块,而没有部署worker模块。比如使用Launcher默认配置上传则导致此情况。
  2. 没有打开"自定义RSS"的投递开关,此开关在设置网页的最下面。
  3. 没有在kindle邮箱的白名单中加入你的gmail地址:
  4. 添加RSS过多导致内存占用过大,程序被自动终止。
    • 打开module-worker.yaml,将instance_class值修改为B4,然后重新上传。
  5. 你输入的订阅地址不是合法的RSS/ATOM订阅(XML格式)。
  6. 如果RSS订阅源是Feedburner生成的,你可以在其链接之后添加一个查询字符串'?format=xml'或'?fmt=xml',比如:http://xx.com/feed?format=xml.

 

何为全文RSS?

全文RSS就是在RSS的XML文件中已经给出了文章全文的RSS,使用浏览器打开RSS对应的链接,查看是否已经有全部的文章内容?如果是,则为全文RSS。如果仅给出文章摘要,则不是。

全文RSS能否按照摘要RSS处理?反之是否可以?

全文RSS当然可以按照摘要RSS处理,这样就忽略RSS链接中给出的文章内容,而直接到原链接中获取,只是时间要多花费不少,导致支持的RSS数量下降。如果是摘要RSS,则不能按全文RSS处理,否则会导致文章内容不全。

如何按周订阅?

有些RSS每周更新,这样每天推送同样的内容就蛋疼了点,碰到这种情况,有两种处理方法:

  1. 在books目录下添加一个py文件,将参数deliver_days设置为你需要推送的星期(头字母大写的英文星期单词),注意deliver_days是一个列表,你也可以设置为几个单词,这样的话,其实也可以设置为哪天不推送。
    比如:
    deliver_days=['Friday']
    deliver_days=['Sunday', 'Friday']
  2. 使用管理员登陆,新增一个账号,退出,使用新账号登陆,添加需要的RSS,然后在“设置”页面仅选择你需要的其中一个“投递日”,在页面下方的“最旧文章”中选择“一个星期”。

 

如何一天推送多次?

需要及时跟踪网站最新消息的同学可能有一天推送多次的需求,以下步骤告诉你如何实现:

  1. 在books目录下添加一个py文件。
  2. deliver_times设置为你需要推送的整点时间列表。
    比如:
    deliver_times=[6,14,22] #6:00,14:00,22:00三次推送
  3. 如果需要,oldest_article设置为多次推送的间隔秒数,这样就不推送重复文章了。
    比如:
    oldest_article=28800 #8*60*60

 

URL过滤器功能如何使用?

URL过滤器为高级功能,面向懂python正则表达式的同学,应用场景是这样的:有一些RSS的一部分固定的图像会一直下载不了或者其本身就是烦人的广告图像,为了节省时间支持更多的RSS或更好的阅读体验,则可以过滤这些图像URL,不再下载。URL过滤器支持正则表达式,请严格按python正则表达式的语法编写URL过滤器。

部分RSS有敏感内容,被墙屏蔽了怎么办?

升级到1.5及以上版本,并且将被qiang的RSS的链接协议改为https。

自定义书籍py文件,如何将封面/报头放到py同一目录?

升级到1.5及以上版本,在封面/报头文件设置中有全路径信息即可,如下:
mastheadfile = 'books/xxxx.gif'
coverfile = 'books/xxxx.jpg'

 

GAE上传遇到SSL出错,如何解决?

墙内的朋友有时候在上传代码时遇到此错误:urllib2.URLError: <urlopen error [Errno 8] _ssl.c:504: EOF occurred in violation of protocol>,如果这样,改hosts即可:“74.125.229.174 appengine.google.com”

 

有部分文章乱码?

对于自定义RSS和不指定编码的内置书籍,软件使用多种方法综合确定网页的编码:HTTP头/HTML头/python模块chardet检测的编码,最终结果并不是100%正确的,如果检测错误,则文章可能乱码,这在浏览器上偶尔碰到网页乱码一样道理。
因为这种情况很少见,KindleEar仅提供一个不是很优雅的hack方案:手工更改数据库缓存的chardet检测的编码。
方法如下:

  1. 使用admin登陆appid.appspot.com(假定你的应用名字为appid)。
  2. 浏览器地址栏中输入https://appid.appspot.com/dbviewer,翻到页面UrlEncoding区段,查看乱码文章对应网站的编码信息,如果编码不对,记下ID号,进行下一步。
  3. 地址栏中输入https://appid.appspot.com/dbviewer?action=modurlenc&id=dbid&feedenc=fenc&pageenc=penc
      解释一下,在这一长串字符串中,你先要更改:

    • dbid:你记下来的编码对应网站ID。
    • fenc:你希望更改FeedEncoding的编码。
    • penc:你希望更改PageEncoding的编码。
  4. 或者你可以在GAE后台的Datastore Viewer中修改。
  5. 至于怎么获取正确的编码,可以通过在浏览器中查看网页源码。
  6. 如果你在dbviewer页面中找不到你需要修改的网站,则说明KindleEar一直没有使用chardet检测过此网站任何网页编码,仅使用HTTP头/HTML头信息,这种情况你可以设置config.py文件中的ALWAYS_CHAR_DETECT变量为True再尝试。
  7. 如果设置ALWAYS_CHAR_DETECT为True还是乱码,则说明chardet检测到的编码错误,并且HTTP头/HTML头编码信息不一致(还是有这种奇葩的网站的),这种情况还可以尝试将TRUST_ENCODING_IN_HEADER_OR_META设置为True。
  8. 尝试了ALWAYS_CHAR_DETECT和TRUST_ENCODING_IN_HEADER_OR_META都不行的话,软件无能为力了,请增加一个py文件,然后手工指定正确的编码吧。

 

忘记密码了怎么办?

如果是忘记非管理员账号的密码,则可以通知管理员改密码。
如果是管理员密码,则可以登陆 App Engine,在左边选择 "Datastore | 实体",在种类里面选择 "KeUser",选中 name 为 admin 的行,记下 "secret_key" 的值,比如为 "abcdefgh",在前面加随便几个字符,比如 "123abcdefgh",然后随便搜索一个在线的MD5计算网站,将其转换为MD5摘要字符串,比如 "8b920d97ca5fceff6c5835223c541bf4",再点击修改上面选择的数据行,将最后的MD5字符串填写到passwd域,然后点击页面下方的保存,重新使用密码 "123" 登录。

[email protected]邮件地址怎么用?

[email protected]是KindleEar附送的邮件服务,在部署好KindleEar后,你自动拥有了无数个EMAIL邮箱地址,格式为:[email protected],xxx为任意合法字符串,appid为你的应用名。

  • 要使用此功能,先要添加白名单,如果为 '*' 则允许所有邮件,否则格式为 '[email protected]' 或 '@xx.xx' (不包括单引号)。
  • 此邮箱将收到的邮件正文转换为邮件附件推送至你注册的Email邮箱,。如果邮件中只有链接(多个链接则每行一个),则抓取链接的网页内容制作成电子书然后再推送。
  • 如果在邮件主题最后添加了标识 !links,则不论邮件内容如何,KindleEar都只会提取邮件中的链接,然后抓取网页,制作成电子书发送至你的Kindle。这个功能最适合将网络连载直接发送至Kindle观看。
  • 如果在邮件主题后添加了标识 !article,则忽略所有链接,直接将内容转换为电子书发送。
  • 默认推送至管理员注册的邮箱,如果要推送至其他用户的邮箱,则使用格式:[email protected]。(注意是双下划线)
  • 如果将电子书下载链接发送至[email protected][email protected]则KindleEar直接下载对应的电子书并转发至注册的邮箱(注意GAE对后缀名有限制,不能发送可能有安全隐患的文件后缀比如exe等,zip文件能发送,但是zip文件内不能包含可能有安全隐患的文件)。
    GAE可邮件发送的后缀名列表参见:Mail Python API Overview
    (book/file/download邮件地址保留为下载电子书使用)
  • 发送至[email protected][email protected],则触发一次手动投递。邮件标题为空或为all则完全等同于网页上的“现在投递”按钮。如果需要推送特定书籍,则在标题上写书籍名字,多个书籍名字使用逗号分隔。
    注意:邮件标题上写多个书籍名字则自动合并推送为一本书。
  • 发送至[email protected]的邮件则直接抓取邮件中的链接并直接发送HTML文件至管理员邮箱。

 

推送至亚马逊中国邮箱有比较大的延迟?

这个经过网友们试验,和伟大的墙有关系,有一个解决方法:KindleEar先推送至某个个人邮箱,然后此个人邮箱自动转发至中亚的kindle邮箱。
不过还面临一个问题:部分邮箱设置自动转发需要发到邮箱的验证,而亚马逊邮箱不能登陆无法验证。其实你需要的是找一个不需要目标邮箱确认的邮箱来设置自动转发,比如outlook.com。

 

为何合并多本书籍推送后无法查词典?

如果有外文RSS而且需要在kindle上查字典的话,请将自定义RSS的语言设置为对应的外文。
同时,还要注意合并书籍推送的其他特性:

  1. 合并后的书籍使用默认报头和封面;
  2. 合并后的书籍使用自定义RSS设定的标题和语言设置;

 

“高级设置”里的归档和分享功能如何使用?

启用此功能后,KindleEar会在每篇文件的最后都附加一个超链接,在Kindle上点击此超链接会自动打开浏览器将你正在阅读的此文章归档至网络笔记或分享至社交网络(需要打开网络连接)。
有几点需要注意的:

  1. 请先修改config.py里面的DOMAIN为你申请的应用域名;
  2. 如果你在红墙内,可能需要打开“我需要翻墙(针对中国用户)”开关,默认的翻墙转发器采用作者在heroku上搭建的免费服务器: http://kforwarder.herokuapp.com,如果你有余力或者注重隐私,建议自己搭建一个,源码托管在 https://github.com/cdhigh/forwarder。(如果将来墙也封锁了heroku,则此翻墙方法无效)

 

有的网站需要登陆才能阅读文章的问题如何解决?

有些网站需要先注册账户然后登陆后才能阅读和下载文章,对于此类网站,则可以仿照books目录下的预置书籍,增加一个新的py文件,然后设置这几个属性:

  1. needs_subscription :设置为True
  2. login_url :为此网站的登陆网页URL
  3. form_4_login :可选(如果你不会看网页HTML源码就暂时不用设置),如果不设置或设置为None则KindleEar尝试自动判断;设置为整数则表示此网页中第几个form为登陆表单(0为第一个);设置为字符串则表示对应登陆表单form的名字,'#'打头表示id,'.'打头表示class,否则则匹配name/id/class任何一个。
  4. 登陆KindleEar后,在“我的订阅”页面先订阅对应书籍,然后书籍行右边会新出现一个按钮“登陆信息”, 点击后请在新页面中输入正确的账号和密码。

注1:因为GAE环境的限制,需要执行javascript或要输入验证码的网站则无法支持。

注2:对于一些足够特殊和复杂的网站,可能你需要在书籍子类中重写login()函数。

注3:你输入的密码将加密保存,密钥为每个账号都不一样的8位随机字符串,有一定的安全性,而且我尽量照顾你的密码安全,你可以随时删除保存的密码信息,书籍退订后也马上删除密码,但因为密钥也保存在GAE上(在另外的数据表),所以不能保证很高的安全性,请自己明白并愿意承担其中的风险。

 

网站在IE6下显示不正常?

在IE6下网站排版混乱并且无法显示导航栏,因为网站的排版采用YAHOO的CSS框架pure,而此框架要求IE7以上的IE,或者chrome/firefox,如果你使用的IE版本过低,建议升级到新版本。

 

内置书籍订阅时“Separate”选项是什么意思?

一旦你选择了“合并推送”,则所有订阅源都会合并成一本书籍推送至kindle,如果你需要有部分订阅源分开单独推送,则在订阅时选择“Separate“。

 

部署应用后打开网页出现“internal server error”如何处理?

有部分网友在部署后打开此应用的“我的订阅”和“投递日志”网页会出现“internal server error”错误,一般情况下因为gae没有及时生成对应数据库的索引导致。
你可以打开gae后台,查看logs日志,看是否有“NeedIndexError: no matching index found.”异常,如果有的话,证明是没有生成索引。
你也可以在gae后台查看“Datastore Indexes”,看每个条目的“Status”,正常情况下应该都是“Serving”,如果是“Building”或其他值,则说明索引也没有正确生成。
如果你部署步骤完全正确的话,可以稍等几分钟到几十分钟,等gae自动生成索引,如果gae没有成功自动生成索引,你也可以手动更新索引:
python appcfg.py update_indexes KindleEar/
在终端窗口执行此命令,注意最后一个KindleEar是你保存的此应用的目录名。
如果出现的异常信息中有“UnknownQueueError”,则说明部署有问题,可以先单独执行此命令上传更新队列配置信息:
python appcfg.py update_queues KindleEar/
这几个命令也可以执行一遍试试。(比如手动可以推送无法自动推送则执行 update_cron)
python appcfg.py update_cron KindleEar/
python appcfg.py update_queues KindleEar/
python appcfg.py update_dispatch KindleEar/

如果上面的步骤执行完后还是不行的话,请按照正确步骤重新部署。

 

如何修改多本书籍合并后的封面?

默认配置下如果合并多本书籍,则合并后的封面会将所有书籍的封面缩小并拼贴在一起,并且每次推送的排列顺序都不一样,此效果由config.py里面的参数项 DEFAULT_COVER_BV 控制,默认为 None。
如果你不喜欢这个效果,设置DEFAULT_COVER_BV为某个文件名则可以取消此效果,比如: DEFAULT_COVER_BV='cv_bound.jpg'

有关墙的汇总

在天朝的网友在部署时和使用时会遇到一个强大的墙,特别google又是特别重要的黑名单,这是几个简单的说明,其他的请自己解决:

  • 在部署时需要开全局代理,单单浏览器代理无法上传代码。
  • 这里有两篇参考文章:[GITHUB]上传gae app失败的解决办法, [BLOG]上传GAE APP失败的解决办法,可以尝试一下。
  • 在上传之后,如果使用代理还是无法访问appspot,可以将appspot中的字母o改成0(零)试一下,形如:xxx.appsp0t.com,感谢天朝某位网友的默默服务吧。

 

保存到Pocket功能如何使用?

Pocket 是一个比较流行的稍后阅读应用,你在电子书上读到有趣或有用的文章后,可以选择将其发送到你的Pocket账号,然后就可以通过跨平台的Pocket应用来继续阅读。
要启动此功能,请按如下步骤打开:

  • 申请Pocket账号;
  • 点击网站上的"高级设置" | "归档与分享"页面中的 'Save to Pocket' 区段的[申请授权],然后浏览器会跳转到Pocket的页面进行授权,在你确认授权后会自动跳转回来,则完成申请授权过程;
  • 在KindleEar的“高级设置” | "归档与分享"页面中,勾选“在每篇文章后附加 'Save to Pocket' 超链接”。

备注:

  • Pocket对应用授权采用Oauth v2技术,只有Pocket才知道你的账号和密码;
  • 此应用仅申请了添加文章权限,没有权限修改和删除你的账户中的已有文章,也没有权限查看你的文章列表;
  • 在Pocket申请到的授权码保存在你自己的应用数据库中,其他人搭建的KindleEar没有权限访问你的账户;
  • 如果你更注重隐私和安全,你也可以自己在Pocket上申请一个开发者的Consumer Key,然后修改config.py中的POCKET_CONSUMER_KEY。
  • 如果需要反向将Pocket的文章推送至Kindle,可以打开Pocket的自定义RSS功能,在Pocket控制面板的“隐私控制”|“RSS 订阅源”可以找到你的专有RSS订阅地址,把它加入KindleEar的订阅列表中即可。
  • 而因Instapaper仅提供了简单的认证API,所以 'Save to Instapaper' 功能需要输入账号和密码,但是密码是加密后保存在你自己的应用的数据库中的。

 

投递日志状态wrong SRC_EMAIL的解决方案。

到Gae后台的Settings页面,看看 已经授权的Email列表里面有没有你的发送邮箱地址,如果没有就添加即可。

 

其他的一些小Tips。

  • 设置界面上的邮箱地址可以设置为多个,用分号隔开即可。同样,分享界面上的邮箱地址也可以设置为多个。
  • 如果推送到手机上观看,可以设置config.py里面的COLOR_TO_GRAY=False,以便查看彩色图像。
  • 自定义书籍中的属性 extra_css 可以自定义投递文章的样式。
  • 在高级设置中可以批量导入和导出OPML格式的订阅列表,这功能比较适合从其他RSS软件中转移数据。
  • 因Evernote的免费政策,通过邮件保存到Evernote仅支持5个邮件,需要更多则需要升级Evernote账户。

 

漫画订阅说明

目前支持以下网站的漫画

漫画的订阅方法有两种,可以选择其中任意一种。
这里使用【食戟之灵】举例,先从动漫狂中搜索得到该漫画的URL。

    • 1. 通过Feeds订阅

这种方法比较简单,在【我的订阅】页面的【自定义RSS】框中,添加书籍标题和URL进行订阅。

注意:投递时需要打开【自动定时投递自定义RSS】选项。

    • 2. 新建书籍并上传订阅

进入books/comic/下,在该目录拷贝conan.py并任意命名,修改其中的下列位置以后,重新上传到GAE,点击新的书籍【[漫画]食戟之灵】进行订阅。

拷贝conan.py到soma.py。

 

位置修改前修改后说明
7行return Conanreturn Soma使用"Soma"作为类名
9行class Conan(CartoonMadBaseBook):class Soma(CartoonMadBaseBook):使用"Soma"作为类名
10行title = u'[漫画]名侦探柯南'title = u'[漫画]食戟之灵'漫画名为【食戟之灵】
11行description = u'日本漫画家青山刚昌创作的侦探漫画'description = u'由附田祐斗原作,佐伯俊作画的连载作品。'漫画的简单说明
17行feeds = [(u'[漫画]名侦探柯南', 'http://www.cartoonmad.com/comic/1066.html')]feeds = [(u'[漫画]食戟之灵', 'http://www.cartoonmad.com/comic/1698.html')]在网站上搜索到该漫画的网址

 

使用sendgrid发送邮件

在设置界面,可以设置sendgrid发送邮件,需要在下面网站申请帐号并创建自己的apikey。
sendgrid
推荐按照Google的官方说明进行操作。 google
需要说明的是sendgrid支持的邮件大小是30M,但是由于gcloud的urlfetch的限制变成了10M。

匿名

发表评论

匿名网友填写信息

:?::razz::sad::evil::!::smile::oops::grin::eek::shock::???::cool::lol::mad::twisted::roll::wink::idea::arrow::neutral::cry::mrgreen: