|
|
- #!/usr/bin/env perl
-
- =pod
-
- =head1 NAME
-
- pinboard - get some stuff from a pinboard account
-
- =head1 USAGE
-
- F<~/.pinboardrc> must contain a username in the format C<username:token>.
-
- # Show some recent stuff from today (empty if nothing):
- pinboard
-
- # List all tags:
- pinboard tags
-
- # Everything for a specific tag:
- pinboard by-tag some-tag
-
- =head1 DESCRIPTION
-
- A wrapper for some Pinboard API calls I use routinely.
-
- Pretty crap.
-
- =head1 AUTHOR
-
- L<Brennen Bearnes|https://p1k3.com/>
-
- =cut
-
- use strict;
- use warnings;
-
- use 5.10.0;
-
- use Carp;
- use Data::Dumper;
- use File::HomeDir;
- use Getopt::Long;
- use LWP::Simple;
- use Pod::Usage;
- use JSON;
- use Time::Piece;
-
- use utf8;
- use open qw(:std :utf8);
-
- # Handle options, including help generated from the POD above
- # (there's nothing else here at the moment, but it's a good place
- # to hang things if I want options):
- GetOptions(
- 'help' => sub { pod2usage(0) },
- ) or pod2usage(2);
-
- if (defined $ARGV[0] && $ARGV[0] eq 'tags') {
- print tags();
- } elsif (defined $ARGV[0] && $ARGV[0] eq 'by-tag') {
- croak "Must supply a tag name"
- unless defined $ARGV[1];
- say format_posts(by_tag($ARGV[1]));
- } else {
- my $today = localtime;
- say format_posts(recent($today));
- }
-
- sub tags {
- my $token = get_token();
-
- my $url = 'https://api.pinboard.in/v1/tags/get?format=json&auth_token=' . $token;
- my $pinboard_json = get($url);
-
- # https://stackoverflow.com/questions/45941522/parsing-utf-8-json-with-perl
- # Strip byte order mark:
- # $pinboard_json =~ s/^\N{BOM}//g;
- $pinboard_json =~ s/^[^\x00-\x7f]+//;
-
- my $JSON = JSON->new->utf8->pretty;
- my $pinboard_hashref = $JSON->decode($pinboard_json);
- my %tags = %{ $pinboard_hashref };
- my $output = '';
- foreach my $tag (keys %tags) {
- $output .= "$tag\n";
- }
- return $output;
- }
-
- sub by_tag {
- my $tag = shift;
- my $token = get_token();
-
- # lol this is terrible
- my $url = 'https://api.pinboard.in/v1/posts/all?tag='
- . $tag
- . '&format=json&auth_token=' . $token;
- my $pinboard_json = get($url);
- # print $url;
- # print $pinboard_json;
- my $JSON = JSON->new->utf8->pretty;
- my $pinboard_hashref = $JSON->decode($pinboard_json);
-
- return @{ $pinboard_hashref };
- }
-
- sub recent {
- my ($day) = @_;
-
- my $token = get_token();
-
- my $url = $day->strftime(
- 'https://api.pinboard.in/v1/posts/get?dt=%Y-%m-%d&meta=yes&format=json&auth_token='
- . $token
- );
-
- my $pinboard_json = get($url);
- my $JSON = JSON->new->utf8->pretty;
- my $pinboard_hashref = $JSON->decode($pinboard_json);
- return @{ $pinboard_hashref->{posts} };
- }
-
- # Take a list of posts and format them for display
- sub format_posts {
- my @output;
- foreach my $post (@_)
- {
- # push @output, Dumper($post);
- push @output,
- "$post->{time}\t$post->{href}\t$post->{description}\t$post->{tags}";
- }
-
- if (@output > 0) {
- return join "\n", @output;
- }
- return;
- }
-
- # PHP-style file-content grabbing:
- sub file_get_contents {
- my ($file) = @_;
-
- open my $fh, '<', $file
- or croak "Couldn't open $file: $!\n";
-
- my $contents;
- {
- # line separator:
- local $/ = undef;
- $contents = <$fh>;
- }
-
- close $fh or croak "Couldn't close $file: $!";
-
- return $contents;
- }
-
- sub get_token {
- # See the bit about auth here:
- # https://pinboard.in/api/
- my $home = File::HomeDir->my_home;
- my $rc_path = "${home}/.pinboardrc";
- my $token;
- if (-e $rc_path) {
- $token = file_get_contents($rc_path);
- } else {
- die("No $rc_path found - do you need to create a file with credentials?");
- }
- chomp($token);
-
- return $token;
- }
|