Changeset 505 for cybozu2ical/trunk/lib

Show
Ignore:
Timestamp:
08/28/08 13:24:42 (4 months ago)
Author:
ogawa
Message:

Refactor Event classes and employ Class::Accessor::Fast again.

Location:
cybozu2ical/trunk/lib/WWW
Files:
3 added
2 modified

Legend:

Unmodified
Added
Removed
  • cybozu2ical/trunk/lib/WWW/CybozuOffice6/Calendar.pm

    r504 r505  
    55use warnings; 
    66 
     7use base qw( Class::Accessor::Fast ); 
    78use Carp; 
    89use Encode qw( from_to ); 
    910use LWP::UserAgent; 
    1011use URI; 
    11 use DateTime; 
     12use WWW::CybozuOffice6::Calendar::Event; 
     13use WWW::CybozuOffice6::Calendar::RecurrentEvent; 
    1214 
    1315our $VERSION = '0.20'; 
     
    2123} 
    2224 
    23 sub url            { shift->_accessor( 'url',            @_ ) } 
    24 sub host           { shift->_accessor( 'host',           @_ ) } 
    25 sub username       { shift->_accessor( 'username',       @_ ) } 
    26 sub userid         { shift->_accessor( 'userid',         @_ ) } 
    27 sub password       { shift->_accessor( 'password',       @_ ) } 
    28 sub ua             { shift->_accessor( 'ua',             @_ ) } 
    29 sub input_encoding { shift->_accessor( 'input_encoding', @_ ) } 
    30  
    31 sub _accessor { 
    32     my $this = shift; 
    33     my $key  = shift; 
    34     $this->{$key} = shift if @_; 
    35     $this->{$key}; 
    36 } 
     25__PACKAGE__->mk_accessors( 
     26    qw( url host username userid password ua input_encoding )); 
    3727 
    3828sub request { 
     
    156146} 
    157147 
    158 package WWW::CybozuOffice6::Calendar::Event; 
    159  
    160 sub new { 
    161     my $class = shift; 
    162     my $self  = { 
    163         is_full_day => 0, 
    164         modified    => DateTime->now, 
    165     }; 
    166     bless $self, $class; 
    167     return unless $self->parse(@_); 
    168     $self; 
    169 } 
    170  
    171 sub id          { shift->_accessor( 'id',          @_ ) } 
    172 sub start       { shift->_accessor( 'start',       @_ ) } 
    173 sub end         { shift->_accessor( 'end',         @_ ) } 
    174 sub summary     { shift->_accessor( 'summary',     @_ ) } 
    175 sub description { shift->_accessor( 'description', @_ ) } 
    176 sub created     { shift->_accessor( 'created',     @_ ) } 
    177 sub modified    { shift->_accessor( 'modified',    @_ ) } 
    178 sub is_full_day { shift->_accessor( 'is_full_day', @_ ) } 
    179 sub comment     { shift->_accessor( 'comment',     @_ ) } 
    180  
    181 sub _accessor { 
    182     my $this = shift; 
    183     my $key  = shift; 
    184     $this->{$key} = shift if @_; 
    185     $this->{$key}; 
    186 } 
    187  
    188 sub parse { 
    189     my ( $this, %param ) = @_; 
    190  
    191     $this->{id}        = $param{id}        || '0'; 
    192     $this->{time_zone} = $param{time_zone} || 'Asia/Tokyo'; 
    193  
    194     my $start = $this->to_datetime( $param{start_date}, $param{start_time} ); 
    195     my $end   = $this->to_datetime( $param{end_date},   $param{end_time} ); 
    196     return unless $start && $end; 
    197  
    198     # (start_time == empty) => A full-day event 
    199     # (start_time != empty) && (end_time == empty) => A malformed event 
    200     if ( $param{start_time} eq ':' ) { 
    201         $start = $start->truncate( to => 'day' ); 
    202         $end = $end->add( days => 1 )->truncate( to => 'day' ); 
    203         $this->{is_full_day} = 1; 
    204     } 
    205     elsif ( $param{end_time} eq ':' ) { 
    206         $end = $start->clone->add( minutes => 10 ); 
    207     } 
    208     $this->{start} = $start; 
    209     $this->{end}   = $end; 
    210  
    211     $this->{created} = DateTime->from_epoch( epoch => $param{created} || 0 ); 
    212  
    213     my $summary = 
    214       ( $param{abbrev} ? $param{abbrev} . ': ' : '' ) . $param{summary}; 
    215     $this->{summary} = $summary; 
    216     $this->{description} = $param{description} || $summary; 
    217     1; 
    218 } 
    219  
    220 # convert (ymd, hms) pair to a DateTime object (timezone: localtime) 
    221 sub to_datetime { 
    222     my $this = shift; 
    223     my ( $ymd, $hms ) = @_; 
    224  
    225     my %args; 
    226     return 
    227       unless $ymd 
    228           && (   $ymd =~ m!^(\d+)/(\d+)/(\d+)$! 
    229               || $ymd =~ m!^da\.(\d+)\.(\d+)\.(\d+)$! ); 
    230     @args{qw(year month day)} = ( $1, $2, $3 ); 
    231  
    232     if ( $hms && $hms ne ':' ) { 
    233         return unless $hms =~ m!^(\d+):(\d+)(?:\:?(\d+)?)$!; 
    234         @args{qw(hour minute second)} = ( $1, $2, $3 || 0 ); 
    235         @args{qw(hour minute second)} = ( 23, 59, 59 ) if $args{hour} > 23; 
    236     } 
    237     else { 
    238         @args{qw(hour minute second)} = ( 0, 0, 0 ); 
    239     } 
    240  
    241     $args{time_zone} = $this->{time_zone}; 
    242  
    243     DateTime->new(%args); 
    244 } 
    245  
    246 package WWW::CybozuOffice6::Calendar::RecurrentEvent; 
    247  
    248 use base qw( WWW::CybozuOffice6::Calendar::Event ); 
    249  
    250 sub rrule { shift->_accessor( 'rrule', @_ ) } 
    251  
    252 # for compatibility 
    253 sub frequency       { shift->_accessor( 'frequency',       @_ ) } 
    254 sub frequency_value { shift->_accessor( 'frequency_value', @_ ) } 
    255 sub until           { shift->_accessor( 'until',           @_ ) } 
    256  
    257 sub exdates { 
    258     my $this = shift; 
    259     return unless $this->{exdates}; 
    260     my $exdates = $this->{exdates}; 
    261     wantarray ? @$exdates : @$exdates[0]; 
    262 } 
    263  
    264 our %FREQUENCY = ( 
    265     y => 'YEARLY', 
    266     m => 'MONTHLY', 
    267     w => 'WEEKLY', 
    268     d => 'DAILY', 
    269     n => 'WEEKDAYS' 
    270 ); 
    271  
    272 sub parse { 
    273     my ( $this, %param ) = @_; 
    274     $this->SUPER::parse(%param); 
    275  
    276     # frequency 
    277     my $freq = $param{freq}; 
    278     return unless $freq && exists $FREQUENCY{$freq}; 
    279  
    280     # rrule 
    281     my %rrule = (); 
    282     if ( $FREQUENCY{$freq} eq 'WEEKDAYS' ) { 
    283         %rrule = ( FREQ => 'WEEKLY', BYDAY => 'MO,TU,WE,TH,FR' ); 
    284     } 
    285     else { 
    286         %rrule = ( FREQ => $FREQUENCY{$freq} ); 
    287     } 
    288     if ( $param{freq_value} =~ /^\d(SU|MO|TU|WE|TH|FR|SA)$/ ) { 
    289         $rrule{BYDAY}    = $param{freq_value}; 
    290         $rrule{INTERVAL} = 1; 
    291     } 
    292  
    293     # until 
    294     if (   $param{until_date} =~ m!^(\d+)/(\d+)/(\d+)$! 
    295         || $param{until_date} =~ m!^da\.(\d+)\.(\d+)\.(\d+)$! ) 
    296     { 
    297         my %args = ( year => $1, month => $2, day => $3 ); 
    298         my $until; 
    299         if ( $this->{is_full_day} ) { 
    300             $until = $this->to_datetime( $param{until_date}, ':' ); 
    301         } 
    302         else { 
    303             $until = $this->{end}->clone->set(%args); 
    304             $until->set_time_zone('UTC');    # timezone must be UTC 
    305         } 
    306         $rrule{UNTIL} = $until; 
    307     } 
    308  
    309     $this->{rrule} = \%rrule; 
    310  
    311     # exdates 
    312     if ( defined $param{exdates} ) { 
    313         my @exdates; 
    314         for ( @{ $param{exdates} } ) { 
    315             push @exdates, $this->to_datetime( $_, $param{start_time} ); 
    316         } 
    317         $this->{exdates} = \@exdates; 
    318     } 
    319  
    320     # for compatibility 
    321     $this->{frequency}       = $FREQUENCY{$freq}; 
    322     $this->{frequency_value} = $param{freq_value} || 0; 
    323     $this->{until}           = $rrule{UNTIL} if exists $rrule{UNTIL}; 
    324  
    325     1; 
    326 } 
    327  
    3281481; 
    329149__END__ 
  • cybozu2ical/trunk/lib/WWW/CybozuOffice7/Calendar.pm

    r504 r505  
    1212use URI; 
    1313use DateTime; 
     14use WWW::CybozuOffice6::Calendar::Event; 
     15use WWW::CybozuOffice6::Calendar::RecurrentEvent; 
    1416 
    1517our $VERSION = '0.20';