123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- #!/usr/bin/env perl
- use warnings;
- use strict;
- use Data::ICal;
- use Data::Dumper;
- use DateTime::Format::ICal;
- use Getopt::Long;
- my $category = 'ical';
- GetOptions(
- 'category|c=s' => \$category
- );
- my $cal = Data::ICal->new(data => join '', <STDIN>);
- #print Dumper $cal;
- my %gprops = %{ $cal->properties };
- print "#+TITLE: ical entries\n";
- print "#+AUTHOR: ".$gprops{'x-wr-calname'}[0]->decoded_value."\n";
- print "#+EMAIL: \n";
- print "#+DESCRIPTION: Converted using ical2org.pl\n";
- print "#+CATEGORY: $category\n";
- print "#+STARTUP: overview\n";
- print "\n";
- print "* COMMENT original iCal properties\n";
- #print Dumper \%gprops;
- print "Timezone: ", $gprops{'x-wr-timezone'}[0]->value, "\n";
- foreach my $prop (values %gprops) {
- foreach my $p (@{ $prop }) {
- print $p->key, ':', $p->value, "\n";
- }
- }
- foreach my $entry (@{ $cal->entries }) {
- next if not $entry->isa('Data::ICal::Entry::Event');
- #print 'Entry: ', Dumper $entry;
- my %props = %{ $entry->properties };
- my $dtstart = DateTime::Format::ICal->parse_datetime($props{dtstart}[0]->value);
- my $dtend = DateTime::Format::ICal->parse_datetime($props{dtend}[0]->value);
- my $duration = $dtend->subtract_datetime($dtstart);
- if (defined $props{rrule}) {
- #print " REPEATABLE\n";
- # Bad: There may be multiple rrules but I'm ignoring them
- my $set = DateTime::Format::ICal->parse_recurrence(
- recurrence => $props{rrule}[0]->value,
- dtstart => $dtstart,
- dtend => DateTime->now->add(weeks => 1),
- );
- my $itr = $set->iterator;
- while (my $dt = $itr->next) {
- $dt->set_time_zone(
- $props{dtstart}[0]->parameters->{'TZID'} ||
- $gprops{'x-wr-timezone'}[0]->value
- );
- print "* ".$props{summary}[0]->decoded_value."\n";
- my $end = $dt->clone->add_duration($duration);
- print ' ', org_date_range($dt, $end), "\n";
- #print $dt, "\n";
- print " :PROPERTIES:\n";
- printf " :ID: %s\n", $props{uid}[0]->value;
- if (defined $props{location}) {
- printf " :LOCATION: %s\n", $props{location}[0]->value;
- }
- if (defined $props{status}) {
- printf " :STATUS: %s\n", $props{status}[0]->value;
- }
- print " :END:\n";
- if ($props{description}) {
- print "\n", $props{description}[0]->decoded_value, "\n";
- }
- }
- }
- else {
- print "* ".$props{summary}[0]->decoded_value."\n";
- my $tz = $gprops{'x-wr-timezone'}[0]->value;
- $dtstart->set_time_zone($props{dtstart}[0]->parameters->{'TZID'} || $tz);
- $dtend->set_time_zone($props{dtend}[0]->parameters->{'TZID'} || $tz);
- print ' ', org_date_range($dtstart, $dtend), "\n";
- print " :PROPERTIES:\n";
- printf " :ID: %s\n", $props{uid}[0]->value;
- if (defined $props{location}) {
- printf " :LOCATION: %s\n", $props{location}[0]->value;
- }
- if (defined $props{status}) {
- printf " :STATUS: %s\n", $props{status}[0]->value;
- }
- print " :END:\n";
- if ($props{description}) {
- print "\n", $props{description}[0]->decoded_value, "\n";
- }
- }
- # print Dumper \%props;
- }
- sub org_date_range {
- my $start = shift;
- my $end = shift;
- my $str = sprintf('<%04d-%02d-%02d %s %02d:%02d>',
- $start->year,
- $start->month,
- $start->day,
- $start->day_abbr,
- $start->hour,
- $start->minute
- );
- $str .= '--';
- $str .= sprintf('<%04d-%02d-%02d %s %02d:%02d>',
- $end->year,
- $end->month,
- $end->day,
- $end->day_abbr,
- $end->hour,
- $end->minute
- );
- return $str;
- }
|