2021-07-21 21:43:30 +02:00
|
|
|
# File: NickList.pm
|
|
|
|
#
|
|
|
|
# Purpose: Registers command for viewing nick list and nick metadata.
|
|
|
|
|
|
|
|
# SPDX-FileCopyrightText: 2021 Pragmatic Software <pragma78@gmail.com>
|
|
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
|
|
|
|
package PBot::Core::Commands::NickList;
|
|
|
|
|
|
|
|
use PBot::Imports;
|
2021-07-23 16:24:30 +02:00
|
|
|
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;
|