#!/usr/bin/perl -w -CS

# DESCRIPTION: calendar2mail - parse ical feeds and produce remindermails
#
# Copyright (C) 2015 Cord Beermann
#
# URL: http://cord.de/selfmade/
# AUTHORS: Cord Beermann <Cord@Wunder-Nett.org>
# VERSION: 0.1

# 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 2 of the License, or (at your option)
# any later version.

# (If you modify and want to publish it under the name 'Calamaris', please ask
# me. I don't want to confuse the 'audience' with many different versions of
# the same name and/or Version number. (This is not part of the license, it
# is only a favour i asked of you.))

# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.

# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.

# A Perl script is "correct" if it gets the job done before your boss fires
# you.

use utf8;
use open ':encoding(utf8)';
use open ':std';
use LWP::UserAgent;
use Data::Dumper;
use iCal::Parser;
use Time::Local;
use Text::WrapI18N qw(wrap $columns);
use MIME::Entity;
use Encode;
use Net::SMTP;

my $ua = LWP::UserAgent->new;

# Config below and some more more below. Search for CHANGETHIS
# add your ical feeds one per line here.
my @urls = qw( 
	     https://www.google.com/calendar/ical/*CHANGETHIS*/public/basic.ics
	     https://www.google.com/calendar/ical/*CHANGETHISTOO*/public/basic.ics
);

$sender = 'Your Name <sender@example.com>'; # sender
$recipient = 'recipient@example.com'; # recipient
($mday, $mon, $year) = (localtime(time))[3,4,5];
$subject = sprintf "OWL-Termine ab dem %02d.%02d.%04d", $mday, $mon+1, 1900+$year;

for $url (@urls) {
  my $response = $ua->get($url);
#  binmode STDOUT, ":utf8";

  if ($response->is_success) {
#   print $response->decoded_content;  # or whatever
    my $combined=iCal::Parser->new->parse_strings($response->decoded_content);
    foreach $year (keys %{$combined->{'events'}}) {
      foreach $month (keys %{$combined->{'events'}->{$year}}) {
	foreach $day (keys %{$combined->{'events'}->{$year}->{$month}}) {
	  foreach $event (keys %{$combined->{'events'}->{$year}->{$month}->{$day}}) {
	    $timestamp = timelocal($combined->{'events'}->{$year}->{$month}->{$day}->{$event}->{'DTSTART'}->{'local_c'}->{'second'},
				   $combined->{'events'}->{$year}->{$month}->{$day}->{$event}->{'DTSTART'}->{'local_c'}->{'minute'},
				   $combined->{'events'}->{$year}->{$month}->{$day}->{$event}->{'DTSTART'}->{'local_c'}->{'hour'}, 
				   $day, 
				   $month-1, 
				   $year
				   );
#	    print "debug: " . localtime($timestamp) . "\n"; 
	    push(@{$appointment{$timestamp}}, {
						title => $combined->{'events'}->{$year}->{$month}->{$day}->{$event}->{'SUMMARY'},
						place => $combined->{'events'}->{$year}->{$month}->{$day}->{$event}->{'LOCATION'},
						url => $combined->{'events'}->{$year}->{$month}->{$day}->{$event}->{'URL'}
					      })

#	    print "Titel: " . $combined->{'events'}->{$year}->{$month}->{$day}->{$event}->{'SUMMARY'} . "\n";
#	    print "Ort: " . $combined->{'events'}->{$year}->{$month}->{$day}->{$event}->{'LOCATION'} . "\n";
#	    print "event: $event\n";
#	    print "url: " . $combined->{'events'}->{$year}->{$month}->{$day}->{$event}->{'URL'} . "\n";
#	    print " \n";
	  }
	}
      }
    }
  } else {
    warn $response->status_line;
  }
}

$i = 0;
# CHANGETHIS
$out = wrap('',
	    '',
	    'Diese Termine sind fuer die kommende Woche geplant. Mehr und aktuelle Informationen gibt es auf https://blog.piratenpartei-nrw.de/owl/owl-treffen/'
);

$out .= sprintf "\n";

@wtag = qw( Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag );

foreach $timestamp (sort {$a <=> $b} keys %appointment) {
  next if time() > $timestamp;
  next if $i++ > 10 and (time() + 60*60*24*7) < $timestamp;
  next if (time() + 60*60*24*30) < $timestamp;
#  print Dumper \@{$appointment{$timestamp}};
  ($min,$hour,$mday,$mon,$year,$wday) = (localtime($timestamp))[1,2,3,4,5,6];
  $out .= sprintf "\n%s, %02d.%02d.%04d %02d:%02d\n", $wtag[$wday], $mday, $mon+1, 1900+$year, $hour, $min;
  foreach $event (@{$appointment{$timestamp}}) {
    $event->{'title'} =~ s#\\##g if $event->{'title'};
    $event->{'place'} =~ s#\\##g if $event->{'place'};
    $event->{'url'} =~ s#/\?instance_id=$## if $event->{'url'};
    $out .= wrap('', '      ', "  * " . $event->{'title'} . ($event->{'place'} ? " (" . $event->{'place'} . ")" : '') . "\n");
    $out .= ('       <' . $event->{'url'} . ">\n") if $event->{'url'};
  }
}

# CHANGETHIS
$out .= '
Diese Mail ist automatisch erstellt und ohne Unterschrift gueltig.
-- 
Signature

calendar2mail.pl written by Cord Beermann <cord@Wunder-Nett.org>';

$entity = MIME::Entity->build(
			      Type    => 'text/plain',
			      Charset => "UTF-8",
			      Encoding => 'quoted-printable',
			      Data    => Encode::encode('UTF-8', $out),
			      From => Encode::encode(
						     "MIME-Header", $sender
						     ),
			      To => Encode::encode(
						   "MIME-Header", $recipient
						   ),
			      Subject => Encode::encode(
							"MIME-Header", $subject
							),
);

my $smtp = Net::SMTP->new(
    "localhost",
    Hello => 'localhost.localdomain',
    Timeout => 15,
    Debug => 0,
);

$smtp->mail( $sender );
if ( $smtp->recipient( $recipient ) ) {
  $smtp->data();
  my $msg = $entity->stringify;
  while ( $msg =~ m/([^\r\n]*)(\r\n|\n\r|\r|\n)?/g ) {
    my $line = ( defined($1) ? $1 : "" ) . "\r\n";
    $smtp->datasend( $line );
  }
  if ( $smtp->dataend() ) {
    print STDERR "Message sent!\n";
  } else {
    print STDERR "Failure sending data.\n";
  }
} else {
  print STDERR "Rejected recipient.\n";
}
$smtp->quit();
