#!/usr/bin/perl #$Id: eve,v 1.5 2004/11/29 13:19:39 gleb Exp $ use Time::localtime; use Date::Calc qw(Delta_Days Decode_Month Month_to_Text check_date); use Getopt::Long; use strict; =head1 NAME eve is console events reminder for men. Women no need for it, they remember dates and events very well =) =head1 SYNOPSIS eve [OPTIONS] Options: -f , --file= file with events list for remind (default: ~/.eve) -a, --all show all events (ignore notification rules) -c, --color use ANSI colors -v, --verbose verbose mode -h, --help show this text =head1 DESCRIPTION B is console reminder which shows description of future events. It may be used in ~/.bashrc file (with color mode) or in crontab to get notification by mail. =head1 OPTIONS =over 4 =item B<-f> I or B<--file=>I Use alternative remind list instead of ~/.eve =item B<-a> or B<--all> Show all future events from list (ignore notification rules) =item B<-c> or B<--color> Use ANSI colors =item B<-v> or B<--verbose> Verbose mode for debug =item B<-h> or B<--help> Show help =back =head1 CONFIGURATION File with events list for remind (default: ~/.eve) consists of lines described below. Lines starting with '#' are comments. =head2 Format of event's line B
=over 4 =item B
(number) Day of month 1-31 =item B (string) Name of month - full english name or first 3 letters of it =item B (list of numbers or number diapasons) notification rule - (optional) default notification rule is [30, 20, 10, 5-0] which mean to show remind on 30th, 20th, 10th day before this event and every day starting from fifth day to day zero =item B (string) Text of notification =back =head2 Example of ~/.eve 24 December Marry Christmas 31 dec [20, 10, 4, 1] Happy New Year 01 April Fools Day! # this remind will be show during for 5th, 12th, 13th, 14th and 15th Jun 15 Jun [10, 3-0] John Doe's birthday! =head1 AUTHOR Gleb Galkin Emaniwheel@elnet.ruE =head1 PREREQUISITES This script requires the C and C =pod OSNAMES any =pod SCRIPT CATEGORIES UNIX/System_administration =cut ###################################################################### my %colorize = ( 3 => "red", 10 => "blue", 30 => "green" ); my $notification_rule_def = "[30, 20, 10, 5-0]"; my ($color, $today, $c_day, $c_mon, $c_year, $e_mon, $e_day, $delta, $string, $out); $today = localtime(time); ($c_day, $c_mon, $c_year) = ($today->mday, $today->mon+1, $today->year + 1900); my $opt_file = $ENV{'HOME'} . "/.eve"; my $opt_all=''; my $opt_color=''; my $opt_v=''; my $opt_help=''; usage() unless GetOptions( "file|f=s" => \$opt_file, "all|a" => \$opt_all, "color|c" => \$opt_color, "verbose|v" => \$opt_v, "help|h|?" => \$opt_help ); usage() if $opt_help; $opt_v && print "\n$0:\n-- verbose mode ON\n\n"; $opt_v && print "read file $opt_file\n"; open FILE, $opt_file || die "Can't open file $opt_file\n$!\n"; output ("\nreminders for $c_day-" . Month_to_Text($c_mon) . "-$c_year\n\n", "white"); my $i=0; my $events=0; while () { chomp; $i++; undef($color); undef($string); $opt_v && print "$i: $_\n"; m/^\s*#|^$/ && next; quit ("$opt_file: string number $i is invalid\n> $_ <\n") unless (/^(\d+)\s+(\w+)\s+(\[.*\])?\s*(.*)$/); $string = "$1 $2 - $4"; my $notification_rule = $3 ? $3 : $notification_rule_def; quit ("$opt_file: string number $i contain invalid month\n> $_<\n ^^^\n") unless ($e_mon = Decode_Month($2)); $e_day = $1; quit ("$opt_file: string number $i contain invalid data\n> $_<\n ^^^^^^\n") unless (check_date($c_year, $e_mon, $e_day)); quit ("$opt_file: string number $i contain invalid show days list\n> $3 <\n") if ($3 && $3 !~ /^\[[0-9, -]+\]$/); $delta = Delta_Days($c_year, $c_mon, $c_day, $c_year, $e_mon, $e_day); $delta = Delta_Days($c_year, $c_mon, $c_day, $c_year+1, $e_mon, $e_day) if ($delta < -180); my $check = check_show_day($delta, $notification_rule); quit ("$opt_file: string number $i contain invalid show days list\n> $notification_rule <\n") if ($check == -1); if ($check) { undef($color); foreach (reverse sort by_number keys %colorize) { if ($delta <= $_ && $delta > 0) { $color = $colorize{$_} } } if ($check==1) { output ("$string (in $delta days)\n", $color); $events++; } } } print $out if ($events); sub usage { print " Usage: $0 [OPTIONS] Options: -f , --file= file with events list for remind (default: ~/.eve) -a, --all show all events (ignore notification rules) -c, --color use ANSI colors -v, --verbose verbose mode -h, --help show this text \n"; exit; } sub output { my ($string, $color) = @_; my %colors = (white => "\033[1;37m", red => "\033[1;31m", blue => "\033[1;34m", green => "\033[1;32m"); my $color_off ="\033[0m"; $out .= $colors{$color} if $opt_color; $out .= $string; $out .= $color_off if $opt_color; } sub quit { print $_[0]; exit; } sub check_show_day { my ($delta, $days) = @_; return 1 if ($opt_all); $days =~ s/[\[\] ]//g; my @array = split(/,/, $days); my ($from, $to); foreach (@array) { if (/(^\d+)-(\d+)$/) { if ($1 > $2) { $from=$2; $to=$1; } else { $from=$1; $to=$2; } return 1 if ($delta >= $from && $delta <= $to); } elsif (/^\d+$/) { return 1 if ($delta==$_); } else {return -1} } return 0; } sub by_number { $a <=> $b }