summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Smedegaard <dr@jones.dk>2016-04-13 16:07:08 +0200
committerJonas Smedegaard <dr@jones.dk>2016-04-13 16:07:08 +0200
commitdf3363faf746c905b30b8a731cb239c614469497 (patch)
tree65d5d522ce97af3e4f3f45eb0415c3b9c91094dd
parentbc3daf34ec6fe35dc816d8b7b630baaaf3e6e9ab (diff)
Add text-to-iCalendar converter.
-rwxr-xr-xlocaltxt2ics96
1 files changed, 96 insertions, 0 deletions
diff --git a/localtxt2ics b/localtxt2ics
new file mode 100755
index 0000000..6b154af
--- /dev/null
+++ b/localtxt2ics
@@ -0,0 +1,96 @@
+#!/usr/bin/perl
+# Copyright © 2016 Jonas Smedegaard <dr@jones.dk>
+#
+# 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 3, or (at your option)
+# any later version.
+#
+# Description: Create iCalendar file from multiline news chunks
+#
+# Depends: libdata-ical-perl libdatetime-timezone-perl libdatetime-format-ical-perl
+
+use strict;
+use warnings;
+
+use Data::ICal;
+use Data::ICal::Entry::Event;
+use DateTime::TimeZone;
+use DateTime::Format::ICal;
+
+my $data;
+my $calendar = Data::ICal->new( rfc_strict => 1, auto_uid => 1 );
+my $tz = DateTime::TimeZone->new( name => 'local' );
+
+# warn about resolved timezone
+printf STDERR "using timezone %s - set environment variable TZ to override\n",
+ $tz->name;
+
+# slurp input
+my @lines;
+while (<>) {
+ chomp;
+ $data .= "$_\n";
+}
+
+# parse data and serialize as iCalendar events
+# * Events are newline-newline delimited
+# * First line contains date, location, time(s)
+# * String before date (e.g. weekday) is ignored
+# * Date is formatted as DD.MM.YYYY
+# * Times are formatted as either HH or HH:MM
+# * Times are space-hyphen-space delimited
+# * End time (and delimiter) is optional
+# * string after date (e.g. hour keyword) is ignored
+# * Second line is summary
+# * Third and subsequent lines are description
+while (
+ $data =~ m{
+ (\d{1,2})[./](\d{1,2})[./](\d{4}),\h* # date
+ ([^\n]+?),?\h* # location
+ (\d{1,2})(?::(\d{2}))? # start time
+ (?:\h+-\h+(\d{1,2})(?::(\d{2}))?)? # end time
+ (?:\h+Uhr)?\h*\n
+
+ ([^\n]+)\h*\n # description
+
+ ([^\n]+(?:\n[^\n]+)*)\h*\n(?:\n|\z) # description
+ }gx
+) {
+ my ( $dtstart, $dtend );
+ $dtstart = DateTime->new(
+ year => $3,
+ month => $2,
+ day => $1,
+ hour => $5,
+ minute => $6 || '00',
+ time_zone => $tz,
+ );
+ if ( defined($7) ) {
+ $dtend = DateTime->new(
+ year => $3,
+ month => $2,
+ day => $1,
+ hour => $7,
+ minute => $8 || '00',
+ time_zone => $tz,
+ );
+ }
+ my $location = $4;
+ my $summary = $9;
+ my $description = $10;
+
+ my $vevent = Data::ICal::Entry::Event->new();
+ $vevent->add_properties(
+ dtstart => DateTime::Format::ICal->format_datetime($dtstart),
+ location => $location,
+ summary => $summary,
+ description => $description,
+ );
+ $vevent->add_property(
+ dtend => DateTime::Format::ICal->format_datetime($dtend) )
+ if ($dtend);
+ $calendar->add_entry($vevent);
+}
+
+print $calendar->as_string;