diff options
Diffstat (limited to 'lib/Lifestream')
-rw-r--r-- | lib/Lifestream/Handler.pm | 17 | ||||
-rw-r--r-- | lib/Lifestream/Schema.pm | 6 | ||||
-rw-r--r-- | lib/Lifestream/Schema/Result/Entry.pm | 34 | ||||
-rw-r--r-- | lib/Lifestream/Schema/Result/Feed.pm | 34 | ||||
-rw-r--r-- | lib/Lifestream/Worker.pm | 90 |
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; |