The Perl Toolchain Summit 2025 Needs You: You can help 🙏 Learn more

use strict;
use vars qw($VERSION);
$VERSION = '5.32';
=head1 NAME
Labyrinth::RSS - RSS Handler for Labyrinth
=head1 DESCRIPTION
Contains all the RSS/Atom feeds used by Labyrinth
=cut
# -------------------------------------
# Library Modules
# -------------------------------------
# Variables
my $RSSFEED = 10;
my $GENERATOR = 'Labyrinth v' . $VERSION;
# -------------------------------------
# The Subs
=head1 PUBLIC INTERFACE METHODS
=head2 Constructor
=over
=item new
=back
=cut
sub new {
my $class = shift;
my %hash = @_;
# verify we have the necessary settings
for(qw(rssmail rssname)) {
die "Missing configuration setting: '$_'\n" unless($settings{$_});
}
my $rssuser = "$settings{rssmail} ($settings{rssname})";
$settings{rsseditor} ||= $rssuser;
$settings{rssmaster} ||= $rssuser;
my $atts = {
type => ($hash{type} || 'rss'),
version => ($hash{version} || '2.0'),
perma => ($hash{perma} || $settings{perma}),
id => ($hash{id} || 'articleid'),
block => ($hash{block} || 'articles/arts-block.html'),
};
bless $atts, $class;
return $atts;
}
=head2 Public Methods
=over
=item feed
For the given list of entries, reformats into the requested feed type.
=back
=cut
sub feed {
my $self = shift;
return unless(@_);
return $self->RSS_0_9(@_) if($self->{type} eq 'rss' && $self->{version} eq '0.9');
return $self->RSS_1_0(@_) if($self->{type} eq 'rss' && $self->{version} eq '1.0');
return $self->RSS_2_0(@_) if($self->{type} eq 'rss' && $self->{version} eq '2.0');
return $self->Atom_0_3(@_) if($self->{type} eq 'atom' && $self->{version} eq '0.3');
return $self->Atom_1_0(@_) if($self->{type} eq 'atom' && $self->{version} eq '1.0');
$tvars{errcode} = 'ERROR';
}
=head2 Private Methods
=over
=item RSS_0_9
Reformats article list into RSS 0.9.
=item RSS_1_0
Reformats article list into RSS 1.0.
=item RSS_2_0
Reformats article list into RSS 2.0.
=item Atom_0_3
Reformats article list into Atom 0.3.
=item Atom_1_0
Reformats article list into Atom 1.0.
=item CleanEntities
For a given string, reformats basic entities to avoid potential XML
irregularities.
=back
=cut
sub RSS_0_9 {
my $self = shift;
# verify we have the necessary settings
for(qw(rsstitle rsslink rssdesc)) {
die "Missing configuration setting: '$_'\n" unless($settings{$_});
}
my $rss = XML::RSS->new(version => '0.9');
$rss->channel(
title => $settings{rsstitle},
link => $settings{rsslink},
description => $settings{rssdesc},
);
for my $item (@_) {
my $id = $item->{data}{$self->{id}};
my $perma = $item->{data}{permapath} || $self->{perma} . $id;
$rss->add_item(
title => CleanEntities($item->{data}{title}),
link => $settings{rsslink} . $perma
);
}
$tvars{rss} = $rss->as_string;
}
sub RSS_1_0 {
my $self = shift;
# verify we have the necessary settings
for(qw(rsstitle rsslink rssdesc rsssubject rsscreator rsspublisher copyright)) {
die "Missing configuration setting: '$_'\n" unless($settings{$_});
}
my $rss = XML::RSS->new(version => '1.0');
$rss->channel(
title => $settings{rsstitle},
link => $settings{rsslink},
description => $settings{rssdesc},
dc => {
date => formatDate(16),
subject => $settings{rsssubject},
creator => $settings{rsscreator},
publisher => $settings{rsspublisher},
rights => $settings{copyright},
language => 'en-gb',
},
syn => {
updatePeriod => "daily",
updateFrequency => "1",
updateBase => "2000-01-01T00:00:00+00:00",
},
);
for my $item (@_) {
my $id = $item->{data}{$self->{id}};
my $perma = $item->{data}{permapath} || $self->{perma} . $id;
my $block = '';
my $body = $item->{data}{body} || $item->{body};
if($self->{id} eq 'articleid') {
my %vars = ( 'block' => $body );
$block = Transform($self->{block},\%vars);
} else {
$block = $body;
}
$rss->add_item(
# date => formatDate(16,$item->{data}{createdate}),
title => CleanEntities($item->{data}{title}),
description => CleanEntities($block),
link => $settings{rsslink} . $perma
);
}
$tvars{rss} = $rss->as_string;
}
sub RSS_2_0 {
my $self = shift;
# verify we have the necessary settings
for(qw(rsstitle rsslink rssdesc copyright rsseditor rssmaster)) {
die "Missing configuration setting: '$_'\n" unless($settings{$_});
}
my $rss = XML::RSS->new(version => '2.0');
$rss->channel(
title => $settings{rsstitle},
link => $settings{rsslink},
description => $settings{rssdesc},
language => 'en',
copyrights => $settings{copyright},
pubDate => formatDate(16),
managingEditor => $settings{rsseditor},
webMaster => $settings{rssmaster},
generator => $GENERATOR,
);
for my $item (@_) {
my $id = $item->{data}{$self->{id}};
my $perma = $item->{data}{permapath} || $self->{perma} . $id;
my $block = '';
my $body = $item->{data}{body} || $item->{body};
if($self->{id} eq 'articleid') {
my %vars = ( 'block' => $body );
$block = Transform($self->{block},\%vars);
} else {
$block = $body;
}
$rss->add_item(
pubDate => formatDate(16,$item->{data}{createdate}),
title => CleanEntities($item->{data}{title}),
description => CleanEntities($block),
link => $settings{rsslink} . $perma,
guid => $settings{rsslink} . $perma,
comments => $settings{rsslink} . $perma . '#comments'
);
}
$tvars{rss} = $rss->as_string;
}
sub Atom_0_3 {
my $self = shift;
# verify we have the necessary settings
for(qw(rsstitle rsslink)) {
die "Missing configuration setting: '$_'\n" unless($settings{$_});
}
my ($tag) = $settings{rsslink} =~ m!http://([^/]+)/!;
my $feed = XML::Atom::Feed->new;
$feed->title($settings{rsstitle});
$feed->id("tag:$tag,".formatDate(1).':atom03');
for my $item (@_) {
my $id = $item->{data}{$self->{id}};
my $perma = $item->{data}{permapath} || $self->{perma} . $id;
my $block = '';
my $body = $item->{data}{body} || $item->{body};
if($self->{id} eq 'articleid') {
my %vars = ( 'block' => $body );
$block = Transform($self->{block},\%vars);
} else {
$block = $body;
}
my $entry = XML::Atom::Entry->new;
$entry->title(CleanEntities($item->{data}{title}));
$entry->id("tag:$tag,".formatDate(1) . ':' . $id);
$entry->link($settings{rsslink} . $perma);
$entry->content(CleanEntities($block));
$feed->add_entry($entry);
}
$tvars{rss} = $feed->as_xml;
}
sub Atom_1_0 {
my $self = shift;
# verify we have the necessary settings
for(qw(rsstitle rsslink rssname rssmail)) {
die "Missing configuration setting: '$_'\n" unless($settings{$_});
}
$XML::Atom::DefaultVersion = "1.0";
my ($tag) = $settings{rsslink} =~ m!http://([^/]+)/?!;
my $feed = XML::Atom::Feed->new;
$feed->title($settings{rsstitle});
$feed->id("tag:$tag,".formatDate(1).':atom10');
$feed->updated(formatDate(12,$_[0]->{data}{creatdate}));
my $author = XML::Atom::Person->new;
$author->name($settings{rssname});
$author->email($settings{rssmail});
for my $item (@_) {
my $id = $item->{data}{$self->{id}};
my $perma = $item->{data}{permapath} || $self->{perma} . $id;
my $block = '';
my $body = $item->{data}{body} || $item->{body};
if($self->{id} eq 'articleid') {
my %vars = ( 'block' => $body );
$block = Transform($self->{block},\%vars);
} else {
$block = $body;
}
my $entry = XML::Atom::Entry->new;
$entry->title(CleanEntities($item->{data}{title}));
$entry->id("tag:$tag,".formatDate(1) . ':' . $id);
$entry->content(CleanEntities($block));
$entry->author($author);
$entry->updated(formatDate(12,$item->{data}{createdate}));
my $link = XML::Atom::Link->new;
$link->type('text/html');
$link->rel('alternate');
$link->href($settings{rsslink} . $perma);
$entry->add_link($link);
$feed->add_entry($entry);
}
$tvars{rss} = $feed->as_xml;
}
sub CleanEntities {
my $text = shift;
return '' unless($text);
$text =~ s/–/-/gs; # ndash causes XML problems!
$text =~ s/&/&/gs;
$text =~ s/'/'/gs;
$text =~ s!(src|href)=(["'])/!$1=$2$settings{rssweb}/!igs;
return $text;
}
1;
__END__
=head1 SEE ALSO
Labyrinth
=head1 AUTHOR
Barbie, <barbie@missbarbell.co.uk> for
Miss Barbell Productions, L<http://www.missbarbell.co.uk/>
=head1 COPYRIGHT & LICENSE
Copyright (C) 2007-2015 Barbie for Miss Barbell Productions
All Rights Reserved.
This module is free software; you can redistribute it and/or
modify it under the Artistic License 2.0.
=cut