<?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; 豆瓣</title>
	<atom:link href="http://phill84.org/tag/%e8%b1%86%e7%93%a3/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>豆瓣小組引用回復插件</title>
		<link>http://phill84.org/2009/06/%e8%b1%86%e7%93%a3%e5%b0%8f%e7%b5%84%e5%bc%95%e7%94%a8%e5%9b%9e%e5%be%a9%e6%8f%92%e4%bb%b6/</link>
		<comments>http://phill84.org/2009/06/%e8%b1%86%e7%93%a3%e5%b0%8f%e7%b5%84%e5%bc%95%e7%94%a8%e5%9b%9e%e5%be%a9%e6%8f%92%e4%bb%b6/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 13:59:13 +0000</pubDate>
		<dc:creator>phill84</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[douban]]></category>
		<category><![CDATA[greasemonkey]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[插件]]></category>
		<category><![CDATA[豆瓣]]></category>

		<guid isPermaLink="false">http://phill84.org/2009/06/%e8%b1%86%e7%93%a3%e5%b0%8f%e7%b5%84%e5%bc%95%e7%94%a8%e5%9b%9e%e5%be%a9%e6%8f%92%e4%bb%b6/</guid>
		<description><![CDATA[在顯示樓層插件的基礎上加上了引用回復功能 因為是以顯示樓層插件為基礎, 所以要求依然是 firefox+greasemonkey, 並且包括顯示樓層功能 引用回復的 link 只有在鼠標在回復區塊上時才會顯示 如果想引用留言所在頁面不是最後一頁, 因此沒有回復框, 插件會自動在頁面上加上回復框 引用完成後頁面會滾動到底部回復框 * 增加: ctrl+enter 回復功能 (04/06/2009) * 修正bug: 不能在非第一頁或最後頁創建回復框 (10/06/2009) * 增加: 如果討論分頁, 在頁首也顯示導航條 (10/06/2009) 顯示效果如下圖 請點這裡安裝]]></description>
			<content:encoded><![CDATA[<p>在顯示樓層插件的基礎上加上了引用回復功能</p>
<p>因為是以顯示樓層插件為基礎, 所以要求依然是 firefox+greasemonkey, 並且包括顯示樓層功能</p>
<p>引用回復的 link 只有在鼠標在回復區塊上時才會顯示</p>
<p>如果想引用留言所在頁面不是最後一頁, 因此沒有回復框, 插件會自動在頁面上加上回復框</p>
<p>引用完成後頁面會滾動到底部回復框</p>
<p><span style="color: #993300;">* 增加: ctrl+enter 回復功能 (04/06/2009)</span><br />
<span style="color: #993300;">* 修正bug: 不能在非第一頁或最後頁創建回復框 (10/06/2009)</span><br />
<span style="color: #993300;">* 增加: 如果討論分頁, 在頁首也顯示導航條</span><span style="color: #993300;"> (10/06/2009)</span></p>
<p><span id="more-592"></span>顯示效果如下圖</p>
<blockquote><p><a href="http://phill84.org/wp-content/uploads/2009/06/screenshot.png"><img class="alignnone size-full wp-image-591 colorbox-592" title="Screenshot" src="http://phill84.org/wp-content/uploads/2009/06/screenshot.png" alt="screenshot 豆瓣小組引用回復插件" width="641" height="446" /></a></p></blockquote>
<p>請點<a href="http://userscripts.org/scripts/show/50759">這裡</a>安裝</p>
]]></content:encoded>
			<wfw:commentRss>http://phill84.org/2009/06/%e8%b1%86%e7%93%a3%e5%b0%8f%e7%b5%84%e5%bc%95%e7%94%a8%e5%9b%9e%e5%be%a9%e6%8f%92%e4%bb%b6/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>豆瓣討論區顯示樓層數GreaseMonkey插件</title>
		<link>http://phill84.org/2009/06/%e8%b1%86%e7%93%a3%e8%a8%8e%e8%ab%96%e5%8d%80%e9%a1%af%e7%a4%ba%e6%a8%93%e5%b1%a4%e6%95%b8greasemonkey%e6%8f%92%e4%bb%b6/</link>
		<comments>http://phill84.org/2009/06/%e8%b1%86%e7%93%a3%e8%a8%8e%e8%ab%96%e5%8d%80%e9%a1%af%e7%a4%ba%e6%a8%93%e5%b1%a4%e6%95%b8greasemonkey%e6%8f%92%e4%bb%b6/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 17:42:51 +0000</pubDate>
		<dc:creator>phill84</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[douban]]></category>
		<category><![CDATA[greasemonkey]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[豆瓣]]></category>

		<guid isPermaLink="false">http://phill84.org/2009/06/%e8%b1%86%e7%93%a3%e8%a8%8e%e8%ab%96%e5%8d%80%e9%a1%af%e7%a4%ba%e6%a8%93%e5%b1%a4%e6%95%b8greasemonkey%e6%8f%92%e4%bb%b6/</guid>
		<description><![CDATA[如題 requirements 是 firefox + greasemonkey 啟用後的效果如下 * NOTE: 此插件已不再更新，且因為豆瓣更改頁面布局此插件業已失效，請點擊 這裡 查看豆瓣引用回覆插件]]></description>
			<content:encoded><![CDATA[<p>如題</p>
<p>requirements 是 firefox + greasemonkey</p>
<p>啟用後的效果如下</p>
<blockquote><p><a href="http://phill84.org/wp-content/uploads/2009/06/screenshot_1.png"><img class="alignnone size-full wp-image-588 colorbox-590" title="Screenshot" src="http://phill84.org/wp-content/uploads/2009/06/screenshot_1.png" alt="screenshot 1 豆瓣討論區顯示樓層數GreaseMonkey插件" width="298" height="449" /></a></p></blockquote>
<p><span id="more-590"></span></p>
<blockquote><p><a href="http://phill84.org/wp-content/uploads/2009/06/screenshot_2.png"><img class="alignnone size-medium wp-image-589 colorbox-590" title="Screenshot" src="http://phill84.org/wp-content/uploads/2009/06/screenshot_2-449x147.png" alt="screenshot 2 449x147 豆瓣討論區顯示樓層數GreaseMonkey插件" width="449" height="147" /></a></p></blockquote>
<p><span style="color: #ff0000;">* NOTE: 此插件已不再更新，且因為豆瓣更改頁面布局此插件業已失效，請點擊 <a href="http://phill84.org/2009/06/%E8%B1%86%E7%93%A3%E5%B0%8F%E7%B5%84%E5%BC%95%E7%94%A8%E5%9B%9E%E5%BE%A9%E6%8F%92%E4%BB%B6/">這裡</a> 查看豆瓣引用回覆插件</span></p>
]]></content:encoded>
			<wfw:commentRss>http://phill84.org/2009/06/%e8%b1%86%e7%93%a3%e8%a8%8e%e8%ab%96%e5%8d%80%e9%a1%af%e7%a4%ba%e6%a8%93%e5%b1%a4%e6%95%b8greasemonkey%e6%8f%92%e4%bb%b6/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

