#!/usr/bin/perl
##############################################################################
# ReadAntville.pl     
# 
# Skript zum Lesen eines Anville-Blogs ueber HTTP und
# Auslesen der Artikel mit Speicherung in einer RSS2.0-Datei
# 
# Copyright (C)  2006 Wolfgang Wiese,
#       EMail: xwolf@xwolf.de 
#       URL  : http://www.xwolf.de 
#
# ReadAntville ist freie Software; Sie durfen sie unter den Bedingungen der 
# GNU Lesser General Public License, wie von der Free Software Foundation 
# veroffentlicht, weiterverteilen und/oder modifizieren; entweder gema? 
# Version 2.1 der Lizenz oder (nach Ihrer Option) jeder spateren Version.
#
# ReadAntville wird in der Hoffnung weiterverbreitet, da? sie nutzlich 
# sein wird, jedoch OHNE IRGENDEINE GARANTIE, auch ohne die implizierte Garantie 
# der MARKTREIFE oder der VERWENDBARKEIT FUR EINEN BESTIMMTEN ZWECK. Mehr Details 
# finden Sie in der GNU Lesser General Public License.
#
# Sie sollten eine Kopie der GNU Lesser General Public License zusammen mit 
# dieser Bibliothek/diesem Programm erhalten haben; falls nicht, schreiben Sie 
# an die Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
# MA 02111-1307, USA.
#
##############################################################################
# In den Einstellungen des Blogs muss die SPrache auf Englisch (UK)
# gestellt werden. Dies ist wichtig, damit das Datum das richtige (englische) 
# Fomat hat.
# Einige Importroutinen von anderen Blogs, z.B. Wordpress, koennen
# deutsche Datumsangaben nicht erkennen und interpretieren...
# Ausserdem empfiehlt es sich bei der Einstellung "Days on front page:"
# eine hoehere Zahl als 3 einzustellen. Zum Beispiel 10.
#
# Die Storyskins (Skin 'Story display') sollten wie folgt aussehen:

# <div class="storyTitle"><% story.content part="title" %></div>
# <div class="storyTopic"><% story.topic as="text" %></div>
# <div class="storyDate"><% story.createtime  format="EEE, d MMM yyyy HH:mm:ss Z" %></div>
# 
# <div><% story.content part="text" %></div>
#

# und der Skin 'Full story view' sollte so aussehen:

#
#   <% story.skin name="dayheader" %>
#  <% story.skin name="display" %>
# 
#  <p class="small"><% story.commentlink prefix="...&nbsp;" %><% story.editlink prefix="&nbsp;&nbsp;...&nbsp;" %><% story.onlinelink prefix="&nbsp;&nbsp;...&nbsp;" %></p>

#  
##############################################################################



my $referer ="http://www.blogger.de";
my $file_artikelindex = "artikelindex.txt";
my $file_artikelitems = "artikelitems.xml";
my $NEXTPAGE;
my %ARTIKELURL;
my $STORYNUM;
my $ASKORWAIT = 2;
  # Bei 1 wird gefragt ob die naechste Seite analysiert wird und man muss
  # jeweils bestateigen
  # Bei 2 wird jeweils 1 Sekunde gewartet
##############################################################################
use LWP::UserAgent;
use HTTP::Headers;
use HTML::Parser;

no warnings;
my $url = $ARGV[0];;


$header = HTTP::Headers->new;
# (
 #      Date         => 'Thu, 03 Feb 1994 00:00:00 GMT',
 #      Content_Type => 'text/html; version=3.2',
 #      Content_Base => 'http://www.perl.org/');


$header->referer($referer);
# $header->authorization_basic($user, $pass);



print "Menu\n";
print "\t[1] Index aller Artikel lesen\n";
print "\t[2] Einzelnen Artikel lesen\n";

print "\nBitte waehlen: ";
my $wahl = <STDIN>;
chomp($wahl);

if ($wahl eq "1") {
  @artikelliste = GetIndex();
  if (@artikelliste) {
    my $i;
    open(f1,">$file_artikelindex");
    for ($i=0; $i<=$#artikelliste; $i++) {
      print f1 "$artikelliste[$i]\n";
    }
    close f1;
    open(f1,">>global-$file_artikelindex");
    foreach $key (keys %ARTIKELURL) {
      print f1 "$key\n";
    }
    close f1;
  } else {
    print "Keine Artikel gefunden.\n";
  }
} elsif ($wahl eq "2") {
  my $fertig = 0;
  while(not $fertig) {
    print "\nArtikel: (URL oder q fuer Ende) ";
    $url = <STDIN>;
    chomp($url);

    if ($url eq "q") {
        $fertig =1;
      exit;
    } elsif ($url =~ /^http/i) {
        GetArtikel($url);
    }
  }
}
print "Ich hab fertig\n";

