summaryrefslogtreecommitdiff
path: root/localtxt2ics
blob: 6b154af4246f3d80b76d2227af200596dc66c05c (plain)
  1. #!/usr/bin/perl
  2. # Copyright © 2016 Jonas Smedegaard <dr@jones.dk>
  3. #
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation; either version 3, or (at your option)
  7. # any later version.
  8. #
  9. # Description: Create iCalendar file from multiline news chunks
  10. #
  11. # Depends: libdata-ical-perl libdatetime-timezone-perl libdatetime-format-ical-perl
  12. use strict;
  13. use warnings;
  14. use Data::ICal;
  15. use Data::ICal::Entry::Event;
  16. use DateTime::TimeZone;
  17. use DateTime::Format::ICal;
  18. my $data;
  19. my $calendar = Data::ICal->new( rfc_strict => 1, auto_uid => 1 );
  20. my $tz = DateTime::TimeZone->new( name => 'local' );
  21. # warn about resolved timezone
  22. printf STDERR "using timezone %s - set environment variable TZ to override\n",
  23. $tz->name;
  24. # slurp input
  25. my @lines;
  26. while (<>) {
  27. chomp;
  28. $data .= "$_\n";
  29. }
  30. # parse data and serialize as iCalendar events
  31. # * Events are newline-newline delimited
  32. # * First line contains date, location, time(s)
  33. # * String before date (e.g. weekday) is ignored
  34. # * Date is formatted as DD.MM.YYYY
  35. # * Times are formatted as either HH or HH:MM
  36. # * Times are space-hyphen-space delimited
  37. # * End time (and delimiter) is optional
  38. # * string after date (e.g. hour keyword) is ignored
  39. # * Second line is summary
  40. # * Third and subsequent lines are description
  41. while (
  42. $data =~ m{
  43. (\d{1,2})[./](\d{1,2})[./](\d{4}),\h* # date
  44. ([^\n]+?),?\h* # location
  45. (\d{1,2})(?::(\d{2}))? # start time
  46. (?:\h+-\h+(\d{1,2})(?::(\d{2}))?)? # end time
  47. (?:\h+Uhr)?\h*\n
  48. ([^\n]+)\h*\n # description
  49. ([^\n]+(?:\n[^\n]+)*)\h*\n(?:\n|\z) # description
  50. }gx
  51. ) {
  52. my ( $dtstart, $dtend );
  53. $dtstart = DateTime->new(
  54. year => $3,
  55. month => $2,
  56. day => $1,
  57. hour => $5,
  58. minute => $6 || '00',
  59. time_zone => $tz,
  60. );
  61. if ( defined($7) ) {
  62. $dtend = DateTime->new(
  63. year => $3,
  64. month => $2,
  65. day => $1,
  66. hour => $7,
  67. minute => $8 || '00',
  68. time_zone => $tz,
  69. );
  70. }
  71. my $location = $4;
  72. my $summary = $9;
  73. my $description = $10;
  74. my $vevent = Data::ICal::Entry::Event->new();
  75. $vevent->add_properties(
  76. dtstart => DateTime::Format::ICal->format_datetime($dtstart),
  77. location => $location,
  78. summary => $summary,
  79. description => $description,
  80. );
  81. $vevent->add_property(
  82. dtend => DateTime::Format::ICal->format_datetime($dtend) )
  83. if ($dtend);
  84. $calendar->add_entry($vevent);
  85. }
  86. print $calendar->as_string;