#!/usr/bin/perl
use warnings;
use strict;
use WWW::Mechanize;
use HTML::TokeParser;
use CGI;
my $id = YOUR_ID_HERE; #use quotes!
my $pin = YOUR_PIN_HERE; #use quotes!
my $semester = shift;
my $courses = shift;
my $cgi = CGI->new();
my $form = $cgi->Vars;
my $agent = WWW::Mechanize->new(cookie_jar=>{});
$agent->get('https://poseidon.cc.mcgill.ca/pls/mcgp/twbkwbis.P_WWWLogin');
$agent->form(2);
$agent->field('sid', $id);
$agent->field('PIN', $pin);
$agent->click();
$agent->get('https://poseidon.cc.mcgill.ca/pls/mcgp/bzsktran.P_Display_Form?user_type=S&tran_type=V');
if (!($agent->content =~ m/TERM GPA/)) {
die("Error accessing transcript. Perhaps system is busy or bad login information?\n");
}
my @semmatch = ($agent->content =~ m@(?:(.*?
.*?.*?)(?:TERM GPA|START OF).*?){$semester}@si);
my @grades;
my @nogrades;
my $count;
my @matches;
for ($count=1; $count <= $courses; $count++) {
@matches = ( $semmatch[0] =~ m@.*?(?:\s*| ]+>(?:]+>)?([^<]+)(?:)? | \s*]+>]+>([^<]+)(?: ]+>[^<]+)? | \s*]+>]+>([^<]+) | \s*]+>]+>([^<]+) | \s*]+>]+>([^<]+) | \s*]+>[^<]+ | \s*]+>(?:]+>)?([^<]+)(?:)? | .*?
.*?){$count}@si );
if ($matches[5] ne " ") {
$grades[$#grades+1] = " " . $matches[5] . " in " . $matches[1] . " (" . $matches[3] . ")";
}
else {
$nogrades[$#nogrades+1] = $matches[1];
}
}
$agent->get('https://poseidon.cc.mcgill.ca/pls/mcgp/twbkwbis.P_Logout');
if ($#grades >= 0) {
print "Available grades:\n" . join("\n", @grades) . "\n";
}
if ($#nogrades >= 0) {
print "Grades not available for " . join(", ", @nogrades) . ".\n";
}