#!/usr/bin/perl ###################################################################### # Script Prerequisites ###################################################################### # Perl modules: # LWP::UserAgent; # Cwd # POSIX # Data::ICal::TimeZone (optional) # # Command Line: # rsync # lynx # wdiff ###################################################################### $id_mirror = '/Users/adam/Documents/IETF/internet-drafts/'; # See http://search.cpan.org/~rclamp/Data-ICal-TimeZone-1.23/ $timezone = "Europe/Paris"; $tzdef = mkicaltz($timezone); if (!defined($tzdef)) { warn "Could not find timezone $timezone -- do you have Data::ICal::TimeZone installed?\n"; } #$verbose = 1; ###################################################################### # Working groups of interest, listed in priority order ###################################################################### @groups = ( 'xcon', 'sip', 'simple', 'sipping', # 'behave', 'p2psip', 'speermint', 'mmusic', 'ecrit', 'bliss', 'geopriv', 'drinks', 'sipcore', 'dispatch', 'sipclf', 'e2m', 'martini', 'rucus', 'biff', 'safe', 'peppermint', 'alto', 'codec', 'iri', 'xmpp', 'grobj', 'core', 'ppsp', ); @areas = ( 'RAI' ); ##### # transform these arrays into hashes %include_group = map {$_ => 1} @groups; %include_area = map {$_ => 1} @areas; ###################################################################### # Constants ###################################################################### %month = ( 'January' => '01', 'February' => '02', 'March' => '03', 'April' => '04', 'May' => '05', 'June' => '06', 'July' => '07', 'August' => '08', 'September' => '09', 'October' => '10', 'November' => '11', 'December' => '12' ); ###################################################################### # HTTP User Agent Initialization ###################################################################### use LWP::UserAgent; $ua = LWP::UserAgent->new; $ua->agent("AgendaBuilder/0.2"); ###################################################################### # ICAL Setup ###################################################################### $myname = (getpwuid($<))[0]; ($currsec,$currmin,$currhour, $currmday,$currmon,$curryear) = gmtime(time); $curryear += 1900; $currmon += 1; $currDateTime = sprintf("%4.4d%2.2d%2.2dT%2.2d%2.2d%2.2dZ", $curryear,$currmon,$currmday, $currhour,$currmin,$currsec); $ics = "BEGIN:VCALENDAR\nVERSION\n :2.0\nMETHOD\n :PUBLISH\n"; if (defined($tzdef)) { $ics .= $tzdef; } ###################################################################### ###################################################################### # Little bit of sanity checking ###################################################################### if ($id_mirror !~ /\/$/) { $id_mirror .= "/"; } ###################################################################### # Update drafts ###################################################################### if (defined($id_mirror) && -e $id_mirror) { system ("rsync", '-avz', '--exclude', 'tar', 'ftp.rfc-editor.org::ids-text-only', $id_mirror); } ###################################################################### use Cwd; $number = shift; if ($number < 1) { $number = getcwd; $number =~ /([0-9]{2})$/ || die "Cannot determine IETF number"; $number = $1; } print "Updating local information for IETF $number\n"; ###################################################################### # Retrieve, parse, and prune the current agenda ###################################################################### #$lwp_request = HTTP::Request->new(GET => "http://datatracker.ietf.org/meeting/${number}/agenda.txt"); #$lwp_result = $ua->request($lwp_request); #$txt_agenda = $lwp_result->content; $lwp_request = HTTP::Request->new(GET => "http://datatracker.ietf.org/meeting/${number}/agenda.csv"); $lwp_result = $ua->request($lwp_request); $csv_agenda = $lwp_result->content; if (length ($csv_agenda) < 1000) { die "Could not retrieve agenda."; } @agenda = split ("\n",$csv_agenda); shift @agenda; use POSIX; foreach $line (@agenda) { $line =~ s/^"//; $line =~ s/"$//; ($date, $start, $end, $session, $room, $area, $wg, $type, $desc, $tid, $agenda, $slides) = split ('","',$line); ($year,$month,$day) = split ('-',$date); $time = POSIX::mktime(0,0,0,$day,$month-1,$year-1900); $datestring = POSIX::strftime("%A, %B %e, %Y", gmtime($time)); if ($date ne $prev_date) { $prev_date = $date; $text_agenda .= "\n$datestring\n==============================================================================\n"; $html_agenda .= "\n

$datestring

