diff options
| author | ailin-nemui | 2016-04-27 13:24:46 +0200 |
|---|---|---|
| committer | ailin-nemui | 2016-04-27 13:24:46 +0200 |
| commit | b1a4f1a7680364084a67e1b86d80b5021da72668 (patch) | |
| tree | 0bbfc00dc80553380bba4724079077edcf3aed7f /scripts | |
| parent | 871ec69e1d631771e53f8a93ecf35b15fed272c7 (diff) | |
| parent | ee02295f4e0e75fe9fca62821ab434a7b0116701 (diff) | |
| download | scripts.irssi.org-b1a4f1a7680364084a67e1b86d80b5021da72668.tar.bz2 | |
Merge pull request #265 from ailin-nemui/slackirc
Add fix_slackirc
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/fix_slackirc.pl | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/scripts/fix_slackirc.pl b/scripts/fix_slackirc.pl new file mode 100644 index 0000000..b557dc0 --- /dev/null +++ b/scripts/fix_slackirc.pl @@ -0,0 +1,97 @@ +use strict; +use warnings; + +our $VERSION = '0.1'; # 258918adc08e622 +our %IRSSI = ( + authors => 'Nei', + contact => 'Nei @ anti@conference.jabber.teamidiot.de', + url => "http://anti.teamidiot.de/", + name => 'fix_slackirc', + description => 'Some workarounds to improve irssi experience on the Slack IRC gateway', + license => 'ISC', + ); + +# Usage +# ===== +# Load and enjoy + +use Irssi; + +my $SLACK_ADDRESS = 'irc.tinyspeck.com'; + +# Work-around for 2 bugs in the Slack IRC bridge +# * Format of 315 is broken - the nick is missing +# * No Reply to the MODE b command +# * Empty real names are given as string "null" instead +# these issues will stop channel sync from working properly + +my %timer; +my %chanlist; + +Irssi::signal_register({ + 'chanquery who end' => [qw[iobject string]], +}); + +# Accessor for the Rawlog +sub _s2r { + my $ref = shift; + if ($ref =~ /=SCALAR/) { + bless +{ _irssi => $$ref } => ref $ref + } else { + $ref + } +} + +sub queue_ban_end { + my ($server, $raw) = @_; + return unless $server && $server->{real_address} eq $SLACK_ADDRESS; + my (@p) = split ' :', $raw, 2; + unshift @p, (split / /, shift @p); + my $tag = $server->{tag}; + push @{ $chanlist{$tag} }, split /,/, $p[1]; + if (my $t = delete $timer{$tag}) { + Irssi::timeout_remove($t); + } + # Gross hack due to Irssi missing a signal. We expect that irssi will ask for bans "soon" and in order + $timer{$tag} = Irssi::timeout_add_once(5_000, 'send_end_of_bans', $tag); +} + +sub send_end_of_bans { + my ($tag) = @_; + delete $timer{$tag}; + return unless $chanlist{$tag} && @{$chanlist{$tag}}; + my $chan = shift @{ $chanlist{$tag} // [] } || return; + if (my $server = Irssi::server_find_tag($tag)) { + my $raw = ':'.$server->{real_address}.' 368 '.$server->{nick}.' '.$chan.' :Slack has no Ban List'; + _s2r($server->{rawlog})->input("[FAKED] $raw") if $server->{rawlog}; + Irssi::signal_emit('server incoming', $server, $raw); + if (@{$chanlist{$tag}}) { + # We expect that irssi will ask for the "next" ban soon + $timer{$tag} = Irssi::timeout_add_once(2_000, 'send_end_of_bans', $tag); + } + else { + delete $chanlist{$tag}; + } + } +} + +sub fix_incoming { + my ($server, $raw) = @_; + my $nick = $server->{nick}; + my $continue; + # fix end of wholist + if ($raw =~ s/:$SLACK_ADDRESS 315 \K /$nick /) { + $continue = 1; + } + # fix "null" realnames + elsif ($raw =~ s/:$SLACK_ADDRESS 352 .* :\d+ \Knull$//) { + $continue = 1; + } + if ($continue) { + _s2r($server->{rawlog})->input("[FIXED] $raw") if $server->{rawlog}; + Irssi::signal_continue($server, $raw); + } +} + +Irssi::signal_add_last('chanquery who end' => 'queue_ban_end'); +Irssi::signal_add_first('server incoming' => 'fix_incoming'); |
