理系学生日記

おまえはいつまで学生気分なのか

Pocket で特定のタグを付けたエントリを自動ではてブする

これでできる。
15 分毎で cron 登録した。

#!/usr/bin/env perl
use strict;
use warnings;

use Getopt::Long qw(:config posix_default no_ignore_case gnu_compat);
use Pod::Usage;
use Config::Pit;
use Array::Diff;
use Log::Minimal;
use Try::Tiny;
use File::Stamped;
use Data::Dumper;

use WebService::Pocket::Lite;
use WebService::Hatena::Bookmark::Lite;

Getopt::Long::GetOptions(
    'target-tag=s' => \my @target_tags,
    'logdir=s' => \my $logdir,
    'interval=i' => \my $interval,
    'help|?' => \my $help,
) or pod2usage(2);

pod2usage(2) unless scalar(@target_tags) > 0;
pod2usage(2) if (not $logdir) or (not $interval);
pos2usage(-exitstatus => 0, -verbose => 2) if $help;

my $fh = File::Stamped->new( pattern => "$logdir/hatena2pocket.log.%Y-%m-%d" );
local $Log::Minimal::PRINT = sub {
    my ( $time, $type, $message, $trace) = @_;
    print {$fh} "$time [$type] $message at $trace\n";
};

run();


sub run {
    infof("$0 starts.");

    my $pocket = pocket_client();
    try {
        my @entries = extract_entries($pocket, @target_tags);
        
        infof(scalar(@entries) . " entries retrieved");
        hatena_bookmark(@entries);
        
        archive($pocket, @entries);
    } catch {
        critff( $_ );
    } finally {
        infof("$0 ends.");
    };

};

sub extract_entries {
    my ($pocket, @targettags) = @_;

    my @entries;
    foreach my $targettag (@targettags) {

        my $res = $pocket->retrieve({
            state => 'unread',
            tag => $targettag,
            detailType => 'complete',
            since => time() - $interval,
        });

        if ( ref($res->{list}) eq 'HASH' ) {
            push @entries, values %{$res->{list}};
        }
    }
    @entries;
}

sub pocket_client {
    my $conf = pit_get('getpocket.com', require => {
        consumer_key => 'Pocket consumer key',
        access_token => 'Pocket access token',
    });
   
    my $pocket = WebService::Pocket::Lite->new(
        consumer_key => $conf->{consumer_key},
        access_token => $conf->{access_token},
    );
}

sub hatena_bookmark {
    my @entries = @_;

    my $conf = pit_get('www.hatena.ne.jp', require => {
        username => 'Hatena username',
        password => 'Hatena password',
    });

    my $bookmark = WebService::Hatena::Bookmark::Lite->new(
        username => $conf->{username},
        password => $conf->{password},
    );

    foreach my $entry (@entries) {
        my @tag = keys %{$entry->{tags}};
        my $tag = Array::Diff->diff( \@tag, \@target_tags )->deleted;
        
        my $uri = $bookmark->add(
            url => $entry->{given_url},
            tag => $tag,
        );
    };
}

sub archive {
    my ($pocket, @entries) = @_;

    foreach my $entry (@entries) {
        $pocket->push_archive({ item_id => $entry->{item_id } });
    }
    $pocket->send;
}

    
__END__

=head1 NAME

hatena2pocket.pl - transfers given-tagged entries in Pocket to Hatena Bookmark.

=head1 SYNOPSIS

hatena2pocket.pl --target-tag bookmark --target-tag b --logdir /var/tmp --interval 3600

Options:
--target-tag tag name in Pocket.
tagged entries with these tags are extracted from Pocket.
--logdir log directory to which this app writes.
--interval seconds since when target entries retrieved.

=head1 Details

Tagged entries with given tags on command lines are extracted from Pocket,
and bookmarked in Hatena Bookmark.

These entries in Pocket are archived.