\n\n"; } $slides{$wg} = $slides; $agenda{$wg} = $agenda; if ($type =~ /bof/i){ push (@bofs, "$area - $wg - $desc"); } if ($wg =~ /plenary/i) { &addEvent($month, $day, $year, $start, $end, $desc, $room); # Plenaries } elsif ($desc =~ /break/i) { &addEvent($month, $day, $year, $start, $end, $desc); # Breaks } elsif ($include_group{$wg} || $include_area{$area}) { $meeting{$wg}++; &addEvent($month, $day, $year, $start, $end, $wg, $room, $desc); # wg meetings if ($agenda{$wg}) { $html_agenda .= "". "\n"; } else { $html_agenda .= "". "\n"; } } } ###################################################################### # Write out the agenda file ###################################################################### open (AGENDA, ">agenda_${number}.txt"); print AGENDA $text_agenda; close (AGENDA); ###################################################################### # Write out the HTML agenda file ###################################################################### open (AGENDA, ">agenda_${number}.html"); print AGENDA "IETF $number Agenda". "". "
". "
". "$wg has not yet uploaded an agenda
\n".$html_agenda. "
\n"; close (AGENDA); ###################################################################### # Retrieve the sub-agendas ###################################################################### mkdir ("groups"); chdir("groups") || die $!; foreach $wg (sort keys %meeting) { if (!$agenda{$wg}) { print "\x1B[31;3mWarning: $wg has no agenda uploaded\x1B[0m\n"; next; } print "Getting agenda for $wg ($agenda{$wg})...\n"; unlink ("${wg}.htm"); unlink ("${wg}.html"); unlink ("${wg}.txt"); # $subdir = $number; # $subdir = $meetingCode; #foreach $subdir ($number, $meetingCode) #{ # &wget("http://www.ietf.org/proceedings/${subdir}/agenda/${wg}.txt", "${wg}.txt"); # &wget("http://www.ietf.org/proceedings/${subdir}/agenda/${wg}.htm", "${wg}.htm"); # &wget("http://www.ietf.org/proceedings/${subdir}/agenda/${wg}.html", "${wg}.html"); #} $agenda{$wg} =~ /([^\/]*)$/; #$output = $1; $output = "$wg"; &wget($agenda{$wg},$output); if (-z "${wg}.htm") { unlink ("${wg}.htm"); } if (-z "${wg}.html") { unlink ("${wg}.html"); } if (-e "${wg}.htm") { rename ("${wg}.htm", "${wg}.html"); } if (-e "${wg}.html" && !-e"${wg}.txt") { system ("lynx --nolist --dump '${wg}.html' > '${wg}.txt'"); } if (!-e "${wg}.html" && !-e"${wg}.txt") { &cp ("../provisional/$wg.txt", "."); &cp ("../provisional/$wg.html", "."); } } chdir("..") || die $!; ###################################################################### # Substitue agendas for description fields, where possible ###################################################################### foreach $wg_agenda () { $wg = $wg_agenda; $wg =~ s/.*\///; $wg =~ s/\.txt//; $description = $desc{$wg}; open (AGENDA, $wg_agenda); $agenda = join('',); close (AGENDA); $agenda =~ s/\\/\\\\/g; $agenda =~ s/;/\\;/g; $agenda =~ s/,/\\,/g; $agenda =~ s/\n/\\n/g; $agenda =~ s/\r//g; $ics =~ s/ :$description *[\r\n]/ :$agenda\n/g; } ###################################################################### # Wrap up and write out the ical file ###################################################################### $ics .= "END:VCALENDAR\n"; while ($ics =~ s/([\r\n])([^\r\n]{74})([^\r\n])/$1$2\n $3/gs){;} $icalfile = "ietf_${number}.ics"; open (ICS, ">", $icalfile); print ICS $ics; close (ICS); ###################################################################### # Copy the drafts ###################################################################### foreach $wg_agenda (,) { open (AGENDA, $wg_agenda); $wg = $wg_agenda; $wg =~ s/\.txt//g; $wg =~ s/\.html//g; print "\n$wg\n".('-' x length($wg))."\n"; @drafts = (join('',) =~ /(draft-[-a-z0-9]*)/g); close (AGENDA); # Make the list of drafts unique undef %tmp; foreach $draft (@drafts) { $draft =~ s/-*$//; $tmp{$draft}++; } @drafts = sort keys %tmp; mkdir($wg); foreach $draft (@drafts) { # If there's not a number, count down from 99 until we find the right one if (defined($id_mirror) && (-e $id_mirror) && ($draft !~ /-[0-9]$/)) { for ($i = 99; $i >= 0; $i--) { $fname = sprintf("${id_mirror}${draft}-%2.2d.txt", $i) ; if (-e $fname) { $fixedname{$draft} = sprintf("${draft}-%2.2d", $i) ; $draft = $fixedname{$draft}; last; } } } $d = $draft; if ($fixedname{$draft}) { $d = $fixedname{$draft}; } print " ${d}.txt\n"; if (-e $id_mirror.$d.".txt") { &cp ($id_mirror.$d.".txt", $wg); $source{"$wg/${d}.txt"} = $id_mirror.$d.".txt"; } else { if ($verbose) { print "Getting ${d}.txt into $wg\n"; } &wget("http://tools.ietf.org/id/${d}.txt","$wg/${d}.txt"); $source{"$wg/${d}.txt"} = "$wg/${d}.txt"; } } } print "\n"; ###################################################################### # Find and create diffs (from previous meeting, if available; from # previous version if not discussed at previous meeting) ###################################################################### foreach $draft (sort keys %source) { $source{$draft} =~ /([0-9]{2})\.txt$/; $num = $1; undef($old); $lastMeeting = getcwd; $lastNumber = $number-1; $lastMeeting =~ s/$number/$lastNumber/; $lastMeeting .= "/$draft"; $lastMeeting =~ s/[0-9]{2}\.txt/??.txt/; $lastMeeting =~ s/draft-ietf-/draft-*-/; ($oldDraft) = glob($lastMeeting); if (-e $oldDraft) { $old = $oldDraft; } elsif ($num ne '00') { $prev = $num - 1; $prev = sprintf("%2.2d",$prev); $old = $source{$draft}; $old =~ s/$num\.txt$/$prev\.txt/; if (! -e $old) { $old_draft_name = $draft; $old_draft_name =~ s/.*\/([^\/]*)$/$1/g; $old_draft_name =~ s/$num\.txt$/$prev\.txt/; if ($verbose) { print "Getting old draft $old_draft_name\n"; } &wget("http://tools.ietf.org/id/${old_draft_name}",$old); } } if (defined($old) && -e $old) { $diff = &htmlwdiff($old, $source{$draft}); $output = "${draft}-diff.html"; print "Writing $output...\n"; open (DIFF, ">$output"); print DIFF $diff; close DIFF; } else { if ($verbose) { print "Can't diff $draft...\n"; } } } ###################################################################### # Relink any pre-existing HTML agendas ###################################################################### foreach $agenda () { ($group) = ($agenda =~ /([^\/]*)\.html$/); open (IN, $agenda); $body = join('',); close IN; $out = $agenda; $body =~ s/]*href *= *['"]http[^'"]*['"][^>]*>(.*?)<\/a>/$1/gis; $body =~ s/(draft-[-a-z0-9]*[a-z0-9])/&linkdraft($group,$1)/ge; open (OUT, ">$out"); print OUT $body; close (OUT); } ###################################################################### # HTML-ize any text sub-agendas ###################################################################### foreach $agenda () { $out = $agenda; $out =~ s/(.*)\/([^\/]*)\.txt/$1\/$2.html/g; $group = $2; if (-e $out) { next; } open (IN, $agenda); # open (IN, "fmt $agenda|"); $body = join('',); close IN; $body =~ s/\&/&/g; $body =~ s//>/g; $body =~ s/\r?\n\r?( *)/'
'. ($1)/eg; # This is in case the ECRIT chairs' text editor goes bonkers. $body =~ s/\r( *)/'
'. ($1)/eg; $body =~ s/\t/        /g; $body =~ s/(draft-[-a-z0-9]*[a-z0-9])/&linkdraft($group,$1)/ge; open (OUT, ">$out"); print OUT "$group agenda\n". $body. "\n\n"; close (OUT); } ###################################################################### # Merge all agenda files into one file for printing ###################################################################### open (IN, "agenda_${number}.html"); $agenda = join '', ; close (IN); $agenda =~ s/]*src="([^"]*)"[^>]*><\/iframe>/&import($1)/goem; open (OUT, ">agenda_${number}_printable.html"); print OUT $agenda; close (OUT); sub import { open (IFRAME, shift); my ($body) = join '',