From a710596349ecaa851e1aeb89dfb909246b505753 Mon Sep 17 00:00:00 2001 From: Ricardo Signes Date: Thu, 30 Jan 2025 21:35:56 -0500 Subject: [PATCH 1/7] TextThemer: add a "raw" formatter --- lib/Synergy/TextThemer.pm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/Synergy/TextThemer.pm b/lib/Synergy/TextThemer.pm index 4bdb1513..004cfcaf 100644 --- a/lib/Synergy/TextThemer.pm +++ b/lib/Synergy/TextThemer.pm @@ -53,6 +53,10 @@ sub from_name ($class, $name) { return $class->new($THEME{$name}); } +sub _format_raw ($self, $thing) { + return $thing; +} + sub _format_box ($self, $text, $title = undef) { $self->_format_generic_box($text, 1, $title); } From 7e93d20a94b43c5fd7096d8cec41498e58a09031 Mon Sep 17 00:00:00 2001 From: Ricardo Signes Date: Thu, 30 Jan 2025 21:37:37 -0500 Subject: [PATCH 2/7] Console: if configured to, log the messages that we send This lets us go back and look at more things about the messages, which will be useful for investigating "alts" that are not normally displayed in the console. --- lib/Synergy/Channel/Console.pm | 66 +++++++++++++++++++++++++++++----- lib/Synergy/TextThemer.pm | 20 ++++++++--- 2 files changed, 73 insertions(+), 13 deletions(-) diff --git a/lib/Synergy/Channel/Console.pm b/lib/Synergy/Channel/Console.pm index 81aef6c1..c254555b 100644 --- a/lib/Synergy/Channel/Console.pm +++ b/lib/Synergy/Channel/Console.pm @@ -448,32 +448,80 @@ async sub start ($self) { return; } +has _next_message_number => ( + is => 'rw', + init_arg => undef, + default => 0, + traits => [ 'Counter' ], + handles => { get_next_message_number => 'inc' }, +); + +has _message_log => ( + is => 'ro', + init_arg => undef, + default => sub { [] }, +); + +has max_message_history => ( + is => 'ro', + default => 0, +); + +sub _log_message ($self, $message) { + return undef unless $self->max_message_history > 0; + + my $i = $self->get_next_message_number; + + $message->{number} = $i; + + my $log = $self->_message_log; + push @$log, $message; + + if (@$log > $self->max_message_history) { + shift @$log; + } +} + sub send_message_to_user ($self, $user, $text, $alts = {}) { $self->send_message($user->username, $text, $alts); } -sub _format_message ($self, $name, $address, $text) { +sub _format_message ($self, $message) { if ($self->message_format eq 'compact') { - return $self->_format_message_compact($name, $address, $text) + return $self->_format_message_compact($message); } - return $self->_format_message_chonky($name, $address, $text) + return $self->_format_message_chonky($message); } sub send_message ($self, $address, $text, $alts = {}) { my $name = $self->name; - $self->_stream->write( - $self->_format_message($name, $address, $text) - ); + my $message = { + name => $name, + address => $address, + text => $text, + alts => $alts, + }; + + $self->_log_message($message); + + $self->_stream->write( $self->_format_message($message) ); } sub send_ephemeral_message ($self, $conv_address, $to_address, $text) { my $name = $self->name; - $self->_stream->write( - $self->_format_message($name, $to_address, "[ephemeral] $text") - ); + my $message = { + name => $name, + address => $to_address, + text => "[ephemeral] $text", + alts => undef, + }; + + $self->_log_message($message); + + $self->_stream->write( $self->_format_message($message) ); } sub describe_event ($self, $event) { diff --git a/lib/Synergy/TextThemer.pm b/lib/Synergy/TextThemer.pm index 004cfcaf..3b4fcb83 100644 --- a/lib/Synergy/TextThemer.pm +++ b/lib/Synergy/TextThemer.pm @@ -136,7 +136,11 @@ sub _format_notice ($self, $from, $text) { return $message; } -sub _format_message_compact ($self, $name, $address, $text) { +sub _format_message_compact ($self, $message) { + my $address = $message->{address}; + my $name = $message->{name}; + my $text = $message->{text}; + return "❱❱ $name!$address ❱❱ $text\n" if $self->is_null; my $c0 = $self->decoration_color; @@ -151,7 +155,11 @@ sub _format_message_compact ($self, $name, $address, $text) { . "\n"; } -sub _format_message_chonky ($self, $name, $address, $text) { +sub _format_message_chonky ($self, $message) { + my $address = $message->{address}; + my $name = $message->{name}; + my $text = $message->{text}; + state $B_TL = q{╭}; state $B_BL = q{╰}; state $B_TR = q{╮}; @@ -168,10 +176,14 @@ sub _format_message_chonky ($self, $name, $address, $text) { my $line_C = $themed ? $self->decoration_color_code : q{}; my $null_C = $themed ? Term::ANSIColor::color('reset') : q{}; - my $dest_width = length "$name/$address"; - my $dest = "$text_C$name$line_C!$text_C$address$line_C"; + if (defined $message->{number}) { + $dest .= " ${line_C}#$text_C$message->{number}"; + } + + my $dest_width = plainlength($dest); + my $header = "$line_C$B_TL" . ($B_hor x 5) . "$B_boxleft $dest $B_boxright" From d646b3a345c482b93fb78f69a3195ff93a4a3b5c Mon Sep 17 00:00:00 2001 From: Ricardo Signes Date: Thu, 30 Jan 2025 21:38:15 -0500 Subject: [PATCH 3/7] Console: add a diagnostic /history command This will let you see things in history, including with "alts". --- lib/Synergy/Channel/Console.pm | 57 ++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/lib/Synergy/Channel/Console.pm b/lib/Synergy/Channel/Console.pm index c254555b..b5236ade 100644 --- a/lib/Synergy/Channel/Console.pm +++ b/lib/Synergy/Channel/Console.pm @@ -14,6 +14,7 @@ use namespace::autoclean; use List::Util qw(max); use Term::ANSIColor qw(colored); +use YAML::XS (); with 'Synergy::Role::Channel'; @@ -307,6 +308,62 @@ EOH return [ box => "Updated $var" ]; } + sub _diagnostic_cmd_history ($self, $rest) { + my ($channel_name, $number, $more) = split /\s+/, $rest, 3; + + $more = 'text' unless length $more; + + my $channel = $self->hub->channel_named($channel_name); + + unless ($channel) { + return [ box => "Unknown channel: $channel_name" ]; + } + + unless ($channel->DOES('Synergy::Channel::Console')) { + return [ box => "That isn't a Console channel, so this won't work. $channel" ]; + } + + unless ($channel->max_message_history > 0) { + return [ box => "That reactor does not store message history." ]; + } + + unless ($number =~ /\A[0-9]+\z/) { + return [ box => "That second argument doesn't look like a number." ]; + } + + my $message_log = $channel->_message_log; + + unless (@$message_log) { + return [ box => "There's no history logged (yet?)." ]; + } + + my ($message) = grep {; $_->{number} == $number } @$message_log; + + unless ($message) { + my $expired = $number < $message_log->[0]{number}; + if ($expired) { + return [ box => "I can't find that message in history. It probably expired." ]; + } + + return [ box => "There's no message in history with that number." ]; + } + + my %new_message = %$message; + + my $content + = $more eq 'text' ? $channel->_format_message_chonky(\%new_message) + : $more eq 'alts' ? YAML::XS::Dump($new_message{alts}) + : undef; + + unless ($content) { + return [ box => "I don't know how to format things this way: $more" ]; + } + + my $title = "history: channel=$channel_name item=$number format=$more"; + + return [ wide_box => $content, $title ]; + } + sub _display_notice ($self, $text) { $self->stream->write($self->_format_notice($self->channel->name, $text)); return; From c9f76b86d536843d394d19cd60c67cf30ad5146b Mon Sep 17 00:00:00 2001 From: Ricardo Signes Date: Thu, 30 Jan 2025 21:45:39 -0500 Subject: [PATCH 4/7] Console: add help for /history --- lib/Synergy/Channel/Console.pm | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/Synergy/Channel/Console.pm b/lib/Synergy/Channel/Console.pm index b5236ade..9e9036ed 100644 --- a/lib/Synergy/Channel/Console.pm +++ b/lib/Synergy/Channel/Console.pm @@ -147,6 +147,7 @@ package Synergy::Channel::Console::DiagnosticHandler { /console - print Console channel configuration /format - configure Console channel output (see "/help format") + /history - inspect messages previously sent across this channel /set VAR VALUE - change the default value for one of the following @@ -174,6 +175,33 @@ package Synergy::Channel::Console::DiagnosticHandler { channels. EOH + $HELP{history} = <<~'EOH'; + The history command lets you see messages sent across a Console channel, + assuming you have history logging turned on. Your Console channel will need + a max_message_history setting greater than 1. + + It works like this: + + /history $channel_name $message_number $format + + The message number is shown on (chonky-formatted) messages in a Console + channel, if it's logging history. So, given this message box: + + ╭─────┤ term-rw!rjbs #6 ├──────────────────────────────╮ + │ I don't know how to search for that! + ╰──────────────────────────────────────────────────────╯ + + You can enter: + + /history term-rw 6 + + to see the message re-displayed. $format is optional, and defaults to text, + the same thing normally displayed. You can also use "alts", which will + display a YAML-formatted dump of all the alternate representations of the + message. This is useful for using the Console environment for debugging + non-text alternatives. + EOH + $HELP{events} = <<~'EOH'; You can begin your message with a string inside braces. The string is made up of instructions separated by spaces. They can be: From 0d31003fec389d067f4e2c629b54b20514479a41 Mon Sep 17 00:00:00 2001 From: Ricardo Signes Date: Thu, 30 Jan 2025 21:56:08 -0500 Subject: [PATCH 5/7] Console: improve the argument order for /history Since we can default to "this channel", make it optional. Format is more likely to be useful, so put channel name at the end. --- lib/Synergy/Channel/Console.pm | 51 +++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/lib/Synergy/Channel/Console.pm b/lib/Synergy/Channel/Console.pm index 9e9036ed..11c53321 100644 --- a/lib/Synergy/Channel/Console.pm +++ b/lib/Synergy/Channel/Console.pm @@ -182,24 +182,22 @@ package Synergy::Channel::Console::DiagnosticHandler { It works like this: - /history $channel_name $message_number $format + /history $message_number $format? $channel_name? The message number is shown on (chonky-formatted) messages in a Console - channel, if it's logging history. So, given this message box: + channel, if it's logging history. $format defaults to "text" and + $channel_name defaults to the channel on which you're sending this command. + This can be useful for using the Console environment for debugging non-text + alternatives. + + So, given this message box: ╭─────┤ term-rw!rjbs #6 ├──────────────────────────────╮ │ I don't know how to search for that! ╰──────────────────────────────────────────────────────╯ - You can enter: - - /history term-rw 6 - - to see the message re-displayed. $format is optional, and defaults to text, - the same thing normally displayed. You can also use "alts", which will - display a YAML-formatted dump of all the alternate representations of the - message. This is useful for using the Console environment for debugging - non-text alternatives. + You can enter "/history 6" to see the message re-displayed as text, or + "/history 6 alts" to see the non-text alternatives dumped. EOH $HELP{events} = <<~'EOH'; @@ -337,18 +335,25 @@ EOH } sub _diagnostic_cmd_history ($self, $rest) { - my ($channel_name, $number, $more) = split /\s+/, $rest, 3; + my ($number, $format, $channel_name) = split /\s+/, $rest, 3; - $more = 'text' unless length $more; + $format = 'text' unless length $format; - my $channel = $self->hub->channel_named($channel_name); + my $channel; - unless ($channel) { - return [ box => "Unknown channel: $channel_name" ]; - } + if ($channel_name) { + $channel = $self->hub->channel_named($channel_name); - unless ($channel->DOES('Synergy::Channel::Console')) { - return [ box => "That isn't a Console channel, so this won't work. $channel" ]; + unless ($channel) { + return [ box => "Unknown channel: $channel_name" ]; + } + + unless ($channel->DOES('Synergy::Channel::Console')) { + return [ box => "That isn't a Console channel, so this won't work. $channel" ]; + } + } else { + $channel = $self->channel; + $channel_name = $channel->name; } unless ($channel->max_message_history > 0) { @@ -379,15 +384,15 @@ EOH my %new_message = %$message; my $content - = $more eq 'text' ? $channel->_format_message_chonky(\%new_message) - : $more eq 'alts' ? YAML::XS::Dump($new_message{alts}) + = $format eq 'text' ? $channel->_format_message_chonky(\%new_message) + : $format eq 'alts' ? YAML::XS::Dump($new_message{alts}) : undef; unless ($content) { - return [ box => "I don't know how to format things this way: $more" ]; + return [ box => "I don't know how to format things this way: $format" ]; } - my $title = "history: channel=$channel_name item=$number format=$more"; + my $title = "history: channel=$channel_name item=$number format=$format"; return [ wide_box => $content, $title ]; } From 386dcada51c0ce69cf85fd97281c723ee38495a0 Mon Sep 17 00:00:00 2001 From: Ricardo Signes Date: Thu, 30 Jan 2025 22:08:05 -0500 Subject: [PATCH 6/7] JSON: replace use of JSON libraries other than MaybeXS I feel like I have done this before... --- Makefile.PL | 2 -- cpanfile | 1 - lib/Synergy/Channel/Discord.pm | 2 +- lib/Synergy/Channel/IRC.pm | 2 -- lib/Synergy/Channel/Pushover.pm | 1 - lib/Synergy/Channel/Slack.pm | 2 +- lib/Synergy/DiagnosticUplink.pm | 4 ++-- lib/Synergy/External/Discord.pm | 2 +- lib/Synergy/Reactor/InABox.pm | 1 - 9 files changed, 5 insertions(+), 12 deletions(-) diff --git a/Makefile.PL b/Makefile.PL index 05777f2d..b1185eaa 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -57,7 +57,6 @@ my %WriteMakefileArgs = ( "IO::Async::Timer::Countdown" => 0, "IO::Async::Timer::Periodic" => 0, "JMAP::Tester" => 0, - "JSON" => 0, "JSON::MaybeXS" => 0, "LWP::Protocol::https" => 0, "Lingua::EN::Inflect" => 0, @@ -170,7 +169,6 @@ my %FallbackPrereqs = ( "IO::Async::Timer::Countdown" => 0, "IO::Async::Timer::Periodic" => 0, "JMAP::Tester" => 0, - "JSON" => 0, "JSON::MaybeXS" => 0, "LWP::Protocol::https" => 0, "Lingua::EN::Inflect" => 0, diff --git a/cpanfile b/cpanfile index 38ee9b49..a408722e 100644 --- a/cpanfile +++ b/cpanfile @@ -30,7 +30,6 @@ requires "IO::Async::Timer::Absolute" => "0"; requires "IO::Async::Timer::Countdown" => "0"; requires "IO::Async::Timer::Periodic" => "0"; requires "JMAP::Tester" => "0"; -requires "JSON" => "0"; requires "JSON::MaybeXS" => "0"; requires "LWP::Protocol::https" => "0"; requires "Lingua::EN::Inflect" => "0"; diff --git a/lib/Synergy/Channel/Discord.pm b/lib/Synergy/Channel/Discord.pm index 3f6fd826..f9ed4e82 100644 --- a/lib/Synergy/Channel/Discord.pm +++ b/lib/Synergy/Channel/Discord.pm @@ -13,7 +13,7 @@ use Synergy::Logger '$Logger'; use namespace::autoclean; -my $JSON = JSON->new->canonical; +my $JSON = JSON::MaybeXS->new->canonical; with 'Synergy::Role::Channel'; diff --git a/lib/Synergy/Channel/IRC.pm b/lib/Synergy/Channel/IRC.pm index 308e6dae..ce1f19a8 100644 --- a/lib/Synergy/Channel/IRC.pm +++ b/lib/Synergy/Channel/IRC.pm @@ -5,8 +5,6 @@ use Moose; use Future::AsyncAwait; -use JSON::MaybeXS; - use Synergy::Event; use Synergy::Logger '$Logger'; diff --git a/lib/Synergy/Channel/Pushover.pm b/lib/Synergy/Channel/Pushover.pm index b962bcc3..37597f25 100644 --- a/lib/Synergy/Channel/Pushover.pm +++ b/lib/Synergy/Channel/Pushover.pm @@ -3,7 +3,6 @@ package Synergy::Channel::Pushover; use Moose; use Future::AsyncAwait; -use JSON::MaybeXS qw(encode_json decode_json); use Synergy::Logger '$Logger'; diff --git a/lib/Synergy/Channel/Slack.pm b/lib/Synergy/Channel/Slack.pm index 3f3f59bb..10276f52 100644 --- a/lib/Synergy/Channel/Slack.pm +++ b/lib/Synergy/Channel/Slack.pm @@ -13,7 +13,7 @@ use Synergy::Logger '$Logger'; use namespace::autoclean; -my $JSON = JSON->new->canonical; +my $JSON = JSON::MaybeXS->new->canonical; with 'Synergy::Role::Channel', 'Synergy::Role::ProvidesUserStatus'; diff --git a/lib/Synergy/DiagnosticUplink.pm b/lib/Synergy/DiagnosticUplink.pm index bba2a14d..b632e9be 100644 --- a/lib/Synergy/DiagnosticUplink.pm +++ b/lib/Synergy/DiagnosticUplink.pm @@ -7,8 +7,8 @@ use utf8; use Future::AsyncAwait; use Synergy::Logger '$Logger'; -require JSON; -my $JSON = JSON->new; +require JSON::MaybeXS; +my $JSON = JSON::MaybeXS->new; with 'Synergy::Role::HubComponent'; diff --git a/lib/Synergy/External/Discord.pm b/lib/Synergy/External/Discord.pm index 3da4dd0a..5c9b4441 100644 --- a/lib/Synergy/External/Discord.pm +++ b/lib/Synergy/External/Discord.pm @@ -18,7 +18,7 @@ use Time::HiRes (); use Synergy::Logger '$Logger'; -my $JSON = JSON->new; +my $JSON = JSON::MaybeXS->new; with 'Synergy::Role::HubComponent'; diff --git a/lib/Synergy/Reactor/InABox.pm b/lib/Synergy/Reactor/InABox.pm index bc0778f5..dcf5715c 100644 --- a/lib/Synergy/Reactor/InABox.pm +++ b/lib/Synergy/Reactor/InABox.pm @@ -17,7 +17,6 @@ use Synergy::CommandPost; use Synergy::Logger '$Logger'; use Synergy::Util qw(bool_from_text reformat_help); use String::Switches qw(parse_switches); -use JSON::MaybeXS; use Future::Utils qw(repeat); use Text::Template; use Time::Duration qw(ago); From 6130c4eff29f9cc256a77245af3a62e3fc4a0dab Mon Sep 17 00:00:00 2001 From: Ricardo Signes Date: Thu, 30 Jan 2025 21:35:17 -0500 Subject: [PATCH 7/7] Console: remove unused JSON::MaybeXS import --- lib/Synergy/Channel/Console.pm | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Synergy/Channel/Console.pm b/lib/Synergy/Channel/Console.pm index 11c53321..bb5e1a97 100644 --- a/lib/Synergy/Channel/Console.pm +++ b/lib/Synergy/Channel/Console.pm @@ -4,7 +4,6 @@ package Synergy::Channel::Console; use utf8; use Moose; -use JSON::MaybeXS; use Future::AsyncAwait; use Synergy::Event;