免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 71251 | 回复: 34
打印 上一主题 下一主题

web.py+Jinja2开源kindle推送网站,全网络首发“在GAE上使用Python生成MOBI“ [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-07-05 08:37 |只看该作者 |倒序浏览
本帖最后由 cdhigh 于 2013-07-05 08:53 编辑

起因:
最近因为网络上的一些kindle推送服务不太合自己的意,也不想买VIP服务,因此就自己使用web.py+Jinja2实现了此网站:
http://kindleear.appspot.com

用于推送自己感兴趣的RSS或网页内容至自己的kindle。
现已开源在github
https://github.com/cdhigh/kindleear

值得一说的是,此网站有一个首创,第一个移植calibre(一个电子书管理工具)的mobi生成模块用于google app engine(GAE)。

下面说说开发心得:

1.为何不使用GAE自带的webapp框架,而选择web.py?
   其实最重要的就是webapp缺少移植性,只能在gae上使用,反正webapp和web.py都需要学习,为何不学习一个以后在其他平台上也能使用的框架呢?还有,最开始时我也使用了django搭建了初始版本,后来发现使用django太繁琐了,太笨重了,而且时不时有各种各样的问题要解决,一气之下就丢一边去了。然后看了网上对于各种WEB框架的一大堆讨论分析对比,还是按照自己的心意和喜好选定了web.py。

2. 为何不使用web.py自带的模板,而使用jinja2?
   其实我之前已经使用web.py的模板搭建好系统框架了,后来发现Templetor模板(web.py自带模板)的“模板继承”功能太弱,各个页面之间的重复代码太多,就考虑换一个模板系统,因为学过django,所以jinja2无疑是首选,语法类似,并且jinja2也是GAE推荐,根据网上评测,性能也很好,所以就选定了jinja2。
   题外话:我没有使用web.py封装的jinja2接口,而是直接使用jinja2的Environment() API,也是为了更通用,不被绑死在web.py上,比如万一我哪天不爽,想切换成bottle...

3. 模块动态加载(插件机制)
   此网站支持插件机制,类似于calibre的recipe,写一个特定格式的py文件放到books目录下,网站自动加载并显示在“我的订阅”页面。
    核心代码:
  1. def LoadBooks():
  2.     for bkfile in os.listdir(os.path.dirname(__file__)):
  3.         if bkfile.endswith('.py') and not bkfile.startswith('__') and not bkfile.endswith("base.py"):
  4.             bookname = os.path.splitext(bkfile)[0]
  5.             mbook = __import__("books." + bookname, fromlist='*')
  6.             bk = mbook.getBook()
  7.             RegisterBook(bk)
复制代码
4.更好的urlfetch。
   有些网站很可恶,如果你不带cookie访问,会返回302,并重定向到同一个地址,如果再次访问,有一定的概率会返回200。
   所以GAE时不时会报Too many redirects异常,又不是每次重现,之前因为这个问题,折腾了我好几天,后来经过google的反复调教,终于明白是cookie的问题,带cookie访问就没这个问题了。
   还有,因为要抓取网页,有时候网页中的一些图片会导致无法访问或访问超时,也会时不时出错,当然了,也是经过万能的google的帮助,在一位前辈那里学会了给urlfetch增加失败重试功能。
   然后,我再将上面两个解决方案合一,参见urlopener.py,使用此类代替urlfetch后,网站稳定了。

5.web.py在gae上使用session。
   web.py的session机制无法直接部署到GAE上,因为GAE不支持本地文件存储。
   这个问题的解决方案也是google来的,特地整理在这里,
   就是使用memcache实现一个Store子类,参见memcachestore.py文件。

6.尽管是个人网站,但是密码也不应该明文保存吧。
    但是也没有必要加密过甚,因此使用最简单的MD5即可:
  1.     import hashlib
  2.     passwd = hashlib.md5(password).hexdigest()
复制代码

论坛徽章:
0
2 [报告]
发表于 2013-07-05 21:19 |只看该作者
一个烦恼:
在移植calibre的mobi模块过程中,遇到了n次很恼火的文件和字符串编码问题,不是解码失败就是编码失败,每次都不是很容易解决,都快要崩溃了。
所以终于明白了python 3的潜力,python 3和以前版本至少从UNICODE的角度看就必须要替代python 2,如果GAE支持了python 3,我将毫不犹豫的马上转向python 3

论坛徽章:
4
金牛座
日期:2013-10-11 16:12:50卯兔
日期:2014-07-31 09:17:19辰龙
日期:2014-08-08 09:28:02狮子座
日期:2014-09-14 20:32:05
3 [报告]
发表于 2013-07-08 16:55 |只看该作者
楼主闭关一段时间就会有大作呀。

python3肯定是以后的方向,我早就看到了,所以直接就学python3,无视python2。:wink:

不知道gae支持python3有多难,google就是不支持python3。

我发现python3在windows下默认保存编码竟然不是utf-8,感觉很蛋疼。又不知道该怎么修改这个默认值,又或者必须重新编译才能搞定。

论坛徽章:
0
4 [报告]
发表于 2013-07-08 22:26 |只看该作者
回复 3# ssfjhh

有hack的方法,不过不推荐,建议每个文件都在文件头声明编码:
# -*- coding:utf-8 -*-
PYTHON保存时会自动按照编码声明保存。
这也是python推荐的方法。

如果不想这样,也可以自己修改代码:
3.2.7:
C:\Python32\Lib\idlelib\IOBinding.py
392行
return chars.encode('ascii')
将ascii修改为utf-8
==============
2.7.3
C:\Python27\Lib\idlelib\IOBinding.py的399行
return chars.encode('ascii')
将ascii修改为utf-8即可
   

论坛徽章:
0
5 [报告]
发表于 2013-07-09 11:58 |只看该作者
推送服务听说nginx的模块比较好
我是自己在libevent为底层自己扩充了一下,适合自定义协议的推送。

论坛徽章:
4
金牛座
日期:2013-10-11 16:12:50卯兔
日期:2014-07-31 09:17:19辰龙
日期:2014-08-08 09:28:02狮子座
日期:2014-09-14 20:32:05
6 [报告]
发表于 2013-07-09 13:06 |只看该作者
回复 4# cdhigh


     已经改了貌似不行。我用的是Python 3.3.2 你说的这行代码在这个版本中是第397行。
  1.         if self.fileencoding == 'BOM':
  2.             return BOM_UTF8 + chars.encode("utf-8")
  3.         # See whether there is anything non-ASCII in it.
  4.         # If not, no need to figure out the encoding.
  5.         try:
  6.             return chars.encode("utf-8")
复制代码

论坛徽章:
0
7 [报告]
发表于 2013-07-10 09:58 |只看该作者
经过我亲自测试,证明是有效的,不知你为何无效。
只是要注意,对于全文都是英文字符来说,ASCII编码和UTF-8编码等效,如果没有BOM,你无法确认是否是UTF-8还是ASCII编码,所以要证明是否有效,内容至少有中文字符才行。

论坛徽章:
0
8 [报告]
发表于 2013-07-20 14:48 |只看该作者
lz,在GAE Launcher上怎么缺省的8080端口不能进行调试?
系统自带的guest book的demo却可以?

重度kindle用户,正在学习gae和python中

论坛徽章:
0
9 [报告]
发表于 2013-07-20 23:29 |只看该作者
话说GAE Launcher是经常出问题的,不是连不上就是报各种错误。
自从切换为使用命令行,从来就没有出过问题。
转到:C:\Program Files\Google\google_appengine
执行CMD命令
启动调试服务器:python.exe dev_appserver.py (app目录)
上传代码:python.exe appcfg.py update (app目录)

论坛徽章:
4
金牛座
日期:2013-10-11 16:12:50卯兔
日期:2014-07-31 09:17:19辰龙
日期:2014-08-08 09:28:02狮子座
日期:2014-09-14 20:32:05
10 [报告]
发表于 2013-07-21 16:12 |只看该作者
回复 7# cdhigh


    又试了下,依然不行,真是奇了怪了。
  1. >>> with open('abc.txt', 'w') as f:
  2.         f.write('中华人民共和国,abc')

  3.        
  4. 11
  5. >>> with open('abc.txt', 'r',encoding = 'utf-8') as f:
  6.         print(f.readline())

  7.        
  8. Traceback (most recent call last):
  9.   File "<pyshell#14>", line 2, in <module>
  10.     print(f.readline())
  11.   File "D:\Python33\lib\codecs.py", line 300, in decode
  12.     (result, consumed) = self._buffer_decode(data, self.errors, final)
  13. UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd6 in position 0: invalid continuation byte
  14. >>>
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP