#!/usr/bin/perl -w
use strict;
use File::Spec;
use File::Temp;
use Net::FTP;
use Text::Template;

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

## Globalne ustawienia konfiguracyjne

## $FAV_ROOT = Pooenie korzenia folderu Ulubione
my $FAV_ROOT = File::Spec->join( $ENV{USERPROFILE}, 'Favorites' );

## $FAV_NAME = Nazwa najwyszego poziomu uywana w drzewie foldera Ulubione
my $FAV_NAME = 'Favorites';

## $FAV_TMPL = Plik Text::Template file; pliki wynikowe bd miay 
##             takie samo rozszerzenie
my $FAV_TMPL = 'favorites.tmpl.html';

## Dane serwera, na ktrym bd przez FTP publikowane zakadki
my $FAV_HOST = 'myserver.net';
my $FAV_PATH = 'favorites';
my $FAV_USER = 'uytkownik';
my $FAV_PASS = 'haso';

## Koniec konfiguracji

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

my $_FAV_TEMPDIR = File::Temp->tempdir( 'XXXXXXXX', CLEANUP => 1 );

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

sub LoadFavorites {

  # Rekurencyjnie adujemy struktur drzewa katalogw Ulubionych Internet
  # Explorera, umieszczamy j w tablicach asocjacyjnych.

  my $FolderIn = shift;      # Przetwarzany folder
  my $FavoritesOut = shift;  # Wskanik do adowania danych z folderu

  # Do tablicy wstawiamy wyniki readdir, pobierajc przez to
  # poszczeglne pozycje z katalogu.
  opendir( FOLDER, $FolderIn ) ||
    die "Niemoliwe otwarcie foldera Ulubionych '$FolderIn'";
  my @FolderEntries = readdir( FOLDER );
  closedir( FOLDER );

  # Przetwarzanie poszczeglnych pozycji z katalogu.
  foreach my $FolderEntry ( @FolderEntries ) {

    # Pomijamy nazwy specjalne, . i ..
    next if $FolderEntry eq '.' || $FolderEntry eq '..';

    # Tworzymy pen ciek dla biecej pozycji.
    my $FileSpec = File::Spec->join( $FolderIn, $FolderEntry );

    # Jeli przetwarzamy katalog, rekurencyjnie wywoujemy LoadFavorites.
    if ( -d $FileSpec && !( -l $FileSpec ) ) {
      $FavoritesOut->{$FolderEntry} = {};
      LoadFavorites( $FileSpec, $FavoritesOut->{$FolderEntry} );
    }

    # Jeli nie jest to katalog, sprawdzamy, czy nazwa pliku koczy si '.url'.
    # Po znalezieniu pliku cza pobieramy adres URL, przypisujemy mu zakadk.
    elsif ( $FolderEntry =~ /^.*\.url$/i ) {
      my ( $FavoriteId ) = $FolderEntry =~ /^(.*)\.url$/i;
      next if !open( FAVORITE, $FileSpec );
      ( $FavoritesOut->{$FavoriteId} ) =
           join( '', <FAVORITE> ) =~ /^URL=([^\n]*)\n/m;
      close( FAVORITE );
    }
  }
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

sub MakeDocName {

  # Generujemy bezpieczne nazwy plikw dla poszczeglnych pozycji z Ulubionych.
  # Wszystkie biae znaki i znaki specjalne zastpujemy podkreleniami,
  # czymy dane rodzica z danymi aktualnymi oraz cao uzupeniamy
  # o takie samo rozszerzenie, jakie mia dokument szablonu.

  my $FavoriteIn = shift;        # Oznaczamy now pozycj Ulubionych
  my $ParentFilenameIn = shift;  # MakeDocName dla poziomu rodzica

  my ( $FileType ) = $FAV_TMPL =~ /\.([^\.]+)$/;
  $FavoriteIn =~ s/(\s+|\W)/_/g;
  $ParentFilenameIn =~ s/$FileType$//;
  return lc( $ParentFilenameIn . $FavoriteIn . '.' . $FileType );
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

sub GenerateFavorites {

  # Rekurencja w drzewie Ulubionych, generowanie dokumentu na kadym poziomie
  # oparte na globalnym szablonie dokumentu.

  my $FavoritesIn = shift;       # Wskanik aktualnego poziomu drzewa
  my $FolderNameIn = shift;      # Nazwa aktualnego foldera
  my $ParentFilenameIn = shift;  # MakeDocName poziomu rodzica

  # Tworzymy skrcone identyfikatory dla czsto uywanych danych.
  my $Folder = $FavoritesIn->{$FolderNameIn};
  my $FolderFilename = MakeDocName( $FolderNameIn, $ParentFilenameIn );

  # Rozdzielamy pozycje z aktualnego foldera na foldery i cza.
  # Foldery mona wyrni po wskanikach tablic asocjacyjnych,
  # podczas gdy czom odpowiadaj zwyke skalary (adresy URL).
  my (%Folders,%Links);
  foreach my $Favorite ( keys( %{$Folder} ) ) {
    if ( ref( $Folder->{$Favorite} ) eq 'HASH' ) {
      $Folders{$Favorite} = { label => $Favorite,
        document => MakeDocName( $Favorite, $FolderFilename ) };
    }
    else {
      $Links{$Favorite}={label => $Favorite, href => $Folder->{$Favorite} };
    }
  }

  # Przygotowujemy zmienne Text::Template variables, wypeniamy szablon
  # folderami i czami na danym poziomie drzewa, nastpnie przetworzony
  # tak dokument wstawiamy do naszego foldera tymczasowego.
  my $Template = Text::Template->new( TYPE => 'FILE',
    DELIMITERS => [ '<{', '}>' ], SOURCE => $FAV_TMPL );
  my %Vars = (
    FAV_Name => $FAV_NAME,
    FAV_Home => MakeDocName( $FAV_NAME ),
    FAV_Folder => $FolderNameIn,
    FAV_Parent => $ParentFilenameIn,
    FAV_Folders => \%Folders,
    FAV_Links => \%Links
  );
  my $Document = $Template->fill_in( HASH => \%Vars );
  my $DocumentFile = File::Spec->join( $_FAV_TEMPDIR, $FolderFilename );
  if ( open( FAVORITES, ">$DocumentFile" ) ) {
    print( FAVORITES $Document );
    close( FAVORITES );
  }

  # Rekurencyjnie generujemy Ulubione dla kadego podfoldera foldera biecego.
  foreach my $Subfolder ( keys( %Folders ) ) {
    GenerateFavorites( $Folder, $Subfolder, $FolderFilename );
  }
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

sub PublishFavorites {

  # Publikujemy wygenerowane dokumenty za pomoc FTP. Wikszo sytuacji
  # bdnych powoduje przerwanie dziaania skryptu.

  my $ftp = Net::FTP->new( $FAV_HOST ) ||
    die( "Nie mog poczy si z '$FAV_HOST'" );
  $ftp->login( $FAV_USER, $FAV_PASS ) ||
    die( "Autoryzacja uytkownika '$FAV_USER' nie powioda si" );
  $ftp->cwd( $FAV_PATH ) ||
    die( "Niemoliwe wykonanie CWD dla '$FAV_PATH'" );
  opendir( FOLDER, $_FAV_TEMPDIR ) ||
    die( "Nie mona otworzy katalogu roboczego '$_FAV_TEMPDIR'" );
  my @FolderEntries = readdir( FOLDER );
  closedir( FOLDER );
  foreach my $FolderEntry ( @FolderEntries ) {
    next if $FolderEntry eq '.' || $FolderEntry eq '..';
    $ftp->put( File::Spec->join( $_FAV_TEMPDIR, $FolderEntry ) ) ||
      warn( "Nie mog wstawi '$FolderEntry'...pomijam" );
  }
  $ftp->quit;
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

sub main {
  my %Favorites;
  $Favorites{$FAV_NAME} = {};
  LoadFavorites( $FAV_ROOT, $Favorites{$FAV_NAME} );
  GenerateFavorites( \%Favorites, $FAV_NAME, '' );
  PublishFavorites(  );
}

main(  );

