XML::LibXMLのせいでNet::Google::Calendarがcpan installできない。

Raspberry piにNet::Google::Calendarを入れようとしたのですが、XML::Atom::Feedとかのmakeに失敗してcpan installできませんでした。
XML::Atom::Feedとかの依存の大元がXML::LibXMLだったので、こいつをinstallしようとしたのですが、libxml2がないとかわけのわからんことを言い出してmakeに失敗しました。
いや、libxml2入ってるから…と思ってたのですが、よく考えたらlibxml2のdevelを入れてませんでした。

Debian系統なら以下のコマンドを実行後にcpan install Net::Google::Calendarで解決できるかもしれません。

$sudo apt-get install libxml2-dev

lists/members/create_allが502エラーを返す。

POST lists/members/create_all | Twitter Developers

A comma separated list of user IDs, up to 100 are allowed in a single request.

仕様通り素直に100人直列で送ると間違いなく502エラーを返します。

TimeLine Copier – フォローしてる人をリストにコピーするツール
最初は50人で送ってたのですが、どうも不安定で使えないことこの上ない(一度に60人登録できたり10人でエラー起こしたり不定)ので、問答無用で100人ずつぶちこんだあと、自分のFollowingとリストに登録できた人の差分をとって繰り返し処理することにしました。
配列の差分をとる方法がないか調べたらList::Compareというモジュールがよさそうだったので使用しました。
List::Compare – search.cpan.org

my $lc = List::Compare->new(\@array1, \@array2);
my @l_only = $lc->get_Lonly; #array1にしかない要素の配列を取得

結果的に処理に時間かかるようになったのと、lists/membersエンドポイントにもアクセスしないといけなくなったのでAPI消費量があれなのですが、確実性は増したかなって気がします。
ちなみにめんどくさくてFoolowingが5000人の場合で試してないですが、確実にAPI切れ起こすと思います。
要請があったらテストするけど、そのときはベタの配列で5000人分のデータそっちで用意して欲しいなーって思います。
テストしたんですがやっぱり2600あたりでエラー起こしました。スリープさせて15分後に処理再開したら全員入れられるんだけど、そこまでする義理もないので対処しません。

ふぁぼってるひと計算するツールのソース。

あなたが一番ふぁぼってる人
ふぁぼった覚えのない人が結果に出てきた、って言ってる方がいて問題扱いされてるらしいので、GitHubにコードあげときました。
連想配列ソートしてるので、同率がいた場合はだれが結果に出てくるかわかりません。多分200件のうちの誰か1人にいるはずなので探していただきたいなと思います。
いなかったらAPIバグってるとしか言いようがないので私じゃ対処できないです。

GitHub: retrorocket/fav

これ自体練習用につくったやつだし無くしてもいいかなーって気がします。最近アレなことが多いのでfavico以外全消ししたい気分になりました。

Web::ScraperとNet::Google::Calendarをあわせて使う。

過去に北海道ライフル射撃協会の紹介(動画あり) の内容をWeb::ScraperでスクレーピングしてNet::Google::Calendarで投稿するスクリプトを書きました。
が、サンプルに使ってたページが無くなってました。
スクレーピングする元さえあれば動くスクリプトなのでそのまま貼っておきます。

これを応用すると色んなページのHTMLで書いてある予定とかをGoogleカレンダーに投稿できます。
例えばHTMLで書いてた昔の日記のタイトルを$entry->content(‘content’)で内容と一緒に投稿するとか。

use utf8;
use strict;
use warnings;

use Web::Scraper;
use URI;
use DateTime;
use Net::Google::Calendar;


# HTMLスクレーピング
my $scraper = scraper {
	 process '/html/body/table/tbody/tr/td/table/tbody/tr/td/div[2]/div[3]/table/tbody/tr[2]/td[2]', 'date' => 'HTML';#日付の書いてあるtdまでのXPath
	 process '/html/body/table/tbody/tr/td/table/tbody/tr/td/div[2]/div[3]/table/tbody/tr[2]/td[3]', 'nakami' => 'HTML';#内容までのXPath
};

# URL
my $uri = new URI('http://www.h3.dion.ne.jp/~moasa/shoukai.html');

