diff options
Diffstat (limited to 'ical2rem')
-rwxr-xr-x | ical2rem | 279 |
1 files changed, 0 insertions, 279 deletions
diff --git a/ical2rem b/ical2rem deleted file mode 100755 index aab07d5..0000000 --- a/ical2rem +++ /dev/null @@ -1,279 +0,0 @@ -#!/usr/bin/perl -w -# -# ical2rem.pl - -# Reads iCal files and outputs remind-compatible files. Tested ONLY with -# calendar files created by Mozilla Calendar/Sunbird. Use at your own risk. -# Copyright (c) 2005, 2007, Justin B. Alcorn - -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# -# version 0.5.2 2007-03-23 -# - BUG: leadtime for recurring events had a max of 4 instead of DEFAULT_LEAD_TIME -# - remove project-lead-time, since Category was a non-standard attribute -# - NOTE: There is a bug in iCal::Parser v1.14 that causes multiple calendars to -# fail if a calendar with recurring events is followed by a calendar with no -# recurring events. This has been reported to the iCal::Parser author. -# version 0.5.1 2007-03-21 -# - BUG: Handle multiple calendars on STDIN -# - add --heading option for priority on section headers -# version 0.5 2007-03-21 -# - Add more help options -# - --project-lead-time option -# - Supress printing of heading if there are no todos to print -# version 0.4 -# - Version 0.4 changes all written or inspired by, and thanks to Mark Stosberg -# - Change to GetOptions -# - Change to pipe -# - Add --label, --help options -# - Add Help Text -# - Change to subroutines -# - Efficiency and Cleanup -# version 0.3 -# - Convert to GPL (Thanks to Mark Stosberg) -# - Add usage -# version 0.2 -# - add command line switches -# - add debug code -# - add SCHED _sfun keyword -# - fix typos -# version 0.1 - ALPHA CODE. - -=head1 SYNOPSIS - - cat /path/to/file*.ics | ical2rem.pl > ~/.ical2rem - - All options have reasonable defaults: - --label Calendar name (Default: Calendar) - --lead-time Advance days to start reminders (Default: 3) - --todos, --no-todos Process Todos? (Default: Yes) - --heading Define a priority for static entries - --help Usage - --man Complete man page - -Expects an ICAL stream on STDIN. Converts it to the format -used by the C<remind> script and prints it to STDOUT. - -=head2 --label - - ical2rem.pl --label "Bob's Calendar" - -The syntax generated includes a label for the calendar parsed. -By default this is "Calendar". You can customize this with -the "--label" option. - -=head2 --lead-time - - ical2rem.pl --lead-time 3 - -How may days in advance to start getting reminders about the events. Defaults to 3. - -=head2 --no-todos - - ical2rem.pl --no-todos - -If you don't care about the ToDos the calendar, this will surpress -printing of the ToDo heading, as well as skipping ToDo processing. - -=head2 --heading - - ical2rem.pl --heading "PRIORITY 9999" - -Set an option on static messages output. Using priorities can made the static messages look different from -the calendar entries. See the file defs.rem from the remind distribution for more information. - -=cut - -use strict; -use iCal::Parser; -use DateTime; -use Getopt::Long 2.24 qw':config auto_help'; -use Pod::Usage; -use Data::Dumper; -use vars '$VERSION'; -$VERSION = "0.5.2"; - -# Declare how many days in advance to remind -my $DEFAULT_LEAD_TIME = 3; -my $PROCESS_TODOS = 1; -my $HEADING = ""; -my $help; -my $man; - -my $label = 'Calendar'; -GetOptions ( - "label=s" => \$label, - "lead-time=i" => \$DEFAULT_LEAD_TIME, - "todos!" => \$PROCESS_TODOS, - "heading=s" => \$HEADING, - "help|?" => \$help, - "man" => \$man -); -pod2usage(1) if $help; -pod2usage(-verbose => 2) if $man; - -my $month = ['None','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; - -my @calendars; -my $in; - -while (<>) { - $in .= $_; - if (/END:VCALENDAR/) { - push(@calendars,$in); - $in = ""; - } -} -my $parser = iCal::Parser->new(); -my $hash = $parser->parse_strings(@calendars); - -############################################################## -# -# Subroutines -# -############################################################# -# -# _process_todos() -# expects 'todos' hashref from iCal::Parser is input -# returns String to output -sub _process_todos { - my $todos = shift; - - my ($todo, @newtodos, $leadtime); - my $output = ""; - - $output .= 'REM '.$HEADING.' MSG '.$label.' ToDos:%"%"%'."\n"; - -# For sorting, make sure everything's got something -# To sort on. - my $now = DateTime->now; - for $todo (@{$todos}) { - # remove completed items - if ($todo->{'STATUS'} && $todo->{'STATUS'} eq 'COMPLETED') { - next; - } elsif ($todo->{'DUE'}) { - # All we need is a due date, everything else is sugar - $todo->{'SORT'} = $todo->{'DUE'}->clone; - } elsif ($todo->{'DTSTART'}) { - # for sorting, sort on start date if there's no due date - $todo->{'SORT'} = $todo->{'DTSTART'}->clone; - } else { - # if there's no due or start date, just make it now. - $todo->{'SORT'} = $now; - } - push(@newtodos,$todo); - } - if (! (scalar @newtodos)) { - return ""; - } -# Now sort on the new Due dates and print them out. - for $todo (sort { DateTime->compare($a->{'SORT'}, $b->{'SORT'}) } @newtodos) { - my $due = $todo->{'SORT'}->clone(); - my $priority = ""; - if (defined($todo->{'PRIORITY'})) { - if ($todo->{'PRIORITY'} == 1) { - $priority = "PRIORITY 1000"; - } elsif ($todo->{'PRIORITY'} == 3) { - $priority = "PRIORITY 7500"; - } - } - if (defined($todo->{'DTSTART'}) && defined($todo->{'DUE'})) { - # Lead time is duration of task + lead time - my $diff = ($todo->{'DUE'}->delta_days($todo->{'DTSTART'})->days())+$DEFAULT_LEAD_TIME; - $leadtime = "+".$diff; - } else { - $leadtime = "+".$DEFAULT_LEAD_TIME; - } - $output .= "REM ".$due->month_abbr." ".$due->day." ".$due->year." $leadtime $priority MSG \%a $todo->{'SUMMARY'}\%\"\%\"\%\n"; - } - $output .= 'REM '.$HEADING.' MSG %"%"%'."\n"; - return $output; -} - - -####################################################################### -# -# Main Program -# -###################################################################### - -print _process_todos($hash->{'todos'}) if $PROCESS_TODOS; - -my ($leadtime, $yearkey, $monkey, $daykey,$uid,%eventsbyuid); -print 'REM '.$HEADING.' MSG '.$label.' Events:%"%"%'."\n"; -my $events = $hash->{'events'}; -foreach $yearkey (sort keys %{$events} ) { - my $yearevents = $events->{$yearkey}; - foreach $monkey (sort {$a <=> $b} keys %{$yearevents}){ - my $monevents = $yearevents->{$monkey}; - foreach $daykey (sort {$a <=> $b} keys %{$monevents} ) { - my $dayevents = $monevents->{$daykey}; - foreach $uid (sort { - DateTime->compare($dayevents->{$a}->{'DTSTART'}, $dayevents->{$b}->{'DTSTART'}) - } keys %{$dayevents}) { - my $event = $dayevents->{$uid}; - if ($eventsbyuid{$uid}) { - my $curreventday = $event->{'DTSTART'}->clone; - $curreventday->truncate( to => 'day' ); - $eventsbyuid{$uid}{$curreventday->epoch()} =1; - for (my $i = 0;$i < $DEFAULT_LEAD_TIME && !defined($event->{'LEADTIME'});$i++) { - if ($eventsbyuid{$uid}{$curreventday->subtract( days => $i+1 )->epoch() }) { - $event->{'LEADTIME'} = $i; - } - } - } else { - $eventsbyuid{$uid} = $event; - my $curreventday = $event->{'DTSTART'}->clone; - $curreventday->truncate( to => 'day' ); - $eventsbyuid{$uid}{$curreventday->epoch()} =1; - } - - } - } - } -} -foreach $yearkey (sort keys %{$events} ) { - my $yearevents = $events->{$yearkey}; - foreach $monkey (sort {$a <=> $b} keys %{$yearevents}){ - my $monevents = $yearevents->{$monkey}; - foreach $daykey (sort {$a <=> $b} keys %{$monevents} ) { - my $dayevents = $monevents->{$daykey}; - foreach $uid (sort { - DateTime->compare($dayevents->{$a}->{'DTSTART'}, $dayevents->{$b}->{'DTSTART'}) - } keys %{$dayevents}) { - my $event = $dayevents->{$uid}; - if (exists($event->{'LEADTIME'})) { - $leadtime = "+".$event->{'LEADTIME'}; - } else { - $leadtime = "+".$DEFAULT_LEAD_TIME; - } - my $start = $event->{'DTSTART'}; - print "REM ".$start->month_abbr." ".$start->day." ".$start->year." $leadtime "; - if ($start->hour > 0) { - print " AT "; - print $start->strftime("%H:%M"); - print " SCHED _sfun MSG %a %2 "; - } else { - print " MSG %a "; - } - print "%\"$event->{'SUMMARY'}"; - print " at $event->{'LOCATION'}" if $event->{'LOCATION'}; - print "\%\"%\n"; - } - } - } -} -exit 0; -#:vim set ft=perl ts=4 sts=4 expandtab : |