--- AnyEvent-FCP/FCP.pm 2009/07/25 06:28:49 1.2 +++ AnyEvent-FCP/FCP.pm 2009/07/28 02:20:51 1.3 @@ -4,45 +4,34 @@ =head1 SYNOPSIS - use AnyEvent::FCP; + use AnyEvent::FCP; - my $fcp = new AnyEvent::FCP; + my $fcp = new AnyEvent::FCP; - my $ni = $fcp->txn_node_info->result; - my $ni = $fcp->node_info; +# transactions return condvars + my $lp_cv = $fcp->list_peers; + my $pr_cv = $fcp->list_persistent_requests; + + my $peers = $lp_cv->recv; + my $reqs = $pr_cv->recv; =head1 DESCRIPTION This module implements the freenet client protocol version 2.0, as used by freenet 0.7. See L for the earlier freenet 0.5 version. -See L for a description -of what the messages do. +See L for a +description of what the messages do. The module uses L to find a suitable event module. +Only very little is implemented, ask if you need more, and look at the +example program later in this section. + =head2 IMPORT TAGS Nothing much can be "imported" from this module right now. -=head2 FREENET BASICS - -Ok, this section will not explain any freenet basics to you, just some -problems I found that you might want to avoid: - -=over 4 - -=item freenet URIs are _NOT_ URIs - -Whenever a "uri" is required by the protocol, freenet expects a kind of -URI prefixed with the "freenet:" scheme, e.g. "freenet:CHK...". However, -these are not URIs, as freeent fails to parse them correctly, that is, you -must unescape an escaped characters ("%2c" => ",") yourself. Maybe in the -future this library will do it for you, so watch out for this incompatible -change. - -=back - =head2 THE AnyEvent::FCP CLASS =over 4 @@ -55,7 +44,7 @@ use Carp; -our $VERSION = '0.1'; +our $VERSION = '0.2'; use Scalar::Util (); @@ -82,8 +71,10 @@ Create a new FCP connection to the given host and port (default 127.0.0.1:9481, or the environment variables C and C). -If no C was specified, then AnyEvent::FCP will generate a (hopefully) -unique client name for you. +If no C was specified, then AnyEvent::FCP will generate a +(hopefully) unique client name for you. + +=cut #TODO #You can install a progress callback that is being called with the AnyEvent::FCP @@ -96,8 +87,6 @@ # warn "progress<$txn,$type," . (join ":", %$attr) . ">\n"; # } -=cut - sub new { my $class = shift; my $self = bless { @_ }, $class; @@ -134,12 +123,12 @@ $self } -sub progress { - my ($self, $txn, $type, $attr) = @_; - - $self->{progress}->($self, $txn, $type, $attr) - if $self->{progress}; -} +#sub progress { +# my ($self, $txn, $type, $attr) = @_; +# +# $self->{progress}->($self, $txn, $type, $attr) +# if $self->{progress}; +#} sub send_msg { my ($self, $type, %kv) = @_; @@ -255,6 +244,12 @@ }; } +=item $cv = $fcp->list_peers ([$with_metdata[, $with_volatile]]) + +=item $peers = $fcp->list_peers_sync ([$with_metdata[, $with_volatile]]) + +=cut + _txn list_peers => sub { my ($self, $cv, $with_metadata, $with_volatile) = @_; @@ -277,6 +272,12 @@ ); }; +=item $cv = $fcp->list_peer_notes ($node_identifier) + +=item $notes = $fcp->list_peer_notes_sync ($node_identifier) + +=cut + _txn list_peer_notes => sub { my ($self, $cv, $node_identifier) = @_; @@ -291,6 +292,12 @@ ); }; +=item $cv = $fcp->watch_global ($enabled[, $verbosity_mask]) + +=item $fcp->watch_global_sync ($enabled[, $verbosity_mask]) + +=cut + _txn watch_global => sub { my ($self, $cv, $enabled, $verbosity_mask) = @_; @@ -302,6 +309,12 @@ $cv->(); }; +=item $cv = $fcp->list_persistent_requests + +=item $reqs = $fcp->list_persistent_requests_sync + +=cut + _txn list_persistent_requests => sub { my ($self, $cv) = @_; @@ -335,6 +348,12 @@ }; }; +=item $cv = $fcp->remove_request ($global, $identifier) + +=item $status = $fcp->remove_request_sync ($global, $identifier) + +=cut + _txn remove_request => sub { my ($self, $cv, $global, $identifier) = @_; @@ -352,6 +371,12 @@ $cv->(); }; +=item $cv = $fcp->modify_persistent_request ($global, $identifier[, $client_token[, $priority_class]]) + +=item $status = $fcp->modify_persistent_request_sync ($global, $identifier[, $client_token[, $priority_class]]) + +=cut + _txn modify_persistent_request => sub { my ($self, $cv, $global, $identifier, $client_token, $priority_class) = @_; @@ -371,6 +396,12 @@ $cv->(); }; +=item $cv = $fcp->get_plugin_info ($name, $detailed) + +=item $info = $fcp->get_plugin_info_sync ($name, $detailed) + +=cut + _txn get_plugin_info => sub { my ($self, $cv, $name, $detailed) = @_; @@ -390,6 +421,51 @@ =back +=head1 EXAMPLE PROGRAM + + use AnyEvent::FCP; + + my $fcp = new AnyEvent::FCP; + + # let us look at the global request list + $fcp->watch_global (1, 0); + + # list them, synchronously + my $req = $fcp->list_persistent_requests_sync; + + # go through all requests + for my $req (values %$req) { + # skip jobs not directly-to-disk + next unless $req->{return_type} eq "disk"; + # skip jobs not issued by FProxy + next unless $req->{identifier} =~ /^FProxy:/; + + if ($req->{data_found}) { + # file has been successfully downloaded + + ... move the file away + (left as exercise) + + # remove the request + + $fcp->remove_request (1, $req->{identifier}); + } elsif ($req->{get_failed}) { + # request has failed + if ($req->{get_failed}{code} == 11) { + # too many path components, should restart + } else { + # other failure + } + } else { + # modify priorities randomly, to improve download rates + $fcp->modify_persistent_request (1, $req->{identifier}, undef, int 6 - 5 * (rand) ** 1.7) + if 0.1 > rand; + } + } + + # see if the dummy plugin is loaded, to ensure all previous requests have finished. + $fcp->get_plugin_info_sync ("dummy"); + =head1 SEE ALSO L, L.