Posts Tagged ‘python’

Exaile-doubanfm-plugin 0.0.2

07月 4, 2010

Exaile doubanfm plugin 0.0.2 预览版,目标是在Linux桌面提供豆瓣电台的完整体验。

目前插件只能运行在Exaile 0.3.1版本上。

0.0.2增加了豆瓣电台专用的视图:
screenshot_001

相比第一版通过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。
screenshot_002

打开File菜单,选择豆瓣电台频道
screenshot_001

选择曲目就可以开始播放了,选择视图中豆瓣电台视图可以切换到豆瓣电台视图。

项目地址:
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

exaile豆瓣电台插件(exaile-doubanfm-plugin)

07月 2, 2010

豆瓣电台一直是flash客户端,嵌入浏览器,出于对flash的厌恶,本人开发了这个exaile插件,让广大linux同学在exaile里享受豆瓣电台一目了然桌面集成和全部豆瓣电台功能。

exaile-doubanfm-plugin features:

  • 登录豆瓣,获取豆瓣电台播放列表
  • 持续下载电台播放列表,实现不重复的持续播放
  • 标记/取消“喜爱”、标记“回收站”、跳过
  • 显示歌曲信息

screenshot_001

screenshot_002

screenshot_002

项目地址:
http://github.com/sunng87/exaile-doubanfm-plugin

下载页:
http://github.com/sunng87/exaile-doubanfm-plugin/downloads

使用:

  1. 激活插件,填写用户名密码
  2. 重启exaile
  3. 文件菜单,open douban.fm,选择频道
  4. 点击播放开始
  5. 将rating设置为5 标记喜欢
  6. rating设置2 豆瓣标准跳过
  7. rating设置1 豆瓣删除

The post is brought to you by lekhonee v0.7

Python获取本机IP

06月 5, 2010

除了用inetface库和分析ifconfig输出以外,一个比较简单的获取本机IP的方法:
[cc lang="python"]
import socket
def get_local_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((“sdo.com”,80))
return s.getsockname()[0]
[/cc]

参考 http://stackoverflow.com/questions/166506/finding-local-ip-addresses-in-python

搞定gwibber

03月 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行:
[cc lang="python"]
self.curl.setopt(pycurl.URL, str(url).encode(‘ascii’))

if username and password:
self.curl.setopt(pycurl.USERPWD, (“%s:%s” % (username, password)).encode(‘ascii’))
[/cc]

另外,使用StatusNet的Twitter兼容API来做Twitter API代理,需要把代理的目录名设置为api,因为/api这个路径是写死在gwibber代码里的。通过界面输入的,只是代理的domain。

说实在的gwibber还是挺烂的。

https://bugs.launchpad.net/bugs/542501

https://bugs.launchpad.net/bugs/543860

Virtual Machine Searcher for Gnome Deskbar Applet

02月 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. The deskbar applet has been a great replacement, however, the virtualbox plugin in Do is really impressive while deskbar doesn’t provide me the same functionality.

You can ignore words above and just take a look at the screenshot:
deskbar-virtualbox

Download

Download the extension from (the highlighted one):
http://bitbucket.org/sunng/daily-coding/downloads/?highlight=5137

You can also trace the development at bitbucket project. However, the repository is mixed with other small code snippets. Currently, mercurial doesn’t support subdirectory pull. So there is no way to grab the deskbar-applet individually.

Installation

copy this file to /usr/lib/deskbar-applet/deskbar-applet/modules-2.20-compatible/ (Ubuntu installation for example) with super user privilege. Right click desktbar applet, select Preference, Searchers tab, hit “Reload” button, then check the Virtualbox Deskbar Module.
deskbar-preference

Issue

Feel free the report issues on bitbucket:
http://bitbucket.org/sunng/daily-coding/issues/

List your installed virtualbox virtual marchines using vbox python xpcom api

02月 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.
[cc lang="python"]
import vboxapi
vmsg = vboxapi.VirtualBoxManager(None, None)
vbox = vmsg.vbox
vmsg.mgr.getSessionObject(vbox)
machs = vbox.getMachines()
names = map(lambda x: (x.name,x.id), machs)
print names
[/cc]
Output:
[cc lang="python" nowrap="false" line_numbers="false"]
[(u'Ubuntu', u'aac3fd46-4f1e-4f6e-8abe-b1a5516abf8c'), (u'Windows', u'fa73952e-f0a6-4bf0-af20-259513d73bc1'), (u'OpenSolaris', u'a951542c-3178-4a6b-8087-f1b0314e283a'), (u'LinuxMint', u'8191f256-1b76-4ce7-a202-93730dae1b33'), (u'Fedora', u'ca250f45-d752-4baf-9281-fb0847dc8287'), (u'Freebsd', u'8322b62a-aed5-4f04-9815-9fadfeba9fe1'), (u'ArchLinux', u'efc1167a-4e06-4c14-aeb0-bfb303c8f5f7'), (u'openSUSE', u'02e18816-311d-420b-99b3-6b4b4cccf7b7'), (u'CentOS', u'ccf0421c-85c4-4123-8722-57abc494c633')]
[/cc]

