#!/usr/bin/perl -w
#############################################################################
#                                                                           #
#  Ranker v1.02s this special version Copyright (c)2006 Future Publishing.  #
#            Based on Ranker by Paul Grosse All Rights Reserved.            #
#                                                                           #
#############################################################################

#use warnings;
use Tk;
use LWP::UserAgent;

&initvars;
&buildgui;

MainLoop;

##### SUBS ###################################
#
sub initvars {
  # default number of searches
  $sr = 100;
  # default search engine
  $se = 'Google';
  # default string
  $ss = "news";
  # default URL
  $url = "bbc.co.uk";
  $resultpos = "  ";
  # Set the colour scheme according to OS
  # use "xp", "98", "linux" or "default". It is case dependent but for the latter,
  # you do not need to specify anything in particular as this is a catch-all.
  $os = "xp";
  if ($os eq "xp") {
    # win xp
    ($butbg, $fbg, $tbg) = ('#ffffff', '#f7ffcb', '#ffffff');
  } elsif ($os eq "98") {
    # win 98
    ($butbg, $fbg, $tbg) = ('#000000', '#c0c0c0', '#ffffff');
  } elsif ($os eq "linux") {
    # it depends largely on what you are running so feel free to change this
    ($butbg, $fbg, $tbg) = ('#0000ff', '#e0e0e0', '#ffffff');
  } else {
    ($butbg, $fbg, $tbg) = ('#ffff00', '#e000e0', '#00ff88');
  }
}

sub buildgui {
  $mw = MainWindow -> new(-bd => "10");
  $mw -> title("Site Ranker");
  $mw -> setPalette($fbg);
  $mw -> appname("SiteRanker");
  $mw -> resizable(0,0);
  $f1 = $mw->Frame->pack(-fill => 'x');
  $lf1 = $f1->Frame()->pack(-anchor => 'nw');
    $lf1->Label(-text => "Search engine: ")->pack(-side => 'left');
  foreach (qw/Google Yahoo/){
    $lf1->Radiobutton(-text => $_,
               -selectcolor => $butbg,
                  -variable => \$se,
                     -value => $_)->pack(-side => 'left');
  }
  $lf2 = $f1->Frame()->pack(-anchor => 'sw');
    $lf2->Label(-text => "Range to request:")->pack(-side => 'left');
  foreach (qw/100 50 10/){
    $lf2->Radiobutton(-text => $_,
               -selectcolor => $butbg,
                  -variable => \$sr,
                     -value => $_)->pack(-side => "left");
  }
  $f3 = $mw->Frame()->pack;
    $f3->Label(-text => "Search string to send:")->pack(-anchor => 'nw');
    $f3->Entry(-textvariable => \$ss,
                         -bg => $tbg,
                      -width => 40)->pack;
  $f4 = $mw->Frame()->pack;
    $f4->Label(-text => "Site or string to locate in results:")->pack(-anchor => 'nw');
    $f4->Entry(-textvariable => \$url,
                         -bg => $tbg,
                      -width => 40)->pack;
  $mw -> Button(-text => "Search",
             -command => \&gosearch)->pack(-anchor => 'e');
  $f5 = $mw->Frame()->pack;
    $f5->Label(-text => "Ranking:")->pack(-anchor => 'nw');
    $f5->Label(-textvariable => \$resultpos,
                      -width => 40,
                     -height => 2,
                         -bd => 2,
                     -relief => "groove")->pack;
  $mw -> Button(-text => "Exit",
             -command => sub {exit(0)})->pack(-anchor => 'e');
}

