# yer/perl/here ############################################################################### # # convert-favorites # Copyright (c) 2000 Aaron Straup Cope # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. ############################################################################### use strict; # use lib qw ( /yer/lib/here ); # TODO # 1 )Query Favorites::Convert for list of "convertable" file types # so that %files doesn't need to be hard-coded. # 2) Comment the code...sigh # 3) Convert sub usage to POD # Modules # http://aaronland.net/toys/favorites use Favorites::Convert; # Modules CPAN use Data::Dumper; use File::Basename; use File::Copy; use Getopt::Std; use Net::FTP; use Term::ReadKey; my $debug; my $verbose; my $pkg = "Net::FTP"; my %files = ( "html" => "Netscape", "xbel" => "XBEL", "opml" => "OPML" ); my $suffix; my $format; my @files; my %options; my $prompt; # Default options (optional) my $path_to_favorites = ""; my $path_to_save = ""; my $filename = ""; my $title = ""; my $ftp = 0; my $scp = 0; my $host = ""; my $user = ""; my $pass = ""; my $dir = ""; my $unlink = 0; { &main; exit; } sub main { &usage; &inform; &untaint; &convert; &transfer; return 1; } sub inform { $prompt ||= ($ARGV[0]) ? 0 : 1; &getopts('vhp:d:f:t:u:r:sxNOXA',\%options) unless ($prompt); $verbose ||= ($prompt) ? ((&ask("Verbose? [y|n] ") eq "y") ? 1 : 0) : $options{v}; $path_to_favorites ||= ($prompt) ? &ask("Favorites : ") : $options{p}; $path_to_save ||= ($prompt) ? &ask("Save to : ") : $options{d}; $filename ||= ($prompt) ? &ask("Filename : ") : $options{f}; $title ||= ($prompt) ? &ask("Title :") : $options{t}; if ($prompt) { if (&ask("Convert to all? :") eq "n") { map { delete $files{$_} unless (&ask("$files{$_} ? [y|n] ") eq "y"); } keys %files; } }else{ if (! $options{'A'}) { $options{'N'} || delete $files{'html'}; $options{'O'} || delete $files{'opml'}; $options{'X'} || delete $files{'xbel'}; } } $ftp ||= ($prompt) ? ((&ask("Transfer files? [y|n] ") eq "y") ? 1 : 0) : $options{'h'}; if ($ftp) { $scp ||= ($prompt) ? ((&ask("Use secure copy? [y|n] ") eq "y" ) ? 1 : 0) : $options{'s'}; if ($scp) { $pkg = "Net::SCP"; eval { require $pkg; }; if ($@) { warn "Unable to load Net::SCP\n"; warn $@; $ftp = 0 if (&ask("Do you want to continue using plain old FTP? [y|n] ") eq "n"); $pkg = "Net::FTP"; } } } if ($ftp) { $host ||= ($prompt) ? &ask("FTP host? ") : $options{'h'}; $user ||= ($prompt) ? &ask("FTP username? ") : $options{'u'}; $dir ||= ($prompt) ? &ask("FTP directory? ") : $options{'r'}; } $title ||= "IE Favorites"; return 1; } sub untaint { # Untaint paths map { die "$_ : $!\n" if (! -e $_); } ($path_to_favorites, $path_to_save); # Untaint $filename unless ( $filename =~ /^([a-zA-Z0-9-_]+)$/) { die "Filename '$filename' may only contain letters, numbers, dashes and underbars.\n"; } # Untaint $dir if ($dir =~ /[\.~]/) { die "Remote directory '$dir' must be an absolute path.\n"; } return 1; } sub convert { if (! keys %files) { warn "Ack! There are no file formats defined.\n"; return 0; } print "Converting $path_to_favorites\n" if ($verbose); foreach my $el (keys %files) { $suffix = $el; $format = $files{$suffix}; my $outfile = "$path_to_save/$filename.$suffix"; if (-e $outfile) { print "Backing up existing copy of $outfile..." if ($verbose); my $backup = "$outfile.bak.$$"; if (! copy $outfile, $backup) { warn $!,"\n"; next; } print "ok\n" if ($verbose); } my $favorite = new Favorites::Convert ("favorites"=>$path_to_favorites,"format"=>$format); print "Creating $outfile...." if ($verbose); if ((! $favorite->convert(outfile=>$outfile,title=>$title)) || (! -e $outfile)) { warn "Failed to convert favorites to '$outfile' : $!\n"; next; } push (@files, $outfile); print "ok\n" if ($verbose); } return 1; } sub transfer { return 1 if (! $ftp); if (! @files) { warn "No files to transfer."; return 0; } $pkg = $pkg->new($host) || die "Ack! Failed to connect\n"; $pkg->login($user, &get_pass) || die "Ack! Failed to login\n"; if ($dir) { print "Changing directory ($dir)..." if ($verbose); $pkg->cwd($dir) || die "Ack! Failed to change directories.\n"; print "ok\n" if ($verbose); } $unlink ||= ($prompt) ? ((&ask("Remove files after upload? [y|n] ") eq "y") ? 1 : 0) : $options{'x'}; foreach (@files) { my $local = $_; my $remote = &basename($local); print "Copying $local...." if ($verbose); if (! $pkg->put($local, $remote)) { warn $!,"\n"; next; } print "ok\n" if ($verbose); if ($unlink) { print "Removing $local..." if ($verbose); if (unlink $local){ print "ok\n" if ($verbose); }else{ print $!,"\n"; } } } $pkg->quit; return 1; } sub ask { print $_[0]; my $answer = ; chomp $answer; return $answer; } sub get_pass { print "Enter password for $user \@ $host: "; ReadMode "noecho"; my $pswd = ReadLine 0; chomp $pswd; ReadMode "normal"; print "\n"; return $pswd; } sub usage { return 1 unless ($ARGV[0] =~ /-h/); print "convert-favorites - usage:\n", "If no options are present this program will run in interactive mode.\n", "\n", "-p Path to the favorites directory. (required)\n", "-d Path to directory where new file(s) should be saved. (required)\n", "-f Filename for new file(s). (required)\n", "-t Title for new file(s).\n", "\n", "-h Name of remote host.\n", "-u User login for remote host.\n", "-r Save files on remote host in this directory.\n", "-s Use SCP.\n", "-x Remove local files after copying to remote host.\n", "\n", "(one or more of the following is required.)\n", "-N Convert to Netscape bookmark file.\n", "-O Convert to OPML format.\n", "-X Convert to XBEL format.\n", "-A Convert to all formats.\n", "\n", "-v Verbose.\n", "-h Print this message.\n", "\n"; exit; }