#!/bin/bash ### ### DRAFTTIMELINE -- Draw a picture of draft timeline ### ### ### Version: 1.0.0, Jan 11th, 2008 ### ### Usage ### ### drafttimeline [options] draftname jpgfile ### initialindividualsubmission individualdays indname ### initialsubmission wgdays ### firstiesgstate iesgdays ### firstapprov rfceddays ### firstpub ### ### where options is one of the following: ### ### --versions Draw also version dates ### ### --debug Turn on debugging ### ### --prefer-family={IPv4,IPv6} Select IP version preference for wget ### ### ### Parse command line ### PREFFAMILY=IPv6 VERSIONS=0 DEBUG=0 while [ $# -gt 12 ] do case $1 in --debug) shift; DEBUG=1;; --versions) shift; VERSIONS=1;; --prefer-family=IPv4) shift; PREFFAMILY=IPv4;; --prefer-family=IPv6) shift; PREFFAMILY=IPv6;; *) echo 'drafttimeline: Unrecognized argument ('$1') -- exit'; exit 1;; esac done if [ $# = 12 ] then jpgfile="$2" inddraft="$5" draft="$1" begindate="$3" wgdate="$6" iesgdate="$8" approvdate=${10} enddate=${12} ageindividual=$4 agewg="$7" ageiesg="$9" agerfced=${11} else echo 'drafttimeline: wrong number of arguments ('$#', expected 12 -- exit' exit 1 fi if [ x$inddraft = x -a $ageindividual = 0 ] then case $draft in draft-ietf-*) ;; draft-iab-*) ;; draft-iesg-*) ;; draft-irtf-*) ;; *) inddraft=$draft; ageindividual=$agewg; begindate=$wgdate; agewg=0; wgdate=none;; esac fi ### ### Make some checks ### if [ $ageindividual -lt 0 ] then echo "warning: drafttimeline: Individual age negative for $draft -- exit" exit 1 fi if [ $agewg -lt 0 ] then echo "warning: drafttimeline: WG age negative for $draft -- exit" exit 1 fi if [ $ageiesg -lt 0 ] then echo "warning: drafttimeline: IESG age negative for $draft -- exit" exit 1 fi if [ $agerfced -lt 0 ] then echo "warning: drafttimeline: RFC Editor age negative for $draft -- exit" exit 1 fi ### ### Make temporary directory ### tmpdir=/tmp/drafttimeline.$draft rm -rf $tmpdir 2>&1 > /dev/null mkdir $tmpdir ### ### Fixed picture constants ### toty=400 totx=900 blockheight=70 xstart=15 ystart=15 yend=120 datesize=10 explainsize=12 versionsize=7 versionxoffset=`expr $versionsize + 2` versionyoffset=-4 maxblock=`expr $totx - $xstart - $xstart - 100` ### ### Function: difference in days ### function daydifference() { awk -v date1=$1 -v date2=$2 ' function daydifference(d1,d2) { split(d1,d1a,"-"); split(d2,d2a,"-"); y1 = d1a[1] + 0; m1 = d1a[2] + 0; d1 = d1a[3] + 0; u1 = (y1 - 1970) * 365 + m1 * 30 + d1; y2 = d2a[1] + 0; m2 = d2a[2] + 0; d2 = d2a[3] + 0; u2 = (y2 - 1970) * 365 + m2 * 30 + d2; return(u1 - u2); } END { printf("%s\n", daydifference(date1,date2)); } ' < /dev/null } ### ### Function: revsmerge, merge revisions from the same day ### function revsmerge() { sort -n | awk ' BEGIN { FS=":"; } /:/ { ver = $1; date = $2; if (tab[date] == "") { tab[date] = ver; } else if (index(tab[date],ver) != 0) { # do not add anything } else { tab[date] = tab[date] "," ver; } } END { for (i in tab) { printf("%s:%s\n", tab[i], i); } } ' } ### ### Calculate some basic statistics ### agetotal=`expr $ageindividual + $agewg + $ageiesg + $agerfced` if [ $agetotal = 0 ] then agetotal=1 fi individual=`expr $maxblock \* $ageindividual / $agetotal` wg=`expr $maxblock \* $agewg / $agetotal` iesg=`expr $maxblock \* $ageiesg / $agetotal` rfced=`expr $maxblock \* $agerfced / $agetotal` persindividual=`(echo scale=1; echo 100 "*" $ageindividual / $agetotal) | bc` perswg=`(echo scale=1; echo 100 "*" $agewg / $agetotal) | bc` persiesg=`(echo scale=1; echo 100 "*" $ageiesg / $agetotal) | bc` persrfced=`(echo scale=1; echo 100 "*" $agerfced / $agetotal) | bc` #echo drafttimeline debug: ageindividual = $ageindividual >> /dev/stderr #echo drafttimeline debug: agewg = $agewg >> /dev/stderr #echo drafttimeline debug: ageiesg = $ageiesg >> /dev/stderr #echo drafttimeline debug: agerfced = $agerfced >> /dev/stderr #echo drafttimeline debug: agetotal = $agetotal >> /dev/stderr #echo drafttimeline debug: wg = $wg >> /dev/stderr #echo drafttimeline debug: iesg = $iesg >> /dev/stderr #echo drafttimeline debug: rfced = $rfced >> /dev/stderr #echo drafttimeline debug: persindividual = $persindividual >> /dev/stderr #echo drafttimeline debug: perswg = $perswg >> /dev/stderr #echo drafttimeline debug: persiesg = $persiesg >> /dev/stderr #echo drafttimeline debug: persrfced = $persrfced >> /dev/stderr ### ### Create basic background tool images ### #echo drafttimeline debug: basic images >> /dev/stderr ppmmake black `expr $maxblock + 2` `expr $blockheight + 2` > $tmpdir/black.ppm ppmmake black 1 `expr $blockheight` > $tmpdir/line.ppm ### ### Create the bars in the diagram ### #echo drafttimeline debug: bars >> /dev/stderr if [ $individual -gt 0 ] then ppmmake grey `expr $individual - 1` $blockheight > $tmpdir/individual.ppm fi if [ $wg -gt 0 ] then ppmmake lightblue `expr $wg - 1` $blockheight > $tmpdir/wg.ppm fi if [ $iesg -gt 0 ] then ppmmake yellow `expr $iesg - 1` $blockheight > $tmpdir/iesg.ppm fi if [ $rfced -gt 0 ] then ppmmake pink $rfced $blockheight > $tmpdir/rfced.ppm fi ### ### Create image ### #echo drafttimeline debug: image >> /dev/stderr ppmmake white $totx $toty | pnmpaste -replace $tmpdir/black.ppm `expr $xstart - 1` `expr $toty - $yend - $blockheight - 1` | ### ### Individual phase ### if [ $individual -gt 0 ] then #echo drafttimeline debug: individual >> /dev/stderr ppmlabel -angle 90 -size $datesize \ -x `expr $xstart + $datesize` -y `expr $toty - $datesize` -colour black -text "$begindate" | pnmpaste -replace $tmpdir/individual.ppm $xstart `expr $toty - $yend - $blockheight` | ppmlabel -angle 45 -size $explainsize -color black \ -x `expr $xstart + \( $individual / 2 \) - $explainsize` \ -y `expr $toty - $yend - $blockheight - $explainsize` \ -text "Individual draft" -text " $inddraft" -text " $ageindividual days ($persindividual%)" else cat fi | ### ### WG phase ### if [ $wg -gt 0 ] then #echo drafttimeline debug: wg >> /dev/stderr ppmlabel -angle 90 -size $datesize \ -x `expr $xstart + $individual + $datesize / 2` -y `expr $toty - $datesize` \ -colour black -text "$wgdate" | pnmpaste -replace $tmpdir/wg.ppm `expr $xstart + $individual` `expr $toty - $yend - $blockheight` | ppmlabel -angle 45 -size $explainsize -color black \ -x `expr $xstart + $individual + \( $wg / 2 \) - $explainsize` \ -y `expr $toty - $yend - $blockheight - $explainsize` \ -text "WG draft" -text " "$draft -text " "$agewg" days ($perswg%)" else cat fi | ### ### IESG phase ### if [ $iesg -gt 0 ] then #echo drafttimeline debug: iesg >> /dev/stderr ppmlabel -angle 90 -size $datesize \ -x `expr $xstart + $individual + $wg + $datesize / 2` -y `expr $toty - $datesize` \ -colour black -text "$iesgdate" | pnmpaste -replace $tmpdir/iesg.ppm `expr $xstart + $individual + $wg` `expr $toty - $yend - $blockheight` | ppmlabel -angle 45 -size $explainsize -color black \ -x `expr $xstart + $individual + $wg + \( $iesg / 2 \) - $explainsize` \ -y `expr $toty - $yend - $blockheight - $explainsize` \ -text "IESG processing" -text " "$ageiesg" days ($persiesg%)" else cat fi | ### ### RFC Editor phase ### if [ $rfced -gt 0 ] then #echo drafttimeline debug: rfced >> /dev/stderr ppmlabel -angle 90 -size $datesize \ -x `expr $xstart + $individual + $wg + $iesg + $datesize / 2` -y `expr $toty - $datesize` \ -colour black -text "$approvdate" | pnmpaste -replace $tmpdir/rfced.ppm `expr $xstart + $individual + $wg + $iesg` `expr $toty - $yend - $blockheight` | ppmlabel -angle 45 -size $explainsize -color black \ -x `expr $xstart + $individual + $wg + $iesg + \( $rfced / 2 \) - $explainsize` \ -y `expr $toty - $yend - $blockheight - $explainsize` \ -text "RFC Editor processing" -text " "$agerfced" days ($persrfced%)" else cat fi | ### ### Publication ### if [ $enddate = none ] then cat else #echo drafttimeline debug: publication >> /dev/stderr ppmlabel -angle 90 -size $datesize \ -x `expr $xstart + $maxblock` -y `expr $toty - $datesize` \ -colour black -text "$enddate" fi | ### ### Add version bars and labels ### if [ $VERSIONS = 1 ] then cat > $tmpdir/beforeversion.ppm #echo drafttimeline debug: versions >> /dev/stderr revsfileorig=$tmpdir/revsorig.txt revsfile=$tmpdir/revs.txt docrevs --dates --prefer-family=$PREFFAMILY $draft | fgrep : > $revsfileorig if [ x$inddraft = x ] then nop=nop else docrevs --dates --prefer-family=$PREFFAMILY $inddraft | fgrep : >> $revsfileorig fi revsmerge < $revsfileorig > $revsfile for item in `cat $revsfile` do version=`echo $item | cut -f1 -d:` date=`echo $item | cut -f2 -d:` #echo "drafttimeline debug: for $draft, -$version appeared at $date" >> /dev/stderr if [ $date = UNKNOWN ] then nop=nop else days=`daydifference $date $begindate` daypixels=`expr $maxblock \* $days / $agetotal` #echo "drafttimeline debug: which is $days days and $daypixels pixels" >> /dev/stderr if [ $daypixels -ge 0 -a $daypixels -le $maxblock ] then cat $tmpdir/beforeversion.ppm | pnmpaste -replace $tmpdir/line.ppm `expr $xstart + $daypixels` `expr $toty - $yend - $blockheight` | ppmlabel -size $versionsize -color black -angle 90 \ -x `expr $xstart + $daypixels + $versionxoffset` \ -y `expr $toty - $yend - $versionsize - $versionyoffset` \ -text "$version" | cat > $tmpdir/afterversion.ppm cp $tmpdir/afterversion.ppm $tmpdir/beforeversion.ppm else echo "drafttimeline: $draft revision $version date is outside bounds" >> /dev/stderr fi fi done cat $tmpdir/beforeversion.ppm else cat fi | ### ### Finalize ### pnmmargin -white 1 | pnmtojpeg > $jpgfile #echo drafttimeline debug: finalize >> /dev/stderr ### ### Cleanup ### rm -rf $tmpdir 2>&1 > /dev/null