OAuth Step by Step

01月 4, 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)
	print msg

	signed = base64.b64encode(hmac.new(consumer_secret+"&", msg, hashlib.sha1).digest())
	print signed
	data['oauth_signature']=signed
	return data

def result2dict(result_string):
	d = {}
	params = res.split('&')
	for p in params:
		d[p.split('=')[0]] = p.split('=')[1]
	return d

conn = httplib.HTTPConnection("www.douban.com", 80)

params = request_token_params(consumer_key, consumer_secret, request_token_path)
conn.request('GET', request_token_path+"?"+urllib.urlencode(params))
res = conn.getresponse().read()
print res
request_token = result2dict(res)

这一步可以获得未经认证的Request Token和Request Token Secret。需要注意的细节是在计算hmac签名的时候,即使只有一个Token Secret,仍然需要加上”&”

第二步要求用户授权该Request Token,打开浏览器,将用户定向到相应的授权页面,参数为上一步获得的Request Token

第三步,用授权过的Request Token换取Access Token。这一步类似第一步,只是用于签名的token包括API Key Secret和Request Token

def access_token_params(consumer_key, consumer_secret, oauth_token, oauth_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)])
	data['oauth_token'] = oauth_token

	msg = to_signature_key(method, path, data)
	print msg

	signed = base64.b64encode(hmac.new(consumer_secret+"&"+oauth_secret, msg, hashlib.sha1).digest())
	print signed
	data['oauth_signature']=signed
	return data

params = access_token_params(consumer_key, consumer_secret, request_token['oauth_token'],
	request_token['oauth_token_secret'], access_token_path)
conn.request('GET', access_token_path+"?"+urllib.urlencode(params))
res = conn.getresponse().read()
print res
access_token = result2dict(res)

这一步将至少返回Access Token和Access Token Secret,是最终用于访问受限资源的Token。以豆瓣的实现为例,OAuth的相关参数应放在HTTP头里随请求进行发送。

def oauth_header(consumer_key, consumer_secret, oauth_token, oauth_secret, path, realm):
	data = access_token_params(consumer_key, consumer_secret, oauth_token, oauth_secret, path, method="POST")
	header_string = ','.join([key+'="'+data[key]+'"' for key in data.keys()])
	return 'OAuth realm="'+realm+'",'+header_string

posturl = 'http://api.douban.com/miniblog/saying'

content = """<?xml version='1.0' encoding='UTF-8'?>
<entry xmlns:ns0="http://www.w3.org/2005/Atom" xmlns:db="http://www.douban.com/xmlns/">
<content>li lei ju le han mei mei</content>
</entry>
"""

header = {}
header['Authorization'] = oauth_header(consumer_key, consumer_secret,
		access_token['oauth_token'], access_token['oauth_token_secret'],
		posturl, "http://api.douban.com")
header['Content-Type'] = 'application/atom+xml'
print header

conn.request('POST', posturl, content, header)
res = conn.getresponse().read()

print res

conn.close()

在这一步中,用于生成signature base string的url是要访问的受限资源地址,而签名的参数表依然是oauth相关的参数。
生成的Authorization头如下

Authorization: OAuth realm="http://api.douban.com",
    oauth_nonce="8735717688",
    oauth_timestamp="1262613619",
    oauth_consumer_key="0bc081a01168b263234184e0343a1729",
    oauth_signature_method="HMAC-SHA1",
    oauth_token="5fb836c37543ad691f28a44a5fcb083b",
    oauth_signature="jk6p5qaXVPrGQctSzpO5jjYHfDk="

用这个头就可以在一定的时间内访问所有授权范围内的受限资源。

代码是ugly了一些,不过应该相对易于理解吧。

在RHEL4上搭建Python/Lighttpd/FastCGI环境

11月 27, 2009

在一台赤裸裸的RHEL4上部署web.py程序,一切从几乎是从零开始。以下操作均以root用户操作。

1. 安装MySQL数据库

