diff options
author | franck cuny <franck@lumberjaph.net> | 2010-03-30 20:53:21 +0200 |
---|---|---|
committer | franck cuny <franck@lumberjaph.net> | 2010-03-30 20:53:21 +0200 |
commit | a6bd5aa5f6d9f8356fd6b4d80ef9b4ed92a47d3d (patch) | |
tree | afdb4158cd316a81daa3de1dcce99a9ff82385c5 | |
parent | initial commit (diff) | |
download | feeddiscovery-a6bd5aa5f6d9f8356fd6b4d80ef9b4ed92a47d3d.tar.gz |
application
Diffstat (limited to '')
-rw-r--r-- | bin/app.psgi | 23 | ||||
-rw-r--r-- | lib/FeedDiscovery.pm | 1 | ||||
-rw-r--r-- | lib/FeedDiscovery/Handler.pm | 93 | ||||
-rw-r--r-- | templates/index.html | 12 |
4 files changed, 128 insertions, 1 deletions
diff --git a/bin/app.psgi b/bin/app.psgi new file mode 100644 index 0000000..21c4aa8 --- /dev/null +++ b/bin/app.psgi @@ -0,0 +1,23 @@ +#!/usr/bin/perl +use strict; +use warnings; +use lib ('lib'); + +use FeedDiscovery::Handler; +use Tatsumaki::Application; +use Plack::Builder; +use Plack::Middleware::APIRateLimit::Backend::Redis; + +my $app = Tatsumaki::Application->new( [ '/' => 'FeedDiscovery::Handler' ], ); + +builder { + enable "Plack::Middleware::ConditionalGET"; + enable "Plack::Middleware::ETag"; + enable "Plack::Middleware::APIRateLimit", + backend => Plack::Middleware::APIRateLimit::Backend::Redis->new( + server => '127.0.0.1:6379', + ), + requests_per_hour => 4; + $app; +}; + diff --git a/lib/FeedDiscovery.pm b/lib/FeedDiscovery.pm index 94bb7aa..7505673 100644 --- a/lib/FeedDiscovery.pm +++ b/lib/FeedDiscovery.pm @@ -1,6 +1,5 @@ package FeedDiscovery; -use Moose; our $VERSION = '0.01'; 1; diff --git a/lib/FeedDiscovery/Handler.pm b/lib/FeedDiscovery/Handler.pm new file mode 100644 index 0000000..9f3f56b --- /dev/null +++ b/lib/FeedDiscovery/Handler.pm @@ -0,0 +1,93 @@ +package FeedDiscovery::Handler; + +use Moose; +extends 'Tatsumaki::Handler'; +__PACKAGE__->asynchronous(1); + +use JSON; +use Web::Scraper; +use AnyEvent::Redis; +use Tatsumaki::HTTPClient; +use Digest::SHA; + +has redis => ( + isa => 'Object', + is => 'rw', + lazy => 1, + default => sub { + my $redis = AnyEvent::Redis->new( + host => '127.0.0.1', + port => 6379, + on_error => sub { warn @_ }, + ); + } +); + +sub get { + my $self = shift; + + my $input = $self->request->parameters; + my $url = $input->{url}; + + if ( !$url ) { + return $self->render("index.html"); + } + else { + return $self->fetch_links($url); + } +} + +sub fetch_links { + my ( $self, $url ) = @_; + + my $key = Digest::SHA::sha1_hex($url); + + $self->redis->get( + $key, + sub { + my $value = shift; + if ($value) { + $self->response->header( + 'Content-Type' => 'application/json' ); + $self->finish($value); + } + else { + my $scraper = scraper { + process 'link[rel=~"alternate"]', "links[]" => { + href => '@href', + title => '@title', + type => '@type' + }; + }; + Tatsumaki::HTTPClient->new->get( + $url, + sub { + my $res = shift; + if ( $res->is_success ) { + my $xtract + = $scraper->scrape( \$res->decoded_content ); + my $json_content + = JSON::encode_json $xtract->{links}; + $self->redis->set( + $key => $json_content, + sub { + $self->response->header( 'Content-Type' => + 'application/json' ); + $self->finish( + JSON::encode_json $xtract->{links} ); + } + ); + } + else { + $self->response->code(500); + $self->finish( + "can't get url: " . $res->message ); + } + } + ); + } + } + ); +} + +1; diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..6ca4297 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,12 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>feeddiscover</title> + </head> + <body> + <h1>feeddiscover</h1> + <p><code>GET http://feeddiscover.tirnan0g.org/?url=http://lumberjaph.net/blog/</code><br /> +→ <code> +[{"href":"http://lumberjaph.net/blog/index.php/feed/","type":"application/rss+xml","title":"iâm a lumberjaph RSS Feed"}] +</code></p> +</html> |