mirror of
https://github.com/pragma-/pbot.git
synced 2024-12-23 11:12:42 +01:00
Fix issues with Users and add date
command
This commit is contained in:
parent
718b52bc03
commit
4e27b036cd
@ -140,48 +140,55 @@ sub save {
|
||||
$self->{users}->save;
|
||||
}
|
||||
|
||||
sub hostmask_or_account_name {
|
||||
sub find_user_account {
|
||||
my ($self, $channel, $hostmask) = @_;
|
||||
|
||||
$channel = lc $channel;
|
||||
$hostmask = lc $hostmask;
|
||||
$channel = '.*' if $channel !~ /^#/;
|
||||
my ($found_channel, $found_hostmask) = ($channel, $hostmask);
|
||||
|
||||
if (exists $self->{users}->{hash}->{$channel}) {
|
||||
if (not exists $self->{users}->{hash}->{$channel}->{$hostmask}) {
|
||||
my $last_level = 0;
|
||||
# find hostmask by account name or wildcard
|
||||
foreach my $mask (keys %{ $self->{users}->{hash}->{$channel} }) {
|
||||
next if $mask eq '_name';
|
||||
if (lc $self->{users}->{hash}->{$channel}->{$mask}->{name} eq $hostmask) {
|
||||
if ($last_level < $self->{users}->{hash}->{$channel}->{$mask}->{level}) {
|
||||
$hostmask = $mask;
|
||||
$last_level = $self->{users}->{hash}->{$channel}->{$mask}->{level};
|
||||
foreach my $chan (keys %{ $self->{users}->{hash} }) {
|
||||
if ($channel !~ m/^#/ or $channel =~ m/^$chan$/i) {
|
||||
if (not exists $self->{users}->{hash}->{$chan}->{$hostmask}) {
|
||||
my $last_level = 0;
|
||||
# find hostmask by account name or wildcard
|
||||
foreach my $mask (keys %{ $self->{users}->{hash}->{$chan} }) {
|
||||
next if $mask eq '_name';
|
||||
if (lc $self->{users}->{hash}->{$chan}->{$mask}->{name} eq $hostmask) {
|
||||
if ($last_level <= $self->{users}->{hash}->{$chan}->{$mask}->{level}) {
|
||||
$found_hostmask = $mask;
|
||||
$found_channel = $chan;
|
||||
$last_level = $self->{users}->{hash}->{$chan}->{$mask}->{level};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($mask =~ /[*?]/) {
|
||||
# contains * or ? so it's converted to a regex
|
||||
my $mask_quoted = quotemeta $mask;
|
||||
$mask_quoted =~ s/\\\*/.*?/g;
|
||||
$mask_quoted =~ s/\\\?/./g;
|
||||
if ($hostmask =~ m/^$mask_quoted$/i) {
|
||||
if ($last_level < $self->{users}->{hash}->{$channel}->{$mask}->{level}) {
|
||||
$hostmask = $mask;
|
||||
$last_level = $self->{users}->{hash}->{$channel}->{$mask}->{level};
|
||||
if ($mask =~ /[*?]/) {
|
||||
# contains * or ? so it's converted to a regex
|
||||
my $mask_quoted = quotemeta $mask;
|
||||
$mask_quoted =~ s/\\\*/.*?/g;
|
||||
$mask_quoted =~ s/\\\?/./g;
|
||||
if ($hostmask =~ m/^$mask_quoted$/i) {
|
||||
if ($last_level <= $self->{users}->{hash}->{$chan}->{$mask}->{level}) {
|
||||
$found_hostmask = $mask;
|
||||
$found_channel = $chan;
|
||||
$last_level = $self->{users}->{hash}->{$chan}->{$mask}->{level};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $hostmask;
|
||||
return ($found_channel, $found_hostmask);
|
||||
}
|
||||
|
||||
sub find_admin {
|
||||
my ($self, $channel, $hostmask, $min_level) = @_;
|
||||
$min_level //= 1;
|
||||
|
||||
($channel, $hostmask) = $self->find_user_account($channel, $hostmask);
|
||||
|
||||
$channel = $self->{pbot}->{registry}->get_value('irc', 'botnick') if not defined $channel;
|
||||
$hostmask = '.*' if not defined $hostmask;
|
||||
$hostmask = lc $hostmask;
|
||||
@ -199,13 +206,13 @@ sub find_admin {
|
||||
$hostmask_quoted =~ s/\\\?/./g;
|
||||
if ($hostmask =~ m/^$hostmask_quoted$/i) {
|
||||
my $temp = $self->{users}->{hash}->{$channel_regex}->{$hostmask_regex};
|
||||
$admin = $temp if $temp->{level} >= $min_level and (not defined $admin or $admin->{level} < $temp->{level});
|
||||
$admin = $temp if $temp->{level} >= $min_level and (not defined $admin or $admin->{level} <= $temp->{level});
|
||||
}
|
||||
} else {
|
||||
# direct comparison
|
||||
if ($hostmask eq lc $hostmask_regex) {
|
||||
my $temp = $self->{users}->{hash}->{$channel_regex}->{$hostmask_regex};
|
||||
$admin = $temp if $temp->{level} >= $min_level and (not defined $admin or $admin->{level} < $temp->{level});
|
||||
$admin = $temp if $temp->{level} >= $min_level and (not defined $admin or $admin->{level} <= $temp->{level});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -271,6 +278,15 @@ sub logout {
|
||||
delete $user->{loggedin} if defined $user;
|
||||
}
|
||||
|
||||
sub get_loggedin_user_metadata {
|
||||
my ($self, $channel, $hostmask, $key) = @_;
|
||||
my $user = $self->loggedin($channel, $hostmask);
|
||||
if ($user) {
|
||||
return $user->{lc $key};
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub logincmd {
|
||||
my ($self, $from, $nick, $user, $host, $arguments) = @_;
|
||||
my $channel = $from;
|
||||
@ -314,6 +330,7 @@ sub useradd {
|
||||
my $admin = $self->{pbot}->{users}->find_admin($channel, "$nick!$user\@$host");
|
||||
|
||||
if (not $admin) {
|
||||
$channel = 'global' if $channel eq '.*';
|
||||
return "You are not an admin for $channel; cannot add users to that channel.\n";
|
||||
}
|
||||
|
||||
@ -335,8 +352,7 @@ sub userdel {
|
||||
return "/msg $nick Usage: userdel <channel> <hostmask or account name>";
|
||||
}
|
||||
|
||||
$hostmask = $self->hostmask_or_account_name($channel, $hostmask);
|
||||
$channel = '.*' if $channel !~ /^#/;
|
||||
($channel, $hostmask) = $self->find_user_account($channel, $hostmask);
|
||||
return $self->remove_user($channel, $hostmask);
|
||||
}
|
||||
|
||||
@ -348,15 +364,16 @@ sub userset {
|
||||
return "Usage: userset <channel> <hostmask or account name> [key] [value]";
|
||||
}
|
||||
|
||||
$hostmask = $self->hostmask_or_account_name($channel, $hostmask);
|
||||
my $admin = $self->find_admin($channel, "$nick!$user\@$host");
|
||||
my $target = $self->find_user($channel, $hostmask);
|
||||
|
||||
if (not $admin) {
|
||||
$channel = 'global' if $channel eq '.*';
|
||||
return "You are not an admin for $channel; cannot modify their users.";
|
||||
}
|
||||
|
||||
if (not $target) {
|
||||
$channel = 'global' if $channel eq '.*';
|
||||
return "There is no user $hostmask in channel $channel.";
|
||||
}
|
||||
|
||||
@ -369,7 +386,7 @@ sub userset {
|
||||
return "You may not modify users higher in level than you.";
|
||||
}
|
||||
|
||||
$channel = '.*' if $channel !~ /^#/;
|
||||
($channel, $hostmask) = $self->find_user_account($channel, $hostmask);
|
||||
my $result = $self->{users}->set($channel, $hostmask, $key, $value);
|
||||
$result =~ s/^password => .*;$/password => <private>;/m;
|
||||
return $result;
|
||||
@ -384,22 +401,23 @@ sub userunset {
|
||||
}
|
||||
|
||||
my $admin = $self->find_admin($channel, "$nick!$user\@$host");
|
||||
$hostmask = $self->hostmask_or_account_name($channel, $hostmask);
|
||||
my $target = $self->find_user($channel, $hostmask);
|
||||
|
||||
if (not $admin) {
|
||||
$channel = 'global' if $channel eq '.*';
|
||||
return "You are not an admin for $channel; cannot modify their users.";
|
||||
}
|
||||
|
||||
if (not $target) {
|
||||
$channel = 'global' if $channel eq '.*';
|
||||
return "There is no user $hostmask in channel $channel.";
|
||||
}
|
||||
|
||||
if ($target->{level} >= $user->{level}) {
|
||||
return "You may not modify users equal or higher in level than you.";
|
||||
if ($target->{level} > $admin->{level}) {
|
||||
return "You may not modify users higher in level than you.";
|
||||
}
|
||||
|
||||
$channel = '.*' if $channel !~ /^#/;
|
||||
($channel, $hostmask) = $self->find_user_account($channel, $hostmask);
|
||||
return $self->{users}->unset($channel, $hostmask, $key);
|
||||
}
|
||||
|
||||
@ -411,14 +429,11 @@ sub mycmd {
|
||||
return "Usage: my <key> [value]";
|
||||
}
|
||||
|
||||
$key = lc $key;
|
||||
my $channel = $from;
|
||||
$channel = '.*' if $channel !~ /^#/;
|
||||
my $hostmask = $self->hostmask_or_account_name($channel, "$nick!$user\@$host");
|
||||
my $u = $self->find_user($channel, $hostmask);
|
||||
my $hostmask = "$nick!$user\@$host";
|
||||
|
||||
print "hostmask: $hostmask\n";
|
||||
use Data::Dumper;
|
||||
print Dumper \$u;
|
||||
my $u = $self->find_user($channel, $hostmask);
|
||||
|
||||
if (not $u) {
|
||||
$channel = '.*';
|
||||
@ -428,13 +443,15 @@ sub mycmd {
|
||||
$u->{loggedin} = 1;
|
||||
}
|
||||
|
||||
if ($u->{level} == 0) {
|
||||
if (defined $value and $u->{level} == 0) {
|
||||
my @disallowed = qw/level autoop autovoice/;
|
||||
if (grep { lc $key } @disallowed) {
|
||||
if (grep { $_ eq $key } @disallowed) {
|
||||
return "You must be an admin to set $key.";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
($channel, $hostmask) = $self->find_user_account($channel, $hostmask);
|
||||
my $result = $self->{users}->set($channel, $hostmask, $key, $value);
|
||||
$result =~ s/^password => .*;$/password => <private>;/m;
|
||||
return $result;
|
||||
|
55
Plugins/Date.pm
Normal file
55
Plugins/Date.pm
Normal file
@ -0,0 +1,55 @@
|
||||
# File: Date.pm
|
||||
# Author: pragma-
|
||||
#
|
||||
# Purpose: Adds command to display time and date for timezones.
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package Plugins::Date;
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use feature 'unicode_strings';
|
||||
|
||||
use Carp ();
|
||||
|
||||
sub new {
|
||||
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref $_[1] eq 'HASH';
|
||||
my ($class, %conf) = @_;
|
||||
my $self = bless {}, $class;
|
||||
$self->initialize(%conf);
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub initialize {
|
||||
my ($self, %conf) = @_;
|
||||
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
|
||||
$self->{pbot}->{registry}->add_default('text', 'date', 'default_timezone', 'UTC');
|
||||
$self->{pbot}->{commands}->register(sub { $self->datecmd(@_) }, "date", 0);
|
||||
}
|
||||
|
||||
sub unload {
|
||||
my $self = shift;
|
||||
$self->{pbot}->{commands}->unregister("date");
|
||||
}
|
||||
|
||||
sub datecmd {
|
||||
my ($self, $from, $nick, $user, $host, $arguments, $stuff) = @_;
|
||||
|
||||
my $timezone = $self->{pbot}->{registry}->get_value('date', 'default_timezone') // 'UTC';
|
||||
my $tz_override = $self->{pbot}->{users}->get_loggedin_user_metadata($from, "$nick!$user\@$host", 'timezone');
|
||||
$timezone = $tz_override if $tz_override;
|
||||
|
||||
my $newstuff = {
|
||||
from => $from, nick => $nick, user => $user, host => $host,
|
||||
command => "date_module $timezone", root_channel => $from, root_keyword => "date_module",
|
||||
keyword => "date_module", arguments => "$timezone"
|
||||
};
|
||||
|
||||
$self->{pbot}->{factoids}->{factoidmodulelauncher}->execute_module($newstuff);
|
||||
}
|
||||
|
||||
1;
|
13
data/factoids
vendored
13
data/factoids
vendored
@ -5540,6 +5540,19 @@
|
||||
"ref_user" : "esselfe!~bsfc@unaffiliated/esselfe",
|
||||
"type" : "text"
|
||||
},
|
||||
"date_module" : {
|
||||
"_name" : "date_module",
|
||||
"action" : "date.sh",
|
||||
"add_nick" : 1,
|
||||
"created_on" : 1579985843.56774,
|
||||
"enabled" : 1,
|
||||
"nooverride" : 1,
|
||||
"owner" : "pragma-!~chaos@unaffiliated/pragmatic-chaos",
|
||||
"rate_limit" : "15",
|
||||
"ref_count" : 0,
|
||||
"ref_user" : "nobody",
|
||||
"type" : "module"
|
||||
},
|
||||
"ddd" : {
|
||||
"_name" : "ddd",
|
||||
"action" : "a graphical front end to gdb and other debuggers (http://www.gnu.org/software/ddd/)",
|
||||
|
13
modules/date.sh
vendored
Executable file
13
modules/date.sh
vendored
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
export TZ=UTC
|
||||
if (( $# )) && ! read -r TZ < <(IFS=_; find -L /usr/share/zoneinfo/posix -type f -iname "*$**" -printf '%P\n' -quit); then
|
||||
echo "No match for '$*'." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ $TZ != UTC ]]; then
|
||||
_city=${TZ##*/}
|
||||
echo "It's $(date) in ${_city//_/ }."
|
||||
else
|
||||
echo "It's $(date)."
|
||||
fi
|
Loading…
Reference in New Issue
Block a user