#!/usr/bin/perl my $debug = 0 ; use Time::Local ; use Jcode ; use Net::Google::Calendar; use Text::vFile::asData ; use DateTime::Duration ; #------------------------------- # Google Calendar の登録情報 $url = 'http://www.google.com/calendar/feeds/XXXX%40gmail.com/' .'private-XXXXXXXXXXX/basic' ; $user = 'XXXX@gmail.com'; $pass = 'PPPPPPPP'; $calname = Jcode->new( 'NNNN' )->utf8 ; #------------------------------- # iCalの日時の形式をDateTime形式に変換する。 sub DateTime_ical( $$ ) { my $str = shift ; my $opt = shift ; my $tz ; if ( $opt =~ /TZID=([a-z\/]+)/i ) { $tz = $1 ; } if ( $str =~ /^(\d\d\d\d)(\d\d)(\d\d)$/ ) { # 終日イベント return DateTime->new( year => $1 , month => $2 , day =>$3 ) ; } elsif ( $str =~ /^(\d\d\d\d)(\d\d)(\d\d)T(\d\d)(\d\d)(\d\d)(Z|)$/ ) { # 時間指定イベント if ( $7 eq "Z" ) { # GMT イベント return DateTime->new( year => $1 , month => $2 , day =>$3 , hour => $4 , minute => $5 , second =>$6 ) ; } else { # ローカル時間イベント return DateTime->new( time_zone => $tz , year => $1 , month => $2 , day =>$3 , hour => $4 , minute => $5 , second =>$6 ) ; } } } # iCalから読んだデータを Google Calendar に追加 sub ical2gcal( $$ ) { my $cal = shift ; my $fh = shift ; my $data = Text::vFile::asData->new->parse( $fh ) ; my $entry , $when ; foreach my $line ( Text::vFile::asData->generate_lines( $data ) ) { if ( $line =~ /^BEGIN:VEVENT$/ ) { # Event処理の開始 $entry = Net::Google::Calendar::Entry->new() ; } elsif ( $line =~ /^END:VEVENT$/ ) { # Eventの終了マーカで、イベントを書き込む if ( $entry && $when{'DTSTART'} ne "" && $when{'DTEND'} ne "" ) { # print "DTSTART:".$when{'DTSTART'}."/ DTEND:" , $when{'DTEND'}."\n" ; $entry->when( $when{'DTSTART'} , $when{'DTEND'} , $when{'allday'} ) ; print "add_entry:".Jcode->new( $entry->title )->euc."\n" if ( $debug ) ; $cal->add_entry( $entry ) ; } undef $entry ; undef %when ; } elsif ( $entry ) { # 互換性のある情報だけを抜き出す(繰り返しイベントは無視) if ( $line =~ /^TRANSP:(.*)$/ ) { #$entry->trasparency( lc $1 ) ; } elsif ( $line =~ /^STATUS:(.*)$/ ) { $entry->status( lc $1 ) ; } elsif ( $line =~ /^CLASS:(.*)$/ ) { $entry->visibility( lc $1 ) ; } elsif ( $line =~ /^LOCATION:(.*)$/ ) { $entry->location( Jcode->new( $1 )->utf8 ) ; } elsif ( $line =~ /^SUMMARY:(.*)$/ ) { $entry->title( Jcode->new( $1 )->utf8 ) ; } elsif ( $line =~ /^(DTSTART|DTEND)((;(TZID|VALUE)=[^;:]*)*):(.*)$/ ) { ($key,$opt,$val) = ($1,$2,$5) ; $when{$key} = DateTime_ical( $val , $opt ) ; $when{'allday'} = 'allday' if ( $opt =~ /VALUE=DATE/ ) ; # 終日 } } } } my $cal = Net::Google::Calendar->new( url => $url ); # $cal->{_ua}->env_proxy; # (2) $cal->login($user, $pass) or die $@; # (3) # 指定されたカレンダーを選ぶ my $dest_cal ; foreach my $c ( $cal->get_calendars ) { $dest_cal = $c if ( $c->title eq $calname ) ; } if ( $dest_cal ) { # 登録されていたイベントを全部消す $cal->set_calendar( $dest_cal ) ; my $start_index = 1 ; my $max_results = 20 ; my @ev ; while( 1 ) { # 指定件数しかイベントを返さないので少しづつ消す @ev = $cal->get_events( start-index => $start_index , max-results => $max_results ) ; last if ( @ev == 0 ) ; foreach my $e ( @ev ) { print "delete_entry:".Jcode->new( $e->title )->euc."\n" if ( $debug ) ; $cal->delete_entry( $e ) ; } $start_index += @ev ; } # 複数の iCal から読み取ったイベントをカレンダーに追加 print "set_calendar:".Jcode->new( $dest_cal->title )->euc."\n" if ( $debug ) ; $cal->set_calendar( $dest_cal ) ; foreach $file ( @ARGV ) { open my $fh , $file or die "Can't open file:$!" ; ical2gcal( $cal , $fh ) ; close $fh ; } }