X-Git-Url: http://git.tpope.net/?p=tpope-extra.git;a=blobdiff_plain;f=perl%2Fschedproc;h=81f4a1aec943be197811efe3cfe9675544930d98;hp=eaaa024664b168e2619163128ed1dd4b76b41dcc;hb=bda4e7dc19a041c49e7f2bab8051fa3921a59503;hpb=675d8f81afaea93d4fa584a0ab3da9896f0bbd87 diff --git a/perl/schedproc b/perl/schedproc index eaaa024..81f4a1a 100755 --- a/perl/schedproc +++ b/perl/schedproc @@ -3,51 +3,114 @@ # -*- perl -*- vim: ft=perl sw=4 sts=4 # Brief usage instructions: -# Create a ~/.sct6rc that has SID=yourssn and PIN=yourpin -# You'll need to change the url below if you go anywhere but TAMUK. +# Create a ~/.schedprocrc that has schedule=/path/to/schedule.xml and +# grades=/path/to/grades.xml. HTTP URLs are acceptable use strict; use Date::Calc::Object qw(Day_of_Week Decode_Day_of_Week Decode_Month Week_of_Year Monday_of_Week Day_of_Week_Abbreviation Delta_Days Add_Delta_Days Nth_Weekday_of_Month_Year Gmtime Mktime); use Date::Calendar::Profiles qw($Profiles); use Date::Calendar::Year; +use Getopt::Long; use LWP::UserAgent; use XML::Simple; -use vars qw(%opts %faculty); +use vars qw(%opts %faculty %facurl); -my ($response); +$opts{'config'} = $ENV{HOME} . "/.schedprocrc"; -my $config = $ENV{HOME} . "/.schedprocrc"; -if (($ARGV[0] || "") eq '-F') { +my $arg = $ARGV[0] || ""; +if($arg eq "-x") { shift; - $config = shift; + $opts{'format'} = "xml"; +} elsif($arg eq "-h") { + shift; + $opts{'format'} = "html"; +} elsif($arg eq "-m") { + shift; + $opts{'format'} = "mhc"; +} elsif($arg eq "-c") { + shift; + $opts{'format'} = "csv"; +} elsif($arg eq "-v") { + shift; + $opts{'format'} = "vcs"; +} elsif($arg eq "-g") { + shift; + $opts{'format'} = "grades"; } -my $arg = ""; -$arg = shift if (defined($ARGV[0]) && $ARGV[0] =~ /^-\w$/); +Getopt::Long::Configure ("bundling", "auto_help"); +die "Invalid arguments\n" unless +GetOptions(\%opts, 'schedule|S=s', 'grades|G=s', 'faculty=s', 'name|n=s', 'email|e=s', 'format|f=s', 'config|F=s', 'out|o=s'); -if (-r $config) { - open CONFIG, $config; +if (-r $opts{'config'}) { + open CONFIG, $opts{'config'} or die $!; while() { s/\#.*//; next unless m/^([^=]*)=(.*)/; - $opts{$1}=$2; + my ($l, $r) = ($1, $2); + if ($l =~ /^(schedule|grades|name|email|faculty)$/) { + $opts{$l}=$r unless(defined($opts{$l})); + } else { + warn "Unknown config file option $l.\n"; + } } close CONFIG; } -my $schedurl = $ENV{HOME} . "/schedule.xml"; -$schedurl = $opts{'schedule'} if(defined($opts{'schedule'})); -my $gradeurl = $ENV{HOME} . "/grades.xml"; -$gradeurl = $opts{'grades'} if(defined($opts{'schedule'})); + +$opts{'schedule'} ||= "~/schedule.xml"; +$opts{'grades'} ||= "~/grades.xml"; +$opts{'faculty'} ||= ""; + +$opts{'schedule'} =~ s/(^|,)~\//$1$ENV{HOME}\//; +$opts{'grades'} =~ s/(^|,)~\//$1$ENV{HOME}\//; +$opts{'faculty'} =~ s/(^|,)~\//$1$ENV{HOME}\//; + +if(!defined($opts{'out'}) && defined($ARGV[0])) { + $opts{'out'} = shift; +} + +if(!defined($opts{'format'}) && defined($opts{'out'})) { + $opts{'format'} = $opts{'out'}; + $opts{'format'} =~ s/.*\.//; + $opts{'format'} =~ s/^(.*\/|)\.?schedule$/mhc/; + undef $opts{'out'} if($opts{'out'} =~ /^(html|mhc|csv|vcs|ics|xml|grades)$/); +} + +$opts{'format'} ||= ""; +undef $opts{'out'} if(($opts{'out'}||"") eq "-"); sub generate_id { my ($section, $number) = split("-", shift); my $id = 0; - foreach (split //, $section) {$id=26*$id+(ord($_)-1)%32;} + foreach my $c (split //, $section) {$id=26*$id+(ord($c)-1)%32;} $id=10000*$id+$number; return $id; } +sub first_class { + my %days = (M => 1, T => 2, W => 3, R => 4, F => 5, S => 6, U => 7); + my %class = @_; + $class{'duration'} =~ /(\d\d\d\d)(\d\d)(\d\d)-(\d\d\d\d)(\d\d)(\d\d)/; + my $days = Delta_Days($1,$2,$3,$4,$5,$6); + my $firstday = Date::Calc->new($1,$2,$3); + my $lastday = Date::Calc->new($4,$5,$6); + my $today; + my @days=(); + foreach my $d (split("",$class{'days'})) { + push @days, $days{$d}; + } + my @off = (); + @off = @{$class{'off'}} if ($class{'off'}); + for($today = $firstday; $today < $lastday; $today++) { + next unless(grep($_ == Day_of_Week($today->date), @days)); + next if(grep($_ == "$today", @off)); + return $today; + } + return undef; +} + sub next_class { + my %days = (M => 1, T => 2, W => 3, R => 4, F => 5, S => 6, U => 7); my %class = @_; $class{'duration'} =~ /(\d\d\d\d)(\d\d)(\d\d)-(\d\d\d\d)(\d\d)(\d\d)/; my $days = Delta_Days($1,$2,$3,$4,$5,$6); @@ -55,8 +118,8 @@ sub next_class { my $lastday = Date::Calc->new($4,$5,$6); my $today = Date::Calc->new(Date::Calc->localtime(time+3600*6)->date); my @days=(); - foreach(split(" ",$class{'days'})) { - push @days, Decode_Day_of_Week($_); + foreach my $d(split("",$class{'days'})) { + push @days, $days{$d}; } my @off = (); @off = @{$class{'off'}} if ($class{'off'}); @@ -74,6 +137,16 @@ sub next_class { return undef; } +sub vcal_datetime { + my $date=shift; + my $time=shift; + $date =~ /(\d\d\d\d)(\d\d)(\d\d)/; + my ($y,$m,$d)=($1,$2,$3); + $time =~ /(\d\d):?(\d\d)/; + my $day=Date::Calc->gmtime(Mktime($y,$m,$d,$1,$2,0)); + return sprintf ("%02d%02d%02dT%02d%02d%02dZ", $day->year(), $day->month(), $day->day(), $day->time()); +} + sub capitalize { local $_ = shift || ""; s/ +$//; @@ -101,93 +174,66 @@ sub capitalize { return $_; } -sub get_schedule { +sub read_fileurl { my $content; - if($schedurl =~ /:\/\//) { + my $url=shift; + if($url =~ /:\/\//) { my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; # $ua->cookie_jar( {} ); - $response = $ua->get("$schedurl") or die "$!"; - die $response->status_line unless $response->is_success; - $content = $response->content; + my $response = $ua->get("$url") or die "$!"; + if($response->is_success) { + $content = $response->content; + } else { + die "$!" unless $_[0]; + } } else { - open(F,$schedurl) || die "$!"; - $content = join ("", ); - close F; + if(open(F,$url)) { + $content = join ("", ); + close F; + } else { + die "$!" unless $_[0]; + } } + return $content||""; + #my $ref = XMLin($content, ForceArray => [ 'class', 'cumulative', 'off' ], KeyAttr => ""); + #return @{$ref->{'class'}}; +} + +sub get_schedule { + my $content = read_fileurl($opts{'schedule'}); my $ref = XMLin($content, ForceArray => [ 'class', 'off' ], KeyAttr => ""); + die "Could not load schedule.\n" unless $ref->{'class'}; return @{$ref->{'class'}}; } sub get_grades { - my $content; - if($gradeurl =~ /:\/\//) { - my $ua = LWP::UserAgent->new; - $ua->timeout(10); - $ua->env_proxy; -# $ua->cookie_jar( {} ); - $response = $ua->get("$gradeurl") or die "$!"; - die $response->status_line unless $response->is_success; - $content = $response->content; - } else { - open(F,$schedurl) || die "$!"; - $content = join ("", ); - close F; - } + my $content = read_fileurl($opts{'grades'}); my $ref = XMLin($content, ForceArray => [ 'class', 'cumulative' ], KeyAttr => ""); return $ref; } -sub do_html_grades { - my $grades); - my @showheaders = ("Section ID", "Course Title", "Grade", "Earned
Hours", "Quality
Hours", "Quality
Points"); - #$file = shift unless (!defined $_[0] or $_[0] =~ /^\d/); - $grades = get_grades(@_); - my ($row); - my $shade = "dark"; - print ''."\n"; - print '\n"; - foreach my $ts ($grades->{'class'}) { - foreach my $row (@$ts) { - print ''; - $shade = ($shade eq "dark"?"light":"dark"); - print ''; - print ''; - print '\n"; - } - } - my $lastrow = $grades->{'cumulative'}->[scalar @{$grades->{'cumulative'}}-1]; - print '\n"; - print "
', $showheaders[0]; - print '', $showheaders[1]; - print ''; - print join('',@showheaders[2 .. 5]); - print "
', $row->{'id'}, '', $row->{'title'}, ''; - #print join('', @$row[0 .. 1]); - print join('', ($row->{'grade'},$row->{'earned'},$row->{'hours'},$row->{'points'})); - print "
Cumulative: through ', capitalize($lastrow->{'term'}); - print ''; - print $lastrow->{'gpa'}; - print ''; - print join('', ($lastrow->{'earned'}, $lastrow->{'hours'}, $lastrow->{'points'})); - print "
\n"; -} - -sub get_faculty_email { - my ($name, $school, $email); - if((-f $ENV{'HOME'} . "/public_html/faculty.csv") && ! %faculty) { - open INS, $ENV{'HOME'} . "/public_html/faculty.csv"; - while($_ = ) { - chomp; - m/"([^"]*)",([^,]*),([^,]*)/; # " - ($name, $email, $school) = ($1, $2, $3); +sub load_faculty { + my ($name, $email, $url, $content); + if(($opts{'faculty'}) && ! %faculty) { + $faculty{'done'} = "true"; + $content = read_fileurl($opts{'faculty'},1); + foreach my $f (split("\n", $content)) { + ($name, $email, $url) = $f =~ m/"([^"]*)",([^,]*),([^,]*)/; # " + next unless ($name); $name =~ s/ [A-Z]\.//g; $name = lc $name; $name =~ s/\W//g; - $faculty{$name} = $email; + $faculty{$name} = $email if($email); + $facurl{$name} = $url if ($url); } } +} + +sub get_faculty_email { + load_faculty(); + my ($name); $name = shift; $name =~ s/ [A-Z]r?\.//g; $name = lc $name; @@ -195,6 +241,16 @@ sub get_faculty_email { return $faculty{$name}; } +sub get_faculty_url { + load_faculty(); + my ($name); + $name = shift; + $name =~ s/ [A-Z]r?\.//g; + $name = lc $name; + $name =~ s/\W//g; + return $facurl{$name}; +} + sub get_mhc_header { return ( "X-SC-Subject: New Years Day\nX-SC-Category: Holiday\nX-SC-Cond: 1 Jan\nX-SC-Duration: 00010101-\nX-SC-Record-Id: \n", @@ -215,15 +271,16 @@ sub do_mhc_schedule { my %days = (M => "Mon", T => "Tue", W => "Wed", R => "Thu", F => "Fri", S => "Sat", U => "SU"); my @mon = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); my ($file, $current, @mhc, @schedule); - $file = shift unless (!defined $_[0] or $_[0] =~ /^\d/); + $file = $opts{'out'}; @schedule = get_schedule(@_); @mhc = get_mhc_header; if(defined($file) && (-d $file)) { my @mhc2; + local $_; foreach (@mhc) { - $_ =~ s/X-SC-Subject: ([^\n]*)/X-SC-Subject: $1\nSubject: $1/; - $_ =~ s/X-SC-Category: ([^\n]*)/X-SC-Category: $1\nFrom: $1/; - $_ =~ s/X-SC-Duration: (\d\d\d\d)(\d\d)(\d\d)-/"X-SC-Duration: $1$2$3-\nDate: $3 " . $mon[$2-1] . " 1970 12:00:00 +0000"/e; + s/X-SC-Subject: ([^\n]*)/X-SC-Subject: $1\nSubject: $1/; + s/X-SC-Category: ([^\n]*)/X-SC-Category: $1\nFrom: $1/; + s/X-SC-Duration: (\d\d\d\d)(\d\d)(\d\d)-/"X-SC-Duration: $1$2$3-\nDate: $3 " . $mon[$2-1] . " 1970 12:00:00 +0000"/e; push @mhc2, $_; } @mhc = @mhc2; @@ -231,11 +288,12 @@ sub do_mhc_schedule { foreach my $row (@schedule) { map {s/\n/-/g if defined; $_} %$row; my $id=generate_id($row->{'id'}); + my $next = next_class(%$row); $row->{'days'} =~ s/([MTWRFS])/ $days{$1}/g; $row->{'days'} =~ s/^ //; #$row->{'duration'} =~ s/(\d\d)-(\d\d)-(\d\d)/20$3$1$2/g; my @day = (); - @day = map { "!" . $_ } (@{$row->{'off'}}) if ($row->{'off'}); + @day = map { "!$_" } (@{$row->{'off'}}) if ($row->{'off'}); $current = ""; #print "# $id\n"; $current .= "X-SC-Subject: " . $row->{'title'} . "\n"; @@ -252,7 +310,6 @@ sub do_mhc_schedule { $row->{'instructor'} = '"' . $row->{'instructor'} . '" <'. ($email || ($1 || "unknown") . "\@from.sctweb") . ">"; $row->{'duration'} =~ /^(\d\d\d\d)(\d\d)(\d\d)-\d{8}$/; $row->{'begin'} =~ /^(\d\d):(\d\d)$/; - my $next = next_class(%$row); my @date = Gmtime(Mktime($next->date,$1,$2,0)); $current .= sprintf "Date: %s, %2d %s %4d %02d:%02d:00 +0000\n", Day_of_Week_Abbreviation($date[7]), $date[2], $mon[$date[1]-1], $date[0], $date[3], $date[4], $date[5]; $current .= "Subject: " . $row->{'title'} . "\n"; @@ -265,7 +322,7 @@ sub do_mhc_schedule { my @lines; foreach my $name (<$file/[1-9]*>) { next unless $name =~ /^$file\/[1-9][0-9]*$/; - open FH, $name; + open (FH, $name) || die $!; @lines = ; close FH; foreach (@lines) { @@ -273,14 +330,14 @@ sub do_mhc_schedule { } } my $i=0; - foreach (@mhc) { + foreach my $h (@mhc) { while(-f ++$i) {} - open FH, ">$file/$i" or die $!; - print FH $_; + open (FH, ">$file/$i") || die $!; + print FH $h; close FH; } } else { - open(STDOUT, ">" . $file) if(defined($file)); + open(STDOUT, ">" . $file) || die $! if(defined($file)); print "# MHC school schedule\n# Autogenerated by sctweb ".localtime()."\n\n"; print join("\n", @mhc); } @@ -290,21 +347,22 @@ sub do_csv_schedule { $| = 1; my %days = (M => "Mon", T => "Tue", W => "Wed", R => "Thu", F => "Fri", S => "Sat", U => "SU"); my @mon = qw(Jan. Feb. Mar. Apr. May June July Aug. Sept. Oct. Nov. Dec.); - my (@terms, $file, $current, @mhc, @schedule); - $file = shift unless (!defined $_[0] or $_[0] =~ /^\d/); + my ($current, @mhc, @schedule); @schedule = get_schedule(@_); - open(STDOUT, ">" . $file) if(defined($file)); + open(STDOUT, ">" . $opts{'out'}) || die $! if(defined($opts{'out'})); foreach my $row (@schedule) { map {s/\n/-/g if defined; $_} %$row; my $id=generate_id($row->{'id'}); + my $next = next_class(%$row); $row->{'days'} =~ s/([MTWRFS])/ $days{$1}/g; $row->{'days'} =~ s/^ //; - my $next = next_class(%$row); $current = ""; #print "# $id\n"; $current .= $row->{'id'} . ","; $current .= $row->{'title'} . ","; - $current .= '"' . $row->{'instructor'} . '",'; + my $instructor = $row->{'instructor'}; + $instructor =~ s/ [A-Z. ]* / /; + $current .= '"' . $instructor . '",'; $next =~ /^(\d\d\d\d)(\d\d)(\d\d)$/; $current .= $1 . "-". $2 ."-" . $3 . "\n"; print $current; @@ -314,26 +372,25 @@ sub do_csv_schedule { sub do_vcalendar_schedule { $| = 1; my %days = (M => "MO", T => "TU", W => "WE", R => "TH", F => "FR", S => "SA", U => "SU"); - my $file = shift if (defined $_[0] and $_[0] !~ /^\d/); + my $file = $opts{'out'}; my @schedule = get_schedule(@_); - open(STDOUT, ">>" . $file) if(defined($file) && (! -d $file)); - open(STDOUT, ">/dev/null") if(defined($file) && (-d $file)); + open(STDOUT, ">" . $file) || die $! if(defined($file) && (! -d $file)); + open(STDOUT, ">/dev/null") || die $! if(defined($file) && (-d $file)); print "BEGIN:VCALENDAR\r\nVERSION:1.0\r\n"; foreach my $row (@schedule) { map { s/\n/-/g; $_} %$row; - $row->{'days'} =~ s/([MTWRFS])/ $days{$1}/g; - $row->{'days'} =~ s/^ //; + my ($starttime, $stoptime)=($row->{'begin'}, $row->{'end'}); + my ($startdate, $stopdate)=split(/-/, $row->{'duration'}); + $starttime =~ s/://; + $stoptime =~ s/://; + my $first = first_class(%$row); my @day = (); @day = @{$row->{'off'}} if ($row->{'off'}); my $day = ""; if(exists($day[0])) { $day = join(";", @day); - $day =~ s/\b(\d{8})\b/$1T000000/g; + $day =~ s/\b(\d{8})\b/$1T${starttime}00/g; } - my ($starttime, $stoptime)=($row->{'begin'}, $row->{'end'}); - my ($startdate, $stopdate)=split(/-/, $row->{'duration'}); - $starttime =~ s/://; - $stoptime =~ s/://; if(defined($file) && (-d $file)) { open FH, ">$file/" . $row->{'id'} . ".vcs" or die "$!"; select FH; @@ -344,11 +401,15 @@ sub do_vcalendar_schedule { print "DESCRIPTION:", $row->{'id'}, "\r\n"; print "LOCATION:", $row->{'location'}, "\r\n"; print "CATEGORIES:Education\r\n"; - print "DTSTART:", $startdate."T".$starttime, "00\r\n"; - print "DTEND:", $startdate."T".$stoptime, "00\r\n"; + print "DTSTART:", vcal_datetime($first,$starttime), "\r\n"; + print "DTEND:", vcal_datetime($first,$stoptime), "\r\n"; + #print "DTSTART:", $first."T".$starttime, "00\r\n"; + #print "DTEND:", $first."T".$stoptime, "00\r\n"; + $row->{'days'} =~ s/([MTWRFS])/ $days{$1}/g; + $row->{'days'} =~ s/^ //; print "RRULE:W1 ", $row->{'days'} . " $stopdate", "T000000\r\n"; print("EXDATE:$day\r\n") if($day); - print "ATTENDEE;ROLE=OWNER;STATUS=CONFIRMED:", $opts{'name'}, "\r\n" if(defined($opts{'name'})); + print "ATTENDEE;ROLE=OWNER;STATUS=CONFIRMED:", $opts{'name'}, ($opts{'email'}?" <".$opts{'email'}.">":""), "\r\n" if(defined($opts{'name'})); print "ATTENDEE;ROLE=ORGANIZER;STATUS=CONFIRMED:", $row->{'instructor'}, " <" . (get_faculty_email($row->{'instructor'}) || "fake\@ddress"), ">\r\n"; print "END:VEVENT\r\n"; if(defined($file) && (-d $file)) { @@ -360,12 +421,93 @@ sub do_vcalendar_schedule { print "END:VCALENDAR\r\n"; } +sub do_icalendar_schedule { + $| = 1; + my $r="\r"; + # Ugh, I can't find a better solution than hardwiring it to CST + my $tzn = "America/Chicago"; + my $timezone = <now(); + $now = sprintf ("%02d%02d%02dT%02d%02d%02dZ", $now->datetime()); + my %days = (M => "MO", T => "TU", W => "WE", R => "TH", F => "FR", S => "SA", U => "SU"); + my $file = $opts{'out'}; + my @schedule = get_schedule(@_); + open(STDOUT, ">" . $file) || die $! if(defined($file) && (! -d $file)); + open(STDOUT, ">/dev/null") || die $! if(defined($file) && (-d $file)); + print "BEGIN:VCALENDAR$r\nPRODID:-//Tim Pope//NONSGML Schedproc//EN$r\nVERSION:2.0$r\nMETHOD:PUBLISH$r\n$timezone"; + foreach my $row (@schedule) { + map { s/\n/-/g; $_} %$row; + my ($starttime, $stoptime)=($row->{'begin'}, $row->{'end'}); + my ($startdate, $stopdate)=split(/-/, $row->{'duration'}); + $starttime =~ s/://; + $stoptime =~ s/://; + my $first = first_class(%$row); + my @day = (); + @day = @{$row->{'off'}} if ($row->{'off'}); + my $day = ""; + if(exists($day[0])) { + $day = join(",", @day); + #$day =~ s/\b(\d{8})\b/$1T${starttime}00/g; + } + if(defined($file) && (-d $file)) { + open FH, ">$file/" . $row->{'id'} . ".vcs" or die "$!"; + select FH; + print "BEGIN:VCALENDAR$r\nPRODID:-//Tim Pope//NONSGML Schedproc//EN$r\nVERSION:2.0$r\nMETHOD:PUBLISH$r\n$timezone"; + } + print "BEGIN:VEVENT$r\n"; + print "ORGANIZER:mailto:" . $opts{'email'} . "$r\n" if $opts{'email'}; + print "UID:" . $row->{'id'} . "\@from.sctweb$r\n"; + print "DTSTAMP:$now$r\n"; + print "SUMMARY:", $row->{'title'}, "$r\n"; + print "DESCRIPTION:", $row->{'id'}, "$r\n"; + print "LOCATION:", $row->{'location'}, "$r\n"; + print "CATEGORIES:Education$r\n"; + print "TRANSP:OPAQUE$r\n"; + print "DTSTART;TZID=\"$tzn\":", $first."T".$starttime, "00$r\n"; + print "DTEND;TZID=\"$tzn\":", $first."T".$stoptime, "00$r\n"; + $row->{'days'} =~ s/([MTWRFS])/,$days{$1}/g; + $row->{'days'} =~ s/^,//; + #$stopdate++; + print "RRULE:FREQ=WEEKLY;UNTIL=${stopdate}T000000Z;BYDAY=", $row->{'days'}, "$r\n"; + #print("EXDATE;TZID=\"$tzn\":$day$r\n") if($day); + print("EXDATE;VALUE=DATE:$day$r\n") if($day); + print "ATTENDEE;CN=".$row->{'instructor'}.";RSVP=FALSE;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:" . (get_faculty_email($row->{'instructor'}) || "fake\@ddress"), "$r\n"; + print "ATTENDEE;CN=".$opts{'name'}.";RSVP=FALSE;PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT:mailto:" . ($opts{'email'} || "fake\@ddress"), "$r\n" if $opts{'name'}; + print "END:VEVENT$r\n"; + if(defined($file) && (-d $file)) { + print "END:VCALENDAR$r\n"; + close FH; + select STDOUT; + } + } + print "END:VCALENDAR$r\n"; +} + sub do_xml_schedule { - my $file = shift if (defined $_[0] and $_[0] !~ /^\d/); + my $file = $opts{'out'}; my $schedule = { class => [ get_schedule(@_) ] }; my $xml = XMLout($schedule, NoAttr => 1, RootName => 'schedule'); if($file) { - open FH, ">$file"; + open FH, ">$file" || die $!; print FH $xml; close FH; } else { @@ -377,12 +519,15 @@ sub do_html_schedule { my @showheaders = ("Section ID/Title", "Instructor", "Days", "Time", "Duration", "Location"); my $shade = "dark"; my @schedule = get_schedule(@_); + if($opts{'out'}) { + open (FH, ">".$opts{'out'}) || die $!; + select FH; + } print ''."\n\n"; foreach my $row (@schedule) { map { s/\n/
/g; $_} %$row; - #$row->{'time'} =~ s/-/-/; $row->{'duration'} =~ s/-/
/g; $row->{'duration'} =~ s/\d\d(\d\d)(\d\d)(\d\d)/$2-$3-$1/g; print ''; @@ -391,33 +536,82 @@ sub do_html_schedule { print '' .$row->{'id'}. '
'; print '' .$row->{'title'}. ''; my $instructor = $row->{'instructor'}; - my $email = get_faculty_email($row->{'instructor'}); - #if($email) { - #print '"; - # } else { - print ""; - #} + #$instructor =~ s/ [A-Z. ]* / /; + my $url = get_faculty_url($row->{'instructor'}); + if($url) { + print '"; + } else { + print '"; + } print ""; - print ""; + my ($a,$b) = ($row->{'begin'}, $row->{'end'}); + $b .= "AM"; + $a=~s/(1[3-9]|2\d|00):(\d\d)/sprintf "%d:%02d",abs $1-12,$2/e; + $b=~s/(1[3-9]|2\d|00):(\d\d)AM/sprintf "%d:%02dPM",abs $1-12,$2/e; + print ""; print ""; - print ""; + print ""; print "\n"; } print "
"; print join("",@showheaders); print "
' - #. $row->{'instructor'} . "" . $row->{'instructor'} . "' + . $row->{'instructor'} . "' . $instructor . "" . $row->{'days'} . "" . $row->{'begin'}."-".$row->{'end'} . "$a-$b" . $row->{'duration'} . "" . $row->{'location'} . "" . (ref($row->{'location'})?"":$row->{'location'}) . "
\n"; + select STDOUT; +} + +sub do_html_grades { + my $grades; + my @showheaders = ("Section ID", "Course Title", "Grade", "Earned
Hours", "Quality
Hours", "Quality
Points"); + $grades = get_grades(@_); + my ($row); + my $shade = "dark"; + if($opts{'out'}) { + open (FH, ">".$opts{'out'}) || die $!; + select FH; + } + print ''."\n"; + print '\n"; + foreach my $ts ($grades->{'class'}) { + foreach my $row (@$ts) { + print ''; + $shade = ($shade eq "dark"?"light":"dark"); + print ''; + print ''; + print '\n"; + } + } + my $lastrow = $grades->{'cumulative'}->[scalar @{$grades->{'cumulative'}}-1]; + print '\n"; + print "
', $showheaders[0]; + print '', $showheaders[1]; + print ''; + print join('',@showheaders[2 .. 5]); + print "
', $row->{'id'}, '', $row->{'title'}, ''; + #print join('', @$row[0 .. 1]); + print join('', ($row->{'grade'},$row->{'earned'},$row->{'hours'},$row->{'points'})); + print "
Cumulative: through ', capitalize($lastrow->{'term'}); + print ''; + print $lastrow->{'gpa'}; + print ''; + print join('', ($lastrow->{'earned'}, $lastrow->{'hours'}, $lastrow->{'points'})); + print "
\n"; + select STDOUT; } -if ($arg eq "-s" || $arg eq "-h") { + +if ($opts{'format'} eq "xml") { + do_xml_schedule(@ARGV); +} elsif ($opts{'format'} eq "html") { do_html_schedule(@ARGV); -} elsif ($arg eq "-m") { +} elsif ($opts{'format'} eq "mhc") { do_mhc_schedule(@ARGV); -} elsif ($arg eq "-c") { +} elsif ($opts{'format'} eq "csv") { do_csv_schedule(@ARGV); -} elsif ($arg eq "-v") { +} elsif ($opts{'format'} eq "vcs") { do_vcalendar_schedule(@ARGV); -} elsif ($arg eq "-x") { - do_xml_schedule(@ARGV); -} elsif ($arg eq "-g") { +} elsif ($opts{'format'} eq "ics") { + do_icalendar_schedule(@ARGV); +} elsif ($opts{'format'} eq "grades") { do_html_grades(@ARGV); +} else { + die "Unknown format. Try specifying --format.\n" } -