<?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>phill84.org &#187; python</title>
	<atom:link href="http://phill84.org/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://phill84.org</link>
	<description>System.out.print</description>
	<lastBuildDate>Sat, 26 Mar 2011 10:21:26 +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>Posting douban saying using python / 用python發送豆瓣廣播</title>
		<link>http://phill84.org/2010/01/posting-douban-saying-using-python-%e7%94%a8python%e7%99%bc%e9%80%81%e8%b1%86%e7%93%a3%e5%bb%a3%e6%92%ad/</link>
		<comments>http://phill84.org/2010/01/posting-douban-saying-using-python-%e7%94%a8python%e7%99%bc%e9%80%81%e8%b1%86%e7%93%a3%e5%bb%a3%e6%92%ad/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 10:48:18 +0000</pubDate>
		<dc:creator>phill84</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[douban]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[saying]]></category>
		<category><![CDATA[廣播]]></category>
		<category><![CDATA[豆瓣]]></category>

		<guid isPermaLink="false">http://phill84.org/2010/01/posting-douban-saying-using-python-%e7%94%a8python%e7%99%bc%e9%80%81%e8%b1%86%e7%93%a3%e5%bb%a3%e6%92%ad/</guid>
		<description><![CDATA[Finally I got sometime to work on implementing my own python script for posting douban saying, again. This time I used the library written by Leah Culver, and everything went smoothly. It&#8217;s just that I have no idea why douban &#8230; <a href="http://phill84.org/2010/01/posting-douban-saying-using-python-%e7%94%a8python%e7%99%bc%e9%80%81%e8%b1%86%e7%93%a3%e5%bb%a3%e6%92%ad/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Finally I got sometime to work on implementing my own python script for posting douban saying, again. This time I used the <a href="http://oauth.googlecode.com/svn/code/python/oauth/">library</a> written by <a href="http://leahculver.com/">Leah Culver</a>, and everything went smoothly. It&#8217;s just that I have no idea why douban chose to use a different signing algorithm(if a thing as stupid as it is can be called a algorithm) for requesting access token.</p>
<p>終於又有時間再一次捯鼓豆瓣. 這次在 <a href="http://leahculver.com/">Leah Culver</a> 寫的 <a href="http://oauth.googlecode.com/svn/code/python/oauth/">library</a> 的基礎上, 終於把python腳本發送豆瓣廣播終於搞定了. 唯一理解不能的事就是豆瓣在獲取access token的時候用了一個莫名其妙的簽名算法(如果這種也能叫做算法的話 = =).</p>
<p>Click on read more to view the actual code of the script.<br />
查看腳本內容請點擊 read more<br />
<span id="more-619"></span></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">binascii</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">cgi</span>
<span style="color: #ff7700;font-weight:bold;">import</span> hashlib
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">hmac</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">httplib</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">random</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib</span>
&nbsp;
SERVER  = <span style="color: #483d8b;">'api.douban.com'</span>
API_KEY = <span style="color: #483d8b;">'your api key'</span>
SECRET  = <span style="color: #483d8b;">'your api secret'</span>
&nbsp;
OAUTH_SERVER            = <span style="color: #483d8b;">'www.douban.com'</span>
REQUEST_TOKEN_URI       = <span style="color: #483d8b;">'/service/auth/request_token'</span>
AUTHORIZATION_URI       = <span style="color: #483d8b;">'/service/auth/authorize'</span>
ACCESS_TOKEN_URI        = <span style="color: #483d8b;">'/service/auth/access_token'</span>
SAYING_URI              = <span style="color: #483d8b;">'/miniblog/saying'</span>
&nbsp;
SIG_METHOD              = <span style="color: #483d8b;">'HMAC-SHA1'</span>
OAUTH_VER               = <span style="color: #483d8b;">'1.0'</span>
SCHEME                  = <span style="color: #483d8b;">'http'</span>
&nbsp;
ACCESS_TOKEN_FILE       = <span style="color: #483d8b;">'douban_access_token'</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> escape<span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">urllib</span>.<span style="color: black;">quote</span><span style="color: black;">&#40;</span>s, safe=<span style="color: #483d8b;">'~'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> generate_timestamp<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> generate_nonce<span style="color: black;">&#40;</span>length=<span style="color: #ff4500;">8</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">''</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">random</span>.<span style="color: black;">randint</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">9</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span>length<span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> normalize_params<span style="color: black;">&#40;</span>params<span style="color: black;">&#41;</span>:
        key_values = <span style="color: black;">&#91;</span><span style="color: black;">&#40;</span>escape<span style="color: black;">&#40;</span>k<span style="color: black;">&#41;</span>, escape<span style="color: black;">&#40;</span>v<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> k,v <span style="color: #ff7700;font-weight:bold;">in</span> params.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
        key_values.<span style="color: black;">sort</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">'&amp;'</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'%s=%s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>k, v<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> k, v <span style="color: #ff7700;font-weight:bold;">in</span> key_values<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> sign<span style="color: black;">&#40;</span>method, url, params, secret, token_secret<span style="color: black;">&#41;</span>:
        sig = <span style="color: black;">&#40;</span>
                        escape<span style="color: black;">&#40;</span>method.<span style="color: black;">upper</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>,
                        escape<span style="color: black;">&#40;</span>SCHEME + <span style="color: #483d8b;">'://'</span> + url<span style="color: black;">&#41;</span>,
                        escape<span style="color: black;">&#40;</span>normalize_params<span style="color: black;">&#40;</span>params<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: black;">&#41;</span>
        key = escape<span style="color: black;">&#40;</span>secret<span style="color: black;">&#41;</span> + <span style="color: #483d8b;">'&amp;'</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> url == OAUTH_SERVER + ACCESS_TOKEN_URI:
                <span style="color: #808080; font-style: italic;">#I have no idea why the fuck douban uses concatenated secrets as signature instead of the computed one</span>
                <span style="color: #ff7700;font-weight:bold;">return</span> secret + <span style="color: #483d8b;">'&amp;'</span> + token_secret
        <span style="color: #ff7700;font-weight:bold;">if</span> token_secret:
                key += escape<span style="color: black;">&#40;</span>token_secret<span style="color: black;">&#41;</span>
        base_string = <span style="color: #483d8b;">'&amp;'</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>sig<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">binascii</span>.<span style="color: black;">b2a_base64</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">hmac</span>.<span style="color: #dc143c;">new</span><span style="color: black;">&#40;</span>key, base_string, hashlib.<span style="color: black;">sha1</span><span style="color: black;">&#41;</span>.<span style="color: black;">digest</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>:-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> generate_header<span style="color: black;">&#40;</span>method, url, params, key, <span style="color: #dc143c;">token</span><span style="color: black;">&#41;</span>:
        header = <span style="color: #483d8b;">'OAuth realm=&quot;&quot;'</span>
        params<span style="color: black;">&#91;</span><span style="color: #483d8b;">'oauth_version'</span><span style="color: black;">&#93;</span> = OAUTH_VER
        signature = sign<span style="color: black;">&#40;</span>method, url, params, key, <span style="color: #dc143c;">token</span><span style="color: black;">&#41;</span>
        params<span style="color: black;">&#91;</span><span style="color: #483d8b;">'oauth_signature'</span><span style="color: black;">&#93;</span> = signature
        key_values = <span style="color: black;">&#91;</span><span style="color: black;">&#40;</span>k, v<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> k,v <span style="color: #ff7700;font-weight:bold;">in</span> params.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
        key_values.<span style="color: black;">sort</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> k, v <span style="color: #ff7700;font-weight:bold;">in</span> key_values:
                header += <span style="color: #483d8b;">', %s=&quot;%s&quot;'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>k, escape<span style="color: black;">&#40;</span>v<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;Authorization&quot;</span>: header<span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> create_connection<span style="color: black;">&#40;</span>server<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">httplib</span>.<span style="color: black;">HTTPConnection</span><span style="color: black;">&#40;</span>server<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> read_access_token_file<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">access</span><span style="color: black;">&#40;</span>ACCESS_TOKEN_FILE, <span style="color: #dc143c;">os</span>.<span style="color: black;">F_OK</span><span style="color: black;">&#41;</span>:
                token_file = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span>ACCESS_TOKEN_FILE, <span style="color: #483d8b;">'r'</span><span style="color: black;">&#41;</span>
                data = token_file.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                data = <span style="color: #dc143c;">cgi</span>.<span style="color: black;">parse_qs</span><span style="color: black;">&#40;</span>data, keep_blank_values=<span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
                <span style="color: #dc143c;">token</span> = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
                <span style="color: #ff7700;font-weight:bold;">for</span> k, v <span style="color: #ff7700;font-weight:bold;">in</span> data.<span style="color: black;">iteritems</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
                        <span style="color: #dc143c;">token</span><span style="color: black;">&#91;</span>k<span style="color: black;">&#93;</span> = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">unquote</span><span style="color: black;">&#40;</span>v<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
                token_file.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">token</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> write_access_token_file<span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">access</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'./'</span>, <span style="color: #dc143c;">os</span>.<span style="color: black;">W_OK</span><span style="color: black;">&#41;</span>:
                token_file = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span>ACCESS_TOKEN_FILE, <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span>
                token_file.<span style="color: black;">write</span><span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
                token_file.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Token file successfully updated&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Cannot write to file, please confirm you have write permission&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> douban<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
                <span style="color: #008000;">self</span>.<span style="color: black;">key</span> = API_KEY
                <span style="color: #008000;">self</span>.<span style="color: black;">secret</span> = SECRET
                <span style="color: #008000;">self</span>.<span style="color: black;">stored_token</span> = read_access_token_file<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">def</span> update_stored_token<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, data<span style="color: black;">&#41;</span>:
                data = <span style="color: #dc143c;">cgi</span>.<span style="color: black;">parse_qs</span><span style="color: black;">&#40;</span>data, keep_blank_values=<span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">for</span> k, v <span style="color: #ff7700;font-weight:bold;">in</span> data.<span style="color: black;">iteritems</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
                        <span style="color: #008000;">self</span>.<span style="color: black;">stored_token</span><span style="color: black;">&#91;</span>k<span style="color: black;">&#93;</span> = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">unquote</span><span style="color: black;">&#40;</span>v<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">def</span> get_request_token<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
                conn = create_connection<span style="color: black;">&#40;</span>OAUTH_SERVER<span style="color: black;">&#41;</span>
                params = <span style="color: black;">&#123;</span>
                                <span style="color: #483d8b;">'oauth_consumer_key'</span>: <span style="color: #008000;">self</span>.<span style="color: black;">key</span>,
                                <span style="color: #483d8b;">'oauth_signature_method'</span>: SIG_METHOD,
                                <span style="color: #483d8b;">'oauth_timestamp'</span>: generate_timestamp<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>,
                                <span style="color: #483d8b;">'oauth_nonce'</span>: generate_nonce<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                <span style="color: black;">&#125;</span>
                header = generate_header<span style="color: black;">&#40;</span><span style="color: #483d8b;">'GET'</span>, OAUTH_SERVER + REQUEST_TOKEN_URI, params, <span style="color: #008000;">self</span>.<span style="color: black;">secret</span>, <span style="color: #008000;">None</span><span style="color: black;">&#41;</span>
                conn.<span style="color: black;">request</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;GET&quot;</span>, REQUEST_TOKEN_URI, headers=header<span style="color: black;">&#41;</span>
                response = conn.<span style="color: black;">getresponse</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                data = response.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> response.<span style="color: black;">status</span> == <span style="color: #ff4500;">200</span>:
                        <span style="color: #008000;">self</span>.<span style="color: black;">update_stored_token</span><span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
                        <span style="color: #008000;">self</span>.<span style="color: black;">authorize_token</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">else</span>:
                        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;%s %s<span style="color: #000099; font-weight: bold;">\n</span>%s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>response.<span style="color: black;">status</span>, response.<span style="color: black;">reason</span>, response.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
                conn.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">def</span> authorize_token<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
                <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Open the link below to authorize the request token:&quot;</span>
                <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;http://%s%s?oauth_token=%s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>OAUTH_SERVER, AUTHORIZATION_URI, escape<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">stored_token</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'oauth_token'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
                <span style="color: #008000;">raw_input</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Press enter to continue&quot;</span><span style="color: black;">&#41;</span>
                <span style="color: #008000;">self</span>.<span style="color: black;">get_access_token</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">def</span> get_access_token<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
                conn = create_connection<span style="color: black;">&#40;</span>OAUTH_SERVER<span style="color: black;">&#41;</span>
                params = <span style="color: black;">&#123;</span>
                                <span style="color: #483d8b;">'oauth_consumer_key'</span>: <span style="color: #008000;">self</span>.<span style="color: black;">key</span>,
                                <span style="color: #483d8b;">'oauth_token'</span>: <span style="color: #008000;">self</span>.<span style="color: black;">stored_token</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'oauth_token'</span><span style="color: black;">&#93;</span>,
                                <span style="color: #483d8b;">'oauth_sgnature_method'</span>: SIG_METHOD,
                                <span style="color: #483d8b;">'oauth_timestamp'</span>: generate_timestamp<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>,
                                <span style="color: #483d8b;">'oauth_nonce'</span>: generate_nonce<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                <span style="color: black;">&#125;</span>
                header = generate_header<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;GET&quot;</span>, OAUTH_SERVER + ACCESS_TOKEN_URI, params, <span style="color: #008000;">self</span>.<span style="color: black;">secret</span>, <span style="color: #008000;">self</span>.<span style="color: black;">stored_token</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'oauth_token_secret'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
                conn.<span style="color: black;">request</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;GET&quot;</span>, ACCESS_TOKEN_URI, headers=header<span style="color: black;">&#41;</span>
                response = conn.<span style="color: black;">getresponse</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> response.<span style="color: black;">status</span> == <span style="color: #ff4500;">200</span>:
                        data = response.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                        write_access_token_file<span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">else</span>:
                        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;%s %s<span style="color: #000099; font-weight: bold;">\n</span>%s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>response.<span style="color: black;">status</span>, response.<span style="color: black;">reason</span>, response.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">def</span> first_run<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
                <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #483d8b;">'douban_user_id'</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>.<span style="color: black;">stored_token</span>:
                        confirm = <span style="color: #008000;">raw_input</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'token file exists arleady, overwrite? ([y]/n):'</span><span style="color: black;">&#41;</span>
                        <span style="color: #ff7700;font-weight:bold;">if</span> confirm.<span style="color: black;">upper</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> == <span style="color: #483d8b;">'N'</span>:
                                <span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
                <span style="color: #008000;">self</span>.<span style="color: black;">get_request_token</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">def</span> add_saying<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, content<span style="color: black;">&#41;</span>:
                <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #483d8b;">'douban_user_id'</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>.<span style="color: black;">stored_token</span>:
                        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Access token file does not exist'</span>
                        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">None</span>
                entry = <span style="color: #483d8b;">'&lt;?xml version=<span style="color: #000099; font-weight: bold;">\'</span>1.0<span style="color: #000099; font-weight: bold;">\'</span> encoding=<span style="color: #000099; font-weight: bold;">\'</span>UTF-8<span style="color: #000099; font-weight: bold;">\'</span>?&gt;'</span>\
                        + <span style="color: #483d8b;">'&lt;entry xmlns:ns0=&quot;http://www.w3.org/2005/Atom&quot; xmlns:db=&quot;http://www.douban.com/xmlns/&quot;&gt;'</span>\
                        + <span style="color: #483d8b;">'&lt;content&gt;'</span> + content + <span style="color: #483d8b;">'&lt;/content&gt;'</span>\
                        + <span style="color: #483d8b;">'&lt;/entry&gt;'</span>
                conn = create_connection<span style="color: black;">&#40;</span>SERVER<span style="color: black;">&#41;</span>
                params = <span style="color: black;">&#123;</span>
                                <span style="color: #483d8b;">'oauth_consumer_key'</span>: <span style="color: #008000;">self</span>.<span style="color: black;">key</span>,
                                <span style="color: #483d8b;">'oauth_token'</span>: <span style="color: #008000;">self</span>.<span style="color: black;">stored_token</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'oauth_token'</span><span style="color: black;">&#93;</span>,
                                <span style="color: #483d8b;">'oauth_signature_method'</span>: SIG_METHOD,
                                <span style="color: #483d8b;">'oauth_timestamp'</span>: generate_timestamp<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>,
                                <span style="color: #483d8b;">'oauth_nonce'</span>: generate_nonce<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                <span style="color: black;">&#125;</span>
                header = generate_header<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;POST&quot;</span>, SERVER + SAYING_URI, params, <span style="color: #008000;">self</span>.<span style="color: black;">secret</span>, <span style="color: #008000;">self</span>.<span style="color: black;">stored_token</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'oauth_token_secret'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
                header<span style="color: black;">&#91;</span><span style="color: #483d8b;">'Content-Type'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">'application/atom+xml'</span>
                conn.<span style="color: black;">request</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;POST&quot;</span>, SAYING_URI, entry, header<span style="color: black;">&#41;</span>
                response = conn.<span style="color: black;">getresponse</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> response.<span style="color: black;">status</span> <span style="color: #66cc66;">!</span>= <span style="color: #ff4500;">201</span>:
                        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;%s %s<span style="color: #000099; font-weight: bold;">\n</span>%s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>response.<span style="color: black;">status</span>, response.<span style="color: black;">reason</span>, response.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://phill84.org/2010/01/posting-douban-saying-using-python-%e7%94%a8python%e7%99%bc%e9%80%81%e8%b1%86%e7%93%a3%e5%bb%a3%e6%92%ad/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Syncing twitter to digu using python / 用python同步twitter到嘀咕</title>
		<link>http://phill84.org/2009/10/syncing-twitter-to-digu-using-python-%e7%94%a8python%e5%90%8c%e6%ad%a5twitter%e5%88%b0%e5%98%80%e5%92%95/</link>
		<comments>http://phill84.org/2009/10/syncing-twitter-to-digu-using-python-%e7%94%a8python%e5%90%8c%e6%ad%a5twitter%e5%88%b0%e5%98%80%e5%92%95/#comments</comments>
		<pubDate>Fri, 30 Oct 2009 19:04:19 +0000</pubDate>
		<dc:creator>phill84</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[digu]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[sync]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[同步]]></category>
		<category><![CDATA[嘀咕]]></category>

		<guid isPermaLink="false">http://phill84.org/2009/10/syncing-twitter-to-digu-using-python-%e7%94%a8python%e5%90%8c%e6%ad%a5twitter%e5%88%b0%e5%98%80%e5%92%95/</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<pre class="brush: python; title: ; notranslate">#!/usr/bin/env python
import base64
import simplejson as json
import os
import sys
import urllib
import urllib2

global twitter_username
global digu_username
global digu_password
twitter_username = 'username'
digu_username = 'username'
digu_password = 'password'

def post_to_digu(msg):
	url = 'http://api.minicloud.com.cn/statuses/update.json'
	data = urllib.urlencode(msg)
	req = urllib2.Request(url, data)
	req.add_header(&quot;Authorization&quot;, &quot;Basic %s&quot; % base64.encodestring('%s:%s' % (digu_username, digu_password))[:-1])
	handle = urllib2.urlopen(req)

def main():
	path = sys.path[0]
	if (sys.platform[:3] == 'win'):
		path += '\\'
	else:
		path += '/'
	id_file = path + 'last_id'
	last_id = 0
	if os.path.exists(id_file):
		f = open(id_file, 'r')
	        last_id = int(f.read())
        	f.close()
	else:
		f = open(id_file, 'w')
		f.write('0')
		f.close()
	url = 'http://twitter.com/statuses/user_timeline/' + twitter_username + '.json?last_id='
	updates = json.load(urllib.urlopen(url+str(last_id)))
	new_last_id = None
	n = 0
	for update in updates:
		text = update['text']
		id = update['id']
		if (text[0] != '@') and (id &amp;gt; last_id):
			if (new_last_id &amp;lt; id):
				new_last_id = id
			text = urllib.quote(text.encode('utf-8'))
			msg = {'content': text}
                        stack.append(msg)
        while (stack)
                post_to_digu(stack.pop())
	if (new_last_id != None):
		f = open(id_file, 'w')
		f.write(str(new_last_id))

if __name__ == &quot;__main__&quot;:
    main()</pre>
]]></content:encoded>
			<wfw:commentRss>http://phill84.org/2009/10/syncing-twitter-to-digu-using-python-%e7%94%a8python%e5%90%8c%e6%ad%a5twitter%e5%88%b0%e5%98%80%e5%92%95/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>同步 twitter 到 飯否</title>
		<link>http://phill84.org/2009/03/%e5%90%8c%e6%ad%a5-twitter-%e5%88%b0-%e9%a3%af%e5%90%a6/</link>
		<comments>http://phill84.org/2009/03/%e5%90%8c%e6%ad%a5-twitter-%e5%88%b0-%e9%a3%af%e5%90%a6/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 09:16:01 +0000</pubDate>
		<dc:creator>phill84</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[fanfou]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[sync]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[同步]]></category>
		<category><![CDATA[飯否]]></category>

		<guid isPermaLink="false">http://phill84.org/2009/03/%e5%90%8c%e6%ad%a5-twitter-%e5%88%b0-%e9%a3%af%e5%90%a6/</guid>
		<description><![CDATA[google 看到 raptium同學的 post Twitter和饭否同步 像我這種懶人自然就拿來用了 不過又不想把 twitter 上的回復也 sync 到飯否 so 加了一個 statement 把 @blah 都過濾了 如果有比我更懶得同學也想這麼做的話只要把 elif snode.nodeName == 'text': 改成 elif &#40;snode.nodeName == 'text'&#41; and &#40;snode.childNodes&#91;0&#93;.nodeValue&#91;0&#93; != '@'&#41;: 就可以了]]></description>
			<content:encoded><![CDATA[<p>google 看到 <a href="http://www.raptium.com/">raptium</a>同學的 post <a href="http://www.raptium.com/2009/02/01/twitter-sync-with-fanfou/">Twitter和饭否同步</a></p>
<p>像我這種懶人自然就拿來用了</p>
<p>不過又不想把 twitter 上的回復也 sync 到飯否</p>
<p>so 加了一個 statement 把 @blah 都過濾了</p>
<p>如果有比我更懶得同學也想這麼做的話只要把</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">elif</span> snode.<span style="color: black;">nodeName</span> == <span style="color: #483d8b;">'text'</span>:</pre></div></div>

<p>改成</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: black;">&#40;</span>snode.<span style="color: black;">nodeName</span> == <span style="color: #483d8b;">'text'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: black;">&#40;</span>snode.<span style="color: black;">childNodes</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">nodeValue</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">'@'</span><span style="color: black;">&#41;</span>:</pre></div></div>

<p>就可以了 <img src='http://phill84.org/wp-includes/images/smilies/icon_biggrin.gif' alt="icon biggrin 同步 twitter 到 飯否" class='wp-smiley colorbox-569' title="同步 twitter 到 飯否" /> </p>
]]></content:encoded>
			<wfw:commentRss>http://phill84.org/2009/03/%e5%90%8c%e6%ad%a5-twitter-%e5%88%b0-%e9%a3%af%e5%90%a6/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

