Published at: 08:09 pm - Thursday September 02 2010
在豆瓣上看到一个无聊的秀gems的活动,我也无聊一下,秀一下eggs。 ls /usr/local/lib/python2.6/dist-packages/ | grep .egg | sed ‘s/\(.*\)/<li>\1<\/li>/’ amqplib-0.6.1-py2.6.egg argparse-1.1-py2.6.egg-info AuthKit-0.4.5-py2.6.egg avro-1.3.3-py2.6.egg Beaker-1.3-py2.6.egg Beaker-1.5.4-py2.6.egg beanstalkc-0.2.0-py2.6.egg bottle-0.8.1-py2.6.egg bottle-0.8.3-py2.6.egg bpython-0.9.6.2-py2.6.egg bson-0.1.2-py2.6.egg CherryPy-3.1.2-py2.6.egg CouchDB-0.6-py2.6.egg coverage-3.2-py2.6-linux-i686.egg Cython-0.12.1-py2.6-linux-i686.egg decorator-3.0.0-py2.6.egg distribute-0.6.14-py2.6.egg Django-1.0.2_final-py2.6.egg Django-1.1-py2.6.egg Django-1.2-py2.6.egg django_sphinx-2.2.3-py2.6.egg docutils-0.6-py2.6.egg Editra-0.4.95-py2.6.egg Editra-0.5.05-py2.6.egg Editra-0.5.72-py2.6.egg elementtree-1.2.7_20070827_preview-py2.6.egg eventlet-0.9.9-py2.6.egg Fabric-0.9.1-py2.6.egg fapws3-0.5.dev-py2.6-linux-i686.egg FormEncode-1.2.1-py2.6.egg GeoAlchemy-0.1-py2.6.egg Geohash-1.0rc1-py2.6.egg gevent-0.13.0.egg-info greenlet-0.3.1-py2.6-linux-i686.egg gunicorn-0.10.0-py2.6.egg gunicorn-0.11.0-py2.6.egg gunicorn-0.8.1-py2.6.egg httplib2-0.5.0-py2.6.egg ipython-0.10-py2.6.egg ipython-0.9.1-py2.6.egg Jinja2-2.5-py2.6.egg Mako-0.2.4-py2.6.egg Mako-0.3.4-py2.6.egg Markdoc-0.6.4-py2.6.egg-info Markdown-2.0.3-py2.6.egg Markdown-2.0.3-py2.6.egg-info [...]
Published at: 02:07 pm - Saturday July 31 2010
写了一个基本的pastebin放在appengine上: http://sunoffline.appspot.com/pb/ 支持纯文本、Markdown和代码高亮。数据永久保留,推荐大家收藏以备不时之需。 The post is brought to you by lekhonee v0.7
Published at: 09:07 pm - Wednesday July 21 2010
Bottle是一个Python web框架,兼容wsgi标准,lightweight,self-contained。 提到web框架,自然要和相类似的python框架相比。 Django是大型框架,包含ORM、Controller、Templating全套,这也是Django的缺点,使用Django意味着必须使用关系型数据库进行存储(尽管有一些Model层的其他实现,但绝大多数都是Hack的方式实现),必须使用Django并不非常出色的Template系统。Pylons针对Django的这些问题,采用了松散的方式,数据层可选择由SQLAlchemy实现,模板系统可以选择mako / jinja等。Pylons用paster来管理项目、创建代码模板。借鉴了rails的哲学,目录结构也相类似。可是pylons仍然显得重量级,把注意力放到web.py。只要定义一个router,定义相应的handler就可以处理web请求,handler对象的GET POST等方法分别对应相应的HTTP请求。看起来不错了,不过与bottle相比,webpy仍然显得繁琐、功能有限,而且它本身的db模块就更加鸡肋了。 看一个实例便知: 定义一个简单的HTTP页面: from bottle import Bottle, run, mako_view, request from bottle import FapwsServer myapp = Bottle() @myapp.route(’/nihao/:name/:count#\\d+#’) @mako_view(’nihao’) def nihao(name, count): return dict(n=name, c=int(count), ip=request.environ.get(’REMOTE_ADDR’)) run(app=myapp, server=FapwsServer) 对应的nihao.tpl模板,用mako引擎实现: <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>Nihao</title> </head> <body> <div id="ip"> [...]
Published at: 10:07 pm - Sunday July 04 2010
Exaile doubanfm plugin 0.0.2 预览版,目标是在Linux桌面提供豆瓣电台的完整体验。 目前插件只能运行在Exaile 0.3.1版本上。 0.0.2增加了豆瓣电台专用的视图: 相比第一版通过rating来实现豆瓣电台喜欢、跳过和删除的功能,在专用视图上有专门的按钮来操作。 其他细节更新: 当剩余曲目超过15首时不再增加播放列表 当播放到最后一首歌曲取新播放列表时增加重试机制 修正libdbfm跳过曲目bug一个 安装: 打开Exaile Preference,Plugin页,点击按钮Install Plugin,选择doubanfm.exz即可。如果存在问题,可以执行以下命令: mv doubanfm.exz douban.tar.gz tar xf doubanfm.tar.gz mv doubanfm ~/.local/share/exaile/plugins/ 转到doubanfm设置页面,填写用户名密码重启Exaile。 打开File菜单,选择豆瓣电台频道 选择曲目就可以开始播放了,选择视图中豆瓣电台视图可以切换到豆瓣电台视图。 项目地址: http://github.com/sunng87/exaile-doubanfm-plugin 下载: http://github.com/sunng87/exaile-doubanfm-plugin/downloads 另外,doubancovers插件也有一个针对豆瓣电台的更新可以快速获取豆瓣电台音乐的封面: http://bitbucket.org/sunng/exailedoubancovers/downloads?highlight=9265 The post is brought to you by lekhonee v0.7
Published at: 06:07 pm - Friday July 02 2010
豆瓣电台一直是flash客户端,嵌入浏览器,出于对flash的厌恶,本人开发了这个exaile插件,让广大linux同学在exaile里享受豆瓣电台一目了然桌面集成和全部豆瓣电台功能。 exaile-doubanfm-plugin features: 登录豆瓣,获取豆瓣电台播放列表 持续下载电台播放列表,实现不重复的持续播放 标记/取消“喜爱”、标记“回收站”、跳过 显示歌曲信息 项目地址: http://github.com/sunng87/exaile-doubanfm-plugin 下载页: http://github.com/sunng87/exaile-doubanfm-plugin/downloads 使用: 激活插件,填写用户名密码 重启exaile 文件菜单,open douban.fm,选择频道 点击播放开始 将rating设置为5 标记喜欢 rating设置2 豆瓣标准跳过 rating设置1 豆瓣删除 The post is brought to you by lekhonee v0.7
Published at: 10:06 pm - Saturday June 05 2010
除了用inetface库和分析ifconfig输出以外,一个比较简单的获取本机IP的方法: import socket def get_local_ip(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("sdo.com",80)) return s.getsockname()[0] 参考 http://stackoverflow.com/questions/166506/finding-local-ip-addresses-in-python
Published at: 12:03 pm - Monday March 22 2010
升级10.04之后,gwibber2.29开始使用pycurl来处理IO。结果一条更新都拿不下来,为此搜到很多相关、不相关的bug。最后终于自己找到问题,原来是pycurl.setopt方法传入字符串如果是unicode就会报typeerror。而通过gwibber配置界面输入的所有字符都是unicode编码,于是问题也就简单了。做个处理,在 /usr/lib/python2.6/dist-packages/gwibber/microblog/network.py 第18到21行: self.curl.setopt(pycurl.URL, str(url).encode(’ascii’)) if username and password: self.curl.setopt(pycurl.USERPWD, ("%s:%s" % (username, password)).encode(’ascii’)) 另外,使用StatusNet的Twitter兼容API来做Twitter API代理,需要把代理的目录名设置为api,因为/api这个路径是写死在gwibber代码里的。通过界面输入的,只是代理的domain。 说实在的gwibber还是挺烂的。 https://bugs.launchpad.net/bugs/542501 https://bugs.launchpad.net/bugs/543860
Published at: 04:02 pm - Friday February 12 2010
Very glad to announce another daily-coding work: an extension for gnome deskbar applet to search and launch virtual machine. There is a plugin for gnome-do that does the same job. That’s what I create the the plugin for. I switched to deskbar because gnome-do’s Do.exe reminds me nightmares when I was a M$ Windows user. [...]
Published at: 01:02 pm - Friday February 12 2010
I’m sorry for the long title. Due to lack of documentation, it’s not easy to use python xpcom api from virtualbox sdk. The code below is just a sample that lists your installed virtual machines. It works on linux with VirtualBox OSE 2.0.8. Hope useful to you. import vboxapi vmsg = vboxapi.VirtualBoxManager(None, None) vbox = [...]
Published at: 11:01 pm - Monday January 04 2010
最近琢磨OAuth认证方式。OAuth的优点主要在于 用户不需要直接提供用户名密码给第三方应用,就可以让第三方应用访问受限资源; 资源提供方对第三方应用有更细粒度的控制。 在整个OAuth协议里,生成signature的base string是最容易出错的部分。它由HTTP方法名、URL编码的请求路径和请求的参数表组成。 请求的参数表是除去oauth_signature以外的所有参数,按参数名排序,并进行url转义 def to_signature_key(method, url, data): keys = list(data.keys()) keys.sort() encoded = urllib.quote(“&”.join([key+"="+data[key] for key in keys])) return “&”.join([method, urllib.quote(url, safe="~"), encoded]) 有了这个通用的生成signature base string的方法,以后就可以根据OAuth协议规范按步骤进行。 首先获取Request Token。这一步通常使用资源提供方注册的API Key和API Key Secret def request_token_params(consumer_key, consumer_secret, path, method=’GET’): data={} data['oauth_consumer_key']=consumer_key data['oauth_signature_method']=’HMAC-SHA1′ data['oauth_timestamp']=str(int(time.time())) data['oauth_nonce']=”.join([str(random.randint(0,9)) for i in range(10)]) print data msg = to_signature_key(method, path, data) [...]