package Net::Gopher::Response::MenuItem;
=head1 NAME
Net::Gopher::Response::MenuItem - Manipulate Gopher/Gopher+ menu items
=head1 SYNOPSIS
use Net::Gopher;
...
my @items = $response->extract_items(ExceptTypes => 'i');
foreach my $menu_item (@items)
{
# there are accessor methods to access every element of a menu item:
printf("%s %s (%s from %s at port %d)\n",
$menu_item->item_type,
$menu_item->display,
$menu_item->selector,
$menu_item->host,
$menu_item->port
);
# you can easily convert menu items into URLs:
my $url = $menu_item->as_url;
# ...or Net::Gopher::Request objects:
my $request = $menu_item->as_request;
$response = $ng->request($request);
# a string containing the item:
print $menu_item->as_string;
}
=head1 DESCRIPTION
The B<Net::Gopher::Response> C<extract_items()> method parses a Gopher menu
and returns the parsed items from the menu in the form of
B<Net::Gopher::Response::MenuItem> objects. This class contains methods to
retrieve the various fields from a menu item object and methods to generate
corresponding URLs and request objects from them.
As a convenience, this class overloads stringification, so using one of these
menu item objects in a string context will yield a string containing the menu
item as it appeared in the Gopher menu (tabs an all). (Which can alternately be
achieved using C<as_string()>, described below.)
=head1 METHODS
The following methods are available:
=cut
use 5.005;
use strict;
use warnings;
use vars qw(@ISA);
use overload (
'""' => sub { shift->as_string },
fallback => 1,
);
use Carp;
use URI;
use Net::Gopher::Constants ':item_types';
use Net::Gopher::Debugging;
use Net::Gopher::Exception;
use Net::Gopher::Request;
use Net::Gopher::Utility 'get_named_params';
push(@ISA, qw(Net::Gopher::Debugging Net::Gopher::Exception));
################################################################################
sub new
{
my $invo = shift;
my $class = ref $invo || $invo;
my ($item_type, $display, $selector, $host, $port, $gopher_plus);
get_named_params({
ItemType => \$item_type,
Display => \$display,
Selector => \$selector,
Host => \$host,
Port => \$port,
GopherPlus => \$gopher_plus
}, \@_
);
my $self = {
item_type => $item_type,
display => $display,
selector => $selector,
host => $host,
port => $port,
gopher_plus => $gopher_plus
};
bless($self, $class);
return $self;
}
#==============================================================================#
=head2 as_string()
This method returns a string containing the item.
=cut
sub as_string
{
my $self = shift;
my $string = sprintf("%s%s\t%s\t%s\t%s",
$self->item_type,
$self->display,
$self->selector,
$self->host,
$self->port
);
$string .= "\t" . $self->gopher_plus if (defined $self->gopher_plus);
return $string;
}
#==============================================================================#
=head2 as_request()
This method creates and returns a new B<Net::Gopher::Request> object using the
fields in the menu item.
=cut
sub as_request
{
my $self = shift;
$self->call_warn(
"You're trying to convert an inline text (\"i\" item type) " .
"menu item into a request object. Inline text items are not " .
"supposed to be downloadable."
) if ($self->item_type eq INLINE_TEXT_TYPE);
my $request;
if (defined $self->gopher_plus and length $self->gopher_plus)
{
my $request_char = substr($self->gopher_plus, 0, 1);
if ($request_char eq '+' or $request_char eq '?')
{
$request = new Net::Gopher::Request ('GopherPlus',
Host => $self->host,
Port => $self->port,
Selector => $self->selector,
ItemType => $self->item_type
);
}
else
{
return $self->call_die(
"Can't convert malformed menu item into a " .
"request object: the Gopher+ string contains " .
"an invalid request type character " .
"(\"$request_char\"). It should be \"+\" or " .
'"?".'
);
}
}
else
{
$request = new Net::Gopher::Request ('Gopher',
Host => $self->host,
Port => $self->port,
Selector => $self->selector,
ItemType => $self->item_type
);
}
return $request;
}
#==============================================================================#
=head2 as_url()
This method creates and returns a new gopher:// URL using the fields in the
menu item.
=cut
sub as_url
{
my $self = shift;
$self->call_warn(
"The menu item lacks a hostname, and any URL it's converted " .
"to will be invalid."
) unless (defined $self->host and length $self->host);
$self->call_warn(
"You're trying to convert an inline text (\"i\" item type) " .
"menu item into a Gopher URL. Inline text items are not " .
"supposed to be downloadable."
) if ($self->item_type eq INLINE_TEXT_TYPE);
my $uri = new URI (undef, 'gopher');
$uri->scheme('gopher');
$uri->host($self->host);
$uri->port($self->port);
$uri->gopher_type($self->item_type);
$uri->selector($self->selector);
$uri->string($self->gopher_plus);
return $uri->as_string;
}
#==============================================================================#
=head2 item_type()
This method returns the item type character of the menu item.
=cut
sub item_type
{
my $self = shift;
if (@_)
{
$self->{'item_type'} = shift;
}
else
{
return $self->{'item_type'};
}
}
#==============================================================================#
=head2 display()
This method returns the display string of the menu item.
=cut
sub display
{
my $self = shift;
if (@_)
{
$self->{'display'} = shift;
}
else
{
return $self->{'display'};
}
}
#==============================================================================#
=head2 selector()
This method returns the selector string of the menu item.
=cut
sub selector
{
my $self = shift;
if (@_)
{
$self->{'selector'} = shift;
}
else
{
return $self->{'selector'};
}
}
#==============================================================================#
=head2 host()
This method returns the host field of the menu item.
=cut
sub host
{
my $self = shift;
if (@_)
{
$self->{'host'} = shift;
}
else
{
return $self->{'host'};
}
}
#==============================================================================#
=head2 port()
This method returns the port field of the menu item.
=cut
sub port
{
my $self = shift;
if (@_)
{
$self->{'port'} = shift;
}
else
{
return $self->{'port'};
}
}
#==============================================================================#
=head2 gopher_plus()
For a Gopher+ menu item, this will return the Gopher+ string of a menu item.
With Gopher items it will just return undef.
=cut
sub gopher_plus
{
my $self = shift;
if (@_)
{
$self->{'gopher_plus'} = shift;
}
else
{
return $self->{'gopher_plus'};
}
}
1;
__END__
=head1 BUGS
Bugs in this package can reported and monitored using CPAN's request
tracker: rt.cpan.org.
If you wish to report bugs to me directly, you can reach me via email at
<william_g_davis at users dot sourceforge dot net>.
=head1 SEE ALSO
L<Net::Gopher|Net::Gopher>, L<Net::Gopher::Response|Net::Gopher::Response>
=head1 COPYRIGHT
Copyright 2003-2004 by William G. Davis.
This library is free software released under the terms of the GNU Lesser
General Public License (LGPL), the full terms of which can be found in the
"COPYING" file that comes with the distribution.
This library 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.
=cut
syntax highlighted by Code2HTML, v. 0.9.1