NAME

Slackware::Slackget::Network::Connection - A wrapper for network operation in slack-get

VERSION

Version 1.0.0

SYNOPSIS

This class is anoter wrapper for slack-get. It will encapsulate all network operation. This class can chang a lot before the release and it may be rename in Slackware::Slackget::NetworkConnection.

Some words about subclass

WARNING: The Slackware::Slackget::Network::Connection::* "drivers" API changed with version 1.0.0

This class use subclass like Slackware::Slackget::Network::Connection::HTTP or Slackware::Slackget::Network::Connection::FTP as "drivers" for a specific protocol.

You can add a "driver" class for a new protocol easily by creating a module in the Slackware::Slackget::Network::Connection:: namespace.

You must know that all class the Slackware::Slackget::Network::Connection::* must implements the following methods (the format is : <method name(<arguments>)> : <returned value>, parmameters between [] are optionnals):

- __test_server : a float (the server response time)
- __fetch_file([$remote_filename],[$local_file]) : a boolean (1 or 0). NOTE: this method store the fetched file on the hard disk. If $local_file is not defined, fetch() must store the file in <config:update-directory> or in "download_directory" (constructor parameter).
- __get_file([$remote_filename]) : the file content

Moreover, this "driver" have to respect the namming convention : the protocol name it implements in upper case (for example, if you implements a driver for the rsync:// protocol the module must be called Slackware::Slackget::Network::Connection::RSYNC.pm).

CONSTRUCTOR

new

WARNING: Since version 1.0.0 of this module you can't instanciate a Slackware::Slackget::Network::Connection object with a constructor with 1 argument. The followinf syntax is deprecated and no longer supported :

my $connection = Slackware::Slackget::Network::Connection->new('http://www.nymphomatic.org/mirror/linuxpackages/Slackware-10.1/');

You can force this class to behave like the old version by setting $Slackware::Slackget::Network::Connection::ENABLE_DEPRECATED_COMPATIBILITY_MODE to 1 *BEFORE* calling the constructor.

This constructor take the followings arguments :

host : a hostname (mandatory)
path : a path on the remote host
files : a arrayref wich contains a list of files to download
config : a reference to a Slackware::Slackget::Config object (mandatory if "download_directory" is not defined)
download_directory : a directory where this object can store fetched files (mandatory if "config" is not defined)
InlineStates : a hashref which contains the reference to event handlers (mandatory)


use Slackware::Slackget::Network::Connection;

(1)
my $connection = Slackware::Slackget::Network::Connection->new(
		host => 'http://www.nymphomatic.org',
		path => '/mirror/linuxpackages/Slackware-10.1/',
		files => ['FILELIST.TXT','PACKAGES.TXT','CHECKSUMS.md5'], # Be carefull that it's the files parameter not file. file is the current working file.
		config => $config,
		InlineStates => {
			progress => \&handle_progress ,
			download_error => \&handle_download_error ,
			download_finished => \&handle_download_finished,
		}
);
$connection->fetch_all or die "An error occur during the download\n";

or (the recommended way) :

(2)
my $connection = Slackware::Slackget::Network::Connection->new(
		host => 'http://www.nymphomatic.org',
		path => '/mirror/linuxpackages/Slackware-10.1/',
		config => $config,
		InlineStates => {
			progress => \&handle_progress ,
			download_error => \&handle_download_error ,
			download_finished => \&handle_download_finished,
		}
);
my $file = $connection->get_file('FILELIST.TXT') or die "[ERROR] unable to download FILELIST.TXT\n";

Instead of using the "config" parameter you can use "download_directory" :

my $connection = Slackware::Slackget::Network::Connection->new(
		host => 'http://www.nymphomatic.org',
		path => '/mirror/linuxpackages/Slackware-10.1/',
		download_directory => "/tmp/",
		InlineStates => {
			progress => \&handle_progress ,
			download_error => \&handle_download_error ,
			download_finished => \&handle_download_finished,
		}
);
my $file = $connection->get_file('FILELIST.TXT') or die "[ERROR] unable to download FILELIST.TXT\n";

or :

my $status = $connection->fetch('FILELIST.TXT',"$config->{common}->{'update-directory'}/".$server->shortname."/cache/FILELIST.TXT");
die "[ERROR] unable to download FILELIST.TXT\n" unless ($status);

The global way (1) is not recommended because of the lake of control on the downloaded file. For example, if there is only 1 download which fail, fetch_all will return undef and you don't know which download have failed.

The recommended way is to give to the constructor the following arguments :

host : the host (with the protocol, do not provide 'ftp.lip6.fr' provide ftp://ftp.lip6.fr. The protocol will be automatically extracted and used to load the correct "driver")
path : the path to the working directory on the server (Ex: '/pub/linux/distributions/slackware/slackware-10.1/'). Don't provide a 'file' argument.
config : the Slackware::Slackget::Config object of the application
mode : a mode between 'normal' or 'secure'. This is only when you attempt to connect to a daemon (front-end/daemon or daemon/daemon connection). 'secure' use SSL connection (** not yet implemented **).
InlineStates : see above.

EVENTS

Since the version 1.0.0 this class is event driven. To manage those events *YOU HAVE* to pass an InlineStates argument to the constructor (new).

There is 3 events generated by this class :

* progress : this event is throw when a progress is detected on file download. The handler will receive the followings parameters (in this order) : the downloaded filename, the amount of data downloaded, the total size of the remote file.

* download_error : this is throw when an error occured during download. The handler will receive the following parameters (in this order) : the downloaded filename, a Slackware::Slackget::Status object.

*download_finished : this is throw when a download finished successfully. The handler will receive the following parameters (in this order) : the downloaded filename, a Slackware::Slackget::Status object.

FUNCTIONS

is_url

Take a string as argument and return TRUE (1) if $string is an http or ftp URL and FALSE (0) else

print "$string is a valid URL\n" if($connection->is_url($string)) ;

parse_url

extract the following informations from $url :

- the protocol 
- the server
- the file (with its total path)

For example :

$connection->parse_url("ftp://ftp.lip6.fr/pub/linux/distributions/slackware/slackware-current/slackware/n/dhcp-3.0.1-i486-1.tgz");

Will extract :

- protocol = ftp
- host = ftp.lip6.fr
- file = /pub/linux/distributions/slackware/slackware-current/slackware/n/dhcp-3.0.1-i486-1.tgz

This method return TRUE (1) if all goes well, else return FALSE (0)

strip_slash

Remove extra slash (/) in the URL and return the URL.

my $url = $connection->strip_slash('http://ftp.infinityperl.org//slackware-repository////CHECKSUMS.md5') ;

DEBUG_show_data_section

test_server

This method test the response time of the mirror, by making a new connection to the server and downloading the FILELIST.TXT file. Be aware of the fact that after testing the connection you will have a new connection (if you were previously connected the previous connection is closed).

my $time = $connection->test_server() ;

This method call the <DRIVER>->__test_server() method.

get_file

Download and return a given file.

my $file = $connection->get_file('PACKAGES.TXT') ;

This method also generate events based on the returned value. If nothing is returned it throw the "download_error" event, else it throw the "download_finished" event.

At this for the moment this method throw a "progress" event with a progress value set at -1.

This method call the <DRIVER>->__get_file() method.

fetch_file

Download and store a given file.

$connection->fetch_file() ; # download the file $connection->file and store it at $config->{common}->{'update-directory'}/$connection->file, this way is not recommended
or
$connection->fetch_file($remote_file) ; # download the file $remote_file and store it at $config->{common}->{'update-directory'}/$connection->file, this way is not recommended
or
$connection->fetch_file('PACKAGES.TXT',"$config->{common}->{'update-directory'}/".$current_specialfilecontainer_object->id."/PACKAGES.TXT") ; # This is the recommended way.
# This is equivalent to : $connection->fetch_file($remote_file,$local_file) ;

This method return a Slackware::Slackget::Status object with the following object declaration :

my $status =  Slackware::Slackget::Status->new(codes => {
	0 => "All goes well.\n",
	1 => "An error occured "
});

A more explicit error string can be concatenate to state 1. This method also generate events based on the returned value. If nothing is returned it throw the "download_error" event, else it throw the "download_finished" event.

All codes greater or equal than 1 should be considered as errors codes.

At this for the moment this method throw a "progress" event with a progress value set at -1.

This method call the <DRIVER>->__fetch_file() method.

fetch_all

This method fetch all files declare in the "files" parameter of the constructor.

$connection->fetch_all or die "Unable to fetch all files\n";

This method save all files in the $config->{common}->{'update-directory'} (or in the "download_directory") directory (so you have to manage yourself the files deletion/replacement problems).

post_event

ACCESSORS

All accessors can get or set a value. You can use them like that :

$proto->my_accessor('a value'); # to set the value of the parameter controlled by this accessor

my $value = $proto->my_accessor ; # to get the value of the parameter controlled by this accessor

The common accessors are :

protocol

return the protocol of the current Connection object as a string :

my $proto = $connection->protocol ;

host

return the host of the current Connection object as a string :

my $host = $connection->host ;

file

return the file of the current Connection object as a string :

my $file = $connection->file ;

files

return the list of files of the current Connection object as an array reference :

my $arrayref = $connection->files ;

path

return or set the path of the current Connection object as a string :

my $path = $connection->path ;

download_directory

set or return the download_directory for the current Connection object as string :

my $dl_dir = $connection->download_directory ;

object_extra_data

This accessor allow you to store and retrieve random data in the connection object.

For example, the slack-get daemon (sg_daemon) use the media id to keep tracks of all connection objects and for the reverse resolution, it need to identify the media id from the Connection object. It's done by the following code :

$connection->object_extra_data('shortname', $media->shortname());

Extra data are not stored in the same space than object data.

AUTHOR

DUPUIS Arnaud, <a.dupuis@infinityperl.org>

BUGS

Please report any bugs or feature requests to bug-Slackware-Slackget@rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Slackware-Slackget. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc Slackware::Slackget

You can also look for information at:

ACKNOWLEDGEMENTS

Thanks to Bertrand Dupuis (yes my brother) for his contribution to the documentation.

COPYRIGHT & LICENSE

Copyright 2005 DUPUIS Arnaud, All Rights Reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.