追記:これ使わなくても同じ機能は実現できます→http://clouder.jp/yoshiki/mt/archives/000671.html 1つのファイルに吐き出したかったので作った。P::P::P::Feedとマージするのは微妙…。とりあえず自分用ということで。
package Plagger::Plugin::Publish::OneFeed;

use strict;
use base qw( Plagger::Plugin );

our $VERSION = 0.01;

use XML::Feed;
use XML::Feed::Entry;
use XML::RSS::LibXML;
use File::Spec;

# xxx ugh
$XML::Feed::RSS::PREFERRED_PARSER =
    $XML::RSS::LibXML::VERSION >= 0.16 ? "XML::RSS::LibXML" : "XML::RSS";

sub register {
    my($self, $context) = @_;
    $context->register_hook(
        $self,
        'publish.feed' => \&publish_feed,
        'publish.finalize' => \&finalize_feed,
    );
    $self->init_feed($context);
}

sub init_feed {
    my($self, $context) = @_;

    # check filename
    $self->conf->{filename} or $context->error("No specify filename in config");

    # check dir
    my $dir = $self->conf->{dir};
    unless (-e $dir && -d _) {

        mkdir $dir, 0755 or $context->error("mkdir $dir: $!");
    }
}

sub publish_feed {
    my($self, $context, $args) = @_;
    for my $e ($args->{feed}->entries) {
        my $entry = XML::Feed::Entry->new($self->conf->{format} || 'Atom');
        $entry->title($e->title);
        $entry->link($e->link);
        $entry->summary($e->body_text);
        $entry->content($e->body);
        $entry->category(join(' ', @{$e->tags}));
        $entry->issued($e->date) if $e->date;
        $entry->author($e->author);
        push @{ $self->{__entries} }, $entry;
    }
}

sub finalize_feed {
    my($self, $context) = @_;
    my $conf = $self->conf;

    # generate feed
    my $feed = XML::Feed->new($conf->{format} || 'Atom');
    $feed->title($conf->{title} || "Plagger Feed");
    $feed->link($conf->{link});
    $feed->modified(Plagger::Date->now);
    $feed->generator("Plagger/$Plagger::VERSION");

    for my $entry (sort { $b->issued cmp $a->issued } @{$self->{__entries}}) {
        $feed->add_entry($entry);
    }

    # generate file
    my $filepath = File::Spec->catfile($conf->{dir}, $conf->{filename});
    my $xml = $feed->as_xml;
    utf8::decode($xml) unless utf8::is_utf8($xml);
    open my $output, ">:utf8", $filepath or $context->error("$filepath: $!");
    print $output $xml;
    close $output;
}

1;

__END__

=head1

Plagger::Plugin::Publish::OnFeed - republish RSS/Atom feeds as one file

=head1 SYNOPSYS

  - module: Publish::Feed
    config:
      format: RSS
      dir: /home/yoshiki/plagger/feed
      filename: my_feed.rss

=head1 CONFIG

=head2 format

Specify the format of feed. C<Plagger::Plugin::Publish::OneFeed> supports
the following syndication feed formats:

=over 4

=item * Atom (default)

=item * RSS

=back

=head2 dir(require)

Directory to save feed files in.

=head2 filename(require)

Filename to be used to create feed files.

=head1 AUTHOR

Yoshiki KURIHARA

=head1 SEE ALSO

L<Plagger>, L<XML::Feed>

=cut