Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Automatically check jury duty on-call status
#!/usr/bin/env perl
#
# A simple script to repeatedly check on-call status for United States
# District Court juror instructions. It will send mail with any instructions
# and, if necessary, schedule itself to check again when instructed.
#
# Usage: /path/to/jury-mojo.pl PARTICIPANT_ID ZIP_CODE
use 5.012;
use Mojo::UserAgent;
use DateTime::Format::DateParse;
use Email::Simple;
use Email::Sender::Simple qw( sendmail );
my $email = Email::Simple->create(
header => [
To => '"Me" <me@example.com>',
From => '"Me Too" <me@example.com>',
],
);
# Safety first!
$SIG{'__DIE__'} = sub {
$email->header_set( 'Subject' => 'Jury Check: Died' );
$email->body_set( $_[0] );
sendmail($email);
die @_;
};
my $ua = Mojo::UserAgent->new;
my $url = 'http://jury.casd.uscourts.gov/AppearWeb/Default.aspx';
my $res = $ua->get($url)->res; # initial fetch to get cookie and form fields
my $tx = $ua->max_redirects(3)->post_form(
$url => {
'__VIEWSTATE' => $res->dom('form#Form1 > input#__VIEWSTATE')->[0]->attrs('value'),
'__EVENTVALIDATION' => $res->dom('form#Form1 > input#__EVENTVALIDATION')->[0]->attrs('value'),
'ctl02$txtPart' => $ARGV[0],
'ctl02$txtZip' => $ARGV[1],
'ctl02$btnInstructions' => 'Reporting Instructions',
}
);
$res = $tx->success or die $tx->error;
# This is what the response message looks like in the HTML:
# <span id="ctl02_lblMsg">Please check again Sunday, April 29, after 6:00pm for further reporting instructions. Do NOT report at this time.</span>
my $message = $res->dom('span#ctl02_lblMsg')->[0]->text;
if ( $message !~ /Do NOT report at this time/ ) {
# We didn't see the message we wanted to see, so we'd better alert.
$email->header_set( 'Subject' => 'Jury Check: You may need to report' );
$email->body_set("$message\n");
sendmail($email);
exit;
}
if ( $message !~ /Please check again (?<weekday>\w+), (?<month>\w+) (?<day>\d+)/ ) {
# We couldn't parse the next date to check, so we'd better alert.
$email->header_set( 'Subject' => 'Jury Check: Failed to parse date' );
$email->body_set("$message\n");
sendmail($email);
exit;
}
my $dt = DateTime::Format::DateParse->parse_datetime("$+{'weekday'}, $+{'day'} $+{'month'} 18:15");
# Set up an at(1) job for the next time we need to check. The jury
# instructions are always updated at 18:00, so we're hard-coding that bit with
# a buffer.
open my $at, '|-', 'at', $dt->strftime('%R'), $dt->strftime('%F') or die "at: $!";
say {$at} "$0 @ARGV 2>/dev/null"; # $0 must be fully qualified or in PATH
close $at;
# We should alert anyway, just in case things didn't work out quite right.
$email->header_set( 'Subject' => 'Jury Check: Do NOT report at this time' );
$email->body_set( sprintf "%s\n\nNext check scheduled for %s.\n", $message, $dt->strftime('%c') );
sendmail($email);
#!/usr/bin/env perl
#
# A simple script to repeatedly check on-call status for United States
# District Court juror instructions. It will send mail with any instructions
# and, if necessary, schedule itself to check again when instructed.
#
# Usage: /path/to/jury.pl PARTICIPANT_ID ZIP_CODE
use 5.012;
use WWW::Scripter; # h/t cpansprout (https://gist.github.com/2522558#gistcomment-292147)
use DateTime::Format::DateParse;
use Email::Simple;
use Email::Sender::Simple qw( sendmail );
my $email = Email::Simple->create(
header => [
To => '"Me" <me@example.com>',
From => '"Me Too" <me@example.com>',
],
);
# Safety first!
$SIG{'__DIE__'} = sub {
$email->header_set( 'Subject' => 'Jury Check: Died' );
$email->body_set( $_[0] );
sendmail($email);
die @_;
};
# This may only work for the Southern District of California.
my $mech = WWW::Scripter->new();
$mech->get('http://jury.casd.uscourts.gov/AppearWeb/Default.aspx');
$mech->submit_form(
form_name => 'Form1',
fields => {
'ctl02$txtPart' => $ARGV[0],
'ctl02$txtZip' => $ARGV[1],
},
button => 'ctl02$btnInstructions',
);
# This is what the response message looks like in the HTML:
# <span id="ctl02_lblMsg">Please check again Sunday, April 29, after 6:00pm for further reporting instructions. Do NOT report at this time.</span>
my $message = $mech->document->getElementById('ctl02_lblMsg')->innerHTML;
if ( $message !~ /Do NOT report at this time/ ) {
# We didn't see the message we wanted to see, so we'd better alert.
$email->header_set( 'Subject' => 'Jury Check: You may need to report' );
$email->body_set("$message\n");
sendmail($email);
exit;
}
if ( $message !~ /Please check again (?<weekday>\w+), (?<month>\w+) (?<day>\d+)/ ) {
# We couldn't parse the next date to check, so we'd better alert.
$email->header_set( 'Subject' => 'Jury Check: Failed to parse date' );
$email->body_set("$message\n");
sendmail($email);
exit;
}
my $dt = DateTime::Format::DateParse->parse_datetime("$+{'weekday'}, $+{'day'} $+{'month'} 18:15");
# Set up an at(1) job for the next time we need to check. The jury
# instructions are always updated at 18:00, so we're hard-coding that bit with
# a buffer.
open my $at, '|-', 'at', $dt->strftime('%R'), $dt->strftime('%F') or die "at: $!";
say {$at} "$0 @ARGV 2>/dev/null"; # $0 must be fully qualified or in PATH
close $at;
# We should alert anyway, just in case things didn't work out quite right.
$email->header_set( 'Subject' => 'Jury Check: Do NOT report at this time' );
$email->body_set( sprintf "%s\n\nNext check scheduled for %s.\n", $message, $dt->strftime('%c') );
sendmail($email);
@cpansprout

Instead of

$dom->parse_file( IO::Scalar->new( do { my $c = $mech->content; \$c } ) );

you could write simply

$dom->write($mech->content);
$dom->close;

Alternatively, you could s/WWW::Mechanize/WWW::Scripter/ and write

my $message = $mech->document->getElementById('ctl02_lblMsg')->innerHTML;

WWW::Scripter, a subclass of WWW::Mechanize, is HTML::DOM’s raison d’être

@sirhc
Owner

Oh, that's excellent. As I was working on a version using Mojo::UserAgent (as someone recommended I try), I found myself thinking, "It would be awesome if WWW::Mechanize gave me access to the document with HTML::DOM." Thanks for the pointer to the module that filled exactly that need.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.