[僕] 2006年07月17日 アーカイブ

僕ト云フ事

たろマークはてなブックマーク

2006年07月17日

[ical][perl][マンガ] マンガの新刊を iCal で追いかける

まんが王倶楽部さんで配布されている新刊 の CSV を iCalendar 形式にする web app を作りました。(元ネタ

Comic2iCal

iCal 形式のデータが読めるアプリだったら使えると思います。(Google Calendar と iPod しか試してない)

Google Calendar に import する手順はこんな感じです。

  1. 右上の Settings をクリック
  2. Calendars タブを選ぶ。
  3. 一番下にある add calendar をクリック
  4. Public Calendar Address タブを選ぶ。
  5. Comic2iCal で出てきた iCal の URL を入力して add ボタンを押す

060717_comic2ical_google_calendar.gif

Google Calendar は反映するのに多少時間かかるので適当に待ってください。

参考にさせていただきました。

Comic2iCal.pm


package Comic2iCal;
 
# $Id: Comic2iCal.pm 34 2006-07-17 00:16:08Z taro $
use warnings;
use strict;
use Carp;
use base qw( Class::Accessor::Fast );
 
use Readonly;
use DateTime;
use LWP::UserAgent;
use Text::CSV::Simple;
use Encode qw( from_to );
use Date::ICal;
use Data::ICal;
use Data::ICal::Entry::Event;
 
__PACKAGE__->mk_accessors( qw(cache date ua csv) );
 
Readonly my $base_uri => 'http://www.mangaoh.co.jp/download/comic';
 
our $VERSION = '0.2';
 
sub new {
    my ($class, %fields) = @_;
    my $self = bless {}, $class;
    $self->cache( $fields{cache} || './cache' );
    $self->date( DateTime->now( time_zone=>'local' ) );
    $self->ua( LWP::UserAgent->new );
    $self->ua->agent( 'Comic2iCal/' . $VERSION );
    $self->csv( Text::CSV::Simple->new({binary=>1}) );
 
    $self;
}
 
sub get_csv {
    my $self = shift;
 
    my $url = $base_uri . $self->date->strftime('%Y%m') . '.csv';
    $self->ua->mirror($url, $self->cache);
}
 
sub search {
    my $self = shift;
    my @keys = @_;
 
    $self->csv->field_map(qw/publisher date title writer price/);
    my @datas = $self->csv->read_file( $self->cache );
 
    my $ical = Data::ICal->new;
    $ical->add_properties(
        'X-WR-CALNAME' => join(' ',@keys),
    );
 
    for my $data ( @datas ) {
        my $hit = 0;
        next unless defined($data->{writer});
        from_to($data->{writer}, 'sjis', 'utf8');
        for my $key ( @keys ) {
            $hit = 1
                if ( $data->{writer} eq $key );
        }
        next unless $hit;
 
        from_to($data->{title}, 'sjis', 'utf8');
        from_to($data->{date}, 'sjis', 'utf8');
 
        my $event = Data::ICal::Entry::Event->new;
        my @date = split('/', $data->{date});
        if ( $date[2] eq '上' ) {
            $date[2] = 1;
        } elsif ( $date[2] eq '中' ) {
            $date[2] = 15;
        } elsif ( $date[2] eq '下'
                    or $date[2] eq '末'
                        or $date[2] eq '未' ) {
            my $dt = DateTime->last_day_of_month(
                year => $date[0],
                month => $date[1]
            );
            $date[2] = $dt->day;
        }
        $data->{date} = sprintf("%04d%02d%02d" , @date );
        $event->add_properties(
            summary     => $data->{title},
            description => $data->{price},
            dtstart     => $data->{date},
        );
        $ical->add_entry($event);
    }
    return $ical->as_string;
}
 
1;
__END__
 
=head1 NAME
 
Comic2iCal - まんが王倶楽部さんで配布されてる CSV を ical にする
 
=head1 SYNOPSIS
 
    use Comic2iCal;
    my $c2i = Comic2iCal->new;
    $ci->get_csv;
    print $ci->search( qw(椎名高志 ゆうきまさみ) );
 
=head1 DESCRIPTION
 
まんが王倶楽部さんで配布されてる CSV を取得し、
特定のマンガ家で絞り込んだ ical を出力します。
 
=head1 Methods
 
=over
 
=item new
 
コンストラクタです。
 
=item get_csv
 
まんが王倶楽部から CSV をダウンロードしてきます。
 
=item search
 
絞り込みたいマンガ家をリストで渡すと ical データを返します。
 
    my $ical $ci->search( qw(椎名高志 ゆうきまさみ) );
 
=back
 
=head2 アクセサ
 
=over
 
=item cache
 
cache の場所を指します。
 
=item date
 
DateTime オブジェクトです。
 
    $c2i->date->set(
        year => 2006
        month => 07
    );
 
=head1 AUTHOR
 
Daisuke Komatsu  C<< <taro@cpan.org> >>
 
=head1 LICENCE AND COPYRIGHT
 
Copyright (c) 2006, Daisuke Komatsu C<< <taro@cpan.org> >>. All rights reserved.
 
This module is free software; you can redistribute it and/or
modify it under the same terms as Perl itself. See L<perlartistic>.