pbot/lib/PBot/Core/Commands/NickList.pm

186 lines
6.1 KiB
Perl
Raw Normal View History

2021-07-21 21:43:30 +02:00
# File: NickList.pm
#
# Purpose: Registers command for viewing nick list and nick metadata.
2023-02-21 06:31:52 +01:00
# SPDX-FileCopyrightText: 2014-2023 Pragmatic Software <pragma78@gmail.com>
2021-07-21 21:43:30 +02:00
# SPDX-License-Identifier: MIT
package PBot::Core::Commands::NickList;
use PBot::Imports;
use parent 'PBot::Core::Class';
2021-07-21 21:43:30 +02:00
use Time::HiRes qw/gettimeofday/;
use Time::Duration qw/concise ago/;
sub initialize {
my ($self, %conf) = @_;
$self->{pbot}->{commands}->register(sub { $self->cmd_nicklist(@_) }, "nicklist", 1);
}
sub cmd_nicklist {
my ($self, $context) = @_;
my $usage = "Usage: nicklist (<channel [nick]> | <nick>) [-sort <by>] [-hostmask] [-join]; -hostmask shows hostmasks instead of nicks; -join includes join time";
my $sort_method = 'nick';
my $full_hostmask = 0;
my $include_join = 0;
2021-07-31 00:01:38 +02:00
my %opts = (
sort => \$sort_method,
hostmask => \$full_hostmask,
join => \$include_join,
);
2021-07-21 21:43:30 +02:00
2021-07-31 00:01:38 +02:00
my ($opt_args, $opt_error) = $self->{pbot}->{interpreter}->getopt(
$context->{arguments},
\%opts,
['bundling_override'],
'sort|s=s',
'hostmask|hm',
'join|j',
2021-07-21 21:43:30 +02:00
);
2021-07-31 00:01:38 +02:00
return "$opt_error; $usage" if defined $opt_error;
return "Too many arguments -- $usage" if @$opt_args > 2;
return $usage if @$opt_args == 0 or not length $opt_args->[0];
2021-07-21 21:43:30 +02:00
my %sort = (
'spoken' => sub {
if ($_[1] eq '+') {
return $_[0]->{$b}->{timestamp} <=> $_[0]->{$a}->{timestamp};
} else {
return $_[0]->{$a}->{timestamp} <=> $_[0]->{$b}->{timestamp};
}
},
'join' => sub {
if ($_[1] eq '+') {
return $_[0]->{$b}->{join} <=> $_[0]->{$a}->{join};
} else {
return $_[0]->{$a}->{join} <=> $_[0]->{$b}->{join};
}
},
'host' => sub {
if ($_[1] eq '+') {
return lc $_[0]->{$a}->{host} cmp lc $_[0]->{$b}->{host};
} else {
return lc $_[0]->{$b}->{host} cmp lc $_[0]->{$a}->{host};
}
},
'nick' => sub {
if ($_[1] eq '+') {
return lc $_[0]->{$a}->{nick} cmp lc $_[0]->{$b}->{nick};
} else {
return lc $_[0]->{$b}->{nick} cmp lc $_[0]->{$a}->{nick};
}
},
);
my $sort_direction = '+';
if ($sort_method =~ s/^(\+|\-)//) {
$sort_direction = $1;
}
if (not exists $sort{$sort_method}) {
return "Invalid sort method '$sort_method'; valid methods are: "
. join(', ', sort keys %sort) . "; prefix with - to invert sort direction.";
}
# insert from channel as first argument if first argument is not a channel
2021-07-31 00:01:38 +02:00
if ($opt_args->[0] !~ /^#/) {
unshift @$opt_args, $context->{from};
2021-07-21 21:43:30 +02:00
}
my $nicklist = $self->{pbot}->{nicklist}->{nicklist};
# ensure channel has a nicklist
2021-07-31 00:01:38 +02:00
if (not exists $nicklist->{lc $opt_args->[0]}) {
return "No nicklist for channel $opt_args->[0].";
2021-07-21 21:43:30 +02:00
}
my $result;
2021-07-31 00:01:38 +02:00
if (@$opt_args == 1) {
2021-07-21 21:43:30 +02:00
# nicklist for a specific channel
2021-07-31 00:01:38 +02:00
my $count = keys %{$nicklist->{lc $opt_args->[0]}};
2021-07-21 21:43:30 +02:00
2021-07-31 00:01:38 +02:00
$result = "$count nick" . ($count == 1 ? '' : 's') . " in $opt_args->[0]:\n";
2021-07-21 21:43:30 +02:00
foreach my $entry (
sort {
2021-07-31 00:01:38 +02:00
$sort{$sort_method}->($nicklist->{lc $opt_args->[0]}, $sort_direction)
} keys %{$nicklist->{lc $opt_args->[0]}}
2021-07-21 21:43:30 +02:00
) {
if ($full_hostmask) {
2021-07-31 00:01:38 +02:00
$result .= " $nicklist->{lc $opt_args->[0]}->{$entry}->{hostmask}";
2021-07-21 21:43:30 +02:00
} else {
2021-07-31 00:01:38 +02:00
$result .= " $nicklist->{lc $opt_args->[0]}->{$entry}->{nick}";
2021-07-21 21:43:30 +02:00
}
my $sep = ': ';
2021-07-31 00:01:38 +02:00
if ($nicklist->{lc $opt_args->[0]}->{$entry}->{timestamp} > 0) {
my $duration = concise ago (gettimeofday - $nicklist->{lc $opt_args->[0]}->{$entry}->{timestamp});
2021-07-21 21:43:30 +02:00
$result .= "${sep}last spoken $duration";
$sep = ', ';
}
2021-07-31 00:01:38 +02:00
if ($include_join and $nicklist->{lc $opt_args->[0]}->{$entry}->{join} > 0) {
my $duration = concise ago (gettimeofday - $nicklist->{lc $opt_args->[0]}->{$entry}->{join});
2021-07-21 21:43:30 +02:00
$result .= "${sep}joined $duration";
$sep = ', ';
}
2021-07-31 00:01:38 +02:00
foreach my $key (sort keys %{$nicklist->{lc $opt_args->[0]}->{$entry}}) {
2021-07-21 21:43:30 +02:00
next if grep { $key eq $_ } qw/nick user host join timestamp hostmask/;
2021-07-31 00:01:38 +02:00
if ($nicklist->{lc $opt_args->[0]}->{$entry}->{$key} == 1) {
2021-07-21 21:43:30 +02:00
$result .= "$sep$key";
} else {
2021-07-31 00:01:38 +02:00
$result .= "$sep$key => $nicklist->{lc $opt_args->[0]}->{$entry}->{$key}";
2021-07-21 21:43:30 +02:00
}
$sep = ', ';
}
$result .= "\n";
}
} else {
# nicklist for a specific user
2021-07-31 00:01:38 +02:00
if (not exists $nicklist->{lc $opt_args->[0]}->{lc $opt_args->[1]}) {
return "No such nick $opt_args->[1] in channel $opt_args->[0].";
2021-07-21 21:43:30 +02:00
}
2021-07-31 00:01:38 +02:00
$result = "Nicklist information for $nicklist->{lc $opt_args->[0]}->{lc $opt_args->[1]}->{hostmask} in $opt_args->[0]: ";
2021-07-21 21:43:30 +02:00
my $sep = '';
2021-07-31 00:01:38 +02:00
if ($nicklist->{lc $opt_args->[0]}->{lc $opt_args->[1]}->{timestamp} > 0) {
my $duration = concise ago (gettimeofday - $nicklist->{lc $opt_args->[0]}->{lc $opt_args->[1]}->{timestamp});
2021-07-21 21:43:30 +02:00
$result .= "last spoken $duration";
$sep = ', ';
}
2021-07-31 00:01:38 +02:00
if ($nicklist->{lc $opt_args->[0]}->{lc $opt_args->[1]}->{join} > 0) {
my $duration = concise ago (gettimeofday - $nicklist->{lc $opt_args->[0]}->{lc $opt_args->[1]}->{join});
2021-07-21 21:43:30 +02:00
$result .= "${sep}joined $duration";
$sep = ', ';
}
2021-07-31 00:01:38 +02:00
foreach my $key (sort keys %{$nicklist->{lc $opt_args->[0]}->{lc $opt_args->[1]}}) {
2021-07-21 21:43:30 +02:00
next if grep { $key eq $_ } qw/nick user host join timestamp hostmask/;
2021-07-31 00:01:38 +02:00
$result .= "$sep$key => $nicklist->{lc $opt_args->[0]}->{lc $opt_args->[1]}->{$key}";
2021-07-21 21:43:30 +02:00
$sep = ', ';
}
$result .= 'no details' if $sep eq '';
}
return $result;
}
1;