[Evolution-hackers] perl script to automatically create recurring (holiday) ical files



hi list,

find attached a small perl script which could help to make the holiday calendars
a little bit easier (and nicer).


the script takes ".date" file which just include 2 entries per line:

DATE	SUMMARY

call the script with `./date2ical.pl FILE.date > FILE.ical`



that's about it, the rest should be self-explanatory

	++dent
-- 
this signature is mostly RFC 1855 compliant.
#!/usr/bin/perl

use Date::Easter;
use Date::Manip;	# for some "sophisticated" dates
use Net::ICal;
use strict;

# for events which are not following a simple recurrency scheme,
# 	create this amount of entries
#use constant RECURRENCIES	=> 20;
use constant RECURRENCIES	=> 1;
use constant CATEGORIES		=> "Holiday";

my $transp = "TRANSPARENT";	# OPAQUE
my $year = 2004;
my $filename = $ARGV[0];

########################################

my @events = date2ical($year, $filename);

#X-WR-CALNAME;Austrian Holidays
#print "Content-Type: text/calendar\n\r\n\r";

my $cal = new Net::ICal::Calendar (events => \ events);
$cal->prodid("-//Ximian//NONSGML Evolution Smart Calendar//EN");

my $out = $cal->as_ical;
$out =~ s/DTSTART:([0-9]+)Z/DTSTART;VALUE=DATE:$1/g;
$out =~ s/DTEND:([0-9]+)Z/DTEND;VALUE=DATE:$1\r\nTRANSP:$transp/g;
print $out;

########################################

sub date2ical
{
	my ($year, $filename) = @_;
	my @events;

	open (FILE, "$filename");

	foreach (<FILE>) {
		s/\#.*$//;		# remove comments
		next if (/^\s*$/);

		my ($str, $summary) = /^\"(.*)\"\s*\"(.*)\"/;
		my %param;

		my ($rrule, @dtstart_arr) = parse_date($year, $str);
		foreach my $dtstart (@dtstart_arr) {
			my $dtend = $dtstart->clone();

			$param{'dtstart'} = $dtstart;
			$param{'dtend'} = $dtend->add("P1D");
			$param{'rrule'} = [$rrule] if $rrule;
			$param{'rrule'} = [$rrule] if $rrule;
			$param{'categories'} = CATEGORIES;

			my $event = new Net::ICal::Event (%param);
			$event->summary($summary) if $summary;

			push @events,$event;
		}
	}
	close (FILE);

	return @events;
}

sub new_event
{
}

sub parse_date
{
	my ($year, $str, %param) = @_;
	my (@dtstart_arr, $rrule);

	if ($str =~ /^EASTER/) {
		my $easter;
		$str =~ /^EASTER.*([+-])(.*)$/;
		my ($op, $offset) = ($1,$2);

		# the rule here is not a simple rule, so just tag it
		#  as recurrent, but only use it for one year
		$rrule = new Net::ICal::Recurrence ();
		$rrule->freq('YEARLY');
		$rrule->count(1);

		for (my $i=$year; $i<($year+RECURRENCIES); $i++) {
			my ($month, $day) = easter($i);
			my $date_ical = new Date::ICal (year => $i, month => $month, day => $day);
			$date_ical->offset(0);
			my $easter = new Net::ICal::Time ($date_ical);

			$easter->add($op.$offset);
			push @dtstart_arr, $easter;
		}
	} else {
		my ($month, $day, $dow) = UnixDate("$str$year", ("%m","%e","%w"));
		my $date_ical = new Date::ICal (year => $year, month => $month, day => $day);
		$date_ical->offset(0);
		push @dtstart_arr, new Net::ICal::Time ($date_ical);

		$rrule = new Net::ICal::Recurrence ();
		$rrule->freq('YEARLY');

		if ($str =~ /\sin\s/ || $str =~ /\sof\s/) {
			my @day_sname = ("MO", "TU", "WE", "TH", "FR", "SA", "SU");

			$month =~ s/\s+//;
			my $occ = int(($day - $dow)/7) + 1;

			$rrule->bymonth($month);
			$rrule->byday("+".$occ.$day_sname[$dow-1]);
		}
	}

	return ($rrule, @dtstart_arr);
}
"January 1"	"Neujahr"
"January 6"	"Heilige Drei Könige"
"EASTER+P1D"	"Ostermontag"
"May 1"		"Staatsfeiertag"
"EASTER+P39D"	"Christi Himmelfahrt"
"EASTER+P50D"	"Pfingstmontag"
"EASTER+P60D"	"Fronleichnam"
"August 15"	"Maria Himmelfahrt"
"October 26"	"Nationalfeiertag"
"November 1"	"Allerheiligen"	
"December 8"	"Maria Empfängnis"
"December 25"	"Christtag"
"December 26"	"Stefanitag"
# http://www.opm.gov/fedhol/2003.asp

"January 1"			"New Year's Day"
"July 4"			"Independence Day"
"November 11"			"Veterans Day"
"December 25"			"Christmas Day"
"Third Monday in January"	"Birthday of Martin Luther King, Jr."
"Third Monday in February"	"Washington's Birthday"
"First Monday in May"		"Memorial Day"
"First Monday in September"	"Labor Day"
"Second Monday in October"	"Columbus Day"
"Fourth Thursday in November"	"Thanksgiving"


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]