#!/usr/bin/perl
######################################################################
# (c) Michael Schilli 1999
######################################################################
###############################################################
use Getopt::Std;            # Kommandozeilen-Parameter-Erfasser
use LWP::UserAgent;         # WWW-Utility
use HTML::TreeBuilder;      # HTML-Parser
use Archive::Tar;           # Tar-Archivierer
use URI::URL;               # URLs manipulieren

                            # Meldungs-Funktionen definieren
sub info { print STDERR @_ if $opt{v};} # Ausgabe Verbose-Modus   
sub err  { print STDERR @_; }           # Fehler-Ausgabe

getopts("ef:ght:v", \%opt); # Kommandozeilen-Parameter erfassen
usage() if(defined $opt{h});  # Help-Option gesetzt?
                              # Ohne Extract oder Get -> Fehler
usage() unless grep {defined} ($opt{e}, $opt{g});

                              # Tar-Objekt erzeugen
my $tar = Archive::Tar->new() if $opt{t};

if(defined $opt{f}) {         # URLs aus einer Datei holen ...
  push(@ARGV, $opt{f});       # Datei einfach an die
                              # Kommandozeile anhängen.
  while(<>) { chop; push(@urls, $_); }
} else {                      # ... oder URLs von der 
                              #     Kommandozeile
  push(@urls, @ARGV) || usage();
}
                              # Alle URLs stehen jetzt 
foreach $url (@urls) {        # in @urls
  info "# GET URL $url ... "; # Meldung

  $ua = LWP::UserAgent->new();      # User-Agent erzeugen

                                    # Request erzeugen
  $request = HTTP::Request->new('GET', $url);
                                    # Netzzugriff ausführen
  $response = $ua->request($request);         

  if($response->is_error) {         # Fehlerprüfung 
      err "ERROR Code: ", $response->code(), 
	    " Message: ", $response->message(), "\n";
  }

  $doc = $response->content();      # Dokument OK
  info "OK\n";
                                    # Mit gesetzter -t Option:
  if($opt{t}) {                     # nicht ausgeben => tarfile
    my $path = URI::URL->new($url)->path;        # Pfad aus URL
    $path =~ s,/$,/index.html,g;       # Ohne Dateinamen -> 
                                       # index.html
    $path =~ s,^/,,g;                  # Führende '/' entfernen
    $tar->add_data($path, $doc);       # Daten ins Archiv
    next;                              # Nächste URL bearbeiten
  }

  if($opt{g}) { print "$doc"; next; }  # Ohne -t Option Doku-
                                       # ment einfach ausgeben

                                       # Links extrahieren
  my $tree = HTML::TreeBuilder->new->parse($doc);

                                       # <A>, <AREA> und <IMG>
  for (@{$tree->extract_links(qw/a area img/)}) {
    my $l = URI::URL->new($_->[0]);    # href-Attribut
    ($s = $l->abs($url)) =~ s/#.*//g;  # URL absolut, #.. raus
     print "$s\n" unless $links{$l}++; # Ausgeben falls neu
  }

  $tree->delete();                     # Parse-Baum löschen
}

if($opt{t}) {
  $tar->write($opt{t});                # Tarfile erzeugen
  info "$opt{t} ready.\n";             # Info im verbose-Mode
}

sub usage {
###############################################################
    $0 =~ s,.*/,,g;           # Pfad entfernen

    print <<EOT;
usage: $0 -g [-f URLfile] [-t tarfile] URL ...  # get URLs
       $0 -e [-f URLfile] URL ...               # extract links
options:
       -h: help
       -v: verbose
EOT
    exit 1;
}
