Archive for the 'Python' Category

用Google的Co-op服务创建了一个定制搜索引擎 “Mobile Python”

今天看了limodou在CU的帖子才知道Google的这个服务 google.com/coop/

limodou创建的是python.cn
google.com/coop/cse?cx=009376466705745340527%3Acpx…

我也创建了一个:Mobile Python,希望搜索Python在移动设备上的开发与应用。
google.com/coop/cse?cx=001459140553769941820%3Alss…

glade+pygtk学习 (3)

这几天用pygtk和glade写了一个不大的应用,在ubuntu下开发,然后移植到Maemo平台。

学习的过程中发现了SimpleGladeApp.py这个module,可以更方便地以面向对象的方式使用libgrade。

还记得serverinfo这个例子吗?里面是这样得到一个widget的实例的:

  1. self.wTree = gtk.glade.XML(self.gladefile, self.windowname) 
  2. self.logwindowview = self.wTree.get_widget("textview1")

用了SimpleGladeApp.py,直接用self.logwindowview就行了。

下面是改造serverinfo使用SimpleGladeApp.py的步骤:

1. 从 www.gnomefiles.org/app.php/SimpleGladeApp.py 下载SimpleGladeApp.py

2. 解压缩后把tepache这个脚本放到你的PATH环境变量指定的路径下,比如/usr/local/bin,然后加上执行权限。

3. 我们已经有现成的serverinfo.glade文件了,现在要做的是用tepache这个脚本解析glade文件来生成一个Python模块,里面是一些对应window或dialog等顶层widget的class,并实现他们的callback方法。命令如下(-o选项是为了不覆盖原来的serverinfo.py):

$ tepache serverinfo.glade -o serverinfo_new.py
written file serverinfo_new.py
$ ls
serverinfo.glade   serverinfo_new.py       serverinfo.py
serverinfo.gladep  serverinfo_new.py.orig  SimpleGladeApp.py

可以看到tepache生成了三个文件:serverinfo_new.py, serverinfo_new.py.orig, SimpleGladeApp.py
.orig文件很重要,tepache用这个文件保护你在serverinfo_new.py添加的代码,所以不要删除这个文件。

可以先运行serverinfo_new.py看看效果。

4. serverinfo_new.py的部分代码:

  1. ......
  2. # Warning: Do not modify any context comment such as #--
  3. # They are required to keep user's code
  4. ......
  5. from SimpleGladeApp import SimpleGladeApp
  6. from SimpleGladeApp import bindtextdomain
  7.  
  8. app_name = "serverinfo"
  9. app_version = "0.0.1"
  10.  
  11. glade_dir = ""
  12. locale_dir = ""
  13.  
  14. bindtextdomain(app_name, locale_dir)
  15.  
  16. class Serverinfo(SimpleGladeApp):
  17.  
  18.     def __init__(self, path="serverinfo.glade",
  19.                  root="serverinfo",
  20.                  domain=app_name, **kwargs):
  21.         path = os.path.join(glade_dir, path)
  22.         SimpleGladeApp.__init__(self, path, root, domain, **kwargs)
  23.  
  24.     #-- Serverinfo.new {
  25.     def new(self):
  26.         print "A new %s has been created" % self.__class__.__name__
  27.     #-- Serverinfo.new }
  28.  
  29.     #-- Serverinfo custom methods {
  30.     #   Write your own methods here
  31.     #-- Serverinfo custom methods }
  32.  
  33.     #-- Serverinfo.on_serverinfo_destroy {
  34.     def on_serverinfo_destroy(self, widget, *args):
  35.         print "on_serverinfo_destroy called with self.%s" % widget.get_name()
  36.     #-- Serverinfo.on_serverinfo_destroy }
  37. ......  
  38. #-- main {
  39.  
  40. def main():
  41.     serverinfo = Serverinfo()
  42.     demodialog = Demodialog()
  43.  
  44.     serverinfo.run()
  45.  
  46. if __name__ == "__main__":
  47.     main()
  48.  
  49. #-- main }

5. 现在就可以添加一些代码来实现serverinfo的功能了。注意不要修改形如#– Demodialog custom methods { 这样的注释,否则如果界面(glade文件)有了改动,tepache就没法做patch了。

