Compare commits

...

3 Commits

Author SHA1 Message Date
eleksir
dbefe68350 Last commit 2022-04-23 13:58:00 +03:00
eleksir
066e961bd2 Добавлено поле misc->good_morning, глубже lint-уем входящий json
* Добавлено описание поля misc->good_morning в README
* Проверяем входной JSON на наличие всех полей и фиксим дефолтами
* Более аккуратная работа с substr - больше перестраховок
* Правка коментариев
2022-04-04 11:26:37 +03:00
eleksir
1f821453cb Более аккуратно используем substr(), подпираем ответ на изменение кармы 2022-03-27 20:34:17 +03:00
5 changed files with 86 additions and 69 deletions

View File

@@ -111,3 +111,5 @@ lib_sections = NAME | VERSION | DESCRIPTION | AUTHOR | LICENSE AND COPYRIGHT
[-Lax::RequireConstantOnLeftSideOfEquality::ExceptEq]
[-Miscellanea::ProhibitUnrestrictedNoCritic]
[-Lax::ProhibitEmptyQuotes::ExceptAsFallback]

27
README
View File

@@ -5,12 +5,18 @@ aleesa-misc
Работает по протоколу Redis pubsub.
Disclaimer
-----------------------------------------------------------------------------------------------------------------------
Вся дальнейшая разработка логики этого модуля будет вестись в рамках проекта aleesa-misc-go. Этот репозиторий остаётся
исключительно для образовательных целей.
Механика работы
-----------------------------------------------------------------------------------------------------------------------
Роутер подписан на канал misc.
Модули, реализующие "клиентские протоколы" - telegram, irc, jabber и проч, подписаны на канал своего протокола. Входящие
сообщения они получают только через этот канал.
Модули, реализующие "клиентские протоколы" - telegram, irc, jabber и проч, подписаны на канал своего протокола.
Входящие сообщения они получают только через этот канал.
Модули, реализующие иную функциональность также подписаны каждый на свой канал. Кроме того, для реализации
дополнительных синхронных возможностей, они могут слушать например http запросы на отдельных - ip:портах. Но это уже
@@ -26,27 +32,30 @@ mode - public или private
misc - объект с дополнительными полями:
misc->answer - 0 если ответ не требуется и 1 если ответ требуется (использован в модуле craniac), значение
misc->answer - 0 если ответ не требуется и 1 если ответ требуется (использован в модуле craniac), значение
по-умолчанию 1, если поля нет.
misc->bot_nick - ник бота. Типа как, для разных чятов он может быть разный. (Использовано в модуле craniac.) Если
misc->bot_nick - ник бота. Типа как, для разных чятов он может быть разный. (Использовано в модуле craniac.) Если
поле отсутствует, проверка на обращение к боту по нику не происходит.
misc->csign - command sign - значок, которым предваряется команда в чятике.Исторически сложилось так, что для
misc->csign - command sign - значок, которым предваряется команда в чятике. Исторически сложилось так, что для
разных ботов этот символ был разный, например, eggdrop использовал точку, а sulci - восклицательный
знак. По-умолчанию, aleesa-bot вездепроставляет восклицательный знак, если во входящем сообщении
такой настройки нету. Изначально настройка задаётся в конфиге чат-модуля (aleesa-telegram,
например).
misc->fwd_cnt - количество пересылок сообщения. Значение по-умолчанию 5. Предполагается, что при пересылке
сообщения,модуль будет инкрементировать это значение и заодно проверять, что оно не превышает
misc->fwd_cnt - количество пересылок сообщения. Значение по-умолчанию 1. Предполагается, что при пересылке
сообщения, модуль будет инкрементировать это значение и заодно проверять, что оно не превышает
настройку forwards_max в конфиге или 5, если в конфиге такой настройки нету.
misc->msg_format - Использовать форматирование в сообщении. На текущий момент этот флажок выставляется в модуле
misc->good_morning - флажок признака сообщения-фразы дня, которая по идее осылается в ~8 часов по мск. Используется в
модуле phrases.
misc->msg_format - Использовать форматирование в сообщении. На текущий момент этот флажок выставляется в модуле
telegram и благополучно проходит через модуль misc, далее попадает в модуль phrases, и, наконец,
возвращается в модуль telegram, чтобы выходное сообщение было отослано как отформатированное.
misc->username - имя пользователя, по которому к нему надо обратиться в ответе (используется в модуле games). Для
misc->username - имя пользователя, по которому к нему надо обратиться в ответе (используется в модуле games). Для
telegram это фактически ссылка на пользователя, как правило с его firstname и lastname (или
@username, если firstname и lastname у него нету), чтобы его можно было захайлатить.

