259 lines
8.3 KiB
Perl
259 lines
8.3 KiB
Perl
package BotLib::Command;
|
|
# Парсит команды
|
|
|
|
use 5.030; ## no critic (ProhibitImplicitImport)
|
|
use strict;
|
|
use warnings;
|
|
use utf8;
|
|
use open qw (:std :utf8);
|
|
use English qw ( -no_match_vars );
|
|
|
|
use JSON::XS qw (encode_json);
|
|
use Log::Any qw ($log);
|
|
|
|
use BotLib::Conf qw (LoadConf);
|
|
use BotLib::Util qw (storedata rakedata deletedata timems utf2md5hex utf2sha1hex utf2sha224hex utf2sha256hex
|
|
utf2sha384hex utf2sha512hex utf2crc32hex utf2murmurhash utf2b64 urlencode irandom);
|
|
|
|
use version; our $VERSION = qw (1.0);
|
|
use Exporter qw (import);
|
|
our @EXPORT_OK = qw (Help Notify DelayedNotify PrintMsg Todo B64Str Md5Str Sha1Str Sha224Str Sha256Str Sha384Str
|
|
Sha512Str Crc32Str MurmurhashStr UrlencodeStr IrandNum);
|
|
|
|
local $OUTPUT_AUTOFLUSH = 1;
|
|
|
|
my $c = LoadConf();
|
|
|
|
# Возвращает список возможных команд
|
|
# $text Help()
|
|
sub Help {
|
|
my $text = '';
|
|
my $csign = $c->{csign};
|
|
$text .= "${csign}help - это сообщение\n";
|
|
$text .= "${csign}ping - попинговать бота\n";
|
|
$text .= "${csign}ver - написать что-то про версию ПО\n";
|
|
$text .= "${csign}cal - календарик\n";
|
|
$text .= "${csign}exit - завершить работу бота\n";
|
|
$text .= "${csign}quit - завершить работу бота\n";
|
|
$text .= "${csign}notify me after N [s|m|h] - одноразовая напоминалка через desktop notification\n";
|
|
$text .= "${csign}n N[s|m|h] message - одноразовая напоминалка через desktop notification\n";
|
|
$text .= "${csign}todo - выводит списк запланированных дел\n";
|
|
$text .= "${csign}todo -d N - удаляет из списка запланированных дел дело N\n";
|
|
$text .= "${csign}todo ДЕЛО - добавляет в списк запланированных дел ДЕЛО\n";
|
|
$text .= "${csign}sha1 STR - выводит sha1sum для STR\n";
|
|
$text .= "${csign}sha224 STR - выводит sha224sum для STR\n";
|
|
$text .= "${csign}sha256 STR - выводит sha256sum для STR\n";
|
|
$text .= "${csign}sha384 STR - выводит sha384sum для STR\n";
|
|
$text .= "${csign}sha512 STR - выводит sha512sum для STR\n";
|
|
$text .= "${csign}crc32 STR - выводит crc32 для STR\n";
|
|
$text .= "${csign}md5 STR - выводит md5sum для STR\n";
|
|
$text .= "${csign}murmurhash STR - выводит murmur hash для STR\n";
|
|
$text .= "${csign}b64 STR - выводит base64 для STR\n";
|
|
$text .= "${csign}urlencode STR - кодирует STR по urlencode\n";
|
|
$text .= "${csign}rand N - выдаёт рандомное целое число от 0 до указанного\n";
|
|
$text .= "${csign}unixtime - выдаёт текущее время в формате unix timestamp (секунды с 1 янв 1970)\n";
|
|
|
|
return $text;
|
|
}
|
|
|
|
# Одноразовая напоминалка. Сохраняет сообщение в базу notifications и отправляет его в delayed notifications.
|
|
# Возвращает либо строку-подтверждение, либо подсказку как пользоваться командой.
|
|
# $string Notify($chatid, $amount, $units, $message)
|
|
sub Notify {
|
|
my $chatid = shift;
|
|
my $amount = shift;
|
|
my $units = shift;
|
|
my $message = shift;
|
|
|
|
if (defined $units) {
|
|
if ($units eq 'm' || $units eq 'minute' || $units eq 'minutes') {
|
|
$amount = eval { $amount * 60 };
|
|
|
|
unless (defined $units) {
|
|
return sprintf ('Usage: %s NUM [s|seconds|m|minutes|h|hours]', $units);
|
|
}
|
|
} elsif ($units eq 'h' || $units eq 'hour' || $units eq 'hours') {
|
|
$amount = eval { $amount * 60 * 60 };
|
|
|
|
unless (defined $units) {
|
|
return sprintf ('Usage: %s NUM [s|seconds|m|minutes|h|hours]', $units);
|
|
}
|
|
} elsif ($units eq 's' || $units eq 'second' || $units eq 'seconds') {
|
|
$amount = eval { $amount + 0 };
|
|
|
|
unless (defined $units) {
|
|
return sprintf ('Usage: %s NUM [s|seconds|m|minutes|h|hours]', $units);
|
|
}
|
|
}
|
|
} else {
|
|
$amount = eval { $amount + 0 };
|
|
|
|
unless (defined $units) {
|
|
return sprintf ('Usage: %s NUM [s|seconds|m|minutes|h|hours]', $units);
|
|
}
|
|
}
|
|
|
|
my $timestamp = time () + $amount;
|
|
my $msg->{title} = 'Meow-bot notification';
|
|
my $json;
|
|
|
|
if (defined $message && $message ne '') {
|
|
$msg->{text} = $message;
|
|
} else {
|
|
$msg->{text} = 'Напоминалка!';
|
|
}
|
|
|
|
$json = encode_json $msg;
|
|
storedata ('notifications', $timestamp, $json, $c->{notifications}->{retention_days});
|
|
DelayedNotify ($c->{channels}->{notify}, $msg->{text});
|
|
|
|
return sprintf 'Notification will be sent after %d seconds', $amount;
|
|
}
|
|
|
|
# Пишет сообщение в чятик и складывает в БД, чтобы позже показать юзеру, когда он появится в чятике
|
|
# undef PrinfMsgForUser($userid, $chatid, $message)
|
|
sub DelayedNotify {
|
|
my $channel = shift;
|
|
my $message = shift;
|
|
|
|
my $timestamp = timems ();
|
|
my $data;
|
|
$data->{message} = $message;
|
|
$data->{channel} = $channel;
|
|
$data->{timestamp} = $timestamp;
|
|
$data->{expiration_time} = $c->{delayed_notifications}->{retention_days} * 24 * 60 * 60 * 1000 + $timestamp;
|
|
$data->{retention_days} = $c->{delayed_notifications}->{retention_days} ;
|
|
|
|
# Достанем список тех, кто есть в канальчике notify, им на джоине показывать сообщение не надо
|
|
my @users = keys %{$MAIN::IRC->channel_list->{$c->{channels}->{notify}}}; ## no critic (Modules::RequireExplicitInclusion)
|
|
$data->{users_shown} = \@users;
|
|
|
|
# TODO: Pretty jsonl
|
|
my $json = encode_json $data;
|
|
storedata ('delayed_notifications', timems (), $json, $c->{delayed_notifications}->{retention_days});
|
|
|
|
return;
|
|
}
|
|
|
|
# Пишет сообщение в чятик или юзеру
|
|
# undef PrintMsg($chatid, $text)
|
|
sub PrintMsg {
|
|
my $channel = shift;
|
|
my $message = shift;
|
|
|
|
$MAIN::IRC->send_long_message ('utf8', 0, 'PRIVMSG', $channel, $message); ## no critic (Modules::RequireExplicitInclusion)
|
|
$log->debug ("[DEBUG] message '$message' sent to $channel");
|
|
|
|
return;
|
|
}
|
|
|
|
# Выгребает список todo-шек из базы
|
|
# $msg = _todoPrint()
|
|
sub _todoPrint {
|
|
$log->debug ('[DEBUG] raking data from todo db');
|
|
my $todo = rakedata ('todo');
|
|
my $msg = '';
|
|
|
|
foreach (sort keys (%{$todo})) {
|
|
$msg .= sprintf "%d. %s\n", $_, $todo->{$_};
|
|
}
|
|
|
|
return $msg;
|
|
}
|
|
|
|
# Парсит запрос команды .todo
|
|
# $reply Todo($message)
|
|
sub Todo {
|
|
my $message = shift;
|
|
|
|
$log->debug ("$message");
|
|
my $reply;
|
|
|
|
if (($message eq 'todo') || ($message =~ /^todo\s+$/)) {
|
|
$log->debug ('[DEBUG] got todo command without arguments');
|
|
$reply = _todoPrint ();
|
|
} elsif ($message =~ /^todo\s+\-d\s+(\d+)\s*$/) {
|
|
$log->debug ('[DEBUG] got todo command with -d argument');
|
|
deletedata('todo', $1);
|
|
$reply = _todoPrint ();
|
|
} else {
|
|
if ($message =~ /^todo\s+(.*)/) {
|
|
my $data = $1;
|
|
$log->debug("[DEBUG] got todo command message: $message");
|
|
my $todo = rakedata ('todo');
|
|
my $num = int (keys %{$todo}) + 1;
|
|
storedata ('todo', $num, $data, 'never');
|
|
$reply = _todoPrint ();
|
|
} else {
|
|
$log->debug ('[DEBUG] got todo command with garbage');
|
|
}
|
|
}
|
|
|
|
return $reply;
|
|
}
|
|
|
|
sub B64Str {
|
|
my $str = shift;
|
|
return utf2b64 ($str);
|
|
}
|
|
|
|
sub Md5Str {
|
|
my $str = shift;
|
|
return utf2md5hex ($str);
|
|
}
|
|
|
|
sub Sha1Str {
|
|
my $str = shift;
|
|
return utf2sha1hex($str);
|
|
}
|
|
|
|
sub Sha224Str {
|
|
my $str = shift;
|
|
return utf2sha224hex($str);
|
|
}
|
|
|
|
sub Sha256Str {
|
|
my $str = shift;
|
|
return utf2sha256hex($str);
|
|
}
|
|
|
|
sub Sha384Str {
|
|
my $str = shift;
|
|
return utf2sha384hex($str);
|
|
}
|
|
|
|
sub Sha512Str {
|
|
my $str = shift;
|
|
return utf2sha512hex($str);
|
|
}
|
|
|
|
sub Crc32Str {
|
|
my $str = shift;
|
|
return utf2crc32hex($str);
|
|
}
|
|
|
|
sub MurmurhashStr {
|
|
my $str = shift;
|
|
return utf2murmurhash($str);
|
|
}
|
|
|
|
sub UrlencodeStr {
|
|
my $str = shift;
|
|
return urlencode ($str);
|
|
}
|
|
|
|
sub IrandNum {
|
|
my $num = shift;
|
|
$num = eval {$num + 0};
|
|
|
|
if (defined $num) {
|
|
return irandom($num);
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
|
|
1;
|
|
|
|
# vim: set ft=perl noet ai ts=4 sw=4 sts=4:
|