Padre’s trac still contains ticket #12 “Add remote editing capability via ftp and ssh” which is 15 month old.
7 weeks ago, Padre::File was added, which should take over all file activity within Padre.
I just started Padre::File::FTP yesterday night which plugs in an FTP server as file storage . Net::FTP was easy to use and I wondered that basic FTP support including write access was not only started, but finished within an hour.
Changeset 9096 added the FTP module including many TODO’s. Here is a quick walkthrough:
if ($url !~ /ftp\:\/?\/?((.+?)(\:(.+?))?\@)?([a-z0-9\-\.]+)(\:(\d+))?(\/.+)$/i) {
# URL parsing failed
# TODO: Warning should go to a user popup not to the text console
warn 'Unable to parse '.$url;
return;
}
# Login data
if (defined($2)) {
$self->{_user} = $2;
$self->{_pass} = $4 if defined($4);
} else {
$self->{_user} = 'ftp';
$self->{_pass} = 'padre_user@devnull.perlide.org';
}
# Host & port
$self->{_host} = $5;
$self->{_port} = $7 || 21;
# Path & filename
$self->{_file} = $8;
Padre should be able to open everything in one-line-URL-format. The URL parsing regular expression accepts optional username/passwort, a server, a optional port and a filename. If no username is defined, the module switches to hard-coded anonymous FTP values. Everything is stored into the blessed “self” hash as individual keys for easy access.
$self->{_ftp} = Net::FTP->new(Host => $self->{_host},Port => $self->{_port},Timeout => 120, # TODO: Make this configurablePassive => 1, # TODO: Make this configurable);
Host and port are used from the URL, static values for timeout and passive mode are ok for a first start and until there is a configuration dialog for Padre::File preferences. A warning is issues on connection problems (this needs to be improved).
$self->{_file_temp} = File::Temp->new( UNLINK => 1 );
$self->{_tmpfile} = $self->{_file_temp}->filename;
Net::FTP offers direct access for data connections but I preferred the good-old get and put commands for this first basic solution. A local tempfile is required for them and File::Temp provides a good OS-independent way of managing tempfiles. The object needs to be stored as the temp file will be finally removed as soon as the File::Temp object is destroyed.
There are some helper methods (like ->exists or ->size), but file access is the most important thing we need:
sub read {
my $self = shift;
$self->{_ftp}->get($self->{_file},$self->{_tmpfile}) or warn $@;
open my $tmpfh,$self->{_tmpfile};
return join('',<$tmpfh>);
}
This method downloads the FTP-file into a local temporary file and just returns the local content. Net::FTP lacks an easy way to get a file directly into a variable, but this is also ok – we’re still talking about a first basic solution.
The next step was done in changeset 9097: Adding support for FTP-style URLs to Padre::File.
Everything – including generation of the module, looking up Net::FTP documentation was done in less than one hour. I really didn’t expect it to be this simple and fast but you see – helping on Padre is much less time-consuming than you might think.
