blog/content/post/2010/03/29/2010-03-29-00001346.md

125 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Tumblr の引用だけを Twitter に通知する Perl スクリプト
author: kazu634
date: 2010-03-29
url: /2010/03/29/_1499/
wordtwit_post_info:
- 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:5199;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}'
categories:
- Perl
---
<div class="section">
<p>
書いてみました。
</p>
<h4>
何が問題だったの?
</h4>
<p>
Tumblr に付属の Twitter 連携だと、画像とかも Twitter に通知されてしまうので、タイムラインが流れてしまいます(どうしても画像がメインになってしまいますよね。。。)。個人的にこれはあまりいい状況ではないと思っていました。そのために、 Tumblr の Twitter 連携機能をオフにしていました。ですが、個人的には引用だけを Twitter に通知したかったので、 Tumblr と Twitter の API を活用して、連携させました。
</p>
<h4>
ソース
</h4>
<p>
Perl で書きました。そのうち gauche に移植する!
</p>
<pre class="syntax-highlight">
# === Libraries ===
use strict<span class="synComment">;</span>
use warnings<span class="synComment">;</span>
use Perl<span class="synConstant">6</span>::Say<span class="synComment">;</span>
use YAML::Syck<span class="synComment">;</span>
use WebService::Simple<span class="synComment">;</span>
use XML::Simple<span class="synComment">;</span>
use utf<span class="synConstant">8</span><span class="synComment">;</span>
use Encode<span class="synComment">;</span>
use Config::Auto<span class="synComment">;</span>
use Net::Twitter<span class="synComment">;</span>
# === Until what ID <span class="synStatement">number</span> <span class="synStatement">do</span> I <span class="synStatement">get</span> from my favorites ===
my $recent_id <span class="synStatement">=</span> <span class="synConstant"></span><span class="synComment">; # variant for storing the recent-obtained ID number</span>
# Read <span class="synStatement">the</span> ID <span class="synStatement">number</span> from <span class="synStatement">the</span> configuration file, .get_tumblr,
# <span class="synStatement">if</span> it exists.
<span class="synStatement">if</span> <span class="synSpecial">(</span> -f <span class="synConstant">&#34;.get_tumblr&#34;</span> <span class="synSpecial">)</span> {
my $config <span class="synStatement">=</span> Config::Auto::parse<span class="synSpecial">(</span><span class="synConstant">&#34;.get_tumblr&#34;</span><span class="synSpecial">)</span><span class="synComment">;</span>
$recent_id <span class="synStatement">=</span> $config-&#62;{recent_id}<span class="synComment">;</span>
}
# === Tumblr から引用を取得する ===
my $tumblr <span class="synStatement">=</span>
WebService::Simple-&#62;new<span class="synSpecial">(</span> base_url =&#62; <span class="synConstant">&#34;http://tumblrのユーザー名.tumblr.com/api/read&#34;</span>, <span class="synSpecial">)</span><span class="synComment">;</span>
my $response <span class="synStatement">=</span> $tumblr-&#62;get<span class="synSpecial">(</span> { <span class="synStatement">type</span> =&#62; <span class="synSpecial">'</span><span class="synIdentifier">quote</span><span class="synSpecial">'</span><span class="synIdentifier">,</span> num =&#62; <span class="synSpecial">'</span><span class="synIdentifier">50</span><span class="synSpecial">'</span> } <span class="synSpecial">)</span><span class="synComment">;</span>
my $data <span class="synStatement">=</span> XMLin<span class="synSpecial">(</span> $response-&#62;content <span class="synSpecial">)</span><span class="synComment">;</span>
my @ids <span class="synStatement">=</span> <span class="synStatement">sort</span> keys %{ $data-&#62;{posts}-&#62;{post} }<span class="synComment">;</span>
# === 取得した XML データを操作する処理 ===
foreach my $id <span class="synSpecial">(</span>@ids<span class="synSpecial">)</span> {
next <span class="synStatement">if</span> <span class="synSpecial">(</span>$id <span class="synStatement">&#60;=</span> $recent_id<span class="synSpecial">)</span><span class="synComment">;</span>
my $text <span class="synStatement">=</span> encode<span class="synSpecial">(</span> <span class="synSpecial">'</span><span class="synIdentifier">utf-8</span><span class="synSpecial">'</span><span class="synIdentifier">,</span> $data-&#62;{posts}-&#62;{post}-&#62;{$id}-&#62;{<span class="synConstant">&#34;quote-text&#34;</span>} <span class="synSpecial">)</span><span class="synComment">;</span>
my $url <span class="synStatement">=</span> encode<span class="synSpecial">(</span> <span class="synSpecial">'</span><span class="synIdentifier">utf-8</span><span class="synSpecial">'</span><span class="synIdentifier">,</span> $data-&#62;{posts}-&#62;{post}-&#62;{$id}-&#62;{<span class="synConstant">&#34;quote-source&#34;</span>} <span class="synSpecial">)</span><span class="synComment">;</span>
# URLの処理
<span class="synStatement">if</span> <span class="synSpecial">(</span>$url <span class="synStatement">=</span>~ /&#60;a href=<span class="synConstant">&#34;([^&#34;</span>]+<span class="synSpecial">)</span><span class="synConstant">&#34;/) {</span>
<span class="synConstant"> $url = $1;</span>
<span class="synConstant"> } else {</span>
<span class="synConstant"> $url = encode( 'utf-8', $data-&#62;{posts}-&#62;{post}-&#62;{$id}-&#62;{&#34;</span>url<span class="synConstant">&#34;} );</span>
<span class="synConstant"> }</span>
<span class="synConstant"> # HTMLを除去する処理</span>
<span class="synConstant"> $text =~ s/&#60;a.*&#62;.+&#60;\/a&#62;://g;</span>
<span class="synConstant"> $text =~ s/&#60;.*?&#62;//g;</span>
<span class="synConstant"> $text =~ s/\(via?[^\)]+\)//g;</span>
<span class="synConstant"> $text =~ s/\n//g;</span>
<span class="synConstant"> $text =~ s/^\s+//g;</span>
<span class="synConstant"> chomp($text);</span>
<span class="synConstant"> # shorten URLs</span>
<span class="synConstant"> my $bitly = WebService::Simple-&#62;new(</span>
<span class="synConstant"> base_url =&#62; &#34;</span>http://api.<span class="synStatement">bit</span>.ly/shorten<span class="synConstant">&#34;,</span>
<span class="synConstant"> param =&#62; {</span>
<span class="synConstant"> login =&#62; &#34;</span><span class="synStatement">bit</span>.lyのユーザー名<span class="synConstant">&#34;,</span>
<span class="synConstant"> apiKey =&#62; &#34;</span><span class="synStatement">bit</span>.lyのAPIキー<span class="synConstant">&#34;,</span>
<span class="synConstant"> version =&#62; &#34;2.0.1&#34;,</span>
<span class="synConstant"> format =&#62; &#34;</span>xml<span class="synConstant">&#34;,</span>
<span class="synConstant"> }</span>
<span class="synConstant"> );</span>
<span class="synConstant"> my $bitly_result = $bitly-&#62;get( { longUrl =&#62; $url } );</span>
<span class="synConstant"> my $short =</span>
<span class="synConstant"> XMLin( $bitly_result-&#62;content )-&#62;{results}-&#62;{nodeKeyVal}-&#62;{shortUrl};</span>
<span class="synConstant"> $url = $short;</span>
<span class="synConstant"> # 文字数のカウント</span>
<span class="synConstant"> # UTFの場合注意が必要!</span>
<span class="synConstant"> # http://weeeblog.net/blog/2007/12/01_1445.php</span>
<span class="synConstant"> my $count_text = length( decode( 'utf-8', $text ) );</span>
<span class="synConstant"> my $count_url = length( decode( 'utf-8', $url ) );</span>
<span class="synConstant"> next if $text eq &#34;&#34;;</span>
<span class="synConstant"> my $twitter =</span>
<span class="synConstant"> Net::Twitter-&#62;new( { username =&#62; 'Twitterのユーザー名', password =&#62; 'Twitterのパスワード' } );</span>
<span class="synConstant"> if ( ( $count_text + $count_url + 16 ) &#60;= 140 ) {</span>
<span class="synConstant"> my $result = $twitter-&#62;update({status =&#62; &#34;</span>[<span class="synStatement">quote</span>] $text $url<span class="synConstant">&#34;});</span>
<span class="synConstant"> }</span>
<span class="synConstant"> else {</span>
<span class="synConstant"> # 投稿するスクリプトの整形処理</span>
<span class="synConstant"> my $display_text =</span>
<span class="synConstant"> substr( decode( 'utf-8', $text ), 0, ( 140 - ( $count_url + 12 ) ) );</span>
<span class="synConstant"> $text = decode( 'utf-8', $text);</span>
<span class="synConstant"> my $result = $twitter-&#62;update({status =&#62; &#34;</span>[<span class="synStatement">quote</span>] $display_text... $url<span class="synConstant">&#34;});</span>
<span class="synConstant"> }</span>
<span class="synConstant"> $recent_id = $id;</span>
<span class="synConstant"> last;</span>
<span class="synConstant">}</span>
<span class="synConstant"># === update the recent_id ===</span>
<span class="synConstant">open( FILE, '&#62; .get_tumblr' ) or die &#34;</span>$!<span class="synConstant">&#34;;</span>
<span class="synConstant">say FILE &#34;</span>recent_id=$recent_id<span class="synConstant">&#34;;</span>
<span class="synConstant">close(FILE);</span>
</pre>
<h4>
とりあえず
</h4>
<p>
自宅サーバで0時8時の間で cron で回してみて結果を見てみます。
</p>
</div>