What is StudWeb?
When you study at universities or university colleges in Norway, you have to use a forsaken beast called StudWeb to check for your grades. This is OK by itself, but it’s getting tedious when you wait for your last grade to show up.
During the past weeks, I’m sure I’ve thrown several hours into opening www.studweb.no (yes, they don’t have an alias on studweb.no, so you have to enter www first), logging in, checking for the grade and confirming that it hasn’t shown up yet.
Come automation
Since I started working again this Wednesday, I simply couldn’t spend this amount of time into something as trivial. Thus, I automated the process through a Perl script utilizing the WWW::Mechanize module. The script runs a reload of the website every 30 seconds. This bypasses the session time to live, thus causing the script to being able to run on a single login more or less forever.
Initially I wanted to simply play a sound or some music when the grade had arrived, but that would imply that I had to be by my computer all the time, so if I went to lunch or to the bathroom, I wouldn’t notice that the grade had arrived. Instead, using Mail::Sendmail I could rather send myself an e-mail that I would be able to get at any given point in time since I always carry my phone with me.
The code
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use Getopt::Long;
use Mail::Sendmail;
use WWW::Mechanize;
my $mech = WWW::Mechanize->new;
GetOptions(
'username:s' => \my $username,
'password:s' => \my $password,
'threshold:i' => \my $threshold,
'email:s' => \my $email,
'smtp:s' => \my $smtp,
);
if (!$username || !$password || !$threshold) {
die 'Usage: ./studweb --username s12345 --password lolpasswd --threshold 160 [--email s12345@student.hio.no --smtp smtp.myisp.com]';
}
# Get main page
$mech->get('https://www.studweb.no/as/WebObjects/studentweb2?inst=HiO');
# Go to login form
$mech->submit_form( form_name => 'feideForm' );
# Set HiO as login form and login
$mech->submit_form( fields => { org => 'hio.no' } );
$mech->submit_form( fields => { feidename => $username, password => $password } );
# Bypass JavaScript
$mech->submit_form();
# Go to innsyn
$mech->follow_link( text_regex => qr/Innsyn/ );
# Go to resultater
$mech->follow_link( text_regex => qr/Resultater/ );
my $last = q();
while (1) {
my $current = q();
my $date = `date +%H:%M:%S`;
chomp($date);
my ($table) = $mech->content =~ m{<table cellspacing="2" cellpadding="2" width="95%" border="0">(.*?)</table>}msi;
my (@tr) = $table =~ m{<tr.*?>(.*?)</tr>}msig;
for (@tr) {
if ($_ !~ m{class="sum-r"}) {
my (@td) = $_ =~ m{<td.*?>(.*?)</td>}msig;
next if scalar @td < 11;
$current .= sprintf "%s: %s\n", $td[2], $td[7];
} else {
my ($sum) = $_ =~ m{<td class="sum-r">(\d+),0</td>}msi;
$current .= sprintf "Sum: %s\n", $sum;
if ($sum >= $threshold) {
if (defined $email && defined $smtp) {
sendmail( To => $email,
From => $email,
Subject => 'Grade from StudWeb',
Message => $current,
smtp => $smtp);
}
print $current;
exit;
}
}
}
print $date;
if ($current ne $last) {
print "\n$current";
$last = $current;
} else {
print ": No change";
}
print "\n";
sleep(30);
$mech->reload;
}