i3blocks-pkfront.pl

#!/usr/bin/env perl
# vim: set noexpandtab syntax=perl6 syn=perl :
#
# i3blocks-pkfront.pl - written by the Iris System <iris@iris.ac.nz>,
# released into the public domain (or licensed under CC0, as required)
#
# a script for i3blocks / waybar to output the current fronters for a 
# system (where a system ID is given in ARGV), using PluralKit APIv2.
#
# usage: i3blocks-pkfront.pl <system id> <format>
# - <system id> is the PluralKit system ID
# - <format> is either:
#   - "json" for waybar-compatible JSON
#   - "i3blocks" for i3blocks-compatible newline-separated output
#
# known issues:
# - has no token support, requires current front to be public
#
# dependencies: (as Fedora package names)
# - perl-JSON
# - perl-LWP-UserAgent-Determined
# - perl-LWP-Protocol-https
#
# latest version of this code is always available at:
#   <https://irys.cc/misc/i3blocks-pkfront.pl.html>
#
# have fun!

use utf8;
use strict;
use warnings;
use open qw( :std :encoding(UTF-8) );

use JSON;
use LWP::UserAgent;

# constants
my $api_base = "https://api.pluralkit.me";

# get system ID from cmdline
my ($system_id, $output_format) = @ARGV;
die "no system ID given" unless defined $system_id;
unless (defined $output_format) {
	warn "no explicit output format, using i3blocks";
	$output_format = "i3blocks";
}

# create user-agent
my $ua = LWP::UserAgent->new;
$ua->agent("i3blocks-pkfront/0.1 (https://irys.cc/misc/i3blocks-pkfront.html) LWP/$LWP::VERSION ");

# build request
my $front_req = HTTP::Request->new(GET => "$api_base/v2/systems/$system_id/fronters");
$front_req->header(Accept => 'application/json');

# make request, bail on error
my $front_res = $ua->request($front_req);
die "PK API response not successful" unless $front_res->is_success;

# decode JSON
my $front_data = decode_json($front_res->content);

# collect member info
my (@member_basenames, @member_info);
foreach (@{ $front_data->{members} }) {
	my %tmember = %$_;

	my $tmember_n = ($tmember{name} || $tmember{display_name}) =~ y/\n/ /r;
	my $tmember_dn = ($tmember{display_name} || $tmember{name}) =~ y/\n/ /r;
	my $tmember_prns = ($tmember{pronouns} || 'pronouns not set') =~ y/\n/ /r;

	push @member_basenames, $tmember_n;
	push @member_info, sprintf("%s (%s)", $tmember_dn, $tmember_prns);
}

# construct output
my @output_classes = ( sprintf('pkfront-system-%s', $system_id), );
if (scalar @member_basenames == 0) {
	push @member_basenames, "no fronters";
	push @output_classes, "pkfront-nofronters";
}

my %output_data = (
	text => sprintf("%s: %s", $system_id, join(', ', @member_basenames)),
	tooltip => sprintf("%s", join(', ', @member_info)),
	class => \@output_classes, 
);

# output!
if ($output_format eq "json") {
	printf "%s\n", JSON->new->latin1->convert_blessed->encode(\%output_data);
} else {
	printf "%s\n%s\n%s", $output_data{text}, $output_data{tooltip}, join(' ', @{ $output_data{class} });
}