Dotfiles, utilities, and other apparatus.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

172 lines
3.5 KiB

#!/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;
}