summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormartin f. krafft2017-02-15 03:08:47 +0100
committermartin f. krafft2017-02-15 03:08:47 +0100
commit4f9d8b3e4e90bb7606cebfb7786c3601df298ccd (patch)
treeff97527df17ebb864151c06668e1cf7f45144b2c
parent1dacfd9fac96f478f31d6f54f252dae968064871 (diff)
downloadscripts.irssi.org-4f9d8b3e4e90bb7606cebfb7786c3601df298ccd.tar.bz2
Add ability to match on server tag
Signed-off-by: martin f. krafft <madduck@madduck.net>
-rw-r--r--scripts/ctrlact.pl142
1 files changed, 89 insertions, 53 deletions
diff --git a/scripts/ctrlact.pl b/scripts/ctrlact.pl
index b7e694c..6911192 100644
--- a/scripts/ctrlact.pl
+++ b/scripts/ctrlact.pl
@@ -15,17 +15,19 @@
#
# For instance, you might never want to be disturbed by activity in any
# channel, unless someone highlights you. However, you do want all activity
-# in queries, as well as an indication about any chatter in your company
-# channels. The following ctrlact map would do this for you:
+# in queries (except on efnet, as well as an indication about any chatter in
+# your company channels. The following ctrlact map would do this for you:
#
-# channel /^#myco-/ messages
-# channel * hilights
-# query * all
+# channel /^#myco-/ messages
+# channel * hilights
+# query efnet * messages
+# query * all
#
# These three lines would be interpreted/read as:
# "only messages or higher in a channel matching /^#myco-/ should trigger act"
# "in all other channels, only hilights (or higher) should trigger act"
-# "messages of all levels should trigger act in queries"
+# "queries on efnet should only trigger act for messages and higher"
+# "messages of all levels should trigger act in queries elsewhere"
#
# The activity level in the third column is thus to be interpreted as
# "the minimum level of activity that will trigger an indication"
@@ -101,7 +103,6 @@
#
# - figure out interplay with activity_hide_level
# - /ctrlact add/delete/move and /ctrlact save, maybe
-# - ability to add a server tag to an item name to make matches more specific
# - completion for commands
#
use strict;
@@ -109,7 +110,7 @@ use warnings;
use Irssi;
use Text::ParseWords;
-our $VERSION = '1.0';
+our $VERSION = '1.1';
our %IRSSI = (
authors => 'martin f. krafft',
@@ -117,7 +118,7 @@ our %IRSSI = (
name => 'ctrlact',
description => 'allows per-channel control over activity indication',
license => 'MIT',
- changed => '2017-02-12'
+ changed => '2017-02-15'
);
### DEFAULTS AND SETTINGS ######################################################
@@ -155,7 +156,7 @@ my @DATALEVEL_KEYWORDS = ('all', 'messages', 'hilights', 'none');
### HELPERS ####################################################################
my $_inhibit_debug_activity = 0;
-use constant DEBUGEVENTFORMAT => "%7s %-22.22s %d %s %d → %-7s (%-8s ← %s)";
+use constant DEBUGEVENTFORMAT => "%7s %7.7s %-22.22s %d %s %d → %-7s (%-8s ← %s)";
sub debugprint {
return unless $debug;
my ($msg, @rest) = @_;
@@ -204,13 +205,17 @@ sub from_data_level {
}
sub walk_match_array {
- my ($name, $type, @arr) = @_;
- foreach my $pair (@arr) {
- my $match = match($pair->[0], $name);
- next unless $match;
- my $result = to_data_level($pair->[1]);
+ my ($name, $net, $type, @arr) = @_;
+ foreach my $quadruplet (@arr) {
+ my $netmatch = match($quadruplet->[0], $net);
+ my $match = match($quadruplet->[1], $name);
+ next unless $netmatch and $match;
+
+ my $result = to_data_level($quadruplet->[2]);
my $tresult = from_data_level($result);
$name = '(unnamed)' unless length $name;
+ $match = sprintf('line %-3d = net:%-10.10s name:%s',
+ $quadruplet->[3], $netmatch, $match);
return ($result, $tresult, $match)
}
return -1;
@@ -220,22 +225,23 @@ sub get_mappings_table {
my (@arr) = @_;
my @ret = ();
for (my $i = 0; $i < @arr; $i++) {
- push @ret, sprintf("%4d: %-40s %-10s", $i, $arr[$i]->[0], $arr[$i]->[1]);
+ push @ret, sprintf("%4d: %-10s %-40s %-10s",
+ $i, $arr[$i]->[0], $arr[$i]->[1], $arr[$i]->[2]);
}
return join("\n", @ret);
}
sub get_specific_threshold {
- my ($type, $name) = @_;
+ my ($type, $name, $net) = @_;
$type = lc($type);
if ($type eq 'window') {
- return walk_match_array($name, $type, @window_thresholds);
+ return walk_match_array($name, $net, $type, @window_thresholds);
}
elsif ($type eq 'channel') {
- return walk_match_array($name, $type, @channel_thresholds);
+ return walk_match_array($name, $net, $type, @channel_thresholds);
}
elsif ($type eq 'query') {
- return walk_match_array($name, $type, @query_thresholds);
+ return walk_match_array($name, $net, $type, @query_thresholds);
}
else {
die "ctrlact: can't look up threshold for type: $type";
@@ -243,8 +249,8 @@ sub get_specific_threshold {
}
sub get_item_threshold {
- my ($chattype, $type, $name) = @_;
- my ($ret, $tret, $match) = get_specific_threshold($type, $name);
+ my ($chattype, $type, $name, $net) = @_;
+ my ($ret, $tret, $match) = get_specific_threshold($type, $name, $net);
return ($ret, $tret, $match) if $ret > 0;
if ($type eq 'CHANNEL') {
return ($fallback_channel_threshold, from_data_level($fallback_channel_threshold), '[default]');
@@ -255,8 +261,8 @@ sub get_item_threshold {
}
sub get_win_threshold {
- my ($name) = @_;
- my ($ret, $tret, $match) = get_specific_threshold('window', $name);
+ my ($name, $net) = @_;
+ my ($ret, $tret, $match) = get_specific_threshold('window', $name, $net);
if ($ret > 0) {
return ($ret, $tret, $match);
}
@@ -270,9 +276,10 @@ sub print_levels_for_all {
Irssi::print("ctrlact: $type mappings:");
for (my $i = 0; $i < @arr; $i++) {
my $name = $arr[$i]->{'name'};
- my ($t, $tt, $match) = get_specific_threshold($type, $name);
- my $c = ($type eq 'window') ? $arr[$i]->{'refnum'} : $i;
- printf CLIENTCRAP "%4d: %-40s → %d (%s; match:%s)", $c, $name, $t, $tt, $match;
+ my $net = $arr[$i]->{'server'}->{'tag'} // '';
+ my ($t, $tt, $match) = get_specific_threshold($type, $name, $net);
+ my $c = ($type eq 'window') ? $arr[$i]->{'refnum'} : $arr[$i]->window()->{'refnum'};
+ printf CLIENTCRAP "%4d: %-40.40s → %d (%-8s) match %s", $c, $name, $t, $tt, $match;
}
}
@@ -293,9 +300,10 @@ sub maybe_inhibit_witem_hilight {
my $wichattype = $witem->{'chat_type'};
my $witype = $witem->{'type'};
my $winame = $witem->{'name'};
- my ($th, $tth, $match) = get_item_threshold($wichattype, $witype, $winame);
+ my $witag = $witem->{'server'}->{'tag'} // '';
+ my ($th, $tth, $match) = get_item_threshold($wichattype, $witype, $winame, $witag);
my $inhibit = $newlevel > 0 && $newlevel < $th;
- debugprint(sprintf(DEBUGEVENTFORMAT, lc($witype), $winame, $newlevel,
+ debugprint(sprintf(DEBUGEVENTFORMAT, lc($witype), $witag, $winame, $newlevel,
$inhibit ? ('<',$th,'inhibit'):('≥',$th,'pass'),
$tth, $match));
if ($inhibit) {
@@ -329,9 +337,10 @@ sub maybe_inhibit_win_hilight {
return if ($newlevel <= $oldlevel);
my $wname = $win->{'name'};
- my ($th, $tth, $match) = get_win_threshold($wname);
+ my $wtag = $win->{'server'}->{'tag'} // '';
+ my ($th, $tth, $match) = get_win_threshold($wname, $wtag);
my $inhibit = $newlevel > 0 && $newlevel < $th;
- debugprint(sprintf(DEBUGEVENTFORMAT, 'window',
+ debugprint(sprintf(DEBUGEVENTFORMAT, 'window', $wtag,
$wname?$wname:'(unnamed)', $newlevel,
$inhibit ? ('<',$th,'inhibit'):('≥',$th,'pass'),
$tth, $match));
@@ -363,39 +372,40 @@ sub get_mappings_fh {
# ctrlact mappings file (version:$VERSION)
#
# type: window, channel, query
+# server: the server tag (chatnet)
# name: full name to match, /regexp/, or * (for all)
# min.level: none, messages, hilights, all, or 1,2,3,4
#
-# type name min.level
+# type server name min.level
# EXAMPLES
#
### only indicate activity in the status window if messages were displayed:
-# window (status) messages
+# window * (status) messages
#
### never ever indicate activity for any item bound to this window:
-# window oubliette none
+# window * oubliette none
#
-### indicate activity on all messages in debian-related channels:
-# channel /^#debian/ messages
+### indicate activity on all messages in debian-related channels on OFTC:
+# channel oftc /^#debian/ messages
#
### display any text (incl. joins etc.) for the '#madduck' channel:
-# channel #madduck all
+# channel * #madduck all
#
### otherwise ignore everything in channels, unless a hilight is triggered:
-# channel * hilights
+# channel * * hilights
#
### make somebot only get your attention if they hilight you:
-# query somebot hilights
+# query efnet somebot hilights
#
### otherwise we want to see everything in queries:
-# query * all
+# query * * all
# DEFAULTS:
-# window * $ftw
-# channel * $ftc
-# query * $ftq
+# window * * $ftw
+# channel * * $ftc
+# query * * $ftq
# vim:noet:tw=0:ts=16
EOF
@@ -408,12 +418,36 @@ sub load_mappings {
my ($filename) = @_;
@window_thresholds = @channel_thresholds = @query_thresholds = ();
my $fh = get_mappings_fh($filename);
+ my $firstline = <$fh>;
+ my $version;
+ if ($firstline =~ m/^#+\s+ctrlact mappings file \(version:([\d.]+)\)/) {
+ $version = $1;
+ }
+ else {
+ die "First line of $filename is not a ctrlact header.";
+ }
+
+ my $nrcols = 4;
+ if ($version eq $VERSION) {
+ # current version
+ }
+ elsif ($version eq "1.0") {
+ $nrcols = 3;
+ }
+ else {
+ die "Unsupported version found in $filename: $version"
+ }
+ my $linesplitter = '^\s*'.join('\s+', ('(\S+)') x $nrcols).'\s*$';
+ my $l = 1;
while (<$fh>) {
+ $l++;
next if m/^\s*(?:#|$)/;
- m/^\s*(\S+)\s+(\S+)\s+(\S+)\s*$/;
- push @window_thresholds, [$2, $3] if match($1, 'window');
- push @channel_thresholds, [$2, $3] if match($1, 'channel');
- push @query_thresholds, [$2, $3] if match($1, 'query');
+ my ($type, @matchers) = m/$linesplitter/;
+ @matchers = ['*', @matchers] if ($version eq "1.0");
+ push @matchers, $l;
+ push @window_thresholds, [@matchers] if match($type, 'window');
+ push @channel_thresholds, [@matchers] if match($type, 'channel');
+ push @query_thresholds, [@matchers] if match($type, 'query');
}
close($fh) || die "Cannot close mappings file: $!";
}
@@ -442,6 +476,7 @@ sub parse_args {
my (@args) = @_;
my @words = ();
my $typewasset = 0;
+ my $tag;
my $max = 0;
my $type = undef;
foreach my $arg (@args) {
@@ -455,25 +490,26 @@ sub parse_args {
$type = 'query' if $1 =~ m/^q/;
$typewasset = 1
}
- elsif ($arg =~ m/^-/) {
- error("Unknown argument: $arg");
+ elsif ($arg =~ m/-(\S+)/) {
+ $tag = $1;
}
else {
push @words, $arg;
$max = length $arg if length $arg > $max;
}
}
- return ($type, $max, @words);
+ return ($type, $tag, $max, @words);
}
sub cmd_query {
my ($data, $server, $item) = @_;
my @args = shellwords($data);
- my ($type, $max, @words) = parse_args(@args);
+ my ($type, $tag, $max, @words) = parse_args(@args);
$type = $type // 'channel';
+ $tag = $tag // '*';
foreach my $word (@words) {
- my ($t, $tt, $match) = get_specific_threshold($type, $word);
- printf CLIENTCRAP "ctrlact $type map: %*s → %d (%s, match:%s)", $max, $word, $t, $tt, $match;
+ my ($t, $tt, $match) = get_specific_threshold($type, $word, $tag);
+ printf CLIENTCRAP "ctrlact $type map: %s %*s → %d (%s, match:%s)", $tag, $max, $word, $t, $tt, $match;
}
}