diff options
author | Jonas Smedegaard <dr@jones.dk> | 2016-04-13 16:07:08 +0200 |
---|---|---|
committer | Jonas Smedegaard <dr@jones.dk> | 2016-04-13 16:07:08 +0200 |
commit | df3363faf746c905b30b8a731cb239c614469497 (patch) | |
tree | 65d5d522ce97af3e4f3f45eb0415c3b9c91094dd /localtxt2ics | |
parent | bc3daf34ec6fe35dc816d8b7b630baaaf3e6e9ab (diff) |
Add text-to-iCalendar converter.
Diffstat (limited to 'localtxt2ics')
-rwxr-xr-x | localtxt2ics | 96 |
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; |