28
TODO
View File

@@ -1,28 +0,0 @@
Реализовать парсер для команды !admin :
* Вероятно, попротокольно, так как эта команда есть только в telegram, но формально должна появиться в jabber и irc.
* Понадобится отдельный способ запросить "протокольный" плагин на тему админ ли чел, который хочет использовать
команду !admin.
* Для телеги у нас есть возможность автоматически определять админов.
* Для IRC - есть возможность определить op-ов. (+ к тому нужно следить за сменой статуса - парсить соответствующие
ивенты).
* Для jabber - пока непонятно.
Брать каналы из конфига. Те самые redis-каналы, в которые надо отсылать сообщения. Продумать вопрос с оптимальным форматом конфига.
Пока что он видится в фомате хэша
{
channels : {
telegram : telegram,
craniac : craniac,
irc : irc,
webapp : webapp,
...
}
}
но не на всех этих каналах надо слушать, в какие-то достаточно только писать.
Реализовать возможность релоада конфига. Но для начала понять, нужно ли оно нам?
Решить вопрос с Cron-ом. Будет ли это отдельный демонок либо эти функции будут в роутере (чего наверно не хотелось бы).
В Cron у нас войдёт как минимум утренняя фортунка и скорее всего rss, когда появится.
Проверить момент, когда при старте сервиса redis ещё не запущен.

View File

@@ -5,7 +5,8 @@ requires 'Cwd', '==3.75';
requires 'Cwd::utf8', '==0.011';
requires 'Data::Dumper', '==2.183';
requires 'Encode', '==3.16';
requires 'English', '==1.11';
# Part of perl
requires 'English', '0';
requires 'EV', '==4.33';
requires 'Exporter', '==5.74';
requires 'File::Basename', '==2.85';
@@ -19,11 +20,11 @@ requires 'Log::Any', '==1.710';
requires 'Log::Any::Adapter', '==1.710';
requires 'Log::Any::For::Std', '==0.05';
requires 'Math::Random::Secure', '==0.080001';
requires 'Mojolicious', '==9.22';
requires 'Mojolicious', '==9.24';
requires 'Mojo::Redis', '==3.27';
requires 'Mojo::IOLoop::Signal', '==0.003';
requires 'open', '==1.12';
# Part of perl
requires 'open', '0';
requires 'POSIX', '0';
requires 'Protocol::Redis::XS', '0';
requires 'utf8', '0';
requires 'version', '==0.9929';

View File

