<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>阳春面的学习摘录 &#187; python</title>
	<atom:link href="http://chenyc.info/category/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://chenyc.info</link>
	<description>人生是一个不断折腾的过程，生命不息，折腾不止</description>
	<lastBuildDate>Mon, 06 Feb 2012 12:48:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>新浪SAE python试用</title>
		<link>http://chenyc.info/2011/12/sae-python-try/</link>
		<comments>http://chenyc.info/2011/12/sae-python-try/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 12:45:48 +0000</pubDate>
		<dc:creator>阳春面</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[sae]]></category>

		<guid isPermaLink="false">http://chenyc.info/?p=785</guid>
		<description><![CDATA[新浪目前提供SAE python版本的内测，内测帐号可以到http://appstack.sinaapp.com/queue申请， 一般估计5分钟左右就可以开通了，开通后没有任何提示，你要自己去SAE里新建项目，看能不能新建python项目了 通过sae python的文档，目前已支持以下几种web框架，比java版的进展快多了 Django Flask Bottle Tornado Uliweb web.py 比较了这几种框架，准备采用Flask作为自己的框架，因为比较简单，灵活性大，学习成本低。而且在SAE都只是做一些个人学习研究性的项目，不需要太复杂的功能。 目前已在本地配置好环境，参考dev-server的安装说明 准备做一下个保存WIKI条目的列表（如百家姓等），通过JSON格式输出，由Android手机端调用显示，并跳转到具体的WIKI页面。 另外目前维基百科访问时，有时候链接会被重置，跟Google一样，这是个头疼的问题，SAE在国内，也不能作为代理访问，这个只能到时候再看了。]]></description>
			<content:encoded><![CDATA[<p>新浪目前提供SAE python版本的内测，内测帐号可以到<a href="http://appstack.sinaapp.com/queue">http://appstack.sinaapp.com/queue</a>申请，</p>
<p>一般估计5分钟左右就可以开通了，开通后没有任何提示，你要自己去SAE里新建项目，看能不能新建python项目了</p>
<p>通过<a href="&lt;a href=&quot;http://appstack.sinaapp.com/static/doc/release/testing/index.html#&quot;&gt;http://appstack.sinaapp.com/static/doc/release/testing/index.html#&lt;">sae python的文档</a>，目前已支持以下几种web框架，比java版的进展快多了</p>
<ul>
<li><a href="http://appstack.sinaapp.com/static/doc/release/testing/framework.html#django">Django</a></li>
<li><a href="http://appstack.sinaapp.com/static/doc/release/testing/framework.html#flask">Flask</a></li>
<li><a href="http://appstack.sinaapp.com/static/doc/release/testing/framework.html#bottle">Bottle</a></li>
<li><a href="http://appstack.sinaapp.com/static/doc/release/testing/framework.html#tornado">Tornado</a></li>
<li><a href="http://appstack.sinaapp.com/static/doc/release/testing/framework.html#uliweb">Uliweb</a></li>
<li><a href="http://appstack.sinaapp.com/static/doc/release/testing/framework.html#web-py">web.py</a></li>
</ul>
<p>比较了这几种框架，准备采用<a href="http://appstack.sinaapp.com/static/doc/release/testing/framework.html#flask">Flask</a>作为自己的框架，因为比较简单，灵活性大，学习成本低。而且在SAE都只是做一些个人学习研究性的项目，不需要太复杂的功能。</p>
<p>目前已在本地配置好环境，参考<a href="http://appstack.sinaapp.com/static/doc/release/testing/runtime.html#dev-server">dev-server</a>的安装说明</p>
<p>准备做一下个保存WIKI条目的列表（如百家姓等），通过JSON格式输出，由Android手机端调用显示，并跳转到具体的WIKI页面。</p>
<p>另外目前<a href="http://zh.wikipedia.org">维基百科</a>访问时，有时候链接会被重置，跟Google一样，这是个头疼的问题，SAE在国内，也不能作为代理访问，这个只能到时候再看了。</p>
]]></content:encoded>
			<wfw:commentRss>http://chenyc.info/2011/12/sae-python-try/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>python生成sitemap</title>
		<link>http://chenyc.info/2010/10/python-gen-sitemap/</link>
		<comments>http://chenyc.info/2010/10/python-gen-sitemap/#comments</comments>
		<pubDate>Mon, 18 Oct 2010 16:10:48 +0000</pubDate>
		<dc:creator>阳春面</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[sitemap]]></category>

		<guid isPermaLink="false">http://chenyc.info/?p=145</guid>
		<description><![CDATA[为最优阅读网编写了一个sitemap自动生成的脚本, 主要是读取数据库中的文章列表，然后根据sitemap格式生成， 最后再通知google sitemap已经更新 #!/usr/bin/python import MySQLdb,time,os url_list = [] #zuiyou.info m1 = {} m1[&#34;loc&#34;]=&#34;http://zuiyou.info&#34; m1[&#34;lastmod&#34;]=time.strftime(&#039;%Y-%m-%d&#039;,time.localtime(time.time())) m1[&#34;changefreq&#34;]=&#34;daily&#34; m1[&#34;priority&#34;]=&#34;1.0&#34; url_list.append(m1) #www.zuiyou.info m1 = {} m1[&#34;loc&#34;]=&#34;http://www.zuiyou.info&#34; m1[&#34;lastmod&#34;]=time.strftime(&#039;%Y-%m-%d&#039;,time.localtime(time.time())) m1[&#34;changefreq&#34;]=&#34;daily&#34; m1[&#34;priority&#34;]=&#34;1.0&#34; url_list.append(m1) #visit database conn = MySQLdb.connect (host=&#34;127.0.0.1&#34;, user=&#34;username&#34;,passwd=&#34;password&#34;, db=&#34;dbname&#34;) cursor = conn.cursor() cursor.execute &#8230; <a href="http://chenyc.info/2010/10/python-gen-sitemap/">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>为<a href="http://zuiyou.info">最优阅读网</a>编写了一个sitemap自动生成的脚本,<br />
主要是读取数据库中的文章列表，然后根据sitemap格式生成，<br />
最后再通知google sitemap已经更新</p>
<pre>

#!/usr/bin/python
import MySQLdb,time,os
url_list = []

#zuiyou.info
m1 = {}
m1[&quot;loc&quot;]=&quot;http://zuiyou.info&quot;
m1[&quot;lastmod&quot;]=time.strftime(&#039;%Y-%m-%d&#039;,time.localtime(time.time()))
m1[&quot;changefreq&quot;]=&quot;daily&quot;
m1[&quot;priority&quot;]=&quot;1.0&quot;
url_list.append(m1)

#www.zuiyou.info
m1 = {}
m1[&quot;loc&quot;]=&quot;http://www.zuiyou.info&quot;
m1[&quot;lastmod&quot;]=time.strftime(&#039;%Y-%m-%d&#039;,time.localtime(time.time()))
m1[&quot;changefreq&quot;]=&quot;daily&quot;
m1[&quot;priority&quot;]=&quot;1.0&quot;
url_list.append(m1)

#visit database
conn = MySQLdb.connect (host=&quot;127.0.0.1&quot;, user=&quot;username&quot;,passwd=&quot;password&quot;, db=&quot;dbname&quot;)
cursor = conn.cursor()
cursor.execute (&quot;SELECT siteid,articleid,lastupdate from jieqi_article_article&quot;)
rows = cursor.fetchall()
cursor.close()
for row in rows:
    m1={}
    m1[&quot;loc&quot;]=&quot;http://zuiyou.info/files/article/html/&quot;+row[0].__str__()+&quot;/&quot;+row[1].__str__()+&quot;/index.html&quot;
    m1[&quot;lastmod&quot;] = time.strftime(&quot;%Y-%m-%d&quot;, time.gmtime(row[2]))
    m1[&quot;changefreq&quot;]=&quot;daily&quot;
    m1[&quot;priority&quot;]=&quot;1.0&quot;
    url_list.append(m1)

    m1={}
    m1[&quot;loc&quot;]=&quot;http://zuiyou.info/book/&quot;+row[1].__str__()+&quot;.html&quot;
    m1[&quot;lastmod&quot;] = time.strftime(&quot;%Y-%m-%d&quot;, time.gmtime(row[2]))
    m1[&quot;changefreq&quot;]=&quot;monthly&quot;
    m1[&quot;priority&quot;]=&quot;0.8&quot;
    url_list.append(m1)

f = open(&quot;/home/wwwroot/zuiyou.info/sitemap.xml&quot;, &quot;w&quot;)

f.write(&quot;&lt;!-- generator=\&quot;chenyc\&quot; --&gt;\n&quot;)
f.write(&quot;&lt;!-- sitemap-generator-url=\&quot;http://zuiyou.info\&quot; sitemap-generator-version=\&quot;3.2.4\&quot; --&gt;\n&quot;)
f.write(&quot;&lt;!-- generated-on=\&quot;&quot;+time.strftime(&quot;%Y-%m-%d %H:%M:%S&quot;, time.localtime(time.time()))+&quot;\&quot; --&gt;\n&quot;)

f.write(&quot;&lt;urlset xmlns=\&quot;http://www.sitemaps.org/schemas/sitemap/0.9\&quot; &quot;)
f.write(&quot;xmlns:xsi=\&quot;http://www.w3.org/2001/XMLSchema-instance\&quot; &quot;)
f.write(&quot;xsi:schemaLocation=\&quot;http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd\&quot;&gt;\n&quot;)

for m in url_list:
    f.write(&quot;&lt;url&gt;\n&quot;)
    f.write(&quot;   &lt;loc&gt;&quot;+m[&quot;loc&quot;]+&quot;&lt;/loc&gt;\n&quot;)
    f.write(&quot;   &lt;lastmod&gt;&quot;+m[&quot;lastmod&quot;]+&quot;&lt;/lastmod&gt;\n&quot;)
    f.write(&quot;   &lt;changefreq&gt;&quot;+m[&quot;changefreq&quot;]+&quot;&lt;/changefreq&gt;\n&quot;)
    f.write(&quot;   &lt;priority&gt;&quot;+m[&quot;priority&quot;]+&quot;&lt;/priority&gt;\n&quot;)
    f.write(&quot;&lt;/url&gt;\n&quot;)

f.write(&quot;&lt;/urlset&gt;&quot;)
f.close()

#ping google
os.system(&quot;wget -qO - http://www.google.com/webmasters/sitemaps/ping?sitemap=http://zuiyou.info&quot;)
</pre>
]]></content:encoded>
			<wfw:commentRss>http://chenyc.info/2010/10/python-gen-sitemap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>对yupoo api的python封装</title>
		<link>http://chenyc.info/2010/02/yupoo-api-python/</link>
		<comments>http://chenyc.info/2010/02/yupoo-api-python/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 13:03:08 +0000</pubDate>
		<dc:creator>阳春面</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[yupoo]]></category>

		<guid isPermaLink="false">http://chenyc.info/?p=29</guid>
		<description><![CDATA[对yupoo api的python封装，2007的时候写的了， 那时候写了用来在nokia s60手机上上传照片到yupoo, 也是第一次接触xmlrpc,rest方式的调用。 yupoo.py,对yupoo api的封装 #-------------------------------------------------------------------- # -*- coding: utf-8 -*- # Name: yupoo api for python # Purpose: yupoo api for python # # Author: chenyc # Created: 22-06-2007 # Copyright: (c) chenyc 2007 # Licence: GNU &#8230; <a href="http://chenyc.info/2010/02/yupoo-api-python/">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>对yupoo api的python封装，2007的时候写的了，<br />
那时候写了用来在nokia s60手机上上传照片到yupoo,<br />
也是第一次接触xmlrpc,rest方式的调用。</p>
<p><strong>yupoo.py</strong>,对yupoo api的封装</p>
<pre>

#--------------------------------------------------------------------
# -*- coding: utf-8 -*-
# Name:        yupoo api for python
# Purpose:     yupoo api for python
#
# Author:      chenyc
# Created:     22-06-2007
# Copyright:   (c) chenyc 2007
# Licence:     GNU
#--------------------------------------------------------------------

import yupoo_helper,urllib,httplib,os
config=yupoo_helper.config
def login(username,password):
    opener=yupoo_helper.bulid_opener()
    login_url=&#039;http://www.yupoo.com/account/auth/&#039;
    postdata=urllib.urlencode({&#039;j_username&#039;:username,&#039;j_password&#039;:password,&#039;j_remember_me&#039;:&#039;1&#039;})
    opener.open(login_url,postdata)
    return opener

def user_auth(username,password,perms,frob):
    opener=login(username,password)
    auth_url=&#039;http://www.yupoo.com/services/auth/?&#039;
    params={&#039;api_key&#039;:config[&#039;api_key&#039;],&#039;frob&#039;:frob,&#039;perms&#039;:perms}
    api_sig=yupoo_helper.sig(yupoo_helper.join_params(params))
    auth_url=auth_url+&#039;api_key=&#039;+config[&#039;api_key&#039;]+&#039;&amp;frob=&#039;+frob+&#039;&amp;perms=&#039;+perms+&#039;&amp;api_sig=&#039;+api_sig
    opener.open(auth_url)

def auth_set_perms(username,password,perms):
    a=Auth()
    frob=a.auth_getFrob()[&#039;frob&#039;]
    user_auth(username,password,perms,frob)
    auth_info=a.auth_getToken(frob)
    config[&#039;auth_token&#039;]=auth_info[&#039;token&#039;]
    yupoo_helper.set_config(config)
    return auth_info

def auth_get_FullToken(mini_token):
    a=Auth()
    auth_info=a.auth_getFullToken(mini_token)
    config[&#039;auth_token&#039;]=auth_info[&#039;token&#039;]
    yupoo_helper.set_config(config)
    return auth_info

def auth_checkToken(auth_token):
    a=Auth()
    auth_info=a.auth_checkToken(auth_token)
    return auth_info

class Auth:
    def auth_getFrob(self):
        method_name=&#039;yupoo.auth.getFrob&#039;
        params={}
        return  yupoo_helper.call_method(method_name,params,True)

    def auth_getToken(self,frob):
        method_name=&#039;yupoo.auth.getToken&#039;
        params={&#039;frob&#039;:frob}
        return  yupoo_helper.call_method(method_name,params,True)

    def auth_getFullToken(self,mini_token):
        method_name=&#039;yupoo.auth.getFullToken&#039;
        params={&#039;mini_token&#039;:mini_token}
        return yupoo_helper.call_method(method_name,params,True)

    def auth_checkToken(self,auth_token):
        method_name=&#039;yupoo.auth.checkToken&#039;
        params={&#039;auth_token&#039;:auth_token}
        return  yupoo_helper.call_method(method_name,params,True)

class YupooAPI:
    def __init__(self,api_key,shared_secret,username=&#039;&#039;,password=&#039;&#039;,perms=&#039;delete&#039;):
        if config[&#039;api_key&#039;]== api_key and config[&#039;shared_secret&#039;]==shared_secret \
        and config[&#039;perms&#039;]==perms and config[&#039;auth_token&#039;]&lt;&gt;&#039;?&#039;:
            auth_info=auth_checkToken(config[&#039;auth_token&#039;])
        else:
            self.set_api_info(api_key,shared_secret,perms)
            auth_info=auth_set_perms(username,password,perms)
        self.auth_token=auth_info[&#039;token&#039;]
        self.user_id=auth_info[&#039;user&#039;][&#039;id&#039;]
        self.callmethod=yupoo_helper.call_method

    def blogs_getList(self):
        method_name=&#039;yupoo.blogs.getList&#039;
        params={}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def blogs_postPhoto(self,blog_id,photo_id,title,description,blog_password=&#039;&#039;):
        method_name=&#039;yupoo.blogs.postPhoto&#039;
        params={&#039;blog_id&#039;:blog_id,&#039;photo_id&#039;:photo_id,&#039;title&#039;:title,
                &#039;description&#039;:description}
        if blog_password&lt;&gt;&#039;&#039;:
            paramsp[&#039;blog_password&#039;]=blog_password

        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def contacts_getList(self,filter=&#039;&#039;):
        method_name=&#039;yupoo.contacts.getList&#039;
        params={}
        if filter&lt;&gt;&#039;&#039;:
            params={&#039;filter&#039;:filter}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def contacts_getPublicList(self,user_id=&#039;&#039;):
        if user_id==&#039;&#039;:
            user_id=self.user_id
        method_name=&#039;yupoo.contacts.getPublicList&#039;
        params={&#039;user_id&#039;:user_id}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def favorites_add(self,photo_id):
        method_name=&#039;yupoo.favorites.add&#039;
        params={&#039;photo_id&#039;:photo_id}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def favorites_getList(self,user_id=&#039;&#039;,per_page=&#039;100&#039;,page=&#039;1&#039;):
        if user_id==&#039;&#039;:
            user_id=self.user_id
        method_name=&#039;yupoo.favorites.getList&#039;
        params={&#039;per_page&#039;:per_page,&#039;page&#039;:page}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def favorites_remove(self,photo_id):
        method_name=&#039;yupoo.favorites.remove&#039;
        params={&#039;photo_id&#039;:photo_id}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def groups_getList(self):
        method_name=&#039;yupoo.groups.getList&#039;
        params={}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def groups_pools_getContext(self,photo_id,group_id):
        method_name=&#039;yupoo.groups.pools.getContext&#039;
        params={&#039;photo_id&#039;:photo_id,&#039;group_id&#039;:group_id}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def groups_pools_getPhotos(self,group_id,tags=&#039;&#039;,user_id=&#039;&#039;,per_page=&#039;100&#039;,page=&#039;1&#039;):
        method_name=&#039;yupoo.groups.pools.getPhotos&#039;
        params={&#039;group_id&#039;:group_id,&#039;per_page&#039;:per_page,&#039;page&#039;:page}
        if user_id&lt;&gt;&#039;&#039;:
            params[&#039;user_id&#039;]=user_id
        if user_id&lt;&gt;&#039;&#039;:
            params[&#039;tags&#039;]=tags
        return  yupoo_helper.call_method(method_name,params)

    def people_findByEmail(self,email):
        method_name=&#039;yupoo.people.findByEmail&#039;
        params={&#039;email&#039;:email}
        return  yupoo_helper.call_method(method_name,params)

    def people_findByUsername(self,username):
        method_name=&#039;yupoo.people.findByUsername&#039;
        params={&#039;username&#039;:username}
        return  yupoo_helper.call_method(method_name,params)

    def people_getUploadStatus(self):
        method_name=&#039;yupoo.people.getUploadStatus&#039;
        params={}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def photos_addTags(self,photo_id,tags):
        method_name=&#039;yupoo.photos.addTags&#039;
        params={&#039;photo_id&#039;:photo_id,&#039;tags&#039;:tags}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def photos_delete(self,photo_id):
        method_name=&#039;yupoo.photos.delete&#039;
        parmas={&#039;photo_id&#039;:photo_id}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def photos_getContext(self,photo_id):
        method_name=&#039;yupoo.photos.getContext&#039;
        parmas={&#039;photo_id&#039;:photo_id}
        return  yupoo_helper.call_method(method_name,params)

    def photos_getArchives(self,user_id=&#039;&#039;,atype=&#039;posted&#039;):
        method_name=&#039;yupoo.photos.getArchives&#039;
        if user_id==&#039;&#039;:
            user_id=self.user_id
        params={&#039;user_id&#039;:user_id,&#039;type&#039;:atype}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def photos_getInfo(self,photo_id):
        method_name=&#039;yupoo.photos.getInfo&#039;
        params={&#039;photo_id&#039;:photo_id}
        return  yupoo_helper.call_method(method_name,params)

    def photos_getPerms(self,photo_id):
        method_name=&#039;yupoo.photos.getPerms&#039;
        params={&#039;photo_id&#039;:photo_id}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def photos_removeTag(self,photo_id,tag):
        method_name=&#039;yupoo.photos.removeTag&#039;
        params={&#039;photo_id&#039;:photo_id,&#039;tag&#039;:tag}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def photos_search(self,user_id=&#039;&#039;,tags=&#039;&#039;,text=&#039;&#039;,per_page=&#039;100&#039;,page=&#039;1&#039;):
        method_name=&#039;yupoo.photos.search&#039;
        if user_id==&#039;&#039;:
            user_id=self.user_id
        params={&#039;user_id&#039;:user_id,&#039;tags&#039;:tags,&#039;text&#039;:text,&#039;per_page&#039;:per_page,&#039;page&#039;:page}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def photos_setMeta(self,photo_id,title,description=&#039;&#039;):
        method_name=&#039;yupoo.photos.setMeta&#039;
        params={&#039;photo_id&#039;:photo_id,&#039;title&#039;:title,&#039;description&#039;:description}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def photos_setPerms(self,photo_id,view,comment,addmeta,blogthis,viewexif ):
        method_name=&#039;yupoo.photos.setPerms&#039;
        params={&#039;photo_id&#039;:photo_id,&#039;view&#039;:view,&#039;comment&#039;:comment,
                &#039;addmeta&#039;:addmeta,&#039;blogthis&#039;:blogthis,&#039;viewexif&#039;:viewexif}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def photos_setTags(self,photo_id,tags):
        method_name=&#039;yupoo.photos.setTags&#039;
        params={&#039;photo_id&#039;:photo_id,&#039;tags&#039;:tags}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def photos_licenses_getInfo(self):
        method_name=&#039;yupoo.photos.licenses.getInfo&#039;
        params={}
        return  yupoo_helper.call_method(method_name,params)

    def photos_licenses_setLicense(self,photo_id,license_id):
        method_name=&#039;yupoo.photos.licenses.setLicense&#039;
        params={&#039;photo_id&#039;:photo_id,&#039;license_id&#039;:license_id}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def photos_notes_add(self,photo_id,note_x,note_y,note_w,note_h,note_text):
        method_name=&#039;yupoo.photos.notes.add&#039;
        params={&#039;photo_id&#039;:photo_id,&#039;note_x&#039;:note_x,&#039;note_y&#039;:note_y,
                &#039;note_w&#039;:note_w,&#039;note_h&#039;:note_h,&#039;note_text&#039;:note_text}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def photos_notes_delete(self,note_id):
        method_name=&#039;yupoo.photos.notes.delete&#039;
        params={&#039;note_id&#039;:note_id}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def photos_notes_edit(self,note_id,note_x,note_y,note_w,note_h,note_text):
        method_name=&#039;yupoo.photos.notes.edit&#039;
        params={&#039;note_id&#039;:note_id,&#039;note_x&#039;:note_x,&#039;note_y&#039;:note_y,
                &#039;note_w&#039;:note_w,&#039;note_h&#039;:note_h,&#039;note_text&#039;:note_text}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def photos_notes_getList(self,photo_id):
        method_name=&#039;yupoo.photos.notes.getList&#039;
        params={&#039;photo_id&#039;:photo_id}
        return  yupoo_helper.call_method(method_name,params)

    def albums_addPhoto(self,album_id,photo_id):
        method_name=&#039;yupoo.albums.addPhoto&#039;
        params={&#039;album_id&#039;:album_id,&#039;photo_id&#039;:photo_id}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def albums_create(self,title,description=&#039;&#039;,cover_id=&#039;&#039;):
        method_name=&#039;yupoo.albums.create&#039;
        params={&#039;title&#039;:title,&#039;description&#039;:description}
        if cover_id&lt;&gt;&#039;&#039;:
            params[&#039;cover_id&#039;]=cover_id
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def albums_delete(self,album_id):
        method_name=&#039;yupoo.albums.delete&#039;
        params={&#039;album_id&#039;:album_id}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def albums_editMeta(self,album_id,title,description=&#039;&#039;):
        method_name=&#039;yupoo.albums.editMeta&#039;
        params={&#039;album_id&#039;:album_id,&#039;title&#039;:title,&#039;description&#039;:description}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def albums_editPhotos(self,album_id,photo_ids,cover_id=&#039;&#039;):
        method_name=&#039;yupoo.albums.editPhotos&#039;
        params={&#039;album_id&#039;:album_id,&#039;photo_ids&#039;:photo_ids}
        if cover_id&lt;&gt;&#039;&#039;:
           params[&#039;cover_id&#039;]=cover_id
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def albums_getContext(self,album_id,photo_id):
        method_name=&#039;yupoo.albums.getContext&#039;
        params={&#039;album_id&#039;:album_id,&#039;photo_id&#039;:photo_id}
        return  yupoo_helper.call_method(method_name,params)

    def albums_getList(self,user_id=&#039;&#039;):
        if user_id==&#039;&#039;:
            user_id=self.user_id
        method_name=&#039;yupoo.albums.getList&#039;
        params={&#039;user_id&#039;:user_id}
        return  yupoo_helper.call_method(method_name,params)

    def albums_getPhotos(self,album_id):
        method_name=&#039;yupoo.albums.getPhotos&#039;
        params={&#039;album_id&#039;:album_id}
        return  yupoo_helper.call_method(method_name,params)

    def albums_order(self,album_ids):
        method_name=&#039;yupoo.albums.order&#039;
        params={&#039;album_ids&#039;:album_ids}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def albums_removePhoto(self,album_id,photo_id):
        method_name=&#039;yupoo.albums.removePhoto&#039;
        params={&#039;album_id&#039;:album_id,&#039;photo_id&#039;:photo_id}
        return  yupoo_helper.call_method(method_name,params,True,self.auth_token)

    def tags_getListPhoto(self,photo_id):
        method_name=&#039;yupoo.tags.getListPhoto&#039;
        params={&#039;photo_id&#039;:photo_id}
        return  yupoo_helper.call_method(method_name,params)

    def tags_getListUser(self,user_id=&#039;&#039;):
        if user_id==&#039;&#039;:
            user_id=self.user_id
        method_name=&#039;yupoo.tags.getListUser&#039;
        params={&#039;user_id&#039;:user_id}
        return  yupoo_helper.call_method(method_name,params)

    def tags_getListUserPopular(self,user_id=&#039;&#039;,count=&#039;10&#039;):
        if user_id==&#039;&#039;:
            user_id=self.user_id
        method_name=&#039;yupoo.tags.getListUserPopular&#039;
        params={&#039;user_id&#039;:user_id,&#039;count&#039;:count}
        return  yupoo_helper.call_method(method_name,params)

    def tags_getRelated(self,tag):
        method_name=&#039;yupoo.tags.getRelated&#039;
        params={&#039;tag&#039;:tag}
        return  yupoo_helper.call_method(method_name,params)

    def set_api_info(self,api_key,shared_secret,perms=&#039;&#039;):
        if api_key&lt;&gt;&#039;&#039;:
            config[&#039;api_key&#039;]=api_key
        if shared_secret&lt;&gt;&#039;&#039;:
            config[&#039;shared_secret&#039;]=shared_secret
        if perms&lt;&gt;&#039;&#039;:
            config[&#039;perms&#039;]=perms
        yupoo_helper.set_config(config)

    def bulid_photo_url(self,host,adir,filename,size_type=&#039;&#039;,secret=&#039;&#039;,originalformat=&#039;&#039;):
        if originalformat==&#039;&#039;:
            url=&#039;http://photo&#039;+host+&#039;.yupoo.com/&#039;+adir+&#039;/&#039;+filename+size_type+&#039;.jpg&#039;
        else:
            url=&#039;http://photo&#039;+host+&#039;.yupoo.com/&#039;+adir+&#039;/&#039;+filename+&#039;_&#039;+secret+&#039;.&#039;+originalformat
        return url

    def upload_photo(self,photo,title=&#039;&#039;,description=&#039;&#039;,tags=&#039;&#039;,album_id=&#039;&#039;,group_id=&#039;&#039;,
                 is_public=&#039;1&#039;,is_contact=&#039;1&#039;,is_friend=&#039;1&#039;,is_family=&#039;1&#039;):

        upload_url=&#039;http://www.yupoo.com/api/upload/&#039;
        auth_token=config[&#039;auth_token&#039;]
        params={&#039;api_key&#039;:config[&#039;api_key&#039;],&#039;title&#039;:title,&#039;description&#039;:description,&#039;tags&#039;:tags,
               &#039;is_public&#039;:is_public,&#039;is_contact&#039;:is_contact,
                &#039;is_friend&#039;:is_friend,&#039;is_family&#039;:is_family,&#039;auth_token&#039;:auth_token}
        if album_id&lt;&gt;&#039;&#039;:
            params[&#039;album_id&#039;]=album_id
        if group_id&lt;&gt;&#039;&#039;:
            params[&#039;group_id&#039;]=group_id

        api_sig=yupoo_helper.sig(yupoo_helper.join_params(params))
        params[&#039;api_sig&#039;]=api_sig
        params[&#039;photo&#039;]=photo
        opener=yupoo_helper.build_Multipart_opener()
        return opener.open(upload_url,params).read()

if __name__ == &quot;__main__&quot;:

    pass
    #p=people()
    #photo=pho.search( p.findByUsername(&#039;chenyangcun&#039;)[&#039;id&#039;])
    #print bulid_photo_url(photo[&#039;host&#039;],photo[&#039;dir&#039;],photo[&#039;filename&#039;])
    #p=people()
    #print p.getUploadStatus()

   # f=open(&#039;c:\\chenyc.jpg&#039;,&#039;rb&#039;)
   # print upload_photo(f)
</pre>
<p><strong>yupoo_helper.py</strong>，读取用户相关的配置文件，返回xml的解析成dict处理</p>
<pre>
#----------------------------------------------------------------------
# -*- coding: utf-8 -*-
# Name:        yupoo_helper
# Purpose:
#
# Author:      chenyc
# Created:     22-06-2007
# Copyright:   (c) chenyc 2007
# Licence:     GNU
#-----------------------------------------------------------------------
import md5,urllib,httplib,os
import urllib2,MultipartPostHandler,cookielib
try:
    import xml.etree.ElementTree as ET  #python2.5
except ImportError:
    import elementtree.ElementTree as ET

def read_config():
    config={}
    keys=[u&#039;api_key&#039;,&#039;shared_secret&#039;,&#039;mini_token&#039;,&#039;auth_token&#039;,&#039;perms&#039;]
    try:
        f=file(&#039;yupoo.xml&#039;,&#039;r&#039;)
        root=ET.parse(f)
        f.close()
    except:
        for key in keys:
            config[key]=&#039;?&#039;
        root=set_config(config)
    db=bulid_dic(root)
    for key in keys:
        config[key]=db[key]
    return config

def set_config(config):
    root=ET.Element(&#039;XML&#039;)
    for key,value in config.items():
        key_node=ET.SubElement(root,key)
        key_node.text=value
    tree=ET.ElementTree(root)
    f=file(&#039;yupoo.xml&#039;,&#039;w&#039;)
    tree.write(f)
    f.close()
    return root

#解析yupoo返回的xml,并生成字典
def bulid_dic(root):
    dic={}
    iter = root.getiterator()
    for element in iter:
        if element.keys():
            key_dic={}
            for name,value in element.items():
                key_dic[name]=value
            if dic.has_key(element.tag):
                if type(dic[element.tag]) is list:
                    dic[element.tag].append(key_dic)
                else:
                    ll=[dic[element.tag],key_dic]
                    dic[element.tag]=ll
            else:
                dic[element.tag]=key_dic;
        else:
            dic[element.tag]=element.text
    return dic

#生成api_sgi
def sig(string):
    return md5.new(string).hexdigest()

def call_method(method_name,params,need_sig=False,auth_token=&#039;&#039;):
    params[&#039;api_key&#039;]=config[&#039;api_key&#039;]
    if auth_token &lt;&gt;&#039;&#039;:
        params[&#039;auth_token&#039;]=auth_token
    if need_sig:
        api_sig=sig(join_params(params,method_name))
        params[&#039;api_sig&#039;]=api_sig
    params[&#039;method&#039;]=method_name
    rest_url=&#039;http://www.yupoo.com/api/rest/?&#039;
    for key,value in params.items():
        rest_url=rest_url+key+&#039;=&#039;+value+&#039;&amp;&#039;
        xmldata=urllib.urlopen(rest_url).read()
    if xmldata&lt;&gt;&#039;&#039;:
        root=ET.fromstring(xmldata)
        return bulid_dic(root)
    else:
	return {}

def join_params(params,method_name=&#039;&#039;):
    string=config[&#039;shared_secret&#039;]
    if method_name&lt;&gt;&#039;&#039;:
        params[&#039;method&#039;]=method_name
    keys=params.keys()
    keys.sort()
    for k in keys:
        string=string+k+params[k]
    return string

#common method for yupoo api
#创建opener,用来登录验证
def bulid_opener():
    cj=cookielib.LWPCookieJar()
    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
    urllib2.install_opener(opener)
    opener.addheaders =[
        (&quot;User-agent&quot;, &quot;Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.5) Gecko/20031107 Debian/1.5-3&quot;),
        (&quot;Accept&quot;, &quot;text/html, image/jpeg, image/png, text/*, image/*, */*&quot;)]
    return opener

#创建Multipart opener,用来上传文件
def build_Multipart_opener():
    cookies = cookielib.CookieJar()
    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies),
                                MultipartPostHandler.MultipartPostHandler)
    return opener

config=read_config()
</pre>
<p><strong>MultipartPostHandler.py</strong> 作者：Will Holcomb，用来处理照片等附件的上传，不过这个在nokia s60的手机上不能调用成功，还需要修改一下。</p>
<pre>
#!/usr/bin/python

####
# 02/2006 Will Holcomb &lt;wholcomb@gmail.com&gt;
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
&quot;&quot;&quot;
Usage:
  Enables the use of multipart/form-data for posting forms

Inspirations:
  Upload files in python:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306

  urllib2_file:
    Fabien Seisen: &lt;fabien@seisen.org&gt;

Example:
  import MultipartPostHandler, urllib2, cookielib

  cookies = cookielib.CookieJar()
  opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies),
                                MultipartPostHandler.MultipartPostHandler)
  params = { &quot;username&quot; : &quot;bob&quot;, &quot;password&quot; : &quot;riviera&quot;,
             &quot;file&quot; : open(&quot;filename&quot;, &quot;rb&quot;) }
  opener.open(&quot;http://wwww.bobsite.com/upload/&quot;, params)

Further Example:
  The main function of this file is a sample which downloads a page and
  then uploads it to the W3C validator.
&quot;&quot;&quot;

import urllib
import urllib2
import mimetools, mimetypes
import os, stat

class Callable:
    def __init__(self, anycallable):
        self.__call__ = anycallable

# Controls how sequences are uncoded. If true, elements may be given multiple values by
#  assigning a sequence.
doseq = 1

class MultipartPostHandler(urllib2.BaseHandler):
    handler_order = urllib2.HTTPHandler.handler_order - 10 # needs to run first

    def http_request(self, request):
        data = request.get_data()
        if data is not None and type(data) != str:
            v_files = []
            v_vars = []
            try:
                 for(key, value) in data.items():
                     if type(value) == file:
                         v_files.append((key, value))
                     else:
                         v_vars.append((key, value))
            except TypeError:
                systype, value, traceback = sys.exc_info()
                raise TypeError, &quot;not a valid non-string sequence or mapping object&quot;, traceback

            if len(v_files) == 0:
                data = urllib.urlencode(v_vars, doseq)
            else:
                boundary, data = self.multipart_encode(v_vars, v_files)
                contenttype = &#039;multipart/form-data; boundary=%s&#039; % boundary
                if(request.has_header(&#039;Content-Type&#039;)
                   and request.get_header(&#039;Content-Type&#039;).find(&#039;multipart/form-data&#039;) != 0):
                    print &quot;Replacing %s with %s&quot; % (request.get_header(&#039;content-type&#039;), &#039;multipart/form-data&#039;)
                request.add_unredirected_header(&#039;Content-Type&#039;, contenttype)

            request.add_data(data)
        return request

    def multipart_encode(vars, files, boundary = None, buffer = None):
        if boundary is None:
            boundary = mimetools.choose_boundary()
        if buffer is None:
            buffer = &#039;&#039;
        for(key, value) in vars:
            buffer += &#039;--%s\r\n&#039; % boundary
            buffer += &#039;Content-Disposition: form-data; name=&quot;%s&quot;&#039; % key
            buffer += &#039;\r\n\r\n&#039; + value + &#039;\r\n&#039;
        for(key, fd) in files:
            file_size = os.fstat(fd.fileno())[stat.ST_SIZE]
            filename = fd.name.split(&#039;/&#039;)[-1]
            contenttype = mimetypes.guess_type(filename)[0] or &#039;application/octet-stream&#039;
            buffer += &#039;--%s\r\n&#039; % boundary
            buffer += &#039;Content-Disposition: form-data; name=&quot;%s&quot;; filename=&quot;%s&quot;\r\n&#039; % (key, filename)
            buffer += &#039;Content-Type: %s\r\n&#039; % contenttype
            # buffer += &#039;Content-Length: %s\r\n&#039; % file_size
            fd.seek(0)
            buffer += &#039;\r\n&#039; + fd.read() + &#039;\r\n&#039;
        buffer += &#039;--%s--\r\n\r\n&#039; % boundary
        return boundary, buffer
    multipart_encode = Callable(multipart_encode)

    https_request = http_request

def main():
    import tempfile, sys

    validatorURL = &quot;http://validator.w3.org/check&quot;
    opener = urllib2.build_opener(MultipartPostHandler)

    def validateFile(url):
        temp = tempfile.mkstemp(suffix=&quot;.html&quot;)
        os.write(temp[0], opener.open(url).read())
        params = { &quot;ss&quot; : &quot;0&quot;,            # show source
                   &quot;doctype&quot; : &quot;Inline&quot;,
                   &quot;uploaded_file&quot; : open(temp[1], &quot;rb&quot;) }
        print opener.open(validatorURL, params).read()
        os.remove(temp[1])

    if len(sys.argv[1:]) &gt; 0:
        for arg in sys.argv[1:]:
            validateFile(arg)
    else:
        validateFile(&quot;http://www.google.com&quot;)

if __name__==&quot;__main__&quot;:
    main()
</pre>
]]></content:encoded>
			<wfw:commentRss>http://chenyc.info/2010/02/yupoo-api-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>以前写的下载yahoo mp3的python脚本</title>
		<link>http://chenyc.info/2010/02/downmp3/</link>
		<comments>http://chenyc.info/2010/02/downmp3/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 12:51:09 +0000</pubDate>
		<dc:creator>阳春面</dc:creator>
				<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://chenyc.info/?p=6</guid>
		<description><![CDATA[以前写的下载yahoo mp3的代码，不知道现在还能不能用; yahoomp3类根据命令行输入的歌曲名，从chinamp3获取歌曲列表并打印到屏幕， 需要选择一个，然后会通过wget进行下载（wget在linux系统下默认都有的，windows下需要另外下载）,歌曲下载完后，自动修改ID3标签，这个通过Ben Gertzfield写的ID3.py进行修改的。 downmp3.py #! /usr/bin/python # create by chenyc version:0.3 import re,urllib,os,socket,locale,sys,getopt,time,urllib2 import ID3 LOCALE_CODE=locale.getdefaultlocale()[1] WEB_CODE=&#039;gbk&#039; &#039;&#039;&#039;DOWN MUSIC FILE FORM MP3.YAHOO.CN&#039;&#039;&#039; class yahoomp3: def __init__(self,time_out=0.3,directory=&#039;./&#039;): self.time_out=time_out if directory[-1]&#60;&#62;&#039;/&#039;: directory=directory+&#039;/&#039; self.path=directory #analyse html,return result list def analyse_html(self,url,expression): socket.setdefaulttimeout(10) &#8230; <a href="http://chenyc.info/2010/02/downmp3/">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>以前写的下载yahoo mp3的代码，不知道现在还能不能用;<br />
yahoomp3类根据命令行输入的歌曲名，从chinamp3获取歌曲列表并打印到屏幕，<br />
需要选择一个，然后会通过wget进行下载（wget在linux系统下默认都有的，windows下需要另外下载）,歌曲下载完后，自动修改ID3标签，这个通过Ben Gertzfield写的ID3.py进行修改的。</p>
<p><strong>downmp3.py</strong></p>
<pre>

#! /usr/bin/python
# create by chenyc version:0.3

import re,urllib,os,socket,locale,sys,getopt,time,urllib2
import ID3
LOCALE_CODE=locale.getdefaultlocale()[1]
WEB_CODE=&#039;gbk&#039;

&#039;&#039;&#039;DOWN MUSIC FILE FORM MP3.YAHOO.CN&#039;&#039;&#039;
class yahoomp3:
    def __init__(self,time_out=0.3,directory=&#039;./&#039;):
        self.time_out=time_out
        if directory[-1]&lt;&gt;&#039;/&#039;:
           directory=directory+&#039;/&#039;
        self.path=directory

    #analyse html,return result list
    def analyse_html(self,url,expression):
        socket.setdefaulttimeout(10)
        try:
            urldata=urllib.urlopen(url)
            html=urldata.read()
            re_list=re.findall(expression,html)
            return re_list
        except:
            print &#039;can&#039;&#039;t connect to the yahoo website! &#039;
            return 1

    #get the music file download url from the search url
    def get_down_url(self,search_url):
        expression=&#039;&lt;a href=&quot;(.*)&quot; onclick=&quot;return&#039;
        music_url_list=self.analyse_html(search_url,expression)
        i=0
        while len(music_url_list)&gt;0 and i&lt;len(music_url_list) :
            expression=&#039;&lt;/b&gt;&lt;a href=&quot;(.*)&quot; target=_blank&gt;&#039;
            down_url_list=self.analyse_html(music_url_list[i],expression)
            if len (down_url_list)&gt;0:
                down_url=&#039;http://&#039;+urllib.quote(down_url_list[0][7:])
            print down_url
            try:
                socket.setdefaulttimeout(self.time_out)
                tmp=urllib.urlopen(down_url).readline()
                if  len(tmp) &gt;1 and tmp.upper().find(&#039;&lt;&#039;)==-1:
                    break
                else:
                    i=i+3
            except:
                i=i+3

        if i&lt;len(music_url_list):
            return down_url

    #generate search url and call method &#039;down_file&#039;
    def down_music(self,name,author=&#039;&#039;,file_type=&#039;all&#039;):
        if author is  None:
            print &#039;the author not find in chinamp3,do you want to download anyway?&#039;
            if str(raw_input(&#039;input y or n for continue:&#039;)).upper() &lt;&gt; &#039;Y&#039;:
                return 1
        else:
            author=author.decode(LOCALE_CODE).encode(WEB_CODE)

        name=name.decode(LOCALE_CODE).encode(WEB_CODE)
        name=&#039;_&#039;.join(name.split())
        search_url=&#039;http://music.cn.yahoo.com/search?pid=ysearch&amp;source=ysearch_music_result_topsearch&amp;p=&#039;
        option=&#039;&amp;mimetype=&#039;+file_type+&#039;&amp;size=3&amp;source=ysearch_music_result_size_3&#039;
        if author is not None:
            search_url=search_url+name+&#039;+&#039;+author+option
        else:
            search_url=search_url+name+&#039;+&#039;+option
        self.down_file(name,author,search_url)

    #use wget to download music file
    def down_file(self,music_name,author,search_url):
        file_path=self.path
        if author is not None:
            file_name=author+&#039;_&#039;+music_name
        else:
            file_name=music_name
        file_name=file_name.decode(WEB_CODE).encode(LOCALE_CODE)
        try:
            file_list=os.listdir(file_path)
        except:
            print &#039;list dir error,abort!&#039;
            return 1

        for name in file_list:
            if name.split(&#039;.&#039;)[0]==file_name:
                print &#039;file &#039;+file_name+&#039; exit,ignore download!&#039;
                return 1

        down_url=self.get_down_url(search_url)
        if down_url is not None:
            print &#039;down music &#039;+file_name
            ext=down_url.split(&#039;.&#039;)[-1]
            file_name=file_name+&#039;.&#039;+ext
            exe_wgetstr=&#039;wget --timeout=30 -l 10 -O &#039;+file_path+file_name+&#039; &#039;+down_url
            os.system(exe_wgetstr)
            change_ID3(file_path,file_name)
        else:
            print &#039;FILE NOT FOUND!&#039;

&#039;&#039;&#039;GET MUSIC INFO FROM CHINAMP3.COM&#039;&#039;&#039;
class music_info:
    #return to post requst from chinamp3
    def get_html(self,url,postdata):
        urldata=urllib2.urlopen(url, postdata)
        html=urldata.read().decode(WEB_CODE).encode(LOCALE_CODE)
        p=re.compile(&#039;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&#039;)
        html=p.sub(&#039;\n&#039;,html)
        return html

    #get author list from music name
    def get_author_list(self,name):
        name=name.decode(LOCALE_CODE).encode(WEB_CODE)
        value=2
        url=&#039;http://search.chinamp3.com/search/searchcontent.php&#039;
        postdata=urllib.urlencode({&#039;type&#039;:value,&#039;key&#039;:name})
        html=self.get_html(url,postdata)
        exp=&#039;&amp;singer_name=(.*)\&#039;\)}&quot;&gt;&#039;
        author_list=re.findall(exp,html)
        return author_list

    #get music name list from author
    def get_music_name(self,author):
        author=author.decode(LOCALE_CODE).encode(WEB_CODE)
        value=1
        url=&#039;http://search.chinamp3.com/search/searchcontent.php&#039;
        postdata=urllib.urlencode({&#039;type&#039;:value,&#039;key&#039;:author})
        html=self.get_html(url,postdata)
        exp=&#039;php\?song_name=(.*)&amp;singer_name=&#039;
        music_list=re.findall(exp,html)
        return music_list

    #get lyrics form music name and author
    def get_lyrics(self,name,author):
        name=name.decode(LOCALE_CODE).encode(WEB_CODE)
        author=author.decode(LOCALE_CODE).encode(WEB_CODE)
        url=&#039;http://geci.chinamp3.com/relatedgeci.php?song_name=&#039;+name+&#039;&amp;singer_name=&#039;+author
        urldata=urllib.urlopen(url)
        html=urldata.read().decode(WEB_CODE).encode(LOCALE_CODE)
        p=re.compile(&#039;\s&#039;)
        html=p.sub(&#039;&#039;,html)
        exp=&#039;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;(.*)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;divalign=&quot;center&quot;&gt;&lt;fontcolor=&quot;#FF0000&quot;&gt;&#039;
        lyrics_list=re.findall(exp,html)
        if len(lyrics_list)&gt;0:
            lyrics=lyrics_list[0]
            p=re.compile(&#039;&lt;br /&gt;|&lt;br/&gt;&#039;)
            lyrics=p.sub(&#039;\n&#039;,lyrics)
            return lyrics

#change the ID3
def change_ID3(file_path,file_name):
    mp3file=file_path+file_name
    try:
        id3info=ID3.ID3(mp3file)
    except:
        print &#039;open file error!&#039;
        return 1
    mp3info=file_name.split(&#039;.&#039;)[0].split(&#039;_&#039;)
    if len(mp3info)==2:
        id3info[&#039;ARTIST&#039;]=mp3info[0]
        id3info[&#039;TITLE&#039;]=mp3info[1]
    elif len(mp3info)==1:
        id3info[&#039;TITLE&#039;]=mp3info[0]

#get author from name
def get_author(name):
    mp3info=music_info();
    author_list=mp3info.get_author_list(name)
    count=len(author_list)
    if count&gt;1:
        print &#039;please select author from the list:&#039;
        i=0
        for author in author_list:
            print str(i)+&#039;.&#039;+author
            i=i+1
        while True:
            try:
                select=int(raw_input(&#039;please select one author:&#039;))
            except:
                continue
            if select&lt;len(author_list):
                author=author_list[select]
                return author
            else:
                print &quot;you select the worng num,please select again!&quot;
                continue
    elif count==1:
        return author_list[0]

# the main method,pass music name and option to program
def main (argv):
    file_type=&#039;all&#039;
    author=&#039;&#039;
    name=&#039;&#039;
    directory=&#039;./&#039;
    time_out=0.3
    try:
        opts,args = getopt.getopt (argv, &quot;ha:t:d:o:&quot;, [&quot;help&quot;,&quot;author=&quot;,&quot;type=&quot;,&quot;directory=&quot;,&quot;time out=&quot;])
    except getopt.GetoptError:
        usage()
        sys.exit(2)
    for opt, arg in opts:
        if opt in (&#039;-h&#039;,&#039;--help&#039;):
            usage()
            sys.exit()
        elif opt in (&#039;-d&#039;,&#039;--directory&#039;):
            directory=arg
        elif opt in (&#039;-a&#039;,&#039;--author&#039;):
            author = arg
        elif opt in (&#039;-t&#039;,&#039;--type&#039;):
            file_type = arg
        elif opt in (&#039;-o&#039;,&#039;--time out&#039;):
            time_out = float(arg)

    if len(args)&gt;0:
        name = args[0]

    if len(args)&gt;1:
        author =args[1]
    yahoo=yahoomp3(time_out,directory)

    if name == &#039;&#039;:
        usage()
    elif author == &#039;&#039;:
        author=get_author(name)
        yahoo.down_music(name,author,file_type)
    else:
        yahoo.down_music(name,author,file_type)

def usage():
    print &#039;usage: down_music [option] music_name \noptions:  \n -a --author  author name for search \n -t --type  music type for search \n -d --directory   set the download directory \n &#039;
    pass

if __name__ == &quot;__main__&quot;:
    main (sys.argv[1:])
</pre>
<p>附件：<a href='http://chenyc.info/blog/wp-content/uploads/2010/02/ID3.py'>ID3.py</a>  <a href='http://chenyc.info/blog/wp-content/uploads/2010/02/downmp3.py'>downmp3.py</a></p>
]]></content:encoded>
			<wfw:commentRss>http://chenyc.info/2010/02/downmp3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

