package Netscape::Bookmarks::Link;
=encoding utf8
=head1 NAME
Netscape::Bookmarks::Link - manipulate, or create Netscape Bookmarks links
=head1 SYNOPSIS
use Netscape::Bookmarks::Link;
my $category = new Netscape::Bookmarks::Category { ... };
my $link = new Netscape::Bookmarks::Link {
TITLE => 'this is the title',
DESCRIPTION => 'this is the description',
HREF => 'http://www.perl.org',
ADD_DATE => 937862073,
LAST_VISIT => 937862073,
LAST_MODIFIED => 937862073,
ALIAS_ID => 4,
}
$category->add($link);
#print a Netscape compatible file
print $link->as_string;
=head1 DESCRIPTION
The Netscape bookmarks file has several basic components:
title
folders (henceforth called categories)
links
aliases
separators
On disk, Netscape browsers store this information in HTML. In the browser,
it is displayed under the "Bookmarks" menu. The data can be manipulated
through the browser interface.
This module allows one to manipulate the links in for a Netscape bookmarks
file. A link has these attributes, only some of which may be present:
title
description
HREF (i.e. URL)
ADD_DATE
LAST_MODIFIED
LAST_VISIT
ALIAS_OF
ALIAS_ID
Additionally, Mozilla (the open source version of Navigator) uses these
attributes:
SHORTCUTURL
ICON
SCHEDULE
LAST_PING
LAST_CHARSET
PING_CONTENT_LEN
PING_STATUS
=head1 METHODS
=over 4
=cut
use strict;
use base qw( Netscape::Bookmarks::AcceptVisitor Netscape::Bookmarks::Isa );
use subs qw();
use vars qw( $DEBUG $VERSION $ERROR );
use URI;
$VERSION = "2.301";
=item Netscape::Bookmarks::Link-E<gt>new( \%hash )
Creates a new Link object. The hash reference argument
can have the following keys to set the properties of the
link:
HREF
ADD_DATE
LAST_MODIFIED
LAST_VISIT
ALIASID
ALIASOF
SHORTCUTURL
ICON
LAST_CHARSET
=cut
sub new {
my $class = shift;
my $param = shift;
my $self = {};
bless $self, $class;
my $url = URI->new( $param->{HREF} );
unless( ref $url ) {
$ERROR = "[$$param{HREF}] is not a valid URL";
return -1;
}
$self->{HREF} = $url;
foreach my $k ( qw(SHORTCUTURL ICON LAST_CHARSET SCHEDULE PING_STATUS) ) {
$self->{$k} = $param->{$k};
}
foreach my $k ( qw(ADD_DATE LAST_MODIFIED LAST_VISIT ALIASID ALIASOF
LAST_PING PING_CONTENT_LEN) ) {
if( defined $param->{$k} and $param->{$k} =~ /\D/ ) {
$ERROR = "[$$param{$k}] is not a valid $k";
return -2;
}
$self->{$k} = $param->{$k};
}
unless( $param->{'TITLE'} ) {
$ERROR = "The TITLE cannot be null.";
return -3;
}
$self->{'TITLE'} = $param->{'TITLE'};
$self->{'DESCRIPTION'} = $param->{'DESCRIPTION'};
$self;
}
=item $obj->href
Returns the URL of the link. The URL appears in the HREF attribute of
the anchor tag.
=cut
sub href {
my $self = shift;
$self->{'HREF'}->as_string
}
=item $obj->add_date
Returns the date when the link was added, in Unix epoch time.
=cut
sub add_date {
my $self = shift;
$self->{'ADD_DATE'}
}
=item $obj->last_modified
Returns the date when the link was last modified, in Unix epoch time. Returns
zero if no information is available.
=cut
sub last_modified {
my $self = shift;
$self->{'LAST_MODIFIED'}
}
=item $obj->last_visit
Returns the date when the link was last vistied, in Unix epoch time. Returns
zero if no information is available.
=cut
sub last_visit {
my $self = shift;
$self->{'LAST_VISIT'}
}
=item $obj->title( [ TITLE ] )
Sets the link title with the given argument, and returns the link title.
If the argument is not defined (e.g. not specified), returns the current
link title.
=cut
sub title {
my( $self, $title ) = @_;
$self->{'TITLE'} = $title if defined $title;
$self->{'TITLE'}
}
=item $obj->description( [ DESCRIPTION ] )
Sets the link description with the given argument, and returns the link
description. If the argument is not defined (e.g. not specified),
returns the current link description.
=cut
sub description {
my( $self, $description ) = @_;
$self->{'DESCRIPTION'} = $description if defined $description;
$self->{'DESCRIPTION'}
}
=item $obj->alias_id
Returns the alias id of a link. Links with aliases are assigned an ALIAS_ID which
associates them with the alias. The alias contains the same value in it's ALIAS_OF
field. The Netscape::Bookmarks::Alias module handles aliases as references to
Netscape::Bookmarks::Link objects.
=cut
sub aliasid {
my $self = shift;
my $data = shift;
$self->{'ALIASID'} = $data if defined $data;
$self->{'ALIASID'}
}
=item $obj->shortcuturl
=cut
sub shortcuturl {
my( $self, $shortcuturl ) = @_;
$self->{'SHORTCUTURL'} = $shortcuturl if defined $shortcuturl;
$self->{'SHORTCUTURL'}
}
=item $obj->icon
=cut
sub icon {
my( $self, $icon ) = @_;
$self->{'ICON'} = $icon if defined $icon;
$self->{'ICON'}
}
=item $obj->schedule
=cut
sub schedule {
my( $self, $schedule ) = @_;
$self->{'SCHEDULE'} = $schedule if defined $schedule;
$self->{'SCHEDULE'}
}
=item $obj->last_ping
=cut
sub last_ping {
my( $self, $last_ping ) = @_;
$self->{'LAST_PING'} = $last_ping if defined $last_ping;
$self->{'LAST_PING'}
}
=item $obj->ping_content_len
=cut
sub ping_content_len {
my( $self, $ping_content_len ) = @_;
$self->{'PING_CONTENT_LEN'} = $ping_content_len if defined $ping_content_len;
$self->{'PING_CONTENT_LEN'}
}
=item $obj->ping_status
=cut
sub ping_status
{
my( $self, $ping_status ) = @_;
$self->{'PING_STATUS'} = $ping_status if defined $ping_status;
$self->{'PING_STATUS'}
}
=item $obj->last_charset
=cut
sub last_charset {
my( $self, $charset ) = @_;
$self->{'LAST_CHARSET'} = $charset if defined $charset;
$self->{'LAST_CHARSET'}
}
# =item $obj->alias_of
#
# Returns the target id of a link. Links with aliases are assigned an ALIAS_ID which
# associates them with the alias. The alias contains the same value in it's ALIAS_OF
# field. The Netscape::Bookmarks::Alias module handles aliases as references to
# Netscape::Bookmarks::Link objects.
#
# =cut
sub aliasof {
my $self = shift;
$self->{'ALIASOF'}
}
# =item $obj->append_title
#
# Adds to the title - used mostly for the HTML parser, although it can
# be used to add a title if none exists (which is an error, though).
#
# =cut
sub append_title {
my $self = shift;
my $text = shift;
$self->{'TITLE'} .= $text;
}
# =item $obj->append_description
#
# Adds to the description - used mostly for the HTML parser, although
# it can be used to add a description if none exists.
#
# =cut
#
sub append_description {
my $self = shift;
my $text = shift;
$self->{'DESCRIPTION'} .= $text;
}
# just show me what you think is in the link. i use this for
# debugging.
#
sub print_dump {
my $self = shift;
print <<"HERE";
$$self{TITLE}
@{[($$self{HREF})->as_string]}
$$self{ADD_DATE}
$$self{LAST_MODIFIED}
$$self{LAST_VISIT}
$$self{ALIASID}
HERE
}
=item $obj->as_string
Returns a Netscape compatible bookmarks file based on the Bookmarks object.
=cut
sub as_string {
my $self = shift;
my $link = $self->href;
my $title = $self->title;
my $aliasid = $self->aliasid;
my $aliasof = $self->aliasof;
my $add_date = $self->add_date;
my $last_visit = $self->last_visit;
my $last_modified = $self->last_modified;
my $shortcuturl = $self->shortcuturl;
my $icon = $self->icon;
my $last_charset = $self->last_charset;
my $schedule = $self->schedule;
my $last_ping = $self->last_ping;
my $ping_content_len = $self->ping_content_len;
my $ping_status = $self->ping_status;
$aliasid = defined $aliasid ? qq|ALIASID="$aliasid"| : '';
$aliasof = defined $aliasof ? qq|ALIASOF="$aliasof"| : '';
$add_date = $add_date ? qq|ADD_DATE="$add_date"| : '';
$last_visit = $last_visit ? qq|LAST_VISIT="$last_visit"| : '';
$last_modified = $last_modified ? qq|LAST_MODIFIED="$last_modified"| : '';
$shortcuturl = $shortcuturl ? qq|SHORTCUTURL="$shortcuturl"| : '';
$icon = $icon ? qq|ICON="$icon"| : '';
$last_charset = $last_charset ? qq|LAST_CHARSET="$last_charset"| : '';
$schedule = $schedule ? qq|SCHEDULE="$schedule"| : '';
$last_ping = $last_ping ? qq|LAST_PING="$last_ping"| : '';
$ping_content_len = $ping_content_len ? qq|PING_CONTENT_LEN="$ping_content_len"| : '';
$ping_status = $ping_status ? qq|PING_STATUS="$ping_status"| : '';
my $attr = join " ", grep( $_ ne '', ($aliasid, $aliasof, $add_date, $last_visit,
$last_modified, $icon, $schedule, $last_ping, $shortcuturl, $last_charset,
$ping_content_len, $ping_status, ) );
$attr = " " . $attr if $attr;
my $desc = '';
$desc = "\n\t<DD>" . $self->description if $self->description;
#XXX: when the parser gets the Link description, it also picks up
#the incidental whitespace between the description and the
#next item, so we need to remove this before we print it.
#
#this is just a kludge though, since we should solve the
#actual problem as it happens. however, since this is a
#stream parser and we don't know when the description ends
#until the next thing starts (since there is no closing DD tag,
#we don't know when to strip whitespace.
$desc =~ s/\s+$//;
return qq|<A HREF="$link"$attr>$title</A>$desc|;
}
=item $obj->remove
Performs any clean up necessary to remove this object from the
Bookmarks tree. Although this method does not remove Alias objects
which point to the Link, it probably should.
=cut
sub remove {
my $self = shift;
return 1;
}
"if you want to believe everything you read, so be it."
__END__
=back
=head1 TO DO
* Add methods for manipulating attributes
=head1 AUTHOR
brian d foy C<< <bdfoy@cpan.org> >>
=head1 COPYRIGHT AND LICENSE
Copyright © 2002-2016, brian d foy <bdfoy@cpan.org>. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=head1 SEE ALSO
L<Netscape::Bookmarks>
=cut