| InfoSys-FreeDB documentation | Contained in the InfoSys-FreeDB distribution. |
InfoSys::FreeDB::Connection::CDDBP - FreeDB CDDBP connection
require InfoSys::FreeDB;
require InfoSys::FreeDB::Entry;
# Read entry from the default CD device
my $entry = InfoSys::FreeDB::Entry->new_from_cdparanoia();
# Create a CDDBP connection
my $fact = InfoSys::FreeDB->new();
my $conn = $fact->create_connection( {
client_name => 'testing-InfoSys::FreeDB',
client_version => $InfoSys::FreeDB::VERSION,
protocol => 'CDDBP',
} );
# Query FreeDB
my $res_q = $conn->query( $entry );
scalar( $res_q->get_match() ) ||
die 'no matches found for the disck in the default CD-Rom drive';
# Read the first match
my $res_r = $conn->read( ( $res_q->get_match() )[0] );
# Write the entry to STDERR
use IO::Handle;
my $fh = IO::Handle->new_from_fd( fileno(STDERR), 'w' );
$res_r->get_entry()->write_fh( $fh );
FreeDB CDDBP connection
InfoSys::FreeDB::Connection::CDDBP is the CDDBP implementation of the InfoSys::FreeDB::Connection abstract class.
Creates a new InfoSys::FreeDB::Connection::CDDBP object. OPT_HASH_REF is a hash reference used to pass initialization options. OPT_HASH_REF is mandatory. On error an exception Error::Simple is thrown.
Options for OPT_HASH_REF may include:
sign_on_responsePassed to set_sign_on_response().
Options for OPT_HASH_REF inherited through package InfoSys::FreeDB::Connection may include:
client_hostPassed to set_client_host(). Mandatory option.
client_namePassed to set_client_name(). Mandatory option.
client_userPassed to set_client_user(). Mandatory option.
client_versionPassed to set_client_version(). Mandatory option.
freedb_hostPassed to set_freedb_host(). Mandatory option.
freedb_portPassed to set_freedb_port(). Mandatory option.
proto_levelPassed to set_proto_level(). Defaults to 1.
proxy_hostPassed to set_proxy_host().
proxy_passwdPassed to set_proxy_passwd().
proxy_portPassed to set_proxy_port(). Defaults to 8080.
proxy_userPassed to set_proxy_user().
This method is an implementation from package InfoSys::FreeDB::Connection. Connects the object to the FreeDB information service using the object's attributes. A hello commend is sent out, the protocol level is queried and set to the highest level available. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Issues a discid command on the FreeDB database. ENTRY is a InfoSys::FreeDB::Entry object. On error an exception Error::Simple is thrown.
This method is overloaded from package InfoSys::FreeDB::Connection. Disconnects the object from the FreeDB information service.
This method is inherited from package InfoSys::FreeDB::Connection. Returns the connecting client host.
This method is inherited from package InfoSys::FreeDB::Connection. Returns the connecting client name.
This method is inherited from package InfoSys::FreeDB::Connection. Returns the connecting client user.
This method is inherited from package InfoSys::FreeDB::Connection. Returns the connecting client version.
This method is inherited from package InfoSys::FreeDB::Connection. Returns the FreeDB host.
This method is inherited from package InfoSys::FreeDB::Connection. Returns the FreeDB port.
This method is inherited from package InfoSys::FreeDB::Connection. Returns the current protocol level.
This method is inherited from package InfoSys::FreeDB::Connection. Returns the proxy host to use.
This method is inherited from package InfoSys::FreeDB::Connection. Returns the proxy password to use.
This method is inherited from package InfoSys::FreeDB::Connection. Returns the proxy port to use.
This method is inherited from package InfoSys::FreeDB::Connection. Returns the proxy user name to use.
Returns the sign-on response.
Sends a hello command to the FreeDB server. Returns a InfoSys::FreeDB::Response::Hello object. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Issues a log command on the FreeDB database. TO BE SPECIFIED
This method is inherited from package InfoSys::FreeDB::Connection. Issues an lscat command on the FreeDB database. Returns a InfoSys::FreeDB::Response::LsCat object. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Issues an motd command on the FreeDB database. Returns InfoSys::FreeDB::Response::Motd object. On error an exception Error::Simple is thrown.
This method is an implementation from package InfoSys::FreeDB::Connection. Issues a proto command on the FreeDB database. If LEVEL is not specified, the protocol level is queried. If LEVEL is specified it is used to set the protocol level. Returns InfoSys::FreeDB::Response::Proto object. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Queries the FreeDB database. ENTRY is a InfoSys::FreeDB::Entry object. Returns a InfoSys::FreeDB::Response::Query object. On error an exception Error::Simple is thrown.
This method is an implementation from package InfoSys::FreeDB::Connection. Issues a quit command on the FreeDB database and disconnects. Returns InfoSys::FreeDB::Response::Quit object. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Reads an entry from the FreeDB database. MATCH is a InfoSys::FreeDB::Match object. Returns a InfoSys::FreeDB::Response::Match object. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Set the connecting client host. VALUE is the value. VALUE may not be undef. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Set the connecting client name. VALUE is the value. VALUE may not be undef. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Set the connecting client user. VALUE is the value. VALUE may not be undef. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Set the connecting client version. VALUE is the value. VALUE may not be undef. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Set the FreeDB host. VALUE is the value. VALUE may not be undef. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Set the FreeDB port. VALUE is the value. VALUE may not be undef. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Set the current protocol level. VALUE is the value. Default value at initialization is 1. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Set the proxy host to use. VALUE is the value. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Set the proxy password to use. VALUE is the value. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Set the proxy port to use. VALUE is the value. Default value at initialization is 8080. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Set the proxy user name to use. VALUE is the value. On error an exception Error::Simple is thrown.
Set the sign-on response. VALUE is the value. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Issues a sites command on the FreeDB database. Returns a InfoSys::FreeDB::Response::Sites object. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Issues a stat command on the FreeDB database. Returns a InfoSys::FreeDB::Response::Stat object. On error an exception Error::Simple is thrown.
This method is an implementation from package InfoSys::FreeDB::Connection. THIS METHOD IS NOT YET IMPLEMENTED Issues a update command on the FreeDB database. TO BE SPECIFIED_
This method is inherited from package InfoSys::FreeDB::Connection. Issues a ver command on the FreeDB database. Returns a InfoSys::FreeDB::Response::Ver object. On error an exception Error::Simple is thrown.
This method is inherited from package InfoSys::FreeDB::Connection. Issues a whom command on the FreeDB database. Returns a InfoSys::FreeDB::Response::Whom object. On error an exception Error::Simple is thrown.
This method is an implementation from package InfoSys::FreeDB::Connection. THIS METHOD IS NOT YET TESTED Writes an entry to the FreeDB database. ENTRY is a InfoSys::FreeDB::Entry object. CATEGORY is a valid FreeDB category. Returns a InfoSys::FreeDB::Response::Write::1 object in the case an error occurred in the first pass of the writing. Otherwise a InfoSys::FreeDB::Response::Write::2 object is returned. On error an exception Error::Simple is thrown._
InfoSys::FreeDB, InfoSys::FreeDB::Connection, InfoSys::FreeDB::Connection::HTTP, InfoSys::FreeDB::Entry, InfoSys::FreeDB::Entry::Track, InfoSys::FreeDB::Match, InfoSys::FreeDB::Response, InfoSys::FreeDB::Response::DiscId, InfoSys::FreeDB::Response::Hello, InfoSys::FreeDB::Response::LsCat, InfoSys::FreeDB::Response::Motd, InfoSys::FreeDB::Response::Proto, InfoSys::FreeDB::Response::Query, InfoSys::FreeDB::Response::Quit, InfoSys::FreeDB::Response::Read, InfoSys::FreeDB::Response::SignOn, InfoSys::FreeDB::Response::Sites, InfoSys::FreeDB::Response::Stat, InfoSys::FreeDB::Response::Ver, InfoSys::FreeDB::Response::Whom, InfoSys::FreeDB::Response::Write::1, InfoSys::FreeDB::Response::Write::2, InfoSys::FreeDB::Site
None known (yet.)
First development: September 2003 Last update: December 2003
Vincenzo Zocca
Copyright 2003 by Vincenzo Zocca
This file is part of the InfoSys::FreeDB module hierarchy for Perl by
Vincenzo Zocca.
The InfoSys::FreeDB module hierarchy 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.
The InfoSys::FreeDB module hierarchy 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 the InfoSys::FreeDB module hierarchy; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| InfoSys-FreeDB documentation | Contained in the InfoSys-FreeDB distribution. |
package InfoSys::FreeDB::Connection::CDDBP; use 5.006; use base qw( InfoSys::FreeDB::Connection ); use strict; use warnings; use AutoLoader qw(AUTOLOAD); use Error qw(:try); use IO::Socket::INET; use InfoSys::FreeDB::Connection qw(:line_parse); # Used by _value_is_allowed our %ALLOW_ISA = ( 'sign_on_response' => [ 'InfoSys::FreeDB::Response::SignOn' ], ); # Used by _value_is_allowed our %ALLOW_REF = ( ); # Used by _value_is_allowed our %ALLOW_RX = ( ); # Used by _value_is_allowed our %ALLOW_VALUE = ( ); # Package version our ($VERSION) = '$Revision: 0.92 $' =~ /\$Revision:\s+([^\s]+)/; 1; __END__
sub _initialize { my $self = shift; my $opt = defined($_[0]) ? shift : {}; # Check $opt ref($opt) eq 'HASH' || throw Error::Simple("ERROR: InfoSys::FreeDB::Connection::CDDBP::_initialize, first argument must be 'HASH' reference."); # sign_on_response, SINGLE exists( $opt->{sign_on_response} ) && $self->set_sign_on_response( $opt->{sign_on_response} ); # Call the superclass' _initialize $self->SUPER::_initialize($opt); # Return $self return($self); } sub _mk_hello { my $self = shift; return('hello ' . join(' ', $self->get_client_user(), $self->get_client_host(), $self->get_client_name(), $self->get_client_version(), ) ); } sub _value_is_allowed { my $name = shift; # Value is allowed if no ALLOW clauses exist for the named attribute if ( ! exists( $ALLOW_ISA{$name} ) && ! exists( $ALLOW_REF{$name} ) && ! exists( $ALLOW_RX{$name} ) && ! exists( $ALLOW_VALUE{$name} ) ) { return(1); } # At this point, all values in @_ must to be allowed CHECK_VALUES: foreach my $val (@_) { # Check ALLOW_ISA if ( ref($val) && exists( $ALLOW_ISA{$name} ) ) { foreach my $class ( @{ $ALLOW_ISA{$name} } ) { &UNIVERSAL::isa( $val, $class ) && next CHECK_VALUES; } } # Check ALLOW_REF if ( ref($val) && exists( $ALLOW_REF{$name} ) ) { exists( $ALLOW_REF{$name}{ ref($val) } ) && next CHECK_VALUES; } # Check ALLOW_RX if ( defined($val) && ! ref($val) && exists( $ALLOW_RX{$name} ) ) { foreach my $rx ( @{ $ALLOW_RX{$name} } ) { $val =~ /$rx/ && next CHECK_VALUES; } } # Check ALLOW_VALUE if ( ! ref($val) && exists( $ALLOW_VALUE{$name} ) ) { exists( $ALLOW_VALUE{$name}{$val} ) && next CHECK_VALUES; } # We caught a not allowed value return(0); } # OK, all values are allowed return(1); } sub _wait_command_reply { my $self = shift; my $cmd = shift; my $rx = shift; # Check if connection is defined defined( $self->get__connection_() ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Connection::CDDBP::_wait_command_reply, not connected."); # Set blocking $self->get__connection_->blocking(1); # Send command if ($cmd) { $self->get__connection_()->send($cmd . "\r\n"); } # Wait for code $self->get__connection_()->recv(my $head, 5); $head =~ s/^\s+//; my ($code) = $head =~ /(\d{3})/; exists($rx->{$code}) || throw Error::Simple("ERROR: InfoSys::FreeDB::Connection::CDDBP::_wait_command_reply, unknown code '$code' returned."); # Wait for the final DOT or EOL my $content .= $head; $self->get__connection_()->blocking(0); while (1) { $self->get__connection_()->recv(my $rest, 1024); $content .= $rest; $content =~ /$rx->{$code}/ && last; sleep(1); } # Return the content reference return(\$content); } sub _wait_write_reply { my $self = shift; my $entry = shift; my $rx = shift; # Check if connection is defined defined( $self->get__connection_() ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Connection::CDDBP::_wait_write_reply, not connected."); # Set blocking $self->get__connection_->blocking(1); # Send entry foreach my $line ( @{$entry} ) { $self->get__connection_()->send($line . "\r\n"); } # Wait for code $self->get__connection_()->recv(my $head, 5); $head =~ s/^\s+//; my ($code) = $head =~ /(\d{3})/; exists($rx->{$code}) || throw Error::Simple("ERROR: InfoSys::FreeDB::Connection::CDDBP::_wait_write_reply, unknown code '$code' returned."); # Wait for the final DOT or EOL my $content .= $head; $self->get__connection_()->blocking(0); while (1) { $self->get__connection_()->recv(my $rest, 1024); $content .= $rest; $content =~ /$rx->{$code}/ && last; sleep(1); } # Return the content reference return(\$content); } sub connect { my $self = shift; # Make socket connection my $host = $self->get_freedb_host(); my $port = $self->get_freedb_port(); my $connection = IO::Socket::INET->new( PeerAddr => $host, PeerPort => $port, ); defined($connection) || throw Error::Simple("ERROR: InfoSys::FreeDB::Connection::CDDBP::connect, handshake failed, failed to connect to host '$host', port '$port'."); # Set connection $self->set__connection_($connection); # Send command and wait for reply my $content_ref = $self->_wait_command_reply(undef, { 200 => $FINAL_EOL_RX, 201 => $FINAL_EOL_RX, 432 => $FINAL_EOL_RX, 433 => $FINAL_EOL_RX, 434 => $FINAL_EOL_RX, } ); # Parse the result and store it require InfoSys::FreeDB::Response::SignOn; $self->set_sign_on_response( InfoSys::FreeDB::Response::SignOn->new_from_content_ref( $content_ref ), ); # Disconnect and throw exception if error if ( ! $self->get_sign_on_response()->is_connection_allowed() ) { $self->set__connection_(); throw Error::Simple("ERROR: InfoSys::FreeDB::Connection::CDDBP::connect, handshake failed, connection is not allowed."); } # Send a hello my $hello = $self->hello(); # Disconnect and throw exception if error if ( $hello->is_error() ) { $self->set__connection_(); throw Error::Simple("ERROR: InfoSys::FreeDB::Connection::CDDBP::connect, handshake failed, hello returned an error."); } # Return if the protocol level is greater than 1 ( $self->get_proto_level() > 1 ) && return(undef); # Check the protocol my $proto = $self->proto(); # Disconnect and throw exception if error if ( $proto->is_error() ) { $self->set__connection_(); throw Error::Simple("ERROR: InfoSys::FreeDB::Connection::CDDBP::connect, handshake failed, proto returned an error."); } # Set the highest protocol $proto = $self->proto( $proto->get_supported_level() ); # Disconnect and throw exception if error if ( $proto->is_error() ) { $self->set__connection_(); throw Error::Simple("ERROR: InfoSys::FreeDB::Connection::CDDBP::connect, handshake failed, proto returned an error."); } # Return undef return(undef); } sub disconnect { my $self = shift; # Call quit return( $self->quit() ); } sub get_sign_on_response { my $self = shift; return( $self->{InfoSys_FreeDB_Connection_CDDBP}{sign_on_response} ); } sub hello { my $self = shift; # Send command and wait for reply my $cmd = 'cddb ' . $self->_mk_hello(); my $content_ref = $self->_wait_command_reply($cmd, { 200 => $FINAL_EOL_RX, 431 => $FINAL_EOL_RX, 402 => $FINAL_EOL_RX, } ); # Parse the result and return it require InfoSys::FreeDB::Response::Hello; return( InfoSys::FreeDB::Response::Hello->new_from_content_ref( $content_ref ) ); } sub proto { my $self = shift; my $level = shift; # Send command and wait for reply my $cmd = 'proto'; $cmd .= " $level" if ($level); my $content_ref = $self->_wait_command_reply($cmd, { 200 => $FINAL_EOL_RX, 201 => $FINAL_EOL_RX, 501 => $FINAL_EOL_RX, 502 => $FINAL_EOL_RX, } ); # Parse result require InfoSys::FreeDB::Response::Proto; my $res = InfoSys::FreeDB::Response::Proto->new_from_content_ref( $content_ref ); # Remember current protocol level $self->set_proto_level( $res->get_cur_level() ); # Return the result return($res); } sub quit { my $self = shift; # Send command and wait for reply my $cmd = 'quit'; my $content_ref = $self->_wait_command_reply($cmd, { 230 => $FINAL_EOL_RX, } ); # Clear the connection $self->set__connection_(); # Parse the result and return it require InfoSys::FreeDB::Response::Quit; return( InfoSys::FreeDB::Response::Quit->new_from_content_ref( $content_ref ) ); } sub set_sign_on_response { my $self = shift; my $val = shift; # Check if isa/ref/rx/value is allowed &_value_is_allowed( 'sign_on_response', $val ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Connection::CDDBP::set_sign_on_response, the specified value '$val' is not allowed."); # Assignment $self->{InfoSys_FreeDB_Connection_CDDBP}{sign_on_response} = $val; } sub update { throw Error::Simple("ERROR: InfoSys::FreeDB::Connection::CDDBP::update, THIS METHOD IS NOT YET IMPLEMENTED."); } sub write { my $self = shift; my $entry = shift; my $cat = shift; # Throw exception if no cat ( $cat ) || throw Error::Simple("ERROR: InfoSys::FreeDB::Connection::CDDBP::write, no category specified."); # Get the discid my $res = $self->discid($entry); # Throw exception if error $res->get_code() == 200 || throw Error::Simple('ERROR: InfoSys::FreeDB::Connection::CDDBP::write, ' . $res->get_result() . '.'); # Send command and wait for reply my $cmd = "cddb write $cat " . $res->get_discid(); my $content_ref = $self->_wait_command_reply($cmd, { 320 => $FINAL_EOL_RX, 401 => $FINAL_EOL_RX, 402 => $FINAL_EOL_RX, 409 => $FINAL_EOL_RX, 501 => $FINAL_EOL_RX, } ); # Parse the result require InfoSys::FreeDB::Response::Write::1; my $pass1 = InfoSys::FreeDB::Response::Write::1->new_from_content_ref( $content_ref ); # Return result if error $pass1->is_error() && return($pass1); # Send entry and wait for reply $content_ref = $self->_wait_write_reply( $entry->write_array_ref(), { 200 => $FINAL_EOL_RX, 401 => $FINAL_EOL_RX, } ); # Parse the result and return it require InfoSys::FreeDB::Response::Write::2; return( InfoSys::FreeDB::Response::Write::2->new_from_content_ref( $content_ref ) ); }