@@ -7,15 +7,13 @@ use warnings;
use utf8;
use open qw (:std :utf8);
use Clone qw (clone);
# Модули для работы приложения
use Clone qw (clone);
use Data::Dumper qw (Dumper);
use Log::Any qw ($log);
# Чтобы "уж точно" использовать hiredis-биндинги, загрузим этот модуль перед Mojo::Redis
use Protocol::Redis::XS ();
use Mojo::Redis ();
use Mojo::IOLoop ();
use Mojo::IOLoop::Signal ();
use Data::Dumper qw (Dumper);
use Conf qw (LoadConf);
@@ -24,7 +22,11 @@ use Exporter qw (import);
our @EXPORT_OK = qw (RunMisc);
my $c = LoadConf ();
my $fwd_cnt = $c->{'forward_max'} // 5;
my $fwd_cnt = 5;
if (defined $c->{'forward_max'}) {
$fwd_cnt = $c->{'forward_max'};
}
# Основной парсер
my $parse_message = sub {
@@ -50,13 +52,33 @@ my $parse_message = sub {
$answer->{misc}->{answer} = 1;
}
unless (defined $answer->{misc}->{bot_nick}) {
$answer->{misc}->{bot_nick} = '';
}
unless (defined $answer->{misc}->{csign}) {
$answer->{misc}->{csign} = '!';
$answer->{misc}->{csign} = $c->{csign};
}
unless (defined $answer->{misc}->{good_morning}) {
$answer->{misc}->{good_morning} = 0;
}
unless (defined $answer->{misc}->{msg_format}) {
$answer->{misc}->{msg_format} = 0;
}
unless (defined $answer->{misc}->{username}) {
$answer->{misc}->{username} = '';
}
} else {
$answer->{misc}->{answer} = 1;
$answer->{misc}->{csign} = '!';
$answer->{misc}->{bot_nick} = '';
$answer->{misc}->{csign} = $c->{csign};
$answer->{misc}->{fwd_cnt} = 1;
$answer->{misc}->{good_morning} = 0;
$answer->{misc}->{msg_format} = 0;
$answer->{misc}->{username} = '';
}
# Если сообщение не попало ни под один шаблон, оно отправляется к craniac-у
@@ -64,9 +86,11 @@ my $parse_message = sub {
$log->debug ('[DEBUG] Incoming message ' . Dumper ($m));
my $csign = $answer->{misc}->{csign};
# Пробуем найти команды. Сообщения, начинающиеся с $answer->{misc}->{csign}
if (substr ($m->{message}, 0, 1) eq $answer->{misc}->{csign}) {
my $cmd = substr $m->{message}, 1;
if ((length $m->{message} > length $csign) && (substr ($m->{message}, 0, length $csign) eq $csign)) {
my $cmd = substr $m->{message}, length $csign;
my $done = 0;
# Вначале поищем команды модуля Phrases
@@ -83,8 +107,8 @@ my $parse_message = sub {
# Потом - команды модуля WebApp
unless ($done) {
my @webapp_cmd = qw (buni anek анек анекдот cat кис drink праздник fox лис frog лягушка horse лошадь лошадка
monkeyuser rabbit bunny кролик snail улитка owl сова сыч xkcd tits boobs tities boobies
сиси сисечки butt booty ass попа попка);
monkeyuser rabbit bunny кролик snail улитка owl сова сыч xkcd tits boobs tities boobies
сиси сисечки butt booty ass попа попка);
while (my $check = pop @webapp_cmd) {
if ($cmd eq $check) {
@@ -108,26 +132,37 @@ my $parse_message = sub {
}
}
# И наконец остальные, более сложные команды, с аргументами
# И, наконец, остальные, более сложные команды, с аргументами
unless ($done) {
if (substr ($m->{message}, 1, 2) eq 'w ' || substr ($m->{message}, 1, 2) eq 'п ') {
$send_to = 'webapp';
$done = 1;
} elsif (substr ($m->{message}, 1, 8) eq 'weather ' || substr ($m->{message}, 1, 8) eq 'погодка ') {
$send_to = 'webapp';
$done = 1;
} elsif (substr ($m->{message}, 1, 7) eq 'погода ' || substr ($m->{message}, 1, 8) eq 'погадка ') {
$send_to = 'webapp';
$done = 1;
my @cmds = ('w ', 'п ', 'weather ', 'погодка ', 'погадка ', 'погода ');
while (my $check = pop @cmds) {
if ((length $cmd > length $check) && substr ($cmd, 0, length $check) eq $check) {
$send_to = 'webapp';
$done = 1;
last;
}
}
$#cmds = -1;
@cmds = ('karma ', 'карма ');
while (my $check = pop @cmds) {
if ((length $cmd > length $check) && substr ($cmd, 0, length $check) eq $check) {
$send_to = 'phrases';
$done = 1;
last;
}
}
}
# Попробуем найти изменение кармы
} elsif (substr ($m->{message}, -2) eq '++' || substr ($m->{message}, -2) eq '--') {
} elsif (substr ($m->{message}, 0 - length ('++')) eq '++' || substr ($m->{message}, 0 - length ('--')) eq '--') {
my @arr = split /\n/, $m->{message};
# Предполагается, что фраза - это только одна строка
if ($#arr < 1) {
# Подпираем это дело - независимо от того, что пришло нам от chat-плагина
$answer->{misc}->{answer} = 1;
$send_to = 'phrases';
}
}
@@ -153,7 +188,7 @@ my $__signal_handler = sub {
};
# main loop, он же event loop
# Main loop, он же event loop
sub RunMisc {
$log->info ("[INFO] Connecting to $c->{server}, $c->{port}");
@@ -194,10 +229,8 @@ sub RunMisc {
);
}
Mojo::IOLoop::Signal->on (
TERM => $__signal_handler,
INT => $__signal_handler,
);
Mojo::IOLoop::Signal->on (TERM => $__signal_handler);
Mojo::IOLoop::Signal->on (INT => $__signal_handler);
do { Mojo::IOLoop->start } until Mojo::IOLoop->is_running;
return;