| 1 | #!/usr/bin/perl
|
|---|
| 2 |
|
|---|
| 3 | use strict;
|
|---|
| 4 | use warnings;
|
|---|
| 5 | use utf8; # but maybe no need ;-D
|
|---|
| 6 |
|
|---|
| 7 | use XML::Feed;
|
|---|
| 8 | use URI;
|
|---|
| 9 |
|
|---|
| 10 | # ID
|
|---|
| 11 | our $ID = $ARGV[0] || 'bayashi_net';
|
|---|
| 12 |
|
|---|
| 13 | # 定数
|
|---|
| 14 | our $LIMIT = 100; # 結果表示するユーザ数の最大数
|
|---|
| 15 | our $PAGE = 4; # 実際に処理するページ - 1 の値
|
|---|
| 16 | our $ROW = 20; # 1ページあたりのブックマーク数
|
|---|
| 17 | our $SLEEP = 3; # ウェイト秒
|
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 | #--- メインルーチン
|
|---|
| 21 | {
|
|---|
| 22 |
|
|---|
| 23 | # 集計するブックマークIDのチェック
|
|---|
| 24 | if ( $ID !~ /^[a-zA-Z][-a-zA-Z0-9_]{1,30}[a-zA-Z0-9]$/ ) {
|
|---|
| 25 | die "ID [$ID] is wrong!";
|
|---|
| 26 | }
|
|---|
| 27 |
|
|---|
| 28 | print "[$ID]\n";
|
|---|
| 29 |
|
|---|
| 30 | # 集計
|
|---|
| 31 | my %users = get_commenters( $ID, get_my_bookmarks( get_my_rss($ID) ) );
|
|---|
| 32 |
|
|---|
| 33 | # 結果表示
|
|---|
| 34 | my $count = 1;
|
|---|
| 35 | for my $user ( sort { $users{$b} <=> $users{$a} } keys %users ) {
|
|---|
| 36 |
|
|---|
| 37 | printf "%03d : %03d : %15s : http://b.hatena.ne.jp/%s/\n",
|
|---|
| 38 | $count, $users{$user}, $user, $user;
|
|---|
| 39 |
|
|---|
| 40 | last if $LIMIT < ++$count;
|
|---|
| 41 |
|
|---|
| 42 | }
|
|---|
| 43 |
|
|---|
| 44 | }
|
|---|
| 45 |
|
|---|
| 46 |
|
|---|
| 47 | #--- 以下、サブルーチン
|
|---|
| 48 |
|
|---|
| 49 | # idのブックマークRSSページのURLをリストで返します
|
|---|
| 50 | sub get_my_rss {
|
|---|
| 51 | my $id = shift;
|
|---|
| 52 |
|
|---|
| 53 | my @my_rss;
|
|---|
| 54 | for my $p (0..$PAGE) {
|
|---|
| 55 |
|
|---|
| 56 | my $of = $p * $ROW + ($p==0);
|
|---|
| 57 | push @my_rss, "http://b.hatena.ne.jp/$id/rss?of=$of";
|
|---|
| 58 |
|
|---|
| 59 | }
|
|---|
| 60 |
|
|---|
| 61 | return @my_rss;
|
|---|
| 62 | }
|
|---|
| 63 |
|
|---|
| 64 | # RSSページからブックマークしたエントリーURLをリストで返します
|
|---|
| 65 | sub get_my_bookmarks {
|
|---|
| 66 | my @my_rss = @_;
|
|---|
| 67 |
|
|---|
| 68 | my @my_bookmarks;
|
|---|
| 69 | for my $rss_url (@my_rss) {
|
|---|
| 70 |
|
|---|
| 71 | my $feed = XML::Feed->parse( URI->new($rss_url) )
|
|---|
| 72 | or die XML::Feed->errstr. "\nCan not parse [$rss_url].\n";
|
|---|
| 73 |
|
|---|
| 74 | for my $item ($feed->entries) {
|
|---|
| 75 | push @my_bookmarks, 'http://b.hatena.ne.jp/entry/rss/'. $item->link;
|
|---|
| 76 | }
|
|---|
| 77 |
|
|---|
| 78 | sleep $SLEEP;
|
|---|
| 79 |
|
|---|
| 80 | }
|
|---|
| 81 |
|
|---|
| 82 | return @my_bookmarks;
|
|---|
| 83 | }
|
|---|
| 84 |
|
|---|
| 85 | # 各ブックマークページのブックマーカーから
|
|---|
| 86 | # 自分($id)よりも早くブックマークしているユーザをハッシュでカウントします
|
|---|
| 87 | sub get_commenters {
|
|---|
| 88 | my ($id, @bookmarks) = @_;
|
|---|
| 89 |
|
|---|
| 90 | my %users;
|
|---|
| 91 | for my $url (@bookmarks) {
|
|---|
| 92 |
|
|---|
| 93 | my $rss = XML::Feed->parse( URI->new($url) )
|
|---|
| 94 | or die XML::Feed->errstr. "\nCan not parse [$url].\n";
|
|---|
| 95 |
|
|---|
| 96 | my $me = 0;
|
|---|
| 97 | for my $item ($rss->entries) {
|
|---|
| 98 |
|
|---|
| 99 | my $link = $item->link;
|
|---|
| 100 | next unless $link;
|
|---|
| 101 |
|
|---|
| 102 | if ($me) {
|
|---|
| 103 | $users{$1}++ if $link =~ m!^http://b\.hatena\.ne\.jp/([^/]+)/!;
|
|---|
| 104 | }
|
|---|
| 105 | elsif ( $link =~ m!^http://b\.hatena\.ne\.jp/\Q$id\E/! ) {
|
|---|
| 106 | $me = 1;
|
|---|
| 107 | }
|
|---|
| 108 |
|
|---|
| 109 | }
|
|---|
| 110 | sleep $SLEEP;
|
|---|
| 111 | }
|
|---|
| 112 | return %users;
|
|---|
| 113 | }
|
|---|
| 114 |
|
|---|
| 115 |
|
|---|
| 116 | __END__
|
|---|
| 117 |
|
|---|
| 118 |
|
|---|
| 119 | =head1 NAME
|
|---|
| 120 |
|
|---|
| 121 | early-hatena-bookmarkers.pl - お気に入りをふやそう!
|
|---|
| 122 |
|
|---|
| 123 | =head1 DESCRIPTION
|
|---|
| 124 |
|
|---|
| 125 | このスクリプトは、あるIDがブックマークしているエントリーを
|
|---|
| 126 | IDよりも早くブックマークしているユーザを集計表示します。
|
|---|
| 127 |
|
|---|
| 128 | =head1 SYNOPSIS
|
|---|
| 129 |
|
|---|
| 130 | # perl early-hatena-bookmarkers.pl HATENA_ID
|
|---|
| 131 |
|
|---|
| 132 | =head1 SEE ALSO
|
|---|
| 133 |
|
|---|
| 134 | http://b.hatena.ne.jp/
|
|---|
| 135 |
|
|---|
| 136 | =head1 AUTHOR
|
|---|
| 137 |
|
|---|
| 138 | id:bayashi_net
|
|---|
| 139 |
|
|---|
| 140 | =head1 LICENSE
|
|---|
| 141 |
|
|---|
| 142 | This module is free software; you can redistribute it and/or
|
|---|
| 143 | modify it under the same terms as Perl itself. See L<perlartistic>.
|
|---|
| 144 |
|
|---|
| 145 | =cut
|
|---|