summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--_data/scripts.yaml165
-rw-r--r--_testing/config.yml7
-rw-r--r--assets/css/style.css9
-rw-r--r--assets/js/votes.js200
-rw-r--r--index.html36
-rw-r--r--scripts/adv_windowlist.pl8
-rw-r--r--scripts/aspell.pl7
-rw-r--r--scripts/cap_sasl_fail.pl6
-rw-r--r--scripts/chanact.pl181
-rw-r--r--scripts/colorkick.pl15
-rw-r--r--scripts/ctrlact.pl574
-rw-r--r--scripts/dccself.pl3
-rw-r--r--scripts/desktop-notify.pl13
-rw-r--r--scripts/go.pl54
-rw-r--r--scripts/hilightwin.pl26
-rw-r--r--scripts/hilite_url.pl28
-rw-r--r--scripts/ident.pl68
-rw-r--r--scripts/invitejoin.pl263
-rw-r--r--scripts/listsort.pl60
-rw-r--r--scripts/logcompress_perl.pl5
-rw-r--r--scripts/mh_sbuserinfo.pl162
-rw-r--r--scripts/nickserv.pl502
-rw-r--r--scripts/pager.pl9
-rw-r--r--scripts/perlalias.pl288
-rw-r--r--scripts/postpone.pl8
-rw-r--r--scripts/print_signals.pl280
-rw-r--r--scripts/reorder.pl311
-rw-r--r--scripts/rud_emotes.pl58
-rw-r--r--scripts/trackbar22.pl11
-rw-r--r--scripts/translit.pl3
-rw-r--r--scripts/xdcc_autoget.pl16
31 files changed, 2725 insertions, 651 deletions
diff --git a/_data/scripts.yaml b/_data/scripts.yaml
index 4135141..512e454 100644
--- a/_data/scripts.yaml
+++ b/_data/scripts.yaml
@@ -99,11 +99,11 @@
description: 'Adds a permanent advanced window list on the right or in a status bar.'
filename: adv_windowlist.pl
license: 'GNU GPLv2 or later'
- modified: '2016-02-15 11:38:04'
+ modified: '2016-11-01 17:15:32'
modules: Text::CharWidth
name: adv_windowlist
url: http://anti.teamidiot.de/
- version: '1.2'
+ version: '1.3'
-
authors: BC-bd
contact: bd@bc-bd.org
@@ -230,10 +230,10 @@
description: 'ASpell spellchecking system for Irssi'
filename: aspell.pl
license: MIT
- modified: '2015-11-16 19:36:52'
+ modified: '2016-10-06 17:55:58'
modules: Text::Aspell
name: aspell
- version: 1.6.1
+ version: 1.6.2
-
authors: 'Philipp Haegi'
commands: rotate_dict
@@ -837,9 +837,9 @@
description: 'Disconnect from server if SASL authentication fails.'
filename: cap_sasl_fail.pl
license: 'GNU GPLv2 or later'
- modified: '2016-03-24 11:01:05'
+ modified: '2017-01-16 16:43:50'
name: cap_sasl_fail
- version: '2.0'
+ version: '2.1'
-
authors: ZaMz0n
commands: cddb
@@ -873,15 +873,15 @@
url: http://pieter-bas.ijdens.com/irssi/
version: 1.0.0
-
- authors: 'BC-bd, Veli'
- contact: 'bd@bc-bd.org, veli@piipiip.net'
+ authors: BC-bd
+ contact: bd@bc-bd.org
description: 'Adds new powerful and customizable [Act: ...] item (chanelnames,modes,alias). Lets you give alias characters to windows so that you can select those with meta-<char>'
filename: chanact.pl
license: 'GNU GPLv2 or later'
- modified: '2016-04-25 18:46:30'
+ modified: '2017-02-13 17:21:07'
name: chanact
- url: https://bc-bd.org/svn/repos/irssi/chanact
- version: 0.5.15
+ url: http://bc-bd.org/blog/irssi/
+ version: 0.6.0
-
authors: "Joern 'Wulf' Heissler"
contact: wulf@wulf.eu.org
@@ -1068,8 +1068,9 @@
description: 'kicking users for using colors or blinks'
filename: colorkick.pl
license: 'public domain'
- modified: '2014-10-17 20:34:00'
+ modified: '2017-03-07 22:28:22'
name: colorkick
+ version: '0.1'
-
authors: "Timo 'cras' Sirainen"
contact: tss@iki.fi
@@ -1167,6 +1168,15 @@
url: http://www.krukowiecki.net/code/irssi/
version: '0.12'
-
+ authors: 'martin f. krafft'
+ contact: madduck@madduck.net
+ description: 'allows per-channel control over activity indication'
+ filename: ctrlact.pl
+ license: MIT
+ modified: '2017-02-24 07:41:29'
+ name: ctrlact
+ version: '1.2'
+-
authors: "Maciek 'fahren' Freudenheim"
contact: fahren@bochnia.pl
description: 'Usage: /CWHO [-a | -l | -o | -v ] [ mask ]'
@@ -1242,8 +1252,9 @@
description: "/dccself ip port, starts a dcc chat with yourself on that \n\t host/port, best used with /set dcc_autochat_masks."
filename: dccself.pl
license: GPL
- modified: '2008-05-17 17:39:11'
+ modified: '2017-03-05 13:58:24'
name: dccself
+ version: '0.1'
-
authors: "Matti 'qvr' Hiljanen"
contact: matti\@hiljanen.com
@@ -1291,10 +1302,10 @@
description: 'Sends notification using the Desktop Notifications Specification.'
filename: desktop-notify.pl
license: 'GPL v3+'
- modified: '2016-08-04 19:09:35'
+ modified: '2017-01-23 21:52:29'
modules: 'Glib::Object::Introspection HTML::Entities'
name: desktop-notify
- version: 1.0.0
+ version: 1.0.1
-
authors: 'Jochem Meyers'
contact: jochem.meyers@gmail.com
@@ -1759,9 +1770,9 @@
description: 'Implements /go command that activates a window given a name/partial name. It features a nice completion.'
filename: go.pl
license: 'GPLv2 or later'
- modified: '2014-10-19 15:12:04'
+ modified: '2017-02-02 02:40:44'
name: 'go to window'
- version: '1.01'
+ version: '1.1'
-
authors: cxreg
contact: cxreg@pobox.com
@@ -1939,10 +1950,20 @@
description: 'Print hilighted messages to window named "hilight"'
filename: hilightwin.pl
license: 'Public Domain'
- modified: '2015-11-07 14:09:15'
+ modified: '2017-02-10 17:59:58'
name: hilightwin
url: http://irssi.org/
- version: '0.04'
+ version: '0.05'
+-
+ authors: 'Stefan Heinemann'
+ contact: stefan.heinemann@codedump.ch
+ description: 'Simple script that highlights URL'
+ filename: hilite_url.pl
+ license: GPL
+ modified: '2017-01-12 12:37:37'
+ name: 'hilite url'
+ url: http://senseless.codedump.ch
+ version: '0.1'
-
authors: 'John Morrissey'
contact: jwm@horde.net
@@ -2024,6 +2045,15 @@
url: http://www.musicpd.org
version: 0.0.0n
-
+ authors: 'Isaac Good'
+ contact: 'irssi@isaacgood.com; irc.freenode.net/yitz'
+ description: 'Automatically IDENTIFY when prompted'
+ filename: ident.pl
+ license: MIT
+ modified: '2016-12-06 18:45:34'
+ name: ident
+ version: '1.0'
+-
authors: 'Eric Jansen'
contact: chaos@sorcery.net
description: 'MD5 NickServ identification script for SorceryNet'
@@ -2143,10 +2173,10 @@
description: 'This script will join a channel if somebody invites you to it.'
filename: invitejoin.pl
license: 'Public Domain'
- modified: '2004-04-11 12:38:18'
+ modified: '2017-01-17 20:26:41'
name: invitejoin.pl
- url: http://irssi.hauwaerts.be/invitejoin.pl
- version: '0.01'
+ url: https://github.com/irssi/scripts.irssi.org/blob/master/scripts/invitejoin.pl
+ version: '0.02'
-
authors: xlony
contact: anderfdez@yahoo.es
@@ -2158,6 +2188,26 @@
name: IPupdate
version: '1.2'
-
+ authors: wilk
+ contact: http://mail.quizpl.net
+ description: 'irssi quiz script'
+ filename: iquiz.pl
+ license: 'GNU GPL v3 or any later version'
+ modified: '2016-10-03 18:26:38'
+ name: iQuiz
+ url: http://iquiz.quizpl.net
+ version: '160919'
+-
+ authors: wilk
+ contact: http://mail.quizpl.net
+ description: 'irssi quiz script'
+ filename: iquiz_en.pl
+ license: 'GNU GPL v3 or any later version'
+ modified: '2016-10-03 18:26:38'
+ name: iQuiz
+ url: http://iquiz.quizpl.net
+ version: 160919_en
+-
authors: DonRumata
commands: none
contact: rumata@dragons.ru
@@ -2532,6 +2582,15 @@
name: listen
version: '0.2'
-
+ authors: 'Isaac Good'
+ contact: irssi@isaacgood.com
+ filename: listsort.pl
+ license: BSD
+ modified: '2016-12-07 11:32:54'
+ name: listsort
+ url: https://github.com/IsaacG/irssi-scripts
+ version: '0.1'
+-
authors: aki
contact: aki@evilbsd.info
description: 'display a loadavg statusbar item using vm.loadavg mib or /proc/loadavg'
@@ -2578,10 +2637,10 @@
description: "compress logfiles then they're rotated, modified from original logcompress.pl to use perl modules instead"
filename: logcompress_perl.pl
license: 'Public Domain'
- modified: '2016-01-31 01:51:39'
+ modified: '2017-01-07 11:52:46'
name: logcompress_perl
url: http://irssi.org/
- version: '0.01'
+ version: '0.02'
-
authors: ferret
commands: 'logtail, logview'
@@ -2747,10 +2806,10 @@
description: 'statusbar item that shows users and limit info in channels'
filename: mh_sbuserinfo.pl
license: BSD
- modified: '2016-01-23 00:22:49'
+ modified: '2016-11-07 14:57:43'
name: mh_sbuserinfo
url: 'http://scripts.irssi.org / https://github.com/mh-source/irssi-scripts'
- version: '1.04'
+ version: '1.05'
-
authors: 'Michael Hansen'
contact: 'mh on IRCnet #help'
@@ -3142,10 +3201,10 @@
description: 'This script will authorize you into NickServ.'
filename: nickserv.pl
license: 'GNU General Public License'
- modified: '2016-04-06 16:03:28'
+ modified: '2017-01-17 00:18:42'
name: nickserv.pl
- url: http://irssi.hauwaerts.be/nickserv.pl
- version: '1.10'
+ url: https://github.com/irssi/scripts.irssi.org/blob/master/scripts/nickserv.pl
+ version: '1.11'
-
authors: BC-bd
contact: bd@bc-bd.org
@@ -3461,9 +3520,9 @@
description: 'Notifies people if they send you a private message or a DCC chat offer while you are away; runs a shell command configurable via /set if they page you'
filename: pager.pl
license: BSD
- modified: '2014-10-19 11:54:16'
+ modified: '2017-03-06 20:58:29'
name: pager
- version: '1.1'
+ version: '1.2'
-
authors: fprintf
contact: fprintf@github.com
@@ -3543,6 +3602,15 @@
url: http://wouter.coekaerts.be/irssi/
version: '1.1'
-
+ authors: aquanight
+ contact: aquanight@gmail.com
+ description: 'Quickly create commands from short perl blocks'
+ filename: perlalias.pl
+ license: 'public domain'
+ modified: '2017-02-19 12:53:47'
+ name: perlalias
+ version: '1.2'
+-
authors: 'Adam Duck'
contact: duck@cs.uni-frankfurt.de
description: 'does CTCP SOUNDs and other similar things.'
@@ -3570,9 +3638,9 @@
description: 'Postpones messages sent to a splitted user and resends them when the nick rejoins'
filename: postpone.pl
license: GPLv2
- modified: '2008-05-17 17:39:11'
+ modified: '2017-02-04 02:11:54'
name: postpone
- version: '20030208'
+ version: '20170204'
-
authors: "Maciek Freudenheim, Marco d'Itri"
contact: 'fahren@bochnia.pl, md@linux.it'
@@ -3584,6 +3652,15 @@
url: http://www.linux.it/~md/irssi/
version: '20020128'
-
+ authors: 'martin f. krafft'
+ contact: madduck@madduck.net
+ description: 'hooks into every signal and writes the information provided to a file'
+ filename: print_signals.pl
+ license: MIT
+ modified: '2017-02-03 11:47:17'
+ name: 'print signals debugger'
+ version: '1.0'
+-
authors: 'Cyprien Debu'
contact: frey@notk.org
description: 'Gets new mails from procmail.log file'
@@ -3751,13 +3828,14 @@
url: http://irssi.dgl.cx/
version: '1'
-
- authors: 'Isaac G'
- contact: irssi@isaac.otherinbox.com
+ authors: 'Isaac Good'
+ contact: irssi@isaacgood.com
description: 'Reordering windows based on a textfile.'
filename: reorder.pl
license: GPL
- modified: '2010-02-12 22:42:13'
+ modified: '2016-12-06 18:47:28'
name: reorder
+ version: '1.0'
-
authors: BC-bd
contact: bd@bc-bd.org
@@ -3853,9 +3931,9 @@
description: 'Replaces :emote_name: text in your sent messages into pre-defined emotes (unicode mostly).'
filename: rud_emotes.pl
license: GPLv3
- modified: '2016-09-17 10:03:31'
+ modified: '2016-11-07 15:43:52'
name: 'emotes script'
- version: '1.00'
+ version: '1.10'
-
authors: "Johan \"Ion\" Kiviniemi, idea taken from Riku Voipio's sana.pl"
contact: 'ion at hassers.org'
@@ -4459,11 +4537,11 @@
description: 'Shows a bar where you have last read a window.'
filename: trackbar22.pl
license: 'GNU General Public License'
- modified: '2015-11-16 19:36:52'
+ modified: '2017-01-09 14:35:07'
modules: Text::CharWidth
name: trackbar
url: http://www.pfoe.be/~peter/trackbar/
- version: '2.2'
+ version: '2.3'
-
authors: 'Timo Sirainen'
contact: tss@iki.fi
@@ -4480,8 +4558,9 @@
description: translitiratar
filename: translit.pl
license: GPL
- modified: '2008-05-17 17:39:11'
+ modified: '2017-03-05 14:29:01'
name: translit
+ version: '0.1'
-
authors: 'Wouter Coekaerts'
contact: wouter@coekaerts.be
@@ -4937,10 +5016,10 @@
description: 'XDCC Autoget, for automated searching and downloading of xdcc packs'
filename: xdcc_autoget.pl
license: 'BeerWare Version 42'
- modified: '2016-02-09 01:27:46'
+ modified: '2016-10-26 19:23:08'
modules: 'File::HomeDir Try::Tiny'
name: autoget
- version: '2.0'
+ version: '2.1'
-
authors: "Stefan 'tommie' Tomanek, Obfuscoder"
commands: xdccget
diff --git a/_testing/config.yml b/_testing/config.yml
index 2b96a25..8764417 100644
--- a/_testing/config.yml
+++ b/_testing/config.yml
@@ -36,12 +36,10 @@ cpan:
whitelist:
- amaroknp
- babelirc
+ - cap_sasl_fail
- cap_sasl
- - cgrep
- - colorkick
- connectcmd
- dau
- - dccself
- dnsspam
- hddtemp
- hitcount
@@ -63,19 +61,16 @@ whitelist:
- 'on'
- osd
- page-c0ffee
- - pager
- query
- quizgr
- quizmaster-fr
- quizmaster
- quiz
- randaway
- - reorder
- scroller
- stocks
- sysinfoplus
- topicsed
- - translit
- tvmusor
- wordcompletition
- xetra
diff --git a/assets/css/style.css b/assets/css/style.css
index fe72819..302d311 100644
--- a/assets/css/style.css
+++ b/assets/css/style.css
@@ -23,3 +23,12 @@ table.sortable thead {
table.sortable thead th:hover {
opacity: 0.8;
}
+
+div.instructions input {
+ opacity: 0;
+ position: fixed;
+}
+div.instructions label { display: inline; }
+input#manual-instructions:checked ~ dl.automatic-instructions,
+input#automatic-instructions:checked ~ dl.manual-instructions
+{ display: none; }
diff --git a/assets/js/votes.js b/assets/js/votes.js
index 4fb585d..2fa9097 100644
--- a/assets/js/votes.js
+++ b/assets/js/votes.js
@@ -1,75 +1,153 @@
(function(document, $){
'use strict';
var jsonpRe = /^\/\*[\s\S]*?\*\/jsonp\(([\s\S]*)\)$/m;
+ var ghLimits = {search: {}, core: {}};
+ var stopId = 0;
+ var queue = {search: [], core: []};
+ var todo = 1;
- function requestAll(start) {
- $.ajax({
+ function requestLater(what, how, arg) {
+ var when = rateTimeout(what);
+ if (when >= 0) {
+ var empty = queue[what].length == 0;
+ queue[what].push([how, arg]);
+ if (empty) window.setTimeout(function(){reQueue(what);}, when);
+ } else {
+ ghLimits[what].remaining--;
+ how(arg);
+ }
+ }
+
+ function reQueue(what) {
+ limitsThen(what, function(q) {
+ q.forEach(function(e) {
+ requestLater(what, e[0], e[1]);
+ });
+ }, queue[what].splice(0, queue[what].length));
+ }
+
+ function signalDone() {
+ if (!todo) $("#th-votes").html("Votes");
+ }
+
+ function _jsonpToJson(dta, typ) {
+ if (typ == "json") {
+ return dta.replace(jsonpRe, "$1");
+ }
+ return dta;
+ }
+
+ function jj(url) {
+ return $.ajax({
accepts: { json: 'application/vnd.github.squirrel-girl-preview' },
dataType: 'json',
- url: start,
+ url: url + (url.indexOf('callback=') === -1
+ ? (url.indexOf('?') === -1 ? '?' : ';') + 'callback=jsonp'
+ : ''),
jsonp: false,
jsonpCallback: 'jsonp',
- dataFilter: function(dta, typ) {
- if (typ == "json") {
- return dta.replace(jsonpRe, "$1");
- }
- return dta;
- }
- })
- .done(function(r) {
- var remaining = r.meta['X-RateLimit-Remaining'];
- var rateReset = r.meta['X-RateLimit-Reset'];
- var timeOut = 0;
- var hasMore = false;
- if (remaining < 10) {
- timeOut = 1000 + rateReset * 1000 - (new Date() / 1);
- }
- if (timeOut < 0) timeOut = 0;
- if (r.meta.Link) {
- r.meta.Link.forEach(function(l) {
- if (l[1].rel == "next") {
- window.setTimeout(function(){requestAll(l[0]);}, timeOut);
- hasMore = true;
- return;
- }
- });
- }
- if (timeOut > 0) {
- timeOut += 1000;
+ dataFilter: _jsonpToJson
+ });
+ }
+
+ function searchVotes(url) {
+ var start = url.indexOf("//") !== -1 ? url
+ : 'https://api.github.com/search/issues?q=votes+in:title+state:closed+type:issue+'
+ + 'repo:' + url + ';sort=updated';
+ jj(start).done(function(r) {
+ var hasMore = fetchNext('search', r.meta, searchVotes);
+ if (hasMore) todo++;
+ r.data.items.forEach(function(e) {
+ if (stopId && e.number > stopId) return;
+ if (e.title != "votes") return;
+ if (e.locked) { stopId = e.number; return; }
+ todo++;
+ requestLater('core', requestComments, e.comments_url);
+ todo++;
+ requestLater('core', requestComments, e.comments_url + '?page=2');
+ todo++;
+ requestLater('core', requestComments, e.comments_url + '?page=3');
+ //todo++;
+ //requestLater('core', requestComments, e.comments_url + '?page=4');
+ });
+ todo--;
+ signalDone();
+ });
+ }
+
+ function rateTimeout(what) {
+ if ($.isEmptyObject(ghLimits[what])) return -1;
+
+ var remaining = ghLimits[what].remaining;
+ var rateReset = ghLimits[what].reset;
+ var limit = ghLimits[what].limit;
+
+ var timeOut = -1;
+ if (remaining < Math.log(limit) + Math.sqrt(limit)) {
+ timeOut = 1000 + rateReset * 1000 - (new Date() / 1);
+ if (timeOut < -1) timeOut = 0;
+ }
+ return timeOut;
+ }
+
+ function updateLimits(what, meta) {
+ ghLimits[what].remaining = meta['X-RateLimit-Remaining'];
+ ghLimits[what].reset = meta['X-RateLimit-Reset'];
+ }
+
+ function fetchNext(what, meta, how) {
+ var hasMore = false;
+ updateLimits(what, meta);
+ if (meta.Link) {
+ meta.Link.forEach(function(l) {
+ if (l[1].rel == "next") {
+ hasMore = true;
+ requestLater(what, how, l[0]);
+ return;
}
+ });
+ }
+ return hasMore;
+ }
- r.data.forEach(function(e) {
- e.body = e.body.replace(/\r/g, "");
- var redir = e.body.match(/^#(\d+)$/);
- if (redir) {
- var l = start.replace(/(\/issues\/)\d+(\/comments\?)/, "$1" + redir[1] + "$2").replace(/&.*/, "");
- window.setTimeout(function(){requestAll(l);}, timeOut);
- hasMore = true;
- return;
- }
-
- var lines = e.body.split("\n");
- var script = lines[0].replace(/[^-a-zA-Z0-9_]/g, "_");
- if (script == "comment") {
- script = "adv_windowlist_pl";
- }
- var st = "#script-" + script + " .votes";
- var row = $(st);
- if (row.length) {
- var votes = 1+ e.reactions['+1'] - e.reactions['-1'];
- var link = "๏ผŠ";
- if (e.reactions['heart'] >= votes) {
- link = "๐Ÿ’œ";
- }
- row.html( "" + votes );
-
- row.append("<span><a data-toggle=\"tooltip\" title=\"vote on github\" href=\"" + e.html_url + "\">"+link+"</a></span>");
- }
- });
- if (!hasMore) {
- $("#th-votes").html("Votes");
+ function requestComments(start) {
+ jj(start).done(function(r) {
+ updateLimits('core', r.meta);
+ if (r.meta.status == 403 && !r.meta['X-RateLimit-RateLimit']) {
+ requestLater('core', requestComments, start);
+ return;
+ }
+ //var hasMore = fetchNext('core', r.meta, requestComments);
+ //if (hasMore) todo++;
+ r.data.some(function(e) {
+ e.body = e.body.replace(/\r/g, "");
+ var lines = e.body.split("\n");
+ var redir = e.body.match(/^#(\d+)$/);
+ if (redir) return true;
+ var script = lines[0].replace(/^## /, "").replace(/[^-a-zA-Z0-9_]/g, "_");
+ var row = $("#script-" + script + " .votes");
+ if (row.length) {
+ var votes = 1+ e.reactions['+1'] - e.reactions['-1'];
+ var link = "๏ผŠ";
+ if (e.reactions['heart'] >= votes) link = "๐Ÿ’œ";
+ row.html( "" + votes );
+ row.append("<span><a data-toggle=\"tooltip\" title=\"vote on github\" href=\""
+ + e.html_url + "\">"+link+"</a></span>");
}
+ return false;
});
+ todo--;
+ signalDone();
+ });
}
- requestAll('https://api.github.com/repos/ailin-nemui/scripts.irssi.org/issues/2/comments?callback=jsonp');
+
+ function limitsThen(what, how, arg) {
+ jj('https://api.github.com/rate_limit').done(function(r) {
+ ghLimits = r.data.resources;
+ requestLater(what, how, arg);
+ });
+ }
+
+ limitsThen('search', searchVotes, 'ailin-nemui/scripts.irssi.org');
+
})(document, $);
diff --git a/index.html b/index.html
index b44aa25..feda0dd 100644
--- a/index.html
+++ b/index.html
@@ -10,7 +10,31 @@ layout: default
</div>
<div class="row">
- <dl>
+ <div class="instructions">
+ <input id="automatic-instructions" type="radio" checked="checked" name="instructions" />
+ <input id="manual-instructions" type="radio" name="instructions" />
+ <dl class="automatic-instructions">
+ <dt>How do I install scripts?</dt>
+ <dd>In Irssi, do <code>/run scriptassist</code> (only once per session), then
+ <code>/script install <i>scriptname</i></code> .
+
+ <dt>How do I rerun scripts?</dt>
+ <dd>Just do <code>/script load <i>scriptname</i></code> .</dd>
+
+ <dt>How do I unload scripts?</dt>
+ <dd>Just do <code>/script unload <i>scriptname</i></code> .</dd>
+
+ <dt>How do I run scripts automatically at startup?</dt>
+ <dd>Just do <code>/script autorun <i>scriptname</i></code> .</dd>
+
+ <dt>Scriptassist does not work for me / I want to do it myself?</dt>
+ <dd><label for="manual-instructions" class="btn-link">
+ View manual instructions.</label></dd>
+
+ <dt>How do I submit a script to this page?</dt>
+ <dd>See information on how to contribute <a href="https://github.com/irssi/scripts.irssi.org">here</a>.</dd>
+ </dl>
+ <dl class="manual-instructions">
<dt>How do I run scripts?</dt>
<dd>Put them into <code>~/.irssi/scripts/</code> and in irssi do
<code>/script load script.pl</code> . There is a default alias for
@@ -32,15 +56,17 @@ layout: default
<dt>Is there an easy way of managing scripts?</dt> <dd>Try
<code>scriptassist.pl</code>, it can update and manage your scripts
- as well as install new ones and search the database.</dd>
+ as well as install new ones and search the database.
+ <label for="automatic-instructions" class="btn-link">
+ View instructions when using scriptassist.pl .</label></dd>
<dt>How do I submit a script to this page?</dt>
<dd>See information on how to contribute <a href="https://github.com/irssi/scripts.irssi.org">here</a>.</dd>
</dl>
-
+ </div>
<hr>
- <input type="search" class="light-table-filter form-control" data-table="sortable" data-name="q" placeholder="Filter" style="width: 100%">
+ <input type="search" class="light-table-filter form-control" data-table="sortable" data-name="q" placeholder="Filter" style="width: 100%" autocorrect="off" spellcheck="false">
<table class="table table-striped table-condensed sortable">
<thead>
<tr>
@@ -50,7 +76,7 @@ layout: default
<th class="sorttable_alpha">Description</th>
<th class="sorttable_alpha">Authors</th>
<th class="sorttable_alpha">Modified</th>
- <th class="sorttable_numeric" id="th-votes">&hellip;</th>
+ <th class="sorttable_numeric" id="th-votes">&hellip;&hellip;</th>
</tr>
</thead>
<tbody>
diff --git a/scripts/adv_windowlist.pl b/scripts/adv_windowlist.pl
index ee0219b..6285786 100644
--- a/scripts/adv_windowlist.pl
+++ b/scripts/adv_windowlist.pl
@@ -1,7 +1,7 @@
use strict;
use warnings;
-our $VERSION = '1.2'; # 762850b0c2c1d5a
+our $VERSION = '1.3'; # 463402cffae35e5
our %IRSSI = (
authors => 'Nei',
contact => 'Nei @ anti@conference.jabber.teamidiot.de',
@@ -1710,8 +1710,13 @@ sub string_LCSS {
(sort { length $b <=> length $a } $str =~ /(?=(.+).*\0.*\1)/g)[0]
}
+# workaround for issue #271
{ package Irssi::Nick }
+# workaround for issue #572
+@Irssi::UI::Exec::ISA = 'Irssi::Windowitem'
+ if Irssi::version >= 20140822 && Irssi::version <= 20161101 && !@Irssi::UI::Exec::ISA;
+
UNITCHECK
{ package AwlViewer;
use strict;
@@ -2388,6 +2393,7 @@ UNITCHECK
# Changelog
# =========
+# 1.3 - workaround for irssi issue #572
# 1.2 - new format to choose abbreviation character
# 1.1 - infinite loop on shortening certain window names reported by Kalan
#
diff --git a/scripts/aspell.pl b/scripts/aspell.pl
index b6a254e..71369f3 100644
--- a/scripts/aspell.pl
+++ b/scripts/aspell.pl
@@ -85,6 +85,7 @@ See README file.
use warnings;
use strict;
use Data::Dumper;
+use Encode 'decode';
use Irssi;
use Irssi::Irc;
use Irssi::TextUI;
@@ -107,7 +108,7 @@ if ($@ && $@ =~ m/Can't locate/) {
}
-our $VERSION = '1.6.1';
+our $VERSION = '1.6.2';
our %IRSSI = (
authors => 'Isaac Good (yitz_), Tom Feist (shabble)',
contact => 'irssi@isaacgood.com, shabble+irssi@metavore.org',
@@ -306,6 +307,7 @@ sub process_word {
} else {
print_suggestions();
+ highlight_incorrect_word($word_obj);
}
} else {
@@ -391,7 +393,8 @@ sub spellcheck_finish {
# stick the cursor at the end of the input line?
my $input = _input();
- my $end = length($input);
+ my $charset = lc Irssi::settings_get_str('term_charset');
+ my $end = length(decode $charset=>$input);
Irssi::gui_input_set_pos($end);
}
diff --git a/scripts/cap_sasl_fail.pl b/scripts/cap_sasl_fail.pl
index 226bc2c..22d0b79 100644
--- a/scripts/cap_sasl_fail.pl
+++ b/scripts/cap_sasl_fail.pl
@@ -1,7 +1,7 @@
use strict;
use warnings;
-our $VERSION = '2.0'; # ed9e98e5d63cfb3
+our $VERSION = '2.1'; # bb62357c61d9e54
our %IRSSI = (
authors => 'Nei',
name => 'cap_sasl_fail',
@@ -15,8 +15,8 @@ use version;
my %disconnect_next;
my $irssi_version = qv(Irssi::parse_special('v$J') =~ s/-.*//r);
-die sprintf "Support for Irssi v%vd has not been written yet.\n", $irssi_version
- if $irssi_version > v0.8.20;
+die sprintf "Please use /set sasl_disconnect_on_failure instead of this script.\n"
+ if $irssi_version >= v1.0.0;
Irssi::signal_register({'server sasl fail' => [qw[iobject string]]});
Irssi::signal_add_first('server sasl fail' => 'sasl_fail_failed');
diff --git a/scripts/chanact.pl b/scripts/chanact.pl
index ee6ef3c..4a42364 100644
--- a/scripts/chanact.pl
+++ b/scripts/chanact.pl
@@ -1,20 +1,25 @@
use Irssi 20020101.0001 ();
+
use strict;
-# FIXME use warning;
+use warnings;
+
use Irssi::TextUI;
use vars qw($VERSION %IRSSI);
-$VERSION = "0.5.15";
+$VERSION = "0.6.0";
%IRSSI = (
- authors => 'BC-bd, Veli',
- contact => 'bd@bc-bd.org, veli@piipiip.net',
+ authors => 'BC-bd',
+ contact => 'bd@bc-bd.org',
name => 'chanact',
description => 'Adds new powerful and customizable [Act: ...] item (chanelnames,modes,alias). Lets you give alias characters to windows so that you can select those with meta-<char>',
license => 'GNU GPLv2 or later',
- url => 'https://bc-bd.org/svn/repos/irssi/chanact'
+ url => 'http://bc-bd.org/blog/irssi/'
);
+# Please send patches / pull requests to the email listed unter contact above
+# and not to the irssi/scripts.irssi.org repository on github.
+
# Adds new powerful and customizable [Act: ...] item (chanelnames,modes,alias).
# Lets you give alias characters to windows so that you can select those with
# meta-<char>.
@@ -27,19 +32,22 @@ $VERSION = "0.5.15";
# Contributors
#########
#
-# veli@piipiip.net /window_alias code
-# qrczak@knm.org.pl chanact_abbreviate_names
-# qerub@home.se Extra chanact_show_mode and chanact_chop_status
+# veli@piipiip.net original /window_alias code
+# qrczak@knm.org.pl chanact_abbreviate_names
+# qerub@home.se Extra chanact_show_mode and chanact_chop_status
# madduck@madduck.net Better channel aliasing (case-sensitive, cross-network)
# chanact_filter_windowlist basis
-# Jan 'jast' Krueger <jast@heapsort.de>, 2004-06-22
-# Ivo Timmermans <ivo@o2w.nl> win->{hilight} patch
-# Trevor 'tee' Slocum <tslocum@gmail.com> Case-insensitive aliases, bugfix
-#
+# jast@heapsort.de Updated documentation
+# ivo@o2w.nl win->{hilight} patch
+# Bazerka base patch for sorting by level change
+# updated documentation
+# mrtnpaolo@gmail.com rename commands
+# tslocum@gmail.com Case-insensitive aliases
+#
#########
# USAGE
###
-#
+#
# copy the script to ~/.irssi/scripts/
#
# In irssi:
@@ -61,11 +69,11 @@ $VERSION = "0.5.15";
# aliases to your windows. Go to the window you want to give the alias to
# and say:
#
-# /window_alias <alias char>
+# /chanact_window_alias <alias char>
#
# You can remove the aliases with from an aliased window:
#
-# /window_unalias
+# /chanact_window_unalias
#
# To see a list of your windows use:
#
@@ -100,11 +108,11 @@ $VERSION = "0.5.15";
# $H : Start highlightning
# $S : Stop highlightning
# * example:
-#
+#
# /set chanact_display $H$N:$M.$S$C
-#
+#
# will give you on #irssi.de if you have voice
-#
+#
# [3:+.#irssi.de]
#
# with '3:+.' highlighted and the channel name printed in regular color
@@ -113,12 +121,26 @@ $VERSION = "0.5.15";
# * ON : Aliases are case-sensitive
# * OFF : Aliases are case-insensitive
#
-# Existing aliases must be reapplied after switching to case-insensitive.
+# Existing aliases must be reapplied after changing this option
+#
+# Switching from OFF to ON _after_ aliases have been defined, and
+# then redefining or changing an existing alias will leave some
+# bindings behind, e.g.
+#
+# /set chanact_case_sensitive OFF
+# /chanact_window_alias x
+#
+# -> window reachable with meta-x/meta-X
+#
+# /set chanact_case_sensitive ON
+# /chanact_window_alias y
+#
+# -> window reachable with meta-y/meta-X
#
# /set chanact_display_alias <string>
# as 'chanact_display' but is used if the window has an alias and
# 'chanact_show_alias' is set to on.
-#
+#
# /set chanact_show_names <ON|OFF>
# * ON : show the channelnames after the number/alias
# * OFF : don't show the names
@@ -141,7 +163,7 @@ $VERSION = "0.5.15";
#
# /set chanact_autorenumber <ON|OFF>
# * ON : Move the window automatically to first available slot
-# starting from "chanact_renumber_start" when assigning
+# starting from "chanact_renumber_start" when assigning
# an alias to window. Also moves the window back to a
# first available slot from refnum 1 when the window
# loses it's alias.
@@ -160,7 +182,7 @@ $VERSION = "0.5.15";
# beginning of the channel name.
# * example :
# To shorten a lot of debian channels:
-#
+#
# /set chanact_remove_prefix deb(ian.(devel-)?)?
#
# /set chanact_filter <int>
@@ -174,7 +196,7 @@ $VERSION = "0.5.15";
# * <string> : space-separated list of windows for which to use
# chanact_filter_windowlist_level instead of
# chanact_filter.
-#
+#
# Alternatively, an entry can be postfixed with
# a comma (',') and the level to use for that
# window.
@@ -232,15 +254,14 @@ sub expand {
# but we dont need to recreate the item every time so we first
# check if something has changed and only then we recreate the string
# this might just save some cycles
-# FIXME implement $get_size_only check, and user $item->{min|max-size}
sub chanact {
my ($item, $get_size_only) = @_;
if ($needRemake) {
remake();
}
-
- $item->default_handler($get_size_only, $actString, undef, 1);
+
+ $item->default_handler($get_size_only, $actString, "", 1);
}
# build a hash to easily access special levels based on
@@ -268,13 +289,13 @@ sub calculate_levels(@) {
my %levels;
foreach my $win (@windows) {
- # FIXME we could use the next statements to weed out entries in
- # @windows that we will not need later on
!ref($win) && next;
my $name = $win->get_active_name;
+ # skip nameless windows
+ next unless $name;
- if (exists($matches{$name})) {
+ if ($name && exists($matches{$name})) {
$levels{$name} = $matches{$name};
} else {
$levels{$name} = $default;
@@ -293,7 +314,7 @@ sub calculate_levels(@) {
# this is the real creation method
sub remake() {
my ($afternumber,$finish,$hilight,$mode,$number,$display,@windows);
- my $separator = Irssi::settings_get_str('chanact_separator');
+ my $separator = Irssi::settings_get_str('chanact_separator');
my $abbrev = Irssi::settings_get_int('chanact_abbreviate_names');
my $remove_prefix = Irssi::settings_get_str('chanact_remove_prefix');
my $remove_hash = Irssi::settings_get_bool('chanact_remove_hash');
@@ -317,6 +338,8 @@ sub remake() {
$type = $active->{type} if $active;
my $name = $win->get_active_name;
+ # skip windows without a name
+ next unless $name;
my $filter_level =
$type eq 'QUERY' ? $levels{'@QUERIES'} : $levels{$name};
@@ -334,7 +357,7 @@ sub remake() {
&& $name eq "(status)") {
$name = "S";
}
-
+
# check if we should show the mode
$mode = "";
if ($type eq "CHANNEL") {
@@ -346,7 +369,7 @@ sub remake() {
my $nick = $channel->nick_find($server->{nick});
!ref($nick) && next;
-
+
if ($nick->{op}) {
$mode = "@";
} elsif ($nick->{voice}) {
@@ -377,13 +400,13 @@ sub remake() {
$name =~ s/^[&#+!=]//;
}
- if (Irssi::settings_get_bool('chanact_show_alias') == 1 &&
+ if (Irssi::settings_get_bool('chanact_show_alias') == 1 &&
$win->{name} =~ /^([a-zA-Z+]):(.+)$/) {
$number = "$1";
- $display = Irssi::settings_get_str('chanact_display_alias');
+ $display = Irssi::settings_get_str('chanact_display_alias');
} else {
$number = $win->{refnum};
- $display = Irssi::settings_get_str('chanact_display');
+ $display = Irssi::settings_get_str('chanact_display');
}
# fixup { and } in nicks, those are used by irssi themes
@@ -396,7 +419,7 @@ sub remake() {
if ($actString ne "") {
# Remove the last separator
$actString =~ s/$separator$//;
-
+
$actString = "{sb ".Irssi::settings_get_str('chanact_header').$actString."}";
}
@@ -429,12 +452,33 @@ sub setup_changed {
chanactHasChanged();
}
+# Remove key binding for current window
+sub unbind {
+ my ($name, $server) = @_;
+
+ # chanact'ified windows have a name like this: X:servertag/name. if we
+ # can't find anything like this we return and do not unbind nor renumber
+ # anything
+ my ($key, $tag) = split(/:/, $name);
+ return unless $tag;
+
+ ($tag, $name) = split('/', $tag);
+ return unless (length($key) == 1);
+
+ if (Irssi::settings_get_bool('chanact_case_sensitive')) {
+ $server->command("/bind -delete meta-$key");
+ } else {
+ $server->command("/bind -delete meta-" . lc($key));
+ $server->command("/bind -delete meta-" . uc($key));
+ }
+}
+
# Remove alias
sub cmd_window_unalias {
- my ($data, $server, $witem, $internal) = @_;
+ my ($data, $server, $witem) = @_;
- if ($data ne '' && !$internal) {
- Irssi::print("chanact: /window_unalias does not take any ".
+ if ($data ne '') {
+ Irssi::print("chanact: /chanact_window_unalias does not take any ".
"parameters, Run it in the window you want to unalias");
return;
}
@@ -442,24 +486,7 @@ sub cmd_window_unalias {
my $win = Irssi::active_win();
my $name = Irssi::active_win()->{name};
- # chanact'ified windows have a name like this: X:servertag/name
- my ($key, $tag) = split(/:/, $name);
- ($tag, $name) = split('/', $tag);
-
- # remove alias only of we have a single character keybinding, if we
- # haven't the name was not set by chanact, so we won't blindly unset
- # stuff
- if (length($key) == 1) {
- if (Irssi::settings_get_bool('chanact_case_sensitive')) {
- $server->command("/bind -delete meta-$data");
- } else {
- $server->command("/bind -delete meta-" . lc($data));
- $server->command("/bind -delete meta-" . uc($data));
- }
- } elsif (!$internal) {
- Irssi::print("chanact: could not determine keybinding. ".
- "Won't unbind anything");
- }
+ unbind($name, $server);
# set the windowname back to it's old one. We don't bother checking
# for a vaild name here, as we want to remove the current one and if
@@ -472,7 +499,7 @@ sub cmd_window_unalias {
# we are renumbering, so move the window to the lowest available
# refnum.
my $refnum = 1;
- while (Irssi::window_find_refnum($refnum) ne "") {
+ while (Irssi::window_find_refnum($refnum)) {
$refnum++;
}
@@ -480,14 +507,13 @@ sub cmd_window_unalias {
Irssi::print("chanact: moved wintow to refnum $refnum");
}
-# function by veli@piipiip.net
# Make an alias
sub cmd_window_alias {
my ($data, $server, $witem) = @_;
my $rn_start = Irssi::settings_get_int('chanact_renumber_start');
unless ($data =~ /^[a-zA-Z+]$/) {
- Irssi::print("Usage: /window_alias <char>");
+ Irssi::print("Usage: /chanact_window_alias <char>");
return;
}
@@ -508,23 +534,23 @@ sub cmd_window_alias {
$winname = $window->{name};
}
- cmd_window_unalias($data, $server, $witem, 1);
+ unbind($window->{name}, $server);
my $winnum = $window->{refnum};
-
+
if (Irssi::settings_get_bool('chanact_autorenumber') == 1 &&
$window->{refnum} < $rn_start) {
my $old_refnum = $window->{refnum};
$winnum = $rn_start;
-
+
# Find the first available slot and move the window
- while (Irssi::window_find_refnum($winnum) ne "") { $winnum++; }
+ while (Irssi::window_find_refnum($winnum)) { $winnum++; }
$window->set_refnum($winnum);
-
+
Irssi::print("Moved the window from $old_refnum to $winnum");
}
-
+
my $winserver = $window->{active_server}->{tag};
my $winhandle = "$winserver/$winname";
# cmd_window_unalias relies on a certain format here
@@ -543,8 +569,8 @@ sub cmd_window_alias {
$needRemake = 1;
# Window alias command
-Irssi::command_bind('window_alias','cmd_window_alias');
-Irssi::command_bind('window_unalias','cmd_window_unalias');
+Irssi::command_bind('chanact_window_alias','cmd_window_alias');
+Irssi::command_bind('chanact_window_unalias','cmd_window_unalias');
# our config item
Irssi::settings_add_str('chanact', 'chanact_display', '$H$N:$M$C$S');
@@ -587,8 +613,15 @@ Irssi::signal_add('nick mode changed', 'chanactHasChanged');
#
# Changelog
#
-# 0.5.15
-# - fixed unbind error when aliasing a previously un-aliased window
+# 0.6.0
+# - fixed URL
+# - now with 'use warnings'
+# - fix cmd_window_unalias call from cmd_window_alias
+# - fix Use of uninitialized value $name in hash element warnings
+# - return from cmd_window_unalias if the window has no valid
+# chanact'ified name
+# - rename /window_(un)alias to /chanact_window_(un)alias
+# - fix refnum renumber race
# - added setting to allow case-insensitive window aliases
#
# 0.5.14
@@ -645,10 +678,10 @@ Irssi::signal_add('nick mode changed', 'chanactHasChanged');
#
# 0.5.6
# - fixed a bug (#1) reported by Wouter Coekaert
-#
+#
# 0.5.5
# - some speedups from David Leadbeater <dgl@dgl.cx>
-#
+#
#
# 0.5.4
# - added help for chanact_display_alias
@@ -662,7 +695,7 @@ Irssi::signal_add('nick mode changed', 'chanactHasChanged');
# - removed unused chanact_show_name settings (thx to Qerub)
# - fixed $mode display
# - guarded reference operations to (hopefully) fix errors on server disconnect
-#
+#
# 0.5.1
# - small typo fixed
#
@@ -670,7 +703,7 @@ Irssi::signal_add('nick mode changed', 'chanactHasChanged');
# - changed chanact_show_mode to chanact_display. reversed changes from
# Qerub through that, but kept funcionality.
# - removed chanact_color_all since it is no longer needed
-#
+#
# 0.4.3
# - changes by Qerub
# + added chanact_show_mode to show the mode just before the channel name
diff --git a/scripts/colorkick.pl b/scripts/colorkick.pl
index 24b29fd..c28e420 100644
--- a/scripts/colorkick.pl
+++ b/scripts/colorkick.pl
@@ -13,7 +13,8 @@ use strict;
use Irssi;
use Irssi::Irc;
-use vars %IRSSI;
+use vars qw/%IRSSI $VERSION/;
+$VERSION='0.1';
%IRSSI =
(
authors => "Gabor Nyeki",
@@ -22,7 +23,7 @@ use vars %IRSSI;
description => "kicking users for using colors or blinks",
license => "public domain",
written => "Thu Dec 26 00:22:54 CET 2002",
- changed => "Fri Jan 2 03:43:10 CET 2004"
+ changed => "2017-03-07"
);
sub catch_junk
@@ -31,15 +32,15 @@ sub catch_junk
my ($target, $text) = split(/ :/, $data, 2);
my $valid_channel = 0;
- if ($target[0] != '#' && $target[0] != '!' && $target[0] != '&')
- {
- return;
- }
+ #if ($target[0] != '#' && $target[0] != '!' && $target[0] != '&')
+ #{
+ # return;
+ #}
for my $channel (split(/ /,
Irssi::settings_get_str('colorkick_channels')))
{
- if ($target == $channel)
+ if ($target eq $channel)
{
$valid_channel = 1;
last;
diff --git a/scripts/ctrlact.pl b/scripts/ctrlact.pl
new file mode 100644
index 0000000..da39804
--- /dev/null
+++ b/scripts/ctrlact.pl
@@ -0,0 +1,574 @@
+# ctrlact.pl โ€” Irssi script for fine-grained control of activity indication
+#
+# ยฉ 2017 martin f. krafft <madduck@madduck.net>
+# Released under the MIT licence.
+#
+### Usage:
+#
+# /script load ctrlact
+#
+# If you like a busy activity statusbar, this script is not for you.
+#
+# If, on the other hand, you don't care about most activity, but you do want
+# the ability to define per-item and per-window, what level of activity should
+# trigger a change in the statusbar, then ctrlact might be for you.
+#
+# 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 (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 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"
+# "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"
+#
+# Loading this script per-se should not change anything, except it will create
+# ~/.irssi/ctrlact with some informational content, including the defaults and
+# some examples.
+#
+# The four activity levels are, and you can use either the words, or the
+# integers in the map.
+#
+# all (data_level: 1)
+# messages (data_level: 2)
+# hilights (data_level: 3)
+# none (data_level: 4)
+#
+# Note that the name is either matched in full and verbatim, or treated like
+# a regular expression, if it starts and ends with the same punctuation
+# character. The asterisk ('*') is special and simply gets translated to /.*/
+# internally. No other wildcards are supported.
+#
+# Once you defined your mappings, please don't forget to /ctrlact reload them.
+# You can then use the following commands from Irssi to check out the result:
+#
+# # list all mappings
+# /ctrlact list
+#
+# # query the applicable activity levels, possibly limited to
+# # windows/channels/queries
+# /ctrlact query name [name, โ€ฆ] [-window|-channel|-query]
+#
+# # display the applicable level for each window/channel/query
+# /ctrlact show [-window|-channel|-query]
+#
+# There's an interplay between window items and windows here, and you can
+# specify mininum activity levels for each. Here are the rules:
+#
+# 1. if the minimum activity level of a window item (channel or query) is not
+# reached, then the window is prevented from indicating activity.
+# 2. if traffic in a window item does reach minimum activity level, then the
+# minimum activity level of the window is considered, and activity is only
+# indicated if the window's minimum activity level is lower.
+#
+# In general, this means you'd have windows defaulting to 'all', but it might
+# come in handy to move window items to windows with min.levels of 'hilights'
+# or even 'none' in certain cases, to further limit activity indication for
+# them.
+#
+# You can use the Irssi settings activity_msg_level and activity_hilight_level
+# to specify which IRC levels will be considered messages and hilights. Note
+# that if an activity indication is inhibited, then there also won't be
+# a beep (cf. beep_msg_level), unless you toggle ctrlmap_inhibit_beep.
+#
+### Settings:
+#
+# /set ctrlact_map_file [~/.irssi/ctrlact]
+# Controls where the activity control map will be read from (and saved to)
+#
+# /set ctrlact_fallback_(channel|query|window)_threshold [1]
+# Controls the lowest data level that will trigger activity for channels,
+# queries, and windows respectively, if no applicable mapping could be
+# found.
+#
+# /set ctrlact_inhibit_beep [on]
+# If an activity wouldn't be indicated, also inhibit the beep/bell. Turn
+# this off if you want the bell anyway.
+#
+# /set ctrlact_debug [off]
+# Turns on debug output. Not that this may itself be buggy, so please don't
+# use it unless you really need it.
+#
+### To-do:
+#
+# - figure out interplay with activity_hide_level
+# - /ctrlact add/delete/move and /ctrlact save, maybe
+# - completion for commands
+#
+use strict;
+use warnings;
+use Carp qw( croak );
+use Irssi;
+use Text::ParseWords;
+
+our $VERSION = '1.2';
+
+our %IRSSI = (
+ authors => 'martin f. krafft',
+ contact => 'madduck@madduck.net',
+ name => 'ctrlact',
+ description => 'allows per-channel control over activity indication',
+ license => 'MIT',
+ changed => '2017-02-24'
+);
+
+### DEFAULTS AND SETTINGS ######################################################
+
+my $debug = 0;
+my $map_file = Irssi::get_irssi_dir()."/ctrlact";
+my $fallback_channel_threshold = 1;
+my $fallback_query_threshold = 1;
+my $fallback_window_threshold = 1;
+my $inhibit_beep = 1;
+
+Irssi::settings_add_str('ctrlact', 'ctrlact_map_file', $map_file);
+Irssi::settings_add_bool('ctrlact', 'ctrlact_debug', $debug);
+Irssi::settings_add_int('ctrlact', 'ctrlact_fallback_channel_threshold', $fallback_channel_threshold);
+Irssi::settings_add_int('ctrlact', 'ctrlact_fallback_query_threshold', $fallback_query_threshold);
+Irssi::settings_add_int('ctrlact', 'ctrlact_fallback_window_threshold', $fallback_window_threshold);
+Irssi::settings_add_bool('ctrlact', 'ctrlact_inhibit_beep', $inhibit_beep);
+
+sub sig_setup_changed {
+ $debug = Irssi::settings_get_bool('ctrlact_debug');
+ $map_file = Irssi::settings_get_str('ctrlact_map_file');
+ $fallback_channel_threshold = Irssi::settings_get_int('ctrlact_fallback_channel_threshold');
+ $fallback_query_threshold = Irssi::settings_get_int('ctrlact_fallback_query_threshold');
+ $fallback_window_threshold = Irssi::settings_get_int('ctrlact_fallback_window_threshold');
+ $inhibit_beep = Irssi::settings_get_bool('ctrlact_inhibit_beep');
+}
+Irssi::signal_add('setup changed', \&sig_setup_changed);
+Irssi::signal_add('setup reread', \&sig_setup_changed);
+sig_setup_changed();
+
+my $changed_since_last_save = 0;
+
+my @DATALEVEL_KEYWORDS = ('all', 'messages', 'hilights', 'none');
+
+### HELPERS ####################################################################
+
+my $_inhibit_debug_activity = 0;
+use constant DEBUGEVENTFORMAT => "%7s %7.7s %-22.22s %d %s %d โ†’ %-7s (%-8s โ† %s)";
+sub debugprint {
+ return unless $debug;
+ my ($msg, @rest) = @_;
+ $_inhibit_debug_activity = 1;
+ Irssi::print("ctrlact debug: ".$msg, MSGLEVEL_CRAP);
+ $_inhibit_debug_activity = 0;
+}
+
+sub error {
+ my ($msg) = @_;
+ Irssi::print("ctrlact: ERROR: $msg", MSGLEVEL_CLIENTERROR);
+}
+
+my @window_thresholds;
+my @channel_thresholds;
+my @query_thresholds;
+
+sub match {
+ my ($pat, $text) = @_;
+ my $npat = ($pat eq '*') ? '/.*/' : $pat;
+ if ($npat =~ m/^(\W)(.+)\1$/) {
+ my $re = qr/$2/;
+ $pat = $2 unless $pat eq '*';
+ return $pat if $text =~ /$re/i;
+ }
+ else {
+ return $pat if lc($text) eq lc($npat);
+ }
+ return 0;
+}
+
+sub to_data_level {
+ my ($kw) = @_;
+ return $1 if $kw =~ m/^(\d+)$/;
+ foreach my $i (2..4) {
+ my $matcher = qr/^$DATALEVEL_KEYWORDS[5-$i]$/;
+ return 6-$i if $kw =~ m/$matcher/i;
+ }
+ return 1;
+}
+
+sub from_data_level {
+ my ($dl) = @_;
+ croak "Invalid numeric data level: $dl" unless $dl =~ m/^([1-4])$/;
+ return $DATALEVEL_KEYWORDS[$dl-1];
+}
+
+sub walk_match_array {
+ my ($name, $net, $type, @arr) = @_;
+ foreach my $quadruplet (@arr) {
+ my $netmatch = $net eq '*' ? '(ignored)'
+ : 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:%s name:%s',
+ $quadruplet->[3], $netmatch, $match);
+ return ($result, $tresult, $match)
+ }
+ return -1;
+}
+
+sub get_mappings_table {
+ my (@arr) = @_;
+ my @ret = ();
+ for (my $i = 0; $i < @arr; $i++) {
+ push @ret, sprintf("%4d: %-10s %-40s %-10s (line: %3d)",
+ $i, $arr[$i]->[0], $arr[$i]->[1], $arr[$i]->[2], $arr[$i]->[3]);
+ }
+ return join("\n", @ret);
+}
+
+sub get_specific_threshold {
+ my ($type, $name, $net) = @_;
+ $type = lc($type);
+ if ($type eq 'window') {
+ return walk_match_array($name, $net, $type, @window_thresholds);
+ }
+ elsif ($type eq 'channel') {
+ return walk_match_array($name, $net, $type, @channel_thresholds);
+ }
+ elsif ($type eq 'query') {
+ return walk_match_array($name, $net, $type, @query_thresholds);
+ }
+ else {
+ croak "ctrlact: can't look up threshold for type: $type";
+ }
+}
+
+sub get_item_threshold {
+ 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]');
+ }
+ else {
+ return ($fallback_query_threshold, from_data_level($fallback_query_threshold), '[default]');
+ }
+}
+
+sub get_win_threshold {
+ my ($name, $net) = @_;
+ my ($ret, $tret, $match) = get_specific_threshold('window', $name, $net);
+ if ($ret > 0) {
+ return ($ret, $tret, $match);
+ }
+ else {
+ return ($fallback_window_threshold, from_data_level($fallback_window_threshold), '[default]');
+ }
+}
+
+sub print_levels_for_all {
+ my ($type, @arr) = @_;
+ Irssi::print("ctrlact: $type mappings:");
+ for (my $i = 0; $i < @arr; $i++) {
+ my $name = $arr[$i]->{'name'};
+ 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'};
+ Irssi::print(sprintf("%4d: %-40.40s โ†’ %d (%-8s) match %s", $c, $name, $t, $tt, $match), MSGLEVEL_CRAP);
+ }
+}
+
+### HILIGHT SIGNAL HANDLERS ####################################################
+
+my $_inhibit_beep = 0;
+my $_inhibit_window = 0;
+
+sub maybe_inhibit_witem_hilight {
+ my ($witem, $oldlevel) = @_;
+ return unless $witem;
+ $oldlevel = 0 unless $oldlevel;
+ my $newlevel = $witem->{'data_level'};
+ return if ($newlevel <= $oldlevel);
+
+ $_inhibit_window = 0;
+ $_inhibit_beep = 0;
+ my $wichattype = $witem->{'chat_type'};
+ my $witype = $witem->{'type'};
+ my $winame = $witem->{'name'};
+ 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), $witag, $winame, $newlevel,
+ $inhibit ? ('<',$th,'inhibit'):('โ‰ฅ',$th,'pass'),
+ $tth, $match));
+ if ($inhibit) {
+ Irssi::signal_stop();
+ # the rhval comes from config, so if the user doesn't want the
+ # bell inhibited, this is effectively a noop.
+ $_inhibit_beep = $inhibit_beep;
+ $_inhibit_window = $witem->window();
+ }
+}
+Irssi::signal_add_first('window item hilight', \&maybe_inhibit_witem_hilight);
+
+sub inhibit_win_hilight {
+ my ($win) = @_;
+ Irssi::signal_stop();
+ Irssi::signal_emit('window dehilight', $win);
+}
+
+sub maybe_inhibit_win_hilight {
+ my ($win, $oldlevel) = @_;
+ return unless $win;
+ if ($_inhibit_debug_activity) {
+ inhibit_win_hilight($win);
+ }
+ elsif ($_inhibit_window && $win->{'refnum'} == $_inhibit_window->{'refnum'}) {
+ inhibit_win_hilight($win);
+ }
+ else {
+ $oldlevel = 0 unless $oldlevel;
+ my $newlevel = $win->{'data_level'};
+ return if ($newlevel <= $oldlevel);
+
+ my $wname = $win->{'name'};
+ my $wtag = $win->{'server'}->{'tag'} // '';
+ my ($th, $tth, $match) = get_win_threshold($wname, $wtag);
+ my $inhibit = $newlevel > 0 && $newlevel < $th;
+ debugprint(sprintf(DEBUGEVENTFORMAT, 'window', $wtag,
+ $wname?$wname:'(unnamed)', $newlevel,
+ $inhibit ? ('<',$th,'inhibit'):('โ‰ฅ',$th,'pass'),
+ $tth, $match));
+ inhibit_win_hilight($win) if $inhibit;
+ }
+}
+Irssi::signal_add_first('window hilight', \&maybe_inhibit_win_hilight);
+
+sub maybe_inhibit_beep {
+ Irssi::signal_stop() if $_inhibit_beep;
+}
+Irssi::signal_add_first('beep', \&maybe_inhibit_beep);
+
+### SAVING AND LOADING #########################################################
+
+sub get_mappings_fh {
+ my ($filename) = @_;
+ my $fh;
+ if (-e $filename) {
+ open($fh, '<', $filename) || croak "Cannot open mappings file: $!";
+ }
+ else {
+ open($fh, '+>', $filename) || croak "Cannot create mappings file: $!";
+
+ my $ftw = from_data_level($fallback_window_threshold);
+ my $ftc = from_data_level($fallback_channel_threshold);
+ my $ftq = from_data_level($fallback_query_threshold);
+ print $fh <<"EOF";
+# 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 server name min.level
+
+
+# EXAMPLES
+#
+### only indicate activity in the status window if messages were displayed:
+# window * (status) messages
+#
+### never ever indicate activity for any item bound to this window:
+# window * oubliette none
+#
+### 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
+#
+### otherwise ignore everything in channels, unless a hilight is triggered:
+# channel * * hilights
+#
+### make somebot only get your attention if they hilight you:
+# query efnet somebot hilights
+#
+### otherwise we want to see everything in queries:
+# query * * all
+
+# DEFAULTS:
+# window * * $ftw
+# channel * * $ftc
+# query * * $ftq
+
+# vim:noet:tw=0:ts=16
+EOF
+ Irssi::print("ctrlact: created new/empty mappings file: $filename");
+ seek($fh, 0, 0) || croak "Cannot rewind $filename.";
+ }
+ return $fh;
+}
+
+sub load_mappings {
+ my ($filename) = @_;
+ @window_thresholds = @channel_thresholds = @query_thresholds = ();
+ my $fh = get_mappings_fh($filename);
+ my $firstline = <$fh> || croak "Cannot read from $filename.";;
+ my $version;
+ if ($firstline =~ m/^#+\s+ctrlact mappings file \(version: *([\d.]+)\)/) {
+ $version = $1;
+ }
+ else {
+ croak "First line of $filename is not a ctrlact header.";
+ }
+
+ my $nrcols = 4;
+ if ($version eq $VERSION) {
+ # current version, i.e. no special handling is required. If
+ # previous versions require special handling, then massage the
+ # data or do whatever is required in the following
+ # elsif-clauses:
+ }
+ elsif ($version eq "1.0") {
+ $nrcols = 3;
+ }
+ my $linesplitter = '^\s*'.join('\s+', ('(\S+)') x $nrcols).'\s*$';
+ my $l = 1;
+ while (<$fh>) {
+ $l++;
+ next if m/^\s*(?:#|$)/;
+ 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) || croak "Cannot close mappings file: $!";
+}
+
+sub cmd_load {
+ Irssi::print("ctrlact: loading mappings from $map_file");
+ load_mappings($map_file);
+ $changed_since_last_save = 0;
+}
+
+sub cmd_save {
+ error("saving not yet implemented");
+ return 1;
+}
+
+sub cmd_list {
+ Irssi::print("ctrlact: window mappings");
+ Irssi::print(get_mappings_table(@window_thresholds), MSGLEVEL_CRAP);
+ Irssi::print("ctrlact: channel mappings");
+ Irssi::print(get_mappings_table(@channel_thresholds), MSGLEVEL_CRAP);
+ Irssi::print("ctrlact: query mappings");
+ Irssi::print(get_mappings_table(@query_thresholds), MSGLEVEL_CRAP);
+}
+
+sub parse_args {
+ my (@args) = @_;
+ my @words = ();
+ my $typewasset = 0;
+ my $tag;
+ my $max = 0;
+ my $type = undef;
+ foreach my $arg (@args) {
+ if ($arg =~ m/^-(windows?|channels?|quer(?:ys?|ies))/) {
+ if ($typewasset) {
+ error("can't specify -$1 after -$type");
+ return 1;
+ }
+ $type = 'window' if $1 =~ m/^w/;
+ $type = 'channel' if $1 =~ m/^c/;
+ $type = 'query' if $1 =~ m/^q/;
+ $typewasset = 1
+ }
+ elsif ($arg =~ m/-(\S+)/) {
+ $tag = $1;
+ }
+ else {
+ push @words, $arg;
+ $max = length $arg if length $arg > $max;
+ }
+ }
+ return ($type, $tag, $max, @words);
+}
+
+sub cmd_query {
+ my ($data, $server, $item) = @_;
+ my @args = shellwords($data);
+ 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, $tag);
+ printf CLIENTCRAP "ctrlact $type map: %s %*s โ†’ %d (%s, match:%s)", $tag, $max, $word, $t, $tt, $match;
+ }
+}
+
+sub cmd_show {
+ my ($data, $server, $item) = @_;
+ my @args = shellwords($data);
+ my ($type, $max, @words) = parse_args(@args);
+ $type = $type // 'all';
+
+ if ($type eq 'channel' or $type eq 'all') {
+ print_levels_for_all('channel', Irssi::channels());
+ }
+ if ($type eq 'query' or $type eq 'all') {
+ print_levels_for_all('query', Irssi::queries());
+ }
+ if ($type eq 'window' or $type eq 'all') {
+ print_levels_for_all('window', Irssi::windows());
+ }
+}
+
+sub autosave {
+ cmd_save() if ($changed_since_last_save);
+}
+
+sub UNLOAD {
+ autosave();
+}
+
+Irssi::signal_add('setup saved', \&autosave);
+Irssi::signal_add('setup reread', \&cmd_load);
+
+Irssi::command_bind('ctrlact help',\&cmd_help);
+Irssi::command_bind('ctrlact reload',\&cmd_load);
+Irssi::command_bind('ctrlact load',\&cmd_load);
+Irssi::command_bind('ctrlact save',\&cmd_save);
+Irssi::command_bind('ctrlact list',\&cmd_list);
+Irssi::command_bind('ctrlact query',\&cmd_query);
+Irssi::command_bind('ctrlact show',\&cmd_show);
+
+Irssi::command_bind('ctrlact' => sub {
+ my ( $data, $server, $item ) = @_;
+ $data =~ s/\s+$//g;
+ if ($data) {
+ Irssi::command_runsub('ctrlact', $data, $server, $item);
+ }
+ else {
+ cmd_help();
+ }
+ }
+);
+Irssi::command_bind('help', sub {
+ $_[0] =~ s/\s+$//g;
+ return unless $_[0] eq 'ctrlact';
+ cmd_help();
+ Irssi::signal_stop();
+ }
+);
+
+cmd_load();
diff --git a/scripts/dccself.pl b/scripts/dccself.pl
index e944133..1a6ccea 100644
--- a/scripts/dccself.pl
+++ b/scripts/dccself.pl
@@ -1,7 +1,8 @@
use strict;
-use vars qw/%IRSSI/;
+use vars qw/%IRSSI $VERSION/;
use Irssi qw(command_bind active_server);
+$VERSION= "0.1";
%IRSSI = (
authors => "David Leadbeater",
contact => "dgl\@dgl.cx",
diff --git a/scripts/desktop-notify.pl b/scripts/desktop-notify.pl
index da25b8c..c41a9f4 100644
--- a/scripts/desktop-notify.pl
+++ b/scripts/desktop-notify.pl
@@ -24,8 +24,9 @@ use strict;
use Irssi;
use HTML::Entities;
use Glib::Object::Introspection; # Ignore 'late INIT' warning message if autoloading
+use Encode;
-our $VERSION = '1.0.0';
+our $VERSION = '1.0.1';
our %IRSSI = (
authors => 'Felipe F. Tonello',
contact => 'eu@felipetonello.com',
@@ -38,6 +39,7 @@ our %IRSSI = (
# List of standard icons can be found here:
# http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html#names
my $notify_icon;
+my $term_charset;
my $help = '
/set notify_icon <icon-name>
@@ -60,6 +62,7 @@ sub UNLOAD {
sub setup_changed {
$notify_icon = Irssi::settings_get_str('notify_icon');
+ $term_charset = Irssi::settings_get_str('term_charset');
}
sub priv_msg {
@@ -71,9 +74,9 @@ sub priv_msg {
return;
}
- my $msg = HTML::Entities::encode_entities(Irssi::strip_codes($msg));
+ my $msg = HTML::Entities::encode_entities(Irssi::strip_codes($msg), "\<>&'");
my $network = $server->{tag};
- my $noti = Notify::Notification->new($nick . '@' . $network, $msg, $notify_icon);
+ my $noti = Notify::Notification->new($nick . '@' . $network, decode($term_charset, $msg), $notify_icon);
$noti->show();
}
@@ -94,8 +97,8 @@ sub hilight {
}
my $network = $server->{tag};
- my $msg = HTML::Entities::encode_entities($stripped);
- my $noti = Notify::Notification->new($dest->{target} . '@' . $network, $msg, $notify_icon);
+ my $msg = HTML::Entities::encode_entities($stripped, "\'<>&");
+ my $noti = Notify::Notification->new($dest->{target} . '@' . $network, decode($term_charset, $msg), $notify_icon);
$noti->show();
}
diff --git a/scripts/go.pl b/scripts/go.pl
index b656a0f..0b0a2a2 100644
--- a/scripts/go.pl
+++ b/scripts/go.pl
@@ -7,8 +7,29 @@ use Irssi::Irc;
# /script load go.pl
# If you are in #irssi you can type /go #irssi or /go irssi or even /go ir ...
# also try /go ir<tab> and /go <tab> (that's two spaces)
+#
+# The following settings exist:
+#
+# /SET go_match_case_sensitive [ON|OFF]
+# Match window/item names sensitively (the default). Turning this off
+# means e.g. "/go foo" would jump to a window named "Foobar", too.
+#
+# /SET go_match_anchored [ON|OFF]
+# Match window/names only at the start of the word (the default). Turning
+# this off will mean that strings can match anywhere in the window/names.
+# The leading '#' of channel names is optional either way.
+#
+# /SET go_complete_case_sensitive [ON|OFF]
+# When using tab-completion, match case-insensitively (the default).
+# Turning this on means that "/go foo<tab>" will *not* suggest "Foobar".
+#
+# /SET go_complete_anchored [ON|OFF]
+# Match window/names only at the start of the word. The default is 'off',
+# which causes completion to match anywhere in the window/names during
+# completion. The leading '#' of channel names is optional either way.
+#
-$VERSION = '1.01';
+$VERSION = '1.1';
%IRSSI = (
authors => 'nohar',
@@ -16,9 +37,17 @@ $VERSION = '1.01';
name => 'go to window',
description => 'Implements /go command that activates a window given a name/partial name. It features a nice completion.',
license => 'GPLv2 or later',
- changed => '2014-10-19'
+ changed => '2017-02-02'
);
+sub _make_regexp {
+ my ($name, $ci, $aw) = @_;
+ my $re = "\Q${name}\E";
+ $re = "(?i:$re)" unless $ci;
+ $re = "^#?$re" if $aw;
+ return $re;
+}
+
sub signal_complete_go {
my ($complist, $window, $word, $linestart, $want_space) = @_;
my $channel = $window->get_active_name();
@@ -26,11 +55,14 @@ sub signal_complete_go {
return unless ($linestart =~ /^\Q${k}\Ego\b/i);
+ my $re = _make_regexp($word,
+ Irssi::settings_get_bool('go_complete_case_sensitive'),
+ Irssi::settings_get_bool('go_complete_anchored'));
@$complist = ();
foreach my $w (Irssi::windows) {
my $name = $w->get_active_name();
if ($word ne "") {
- if ($name =~ /\Q${word}\E/i) {
+ if ($name =~ $re) {
push(@$complist, $name)
}
} else {
@@ -45,9 +77,13 @@ sub cmd_go
my($chan,$server,$witem) = @_;
$chan =~ s/ *//g;
+ my $re = _make_regexp($chan,
+ Irssi::settings_get_bool('go_match_case_sensitive'),
+ Irssi::settings_get_bool('go_match_anchored'));
+
foreach my $w (Irssi::windows) {
my $name = $w->get_active_name();
- if ($name =~ /^#?\Q${chan}\E/) {
+ if ($name =~ $re) {
$w->set_active();
return;
}
@@ -56,4 +92,14 @@ sub cmd_go
Irssi::command_bind("go", "cmd_go");
Irssi::signal_add_first('complete word', 'signal_complete_go');
+Irssi::settings_add_bool('go', 'go_match_case_sensitive', 1);
+Irssi::settings_add_bool('go', 'go_complete_case_sensitive', 0);
+Irssi::settings_add_bool('go', 'go_match_anchored', 1);
+Irssi::settings_add_bool('go', 'go_complete_anchored', 0);
+# Changelog
+#
+# 2017-02-02 1.1 martin f. krafft <madduck@madduck.net>
+# - made case-sensitivity of match configurable
+# - made anchoring of search strings configurable
+#
diff --git a/scripts/hilightwin.pl b/scripts/hilightwin.pl
index 7d70317..2e407fa 100644
--- a/scripts/hilightwin.pl
+++ b/scripts/hilightwin.pl
@@ -11,7 +11,7 @@ use Irssi;
use POSIX;
use vars qw($VERSION %IRSSI);
-$VERSION = "0.04";
+$VERSION = "0.05";
%IRSSI = (
authors => "Timo \'cras\' Sirainen, Mark \'znx\' Sangster",
contact => "tss\@iki.fi, znxster\@gmail.com",
@@ -22,6 +22,26 @@ $VERSION = "0.04";
changed => "Sun May 25 18:59:57 BST 2008"
);
+sub is_ignored {
+ my ($dest) = @_;
+
+ my @ignore = split(' ', Irssi::settings_get_str('hilightwin_ignore_targets'));
+ return 0 if (!@ignore);
+
+ my %targets = map { $_ => 1 } @ignore;
+
+ return 1 if exists($targets{"*"});
+ return 1 if exists($targets{$dest->{target}});
+
+ if ($dest->{server}) {
+ my $tag = $dest->{server}->{tag};
+ return 1 if exists($targets{$tag . "/*"});
+ return 1 if exists($targets{$tag . "/" . $dest->{target}});
+ }
+
+ return 0;
+}
+
sub sig_printtext {
my ($dest, $text, $stripped) = @_;
@@ -33,7 +53,8 @@ sub sig_printtext {
if(
($dest->{level} & ($opt)) &&
- ($dest->{level} & MSGLEVEL_NOHILIGHT) == 0
+ ($dest->{level} & MSGLEVEL_NOHILIGHT) == 0 &&
+ (!is_ignored($dest))
) {
my $window = Irssi::window_find_name('hilight');
@@ -49,6 +70,7 @@ my $window = Irssi::window_find_name('hilight');
Irssi::print("Create a window named 'hilight'") if (!$window);
Irssi::settings_add_bool('hilightwin','hilightwin_showprivmsg',1);
+Irssi::settings_add_str('hilightwin', 'hilightwin_ignore_targets', '');
Irssi::signal_add('print text', 'sig_printtext');
diff --git a/scripts/hilite_url.pl b/scripts/hilite_url.pl
new file mode 100644
index 0000000..11c4b0d
--- /dev/null
+++ b/scripts/hilite_url.pl
@@ -0,0 +1,28 @@
+# Simple script to highlight links in public messages
+
+use strict;
+use vars qw($VERSION %IRSSI);
+
+# Dev. info ^_^
+$VERSION = "0.1";
+%IRSSI = (
+ authors => "Stefan Heinemann",
+ contact => "stefan.heinemann\@codedump.ch",
+ name => "hilite url",
+ description => "Simple script that highlights URL",
+ license => "GPL",
+ url => "http://senseless.codedump.ch",
+);
+
+sub hilite_url {
+ my ($server, $data, $nick, $mask, $target) = @_;
+
+ # Add Colours
+ $data =~ s/(https?:\/\/[^\s]+)/\e[4;34m\1\e[00m/g;
+
+ # Let it flow
+ Irssi::signal_continue($server, $data, $nick, $mask, $target);
+}
+
+# Hook me up
+Irssi::signal_add('message public', 'hilite_url');
diff --git a/scripts/ident.pl b/scripts/ident.pl
new file mode 100644
index 0000000..a4854f2
--- /dev/null
+++ b/scripts/ident.pl
@@ -0,0 +1,68 @@
+#!/usr/bin/perl -w
+
+use strict;
+use Irssi;
+use POSIX;
+
+use vars qw($VERSION %IRSSI);
+
+$VERSION = "1.0";
+%IRSSI = (
+ authors => 'Isaac Good',
+ contact => "irssi\@isaacgood.com; irc.freenode.net/yitz",
+ name => 'ident',
+ description => 'Ident to NickServs',
+ name => "ident",
+ description => "Automatically IDENTIFY when prompted",
+ license => 'MIT',
+);
+
+
+my %pw;
+
+
+sub LoadPasswords {
+ # Load the passwords from file.
+ delete @pw{keys %pw};
+ my $filename = Irssi::get_irssi_dir() . '/passwords';
+ my $FH;
+ unless(open $FH, "<", $filename)
+ {
+ print "Can not open $filename";
+ return 0;
+ }
+ while (my $line = <$FH>)
+ {
+ chomp $line;
+ next unless ($line);
+ my ($tag, $password) = split(/ */, $line, 2);
+ next unless ($tag and $password);
+ $pw{$tag} = $password;
+ }
+ return 1;
+}
+
+
+sub notice {
+ my ($server, $data, $nick, $host) = @_;
+ my ($channel, $msg) = split(/ :/, $data, 2);
+ my $l = 0;
+
+ # Test the notice. Must be from nickserv and be asking you to identify.
+ return undef unless (lc($nick) eq 'nickserv');
+ return undef unless (lc($msg) =~ /msg nickserv identify/);
+ # Check it's a direct message and we have a password for this network.
+ return undef unless (lc($channel) eq lc($server->{'nick'}));
+ return undef unless ($pw{$server->{'chatnet'}});
+
+ my $pw = $pw{$server->{'chatnet'}};
+ # Use the /quote nickserv approach to reduce chance of leaking the password to a bad actor, ie someone pretending to be nickserv.
+ $server->command("^quote nickserv identify $pw");
+
+ return undef;
+}
+
+
+if (LoadPasswords()) {
+ Irssi::signal_add('event notice', \&notice);
+}
diff --git a/scripts/invitejoin.pl b/scripts/invitejoin.pl
index c69ed01..d3b5871 100644
--- a/scripts/invitejoin.pl
+++ b/scripts/invitejoin.pl
@@ -24,7 +24,7 @@ use strict;
use Irssi;
use vars qw($VERSION %IRSSI);
-$VERSION = "0.01";
+$VERSION = '0.02';
%IRSSI = (
authors => 'Geert Hauwaerts',
@@ -32,37 +32,254 @@ $VERSION = "0.01";
name => 'invitejoin.pl',
description => 'This script will join a channel if somebody invites you to it.',
license => 'Public Domain',
- url => 'http://irssi.hauwaerts.be/invitejoin.pl',
- changed => 'Sun Apr 11 12:38:18 2004',
+ url => 'https://github.com/irssi/scripts.irssi.org/blob/master/scripts/invitejoin.pl',
+ changed => 'Di 17. Jan 19:32:45 CET 2017',
);
-## Comments and remarks.
-#
-# This script uses settings.
-# Use /SET to change the value or /TOGGLE to switch it on or off.
-#
-# Setting: invitejoin
-# Description: If this setting is turned on, you will join the channel
-# when invite to.
-#
-##
+my $help = <<EOF;
+
+/SET invitejoin 0|1
+/TOGGLE invitejoin
+ Description: If this setting is turned on, you will join the channel
+ when invited to.
+
+Default is to follow every invite, you can specify a list of allowed nicks.
+
+/INVITEJOIN [addnick <ircnet> <nick>]
+ [delnick <ircnet> <nick>]
+ [listnick]
+ [help]
+
+addnick: Add a new nickname on the given net as allowed autoinvite source.
+delnick: Delete a nickname from the allowed list.
+listnick: Display the contents of the allowed nickname list.
+help: Display this useful little helptext.
+
+Examples: (all on one line)
+/INVITEJOIN addnick Freenode ChanServ
+
+Note: This script doesn't allow wildcards
+EOF
+my @allowed_nicks = ();
+my $allowed_nicks_file = "invitejoin.nicks";
+
+my $irssidir = Irssi::get_irssi_dir();
Irssi::theme_register([
+ 'invitejoin_usage', '%R>>%n %_Invitejoin:%_ Insufficient parameters: Use "%_/INVITEJOIN help%_" for further instructions.',
+ 'invitejoin_help', '$0',
'invitejoin_loaded', '%R>>%n %_Scriptinfo:%_ Loaded $0 version $1 by $2.',
- 'invitejoin_invited', '%R>>%n %_Invitejoin:%_ Joined $1 (Invited by $0).'
+ 'invitejoin_invited', '%R>>%n %_Invitejoin:%_ Joined $1 (Invited by $0).',
+ 'invitejoin_usage_add_nick', '%R>>%n %_Invitejoin:%_ Insufficient parameters: Usage "%_/INVITEJOIN addnick ircnet ChanServ%_".',
+ 'invitejoin_no_net', '%R>>%n %_Invitejoin:%_ Unknown Irssi ircnet %_$0%_.',
+ 'saved_nick', '%R>>%n %_Invitejoin:%_ Added allowed nick "%_$1%_" on %_$0%_.',
+ 'nick_already_present', '%R>>%n %_Invitejoin:%_ Nick already present.',
+ 'invitejoin_delusage', '%R>>%n %_Invitejoin:%_ Insufficient parameters: Usage "%_/INVITEJOIN delnick ircnet nick%_".',
+ 'invitejoin_delled', '%R>>%n %_Invitejoin:%_ Deleted %_$1%_ on %_$0%_ from allowed list.',
+ 'invitejoin_nfound', '%R>>%n %_Invitejoin:%_ The nick %_$1%_ on %_$0%_ could not be found.',
+ 'allowed_nicks_info', '%_Ircnet Nick%_',
+ 'allowed_nicks_empty', '%R>>%n %_Invitejoin:%_ Your allowed nick list is empty. All invites will be followed.',
+ 'allowed_nicks_print', '$[18]0 $1',
+ 'invite_denied', '%R>>%n %_Invitejoin:%_ Invite from nick %_$1%_ on %_$0%_ to %_$2%_ not followed because it is not in the allowed list.',
]);
+sub load_allowed_nicks {
+ my ($file) = @_;
+
+ @allowed_nicks = load_file($file, sub {
+ my $new_allowed = new_allowed_nick(@_);
+
+ return undef if ($new_allowed->{net} eq '' || $new_allowed->{nick} eq '');
+ return $new_allowed;
+ });
+}
+
+sub save_allowed_nicks {
+ my ($file) = @_;
+ save_file($file, \@allowed_nicks, \&allowed_nick_to_list);
+}
+
+sub allowed_nick_to_list {
+ my $allowed_nick = shift;
+
+ return (
+ $allowed_nick->{net},
+ $allowed_nick->{nick}
+ );
+}
+
+sub new_allowed_nick {
+ return {
+ net => shift,
+ nick => shift
+ };
+}
+
+# file: filename to be read
+# parse_line_fn: receives array of entries of a single line as input, should
+# return parsed data object or undef in the data is incomplete
+# returns: parsed data array
+sub load_file {
+ my ($file, $parse_line_fn) = @_;
+ my @parsed_data = ();
+
+ if (-e $file) {
+ open(my $fh, "<", $file);
+ local $/ = "\n";
+
+ while (<$fh>) {
+ chomp;
+ my $data = $parse_line_fn->(split("\t"));
+ push(@parsed_data, $data) if $data;
+ }
+
+ close($fh);
+ }
+
+ return @parsed_data;
+}
+
+# file: filename to be written, is created accessable only by the user
+# data_ref: array ref of data entries
+# serialize_fn: receives a data reference and should return an array or tuples
+# for that data that will be serialized into one line
+sub save_file {
+ my ($file, $data_ref, $serialize_fn) = @_;
+
+ create_private_file($file) unless -e $file;
+
+ open(my $fh, ">", $file) or die "Can't create $file. Reason: $!";
+
+ for my $data (@$data_ref) {
+ print($fh join("\t", $serialize_fn->($data)), "\n");
+ }
+
+ close($fh);
+}
+
+sub create_private_file {
+ my ($file) = @_;
+ my $umask = umask 0077; # save old umask
+ open(my $fh, ">", $file) or die "Can't create $file. Reason: $!";
+ close($fh);
+ umask $umask;
+}
+
+sub add_allowed_nick {
+ my ($network, $nick) = split(" ", $_[0], 2);
+ my ($correct_net);
+
+ if ($network eq '' || $nick eq '') {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'invitejoin_usage_add_nick');
+ return;
+ }
+
+ if ($network) {
+ my ($ircnet) = Irssi::chatnet_find($network);
+ if (!$ircnet) {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'invitejoin_no_net', $network);
+ return;
+ } else {
+ $correct_net = 1;
+ }
+ }
+
+ if ($correct_net && $nick) {
+ if (is_nick_in_list($network, $nick)) {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nick_already_present');
+ return;
+ }
+
+ push(@allowed_nicks, new_allowed_nick($network, $nick));
+ save_allowed_nicks("$irssidir/$allowed_nicks_file");
+
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'saved_nick', $network, $nick);
+ }
+}
+
+sub del_allowed_nick {
+ my ($ircnet, $nick) = split(" ", $_[0], 2);
+
+ if ($ircnet eq '' || $nick eq '') {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'invitejoin_delusage');
+ return;
+ }
+
+ my $size_before = scalar(@allowed_nicks);
+ @allowed_nicks = grep { ! ($_->{net} eq $ircnet && $_->{nick} eq $nick) } @allowed_nicks;
+ my $size_after = scalar(@allowed_nicks);
+
+ if ($size_after != $size_before) {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'invitejoin_delled', $ircnet, $nick);
+ save_allowed_nicks("$irssidir/$allowed_nicks_file");
+ } else {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'invitejoin_nfound', $ircnet, $nick);
+ }
+
+ if ($size_after == 0) {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'allowed_nicks_empty');
+ }
+}
+
+sub list_allowed_nicks {
+ if (@allowed_nicks == 0) {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'allowed_nicks_empty');
+ } else {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'allowed_nicks_info');
+
+ for my $allowed (@allowed_nicks) {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'allowed_nicks_print', $allowed->{net}, $allowed->{nick});
+ }
+ }
+}
+
+sub invitejoin_runsub {
+ my ($data, $server, $item) = @_;
+ $data =~ s/\s+$//g;
+
+ if ($data) {
+ Irssi::command_runsub('invitejoin', $data, $server, $item);
+ } else {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'invitejoin_usage');
+ }
+}
+
+sub is_nick_in_list {
+ my ($net, $nick) = @_;
+
+ return (grep {
+ $_->{net} eq $net &&
+ $_->{nick} eq $nick
+ } @allowed_nicks) > 0;
+}
+
+sub is_allowed_nick {
+ my ($net, $nick) = @_;
+
+ # If no allowed nicks are specified (initial configuration) accept
+ # all invite requests.
+ # # (This mimics previous behavior of this script
+ # before there was an allowed list)
+ return 1 if @allowed_nicks == 0;
+
+ return is_nick_in_list($net, $nick);
+}
+
sub invitejoin {
-
my ($server, $channel, $nick, $address) = @_;
my $invitejoin = Irssi::settings_get_bool('invitejoin');
if ($invitejoin) {
- $server->command("join $channel");
-
- Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'invitejoin_invited', $nick, $channel);
- Irssi::signal_stop();
+ if (is_allowed_nick($server->{tag}, $nick)) {
+ $server->command("join $channel");
+
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'invitejoin_invited', $nick, $channel);
+ Irssi::signal_stop();
+ }
+ else {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'invite_denied', $server->{tag}, $nick, $channel);
+ }
}
}
@@ -70,4 +287,12 @@ Irssi::signal_add('message invite', 'invitejoin');
Irssi::settings_add_bool('invitejoin', 'invitejoin' => 1);
+load_allowed_nicks("$irssidir/$allowed_nicks_file");
+
+Irssi::command_bind('invitejoin', 'invitejoin_runsub');
+Irssi::command_bind('invitejoin addnick', 'add_allowed_nick');
+Irssi::command_bind('invitejoin delnick', 'del_allowed_nick');
+Irssi::command_bind('invitejoin listnick', 'list_allowed_nicks');
+Irssi::command_bind('invitejoin help' => sub { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'invitejoin_help', $help) });
+
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'invitejoin_loaded', $IRSSI{name}, $VERSION, $IRSSI{authors});
diff --git a/scripts/listsort.pl b/scripts/listsort.pl
new file mode 100644
index 0000000..81b9ab9
--- /dev/null
+++ b/scripts/listsort.pl
@@ -0,0 +1,60 @@
+use strict;
+use warnings;
+use Irssi;
+use vars qw/$VERSION %IRSSI/;
+
+$VERSION = '0.1';
+%IRSSI = (
+ authors => 'Isaac Good',
+ name => 'listsort',
+ contact => 'irssi@isaacgood.com',
+ decsription => 'Sort the /list output by channel size',
+ license => 'BSD',
+ url => 'https://github.com/IsaacG/irssi-scripts',
+ created => '2013/02/23',
+);
+
+# Bindings. Start of channel list, end of list, list item.
+Irssi::signal_add_last('event 322', \&list_event);
+Irssi::signal_add_last('event 323', \&list_end);
+
+# Store the channel list between IRC messages
+my %list;
+
+# Store list info in the hash.
+sub list_event {
+ my ($server, $data, $server_name) = @_;
+ my ($meta, $more) = split (/ :/, $data, 2);
+ my ($nick, $name, $size) = split (/ /, $meta, 3);
+ $list{$name}{'size'} = $size;
+
+ my $modes = '';
+ $list{$name}{'desc'} = '';
+ if ($more =~ /^[^[]*\[([^]]*)\][^ ]* *([^ ].*)$/) {
+ $modes = $1;
+ $list{$name}{'desc'} = $2;
+ }
+
+ $modes =~ s/ +$//;
+ $list{$name}{'modes'} = $modes;
+}
+
+# Print out the whole list in sorted order.
+sub list_end {
+ for my $name (sort {$list{$a}{'size'} <=> $list{$b}{'size'}} keys %list) {
+ my $mode = $list{$name}{'modes'};
+ $mode = " ($mode)" if ($mode);
+ my $msg = sprintf (
+ "%d %s: %s%s",
+ $list{$name}{'size'},
+ $name,
+ $list{$name}{'desc'},
+ $mode
+ );
+
+ Irssi::print($msg, MSGLEVEL_CRAP);
+ }
+ # Drop the hash values; no point in holding them in memory.
+ %list = ();
+}
+
diff --git a/scripts/logcompress_perl.pl b/scripts/logcompress_perl.pl
index 062331e..d75755a 100644
--- a/scripts/logcompress_perl.pl
+++ b/scripts/logcompress_perl.pl
@@ -4,7 +4,7 @@ use Irssi;
use IO::Compress::Gzip qw(gzip $GzipError);
use vars qw($VERSION %IRSSI);
-$VERSION = "0.01";
+$VERSION = "0.02";
%IRSSI = (
authors => 'vague',
contact => 'vague!#irssi@fgreenode',
@@ -12,12 +12,13 @@ $VERSION = "0.01";
description => "compress logfiles then they're rotated, modified from original logcompress.pl to use perl modules instead",
license => "Public Domain",
url => "http://irssi.org/",
- changed => "2016-01-31T01:45+0100"
+ changed => "2017-01-07T12:00+0100"
);
sub sig_rotate {
my $input = $_[0]->{real_fname};
gzip $input => "$input.gz" or Irssi::print(MSGLEVEL_CLIENTERROR, "gzip failed: $GzipError\n");
+ unlink $input if -e "$input.gz";
}
Irssi::signal_add('log rotated', 'sig_rotate');
diff --git a/scripts/mh_sbuserinfo.pl b/scripts/mh_sbuserinfo.pl
index fde7ebc..c9ee211 100644
--- a/scripts/mh_sbuserinfo.pl
+++ b/scripts/mh_sbuserinfo.pl
@@ -1,8 +1,8 @@
##############################################################################
#
-# mh_sbuserinfo.pl v1.04 (20151225)
+# mh_sbuserinfo.pl v1.05 (20161106)
#
-# Copyright (c) 2015 Michael Hansen
+# Copyright (c) 2015, 2016 Michael Hansen
#
# Permission to use, copy, modify, and distribute this software
# for any purpose with or without fee is hereby granted, provided
@@ -25,23 +25,41 @@
# displays in the statusbar the number of users and the limit of the channel,
# with several settings for finetuning:
#
-# default settings: [Users: <users>(@<users_op>:+<users_voice>:<users_rest>)/<limit>(<limitusers>)]
+# default settings: [Users: <users>(*<users_oper>:@<users_op>:+<users_voice>:<users_rest>)/<limit>(<limitusers>)]
# "/<limit>(<limitusers>)" will only show when there is a limit set.
# "(<limitusers>)" shows the difference between the limit and current
# users (this can be negative if the limit is lower than users)
#
+# setting mh_sbuserinfo_format_group_begin (default '(') and
+# setting mh_sbuserinfo_format_group_end' (default ')'); change the characters grouping
+# details
+#
+# setting mh_sbuserinfo_format_sep (default ':'): change the : seperator to another string
+#
+# setting mh_sbuserinfo_format_div (default '/'): change the / divider to another string
+#
# setting mh_sbuserinfo_show_prefix (default 'Users: '): set/unset the prefix
# in the window item
#
# setting mh_sbuserinfo_show_details (default ON): enable/disable showing a
-# detailed breakout of users into ops, halfops, voice and normal
+# detailed breakout of users into opers, ops, halfops, voice and normal
#
# setting mh_sbuserinfo_show_details_mode (default ON): enable/disable
-# prefixing ops, halfops and voice with @%+ when details are enabled
+# prefixing opers, ops, halfops and voice with *@%+ when details are enabled
+#
+# setting mh_sbuserinfo_format_mode_oper (default '*'),
+# setting mh_sbuserinfo_format_mode_op (default '@'),
+# setting mh_sbuserinfo_format_mode_ho (default '%%'),
+# setting mh_sbuserinfo_format_mode_vo (default '+') and
+# setting mh_sbuserinfo_format_mode_other (default ''): change the mode prefix
+# for each of oper, op, halfdop, voice and others
#
# setting mh_sbuserinfo_show_details_halfop (default OFF): enable/disable
# showing halfops when details are enabled
#
+# setting mh_sbuserinfo_show_details_oper (default ON): enable/disable
+# showing opers when details are enabled
+#
# setting mh_sbuserinfo_show_details_difference (default ON): enable/disable
# showing the "(<limitusers>)"
#
@@ -51,9 +69,13 @@
# setting mh_sbuserinfo_show_warning_limit (default ON): change the colour
# of "<limit>" if channel is above, at or close to the limited amount of users
#
-# setting mh_sbuserinfo_show_warning_limit_percent (default 95): number in
+# setting mh_sbuserinfo_show_warning_limit_percent (default 0): number in
# percent (0-100) of users relative to the limit before a limit warning is
-# triggered
+# triggered (if set to 0 see mh_sbuserinfo_show_warning_limit_difference)
+#
+# setting mh_sbuserinfo_show_warning_limit_difference (default 5): when
+# mh_sbuserinfo_show_warning_limit_percent is 0, use this absolute value
+# as the difference warning trigger instead of percentage
#
# setting mh_sbuserinfo_warning_format (default '%Y'): the colour used for
# warnings. see http://www.irssi.org/documentation/formats
@@ -63,6 +85,15 @@
# see '/help statusbar' for more details and do not forget to '/save'
#
# history:
+#
+# v1.05 (20161106)
+# added setting _show_details_oper and supporting code
+# added setting _format_sep and supportingf code
+# added setting _format_div and supporting code
+# added setting _group_begin and _format_group_end and supporting code
+# added setting _format_mode_oper, _format_mode_op, _format_mode_ho, _format_mode_vo and _format_mode_other, and supporting code
+# added settting _show_warning_limit_difference and supporting code (changing _show_warning_limit_percent behavior)
+# changed default of _show_warning_limit_percent from 95 to 0
# v1.04 (20151225)
# added setting _show_details_difference and supporting code
# changed _show_warning_limit_percent default from 90 to 95
@@ -96,7 +127,7 @@ use strict;
use Irssi 20100403;
use Irssi::TextUI;
-our $VERSION = '1.04';
+our $VERSION = '1.05';
our %IRSSI =
(
'name' => 'mh_sbuserinfo',
@@ -105,7 +136,7 @@ our %IRSSI =
'authors' => 'Michael Hansen',
'contact' => 'mh on IRCnet #help',
'url' => 'http://scripts.irssi.org / https://github.com/mh-source/irssi-scripts',
- 'changed' => 'Fri Dec 25 17:14:34 CET 2015',
+ 'changed' => 'Sun Nov 6 20:37:05 CET 2016',
);
##############################################################################
@@ -183,6 +214,7 @@ sub statusbar_userinfo
my $users_op = 0;
my $users_ho = 0;
my $users_vo = 0;
+ my $users_oper = 0;
my $warning_format = Irssi::settings_get_str('mh_sbuserinfo_warning_format');
for my $nick ($channel->nicks())
@@ -201,56 +233,84 @@ sub statusbar_userinfo
{
$users_vo++;
}
+
+ if ($nick->{'serverop'})
+ {
+ $users_oper++;
+ }
}
- $format = $format . $users;
+ $format .= $users;
+
+ my $format_sep = Irssi::settings_get_str('mh_sbuserinfo_format_sep');
+ my $format_div = Irssi::settings_get_str('mh_sbuserinfo_format_div');
+
+ my $format_group_begin = Irssi::settings_get_str('mh_sbuserinfo_format_group_begin');
+ my $format_group_end = Irssi::settings_get_str('mh_sbuserinfo_format_group_end');
if (Irssi::settings_get_bool('mh_sbuserinfo_show_details'))
{
- $format = $format . '(';
+ $format .= $format_group_begin;
my $showmode = Irssi::settings_get_bool('mh_sbuserinfo_show_details_mode');
+ if (Irssi::settings_get_bool('mh_sbuserinfo_show_details_oper'))
+ {
+ if ($showmode)
+ {
+ $format .= Irssi::settings_get_str('mh_sbuserinfo_format_mode_oper');
+ }
+
+ $format .= $users_oper . $format_sep
+ }
+
if (Irssi::settings_get_bool('mh_sbuserinfo_show_warning_opless') and (not $users_op))
{
- $format = $format . $warning_format;
+ $format .= $warning_format;
}
if ($showmode)
{
- $format = $format . '@';
+ $format .= Irssi::settings_get_str('mh_sbuserinfo_format_mode_op');
}
- $format = $format . $users_op . '%n:';
+ $format .= $users_op . '%n' . $format_sep;
if (Irssi::settings_get_bool('mh_sbuserinfo_show_details_halfop'))
{
#
# add halfops to ops so users calculation below matches
#
- $users_op = $users_op + $users_ho;
+ $users_op += $users_ho;
if ($showmode)
{
- $format = $format . '%%';
+ $format .= Irssi::settings_get_str('mh_sbuserinfo_format_mode_ho');
}
- $format = $format . $users_ho . ':';
+ $format .= $users_ho . $format_sep;
+ }
+
+ if ($showmode)
+ {
+ $format .= Irssi::settings_get_str('mh_sbuserinfo_format_mode_vo');;
}
+ $format .= $users_vo . $format_sep;
+
if ($showmode)
{
- $format = $format . '+';
+ $format .= Irssi::settings_get_str('mh_sbuserinfo_format_mode_other');;
}
- $format = $format . $users_vo . ':' . ($users - ($users_op + $users_vo)) . ')';
+ $format .= ($users - ($users_op + $users_vo)) . $format_group_end;
}
my $limit = $channel->{'limit'};
if ($limit)
{
- $format = $format . '/';
+ $format .= $format_div;
if (Irssi::settings_get_bool('mh_sbuserinfo_show_warning_limit'))
{
@@ -265,20 +325,39 @@ sub statusbar_userinfo
$setting_percent = 0;
}
- my $percent = int(($users / $limit) * 100);
+ if ($setting_percent)
+ {
+
+ my $percent = int(($users / $limit) * 100);
- if ($percent >= $setting_percent)
+ if ($percent >= $setting_percent)
+ {
+ $format .= $warning_format;
+ }
+ } else
{
- $format = $format . $warning_format;
+ my $setting_percent = Irssi::settings_get_int('mh_sbuserinfo_show_warning_limit_difference');
+
+ my $difference = ($limit - $users);
+
+ if ($setting_percent < 0)
+ {
+ $setting_percent = 0;
+ }
+
+ if ($difference < $setting_percent)
+ {
+ $format .= $warning_format;
+ }
}
}
if (Irssi::settings_get_bool('mh_sbuserinfo_show_details_difference'))
{
- $limit = $limit . '(' . ($limit - $users) . ')';
+ $limit .= $format_group_begin . ($limit - $users) . $format_group_end;
}
- $format = $format . $limit . '%n';
+ $format .= $limit . '%n';
}
}
}
@@ -292,17 +371,26 @@ sub statusbar_userinfo
#
##############################################################################
-Irssi::settings_add_bool('mh_sbuserinfo', 'mh_sbuserinfo_show_details', 1);
-Irssi::settings_add_bool('mh_sbuserinfo', 'mh_sbuserinfo_show_details_mode', 1);
-Irssi::settings_add_bool('mh_sbuserinfo', 'mh_sbuserinfo_show_details_halfop', 0);
-Irssi::settings_add_bool('mh_sbuserinfo', 'mh_sbuserinfo_show_warning_opless', 1);
-Irssi::settings_add_bool('mh_sbuserinfo', 'mh_sbuserinfo_show_warning_limit', 1);
-Irssi::settings_add_int( 'mh_sbuserinfo', 'mh_sbuserinfo_show_warning_limit_percent', 95);
-Irssi::settings_add_str( 'mh_sbuserinfo', 'mh_sbuserinfo_warning_format', '%Y');
-Irssi::settings_add_str( 'mh_sbuserinfo', 'mh_sbuserinfo_show_prefix', 'Users: ');
-Irssi::settings_add_bool('mh_sbuserinfo', 'mh_sbuserinfo_show_details_difference', 1);
-
-Irssi::statusbar_item_register('mh_sbuserinfo', '', 'statusbar_userinfo');
+Irssi::settings_add_bool('mh_sbuserinfo', 'mh_sbuserinfo_show_details', 1);
+Irssi::settings_add_bool('mh_sbuserinfo', 'mh_sbuserinfo_show_details_mode', 1);
+Irssi::settings_add_bool('mh_sbuserinfo', 'mh_sbuserinfo_show_details_halfop', 0);
+Irssi::settings_add_bool('mh_sbuserinfo', 'mh_sbuserinfo_show_warning_opless', 1);
+Irssi::settings_add_bool('mh_sbuserinfo', 'mh_sbuserinfo_show_warning_limit', 1);
+Irssi::settings_add_int( 'mh_sbuserinfo', 'mh_sbuserinfo_show_warning_limit_percent', 0);
+Irssi::settings_add_int( 'mh_sbuserinfo', 'mh_sbuserinfo_show_warning_limit_difference', 5);
+Irssi::settings_add_str( 'mh_sbuserinfo', 'mh_sbuserinfo_warning_format', '%Y');
+Irssi::settings_add_str( 'mh_sbuserinfo', 'mh_sbuserinfo_show_prefix', 'Users: ');
+Irssi::settings_add_bool('mh_sbuserinfo', 'mh_sbuserinfo_show_details_difference', 1);
+Irssi::settings_add_bool('mh_sbuserinfo', 'mh_sbuserinfo_show_details_oper', 1);
+Irssi::settings_add_str( 'mh_sbuserinfo', 'mh_sbuserinfo_format_sep', ':');
+Irssi::settings_add_str( 'mh_sbuserinfo', 'mh_sbuserinfo_format_div', '/');
+Irssi::settings_add_str( 'mh_sbuserinfo', 'mh_sbuserinfo_format_group_begin', '(');
+Irssi::settings_add_str( 'mh_sbuserinfo', 'mh_sbuserinfo_format_group_end', ')');
+Irssi::settings_add_str( 'mh_sbuserinfo', 'mh_sbuserinfo_format_mode_oper', '*');
+Irssi::settings_add_str( 'mh_sbuserinfo', 'mh_sbuserinfo_format_mode_op', '@');
+Irssi::settings_add_str( 'mh_sbuserinfo', 'mh_sbuserinfo_format_mode_ho', '%%');
+Irssi::settings_add_str( 'mh_sbuserinfo', 'mh_sbuserinfo_format_mode_vo', '+');
+Irssi::settings_add_str( 'mh_sbuserinfo', 'mh_sbuserinfo_format_mode_other', '');
Irssi::signal_add_last('channel sync', 'statusbar_redraw');
Irssi::signal_add_last('channel mode changed', 'statusbar_redraw');
@@ -312,6 +400,8 @@ Irssi::signal_add_last('nicklist remove', 'statusbar_redraw');
Irssi::signal_add_last('setup changed', 'signal_setup_changed_last');
Irssi::signal_add_last('window changed', 'signal_window_changed_last');
+Irssi::statusbar_item_register('mh_sbuserinfo', '', 'statusbar_userinfo');
+
1;
##############################################################################
diff --git a/scripts/nickserv.pl b/scripts/nickserv.pl
index c1d9ce8..ff2738d 100644
--- a/scripts/nickserv.pl
+++ b/scripts/nickserv.pl
@@ -24,7 +24,7 @@ use strict;
use Irssi;
use vars qw($VERSION %IRSSI);
-$VERSION = "1.10";
+$VERSION = "1.11";
%IRSSI = (
authors => 'Geert Hauwaerts',
@@ -32,37 +32,47 @@ $VERSION = "1.10";
name => 'nickserv.pl',
description => 'This script will authorize you into NickServ.',
license => 'GNU General Public License',
- url => 'http://irssi.hauwaerts.be/nickserv.pl',
+ url => 'https://github.com/irssi/scripts.irssi.org/blob/master/scripts/nickserv.pl',
+ changed => 'Di 17. Jan 19:32:45 CET 2017',
);
+my $irssidir = Irssi::get_irssi_dir();
+
my @nickservnet = ();
-my $nickservnet_file = "nickserv.networks";
+my $nickservnet_file = "$irssidir/nickserv.networks";
my @nickservauth = ();
-my $nickservauth_file = "nickserv.auth";
+my $nickservauth_file = "$irssidir/nickserv.auth";
-my $irssidir = Irssi::get_irssi_dir();
+my @nickservpostcmd = ();
+my $nickservpostcmd_file = "$irssidir/nickserv.postcmd";
my $help = <<EOF;
Usage: (all on one line)
/NICKSERV [addnet <ircnet> <services\@host>]
[addnick <ircnet> <nickname> <password>]
+ [addpostcmd <ircnet> <nickname> <command>]
[delnet <ircnet>]
[delnick <ircnet> <nick>]
- [help listnet listnick]
-
-addnet: Add a new network into the NickServ list.
-addnick: Add a new nickname into the NickServ list.
-delnet: Delete a network from the NickServ list.
-delnick: Delete a nickname from the NickServ list.
-listnet: Display the contents of the NickServ network list.
-listnick: Display the contents of the NickServ nickname list.
-help: Display this useful little helptext.
+ [delpostcmd <ircnet> <nick>]
+ [help listnet listnick listpostcmd]
+
+addnet: Add a new network into the NickServ list.
+addnick: Add a new nickname into the NickServ list.
+addpostcmd: Add a new post auth command for nickname into the NickServ list.
+delnet: Delete a network from the NickServ list.
+delnick: Delete a nickname from the NickServ list.
+delpostcmd: Deletes all post auth commands for the given nickame.
+listnet: Display the contents of the NickServ network list.
+listnick: Display the contents of the NickServ nickname list.
+listpostcmd: Display the contents of the NickServ postcmd list.
+help: Display this useful little helptext.
Examples: (all on one line)
/NICKSERV addnet Freenode NickServ\@services.
/NICKSERV addnick Freenode Geert mypass
+/NICKSERV addpostcmd Freenode Geert ^MSG ChanServ invite #heaven
/NICKSERV delnet Freenode
/NICKSERV delnick Freenode Geert
@@ -74,19 +84,25 @@ EOF
Irssi::theme_register([
'nickserv_usage_network', '%R>>%n %_NickServ:%_ Insufficient parameters: Usage "%_/NICKSERV addnet ircnet services@host%_".',
'nickserv_usage_nickname', '%R>>%n %_NickServ:%_ Insufficient parameters: Usage "%_/NICKSERV addnick ircnet nickname password%_".',
+ 'nickserv_usage_postcmd', '%R>>%n %_NickServ:%_ Insufficient parameters: Usage "%_/NICKSERV addpostcmd ircnet nickname command%_".',
'nickserv_delusage', '%R>>%n %_NickServ:%_ Insufficient parameters: Usage "%_/NICKSERV delnet ircnet%_".',
'nickserv_delnickusage', '%R>>%n %_NickServ:%_ Insufficient parameters: Usage "%_/NICKSERV delnick ircnet nickname%_".',
- 'nickserv_delled', '%R>>%n %_NickServ:%_ Deleted %_$0%_ and his nicknames from the NickServ ircnet list.',
- 'nickserv_delled_nick', '%R>>%n %_NickServ:%_ Deleted %_$1%_ from the NickServ list on $0.',
+ 'nickserv_delpostcmdusage', '%R>>%n %_NickServ:%_ Insufficient parameters: Usage "%_/NICKSERV delpostcmd ircnet nickname%_".',
+ 'nickserv_delled', '%R>>%n %_NickServ:%_ Deleted %_$0%_ and it\'s nicknames and post commands from the NickServ ircnet list.',
+ 'nickserv_delled_nick', '%R>>%n %_NickServ:%_ Deleted %_$1%_ and it\'s post commands from the NickServ list on $0.',
+ 'nickserv_delled_postcmd', '%R>>%n %_NickServ:%_ Deleted all entries for %_$1%_ from the NickServ postcmd list on $0.',
'nickserv_nfound', '%R>>%n %_NickServ:%_ The NickServ ircnet %_$0%_ could not be found.',
'nickserv_nfound_nick', '%R>>%n %_NickServ:%_ The NickServ nickname %_$0%_ could not be found on $1.',
+ 'nickserv_nfound_postcmd', '%R>>%n %_NickServ:%_ The NickServ post commands for nickname %_$1%_ could not be found on $0.',
'nickserv_usage', '%R>>%n %_NickServ:%_ Insufficient parameters: Use "%_/NICKSERV help%_" for further instructions.',
'nickserv_no_net', '%R>>%n %_NickServ:%_ Unknown Irssi ircnet %_$0%_.',
'nickserv_wrong_host', '%R>>%n %_NickServ:%_ Malformed services hostname %_$0%_.',
'already_loaded_network', '%R>>%n %_NickServ:%_ The ircnet %_$0%_ already exists in the NickServ ircnet list, please remove it first.',
'nickserv_loaded_nick', '%R>>%n %_NickServ:%_ The nickname %_$0%_ already exists in the NickServ authlist on %_$1%_, please remove it first.',
'nickserv_not_loaded_net', '%R>>%n %_NickServ:%_ The ircnet %_$0%_ doesn\'t exists in the NickServ ircnet list, please add it first.',
+ 'nickserv_not_loaded_nick', '%R>>%n %_NickServ:%_ The nickname %_$0%_ doesn\'t exists in the NickServ authlist on %_$1%_, please add it first.',
'saved_nickname', '%R>>%n %_NickServ:%_ Added nickname %_$1%_ on %_$0%_.',
+ 'saved_postcmd', '%R>>%n %_NickServ:%_ Added postcmd %_$1%_ on %_$0%_: %_%2%_.',
'network_print', '$[!-2]0 $[20]1 $2',
'password_request', '%R>>%n %_NickServ:%_ Auth Request from NickServ on %_$0%_.',
'password_accepted', '%R>>%n %_NickServ:%_ Password accepted on %_$0%_.',
@@ -96,6 +112,9 @@ Irssi::theme_register([
'nickname_print', '$[!-2]0 $[20]1 $[18]2 $3',
'nickname_info', '%_ # Ircnet Nickname Password%_',
'nickname_empty', '%R>>%n %_NickServ:%_ Your NickServ authlist is empty.',
+ 'postcmd_print', '$[!-2]0 $[20]1 $[18]2 $3',
+ 'postcmd_info', '%_ # Ircnet Nickname Postcmd%_',
+ 'postcmd_empty', '%R>>%n %_NickServ:%_ Your NickServ postcmd list is empty.',
'nickserv_help', '$0',
'saved_network', '%R>>%n %_NickServ:%_ Added services mask "%_$1%_" on %_$0%_.',
'nickserv_loaded', '%R>>%n %_Scriptinfo:%_ Loaded $0 version $1 by $2.'
@@ -105,139 +124,171 @@ sub load_nickservnet {
my ($file) = @_;
- @nickservnet = ();
+ @nickservnet = load_file($file, sub {
+ my $new_nsnet = new_nickserv_network(@_);
+ return undef if ($new_nsnet->{name} eq "" || $new_nsnet->{host} eq "");
+ return $new_nsnet;
+ });
+}
- if (-e $file) {
- local *F;
- open(F, "<", $file);
- local $/ = "\n";
+sub save_nickservnet {
- while (<F>) {
- chop;
- my $new_nsnet = new_nickserv_network(split("\t"));
-
- if (($new_nsnet->{name} ne "") && ($new_nsnet->{host} ne "")) {
- push(@nickservnet, $new_nsnet);
- }
- }
-
- close(F);
- }
+ save_file($nickservnet_file, \@nickservnet, \&nickservnet_as_list);
}
-sub save_nickservnet {
+sub new_nickserv_network {
- my ($file) = @_;
+ return {
+ name => shift,
+ host => shift
+ };
+}
- return unless scalar @nickservnet; # there's nothing to save
+sub nickservnet_as_list {
- if (-e $file) {
- local *F;
- open(F, ">", $file);
+ my $nickserv_net = shift;
- for (my $n = 0; $n < @nickservnet; ++$n) {
- print(F join("\t", $nickservnet[$n]->{name}, $nickservnet[$n]->{host}) . "\n");
- }
-
- close(F);
- } else {
- create_network_file($file);
- save_nickservnet($file);
- }
+ return (
+ $nickserv_net->{name},
+ $nickserv_net->{host}
+ );
}
-sub create_network_file {
-
+sub load_nickservnick {
+
my ($file) = @_;
-
- open(F, ">", $file) or die "Can't create $file. Reason: $!";
+
+ @nickservauth = load_file($file, sub {
+ my $new_nsnick = new_nickserv_nick(@_);
+
+ return undef if ($new_nsnick->{ircnet} eq "" || $new_nsnick->{nick} eq "" || $new_nsnick->{pass} eq "");
+ return $new_nsnick;
+ });
}
-sub new_nickserv_network {
+sub save_nickservnick {
- my $nsnet = {};
+ save_file($nickservauth_file, \@nickservauth, \&nickserv_nick_as_list);
+}
- $nsnet->{name} = shift;
- $nsnet->{host} = shift;
+sub new_nickserv_nick {
- return $nsnet;
+ return {
+ ircnet => shift,
+ nick => shift,
+ pass => shift
+ };
}
-sub load_nickservnick {
+sub nickserv_nick_as_list {
+
+ my $nickserv_nick = shift;
+ return (
+ $nickserv_nick->{ircnet},
+ $nickserv_nick->{nick},
+ $nickserv_nick->{pass}
+ );
+}
+
+sub load_nickservpostcmd {
my ($file) = @_;
- @nickservauth = ();
+ @nickservpostcmd = load_file($file, sub {
+ my $new_postcmd = new_postcmd(@_);
- if (-e $file) {
- local *F;
- open(F, "<" ,$file);
- local $/ = "\n";
+ return undef if ($new_postcmd->{ircnet} eq "" || $new_postcmd->{nick} eq "" || $new_postcmd->{postcmd} eq "");
+ return $new_postcmd;
+ });
+}
- while (<F>) {
- chop;
- my $new_nsnick = new_nickserv_nick(split("\t"));
-
- if (($new_nsnick->{ircnet} ne "") && ($new_nsnick->{nick} ne "") && ($new_nsnick->{pass} ne "")) {
- push(@nickservauth, $new_nsnick);
- }
- }
-
- close(F);
- }
+sub save_nickservpostcmd {
+
+ save_file($nickservpostcmd_file, \@nickservpostcmd, \&postcmd_as_list);
}
-sub save_nickservnick {
+sub new_postcmd {
- my ($file) = @_;
+ return {
+ ircnet => shift,
+ nick => shift,
+ postcmd => shift
+ };
+}
- return unless scalar @nickservauth; # there's nothing to save
+sub postcmd_as_list {
+ my $postcmd = shift;
- if (-e $file) {
- local *F;
- open(F, ">", $file);
+ return (
+ $postcmd->{ircnet},
+ $postcmd->{nick},
+ $postcmd->{postcmd}
+ );
+}
- for (my $n = 0; $n < @nickservauth; ++$n) {
- print(F join("\t", $nickservauth[$n]->{ircnet}, $nickservauth[$n]->{nick}, $nickservauth[$n]->{pass}) . "\n");
- }
-
- close(F);
- } else {
- create_nick_file($file);
- save_nickservnick($file);
+# file: filename to be read
+# parse_line_fn: receives array of entries of a single line as input, should
+# return parsed data object or undef in the data is incomplete
+# returns: parsed data array
+sub load_file {
+
+ my ($file, $parse_line_fn) = @_;
+ my @parsed_data = ();
+
+ if (-e $file) {
+ open(my $fh, "<", $file);
+ local $/ = "\n";
+
+ while (<$fh>) {
+ chomp;
+ my $data = $parse_line_fn->(split("\t"));
+ push(@parsed_data, $data) if $data;
}
-}
-sub create_nick_file {
-
- my ($file) = @_;
-
- my $umask = umask 0077; # save old umask
- open(F, ">", $file) or die "Can't create $file. Reason: $!";
- umask $umask;
+ close($fh);
+ }
+
+ return @parsed_data;
}
-sub new_nickserv_nick {
+# file: filename to be written, is created accessable only by the user
+# data_ref: array ref of data entries
+# serialize_fn: receives a data reference and should return an array or tuples
+# for that data that will be serialized into one line
+sub save_file {
+
+ my ($file, $data_ref, $serialize_fn) = @_;
+
+ create_private_file($file) unless -e $file;
- my $nsnick = {};
+ open(my $fh, ">", $file) or die "Can't create $file. Reason: $!";
- $nsnick->{ircnet} = shift;
- $nsnick->{nick} = shift;
- $nsnick->{pass} = shift;
+ for my $data (@$data_ref) {
+ print($fh join("\t", $serialize_fn->($data)), "\n");
+ }
+
+ close($fh);
+}
- return $nsnick;
+sub create_private_file {
+
+ my ($file) = @_;
+ my $umask = umask 0077; # save old umask
+ open(my $fh, ">", $file) or die "Can't create $file. Reason: $!";
+ close($fh);
+ umask $umask;
}
sub add_nickname {
-
+
my ($network, $nickname, $password) = split(" ", $_[0], 3);
- my ($correct_network, $correct_nickname, $correct_password);
+ my ($correct_network, $correct_nickname);
if ($network eq "" || $nickname eq "" || $password eq "") {
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_usage_nickname');
return;
}
-
+
if ($network) {
if (!already_loaded_net($network)) {
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_not_loaded_net', $network);
@@ -246,7 +297,7 @@ sub add_nickname {
$correct_network = 1;
}
}
-
+
if ($nickname) {
if (already_loaded_nick($nickname, $network)) {
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_loaded_nick', $nickname, $network);
@@ -255,28 +306,64 @@ sub add_nickname {
$correct_nickname = 1;
}
}
-
+
if ($correct_network && $correct_nickname) {
push(@nickservauth, new_nickserv_nick($network, $nickname, $password));
- save_nickservnick("$irssidir/$nickservauth_file");
-
+ save_nickservnick();
+
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'saved_nickname', $network, $nickname);
}
}
+sub add_postcmd {
+
+ my ($network, $nickname, $postcmd) = split(" ", $_[0], 3);
+ my ($correct_network, $correct_nickname);
+
+ if ($network eq "" || $nickname eq "" || $postcmd eq "") {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_usage_postcmd');
+ return;
+ }
+
+ if ($network) {
+ if (!already_loaded_net($network)) {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_not_loaded_net', $network);
+ return;
+ } else {
+ $correct_network = 1;
+ }
+ }
+
+ if ($nickname) {
+ if (!already_loaded_nick($nickname, $network)) {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_not_loaded_nick', $nickname, $network);
+ return;
+ } else {
+ $correct_nickname = 1;
+ }
+ }
+
+ if ($correct_network && $correct_nickname) {
+ push(@nickservpostcmd, new_postcmd($network, $nickname, $postcmd));
+ save_nickservpostcmd();
+
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'saved_postcmd', $network, $nickname, $postcmd);
+ }
+}
+
sub add_network {
-
+
my ($network, $hostname) = split(" ", $_[0], 2);
my ($correct_net, $correct_host);
-
+
if ($network eq "" || $hostname eq "") {
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_usage_network');
return;
}
-
+
if ($network) {
my ($ircnet) = Irssi::chatnet_find($network);
-
+
if (!$ircnet) {
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_no_net', $network);
return;
@@ -287,7 +374,7 @@ sub add_network {
$correct_net = 1;
}
}
-
+
if ($hostname) {
if ($hostname !~ /^[.+a-zA-Z0-9_-]{1,}@[.+a-zA-Z0-9_-]{1,}$/) {
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_wrong_host', $hostname);
@@ -296,11 +383,11 @@ sub add_network {
$correct_host = 1;
}
}
-
+
if ($correct_net && $correct_host) {
push(@nickservnet, new_nickserv_network($network, $hostname));
- save_nickservnet("$irssidir/$nickservnet_file");
-
+ save_nickservnet();
+
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'saved_network', $network, $hostname);
}
}
@@ -308,56 +395,32 @@ sub add_network {
sub already_loaded_net {
my ($ircnet) = @_;
- my $loaded = check_loaded_net($ircnet);
-
- if ($loaded > -1) {
- return 1;
- }
-
- return 0;
-}
-
-sub check_loaded_net {
-
- my ($ircnet) = @_;
$ircnet = lc($ircnet);
- for (my $loaded = 0; $loaded < @nickservnet; ++$loaded) {
- return $loaded if (lc($nickservnet[$loaded]->{name}) eq $ircnet);
+ for my $loaded (@nickservnet) {
+ return 1 if (lc($loaded->{name}) eq $ircnet);
}
-
- return -1;
+
+ return 0;
}
sub already_loaded_nick {
-
my ($nickname, $network) = @_;
- my $loaded = check_loaded_nick($nickname, $network);
-
- if ($loaded > -1) {
- return 1;
- }
-
- return 0
-}
-sub check_loaded_nick {
-
- my ($nickname, $network) = @_;
-
$nickname = lc($nickname);
$network = lc($network);
-
- for (my $loaded = 0; $loaded < @nickservauth; ++$loaded) {
- return $loaded if (lc($nickservauth[$loaded]->{nick}) eq $nickname && lc ($nickservauth[$loaded]->{ircnet}) eq $network);
+
+ for my $loaded (@nickservauth) {
+ return 1 if (lc($loaded->{nick}) eq $nickname &&
+ lc($loaded->{ircnet}) eq $network);
}
-
- return -1;
+
+ return 0;
}
sub list_net {
-
+
if (@nickservnet == 0) {
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'network_empty');
} else {
@@ -370,7 +433,7 @@ sub list_net {
}
sub list_nick {
-
+
if (@nickservauth == 0) {
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickname_empty');
} else {
@@ -382,8 +445,21 @@ sub list_nick {
}
}
+sub list_postcmd {
+
+ if (@nickservpostcmd == 0) {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'postcmd_empty');
+ } else {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'postcmd_info');
+
+ for (my $n = 0; $n < @nickservpostcmd ; ++$n) {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'postcmd_print', $n, $nickservpostcmd[$n]->{ircnet}, $nickservpostcmd[$n]->{nick}, $nickservpostcmd[$n]->{postcmd});
+ }
+ }
+}
+
sub nickserv_notice {
-
+
my ($server, $data, $nick, $address) = @_;
my ($target, $text) = $data =~ /^(\S*)\s:(.*)/;
@@ -392,14 +468,14 @@ sub nickserv_notice {
if ($text =~ /^(?:If this is your nickname, type|Please identify via|Type) \/msg NickServ (?i:identify)/ || $text =~ /^This nickname is registered and protected. If it is your/ || $text =~ /This nickname is registered\. Please choose a different nickname/) {
my $password = get_password($server->{tag}, $server->{nick});
-
+
if ($password == -1) {
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'password_request', $server->{tag});
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_nfound_nick', $server->{nick}, $server->{tag});
Irssi::signal_stop();
return;
}
-
+
Irssi::signal_stop();
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'password_request', $server->{tag});
$server->command("^MSG NickServ IDENTIFY $password");
@@ -442,6 +518,7 @@ sub nickserv_notice {
} elsif ($text =~ /^Password accepted - you are now recognized/ || $text =~ /^You are now identified for/) {
Irssi::signal_stop();
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'password_accepted', $server->{tag});
+ run_postcmds($server, $server->{tag}, $server->{nick})
} elsif ($text =~ /^Password Incorrect/ || $text =~ /^Password incorrect./) {
Irssi::signal_stop();
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'password_wrong', $server->{tag});
@@ -449,24 +526,39 @@ sub nickserv_notice {
}
}
+sub run_postcmds {
+ my ($server, $ircnet, $nick) = @_;
+ return if @nickservpostcmd == 0;
+
+ for my $cmd (@nickservpostcmd) {
+ if ($ircnet eq $cmd->{ircnet} &&
+ $nick eq $cmd->{nick} &&
+ $cmd->{postcmd}) {
+ $server->command($cmd->{postcmd});
+ }
+ }
+}
+
sub is_nickserv {
-
+
my ($net, $host) = @_;
for (my $loaded = 0; $loaded < @nickservnet; ++$loaded) {
- return 1 if (lc($nickservnet[$loaded]->{name}) eq lc($net) && lc($nickservnet[$loaded]->{host}) eq lc($host));
+ return 1 if (lc($nickservnet[$loaded]->{name}) eq lc($net) &&
+ lc($nickservnet[$loaded]->{host}) eq lc($host));
}
return 0;
}
sub get_password {
-
+
my ($ircnet, $nick) = @_;
-
+
for (my $loaded = 0; $loaded < @nickservauth; ++$loaded) {
- return $nickservauth[$loaded]->{pass} if (lc($nickservauth[$loaded]->{ircnet}) eq lc($ircnet) && lc($nickservauth[$loaded]->{nick}) eq lc($nick));
+ return $nickservauth[$loaded]->{pass} if (lc($nickservauth[$loaded]->{ircnet}) eq lc($ircnet) &&
+ lc($nickservauth[$loaded]->{nick}) eq lc($nick));
}
-
+
return -1;
}
@@ -485,47 +577,76 @@ sub del_network {
$ircnetindex = 1;
}
}
-
+
if ($ircnetindex) {
@nickservnet = grep {lc($_->{name}) ne lc($ircnet)} @nickservnet;
@nickservauth = grep {lc($_->{ircnet}) ne lc($ircnet)} @nickservauth;
+ @nickservpostcmd = grep {lc($_->{ircnet}) ne lc($ircnet)} @nickservpostcmd;
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_delled', $ircnet);
- save_nickservnet("$irssidir/$nickservnet_file");
- save_nickservnick("$irssidir/$nickservauth_file");
+ save_nickservnet();
+ save_nickservnick();
+ save_nickservpostcmd();
} else {
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_nfound', $ircnet);
}
}
sub del_nickname {
-
+
my ($ircnet, $nickname) = split(" ", $_[0], 2);
my ($nickindex);
-
+
if ($ircnet eq "" || $nickname eq "") {
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_delnickusage');
return;
}
for (my $index = 0; $index < @nickservauth; ++$index) {
- if (lc($nickservauth[$index]->{ircnet}) eq lc($ircnet) && lc($nickservauth[$index]->{nick}) eq lc($nickname)) {
+ if (lc($nickservauth[$index]->{ircnet}) eq lc($ircnet) &&
+ lc($nickservauth[$index]->{nick}) eq lc($nickname)) {
$nickindex = splice(@nickservauth, $index, 1);
- }
+ }
}
if ($nickindex) {
+ @nickservpostcmd = grep {lc($_->{ircnet}) ne lc($ircnet) ||
+ lc($_->{nick}) ne lc($nickname)}
+ @nickservpostcmd;
+
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_delled_nick', $ircnet, $nickname);
- save_nickservnick("$irssidir/$nickservauth_file");
+ save_nickservnick();
+ save_nickservpostcmd();
} else {
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_nfound_nick', $ircnet, $nickname);
}
}
+sub del_postcmd {
+
+ my ($ircnet, $nickname) = split(" ", $_[0], 2);
+
+ if ($ircnet eq "" || $nickname eq "") {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_delpostcmdusage');
+ return;
+ }
+
+ my $size_before = scalar(@nickservpostcmd);
+ @nickservpostcmd = grep { !( lc($_->{ircnet}) eq lc($ircnet) && lc($_->{nick}) eq lc($nickname) )} @nickservpostcmd;
+ my $size_after = scalar(@nickservpostcmd);
+
+ if ($size_before != $size_after) {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_delled_postcmd', $ircnet, $nickname);
+ save_nickservpostcmd();
+ } else {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_nfound_postcmd', $ircnet, $nickname);
+ }
+}
+
sub nickserv_runsub {
-
+
my ($data, $server, $item) = @_;
$data =~ s/\s+$//g;
-
+
if ($data) {
Irssi::command_runsub('nickserv', $data, $server, $item);
} else {
@@ -533,32 +654,31 @@ sub nickserv_runsub {
}
}
-load_nickservnet("$irssidir/$nickservnet_file");
-load_nickservnick("$irssidir/$nickservauth_file");
+load_nickservnet($nickservnet_file);
+load_nickservnick($nickservauth_file);
+load_nickservpostcmd($nickservpostcmd_file);
Irssi::command_bind('nickserv', 'nickserv_runsub');
Irssi::command_bind('ns', 'nickserv_runsub');
-Irssi::command_bind('nickserv addnet', 'add_network');
-Irssi::command_bind('ns addnet', 'add_network');
-
-Irssi::command_bind('nickserv addnick', 'add_nickname');
-Irssi::command_bind('ns addnick', 'add_nickname');
-
-Irssi::command_bind('nickserv listnet', 'list_net');
-Irssi::command_bind('ns listnet', 'list_net');
-
-Irssi::command_bind('nickserv listnick', 'list_nick');
-Irssi::command_bind('ns listnick', 'list_nick');
-
-Irssi::command_bind('nickserv delnet', 'del_network');
-Irssi::command_bind('ns delnet', 'del_network');
-
-Irssi::command_bind('nickserv delnick', 'del_nickname');
-Irssi::command_bind('ns delnick', 'del_nickname');
-
Irssi::command_bind('nickserv help' => sub { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_help', $help) });
Irssi::command_bind('ns help' => sub { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_help', $help) });
+# "command binding" -> "function name" mapping
+for my $cmd ((
+ ['addnet' => 'add_network'],
+ ['addnick' => 'add_nickname'],
+ ['addpostcmd' => 'add_postcmd'],
+ ['listnet' => 'list_net'],
+ ['listnick' => 'list_nick'],
+ ['listpostcmd' => 'list_postcmd'],
+ ['delnet' => 'del_network'],
+ ['delnick' => 'del_nickname'],
+ ['delpostcmd' => 'del_postcmd'],
+)) {
+ Irssi::command_bind("nickserv $cmd->[0]", $cmd->[1]);
+ Irssi::command_bind("ns $cmd->[0]", $cmd->[1]);
+}
+
Irssi::signal_add('event notice', 'nickserv_notice');
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_loaded', $IRSSI{name}, $VERSION, $IRSSI{authors});
diff --git a/scripts/pager.pl b/scripts/pager.pl
index 32f0902..50d7899 100644
--- a/scripts/pager.pl
+++ b/scripts/pager.pl
@@ -2,14 +2,16 @@
use strict;
use Irssi 20020121.2020 ();
-$VERSION = "1.1";
+
+use vars qw/$VERSION %IRSSI/;
+$VERSION = "1.2";
%IRSSI = (
authors => 'Jean-Yves Lefort',
contact => 'jylefort\@brutele.be',
name => 'pager',
description => 'Notifies people if they send you a private message or a DCC chat offer while you are away; runs a shell command configurable via /set if they page you',
license => 'BSD',
- changed => '$Date: 2003/01/27 09:45:16 $ ',
+ changed => '$Date: 2017/03/06 $ ',
);
# note:
@@ -33,6 +35,9 @@ $VERSION = "1.1";
#
# changes:
#
+# 2017-03-06 release 1.2
+# * declaration $VERSION %IRSSI
+#
# 2003-01-27 release 1.1
# * notices and commands are now optional
#
diff --git a/scripts/perlalias.pl b/scripts/perlalias.pl
new file mode 100644
index 0000000..b546688
--- /dev/null
+++ b/scripts/perlalias.pl
@@ -0,0 +1,288 @@
+=head1 perlalias.pl - Perl-based command aliases for irssi
+
+This script provides an /alias-like function that uses small pieces of perl code to carry out the commands.
+
+=head2 Usage
+
+Install into irssi script directory and /run perlalias and/or put into autorun.
+
+=head2 Commands
+
+=over
+
+=item /perlalias
+
+Syntax: /perlalias [[[-]<alias>] [<code>]]
+
+Parameters: A name of the alias and the perl code to execute.
+
+If you prepend the alias with -, it will remove the alias.
+
+If you give no arguments, the list of defined aliases will be displayed.
+
+Description:
+
+Creates or updates an alias. Like any perl code, multiple statements must be separated using ; characters.
+No replacement of parameter values is done: any $text is a perl variable.
+
+The arguments given to the /alias when typed are put into $_ and are also split on whitespace and put into @_.
+In addition, the variables $server and $witem will refer to the active server and window item respectively.
+
+Examples:
+
+/PERLALIAS UNACT foreach my $w (Irssi::windows) { $w->activity(0); }
+
+=back
+
+=over
+
+=item /perlunalias
+
+Syntax: /perlunalias <alias>
+
+Parameters: The alias to remove.
+
+Description:
+
+Removes the given alias.
+
+=back
+
+Additionally, all aliases added are linked to perlalias.pl: if it is unloaded, the aliases will be removed.
+
+Aliases can be saved and reloaded with the usual /save and /reload (including autosave). Saved aliases are loaded at script load.
+
+=head2 ChangeLog
+
+=over
+
+=item 1.0
+
+First version.
+
+=back
+
+=cut
+
+use strict;
+use warnings FATAL => qw(all);
+use Irssi;
+use Irssi::Irc;
+use Carp ();
+
+#use Cwd;
+use POSIX qw(strftime);
+
+{ package Irssi::Nick; } # Keeps trying to look for this package but for some reason it doesn't get loaded.
+
+our $VERSION = '1.2';
+our %IRSSI = (
+ authors => 'aquanight',
+ contact => 'aquanight@gmail.com',
+ name => 'perlalias',
+ description => 'Quickly create commands from short perl blocks',
+ license => 'public domain'
+ );
+
+# Bound commands
+my %cmds; # Contains command entries. The entry has three items:
+ # textcmd => Plaintext of the command to execute, which is used for loading/saving
+ # cmpcmd => Compiled command, for executing.
+ # tag => Our tag which we need to remove the command
+
+# Package we execute all the commands within, to keep them away from our bits.
+package Irssi::Script::perlalias::aliaspkg {
+}
+
+sub DESTROY {
+ Symbol::delete_package("Irssi::Script::perlalias::aliaspkg::");
+}
+
+# Alias executor
+sub exec_perlalias {
+ my ($cmd, $data, $server, $witem) = @_;
+ exists $cmds{$cmd} or return;
+ defined $cmds{$cmd}->{cmpcmd} or return;
+ local $_ = $data;
+ $cmds{$cmd}->{cmpcmd}->($server, $witem, split / +/, $data);
+}
+
+# Bind a command
+sub setup_command {
+ my ($cmd, $data) = @_;
+ # Compile the script.
+ my $code = qq{package Irssi::Scripts::perlalias::aliaspkg;\nno warnings;\nsub {my \$server = shift; my \$witem = shift;\n#line 1 "perlalias $cmd"\n$data}\n};
+ my $proc = eval $code;
+ if ($@) {
+ Irssi::printformat(MSGLEVEL_CLIENTERROR, perlalias_compile_error => $cmd);
+ Irssi::print(MSGLEVEL_CLIENTERROR, $@);
+ return "";
+ }
+ if (exists($cmds{$cmd})) {
+ my $entry = $cmds{$cmd};
+ $entry->{textcmd} = $data;
+ $entry->{cmpcmd} = $proc;
+ }
+ else {
+ my $entry = {};
+ my $tag = sub { exec_perlalias $cmd, @_; };
+ foreach my $existing_cmd (Irssi::commands()) {
+ if ($existing_cmd->{cmd} eq $cmd) {
+ Irssi::print_format(MSGLEVEL_CLIENTERROR, perlalias_cmd_in_use => $cmd);
+ return "";
+ }
+ }
+ $entry->{textcmd} = $data;
+ $entry->{cmpcmd} = $proc;
+ $entry->{tag} = sub { exec_perlalias $cmd, @_; };
+ Irssi::command_bind($cmd, $entry->{tag});
+ $cmds{$cmd} = $entry;
+ }
+ return 1;
+}
+
+sub remove_command {
+ my ($cmd) = @_;
+ if (exists($cmds{$cmd})) {
+ my $entry = $cmds{$cmd};
+ $entry->{tag}//die "Missing the tag we need to remove the alias!!!";
+ Irssi::command_unbind($cmd, $entry->{tag});
+ delete $cmds{$cmd};
+ return 1;
+ }
+ else {
+ Irssi::printformat(MSGLEVEL_CLIENTERROR, perlalias_not_found => $cmd);
+ return "";
+ }
+}
+
+sub list_commands {
+ my ($prefix) = @_;
+ my @whichones = sort grep /^\Q$prefix\E/, keys %cmds;
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'perlaliaslist_header');
+ for my $name (@whichones) {
+ my $entry = $cmds{$name};
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, perlaliaslist_line => $name, $entry->{textcmd});
+ }
+}
+
+sub cmd_perlalias {
+ my ($data, $server, $witem) = @_;
+ my ($command, $script) = split /\s+/, $data, 2;
+ if (($command//"") eq "") {
+ list_commands "";
+ }
+ elsif ($command =~ m/^-/) {
+ $command = substr($command, 1);
+ if (remove_command($command)) { Irssi::printformat(MSGLEVEL_CLIENTNOTICE, perlalias_removed => $command); }
+ }
+ elsif (($script//"") eq "") {
+ list_commands $command;
+ }
+ else {
+ if (setup_command($command, $script)) { Irssi::printformat(MSGLEVEL_CLIENTNOTICE, perlalias_added => $command); }
+ }
+
+}
+
+sub cmd_perlunalias {
+ my ($data, $server, $witem) = @_;
+ if (remove_command $data) { Irssi::printformat(MSGLEVEL_CLIENTNOTICE, perlalias_removed => $data); }
+}
+
+sub sig_setup_saved {
+ my ($main, $auto) = @_;
+ my $file = Irssi::get_irssi_dir() . "/perlalias";
+ open my $fd, '>', $file or return;
+ for my $cmd (keys %cmds) {
+ my $entry = $cmds{$cmd};
+ printf $fd "%s\t%s\n", $cmd, $entry->{textcmd};
+ }
+ close $fd;
+}
+
+sub sig_setup_reread {
+ my $file = Irssi::get_irssi_dir() . "/perlalias";
+ open my $fd, "<", $file or return;
+ my $ln;
+ my %newcmds;
+ while (defined($ln = <$fd>)) {
+ chomp $ln;
+ my ($cmd, $script) = split /\t/, $ln, 2;
+ if (exists $newcmds{$cmd}) {
+ Irssi::print(MSGLEVEL_CLIENTERROR, "There is a duplicate record in the PerlAlias save file.");
+ Irssi::print(MSGLEVEL_CLIENTERROR, "Offending alias: $cmd");
+ Irssi::print(MSGLEVEL_CLIENTERROR, "Previous definition: " . $newcmds{$cmd});
+ Irssi::print(MSGLEVEL_CLIENTERROR, "Duplicate definition: $script");
+ }
+ $newcmds{$cmd} = $script;
+ }
+ # Scrub the existing list. Update existings, remove any that aren't in the config, then we'll add any that's new.
+ my @currentcmds = keys %cmds;
+ for my $cmd (@currentcmds) {
+ if (exists $newcmds{$cmd}) {
+ setup_command($cmd, $newcmds{$cmd});
+ }
+ else {
+ remove_command($cmd);
+ }
+ delete $newcmds{$cmd};
+ }
+ # By this point all that should be in newcmds is any ... new commands.
+ for my $cmd (keys %newcmds) {
+ setup_command($cmd, $newcmds{$cmd});
+ }
+ close $fd;
+}
+
+sub sig_complete_perlalias {
+ my ($lst, $win, $word, $line, $want_space) = @_;
+ $word//return;
+ $line//return;
+ $lst//return;
+ if ($line ne '') {
+ my $def = $cmds{$line};
+ $def//return;
+ push @$lst, $def->{textcmd};
+ Irssi::signal_stop();
+ }
+ else {
+ push @$lst, (grep /^\Q$word\E/i, keys %cmds);
+ Irssi::signal_stop();
+ }
+}
+
+sub sig_complete_perlunalias {
+ my ($lst, $win, $word, $line, $want_space) = @_;
+ $lst//return;
+ $word//return;
+ push @$lst, (grep /^\Q$word\E/i, keys %cmds);
+}
+
+Irssi::signal_register({"complete command " => [qw(glistptr_char* Irssi::UI::Window string string intptr)]});
+Irssi::signal_add("complete command perlalias" => \&sig_complete_perlalias);
+Irssi::signal_add("complete command perlunalias" => \&sig_complete_perlunalias);
+
+Irssi::signal_add("setup saved" => \&sig_setup_saved);
+Irssi::signal_add("setup reread" => \&sig_setup_reread);
+
+Irssi::command_bind(perlalias => \&cmd_perlalias);
+Irssi::command_bind(perlunalias => \&cmd_perlunalias);
+
+my %formats = (
+ # $0 Name of alias
+ 'perlalias_compile_error' => '{error Error compiling alias {hilight $0}:}',
+ # $0 Name of alias
+ 'perlalias_exec_error' => '{error Error executing alias {hilight $0}:}',
+ 'perlalias_cmd_in_use' => 'Command {hilight $0} is already in use',
+ 'perlalias_added' => 'PerlAlias {hilight $0} added',
+ 'perlalias_removed' => 'PerlAlias {hilight $0} removed',
+ 'perlalias_not_found' => 'PerlAlias {hilight $0} not found',
+ 'perlaliaslist_header' => '%#PerlAliases:',
+ # $0 Name of alias, $1 alias text
+ 'perlaliaslist_line' => '%#$[10]0 $1',
+);
+
+Irssi::theme_register([%formats]);
+
+sig_setup_reread;
diff --git a/scripts/postpone.pl b/scripts/postpone.pl
index 72e0a90..11011f2 100644
--- a/scripts/postpone.pl
+++ b/scripts/postpone.pl
@@ -5,7 +5,7 @@
use strict;
use vars qw($VERSION %IRSSI);
-$VERSION = "20030208";
+$VERSION = "20170204";
%IRSSI = (
authors => "Stefan 'tommie' Tomanek",
contact => "stefan\@pico.ruhr.de",
@@ -37,6 +37,8 @@ sub show_help() {
Display this help
/postpone flush <nick>
Flush postponed messages to <nick>
+/postpone discard <nick>
+ Discard postponed messages to <nick>
/postpone list
List postponed messages
";
@@ -85,11 +87,11 @@ sub cmd_postpone ($$$) {
my @arg = split(/ /, $args);
if (scalar(@arg) < 1) {
#foo
- } elsif ($arg[0] eq 'flush' && defined $arg[1]) {
+ } elsif (($arg[0] eq 'discard' || $arg[0] eq 'flush') && defined $arg[1]) {
return unless ($witem && $witem->{type} eq "CHANNEL");
while (scalar(@{$messages{$server->{tag}}{$witem->{name}}{$arg[1]}}) > 0) {
my $msg = pop @{$messages{$server->{tag}}{$witem->{name}}{$arg[1]}};
- $server->command('MSG '.$witem->{name}.' '.$msg);
+ $server->command('MSG '.$witem->{name}.' '.$msg) if $arg[0] eq 'flush';
}
} elsif ($arg[0] eq 'list') {
my $text;
diff --git a/scripts/print_signals.pl b/scripts/print_signals.pl
new file mode 100644
index 0000000..dadd9eb
--- /dev/null
+++ b/scripts/print_signals.pl
@@ -0,0 +1,280 @@
+# print_signals.pl โ€” Irssi script to help with inspecting signals
+#
+# ยฉ 2017 martin f. krafft <madduck@madduck.net>
+# Released under the MIT licence.
+#
+### Usage:
+#
+# /script load print_signals
+#
+# and then use e.g. tail -F /tmp/irssi_signals.log outside of irssi.
+#
+### Settings:
+#
+# /set print_signals_to_file ["/tmp/irssi_signals.log"]
+# Set the file to which to log all signals and their data
+#
+# /set print_signals_limit_regexp [""]
+# Specify a regexp to limit the signals being captured, e.g. "^window".
+# Default is no limit.
+#
+# # Please note that exclude takes precedence over limit:
+#
+# /set print_signals_exclude_regexp ["print text|key press|textbuffer"]
+# Specify a regexp to exclude signals from being captured. Default is not to
+# fire on signals about printing text or key presses.
+#
+
+use strict;
+use warnings;
+use vars qw($VERSION %IRSSI);
+use Irssi;
+use Data::Dumper;
+
+$VERSION = '1.0';
+
+%IRSSI = (
+ authors => 'martin f. krafft',
+ contact => 'madduck@madduck.net',
+ name => 'print signals debugger',
+ description => 'hooks into every signal and writes the information provided to a file',
+ license => 'MIT',
+ changed => '2017-02-03'
+);
+
+Irssi::settings_add_str('print_signals', 'print_signals_to_file', '/tmp/irssi_signals.log');
+Irssi::settings_add_str('print_signals', 'print_signals_limit_regexp', '');
+Irssi::settings_add_str('print_signals', 'print_signals_exclude_regexp',
+ 'print text|key press|textbuffer|rawlog|log written');
+
+$Data::Dumper::Sortkeys = 1;
+$Data::Dumper::Pad = ' ';
+
+sub signal_handler {
+ my $signal = shift(@_);
+ my $limitre = Irssi::settings_get_str('print_signals_limit_regexp');
+ return unless $signal =~ qr/$limitre/;
+ my $excludere = Irssi::settings_get_str('print_signals_exclude_regexp');
+ return if $signal =~ qr/$excludere/;
+ my @names = shift(@_);
+ my @data = shift(@_);
+ my $outfile = Irssi::settings_get_str('print_signals_to_file');
+ my $fh;
+ if (!open($fh, '>>', $outfile)) {
+ Irssi::print("cannot append to log file $outfile while handling signal '$signal'");
+ return;
+ };
+ print $fh "\n== $signal ==\n";
+ print $fh Data::Dumper->Dump(@data, @names);
+ close($fh);
+}
+
+# TODO: a programmatic way to extract the list of all signals from Irssi
+# itself, along with descriptive names of the arguments.
+my $signals = <<_END;
+# curl -s https://raw.githubusercontent.com/irssi/irssi/master/docs/signals.txt | sed -rne 's,^ ",",p'
+"gui exit"
+"gui dialog", char *type, char *text
+"send command", char *command, SERVER_REC, WI_ITEM_REC
+"chat protocol created", CHAT_PROTOCOL_REC
+"chat protocol updated", CHAT_PROTOCOL_REC
+"chat protocol destroyed", CHAT_PROTOCOL_REC
+"channel created", CHANNEL_REC, int automatic
+"channel destroyed", CHANNEL_REC
+"chatnet created", CHATNET_REC
+"chatnet destroyed", CHATNET_REC
+"commandlist new", COMMAND_REC
+"commandlist remove", COMMAND_REC
+"error command", int err, char *cmd
+"send command", char *args, SERVER_REC, WI_ITEM_REC
+"send text", char *line, SERVER_REC, WI_ITEM_REC
+"command "<cmd>, char *args, SERVER_REC, WI_ITEM_REC
+"default command", char *args, SERVER_REC, WI_ITEM_REC
+"ignore created", IGNORE_REC
+"ignore destroyed", IGNORE_REC
+"ignore changed", IGNORE_REC
+"log new", LOG_REC
+"log remove", LOG_REC
+"log create failed", LOG_REC
+"log locked", LOG_REC
+"log started", LOG_REC
+"log stopped", LOG_REC
+"log rotated", LOG_REC
+"log written", LOG_REC, char *line
+"module loaded", MODULE_REC, MODULE_FILE_REC
+"module unloaded", MODULE_REC, MODULE_FILE_REC
+"module error", int error, char *text, char *rootmodule, char *submodule
+"tls handshake finished", SERVER_REC, TLS_REC
+"nicklist new", CHANNEL_REC, NICK_REC
+"nicklist remove", CHANNEL_REC, NICK_REC
+"nicklist changed", CHANNEL_REC, NICK_REC, char *old_nick
+"nicklist host changed", CHANNEL_REC, NICK_REC
+"nicklist gone changed", CHANNEL_REC, NICK_REC
+"nicklist serverop changed", CHANNEL_REC, NICK_REC
+"pidwait", int pid, int status
+"query created", QUERY_REC, int automatic
+"query destroyed", QUERY_REC
+"query nick changed", QUERY_REC, char *orignick
+"window item name changed", WI_ITEM_REC
+"query address changed", QUERY_REC
+"query server changed", QUERY_REC, SERVER_REC
+"rawlog", RAWLOG_REC, char *data
+"server looking", SERVER_REC
+"server connected", SERVER_REC
+"server connecting", SERVER_REC, ulong *ip
+"server connect failed", SERVER_REC
+"server disconnected", SERVER_REC
+"server quit", SERVER_REC, char *msg
+"server sendmsg", SERVER_REC, char *target, char *msg, int target_type
+"setup changed"
+"setup reread", char *fname
+"setup saved", char *fname, int autosaved
+"ban type changed", char *bantype
+"channel joined", CHANNEL_REC
+"channel wholist", CHANNEL_REC
+"channel sync", CHANNEL_REC
+"channel topic changed", CHANNEL_REC
+"ctcp msg", SERVER_REC, char *args, char *nick, char *addr, char *target
+"ctcp msg "<cmd>, SERVER_REC, char *args, char *nick, char *addr, char *target
+"default ctcp msg", SERVER_REC, char *args, char *nick, char *addr, char *target
+"ctcp reply", SERVER_REC, char *args, char *nick, char *addr, char *target
+"ctcp reply "<cmd>, SERVER_REC, char *args, char *nick, char *addr, char *target
+"default ctcp reply", SERVER_REC, char *args, char *nick, char *addr, char *target
+"ctcp action", SERVER_REC, char *args, char *nick, char *addr, char *target
+"awaylog show", LOG_REC, int away_msgs, int filepos
+"server nick changed", SERVER_REC
+"event connected", SERVER_REC
+"server cap ack "<cmd>, SERVER_REC
+"server cap nak "<cmd>, SERVER_REC
+"server cap end", SERVER_REC
+"server sasl failure", SERVER_REC, char *reason
+"server sasl success", SERVER_REC
+"server event", SERVER_REC, char *data, char *sender_nick, char *sender_address
+"event "<cmd>, SERVER_REC, char *args, char *sender_nick, char *sender_address
+"default event", SERVER_REC, char *data, char *sender_nick, char *sender_address
+"whois default event", SERVER_REC, char *args, char *sender_nick, char *sender_address
+"server incoming", SERVER_REC, char *data
+"redir "<cmd>, SERVER_REC, char *args, char *sender_nick, char *sender_address
+"server lag", SERVER_REC
+"server lag disconnect", SERVER_REC
+"massjoin", CHANNEL_REC, GSList of NICK_RECs
+"ban new", CHANNEL_REC, BAN_REC
+"ban remove", CHANNEL_REC, BAN_REC, char *setby
+"channel mode changed", CHANNEL_REC, char *setby
+"nick mode changed", CHANNEL_REC, NICK_REC, char *setby, char *mode, char *type
+"user mode changed", SERVER_REC, char *old
+"away mode changed", SERVER_REC
+"netsplit server new", SERVER_REC, NETSPLIT_SERVER_REC
+"netsplit server remove", SERVER_REC, NETSPLIT_SERVER_REC
+"netsplit new", NETSPLIT_REC
+"netsplit remove", NETSPLIT_REC
+"dcc ctcp "<cmd>, char *args, DCC_REC
+"default dcc ctcp", char *args, DCC_REC
+"dcc unknown ctcp", char *args, char *sender, char *sendaddr
+"dcc reply "<cmd>, char *args, DCC_REC
+"default dcc reply", char *args, DCC_REC
+"dcc unknown reply", char *args, char *sender, char *sendaddr
+"dcc chat message", DCC_REC, char *msg
+"dcc created", DCC_REC
+"dcc destroyed", DCC_REC
+"dcc connected", DCC_REC
+"dcc rejecting", DCC_REC
+"dcc closed", DCC_REC
+"dcc request", DCC_REC, char *sendaddr
+"dcc request send", DCC_REC
+"dcc chat message", DCC_REC, char *msg
+"dcc transfer update", DCC_REC
+"dcc get receive", DCC_REC
+"dcc error connect", DCC_REC
+"dcc error file create", DCC_REC, char *filename
+"dcc error file open", char *nick, char *filename, int errno
+"dcc error get not found", char *nick
+"dcc error send exists", char *nick, char *filename
+"dcc error unknown type", char *type
+"dcc error close not found", char *type, char *nick, char *filename
+"autoignore new", SERVER_REC, AUTOIGNORE_REC
+"autoignore remove", SERVER_REC, AUTOIGNORE_REC
+"flood", SERVER_REC, char *nick, char *host, int level, char *target
+"notifylist new", NOTIFYLIST_REC
+"notifylist remove", NOTIFYLIST_REC
+"notifylist joined", SERVER_REC, char *nick, char *user, char *host, char *realname, char *awaymsg
+"notifylist away changed", SERVER_REC, char *nick, char *user, char *host, char *realname, char *awaymsg
+"notifylist left", SERVER_REC, char *nick, char *user, char *host, char *realname, char *awaymsg
+"proxy client connecting", CLIENT_REC
+"proxy client connected", CLIENT_REC
+"proxy client disconnected", CLIENT_REC
+"proxy client command", CLIENT_REC, char *args, char *data
+"proxy client dump", CLIENT_REC, char *data
+"gui print text", WINDOW_REC, int fg, int bg, int flags, char *text, TEXT_DEST_REC
+"gui print text finished", WINDOW_REC
+"complete word", GList * of char*, WINDOW_REC, char *word, char *linestart, int *want_space
+"irssi init read settings"
+"exec new", PROCESS_REC
+"exec remove", PROCESS_REC, int status
+"exec input", PROCESS_REC, char *text
+"message public", SERVER_REC, char *msg, char *nick, char *address, char *target
+"message private", SERVER_REC, char *msg, char *nick, char *address, char *target
+"message own_public", SERVER_REC, char *msg, char *target
+"message own_private", SERVER_REC, char *msg, char *target, char *orig_target
+"message join", SERVER_REC, char *channel, char *nick, char *address
+"message part", SERVER_REC, char *channel, char *nick, char *address, char *reason
+"message quit", SERVER_REC, char *nick, char *address, char *reason
+"message kick", SERVER_REC, char *channel, char *nick, char *kicker, char *address, char *reason
+"message nick", SERVER_REC, char *newnick, char *oldnick, char *address
+"message own_nick", SERVER_REC, char *newnick, char *oldnick, char *address
+"message invite", SERVER_REC, char *channel, char *nick, char *address
+"message topic", SERVER_REC, char *channel, char *topic, char *nick, char *address
+"keyinfo created", KEYINFO_REC
+"keyinfo destroyed", KEYINFO_REC
+"print text", TEXT_DEST_REC *dest, char *text, char *stripped
+"theme created", THEME_REC
+"theme destroyed", THEME_REC
+"window hilight", WINDOW_REC
+"window dehilight", WINDOW_REC
+"window activity", WINDOW_REC, int old_level
+"window item hilight", WI_ITEM_REC
+"window item activity", WI_ITEM_REC, int old_level
+"window item new", WINDOW_REC, WI_ITEM_REC
+"window item remove", WINDOW_REC, WI_ITEM_REC
+"window item moved", WINDOW_REC, WI_ITEM_REC, WINDOW_REC
+"window item changed", WINDOW_REC, WI_ITEM_REC
+"window item server changed", WINDOW_REC, WI_ITEM_REC
+"window created", WINDOW_REC
+"window destroyed", WINDOW_REC
+"window changed", WINDOW_REC, WINDOW_REC old
+"window changed automatic", WINDOW_REC
+"window server changed", WINDOW_REC, SERVER_REC
+"window refnum changed", WINDOW_REC, int old
+"window name changed", WINDOW_REC
+"window history changed", WINDOW_REC, char *oldname
+"window level changed", WINDOW_REC
+"default event numeric", SERVER_REC, char *data, char *nick, char *address
+"message irc op_public", SERVER_REC, char *msg, char *nick, char *address, char *target
+"message irc own_wall", SERVER_REC, char *msg, char *target
+"message irc own_action", SERVER_REC, char *msg, char *target
+"message irc action", SERVER_REC, char *msg, char *nick, char *address, char *target
+"message irc own_notice", SERVER_REC, char *msg, char *target
+"message irc notice", SERVER_REC, char *msg, char *nick, char *address, char *target
+"message irc own_ctcp", SERVER_REC, char *cmd, char *data, char *target
+"message irc ctcp", SERVER_REC, char *cmd, char *data, char *nick, char *address, char *target
+"message irc mode", SERVER_REC, char *channel, char *nick, char *addr, char *mode
+"message dcc own", DCC_REC *dcc, char *msg
+"message dcc own_action", DCC_REC *dcc, char *msg
+"message dcc own_ctcp", DCC_REC *dcc, char *cmd, char *data
+"message dcc", DCC_REC *dcc, char *msg
+"message dcc action", DCC_REC *dcc, char *msg
+"message dcc ctcp", DCC_REC *dcc, char *cmd, char *data
+"gui key pressed", int key
+"beep"
+"gui print text after finished", WINDOW_REC, LINE_REC *line, LINE_REC *prev_line
+"gui textbuffer line removed", TEXTBUFFER_VIEW_REC *view, LINE_REC *line, LINE_REC *prev_line
+_END
+
+foreach my $sigline (split(/\n/, $signals)) {
+ my ($sig, @args) = split(/, /, $sigline);
+ $sig =~ y/"//d;
+ Irssi::signal_add_first($sig, sub {
+ signal_handler($sig, \@args, \@_);
+ }
+ );
+};
diff --git a/scripts/reorder.pl b/scripts/reorder.pl
index 7bec6b8..ce82fa4 100644
--- a/scripts/reorder.pl
+++ b/scripts/reorder.pl
@@ -1,150 +1,161 @@
-# Save window layout to an arbitrary file and load layouts upon demand
-# Useful for being able to temporarily reorder your windows and then reverting to your "normal" layout
-# Also useful as an easy way to reorder your windows
-#
-# A special thanks to billnye, Zed` and Bazerka for their help
-#
-# Usage:
-# /layout_save filename
-# Saves the layout to the textfile "filename.layout"
-# /layout_load filename
-# Loads the layout from the textfile "filename.layout"
-# /set layout_savepath path
-# Use to set a default path for layouts
-#
-# TODO:
-# Check the layout file for a number used twice
-#
-
-use strict;
-use Irssi;
-use Data::Dumper;
-use vars qw($VERSION %IRSSI);
-
-%IRSSI = (
- authors => "Isaac G",
- contact => "irssi\@isaac.otherinbox.com",
- name => "reorder",
- description => "Reordering windows based on a textfile.",
- license => "GPL",
-);
-
-sub doFilenameFixing
-{
- my ($filename) = @_;
- unless ($filename)
- {
- print "No filename specified!";
- return;
- }
-
- $filename = glob($filename);
-
- if ($filename =~ /\//)
- {
- unless ($filename =~ /^\//)
- {
- print "I don't like /'s in filenames. Unless you want to specify an absolute path.";
- return;
- }
- # Let it go?
- }
-
- $filename .= '.layout' unless ($filename =~ /.layout$/);
-
- my $path = Irssi::settings_get_str('layout_savepath');
- $path .= '/' unless ($path =~ /\/$/);
- $filename = $path . $filename unless ($filename =~ /\//);
-
- return $filename;
-}
-
-sub canReadFile
-{
- my ($filename) = @_;
- unless (-f $filename)
- {
- print "No such file $filename";
- return;
- }
- unless (-r $filename)
- {
- print "Can not read file $filename";
- return;
- }
- return 1;
-}
-
-# Save a list of refnum and window info to file
-sub cmd_layout_save
-{
- my ($filename, $data, $more) = @_;
- my $FH;
-
- $filename = doFilenameFixing($filename);
- return unless ($filename);
-
- unless(open $FH, ">", $filename)
- {
- print "Can not open $filename";
- return;
- }
-
- # Order by ref. Print ref and an id tag
- for my $win (sort {$a->{'refnum'} <=> $b->{'refnum'}} Irssi::windows())
- {
- my $id = $win->{'name'} ? $win->{'name'} : $win->{'active'}->{'name'} . ":" . $win->{'active'}->{'server'}->{'tag'};
- printf $FH "%d\t%s\n", $win->{'refnum'}, $id;
- }
- close $FH;
- print "Layout saved to $filename";
-}
-
-# Load a list and use it to reorder
-sub cmd_layout_load
-{
- # Check filename supplied, exists and readable
- my ($filename, $data, $more) = @_;
- $filename = doFilenameFixing($filename);
- return unless ($filename);
-
- return unless canReadFile($filename);
-
- my @layout;
- my ($ref, $id, $FH);
-
- # Pull the refnum and id
- unless(open $FH, "<", $filename)
- {
- print "Can not open file $filename.";
- return;
- }
- while (my $line = <$FH>)
- {
- chomp $line;
- my ($ref, $id) = split(/\t/, $line, 2);
- next unless ($ref and $id);
-
- push @layout, {refnum => $ref, id => $id};
- }
- close $FH;
-
- # For each layout item from the file, find the window and set it's ref to that number
- for my $position (sort {$a->{'refnum'} <=> $b->{'refnum'}} @layout)
- {
- for my $win (Irssi::windows())
- {
- $id = $win->{'name'} ? $win->{'name'} : $win->{'active'}->{'name'} . ":" . $win->{'active'}->{'server'}->{'tag'};
- if ($id eq $position->{'id'})
- {
- $win->set_refnum($position->{'refnum'});
- last;
- }
- }
- }
-}
-
-Irssi::settings_add_str('misc', 'layout_savepath', Irssi::get_irssi_dir());
-
-Irssi::command_bind( 'layout_save', 'cmd_layout_save' );
-Irssi::command_bind( 'layout_load', 'cmd_layout_load' ); \ No newline at end of file
+# Save window layout to an arbitrary file and load layouts upon demand
+# Useful for being able to temporarily reorder your windows and then reverting to your "normal" layout
+# Also useful as an easy way to reorder your windows
+#
+# A special thanks to billnye, Zed` and Bazerka for their help
+#
+# Usage:
+# /layout_save filename
+# Saves the layout to the textfile "filename.layout"
+# /layout_load filename
+# Loads the layout from the textfile "filename.layout"
+#
+# TODO:
+# Check the layout file for a number used twice
+# On script load, run a layout_load
+# On channel join, run load: channel joined
+#
+
+use strict;
+use Irssi;
+use Data::Dumper;
+use vars qw($VERSION %IRSSI);
+use POSIX 'strftime';
+
+%IRSSI = (
+ authors => "Isaac Good",
+ contact => "irssi\@isaacgood.com",
+ name => "reorder",
+ description => "Reordering windows based on a textfile.",
+ license => "GPL",
+);
+$VERSION = '1.0';
+
+# Map user input to a valid filename
+sub GetFilename
+{
+ my ($filename) = @_;
+
+ # On no input, use a default filename.
+ unless (length($filename))
+ {
+ my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
+ $filename = POSIX::strftime("%y%m%d", $sec, $min, $hour, $mday, $mon, $year);
+ # If you prefer not having datestamped filenames, uncomment:
+ # $filename = "default";
+ }
+
+ # Use glob expansion to match things like ~/
+ my $glob = glob($filename);
+ $filename = $glob if $glob;
+
+ # Only handle directories when using an absolute path.
+ if ($filename =~ /\// and $filename !~ /^\//)
+ {
+ print "I don't like /'s in filenames. Unless you want to specify an absolute path.";
+ return;
+ }
+
+ # Add a file extension
+ $filename .= '.layout' unless ($filename =~ /\.layout$/);
+
+ # Use get_irssi_dir() unless using an absolute path
+ if ($filename !~ /\//) {
+ my $path = Irssi::get_irssi_dir();
+ $path .= '/' unless ($path =~ /\/$/);
+ $filename = $path . $filename;
+ }
+
+ return $filename;
+}
+
+# Check a filename exists and can be read.
+sub CanReadFile
+{
+ my ($filename) = @_;
+ unless (-f $filename)
+ {
+ print "No such file $filename";
+ return 0;
+ }
+ unless (-r $filename)
+ {
+ print "Can not read file $filename";
+ return 0;
+ }
+ return 1;
+}
+
+# Save the current layout to file
+sub CmdLayoutSave
+{
+ my ($filename, $data, $more) = @_;
+ my $FH;
+
+ $filename = GetFilename($filename);
+ return unless ($filename);
+
+ unless(open $FH, ">", $filename)
+ {
+ print "Can not open $filename";
+ return;
+ }
+
+ # Order by ref. Print ref and an id tag
+ for my $win (sort {$a->{'refnum'} <=> $b->{'refnum'}} Irssi::windows())
+ {
+ my $id = $win->{'name'} ? $win->{'name'} : $win->{'active'}->{'name'};
+ my $tag = $win->{'active'}->{'server'}->{'tag'};
+ printf $FH "%d\t%s:%s\n", $win->{'refnum'}, $id, $tag;
+ }
+ close $FH;
+ print "Layout saved to $filename";
+}
+
+# Load a list and use it to reorder
+sub CmdLayoutLoad
+{
+ my ($filename, $data, $more) = @_;
+ $filename = GetFilename($filename);
+
+ return unless ($filename);
+ return unless CanReadFile($filename);
+
+ my @layout;
+ my ($ref, $id, $tag, $FH);
+
+ # Pull the refnum and id
+ unless(open $FH, "<", $filename)
+ {
+ print "Can not open file $filename.";
+ return;
+ }
+ while (my $line = <$FH>)
+ {
+ chomp $line;
+ my ($ref, $id) = split(/\t/, $line, 2);
+ next unless ($ref and $id);
+
+ push @layout, {refnum => $ref, id => $id};
+ }
+ close $FH;
+
+ # For each layout item from the file, find the window and set it's ref to that number
+ for my $position (sort {$a->{'refnum'} <=> $b->{'refnum'}} @layout)
+ {
+ for my $win (Irssi::windows())
+ {
+ $id = $win->{'name'} ? $win->{'name'} : $win->{'active'}->{'name'};
+ $tag = $win->{'active'}->{'server'}->{'tag'};
+ $id .= ":" . $tag;
+ if ($id eq $position->{'id'})
+ {
+ $win->set_refnum($position->{'refnum'});
+ last;
+ }
+ }
+ }
+}
+
+Irssi::command_bind( 'layout_save', 'CmdLayoutSave' );
+Irssi::command_bind( 'layout_load', 'CmdLayoutLoad' );
diff --git a/scripts/rud_emotes.pl b/scripts/rud_emotes.pl
index e783d75..de55cba 100644
--- a/scripts/rud_emotes.pl
+++ b/scripts/rud_emotes.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2015 Dawid Lekawski
+# Copyright (C) 2016 Dawid Lekawski
# contact: xxrud0lf@gmail.com
#
# --- INFORMATION ---
@@ -33,7 +33,7 @@
# notes:
#
# - script doesn't work with /msg target text; must be typed in a channel
-# or query window
+# or query window (from version 1.10 it works with /me command too)
#
# - Ctrl+O (ascii 15) at the beggining of your text turns off emote replacing
# for this text
@@ -41,20 +41,31 @@
# - remeber to escape "\" characters in emotes (just type it twice -> "\\"),
# take a look at 'shrug' emote for reference
#
+#
+#
+# -- CHANGES: --
+#
+# - script now works with /me command (action)
+#
+# - moved text output messages into nice and clean theme_register
+#
+#
use strict;
use warnings;
use utf8;
-use Irssi qw(signal_add signal_continue command_bind);
+use Irssi qw(signal_add signal_continue command_bind theme_register
+ printformat);
-our $VERSION = "1.00";
+our $VERSION = "1.10";
our %IRSSI = (
authors => "Dawid 'rud0lf' Lekawski",
contact => 'rud0lf/IRCnet; rud0lf/freenode; xxrud0lf@gmail.com',
name => 'emotes script',
description => 'Replaces :emote_name: text in your sent messages into pre-defined emotes (unicode mostly).',
- license => 'GPLv3'
+ license => 'GPLv3',
+ changed => 'Mon Nov 07 14:54:38 2016'
);
my $pattern = '';
@@ -94,10 +105,18 @@ my %emotes = (
'wink', 'โ—•โ€ฟโ†ผ',
'gift', '(ยดใƒปฯ‰ใƒป)ใฃ็”ฑ',
'success', '(โ€ขฬ€แด—โ€ขฬ)ูˆ',
- 'whatever', 'โ—”_โ—”'
+ 'whatever', 'โ—”_โ—”',
+ 'run', 'แ••(โš† ส–ฬฏโš†)แ•—',
+ 'rock', '(ใƒ„)\m/'
);
sub init {
+ theme_register([
+ 'rud_emotes_list', 'List of emotes:',
+ 'rud_emotes_emote', '* $[!15]0 : $1',
+ 'rud_emotes_total', 'Total of $0 emotes.'
+]);
+
$pattern = join('|', keys %emotes);
if ($pattern eq '') {
$pattern = '!?';
@@ -127,31 +146,28 @@ sub sig_send_text {
signal_continue($newline, $server, $witem);
}
-sub pad {
- my ($txt, $cnt) = @_;
+sub sig_command_me {
+ my ($line, $server, $witem) = @_;
- if (length($txt) >= $cnt) {
- return $txt;
- }
-
- $txt .= " " x ($cnt - length($txt));
- return $txt;
+ return unless ($witem);
+ return unless ($witem->{type} eq "CHANNEL" or $witem->{type} eq "QUERY");
+
+ my $newline = process_emotes($line);
+ signal_continue($newline, $server, $witem);
}
sub cmd_emotes {
my ($data, $server, $witem) = @_;
-
- Irssi::print('List of emotes:', MSGLEVEL_CLIENTCRAP);
+
+ printformat(MSGLEVEL_CLIENTCRAP, 'rud_emotes_list');
foreach my $key (sort(keys %emotes)) {
- my $emote = $emotes{$key};
- Irssi::print('* '. pad($key, 15) . ' : ' . $emote, MSGLEVEL_CLIENTCRAP);
+ printformat(MSGLEVEL_CLIENTCRAP, 'rud_emotes_emote', $key, $emotes{$key});
}
- Irssi::print('Total of '.scalar(keys %emotes).' emotes.', MSGLEVEL_CLIENTCRAP);
+ printformat(MSGLEVEL_CLIENTCRAP, 'rud_emotes_total', scalar(keys %emotes));
}
init();
signal_add("send text", "sig_send_text");
+signal_add("command me", "sig_command_me");
command_bind("emotes", "cmd_emotes");
-
-
diff --git a/scripts/trackbar22.pl b/scripts/trackbar22.pl
index 30015a2..6c899b6 100644
--- a/scripts/trackbar22.pl
+++ b/scripts/trackbar22.pl
@@ -96,7 +96,7 @@ use Encode;
use POSIX qw(strftime);
use vars qw($VERSION %IRSSI);
-$VERSION = "2.2"; # cb3189a33c8e5f9
+$VERSION = "2.3"; # 45c0adad4366edd
%IRSSI = (
authors => 'Peter Leurs and Geert Hauwaerts',
@@ -106,7 +106,6 @@ $VERSION = "2.2"; # cb3189a33c8e5f9
description => 'Shows a bar where you have last read a window.',
license => 'GNU General Public License',
url => 'http://www.pfoe.be/~peter/trackbar/',
- changed => 'Fri Jan 23 23:59:11 2004',
commands => 'trackbar',
);
@@ -234,6 +233,7 @@ sub add_one_trackbar {
$win->print(line($win->{width}), MSGLEVEL_NEVER);
$view->set_bookmark_bottom('trackbar');
$unseen_trackbar{ $win->{_irssi} } = 1;
+ Irssi::signal_emit("window trackbar added", $win);
$view->redraw;
}
@@ -253,6 +253,7 @@ sub win_ignored {
my $view = shift || $win->view;
return 1 unless $view->{buffer}{lines_count};
return 1 if $win->{name} eq '(status)' && !$config{use_status_window};
+ no warnings 'uninitialized';
return 1 if grep { $win->{name} eq $_ || $win->{refnum} eq $_
|| $win->get_active_name eq $_ } @{ $config{ignore_windows} };
return 0;
@@ -271,10 +272,13 @@ sub sig_window_changed {
sub trackbar_update_seen {
my $win = shift;
return unless $win;
+ return unless $unseen_trackbar{ $win->{_irssi} };
+
my $view = $win->view;
my $line = $view->get_bookmark('trackbar');
unless ($line) {
delete $unseen_trackbar{ $win->{_irssi} };
+ Irssi::signal_emit("window trackbar seen", $win);
return;
}
my $startline = $view->{startline};
@@ -283,6 +287,7 @@ sub trackbar_update_seen {
if ($startline->{info}{time} < $line->{info}{time}
|| $startline->{_irssi} == $line->{_irssi}) {
delete $unseen_trackbar{ $win->{_irssi} };
+ Irssi::signal_emit("window trackbar seen", $win);
}
}
@@ -477,6 +482,8 @@ update_config();
Irssi::signal_add_last( 'mainwindow resized' => 'redraw_trackbars')
unless $old_irssi;
+Irssi::signal_register({'window trackbar added' => [qw/Irssi::UI::Window/]});
+Irssi::signal_register({'window trackbar seen' => [qw/Irssi::UI::Window/]});
Irssi::signal_register({'gui page scrolled' => [qw/Irssi::UI::Window/]});
Irssi::signal_add_last('gui page scrolled' => 'trackbar_update_seen');
diff --git a/scripts/translit.pl b/scripts/translit.pl
index 478dd50..0a01506 100644
--- a/scripts/translit.pl
+++ b/scripts/translit.pl
@@ -1,7 +1,8 @@
use strict;
-use vars qw(%IRSSI);
+use vars qw(%IRSSI $VERSION);
use Irssi;
+$VERSION = "0.1";
%IRSSI = (
authors => 'dreg',
contact => 'dreg@fine.lv',
diff --git a/scripts/xdcc_autoget.pl b/scripts/xdcc_autoget.pl
index 16f4639..57bcf65 100644
--- a/scripts/xdcc_autoget.pl
+++ b/scripts/xdcc_autoget.pl
@@ -50,7 +50,7 @@ use File::Copy;
use Try::Tiny;
use vars qw($VERSION %IRSSI);
-$VERSION = "2.0";
+$VERSION = "2.1";
%IRSSI = (
name => "autoget",
description => "XDCC Autoget, for automated searching and downloading of xdcc packs",
@@ -143,7 +143,7 @@ sub ag_list
sub ag_initserver #init server
{
- Irssi::signal_remove("server connected", "ag_server");
+ Irssi::signal_remove("server connected", "ag_initserver");
$statusbarmessage = "Connected";
$server = $_[0];
if (!$runningflag) {Irssi::timeout_add_once(5000, sub { &ag_run; }, []);}
@@ -270,11 +270,11 @@ sub ag_search #searches bots for packs
$msgflag[$botcounter] = 0; #unset message flag so that ag_skip knows no important message has arrived
if($episodicflag)
{
- my $searchterm;
+ my $searchterm = $terms[$termcounter[$botcounter]];
my @words = split(/#/, $terms[$termcounter[$botcounter]]);
my $ep = sprintf("%.2d", $episode[$botcounter]);
if ($#words > 0){$searchterm = "$words[0]$ep$words[1]";}
- else {$searchterm = "$words[0] $ep";}
+ elsif ($words[0] ne $searchterm) {$searchterm = "$words[0] $ep";}
ag_message("msg $bots[$botcounter] $findprefix $searchterm" );
push(@{$totags[$botcounter]}, Irssi::timeout_add_once($botdelay * 1000, sub { ag_skip($botcounter); } , []));
@@ -323,9 +323,9 @@ sub ag_getpacks #if ($m =~ m{#(\d+):})
my @temp = split(/[#,]/, $message); #split up the message into 'words'
my $timeoutscleared = 0;
- my $newpackflag = 1;
foreach my $m (@temp) #find packs (#[NUMBER]: format)
{
+ my $newpackflag = 1;
if ($m =~ m/(\d+):(.+)/)
{
if (!$timeoutscleared) #reset timeouts if any packs are found
@@ -339,7 +339,7 @@ sub ag_getpacks #if ($m =~ m{#(\d+):})
my $filename = $2;
$filename =~ tr/[ ']/[__]/;
if ($n eq "$bots[$botcounter] $1" or $n eq $filename) {$newpackflag = 0;}
- last if ($n eq "$bots[$botcounter] $1");
+ last if ($n eq "$bots[$botcounter] $1" or $n eq $filename);
}
if($newpackflag){push(@{$packs[$botcounter]}, $1);} #push all new pack numbers to list of packs
}
@@ -650,7 +650,6 @@ sub ag_parserem #parses remove arguments for deletion from file
sub ag_add #add search terms
{
- ag_server;
my @args = quotewords('\s+', 0, $_[0]); #split arguments (words in brackets not seperated)
if ($#args < 0)
{
@@ -664,7 +663,6 @@ sub ag_add #add search terms
sub ag_rem #remove ssearch terms
{
- ag_server;
my @args = quotewords('\s+', 0, $_[0]);
if ($#args < 0)
{
@@ -678,7 +676,6 @@ sub ag_rem #remove ssearch terms
sub ag_botadd #add bots
{
- ag_server;
my @args = quotewords('\s+', 0, $_[0]);
if ($#args < 0)
{
@@ -692,7 +689,6 @@ sub ag_botadd #add bots
sub ag_botrem #remove bots
{
- ag_server;
my @args = quotewords('\s+', 0, $_[0]);
if ($#args < 0)
{