exit;
##########################################################
sub GetIndex {
  
  print "Start-URL: ";
  my $starturl = <STDIN>;
  chomp($starturl);
  return if not ($starturl);
  my $thisurl;
  my @liste;
  
  print "Parse und speichere Artikel dabei ? ";
  my $saveart = <STDIN>;
  chomp($saveart);
  my $fname = $starturl;
  my $rssname;
  $fname =~ s/^[htps]+:\/\///gi;
  $fname =~ s/[^a-z0-9\.\-_]+//gi;
  $rssname = $fname.".xml";
  $fname .= "-items.xml";
  
  $file_artikelitems = $fname if ($fname);
  

  $NEXTPAGE = $starturl;
  my $next;
  my @resultliste;
  my $i;
  while($NEXTPAGE) {
     $thisurl = $NEXTPAGE; 
     $NEXTPAGE = ""; 
    @liste = GetPageIndex($thisurl,$saveart);
    if (not @resultliste) {
      @resultliste = @liste;
    } else {
      for ($i=0; $i<=$#liste; $i++) {
        push(@resultliste, $liste[$i]);
      }
    }
    if  ($NEXTPAGE) {
      if ($ASKORWAIT==1) {
        print "Naechste Seite ($NEXTPAGE)...\n";    
        $next = <STDIN>;
      } else {
        sleep(1);
      }
    }  
  }
  if ($saveart) {
    print "Blogtitle: ";
    my $blogtitle = <STDIN>;
    chomp($blogtitle);
    print "Kurzbeschreibung: ";
    my $kurzbesch = <STDIN>;
    chomp($kurzbesch);
    open(f1,">$rssname");
    print f1 "<?xml version=\"1.0\"?>\n";
    print f1 "<rss version=\"2.0\">\n";
    print f1 "<channel>\n";
      print f1 "<title>$blogtitle</title>\n";
      print f1 "<link>$starturl</link>\n";
      print f1 "<description>$kurzbesch</description>\n";
      print f1 "<language>de-DE</language>\n";
      print f1 "<generator>Antville2Rss2.0 Export</generator>\n";
      
      open(f2,"<$file_artikelitems");
        while(<f2>) {
          chomp($_);
          print f1 "\t$_\n";
        }
      close f2;
      print f1 "</channel>\n";
      print f1 "</rss>\n";
    close f1;
    print "RSS-Datei $rssname angelegt.\n";
  }
  return @resultliste;
  
}
##########################################################
sub GetPageIndex {
  my $indexurl = shift;
  my $save = shift;
  return if (not $indexurl);
  local $result;
  my $ua= new LWP::UserAgent;
  $ua->default_headers( $header );

  
  local $shtml;
  local %inside = {};

  local @linkliste;
  local @nextliste;
  local %madeliste;
  local $artikel;
  local %contentinside = {};
  local $opendivs = 0;
  $STORYNUM = 0;
  print "\tLese $indexurl";
  local $request = new HTTP::Request('GET',$indexurl);
  local $response = $ua->request($request);

  if ($response->is_success) {
     $content = $response->content;  # or whatever
  }

   if (not $content) {
        print "Kein Content erhalten\n";
        return;
  }
 
  
  $shtml = HTML::Parser->new(api_version   => 3,
                                handlers    => [
                                                start => [\&tag, "tagname, tokenpos, text, attr,line"],
                                                end   => [\&endtag, "tagname, attr, text, line"],
                                                text  => [\&text, "text, line"],
                                        ],
                                marked_sections => 1,

                        );
  $shtml->parse($content);
  $shtml->DESTROY;
  

  print "\tdone\n";
  local $num = scalar(@linkliste);
  print "\t -> $num Artikel\n";
  if ($save) {
    
    open(f1,">>$file_artikelitems");
        my $key;
        foreach $key (sort {$a <=> $b} keys %{$result}) {
          next if (not $result->{$key}{'storyTitle'});
          print f1 "<item>\n";
          print f1 "\t<title>$result->{$key}{'storyTitle'}</title>\n";
          print f1 "\t<link>$result->{$key}{'storylink'}</link>\n";
          print f1 "\t<guid>$result->{$key}{'storylink'}</guid>\n";
          print f1 "\t<category>$result->{$key}{'storyTopic'}</category>\n" if ($result->{$key}{'storyTopic'});
          print f1 "\t<pubDate>$result->{$key}{'storyDate'}</pubDate>\n";
          print f1 "\t<description>$result->{$key}{'story'}</description>\n";
          print f1 "\t<content:encoded>$result->{$key}{'storyhtml'}</content:encoded>\n";
          print f1 "</item>\n";
        }
    close f1;
  }
  return @linkliste;

  ############################################
  sub tag {
    my $tag = shift;
    my $pos = shift;
    my $text = shift;
    my $attribute = shift;
    my $line = shift;
    $inside{$tag} += 1;
    
    if ($tag eq "a") {
      $currentlink = $attribute->{'href'};  
    }
    if (($contentinside{'content'}) && ($contentinside{'story'})) {
        $result->{$STORYNUM}{'storyhtml'} .= $text;
    }       
    if (lc($tag) eq "div") {
      $opendivs++;
      if ($attribute->{'class'} eq "content") {          
          $contentinside{'content'} = $opendivs;          
      }
       if ($attribute->{'class'} eq "dayHeader") {
          $contentinside{'dayHeader'} = $opendivs;
      }
      if ($attribute->{'class'} eq "storyTitle") {
          $contentinside{'storyTitle'} = $opendivs;
           
          if ($lastcurrentlink) {           
            $result->{$STORYNUM}{'storylink'} = $lastcurrentlink;
          }
          $STORYNUM++;
      }
      if ($attribute->{'class'} eq "storyDate") {
          $contentinside{'storyDate'} = $opendivs;
      }
      if ($attribute->{'class'} eq "storyTopic") {
          $contentinside{'storyTopic'} = $opendivs;
      }      
      if (($contentinside{'content'}) && (not $attribute->{'class'}) && (($contentinside{'content'}+1) == $opendivs)) {
        $contentinside{'story'} = $opendivs;
      }   
    }
    return;
  }
  sub endtag {
      my $tag = shift;
      my $attribute = shift; 
      my $text = shift;
      my $line = shift;
       
      $inside{$tag} -= 1;
    if ($tag eq "a") {
      $currentlink = "";  
    }
      if ((lc($tag) eq "div") && ($contentinside{'content'}  == $opendivs)) {
          $contentinside{'content'} =0;          
      }
      if ((lc($tag) eq "div") && ($contentinside{'dayHeader'}  == $opendivs)) {
          $contentinside{'dayHeader'} =0;
      }
      if ((lc($tag) eq "div") && ($contentinside{'storyTitle'}  == $opendivs)) {
          $contentinside{'storyTitle'} =0;
      }
      if ((lc($tag) eq "div") && ($contentinside{'storyDate'}  == $opendivs)) {
          $contentinside{'storyDate'} =0;
      }
      if ((lc($tag) eq "div") && ($contentinside{'storyTopic'}  == $opendivs)) {
          $contentinside{'storyTopic'} =0;
      }
      if ((lc($tag) eq "div") && ($contentinside{'story'}  == $opendivs)) {
          $contentinside{'story'} =0;          
      }
      if (lc($tag) eq "div") {
          $opendivs--;
      } 
      if (($contentinside{'content'}) && ($contentinside{'story'})) {
        $result->{$STORYNUM}{'storyhtml'} .= $text;
      }

      
  }
  sub text {
      my $text = shift;     
      my $line = shift;
                       
      if (($inside{'p'}) && ($inside{'a'}) && ($text =~ /^link$/i)) {
        push(@linkliste, $currentlink);
        $ARTIKELURL{$currentlink} = 1;
        $lastcurrentlink = $currentlink;
      #  print "Found link $currentlink\n";
      }
      if (($inside{'div'}) && ($inside{'a'}) && ($text =~ /^older stories$/i)) {
          $NEXTPAGE = $currentlink;
  #        print "Found Next page: $currentlink\n";
      }  
      if ($inside{'title'}) {
        $result->{$STORYNUM}{'title'} = $text;
      }

      if (($contentinside{'content'}) && ($contentinside{'storyTitle'})) {
        $result->{$STORYNUM}{'storyTitle'} = $text;
      }
      if (($contentinside{'content'}) && ($contentinside{'storyDate'})) {
        $result->{$STORYNUM}{'storyDate'} = $text;
      }
      if (($contentinside{'content'}) && ($contentinside{'storyTopic'})) {
        $result->{$STORYNUM}{'storyTopic'} = $text;
      }
      if (($contentinside{'content'}) && ($contentinside{'story'})) {
        $result->{$STORYNUM}{'story'} .= $text;
        $result->{$STORYNUM}{'storyhtml'} .= $text;
      }     
}
  # <div class="pagelinkBottom">...&nbsp;<a href="http://xwolf.blogger.de/?day=20060404">older stories</a></div>
  
}
##########################################################
sub GetArtikel {
   my $thisurl = shift;
   my $result;
   
  if (not $thisurl)  {
    return;
  }

  local $ua= new LWP::UserAgent;
  $ua->default_headers( $header );

  
  local $request = new HTTP::Request('GET',$url);
  local $response = $ua->request($request);

  if ($response->is_success) {
     $content = $response->content;  # or whatever
  }

   if (not $content) {
        print "Kein Content erhalten\n";
        return;
  }
  local $shtml;
  local %inside = {};
  local %contentinside = {};
  local $opendivs = 0;
  $shtml = HTML::Parser->new(api_version   => 3,
                                handlers    => [
                                                start => [\&stag, "tagname, tokenpos, text, attr,line"],
                                                end   => [\&sendtag, "tagname, attr, text, line"],
                                                text  => [\&stext, "text, line"],
                                        ],
                                marked_sections => 1,

                        );
        $shtml->eof;
        $shtml->parse($content);


   my $key;
   print "Parsing abgeschlossen.\n";
  foreach $key (keys %{$result}) {
      print "$key\n\t$result->{$key}\n";    
  }  

   return $result;

  sub stag {
    my $tag = shift;
    my $pos = shift;
    my $text = shift;
    my $attribute = shift;
    my $line = shift;
    $inside{$tag} += 1;
    
    if (($contentinside{'content'}) && ($contentinside{'story'})) {
        $result->{'storyhtml'} .= $text;
    }       
    if (lc($tag) eq "div") {
      $opendivs++;
      if ($attribute->{'class'} eq "content") {
          $contentinside{'content'} = $opendivs;
      }
       if ($attribute->{'class'} eq "dayHeader") {
          $contentinside{'dayHeader'} = $opendivs;
      }
      if ($attribute->{'class'} eq "storyTitle") {
          $contentinside{'storyTitle'} = $opendivs;
      }
      if ($attribute->{'class'} eq "storyDate") {
          $contentinside{'storyDate'} = $opendivs;
      }
      if ($attribute->{'class'} eq "storyTopic") {
          $contentinside{'storyTopic'} = $opendivs;
      }      
      if (($contentinside{'content'}) && (not $attribute->{'class'}) && (($contentinside{'content'}+1) == $opendivs)) {
        $contentinside{'story'} = $opendivs;
      }   
    }
    return;
  }
  sub sendtag {
      my $tag = shift;
      my $attribute = shift; 
      my $text = shift;
      my $line = shift;
       
      $inside{$tag} -= 1;
      
      if ((lc($tag) eq "div") && ($contentinside{'content'}  == $opendivs)) {
          $contentinside{'content'} =0;
      }
      if ((lc($tag) eq "div") && ($contentinside{'dayHeader'}  == $opendivs)) {
          $contentinside{'dayHeader'} =0;
      }
      if ((lc($tag) eq "div") && ($contentinside{'storyTitle'}  == $opendivs)) {
          $contentinside{'storyTitle'} =0;
      }
      if ((lc($tag) eq "div") && ($contentinside{'storyDate'}  == $opendivs)) {
          $contentinside{'storyDate'} =0;
      }
      if ((lc($tag) eq "div") && ($contentinside{'storyTopic'}  == $opendivs)) {
          $contentinside{'storyTopic'} =0;
      }
      if ((lc($tag) eq "div") && ($contentinside{'story'}  == $opendivs)) {
          $contentinside{'story'} =0;
      }
      if (lc($tag) eq "div") {
          $opendivs--;
      } 
      if (($contentinside{'content'}) && ($contentinside{'story'})) {
        $result->{'storyhtml'} .= $text;
      }
  }
  sub stext {
      my $text = shift;
     
      my $line = shift;
                       
      if ($inside{'title'}) {
        $result->{'title'} = $text;
      }
      if (($contentinside{'content'}) && ($contentinside{'dayHeader'})) {
        $result->{'dayHeader'} = $text;
      }
      if (($contentinside{'content'}) && ($contentinside{'storyTitle'})) {
        $result->{'storyTitle'} = $text;
      }
      if (($contentinside{'content'}) && ($contentinside{'storyDate'})) {
        $result->{'storyDate'} = $text;
      }
      if (($contentinside{'content'}) && ($contentinside{'storyTopic'})) {
        $result->{'storyTopic'} = $text;
      }
      if (($contentinside{'content'}) && ($contentinside{'story'})) {
        $result->{'story'} = $text;
        $result->{'storyhtml'} .= $text;
      }
  }

}


