自分の発言をダウンロードしたくて
Twitterでの自分の発言をダウンロードしたくてコードを書いた。Archiveのダウンロードは無理っぽかったので、user_timelineをとってきてcronで回す方法に変更。
汎用性を持たせようと思ったのでコードが長くなった。いつもはDBIx::Class使っているけど、Loaderの設定とか面倒になったのでDBIを直にたたいてみたら終わるまで時間がかかってしまった。
以下コードのこと
最初書き忘れてしまったが、設定にはYAMLファイルを使います。第一引数にyamlファイルを指定してください。
username: ******** password: ******** db_file : hogehoge.sqlite3 (絶対パス推奨) table: message: messages
あと、テーブルの仕様は以下のものでデータベースにはSQLiteを使っています。
CREATE TABLE messages ( id BIGINT PRIMARY KEY, text TEXT, created_at DATETIME );
一応このSQL文はMySQLでも通るはずです。未確認ですが。
以下コード
#!/usr/bin/env perl use strict; use warnings; use Carp; use utf8; use encoding 'utf8'; use YAML::Syck; use Net::Twitter; use DateTime::Format::RSS; use DateTime::Format::MySQL; use SQL::Abstract; use DBI; use Readonly; Readonly our %DEFAULT => (MESSAGE_TABLE => 'messages'); our $config = init_config( @ARGV ); { my $message_table = $config->{table}->{message}; my $dbh = DBI->connect("dbi:SQLite:dbname=$config->{db_file}", '', '', { RaiseError => 1 }); $dbh->{unicode} = 1; my $max_id = $dbh->selectrow_array("SELECT max(id) FROM $message_table"); my $since = undef; if (defined $max_id ) { $since = $dbh->selectrow_array("SELECT created_at FROM $message_table WHERE id = $max_id") ; } my $twit = Net::Twitter->new(username => $config->{username}, password => $config->{password}); my $timeline = $twit->user_timeline( { id=> $config->{username}, count => 20, since => $since } ); insert_timeline($dbh, $timeline) if (defined $timeline); $dbh->disconnect; } sub init_config { my ($config_filename, $db_file) = @_; unless (-e $config_filename) { die "Can not open $config_filename"; } my $config_file = LoadFile($config_filename); my $config = {}; $config->{username} = $config_file->{username} || die 'Not input username'; $config->{password} = $config_file->{password} || die 'Not input password'; $config->{db_file} = $db_file || $config_file->{db_file} || die 'Not input DB File'; unless (-e $config->{db_file} ) { die "Can not open $config->{db_file}"; } $config->{table} = {}; if (defined $config_file->{table}) { $config->{table}->{message} = $config_file->{table}->{message} || $DEFAULT{MESSAGE_TABLE}; } else { $config->{table}->{message} = $DEFAULT{MESSAGE_TABLE}; } return $config; } sub insert_timeline { my $dbh = shift; my $timeline = shift; my $message_table = $config->{table}->{message}; my $table_item = { id => 0, text => q//, created_at => q// }; my $sql = SQL::Abstract->new; my ($stmt, @bind) = $sql->insert($message_table, $table_item); my $sth = $dbh->prepare($stmt); for my $item (@{$timeline}) { my $date = DateTime::Format::RSS->parse_datetime( $item->{created_at} ); my $date_str = DateTime::Format::MySQL->format_datetime( $date ); $table_item->{id} = $item->{id}; $table_item->{text} = $item->{text}; $table_item->{created_at} = $date_str; @bind = $sql->values( $table_item ); $sth->execute(@bind); } $sth->finish; } 1; __END__