Subscribed unsubscribe Subscribe Subscribe

PerlでTwitterとWassr

とりあえず投稿もできるようになったので、ある程度使い物になりそうな気がする

#!/usr/bin/perl
use strict;
use warnings;

use Encode;
use Getopt::Std;
use HTTP::Date;
# Net::Wassrは以下から取得
# http://svn.coderepos.org/share/lang/perl/Net-Wassr/
use Net::Wassr;
use Net::Twitter;

# オプションと引数
my %opts;
getopts('r:twhv', \%opts);
if ($opts{h}) {
    print "usage: ./twissr.pl [ -r 'rid_for_wassr' ] [ -tw 'message' ]\n";
    exit 1;
}
if ($opts{v}) {
    print "version 1.0\n";
    exit 1;
}

# ハッシュデータのキー名
my $id = 'id';
my $name = 'name';
my $time = 'time';
my $text = 'text';
my $reply = 'reply';
my $photo = 'photo_url';
my $service = 'service';

# ユーザー情報
# conf.txt または 標準入力 から読み取る
# 例:
# twitter_username=hogefugapiyo
# twitter_password=********
# wassr_username=hogefugapiyo
# wassr_password=********
my $conf_data;
open $conf_data, '<', 'conf.txt' or open $conf_data, '-';
my %conf;
for (<$conf_data>) {
    $conf{$1} = $2 if $_ =~ /^([^=]*)=(.*)/;
}
# Wassrインスタンス生成
my $wassr = Net::Wassr->new(
    user   => $conf{'wassr_username'},
    passwd => $conf{'wassr_password'},
    );
# Twitterインスタンス生成
my $twitter = Net::Twitter->new(
    username => $conf{'twitter_username'},
    password => $conf{'twitter_password'},
    );

# -w, -t の引数があれば投稿する
if ($opts{t} or $opts{w}) {
    if ($ARGV[0]) {
	&update($ARGV[0]);
    }
    exit 1;
}

# friends_timelineデータを取得する
my @array = ();
push(@array, &get_wassr_friends_timeline);
push(@array, &get_twitter_friends_timeline);
# 時刻順にソート
@array = sort {
    $a->{$time} <=> $b->{$time}
} @array;

# まとめて出力
for (@array) {
    print "from $_->{$service}($_->{$id})\n";
    print "$_->{$reply}\n" if $_->{$reply};
    print $_->{$text}, "\n";
    print "$_->{$photo}\n" if $_->{$photo};
    print "by $_->{$name} at ", HTTP::Date::time2iso($_->{$time}), "\n";
    print "\n";
}

# 投稿
sub update {
    if (defined($opts{w})) {
	my %args = (
	    status => $_[0],
	    source => $0,
	    reply_status_rid => $opts{r},
	);
	if ($wassr->update(\%args)) {
	    print "Update Wassr success!\n";
	} else {
	    print "Update Wassr failed!\n";
	}
    }
    if (defined($opts{t})) {
	if ($twitter->update($_[0])) {
	    print "Update Twitter success!\n";
	} else {
	    print "Update Twitter failed!\n";
	}
    }
}

# Wassrからfriends_timelineデータを取得
sub get_wassr_friends_timeline {
    my $wassr_data = $wassr->friends_timeline;
    return unless defined($wassr_data);

    my @ret = ();
    for (@{$wassr_data}) {
	my %data = ();
	$data{$service} = 'Wassr';
	$data{$id} = $_->{'rid'};
	$data{$name} = utf8encode($_->{user}->{'screen_name'}) . "($_->{'user_login_id'})";
	$data{$time} = $_->{'epoch'};
	$data{$text} = utf8encode($_->{'text'});
	if ($_->{'reply_user_login_id'}) {
	    my $reply_message;
	    if ($_->{'reply_message'}) {
		$reply_message = utf8encode($_->{'reply_message'});
	    } else {
		$reply_message = "<非公開ヒトコト>";
	    }
	    $data{$reply} = "> " . $reply_message . " by " . utf8encode($_->{'reply_user_nick'});
	}
	$data{$photo} = $_->{'photo_url'};
	push(@ret, \%data);
    }

    return @ret;
}

# Twitterからfriends_timelineデータを取得
sub get_twitter_friends_timeline {
    my $twitter_data = $twitter->friends_timeline();
    return unless defined($twitter_data);

    my @ret = ();
    for (@$twitter_data) {
	my %data = ();
	$data{$service} = 'Twitter';
	$data{$id} = $_->{'id'};
	$data{$name} = $_->{'user'}->{'screen_name'};
	my $created_at = $_->{'created_at'};
	$created_at =~ s/\+0000/UTC/;
	$data{$time} = HTTP::Date::str2time($created_at);
	$data{$text} = utf8encode($_->{'text'});
	push(@ret, \%data);
    }

    return @ret;
}

# UTF-8エンコーディング
sub utf8encode {
    return Encode::encode('UTF-8', $_[0]);
}

SVNで管理することにする。
http://www.sugyan.mydns.jp/repos/sugyan/lang/perl/twissr/src/twissr.pl
うーん、すぐに醜くなってしまう。Perlは難しい。