Changeset 446
- Timestamp:
- 10/16/07 01:34:11 (15 months ago)
- Location:
- cybozu2ical/trunk
- Files:
-
- 2 modified
-
cybozu2ical (modified) (8 diffs)
-
lib/WWW/CybozuOffice6/Calendar.pm (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
cybozu2ical/trunk/cybozu2ical
r376 r446 7 7 use lib 'lib'; 8 8 9 use YAML;10 9 use Encode qw/decode_utf8 encode/; 11 10 use WWW::CybozuOffice6::Calendar; … … 20 19 our $VERSION = '0.13'; 21 20 21 ### 22 22 ### TRICK (stop escaping for 'exdate' property) 23 ### 23 24 *Data::ICal::Property::_value_as_string = sub { 24 25 my $self = shift; … … 38 39 39 40 }; 40 ### END 41 42 my %opt = (conf => 'config.yaml'); 43 GetOptions(\%opt, 'help', 'debug', 'conf=s') or pod2usage(2); 41 42 ### 43 ### Utility subroutines 44 ### 45 sub to_icaldate { 46 my($dt, $is_full_day) = @_; 47 $is_full_day ? 48 $dt->ymd('') : 49 $dt->ymd('') . 'T' . $dt->hms('') . ($dt->time_zone->is_utc ? 'Z' : ''); 50 } 51 52 sub encode_string { 53 my($enc, $text) = @_; 54 if ($enc eq 'ncr') { 55 $text =~ s/(\P{ASCII})/sprintf("&#%d;", ord($1))/eg; 56 } else { 57 $text = encode($enc, $text); 58 } 59 $text; 60 } 61 62 sub read_yaml { 63 my $file = shift; 64 my $yaml; 65 if (eval('require YAML::Tiny')) { 66 ($yaml) = YAML::Tiny::LoadFile($file); 67 } elsif (eval('require YAML')) { 68 ($yaml) = YAML::LoadFile($file); 69 } 70 if ($@) { 71 die "Faild to read yaml file: $@"; 72 } 73 $yaml; 74 } 75 76 ### 77 ### Main part 78 ### 79 80 # Handle command-line options 81 my %opt = ( 82 conf => 'config.yaml', 83 'compat-google-calendar' => 0, 84 ); 85 GetOptions(\%opt, 86 'output=s', 87 'conf=s', 88 'compat-google-calendar', 89 'debug', 90 'help', 91 ) or pod2usage(2); 44 92 pod2usage(1) if $opt{help}; 45 93 46 my $cfg = YAML::LoadFile($opt{conf}); 47 94 # Read configuration file 95 my $cfg = read_yaml($opt{conf}); 48 96 my $time_zone = $cfg->{time_zone} || 'Asia/Tokyo'; 49 97 98 # Generate a root 'calendar' object 50 99 my $vcalendar = Data::ICal->new(); 51 100 $vcalendar->add_properties( … … 57 106 ); 58 107 108 # Obtain Cybozu Office 6 Calendar items 59 109 my $cal = WWW::CybozuOffice6::Calendar->new(%$cfg); 110 111 # For each items, generate an 'event entry' and append it to the calendar 60 112 for my $item ($cal->get_items()) { 61 113 my $vevent = Data::ICal::Entry::Event->new(); … … 83 135 my $freq = $item->frequency; 84 136 my %rrules = $freq ne 'WEEKDAYS' ? 85 ( FREQ => $freq, WKST => 'SU' ) : 86 ( FREQ => 'WEEKLY', WKST => 'SU', BYDAY => 'MO,TU,WE,TH,FR' ); 137 ( FREQ => $freq ) : 138 ( FREQ => 'WEEKLY', BYDAY => 'MO,TU,WE,TH,FR' ); 139 if ($item->frequency_value =~ /^\d(SU|MO|TU|WE|TH|FR|SA)$/) { 140 $rrules{BYDAY} = $item->frequency_value; 141 $rrules{INTERVAL} = 1; 142 } 87 143 $rrules{UNTIL} = to_icaldate($item->until, $item->is_full_day) 88 144 if $item->until; 89 $args{rrule} = join ';', map { $_ . '=' . $rrules{$_} } keys %rrules; 145 $rrules{WKST} = 'SU' 146 if $opt{'compat-google-calendar'}; 147 148 my @rrules; 149 for (qw(FREQ COUNT INTERVAL BYMONTH BYMONTHDAY WKST BYDAY UNTIL)) { 150 push @rrules, $_ . '=' . $rrules{$_} 151 if exists $rrules{$_}; 152 } 153 $args{rrule} = join ';', @rrules; 90 154 91 155 # exdate 92 156 if ($item->exdates) { 93 my $exdate;94 157 if ($item->is_full_day) { 95 $exdate = join ',', map { to_icaldate($_, 1) } $item->exdates;158 my $exdate = join ',', map { to_icaldate($_, 1) } $item->exdates; 96 159 $args{exdate} = [ $exdate, { VALUE => 'DATE' } ]; 97 160 } else { 98 $exdate = join ',', map { to_icaldate($_, 0) } $item->exdates;161 my $exdate = join ',', map { to_icaldate($_, 0) } $item->exdates; 99 162 $args{exdate} = [ $exdate, { TZID => $time_zone } ]; 100 163 } … … 110 173 } 111 174 175 # Generate a 'timezone entry' and append it to the calendar 112 176 my $vtimezone = Data::ICal::Entry::TimeZone->new(); 113 177 $vtimezone->add_properties(tzid => $time_zone); 114 178 115 # probably we need to support the Daylight Saving Time 179 # probably we need to support the Daylight Saving Time, but not yet supported. 116 180 my $standard = Data::ICal::Entry::TimeZone::Standard->new(); 117 118 181 my $std = DateTime->new(year => 1970, month => 1, day => 1, 119 182 hour => 0, minute => 0, second => 0, … … 132 195 $vcalendar->add_entry($vtimezone); 133 196 134 print encode_($cfg->{output_encoding} || 'utf8', $vcalendar->as_string); 135 136 sub to_icaldate { 137 my($dt, $is_full_day) = @_; 138 $is_full_day ? 139 $dt->ymd('') : 140 $dt->ymd('') . 'T' . $dt->hms('') . ($dt->time_zone->is_utc ? 'Z' : ''); 141 } 142 143 sub encode_ { 144 my($enc, $text) = @_; 145 if ($enc eq 'ncr') { 146 $text =~ s/(\P{ASCII})/sprintf("&#%d;", ord($1))/eg; 147 } else { 148 $text = encode($enc, $text); 149 } 150 $text; 197 # Outputs the calendar as a string 198 my $text = encode_string($cfg->{output_encoding} || 'utf8', $vcalendar->as_string); 199 if ($opt{output}) { 200 local *FH; 201 open FH, ">$opt{output}" or die "Failed to write $opt{output}"; 202 print FH $text; 203 close FH; 204 } else { 205 print $text; 151 206 } 152 207 … … 198 253 =over 4 199 254 255 =item --output /path/to/output.ics 256 257 Specifies the output file. By default, this application outputs to 258 STDOUT. 259 200 260 =item --conf /path/to/config.yaml 201 261 202 Specifies the path to a configuration file. By default, C<config.yaml> 203 in the current directory. 262 Specifies the configuration file. By default, C<config.yaml> in the 263 current directory will be used. 264 265 =item --compat-google-calendar 266 267 To be compatible with Google Calendar. 268 269 =item --debug 270 271 Outputs Cybozu Office 6 CSV data as a COMMENT field of each events. 272 It is just for debugging. 273 274 =item --help 275 276 Prints out this message. 204 277 205 278 =back -
cybozu2ical/trunk/lib/WWW/CybozuOffice6/Calendar.pm
r379 r446 87 87 $param{exdates} = \@exdates; 88 88 } 89 my $freq = $param{freq}; 90 if ($freq =~ /^[1-5]$/) { 91 $param{freq} = 'm'; 92 my @week_str = ('SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'); 93 $param{freq_value} = $freq . $week_str[$param{freq_value}]; 94 } 89 95 $item = WWW::CybozuOffice6::Calendar::RecurrentEvent->new(%param); 90 96 }
![(please configure the [header_logo] section in trac.ini)](/public/chrome/common/trac_banner.png)