把原来的insert_row改成ServerInfo类的一个方法,放在#– Serverinfo custom methods 注释之间。
goUrl方法也放在这里。 注意访问widget实例的方法已经由

host = self.wTree.get_widget("entry1").get_text()

变成

host = self.entry1.get_text()

main方法里的实例化Demodialog的语句要挪到button2的clicked事件响应方法里,不然程序一运行对话框就出现了,你刚才一定注意到了。

destroy响应方法里加入self.gtk_main_quit()以便窗口销毁时能够退出程序。

6. 现在运行serverinfo_new.py,原来serverinfo.py的功能基本上都有了。但有一个问题,对话框弹出后点击“确定”或“取消”按钮都不能关闭对话框。我的解决办法是不在glade设计这个对话框,完成在程序里用代码实现。

7. 注意每次重新设计了界面,修改了glade文件,都要运行tepache来patch生成的python模块,已做的修改不会被覆盖。

新的代码下载地址: guoyong.org/?dl=pygtk-learning-serverinfo-simplegl…

glade+pygtk学习 (2)

按照计划,今天参照这篇文章 Building an Application with PyGTK and Glade 学习。第一次使用menu和toolbar,进一步学习了tree/list view的使用,昨天还不太会用的dialog也学会了。

下载源代码: pygtk-learning-pywine.tgz

昨天遗留的几个问题也解决了:
1. 首先完成了那个dialog。虽然没什么功能,就算是复习一下dialog的实现方法吧。
2. 把ServerInfo程序的treeview内容改成显示http的header了。

  1. #get http headers, then insert into tree model
  2. data = page.read()
  3. headers = page.info()
  4. for name in headers.keys():
  5.     insert_row(self.treemodel, None, name, headers[name])

3. 把页面内容转换成unicode字符。用到了re模块去取页面meta标记里的字符集设置。

  1. import re, string
  2.        
  3. r = re.compile(r""".*content=['|"]?text/html;\s?charset=([a-zA-Z0-9\-]+)['|"]?.*""", re.S | re.I | re.M)
  4. m = r.match(data)
  5. if m:
  6.     charset = string.lower(m.group(1))
  7.     if charset != 'utf-8':
  8.         data = data.decode(charset, 'ignore').encode('utf-8', 'ignore')
  9.     else:
  10.         data = data.encode('utf-8', 'ignore')
  11. self.logwindow.set_text(data)

4. 用TexBuffer的set_text方法替代了insert_at_cursor。

新ServerInfo程序的源代码: pygtk-learning-serverinfo.tgz

glade+pygtk学习

今天上午参照 A Beginner’s Guide to Using pyGTK and Glade 这篇文章学习,感觉确实很好用。文章开始部分对比几种GUI开发库写得挺好,虽然是2003年写的。还有后面提到如何结合socket编程,正好要用到。

照着Demo实做了一遍,发现一些用法已经deprecated了:

  • gtk.TRUE - 用True就行了
  • gtk.mainquit - 换成gtk.main_quit
  • gtk.mainloop() - 换成gtk.main()

期间犯了个小错误,忘了在glade里为主窗口添加destroy信号,结果没法关闭窗口后没法退出程序。

显示含有中文的页面内容时会在下面这行代码报错,像是编码问题,先不深究了。

self.logwindow.insert_at_cursor(data, len(data))

自己用为Entry控件加了activate信号,响应回车事件。也准备试试如何显示对话框,还没有完成。

可以在这里下载Demo的源代码: guoyong.org/?dl=pygtk-demo.tgz

接下来计划按照这篇文章 [ www.learningpython.com/2006/05/30/building-an-appl... ]学习,然后准备自己动手写了。

一个把Rss Feed的编码方式由GB2312转成UTF-8的CGI脚本

今天设置自己的guoyong.org“>Planet站点,用CU的feed做试验,发现会乱码,原因是CU的feed是GB2312编码的。

google到一些资料,但好像并不能完全解决问题:

小林的blog,按照这个方法做没成功。

Web4C,我写完脚本才注意到这个搜索结果,但没找到planet源码里的planetlib.py文件。

我想到的土方法,写一个cgi脚本做proxy,取回feed后做转换编码方式再输出。

转码是这样完成的: str.decode('GBK').encode('UTF-8')

下载