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] [-Lax::RequireConstantOnLeftSideOfEquality::ExceptEq]
[-Miscellanea::ProhibitUnrestrictedNoCritic] [-Miscellanea::ProhibitUnrestrictedNoCritic]
[-Lax::ProhibitEmptyQuotes::ExceptAsFallback]

15
README
View File

@@ -5,12 +5,18 @@ aleesa-misc
Работает по протоколу Redis pubsub. Работает по протоколу Redis pubsub.
Disclaimer
-----------------------------------------------------------------------------------------------------------------------
Вся дальнейшая разработка логики этого модуля будет вестись в рамках проекта aleesa-misc-go. Этот репозиторий остаётся
исключительно для образовательных целей.
Механика работы Механика работы
----------------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------
Роутер подписан на канал misc. Роутер подписан на канал misc.
Модули, реализующие "клиентские протоколы" - telegram, irc, jabber и проч, подписаны на канал своего протокола. Входящие Модули, реализующие "клиентские протоколы" - telegram, irc, jabber и проч, подписаны на канал своего протокола.
сообщения они получают только через этот канал. Входящие сообщения они получают только через этот канал.
Модули, реализующие иную функциональность также подписаны каждый на свой канал. Кроме того, для реализации Модули, реализующие иную функциональность также подписаны каждый на свой канал. Кроме того, для реализации
дополнительных синхронных возможностей, они могут слушать например http запросы на отдельных - ip:портах. Но это уже дополнительных синхронных возможностей, они могут слушать например http запросы на отдельных - ip:портах. Но это уже
@@ -38,10 +44,13 @@ misc->csign - command sign - значок, которым предваря
такой настройки нету. Изначально настройка задаётся в конфиге чат-модуля (aleesa-telegram, такой настройки нету. Изначально настройка задаётся в конфиге чат-модуля (aleesa-telegram,
например). например).
misc->fwd_cnt - количество пересылок сообщения. Значение по-умолчанию 5. Предполагается, что при пересылке misc->fwd_cnt - количество пересылок сообщения. Значение по-умолчанию 1. Предполагается, что при пересылке
сообщения, модуль будет инкрементировать это значение и заодно проверять, что оно не превышает сообщения, модуль будет инкрементировать это значение и заодно проверять, что оно не превышает
настройку forwards_max в конфиге или 5, если в конфиге такой настройки нету. настройку forwards_max в конфиге или 5, если в конфиге такой настройки нету.
misc->good_morning - флажок признака сообщения-фразы дня, которая по идее осылается в ~8 часов по мск. Используется в
модуле phrases.
misc->msg_format - Использовать форматирование в сообщении. На текущий момент этот флажок выставляется в модуле misc->msg_format - Использовать форматирование в сообщении. На текущий момент этот флажок выставляется в модуле
telegram и благополучно проходит через модуль misc, далее попадает в модуль phrases, и, наконец, telegram и благополучно проходит через модуль misc, далее попадает в модуль phrases, и, наконец,
возвращается в модуль telegram, чтобы выходное сообщение было отослано как отформатированное. возвращается в модуль telegram, чтобы выходное сообщение было отослано как отформатированное.

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

View File

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