summary refs log tree commit diff
path: root/lib/Lifestream
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Lifestream')
-rw-r--r--lib/Lifestream/Handler.pm17
-rw-r--r--lib/Lifestream/Schema.pm6
-rw-r--r--lib/Lifestream/Schema/Result/Entry.pm34
-rw-r--r--lib/Lifestream/Schema/Result/Feed.pm34
-rw-r--r--lib/Lifestream/Worker.pm90
5 files changed, 181 insertions, 0 deletions
diff --git a/lib/Lifestream/Handler.pm b/lib/Lifestream/Handler.pm
new file mode 100644
index 0000000..3dfd72d
--- /dev/null
+++ b/lib/Lifestream/Handler.pm
@@ -0,0 +1,17 @@
+package Lifestream::Handler;
+use Moose;
+extends 'Tatsumaki::Handler';
+
+sub get {
+    my $self = shift;
+    my %params = %{$self->request->params};
+    $self->render(
+        'lifestream.html',
+        {
+            memes    => $self->application->memes($params{page}),
+            services => $self->application->services
+        }
+    );
+}
+
+1;
diff --git a/lib/Lifestream/Schema.pm b/lib/Lifestream/Schema.pm
new file mode 100644
index 0000000..0bf0295
--- /dev/null
+++ b/lib/Lifestream/Schema.pm
@@ -0,0 +1,6 @@
+package Lifestream::Schema;
+use base qw/DBIx::Class::Schema/;
+
+__PACKAGE__->load_namespaces();
+
+1;
diff --git a/lib/Lifestream/Schema/Result/Entry.pm b/lib/Lifestream/Schema/Result/Entry.pm
new file mode 100644
index 0000000..43013c5
--- /dev/null
+++ b/lib/Lifestream/Schema/Result/Entry.pm
@@ -0,0 +1,34 @@
+package Lifestream::Schema::Result::Entry;
+use base qw/DBIx::Class/;
+
+__PACKAGE__->load_components(qw/Core/);
+__PACKAGE__->table('entry');
+__PACKAGE__->add_columns(
+    id => {
+        data_type   => "varchar",
+        is_nullable => 0,
+    },
+    permalink => {
+        data_type   => "varchar",
+        is_nullable => 0,
+    },
+    feedid => {
+        data_type   => "integer",
+        is_nullable => 0,
+    },
+    date => {
+        data_type   => "date",
+        is_nullable => 0,
+    },
+    title => {
+        data_type   => "text",
+        is_nullable => 0,
+    },
+);
+__PACKAGE__->set_primary_key('id');
+__PACKAGE__->belongs_to(
+    feed => 'Lifestream::Schema::Result::Feed',
+    'feedid'
+);
+
+1;
diff --git a/lib/Lifestream/Schema/Result/Feed.pm b/lib/Lifestream/Schema/Result/Feed.pm
new file mode 100644
index 0000000..8bb7bea
--- /dev/null
+++ b/lib/Lifestream/Schema/Result/Feed.pm
@@ -0,0 +1,34 @@
+package Lifestream::Schema::Result::Feed;
+use base qw/DBIx::Class/;
+
+__PACKAGE__->load_components(qw/Core/);
+__PACKAGE__->table('feed');
+__PACKAGE__->add_columns(
+    feedid => {
+        data_type         => "integer",
+        is_nullable       => 0,
+        is_auto_increment => 1
+    },
+    name => {
+        data_type   => "text",
+        is_nullable => 0,
+    },
+    profile_url => {
+        data_type   => "varchar",
+        is_nullable => 0,
+    },
+    feed_url => {
+        data_type   => "varchar",
+        is_nullable => 0,
+    },
+    favico_url => {
+        data_type   => "varchar",
+        is_nullable => 1,
+    }
+);
+__PACKAGE__->set_primary_key('feedid');
+__PACKAGE__->has_many(
+    entries => 'Lifestream::Schema::Result::Entry',
+    'feedid'
+);
+1;
diff --git a/lib/Lifestream/Worker.pm b/lib/Lifestream/Worker.pm
new file mode 100644
index 0000000..c22abcb
--- /dev/null
+++ b/lib/Lifestream/Worker.pm
@@ -0,0 +1,90 @@
+package Lifestream::Worker;
+use Moose;
+extends 'Tatsumaki::Service';
+use Digest::SHA qw(sha256_hex);
+
+use Lifestream::Schema;
+
+use Tatsumaki::HTTPClient;
+use Try::Tiny;
+use XML::Feed;
+
+has config => (
+    is  => "rw",
+    isa => "HashRef"
+);
+
+has schema => (
+    is      => 'ro',
+    isa     => 'Lifestream::Schema',
+    lazy    => 1,
+    default => sub {
+        my $self = shift;
+        return Lifestream::Schema->connect(
+            @{ $self->config->{connect_info} } );
+    }
+);
+
+sub start {
+    my $self = shift;
+    my $t;
+    $t = AE::timer 0, 15, sub {
+        $self->fetch_feeds;
+    };
+    #$self->fetch_feeds();
+}
+
+sub fetch_feeds {
+    my $self  = shift;
+    my $feeds = $self->schema->resultset('Feed')->search();
+    while ( my $feed = $feeds->next ) {
+        if ( !$feed->favico_url ) {
+            my $uri = URI->new( $feed->profile_url );
+            $uri->path('favicon.ico');
+            $self->schema->txn_do(
+                sub {
+                    $feed->update( { favico_url => $uri->as_string } );
+                }
+            );
+        }
+        $self->work_feed( $feed->feed_url, $feed->id );
+    }
+}
+
+sub work_feed {
+    my ( $self, $url, $id ) = @_;
+    warn "fetching $url\n";
+    Tatsumaki::HTTPClient->new->get(
+        $url,
+        sub {
+            my $res = shift;
+            if ( !$res->is_success ) {
+                warn "can't fetch $url\n";
+                return;
+            }
+            my $feed = XML::Feed->parse( \$res->content );
+            for my $entry ( $feed->entries ) {
+                my $entry_id = sha256_hex( $entry->link );
+                next if $self->schema->resultset('Entry')->find($id);
+                try {
+                    $self->schema->txn_do(
+                        sub {
+                            $self->schema->resultset('Entry')->find_or_create(
+                                {
+                                    id        => $entry_id,
+                                    permalink => $entry->link,
+                                    title     => $entry->title,
+                                    date      => $entry->issued,
+                                    feedid    => $id,
+                                }
+                            );
+                        }
+                    );
+                }
+                catch { warn "can't insert meme : $_\n"; };
+            }
+        }
+    );
+}
+
+1;