From 433a475ea06f93a433c5f2f2ab8128554102627c Mon Sep 17 00:00:00 2001 From: Olli-Antti Kivilahti Date: Sun, 19 Apr 2015 17:43:32 +0300 Subject: [PATCH] Bug 14012 - Koha::FTP, a happy FTP-library to supercharge FTP operations. try { my $ftp = Koha::FTP->new( Net::FTP->new() ); my $currentDir = $ftp->getCurrentFtpDirectory(); $ftp->changeFtpDirectory($targetDirectory, $ftp); $ftp->putFtpFile($filePath, $ftp); $ftp->changeFtpDirectory($currentDir, $ftp); $ftp->deleteFtpFile($fileName, $ftp); catch { if (blessed($_) && $_->isa('Koha::Exception::ConnectionFailed')) { warn $_->error()."\n"; } } --- Koha/FTP.pm | 229 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 Koha/FTP.pm diff --git a/Koha/FTP.pm b/Koha/FTP.pm new file mode 100644 index 0000000..2bee3eb --- /dev/null +++ b/Koha/FTP.pm @@ -0,0 +1,229 @@ +package Koha::FTP; + +# Copyright 2015 Vaara-kirjastot +# +# This file is part of Koha. +# +# Koha 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. +# +# Koha 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. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use Net::FTP; +use Scalar::Util qw( blessed ); + +use Koha::Exception::ConnectionFailed; +use Koha::Exception::LoginFailed; +use Koha::Exception::RemoteInvocation; + +=head1 FTP + +Koha::FTP - Wrapper to Net::FTP to make dealing with FTP-connections so much fun! + +=head1 SYNOPSIS + +sub moveAFileToAnotherFtpDirectory { + my ($filePath, $targetDirectory, $ftpcon) = @_; + my($fileName, $dirs, $suffix) = File::Basename::fileparse( $filePath ); + + try { + + my $ftp = Koha::FTP->new( Net::FTP->new() ); + + my $currentDir = $ftp->getCurrentFtpDirectory(); + $ftp->changeFtpDirectory($targetDirectory, $ftp); + $ftp->putFtpFile($filePath, $ftp); + $ftp->changeFtpDirectory($currentDir, $ftp); + $ftp->deleteFtpFile($fileName, $ftp); + + } catch { + if (blessed($_)){ + if ($_->isa('Koha::Exception::ConnectionFailed')) { + warn $_->error()."\n"; + } + elsif ($_->isa('Koha::Exception::LoginFailed')) { + warn $_->error()."\n"; + } + else { + $_->rethrow(); + } + } + else { + die $_; + } + }; +} + +=cut + + +=head new + + my $ftp = Koha::FTP->new(); + my $ftp = Koha::FTP->new( Net::FTP->new() ); + +=cut + +sub new { + my ($class, $self) = @_; + $self = {} unless ($self); + + if (blessed $self && $self->isa('Net::FTP')) { + my $ftpcon = $self; + $self = {}; + $self->{_connection} = $ftpcon; + } + + bless $self, $class; + return $self; +} + +=head connect +STATIC METHOD! + + Koha::FTP::connect({ Host => 10.0.0.23, + Passive => 0 , + Port => 21, + Timeout => 10, + }, $connectionId); + +@PARAM1, Config HASH, +@PARAM2, String, vendor identifier or a ftp-connection specific identifier. +@RETURNS, Net::FTP-connection object +@THROWS Koha::Exception::LoginFailed + Koha::Exception::ConnectionFailed +=cut + +sub connect { + my ($config, $connectionId) = @_; + + my $ftpcon = Net::FTP->new(Host => $config->{host}, + Passive => ($config->{protocol} =~ m/passive/) ? 1 : 0 , + Port => $config->{port} || 21, + Timeout => 10); + unless ($ftpcon) { + Koha::Exception::ConnectionFailed->throw( error => + "Koha::FTP:> Connecting to '$connectionId', cannot connect to '$connectionId' ftp server: $@"); + } + + if ($ftpcon->login( $config->{username}, $config->{password} )){ + return $ftpcon; + } + else { + Koha::Exception::LoginFailed->throw( error => + "Koha::FTP:> Connecting to '$connectionId', cannot login to '$connectionId' ftp server: $@"); + } + return undef; +} + +sub getConnection { + my ($self) = @_; + return $self->{_connection}; +} + +sub quit { + my ($self) = @_; + $self->{_connection}->quit() if blessed($self->{_connection}) && $self->{_connection}->isa('Net::FTP'); +} + +=head getFtpFile +@THROWS Koha::Exception::RemoteInvocation +=cut + +sub getFtpFile { + my ($self, $directory, $filename) = @_; + my $ftpcon = $self->getConnection(); + + if ($ftpcon->get($filename, $directory.$filename)) { + return 0; #Great! no errors! + } else { + Koha::Exception::RemoteInvocation->throw(error => "Koha::FTP:> Cannot get '$filename' from ftp server '".$self->{connectionId}."': ".$ftpcon->message); + } +} + +=head listFtpDirectory +@THROWS Koha::Exception::RemoteInvocation +=cut + +sub listFtpDirectory { + my ($self) = @_; + my $ftpcon = $self->getConnection(); + + if (my $ftpfiles = $ftpcon->ls()) { + return $ftpfiles; #Great! no errors! + } else { + Koha::Exception::RemoteInvocation->throw(error => "Koha::FTP:> Cannot get directory listing from ftp server '".$self->{connectionId}."': ".$ftpcon->message); + } +} + +=head putFtpFile +@THROWS Koha::Exception::RemoteInvocation +=cut + +sub putFtpFile { + my ($self, $filePath) = @_; + my $ftpcon = $self->getConnection(); + + if ($ftpcon->put($filePath)) { + return 0; #Great! no errors! + } else { + Koha::Exception::RemoteInvocation->throw(error => "Koha::FTP:> Cannot put the file '$filePath' to ftp server '".$self->{connectionId}."': ".$ftpcon->message); + } +} + +=head changeFtpDirectory +@THROWS Koha::Exception::RemoteInvocation +=cut + +sub changeFtpDirectory { + my ($self, $directory) = @_; + my $ftpcon = $self->getConnection(); + + if ($ftpcon->cwd($directory) ) { + return 0; #Great! no errors! + } else { + Koha::Exception::RemoteInvocation->throw(error => "Koha::FTP:> Cannot change to the remote directory '$directory' in ftp server '".$self->{connectionId}."': ".$ftpcon->message); + } +} + +=head getCurrentFtpDirectory +@THROWS Koha::Exception::RemoteInvocation +=cut + +sub getCurrentFtpDirectory { + my ($self) = @_; + my $ftpcon = $self->getConnection(); + + if (my $cwd = $ftpcon->pwd() ) { + return $cwd; #Great! no errors! + } else { + Koha::Exception::RemoteInvocation->throw(error => "Koha::FTP:> Cannot get the remote working directory in ftp server '".$self->{connectionId}."': ".$ftpcon->message); + } +} + +=head deleteFtpFile +@THROWS Koha::Exception::RemoteInvocation +=cut + +sub deleteFtpFile { + my ($self, $filename) = @_; + my $ftpcon = $self->getConnection(); + + if ($ftpcon->delete($filename)) { + return 0; #Great! no errors! + } else { + Koha::Exception::RemoteInvocation->throw(error => "Koha::FTP:> Cannot delete the file '$filename' from ftp server '".$self->{connectionId}."': ".$ftpcon->message); + } +} + +1; #Happy nice joy fun! \ No newline at end of file -- 1.7.9.5