changeset 27:adf0280f5544

relay: initial import
author David Demelier <markand@malikania.fr>
date Wed, 04 Sep 2019 11:19:50 +0200
parents 0ace9be8d836
children 103a9f976cc8
files CMakeLists.txt relay/CMakeLists.txt relay/relay.7 relay/relay.js
diffstat 4 files changed, 311 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Wed Sep 04 21:00:00 2019 +0200
+++ b/CMakeLists.txt	Wed Sep 04 11:19:50 2019 +0200
@@ -21,6 +21,6 @@
 
 find_package(irccd REQUIRED)
 
-foreach(p karma quote)
+foreach(p karma quote relay)
 	add_subdirectory(${p})
 endforeach ()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/relay/CMakeLists.txt	Wed Sep 04 11:19:50 2019 +0200
@@ -0,0 +1,24 @@
+#
+# CMakeLists.txt -- CMake build system for irccd-plugins
+#
+# Copyright (c) 2013-2019 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+irccd_define_plugin(
+	NAME relay
+	TYPE JS
+	SCRIPT relay.js
+	MAN relay.7
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/relay/relay.7	Wed Sep 04 11:19:50 2019 +0200
@@ -0,0 +1,136 @@
+.\"
+.\" Copyright (c) 2013-2019 David Demelier <markand@malikania.fr>
+.\"
+.\" Permission to use, copy, modify, and/or distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd @IRCCD_MAN_DATE@
+.Dt IRCCD-PLUGIN-RELAY 7
+.Os
+.\" NAME
+.Sh NAME
+.Nm relay
+.Nd irccd relay plugin
+.\" DESCRIPTION
+.Sh DESCRIPTION
+The
+.Nm
+plugin links two channels together by sending appropriate joins, parts and
+messages between the two. It is useful when a new channel is meant to replace
+an other one but people are still on the older one.
+.\" INSTALLATION
+.Sh INSTALLATION
+The plugin
+.Nm
+is distributed with irccd-plugins. To enable it add the following to your
+plugins section:
+.Pp
+.Bd -literal
+[plugins]
+relay = ""
+.Ed
+.\" USAGE
+.Sh USAGE
+The plugin has no invocation and must be configured before use.
+.\" CONFIGURATION
+.Sh CONFIGURATION
+The following options are available under the
+.Va [plugin.relay]
+section:
+.Bl -tag -width 30n -offset Ds
+.It Va prefix.link1 No (string)
+The first server/channel combination in the form
+.Dq channel@server
+.It Va prefix.link2 No (string)
+The second combination, similar to link1.
+.It Va prefix.join-action No (string)
+The action upon join events. Can be
+.Dq notice
+or
+.Dq message .
+.It Va prefix.me-action No (string)
+The action upon CTCP action events (/me). Can be
+.Dq notice
+or
+.Dq message .
+.It Va prefix.message-action No (string)
+The action upon message events. Can be
+.Dq notice
+or
+.Dq message .
+.It Va prefix.part-action No (string)
+The action upon part events. Can be
+.Dq notice
+or
+.Dq message .
+.El
+.Pp
+The
+.Va prefix
+before the option keys is used to distinguish several relay configurations, it
+can be an arbitrary string. See examples below.
+.\" TEMPLATES
+.Sh TEMPLATES
+The
+.Nm
+plugin supports the following templates in
+.Va [templates.relay]
+section:
+.Bl -tag -width 10n -offset Ds
+.It Va join
+When someone joins a channel.
+.It Va me
+When someone sends a CTCP action (/me). Keywords:
+.Em message .
+.It Va message
+When someone sends a message. Keywords:
+.Em message .
+.It Va part
+When someone leaves a channel.
+.El
+.Pp
+All templates support the following standard keywords:
+.Em channel , nickname , origin , server .
+.\" EXAMPLES
+.Sh EXAMPLES
+In the following example, we will link the channel #oldchannel from the server
+wanadoo to the channel #newchannel on the server red.
+.Bd -literal
+[server]
+name = wanadoo
+channels = "#oldchannel"
+
+[server]
+name = red
+channels = "#newchannel"
+
+[plugin.relay]
+abc.link1 = "#oldchannel@wanadoo"
+abc.link2 = "#newchannel@red"
+.Ed
+.Pp
+If you prefer messages rather than notices for join and part events, use:
+.Bd -literal
+[plugin.relay]
+abc.join-action = message
+abc.part-action = message
+.Ed
+.Pp
+And configuring the templates:
+.Bd -literal
+[templates.relay]
+message = "<#{channel} on #{server}> #{nickname}: #{message}"
+.Ed
+.\" SEE ALSO
+.Sh SEE ALSO
+.Xr irccd 1 ,
+.Xr irccd-templates 7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/relay/relay.js	Wed Sep 04 11:19:50 2019 +0200
@@ -0,0 +1,150 @@
+/*
+ * relay.js -- link two channels together
+ *
+ * Copyright (c) 2016-2018 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+var Logger = Irccd.Logger;
+var Plugin = Irccd.Plugin;
+var Server = Irccd.Server;
+var Util = Irccd.Util;
+
+info = {
+	summary: "Link two channels together",
+	version: "0.1-dev",
+	license: "ISC",
+	author: "David Demelier <markand@malikania.fr>"
+};
+
+Plugin.templates = {
+	"join":         "[@{cyan}#{channel}@#{server}@{}] #{nickname} joined #{channel}",
+	"me":           "[@{cyan}#{channel}@#{server}@{}] * #{nickname} #{message}",
+	"message":      "[@{cyan}#{channel}@#{server}@{}] #{nickname}: #{message}",
+	"part":         "[@{cyan}#{channel}@#{server}@{}] #{nickname} left #{channel}"
+};
+
+function isLinked(server, channel, value)
+{
+	return value === channel + "@" + server.toString();
+}
+
+function split(value)
+{
+	return value.split("@");
+}
+
+function get(server, channel, prefix)
+{
+	var object = {
+		"join-action": "notice",
+		"me-action": "message",
+		"message-action": "message",
+		"part-action": "notice"
+	};
+
+	var link1 = Plugin.config[prefix + ".link1"];
+	var link2 = Plugin.config[prefix + ".link2"];
+
+	if (Plugin.config[prefix + ".join-action"])
+		object["join-action"] = Plugin.config[prefix + ".join-action"];
+	if (Plugin.config[prefix + ".me-action"])
+		object["me-action"] = Plugin.config[prefix + ".me-action"];
+	if (Plugin.config[prefix + ".message-action"])
+		object["message-action"] = Plugin.config[prefix + ".message-action"];
+	if (Plugin.config[prefix + ".part-action"])
+		object["part-action"] = Plugin.config[prefix + ".part-action"];
+
+	// Determine from/to.
+	if (isLinked(server, channel, link1)) {
+		object["from"] = [ server.toString(), channel ];
+		object["to"] = split(link2);
+	} else {
+		object["from"] = [ server.toString(), channel ];
+		object["to"] = split(link1);
+	}
+
+	// Ensure the object is complete.
+	if (object.from.length !== 2 || object.to.length !== 2)
+		Logger.warning("missing link1/link2 parameters");
+
+	return object;
+}
+
+function find(server, channel)
+{
+	for (var key in Plugin.config) {
+		var value = Plugin.config[key];
+
+		if ((key.endsWith(".link1") && isLinked(server, channel, value)) ||
+		    (key.endsWith(".link2") && isLinked(server, channel, value)))
+			return get(server, channel, key.replace(/\.link[12]$/, ""));
+	}
+}
+
+function keywords(server, origin, channel, extra)
+{
+	var object = {
+		server: server.toString(),
+		channel: channel,
+		origin: origin,
+		nickname: Util.splituser(origin)
+	};
+		
+	return Object.assign(object, extra);
+}
+
+function perform(server, origin, channel, key, extrakw)
+{
+	var link = find(server, channel);
+
+	if (!link)
+		return;
+
+	var destination = Server.find(link.to[1]);
+
+	if (destination) {
+		var fmt = Plugin.templates[key];
+		var kw = keywords(server, origin, channel, extrakw);
+
+		if (link[key + "-action"] === "message")
+			destination.message(link.to[0], Util.format(fmt, kw));
+		else
+			destination.notice(link.to[0], Util.format(fmt, kw));
+	}
+}
+
+function onJoin(server, origin, channel)
+{
+	perform(server, origin, channel, "join")
+}
+
+function onMe(server, origin, channel, message)
+{
+	perform(server, origin, channel, "me", {
+		message: message
+	});
+}
+
+function onMessage(server, origin, channel, message)
+{
+	perform(server, origin, channel, "message", {
+		message: message
+	});
+}
+
+function onPart(server, origin, channel)
+{
+	perform(server, origin, channel, "part")
+}