下载安装MySQL
wget http://dev.mysql.com/get/Downloads/MySQL-5.1/mysql-5.1.41-linux-i686-glibc23.tar.gz/from/http://mirror.services.wisc.edu/mysql/
解压,按照INSTALL文件说明进行安装,不多赘述

2. 安装Python环境

下载Python源码

wget http://www.python.org/ftp/python/2.6.4/Python-2.6.4.tar.bz2
解压,编译安装,不需要特殊操作。

下载Easy_install

wget http://pypi.python.org/packages/2.6/s/setuptools/setuptools-0.6c11-py2.6.egg
安装
sh setuptools-0.6c11-py2.6.egg

安装相关Packages

easy_install DBUtils
easy_install flup
easy_install web.py

安装mysql-python

mysql-python包不能用easy_install安装,手动下载
wget http://downloads.sourceforge.net/project/mysql-python/mysql-python-test/1.2.3b1/MySQL-python-1.2.3b1.tar.gz?use_mirror=softlayer
加压,编辑site.cfg
指定mysql_config的路径,注意是新安装的mysql路径
mysql_config=/usr/local/mysql/bin/mysql_config
编译、安装
python setup.py build
python setup.py install

声明libmysqlclient路径
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/mysql/lib

3. 安装服务器环境

下载安装fastcgi头文件

wget http://www.fastcgi.com/dist/fcgi.tar.gz
解压,默认编译安装

下载安装PCRE

wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.00.tar.bz2
解压,默认编译安装

下载lighttpd

wget http://download.lighttpd.net/lighttpd/releases-1.4.x/lighttpd-1.4.25.tar.bz2
configure时指定–prefix=/usr/local/lighttpd
编译,安装

4. 配置

lighttpd fastcgi运行web.py程序请参考
http://www.classicning.com/blog/2009/11/lighttpd%e9%80%9a%e8%bf%87fastcgi%e8%bf%90%e8%a1%8cweb-py%e7%a8%8b%e5%ba%8f/

非常重要的几点注意:

  • 通过fastcgi运行的python脚本必须具有可执行权限, chmod u+x web/main.py
  • 重启fastcgi程序需要删除/tmp/fastcgi.socket*

任何Python程序出错、权限错误都会导致lighttpd这样的报错:
2009-11-27 18:12:02: (mod_fastcgi.c.1108) child exited with status 13 /home/admin/web/main.py
2009-11-27 18:12:02: (mod_fastcgi.c.1111) If you’re trying to run your app as a FastCGI backend, make sure you’re using the FastCGI-enabled version.
If this is PHP on Gentoo, add ‘fastcgi’ to the USE flags.
2009-11-27 18:12:02: (mod_fastcgi.c.1399) [ERROR]: spawning fcgi failed.
2009-11-27 18:12:02: (server.c.931) Configuration of plugins failed. Going down.

报错会提示fastcgi未正确安装,而实际上仅仅是程序错误或权限问题而已。

Exaile-DoubanCover 0.0.2

11月 22, 2009

The Exaile plugin “Douban Covers” has been upgraded to 0.0.2. Now there is a new preference pane inside exaile preference dialog. This update provides you an optional choice to specify your own apikey when access douban.com open api. With an apikey, your request frequency will be raised to 40 times per minute.

Again, you can get the plugin from:
http://bitbucket.org/sunng/exailedoubancovers/downloads/

Grab source with mercurial:
hg close http://bitbucket.org/sunng/exailedoubancovers/

Also, exaile-cn has its first 0.3.0-compatible version released early today. As a part of Exaile-cn, Exaile-Doubancovers 0.0.1 has been packaged into the public release for the first time. Find the project at: http://code.google.com/p/exaile-cn/

Use pipe in subprocess

11月 12, 2009

问题:

您要通过python的subprocess模块执行一些命令,要在程序中获得命令的标准输出,此外,命令中还有管道操作。

解决:

以这个命令为例:
cat /home/admin/deploy/log/2009-11-11.log |grep example.com |wc -l

import subprocess

cmd1 = 'cat /home/admin/deploy/log/2009-11-11.log'
cmd2 = 'grep example.com'
cmd3 = 'wc -l'

pipe1 = subprocess.Popen(cmd1.split(), stdout=subprocess.PIPE)
pipe2 = subprocess.Popen(cmd2.split(), stdin=pipe1, stdout=subprocess.PIPE)
pipe3 = subprocess.Popen(cmd3.split(), stdin=pipe2, stdout=subprocess.PIPE)

result = pipe3.communicate()[0]

加关注

Get every new post delivered to your Inbox.