summary refs log tree commit diff
diff options
context:
space:
mode:
authorfranck cuny <franck@lumberjaph.net>2010-03-30 20:53:21 +0200
committerfranck cuny <franck@lumberjaph.net>2010-03-30 20:53:21 +0200
commita6bd5aa5f6d9f8356fd6b4d80ef9b4ed92a47d3d (patch)
treeafdb4158cd316a81daa3de1dcce99a9ff82385c5
parentinitial commit (diff)
downloadfeeddiscovery-a6bd5aa5f6d9f8356fd6b4d80ef9b4ed92a47d3d.tar.gz
application
-rw-r--r--bin/app.psgi23
-rw-r--r--lib/FeedDiscovery.pm1
-rw-r--r--lib/FeedDiscovery/Handler.pm93
-rw-r--r--templates/index.html12
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 />
+&#8594; <code>
+[{"href":"http://lumberjaph.net/blog/index.php/feed/","type":"application/rss+xml","title":"iâm a lumberjaph RSS Feed"}]
+</code></p>
+</html>