summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorailin-nemui2016-04-27 13:24:46 +0200
committerailin-nemui2016-04-27 13:24:46 +0200
commitb1a4f1a7680364084a67e1b86d80b5021da72668 (patch)
tree0bbfc00dc80553380bba4724079077edcf3aed7f /scripts
parent871ec69e1d631771e53f8a93ecf35b15fed272c7 (diff)
parentee02295f4e0e75fe9fca62821ab434a7b0116701 (diff)
downloadscripts.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.pl97
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');