#!/opt/local/bin/perl -w # MeetingMaker to iCal proxy, version 1.0, johannes@verelst.net # # This script allows you to export your MeetingMaker agenda to be # imported in iCal. Only tested with Perl 5.8.8, MeetingMaker 7.5.0, iCal 3.0.5. # You might need to install the following Perl modules through CPAN: # IO::Socket, Date::Parse, Date::Format # # First, set up meetingmaker to export your agenda to HTML on regular # intervals. You choose a directory and a filename, remember those. # This script acts as a daemon that watches this dump directory, and # generates an iCal calender you can subscribe on. # # Quick howto: # - in MeetingMaker # - choose 'File -> Publish as Webpage' # - Find a directory (/path/to/directory) to publish to, # and choose a name (for instance: 'work') # - Set frequency to 'Every 30 minutes', and choose a range. # - Click 'Publish' and then 'OK' # - run this script: # - choose a port (e.g. 8080) # - ./mmicalproxy 8080 /path/to/directory # - in iCal # - choose 'Calendar -> Subscribe' # - enter: http://localhost:8080/work and click 'OK' # - set 'Auto-Refresh' to every 5 minutes # # This work is licensed to you through the GNU GPL version 2 license # For updates, check http://www.verelst.net/ # # (c) Johannes Verelst, johannes@verelst.net use strict; use IO::Socket; use Date::Parse; use Date::Format; my $port = $ARGV[0]; my $dir = $ARGV[1]; if (!defined $port || $port eq "" || !defined $dir || $dir eq ""){ print "Usage: ./mmicalproxy.pl \n"; exit(1); } # Bind to the port my $sock = new IO::Socket::INET(LocalPort => $port, Proto => 'tcp', Listen => 5) || die "Cannot bind to port $port\n"; while(1){ my $new_sock = $sock->accept(); my $request = <$new_sock>; chomp($request); my ($method, $url, $version) = split(" ", $request); chomp($url); $url =~ s/[^a-z]//g; my $host = ""; my $line; while ($line = <$new_sock>) { $line =~ s/\r//; $line =~ s/\n//; if ($line =~ m/Host: (.*)/) { $host = $1; } if ($line =~ m/^$/) { if ($host eq "") { $host = $new_sock->sockhost(); } last; } } print $new_sock <) { chomp $line; if ($line =~ m/(.*)<\/tr>/) { my @values = split "\r", $line; foreach $line (@values) { if ($line =~ m/^(..):(..).*(..):(..)/) { $time1 = "$1$2"; $time2 = "$3$4"; } if ($line =~ m/(.*)<\/font>/) { $time1 = $file; $count++; print $new_sock "BEGIN:VEVENT\n"; print $new_sock "DTSTART;VALUE=DATE:20".$file."\n"; my $t1 = str2time("20" . $file); # Date::Parse $t1 += 60*60*24; my @t2 = localtime($t1); print $new_sock "DTEND;VALUE=DATE:".strftime('%Y%m%d', @t2)."\n"; print $new_sock "SUMMARY:$1\n"; print $new_sock "END:VEVENT\n"; } elsif ($line =~ m/(.*)<\/font>/) { my $summary = $1; # Detail informatie inlezen my %vars = (); my ($detailfile) = ($line =~ m//); if (defined($detailfile) && $detailfile ne "") { open DETAIL, "<$dir/$url.mmd/$detailfile.htm"; my $key = ""; my $value = ""; while ($line = ) { chomp($line); if ($line =~ m/(.*):<\/b><\/font><\/td>/) { $key = $1; } elsif ($line =~ m/(.*):<\/b><\/font><\/td>/) { $key = $1; } elsif ($line =~ m/(.*)<\/font><\/a><\/td>/) { $vars{"Guests"} = $1; } elsif ($line =~ m/(.*):<\/b><\/font><\/td>(.*)<\/font><\/td>/) { $key = $1; $value = $2; $value =~ s/
/\\n/g; if ($value ne "-") { $vars{$key} = $value; } } elsif ($line =~ m/(.*)<\/font><\/td>/) { $value = $1; $value =~ s/
/\\n/g; if ($value ne "-") { $vars{$key} = $value; } } } close DETAIL; } $count++; print $new_sock "BEGIN:VEVENT\n"; print $new_sock "DTSTART;TZID=Europe/Amsterdam:20".$file."T".$time1."00\n"; print $new_sock "DTEND;TZID=Europe/Amsterdam:20".$file."T".$time2."00\n"; if (defined($vars{"Title"})) { $summary = $vars{"Title"}; } if (defined($vars{"Location"})) { print $new_sock "LOCATION:$vars{Location}\n"; } if (defined($vars{"Notes"})) { print $new_sock "DESCRIPTION:$vars{Notes}\n"; } if (defined($vars{"Agenda"})) { print $new_sock "DESCRIPTION:$vars{Agenda}\n"; } if (defined($vars{"Guests"})) { my @guests = split("; ", $vars{"Guests"}); my $lastguest = $guests[$#guests]; my ($g1, $g2) = split(" and ", $lastguest); $guests[$#guests] = $g1; $guests[$#guests+1] = $g2; foreach my $guest (@guests) { print $new_sock "ATTENDEE;CN=\"$guest\";CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT:invalid:nomail\n"; } } print $new_sock "SUMMARY:$summary\n"; print $new_sock "END:VEVENT\n"; } } } } close FIL; } print $new_sock "END:VCALENDAR\n"; $new_sock->close(); }