Weitere ähnliche Inhalte
Ähnlich wie Hachiojipm #5 LT資料 [テーマ:最近いいなと思ったもの]
Ähnlich wie Hachiojipm #5 LT資料 [テーマ:最近いいなと思ったもの] (16)
Hachiojipm #5 LT資料 [テーマ:最近いいなと思ったもの]
- 1. Hachioji.pm #5
「最近いいなと思ったもの」 @norry_gogo
前回のHachioji.pmで「今度のGWに作りたいと思っているもの」として「TwitterのリストのTL内に含まれるURLを自動的にRead it later
に流し込む」というのを課題にしてみました
CPANモジュールガイドを参考に、部品を組み合わせるように手軽に「動くもの」が作れる感覚を楽しめました!
初めてのPerl第5版で、言語仕様や色々な書き方やショーカット等のPerlっぽさを知り、CPANモジュールガイドで部品を使って組み立てる
そんなこんなしている内に「あ、そういうことね」とか「あ、こうも書けるのか」とか、ジワジワと手応えを感じてきます
この2つのバイブルを使って脱ビギナーっていうのが、自分の経験からして良い感じと思いました! (と、シレっと脱ビギナー宣言w)
引き続きの課題は「目指せ中級者!」として、続・初めてのPerlやモダンPerl入門等を参考にして行きたいです!
CPANモジュールガイド++
初めてのPerl第5版++
※下記は今回の課題での成果物で、cronで定期実行させてます
#!/usr/bin/env perl sub get_list_statuses {
my ($list, $page) = @_;
use 5.010; my $statuses;
use strict; my $success = 1;
use warnings; eval {
use Net::Twitter; $statuses = $nt->list_statuses({
use URI::Find; user => $list->{user},
use Web::Scraper; list_id => $list->{list_id},
use LWP::UserAgent; per_page => 200,
use YAML; page => $page,
use Scalar::Util 'blessed'; since_id => $list->{since_id}
use Encode; });
};
my $config_uri ='/home/norry/hachioji.pm/5/config.yaml'; if (my $err = $@) {
my $config = YAML::LoadFile($config_uri); die $@ unless blessed $err && $err->isa('Net::Twitter::Error');
# --- $success = undef;
# lists: }
# - list_id: 25141045 return ($statuses, $success);
# list_name: perl }
# since_id: 74264112124801024
# user: norry_gogo sub find_uris_from {
# read_it_later: my $text = shift;
# apikey: ********** state @uris; @uris = ();
# password: ******** state $finder = URI::Find->new( sub {
# username: ******** my ($uri, $orig_uri) = @_;
push @uris, $orig_uri;
my $nt = Net::Twitter->new( return $orig_uri;
traits => [qw/API::REST API::Lists/], });
); $finder->find($text);
my $read_it_later = URI->new('https://readitlaterlist.com/v2/add'); return @uris;
my $ua = LWP::UserAgent->new; }
for my $list ( @{$config->{lists}} ) { sub expand_uri {
my $page = 1; my $uri = shift;
my $start_since_id = $list->{since_id}; my $res = $ua->head($uri);
my $new_since_id = $start_since_id; return undef unless $res->is_success;
LOOP_PAGE: return $res->request->uri;
while (1) { }
my ($statuses, $success) = get_list_statuses($list, $page);
$new_since_id = $start_since_id unless $success; sub get_html_title {
last LOOP_PAGE unless @$statuses; my $uri = shift;
for my $status (reverse @$statuses) { state $scraper = scraper {
my @uris = find_uris_from($status->{text}); process 'title', 'title' => 'TEXT';
for my $uri (@uris) { };
my $expand_uri = expand_uri($uri); my $html;
next unless $expand_uri; eval {
my $html_title = get_html_title($expand_uri); $html = $scraper->scrape(URI->new($uri));
next unless $html_title; };
$read_it_later->query_form( return undef if $@;
apikey => $config->{read_it_later}{apikey}, return "-- No title --" unless $html->{title};
username => $config->{read_it_later}{username}, return $html->{title};
password => $config->{read_it_later}{password}, }
url => $expand_uri,
title => sprintf "[TW]%s@%s / %sn",
$list->{list_name},
$status->{user}{screen_name},
$html_title,
); 感想:
my $res; ・良い点
eval { →自動的に流し込んでおいてくれるのは気持ち良い
$res = $ua->head("$read_it_later");
}; ・悪い点
next if $@; →リストの追加等が設定ファイルへの追記という手作業になる
if ($res->is_success) { →リスト上のURLを無条件に流し込むので、情報源として有用でないデータ
printf "[TW]%s@%s / %s (%s)n", を削除するコストの方が大きいという本末転倒な時もある
$list->{list_name},
$status->{user}{screen_name}, ・課題
encode('utf-8', $html_title), →ロケタッチやInstagram等、情報集めとしての目的とは外れるものをスル
$expand_uri; ーできる様にしたい
} →あるいは…やっぱり、人力での選別を挟みたい
}
$new_since_id = $status->{id} if $new_since_id < $status->{id}; と、言うことで。。。
} 自動で流し込んでくれるが実用的ではない…という結果↓↓↓
$page++;
} このままではあまりにもアレ過ぎるので、
$list->{since_id} = $new_since_id; TL上にURLの展開情報が出てワンボタンでAPI通信してくれるようなオレオレ
} Twitterクライアントを作りたい!っていう課題に発展させようと思います!
YAML::DumpFile($config_uri, $config); やってみて見えること、これとイタチゴッコしていきますw