Changeset 364

Show
Ignore:
Timestamp:
03/23/07 18:43:05 (1 year ago)
Author:
ogawa
Message:

Rewrites in more OO-style.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • cybozu2ical/trunk/cybozu2ical

    r363 r364  
    4141    my $vevent = Data::ICal::Entry::Event->new(); 
    4242    my %args = ( 
    43         summary     => decode_utf8($item->{summary}), 
    44         description => decode_utf8($item->{description}), 
    45         created     => to_icaldate($item->{created}), 
    46         dtstamp     => to_icaldate($item->{modified}), 
     43        summary     => decode_utf8($item->summary), 
     44        description => decode_utf8($item->description), 
     45        created     => to_icaldate($item->created), 
     46        dtstamp     => to_icaldate($item->modified), 
    4747    ); 
    4848 
    49     $args{comment} = decode_utf8($item->{debug_info}
    50         if $opt{debug} && $item->{debug_info}
    51  
    52     if ($item->{is_full_day}) { 
    53         $args{dtstart} = [to_icaldate($item->{start}, 1), { VALUE => 'DATE' }]; 
    54         $args{dtend}   = [to_icaldate($item->{end},   1), { VALUE => 'DATE' }]; 
     49    $args{comment} = decode_utf8($item->comment
     50        if $opt{debug} && $item->comment
     51 
     52    if ($item->is_full_day) { 
     53        $args{dtstart} = [to_icaldate($item->start, 1), { VALUE => 'DATE' }]; 
     54        $args{dtend}   = [to_icaldate($item->end,   1), { VALUE => 'DATE' }]; 
    5555    } else { 
    56         $args{dtstart} = [to_icaldate($item->{start}, 0), { TZID => $time_zone }]; 
    57         $args{dtend}   = [to_icaldate($item->{end},   0), { TZID => $time_zone }]; 
     56        $args{dtstart} = [to_icaldate($item->start, 0), { TZID => $time_zone }]; 
     57        $args{dtend}   = [to_icaldate($item->end,   0), { TZID => $time_zone }]; 
    5858    } 
    5959 
    6060    # handle frequency 
    61     if ($item->{frequency}) { 
    62         my $freq = $item->{frequency}
     61    if ($item->can('frequency')) { 
     62        my $freq = $item->frequency
    6363        my %rrules = $freq ne 'WEEKDAYS' ? 
    6464            ( FREQ => $freq, WKST => 'SU' ) : 
    6565            ( FREQ => 'WEEKLY', WKST => 'SU', BYDAY => 'MO,TU,WE,TH,FR' ); 
    66         $rrules{UNTIL} = to_icaldate($item->{until}, $item->{is_full_day}
    67             if $item->{until}
     66        $rrules{UNTIL} = to_icaldate($item->until, $item->is_full_day
     67            if $item->until
    6868        $args{rrule} = join ';', map { $_ . '=' . $rrules{$_} } keys %rrules; 
    6969    } 
  • cybozu2ical/trunk/lib/WWW/CybozuOffice6/Calendar.pm

    r363 r364  
    5151        next if $#fields < 13; # num. of fields 
    5252 
    53         my $item = $fields[7] ? 
    54             $this->_parse_recurrent_event(@fields) : 
    55             $this->_parse_general_event(@fields); 
    56         $item->{debug_info} = $line; # save the CSV line as for debug info. 
    57         push @items, $item if $item; 
     53        # Cybozu Calendar CSV Format 
     54        #      GENERIC     | RECCURENT 
     55        # [ 0] id?         | id? 
     56        # [ 1] created     | created 
     57        # [ 2] <BLANK>     x start_date 
     58        # [ 3] start_date  x end_date 
     59        # [ 4] end_date    x until_date 
     60        # [ 5] start_time  | start_time 
     61        # [ 6] end_time    | end_time 
     62        # [ 7] <BLANK>     | freq 
     63        # [ 8] <BLANK>     | freq_value 
     64        # [ 9] ???         | ??? 
     65        # [10] ???         | ??? 
     66        # [11] abbrev      | abbrev 
     67        # [12] summary     | summary 
     68        # [13] description | description 
     69 
     70        my %param; 
     71        @param{qw(created start_time end_time freq freq_value abbrev summary description)} = @fields[1,5..8,11..13]; 
     72        $param{created} =~ s/^ts\.//; 
     73        $param{time_zone} = $this->{time_zone} || 'Asia/Tokyo'; 
     74 
     75        my $item; 
     76        if (!$param{freq}) { 
     77            @param{qw(start_date end_date)} = @fields[3,4]; 
     78            $item = WWW::CybozuOffice6::Calendar::Event->new(%param); 
     79        } else { 
     80            @param{qw(start_date end_date until_date)} = @fields[2..4]; 
     81            $item = WWW::CybozuOffice6::Calendar::RecurentEvent->new(%param); 
     82        } 
     83 
     84        next unless $item; 
     85        $item->comment($line); # save the CSV line as for debug info. 
     86        push @items, $item; 
    5887    } 
    5988    wantarray ? @items : $items[0]; 
     
    73102} 
    74103 
    75 # handle non-recurrent events 
    76 sub _parse_general_event { 
    77     my $this = shift; 
    78     my @fields = @_; 
    79  
    80     my $now = DateTime->now; 
    81     my $is_full_day = 0; 
    82  
    83     my $start = $this->to_datetime($fields[3], $fields[5]); 
    84     my $end   = $this->to_datetime($fields[4], $fields[6]); 
     104package WWW::CybozuOffice6::Calendar::Event; 
     105 
     106sub new { 
     107    my $class = shift; 
     108    my $self = { 
     109        is_full_day => 0, 
     110        modified => DateTime->now, 
     111    }; 
     112    bless $self, $class; 
     113    return unless $self->parse(@_); 
     114    $self; 
     115
     116 
     117sub start       { shift->_accessor('start',             @_) } 
     118sub end         { shift->_accessor('end',               @_) } 
     119sub summary     { shift->_accessor('summary',           @_) } 
     120sub description { shift->_accessor('description',       @_) } 
     121sub created     { shift->_accessor('created',           @_) } 
     122sub modified    { shift->_accessor('modified',          @_) } 
     123sub is_full_day { shift->_accessor('is_full_day',       @_) } 
     124sub comment     { shift->_accessor('comment',           @_) } 
     125sub _accessor { 
     126    my $this = shift; 
     127    my $key = shift; 
     128    $this->{$key} = shift if @_; 
     129    $this->{$key}; 
     130
     131 
     132sub parse { 
     133    my($this, %param) = @_; 
     134 
     135    $this->{time_zone} = $param{time_zone} || 'Asia/Tokyo'; 
     136 
     137    my $start = $this->to_datetime($param{start_date}, $param{start_time}); 
     138    my $end   = $this->to_datetime($param{end_date},   $param{end_time}); 
    85139    return unless $start && $end; 
    86     if ($fields[5] eq ':') {            # full-day event 
     140 
     141    # (start_time == empty) => A full-day event 
     142    # (start_time != empty) && (end_time == empty) => A malformed event 
     143    if ($param{start_time} eq ':') { 
    87144        $start = $start->truncate(to => 'day'); 
    88145        $end   = $end->add(days => 1)->truncate(to => 'day'); 
    89         $is_full_day = 1; 
    90     } elsif ($fields[6] eq ':') {      # event w/o endtime 
     146        $this->{is_full_day} = 1; 
     147    } elsif ($param{end_time} eq ':') { 
    91148        $end   = $start->clone->add(minutes => 10); 
    92149    } 
    93  
    94     my($created) = $fields[1] =~ m/^ts\.(\d+)$/; 
    95     $created = DateTime->from_epoch(epoch => $created || 0); 
    96  
    97     my $summary = $fields[11] || ''; 
    98     $summary .= ': ' if $summary; 
    99     $summary .= $fields[12] || ''; 
    100  
    101     my $item = { 
    102         start       => $start, 
    103         end         => $end, 
    104         is_full_day => $is_full_day, 
    105         summary     => $summary, 
    106         description => $fields[13] || $summary, 
    107         created     => $created, 
    108         modified    => $now, 
    109     }; 
    110 
    111  
    112 # handle recurrent events 
    113 our %FREQUENCY = ( y => 'YEARLY', m => 'MONTHLY', w => 'WEEKLY', 
    114                    d => 'DAILY', n => 'WEEKDAYS' ); 
    115 sub _parse_recurrent_event { 
    116     my $this = shift; 
    117     my @fields = @_; 
    118  
    119     # arrange for _parse_general_event 
    120     my @f = @fields; 
    121     $f[4] = $f[3]; 
    122     $f[3] = $f[2]; 
    123     my $item = $this->_parse_general_event(@f); 
    124  
    125     # frequency 
    126     my $freq = $fields[7]; 
    127     if ($freq && exists $FREQUENCY{$freq}) { 
    128         $item->{frequency} = $FREQUENCY{$freq}; 
    129         $item->{frequency_value} = $fields[8] || 0; 
    130         if ($fields[4] =~ m!^(\d+)/(\d+)/(\d+)$!) { 
    131             my %args = (year => $1, month => $2, day => $3); 
    132             my $until; 
    133             if ($item->{is_full_day}) { 
    134                 $until = $this->to_datetime($fields[4], ':'); 
    135             } else { 
    136                 $until = $item->{end}->clone->set(%args); 
    137                 $until->set_time_zone('UTC'); # timezone must be UTC 
    138             } 
    139             $item->{until} = $until; 
    140         } 
    141     } 
    142  
    143     $item; 
    144 
    145  
     150    $this->{start} = $start; 
     151    $this->{end}   = $end; 
     152 
     153    $this->{created} = DateTime->from_epoch(epoch => $param{created} || 0); 
     154 
     155    my $summary = ($param{abbrev} ? $param{abbrev} . ': ' : '') . $param{summary}; 
     156    $this->{summary} = $summary; 
     157    $this->{description} = $param{description} || $summary; 
     158    1; 
     159
     160 
     161# convert (ymd, hms) pair to a DateTime object (timezone: localtime) 
    146162sub to_datetime { 
    147163    my $this = shift; 
     
    160176    } 
    161177 
    162     $args{time_zone} = $this->{time_zone} || 'Asia/Tokyo'
     178    $args{time_zone} = $this->{time_zone}
    163179 
    164180    DateTime->new(%args); 
     181} 
     182 
     183package WWW::CybozuOffice6::Calendar::RecurrentEvent; 
     184 
     185@WWW::CybozuOffice6::Calendar::RecurrentEvent::ISA = qw( WWW::CybozuOffice6::Calendar::Event ); 
     186 
     187sub frequency           { shift->_accessor('frequency',         @_) } 
     188sub frequency_value     { shift->_accessor('frequency_value',   @_) } 
     189 
     190our %FREQUENCY = ( y => 'YEARLY', m => 'MONTHLY', w => 'WEEKLY', 
     191                   d => 'DAILY', n => 'WEEKDAYS' ); 
     192sub parse { 
     193    my($this, %param) = @_; 
     194    $this->SUPER::parse(%param); 
     195 
     196    # frequency 
     197    my $freq = $param{freq}; 
     198    return unless $freq && exists $FREQUENCY{$freq}; 
     199 
     200    $this->{frequency} = $FREQUENCY{$freq}; 
     201    $this->{frequency_value} = $param{freq_value} || 0; 
     202 
     203    if ($param{until_date} =~ m!^(\d+)/(\d+)/(\d+)$!) { 
     204        my %args = (year => $1, month => $2, day => $3); 
     205        my $until; 
     206        if ($this->{is_full_day}) { 
     207            $until = $this->to_datetime($param{until_date}, ':'); 
     208        } else { 
     209            $until = $this->{end}->clone->set(%args); 
     210            $until->set_time_zone('UTC'); # timezone must be UTC 
     211        } 
     212        $this->{until} = $until; 
     213    } 
     214    1; 
    165215} 
    166216