AtomBus
view release on metacpan or search on metacpan
lib/AtomBus.pm view on Meta::CPAN
package AtomBus;
use Dancer qw(:syntax);
use Dancer::Plugin::DBIC qw(schema);
use Atompub::DateTime qw(datetime);
use UUID::Tiny;
use XML::Atom;
$XML::Atom::DefaultVersion = '1.0';
our $VERSION = '1.0405'; # VERSION
set content_type => 'application/xml';
config->{plugins}{DBIC}{atombus} = config->{atombus}{db};
config->{plugins}{DBIC}{atombus}{schema_class} = 'AtomBus::Schema';
eval { schema->deploy }; # Fails gracefully if tables already exist.
get '/feeds/:feed_title/entries/:entry_id' => sub {
my $entry_id = 'urn:uuid:' . params->{entry_id};
my $db_entry = schema->resultset('AtomBusEntry')->find({id => $entry_id});
return send_error("No such message exists", 404)
unless $db_entry;
my $if_none_match = request->header('If-None-Match');
#TODO: support revised entries (i.e. Atompub PUT)
# my $revision_id = $db_entry->revision_id || $db_entry->id;
my $revision_id = $db_entry->id;
# If ETag matches current revision id of entry
if (my $id = $if_none_match) {
$id =~ s/^"(.*)"$/$1/; # Remove surrounding quotes
if ($revision_id eq $id) {
status 304;
return '';
}
}
my $entry = _entry_from_db($db_entry);
_add_etag($revision_id);
header Vary => 'If-None-Match';
return $entry->as_xml;
};
get '/feeds/:feed_title' => sub {
my $feed_title = lc params->{feed_title};
my $start_after = params->{start_after};
my $start_at = params->{start_at};
my $if_none_match = request->header('If-None-Match');
my $order_id;
if (my $id = $if_none_match) {
$id =~ s/^"(.*)"$/$1/; # Remove surrounding quotes
my $entry = schema->resultset('AtomBusEntry')->find({id => $id});
$order_id = $entry->order_id if $entry;
}
if (my $id = $start_after || $start_at) {
my $entry = schema->resultset('AtomBusEntry')->find({id => $id});
return send_error("No such message exists with id $id", 400)
unless $entry;
$order_id = $entry->order_id;
}
my $db_feed = schema->resultset('AtomBusFeed')->find(
{ title => $feed_title });
return send_error("No such feed exists named $feed_title", 404)
unless $db_feed;
my $feed = XML::Atom::Feed->new;
$feed->title($feed_title);
$feed->id($db_feed->id);
my $person = XML::Atom::Person->new;
$person->name($db_feed->author_name);
$feed->author($person);
$feed->updated($db_feed->updated);
my $self_link = XML::Atom::Link->new;
$self_link->rel('self');
$self_link->type('application/atom+xml');
$self_link->href(request->uri_for(request->path));
$feed->add_link($self_link);
#my $hub_link = XML::Atom::Link->new;
#$hub_link->rel('hub');
#$hub_link->href('http://184.106.189.98:8080/publish');
#$feed->add_link($hub_link);
my %query = (feed_title => $feed_title);
if ($order_id) {
$query{order_id} = { '>' => $order_id } if $if_none_match;
$query{order_id} = { '>' => $order_id } if $start_after;
$query{order_id} = { '>=' => $order_id } if $start_at;
}
my $rset = schema->resultset('AtomBusEntry')->search(
\%query, { order_by => ['order_id'] });
my $count = config->{atombus}{page_size} || 1000;
my $last_id;
while ($count-- && (my $entry = $rset->next)) {
$feed->add_entry(_entry_from_db($entry));
$last_id = $entry->id;
}
# If ETag was provided and there are no new entries
if (not $last_id and $if_none_match) {
status 304;
return '';
}
_add_etag($last_id) if $last_id;
header Vary => 'If-None-Match';
return $feed->as_xml;
};
post '/feeds/:feed_title' => sub {
my $feed_title = lc params->{feed_title};
my $body = request->body;
return send_error("Request body is empty", 400)
unless $body;
my $entry = XML::Atom::Entry->new(\$body);
my $updated = datetime->w3cz;
my $db_feed = schema->resultset('AtomBusFeed')->find_or_create({
title => $feed_title,
id => _gen_id(),
author_name => 'AtomBus',
updated => $updated,
( run in 2.201 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )