125 lines
9.5 KiB
Markdown
125 lines
9.5 KiB
Markdown
---
|
||
title: Tumblr の引用だけを Twitter に通知する Perl スクリプト
|
||
author: kazu634
|
||
date: 2010-03-29
|
||
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">".get_tumblr"</span> <span class="synSpecial">)</span> {
|
||
my $config <span class="synStatement">=</span> Config::Auto::parse<span class="synSpecial">(</span><span class="synConstant">".get_tumblr"</span><span class="synSpecial">)</span><span class="synComment">;</span>
|
||
$recent_id <span class="synStatement">=</span> $config->{recent_id}<span class="synComment">;</span>
|
||
}
|
||
# === Tumblr から引用を取得する ===
|
||
my $tumblr <span class="synStatement">=</span>
|
||
WebService::Simple->new<span class="synSpecial">(</span> base_url => <span class="synConstant">"http://tumblrのユーザー名.tumblr.com/api/read"</span>, <span class="synSpecial">)</span><span class="synComment">;</span>
|
||
my $response <span class="synStatement">=</span> $tumblr->get<span class="synSpecial">(</span> { <span class="synStatement">type</span> => <span class="synSpecial">'</span><span class="synIdentifier">quote</span><span class="synSpecial">'</span><span class="synIdentifier">,</span> num => <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->content <span class="synSpecial">)</span><span class="synComment">;</span>
|
||
my @ids <span class="synStatement">=</span> <span class="synStatement">sort</span> keys %{ $data->{posts}->{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"><=</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->{posts}->{post}->{$id}->{<span class="synConstant">"quote-text"</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->{posts}->{post}->{$id}->{<span class="synConstant">"quote-source"</span>} <span class="synSpecial">)</span><span class="synComment">;</span>
|
||
# URLの処理
|
||
<span class="synStatement">if</span> <span class="synSpecial">(</span>$url <span class="synStatement">=</span>~ /<a href=<span class="synConstant">"([^"</span>]+<span class="synSpecial">)</span><span class="synConstant">"/) {</span>
|
||
<span class="synConstant"> $url = $1;</span>
|
||
<span class="synConstant"> } else {</span>
|
||
<span class="synConstant"> $url = encode( 'utf-8', $data->{posts}->{post}->{$id}->{"</span>url<span class="synConstant">"} );</span>
|
||
<span class="synConstant"> }</span>
|
||
<span class="synConstant"> # HTMLを除去する処理</span>
|
||
<span class="synConstant"> $text =~ s/<a.*>.+<\/a>://g;</span>
|
||
<span class="synConstant"> $text =~ s/<.*?>//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->new(</span>
|
||
<span class="synConstant"> base_url => "</span>http://api.<span class="synStatement">bit</span>.ly/shorten<span class="synConstant">",</span>
|
||
<span class="synConstant"> param => {</span>
|
||
<span class="synConstant"> login => "</span><span class="synStatement">bit</span>.lyのユーザー名<span class="synConstant">",</span>
|
||
<span class="synConstant"> apiKey => "</span><span class="synStatement">bit</span>.lyのAPIキー<span class="synConstant">",</span>
|
||
<span class="synConstant"> version => "2.0.1",</span>
|
||
<span class="synConstant"> format => "</span>xml<span class="synConstant">",</span>
|
||
<span class="synConstant"> }</span>
|
||
<span class="synConstant"> );</span>
|
||
<span class="synConstant"> my $bitly_result = $bitly->get( { longUrl => $url } );</span>
|
||
<span class="synConstant"> my $short =</span>
|
||
<span class="synConstant"> XMLin( $bitly_result->content )->{results}->{nodeKeyVal}->{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 "";</span>
|
||
<span class="synConstant"> my $twitter =</span>
|
||
<span class="synConstant"> Net::Twitter->new( { username => 'Twitterのユーザー名', password => 'Twitterのパスワード' } );</span>
|
||
<span class="synConstant"> if ( ( $count_text + $count_url + 16 ) <= 140 ) {</span>
|
||
<span class="synConstant"> my $result = $twitter->update({status => "</span>[<span class="synStatement">quote</span>] $text $url<span class="synConstant">"});</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->update({status => "</span>[<span class="synStatement">quote</span>] $display_text... $url<span class="synConstant">"});</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, '> .get_tumblr' ) or die "</span>$!<span class="synConstant">";</span>
|
||
<span class="synConstant">say FILE "</span>recent_id=$recent_id<span class="synConstant">";</span>
|
||
<span class="synConstant">close(FILE);</span>
|
||
</pre>
|
||
|
||
<h4>
|
||
とりあえず
|
||
</h4>
|
||
|
||
<p>
|
||
自宅サーバで0時~8時の間で cron で回してみて結果を見てみます。
|
||
</p>
|
||
</div>
|