Package TVTome;

use strict;
use Data::Dumper;
use Carp;
use LWP::Simple;
#use WWW::Mechanize;
use HTML::TokeParser;
use Cache::FileCache;

use constant TVTOME => 'http://www.tvtome.com/';

sub new {
    my $pkg = shift;

    my $self = bless { }, $pkg;
    $self->{_cache} = new Cache::FileCache();

    return $self;
}

{
    sub _findResults {
        my $self = shift;
        my $content = shift;
        my $parser = HTML::TokeParser->new(\$content);
    
        my ($tag, @list);
    
        while ($tag = $parser->get_token()) {
            if ($parser->get_text =~ 'Show search for') {
                while ($tag = $parser->get_tag()){
            
                    if ($tag->[0] eq 'a') {
                        my $startcrap = '<a href="';
                        my $endcrap = '">';
                        $tag->[3] =~ s/$startcrap//g;
                        $tag->[3] =~ s/$endcrap//g;
    
                        push @list, {show => $parser->get_text(), url=>$tag->[3]};
                    }
                    last if ($parser->get_text =~ /Here are some hints/);
    
                }
            }
        }
    
        return \@list;
    
    }
    
    sub _getEPs {
        my $self = shift;
        my $content = shift;
        my $parser = HTML::TokeParser->new(\$content);
    
        my ($tag, @list);
        while ($tag = $parser->get_token()) {
    
            if ($parser->get_text =~ 'Season') {
                while ($tag = $parser->get_tag('tr')){
    
                    # Episode number
                    $parser->get_tag('td');
                    my $epno = $parser->get_text;
    
                    $parser->get_tag('td');
                    my $no = $parser->get_text;
    
                    $parser->get_tag('td');
                    my $seasonep = $parser->get_text;
    
                    $parser->get_tag('td');
                    my $airdate = $parser->get_text;
    
                    my $tag = $parser->get_tag('a');
                    my $startcrap = '<a href="';
                    my $endcrap = '">';
                    $tag->[3] =~ s/$startcrap//g;
                    $tag->[3] =~ s/$endcrap//g;
        
                    my $epname = $parser->get_text;
                    my $epurl = $tag->[3];
    
                    push @list, {
                                 epno     => $epno,
                                 no       => $no,
                                 seasonep => $seasonep,
                                 airdate  => $airdate,
                                 epname   => $epname,
                                 epurl    => $epurl,
                                }
                }
             }
     
        }
    
        return \@list;
    
    }
    
    sub _getSynopsis {
        my $self = shift;
        my $content = shift;
        my $parser = HTML::TokeParser->new(\$content);
    
        my ($tag, $synopsis);
        while ($tag = $parser->get_token()) {
            if ($parser->get_text =~ 'Synopsis') {
                $parser->get_tag('tr');
                $parser->get_tag();
                $synopsis .=$parser->get_text();
                while ($tag->[0] ne 'td') {
                    $tag = $parser->get_tag();
                    my $text = $parser->get_text();
                    $synopsis .= $text if (defined $text && length($text) > 0);
                }
            }
    
        }
        return \$synopsis;
    }

    sub _getFirstAired {
        my $self = shift;
        my $content = shift;
        my $parser = HTML::TokeParser->new(\$content);

        my ($tag, $airdate);
        while ($tag = $parser->get_token()) {
            if ($parser->get_text =~ 'Show Information') {
                $parser->get_tag('tr');
                $parser->get_tag('tr');
                $parser->get_tag('tr');
                $parser->get_tag('td');
                $parser->get_tag('td');
                $airdate .=$parser->get_text()||'Unavailable';
            }

        }
        return \$airdate;

    }

    sub _getDirector {
        my $self = shift;
        my $content = shift;
        my $parser = HTML::TokeParser->new(\$content);

        my ($tag, $director);
        while ($tag = $parser->get_token()) {
            if ($parser->get_text =~ 'Show Crew') {
                $parser->get_tag('a');
                $parser->get_tag('a');
                $parser->get_tag('a');
                $director .=$parser->get_text()||'Unavailable';
            }

        }
        return \$director;

    }

    sub _getRunningTime {
        my $self = shift;
        my $content = shift;
        my $parser = HTML::TokeParser->new(\$content);

        my ($tag, $runtime);
        while ($tag = $parser->get_token()) {
            if ($parser->get_text =~ 'Show Information') {
                $parser->get_tag('tr');
                $parser->get_tag('tr');
                $parser->get_tag('tr');
                $parser->get_tag('tr');
                $parser->get_tag('tr');
                $parser->get_tag('td');
                $parser->get_tag('td');
                $runtime .=$parser->get_text()||'Unavailable';
            }

        }
        return \$runtime;

    }

    
    sub _findSingle {
        my $self = shift;
        my $content = shift;
        my $parser = HTML::TokeParser->new(\$content);
    
        my ($tag, @list);
    
        while ($tag = $parser->get_token()) {
            if ($tag->[0] eq 'S' && $tag->[1] eq 'input') {
                if ($tag->[2]->{name} =~ 'returnTo') {
                    return $tag->[2]->{value};
                }
            }
        }
     
    }

    sub _getContent {
        my $self = shift;
        my $url  = shift;
        my $content = $self->{_cache}->get($url);
        if (! defined $content) {
            $content = get($url);
            $self->{_cache}->set($url, $content, "1 hour");
        }

        return $content;

    }

}

sub find {
    my $self = shift;
    my %args = @_;

    croak "Must supply show!" unless (defined $args{show}); 

    $args{show}=~s/\s/%20/g;

    my $url = TVTOME.'tvtome/servlet/Search?searchType=show&searchString='.$args{show};

    my $content = $self->_getContent($url);

    # Attempt to autodetect the search function returning with the only series that matches
    # the serarch criteria
    if ($content =~ /Welcome to/i) {
        # there is only one match and we have dragged back the home page
        my $url = $self->_findSingle($content);    
        $args{show} =~ s/%20/ /g;
        return [{show => $args{show}, url => $url}];
    } else {
        return $self->_findResults($content);
    }
}

sub getEPList {
    my $self = shift;
    my %args = @_;

    croak "Must supply url!" unless (defined $args{url}); 

    my $url = TVTOME.$args{url}.'eplist.html';
    my $content = $self->_getContent($url)  or carp "can't connect to server";

    return $self->_getEPs($content);


}

sub getSynopsis {
    my $self = shift;
    my %args = @_;

    croak "Must supply url!" unless (defined $args{url});

    my $url = TVTOME.$args{url};
    my $content = $self->_getContent($url)  or carp "can't connect to server";

    return $self->_getSynopsis($content);

}

sub getFirstAirDate {
    my $self = shift;
    my %args = @_;

    croak "Must supply url!" unless (defined $args{url});

    my $url = TVTOME.$args{url};
    my $content = $self->_getContent($url)  or carp "can't connect to server";

    return $self->_getFirstAired($content);

}

sub getDirector {
    my $self = shift;
    my %args = @_;

    croak "Must supply url!" unless (defined $args{url});

    my $url = TVTOME.$args{url};
    my $content = $self->_getContent($url)  or carp "can't connect to server";

    return $self->_getDirector($content);

}

sub getRunningTime {
    my $self = shift;
    my %args = @_;

    croak "Must supply url!" unless (defined $args{url});

    my $url = TVTOME.$args{url};
    my $content = $self->_getContent($url)  or carp "can't connect to server";

    return $self->_getRunningTime($content);

}


1