sub gosearch {
  if (length($ss) == 0) {return};
  if (length($url) == 0) {return};
  # build a URL for the search engine
  $ssp = $ss;
  $ssp =~ s/^\s+//;
  $ssp =~ s/\s+$//;
  if (length($ssp) == 0) {return};
  $ssp =~ s/\s+/+/g;
  my $send;
  if ($se eq 'Google') {
    $send = "http://www.google.com/search?num=".$sr."&hl=en&lr=&ie=ISO-8859-1&q=".$ssp."&btnG=Search"
  } elsif ($se eq 'Yahoo') {
    $send = "http://search.yahoo.com/search?ei=UTF-8&fr=sfp&p=".$ssp."&n=".$sr
  }
  my $ua = LWP::UserAgent->new();
  $ua->agent("Mozilla/5.0 (compatible; Konqueror/3.0-rc6; i686 Linux; 20021020)");
  $resultpos = "Sending Request";
  $f5 -> update;
  my $response = $ua->get($send, Referer => "http://graphite.local/");    #
  if ($response->is_error()) {                                            #
    #error code in here
    $resultpos = "Error";
    $f5 -> update;
  } else {                                                                #
    #success
    $content = $response->content();            #### unrem this line and those above
    $resultpos = "Processing";
    $f5 -> update;
    #remove line breaks
    $content =~ s/\n/ /g;
    #Now, analyse the content
    # we need to know how far down the list our site is.
    # our site is in $url
    if ($se eq 'Google') {
      # first, find out how many this is of
      # this is the string...
      # Results <b>1</b> - <b>100</b> of about <b>624,000</b> for
      $score = undef;
      $content =~ m/Results.*?of.*?b>(\d*,?\d*,?\d*,?\d+)<\/b> for/i;
      $score = $1;
      if (defined($score)) {
        $score = " of ".$score;
      } else {
        $score = ""
      };
      # Google uses '<p class=g>' for its lines
      #remove the beginning of the page so that we are close to the first
      $content =~ s/.*?<p class=g>/<p class=g>/;
      my ($c, $gotit) = (0, 0);
      while (($content =~ m/<p class=g>.*<p class=g>/) and ($c <= $sr)) {
        $content =~ s/(<p class=g>.*?)<p class=g>/<p class=g>/;
        $next_item = $1;
        $c++;
        if ($next_item =~ m/$url/i) {
          # got it.
          $gotit = 1;
          $resultpos = "$url\n ranked in position $c$score.";
          last;
        }
      }
      unless ($gotit) {
        #there is no <p class=g> following the last item in the search so use the end tag
        # of the ordered list instead.
        $content =~ s/(<p class=g>.*?)Result\&nbsp;Page://;
        $next_item = $1;
        $c++;
        if ($next_item =~ m/$url/i) {
          # got it.
          $gotit = 1;
          $resultpos = "$url\n ranked in position $c$score.";
        }
      }
      unless ($gotit) {
        $resultpos = "$url\n not found in top $sr.";
      }

    } elsif ($se eq 'Yahoo') {
      # first, find out how many this is of
      # this is the string...
      # Search Results</h1><p>Results <strong>1 - 10</strong> of about <strong>16,300</strong> for
      $score = undef;
      $content =~ m/Results.*?of.*?g>(\d*,?\d*,?\d*,?\d+)<\/strong> for/i;
      $score = $1;
      if (defined($score)) {
        $score = " of ".$score;
      } else {
        $score = ""
      };
      #remove the beginning of the page so that we are close to the first
      # Yahoo uses an ordered list so just look for that...
      $content =~ s/.*<ol start//;
      #now get to the beginning of the list
      $content =~ s/.*?<li/<li/;
      my ($c, $gotit) = (0, 0);
      while (($content =~ m/<li.*?<li/) and ($c <= $sr)) {
        $content =~ s/(<li.*?)<li/<li/;
        $next_item = $1;
        $c++;
        if ($next_item =~ m/$url/i) {
          # got it.
          $gotit = 1;
          $resultpos = "$url\n ranked in position $c$score.";
          last;
        }
      }
      unless ($gotit) {
        #there is no <li> following the last item in the search so use the end tag
        # of the ordered list instead.
        $content =~ s/(<li.*?)<\/ol//;
        $next_item = $1;
        $c++;
        if ($next_item =~ m/$url/i) {
          # got it.
          $gotit = 1;
          $resultpos = "$url\n ranked in position $c$score.";
        }
      }
      unless ($gotit) {
        $resultpos = "$url\n not found in top $sr.";
      }
    }
  }
}
