package WWW::eiNetwork; use strict; use warnings; use Carp; use HTML::TableContentParser; use WWW::Mechanize; our $VERSION = '0.01'; sub new { my ($class, %args) = @_; croak "You must specify your name" unless $args{name}; croak "You must specify your library card number" unless $args{card_number}; # Strip trailing slash from URL prefix my $prefix = $args{url_prefix} || ''; $prefix =~ s/\/$//; my $self = { name => $args{name}, card_number => $args{card_number}, url_prefix => $prefix || 'https://iiisy1.einetwork.net/patroninfo~S1', }; bless $self, $class; return $self; }; sub _login { my ($self, $name, $card) = @_; my $mech = WWW::Mechanize->new; $mech->get($self->{url_prefix}); $mech->form_with_fields('name', 'code'); $mech->field('name', $self->{name}); $mech->field('code', $self->{card_number}); $mech->click('submit'); my $uri = $mech->uri; if ($uri =~ /patroninfo\/(\d+)\//) { $self->{patron_id} = $1; $self->{mech} = $mech; return $self->{mech}; } else { croak "Couldn't log in to eiNetwork!"; return; } } sub holds { my ($self, %args) = @_; my @classes = ('Title', 'Status', 'Pickup', 'Cancel'); my @items = $self->_get_content( page => 'holds', classes => \@classes, html => $args{html}, ); return wantarray ? @items : \@items; } sub items { my ($self, %args) = @_; my @classes = ('Title', 'Barcode', 'Status', 'CallNo'); my @items = $self->_get_content( page => 'items', classes => \@classes, html => $args{html}, ); return wantarray ? @items : \@items; } sub _get_content { my ($self, %args) = @_; my $page = $args{page}; my $classes = $args{classes}; my $html = $args{html}; # Hack to facilitate unit tests $html ||= $self->_get_html($page); my $tables = $self->_get_tables($html); my @items; for my $table (@$tables) { next unless ($table->{class} and $table->{class} eq 'patFunc'); for my $row (@{$table->{rows}}) { next unless ($row->{class} and $row->{class} eq 'patFuncEntry'); my %record; for my $cell (@{$row->{cells}}) { for my $class (@$classes) { if ($cell->{class} and $cell->{class} eq "patFunc$class") { my $data = $self->_cleanup_data($cell->{data}); $record{lc($class)} = $data; next; } } } push @items, \%record; } } return wantarray ? @items : \@items; } sub _get_html { my ($self, $page) = @_; $self->_login or croak "Couldn't log in!"; my $mech = $self->{mech}; return unless $mech; my $patron_id = $self->{patron_id}; return unless $patron_id; my $prefix = $self->{url_prefix}; return unless $prefix; $mech->get("$prefix/$patron_id/$page"); return $mech->content; } sub _get_tables { my ($self, $html) = @_; my $tp = HTML::TableContentParser->new(); my $tables = $tp->parse($html); return $tables; } sub _cleanup_data { my ($self, $data) = @_; # If the result is a link, strip the link tags and use the title. # Not the greatest regex, but works for these simple cases. if ($data =~ /"\>\s*(.*)\s*<\/a>/m) { $data = $1; } # If the data is a select and there's something selected, use the # title of the selected option. if ($data =~ /\