- 僕にはクックブックで例を見ながら、というスタイルがあっているようだ
- WebDBのPerlのコーナーも参考になる
- Javaで勉強したことが役に立っていると思う
- 微妙に違う付近は継承使って、ごまかし(?)た
- YAMLを使ってメアドとパスワードは別ファイルに書き出すようにした*1
- コンストラクタの付近とかがもうちょっと改良しないと
- とにもかくにも初めてPerlで継承とかそっちの付近ができてよかったのでありました
#!/usr/bin/perl package Hatena::Counter; use strict; use warnings; use WWW::Mechanize; use WWW::Mechanize::DecodedContent; use URI; use Web::Scraper; use Encode; use Time::Local; use Time::localtime; use File::Spec; use File::HomeDir; use Term::Prompt; use YAML; sub new() { my ($class) = @_; bless { year => $_[1], month => $_[2], is_recent => $_[3], }, $class; } sub login() { my $self = shift; my $year = $self->{year}; my $month = $self->{month}; my $config = $self->prepare_config(); my $name = $config->{name}; my $password = $config->{password}; my $mech = new WWW::Mechanize( autocheck => 1 ); $mech->get('https://www.hatena.ne.jp/login'); $mech->submit_form( fields => { name => $name, password => $password, }, ); return ($mech); } sub get_count() { #インターフェイス } sub scrape() { my $self = shift; my $mech = shift; scraper { process 'div#dailyreport>div.report_table>table.report>tr>td', 'count[]' => 'TEXT'; result qw/count/; } ->scrape( $mech->decoded_content ); } sub convert_counter() { my $self = shift; my $count = shift; my $year = $self->{year}; my $month = $self->{month}; my %counter = (); foreach ( my $i = 0 ; $i < scalar(@$count) ; $i = $i + 3 ) { my @days = split( /\//, @$count[$i] ); $counter{ timelocal( 0, 0, 0, $days[1], $days[0] - 1, $year ) } = @$count[ $i + 2 ]; } return (%counter); } sub get_date_and_count() { my $self = shift; my $year = $self->{year}; my $month = $self->{month}; my %counter = @_; my $mday; my $mon; my $wday; my $text; my $date; foreach my $day ( sort keys %counter ) { $date = scalar( localtime($day) ); $mday = $date->mday; $mon = $date->mon + 1; $wday = $date->wday; $text .= "$mday,$mon,$wday,$counter{$day}\n"; } return ($text); } sub prepare_config { my $path = File::Spec->catfile( File::HomeDir->my_home, ".hatena_counter" ); my $config = eval { YAML::LoadFile($path) } || {}; my $save; while ( !$config->{name} || !$config->{password} ) { $config->{name} = prompt( 'x', 'name: ', '', '' ); $config->{password} = prompt( 'p', 'password: ', '', '' ); $save++; } YAML::DumpFile( $path, $config ) if $save; chmod 0600, $path; return $config; } package Hatena::Counter::Recent; use base 'Hatena::Counter'; use strict; use warnings; use WWW::Mechanize; use WWW::Mechanize::DecodedContent; use URI; use Web::Scraper; use Encode; use Time::Local; use Time::localtime; sub get_count() { my $self = shift; my $year = $self->{year}; my $month = $self->{month}; my $mech = $self->login(); $mech->get('http://counter.hatena.ne.jp/syou6162/?cid=1'); my $count = $self->scrape($mech); return ($self->convert_counter($count)); } package Hatena::Counter::Month; use base 'Hatena::Counter'; use strict; use warnings; use WWW::Mechanize; use WWW::Mechanize::DecodedContent; use URI; use Web::Scraper; use Encode; use Time::Local; use Time::localtime; sub get_limit_day() { my $self = shift; my $year = $self->{year}; my $month = $self->{month}; my $tm = timelocal( 0, 0, 0, 1, $month, $year ) - 60 * 60 * 24; return ( localtime($tm)->mday ); } sub get_count() { my $self = shift; my $year = $self->{year}; my $month = $self->{month}; my $mech = $self->login(); if ( length($month) == 1 ) { $month = "0$month"; } my $url = 'http://counter.hatena.ne.jp/syou6162/report?cid=1&date=' . $year . '-' . $month . '-01&mode=access&type=monthly'; $mech->get($url); my $count = $self->scrape($mech); my %counter = (); my $newcount; if ( $self->{is_recent} == 0 ) { foreach ( my $i = 0 ; $i < get_limit_day() * 3 ; $i = $i + 3 ) { @$newcount[$i] = @$count[$i]; @$newcount[ $i + 1 ] = @$count[ $i + 1 ]; @$newcount[ $i + 2 ] = @$count[ $i + 2 ]; } } $count = $newcount; foreach ( my $i = 0 ; $i < scalar(@$count) ; $i = $i + 3 ) { my @days = split( /\//, @$count[$i] ); $counter{ timelocal( 0, 0, 0, $days[1], $days[0] - 1, $year ) } = @$count[ $i + 2 ]; } return (%counter); } package main; my $counter = Hatena::Counter::Recent->new( 2007, 10, 0 ); #コンストラクタ付近がいまいち my %counter = $counter->get_count(); print $counter->get_date_and_count(%counter);
*1:http://blog.kentarok.org/2007/04/05/232531.htmlを参考にさせてもらいました!