# オブジェクト生成
my $res = $scraper->scrape($uri);

#########データ整形#################### 
my $temp = $res->{date};
$temp =~ tr/0-9A-Za-z/0-9A-Za-z/;#全角数字を半角に
$temp =~ s/<br \/>/\n/g;
$temp =~ s/<font [^>]*">|<\/font>//g;
my @daylist = split(/\n/, $temp);

##
my $temp2 = $res->{nakami};
$temp2 =~ tr/0-9A-Za-z/0-9A-Za-z/;
$temp2 =~ tr/:/:/;
$temp2 =~ s/<br \/>/\n/g;
$temp2 =~ s/<font [^>]*">|<\/font>| //g;
$temp2 =~ s{\x{301c}}{\x{ff5e}}g; #波ダッシュ変換
$temp2 =~ s/~/-/g;
my @titlelist = split(/\n/, $temp2);
########################################

# Google カレンダーへのログイン処理 
my $private_url = 'https://www.google.com/calendar/feeds/カレンダーID@group.calendar.google.com/private-カレンダーID/basic';
my $username = '***@gmail.com'; # x...@gmail.com 
my $password = '***'; #パスワード

# オブジェクト生成
my $cal = Net::Google::Calendar->new( url => $private_url ); 
$cal->login($username, $password); 

my $counter = 0;
my $datetemp;
my $flag = 0;

my $dt = DateTime->now;
my $year  = $dt->year; #今年の西暦取得

foreach my $title (@titlelist) { #イベントのタイトル

	my $date = $daylist[$counter]; #イベントのタイトルと対になる日付
	$counter++;

	my $entry = Net::Google::Calendar::Entry->new();
	$entry->status('confirmed');
	$entry->transparency('transparent'); 
	$entry->visibility('private'); #一般公開する場合public

	if ($date eq "\n" || $date eq "") { $date = $datetemp; }
	chomp($date);

	my $next;

	my @list = ($date =~ /\d+/g); #日付の数字だけ取得
	my $num = @list;
	if ($num != 2){
		$next = $list[2] - $list[1];
	}
	my $month = $list[0];
	my $day = $list[1];

	if ($month == 12) {$flag = 1;}

	my $hour = 0;
	my $allday = 0;
	my $plus = 0;

	if ($title =~ /(\d{1,2}):(\d{1,2})-(\d{1,2}):(\d{1,2})/) {
		$hour = $1;
		$plus = $3 - $1;
		$title =~ s/\d{1,2}:\d{1,2}-\d{1,2}:\d{1,2}//g;
	}
	elsif ($title =~ /(\d{1,2}):(\d{1,2})-$/) {
		$hour = $1;
		$plus = 24- $1;
		$title =~ s/\d{1,2}:\d{1,2}-//g;
	}
	else {
		$allday = 1;
	}

	if ($month < 12 && $flag == 1) {
		$year++;
		$flag = 0;
	}

	if (defined($next)) { #日付をまたぐ場合
		my $dt = DateTime->new(
    			time_zone => 'Asia/Tokyo',
    			year      => $year,
    			month     => $month,
    			day       => $day
		);
		my $dt2 = $dt + DateTime::Duration->new( days => $next+1 );
		my $dt3 =  $dt2->add( days =>1 );
		$entry->when($dt->add( days =>1 ), $dt2, $dt3);
	}
	elsif ($allday == 1){ #終日の場合
		my $dt = DateTime->new(
    			time_zone => 'Asia/Tokyo',
    			year      => $year,
    			month     => $month,
    			day       => $day
		);
		$entry->when($dt,$dt->add( days => 1 ),$dt);
	}
	else {
		my $dt = DateTime->new( #時間指定の場合
			time_zone => 'Asia/Tokyo',
			year      => $year,
    			month     => $month,
    			day       => $day,
    			hour      => $hour,
    			minute    => 0
		);
		$entry->when($dt, $dt+DateTime::Duration->new( hours => $plus ));
	}

	$entry->title($title);
	$cal->add_entry($entry); #カレンダーにイベントを投稿

	$datetemp = $date;
}