Add support for the ZNC Playback module.
Author: jazzpi
— Version: 0.2.2
— License: GPL-3.0-or-later
For WeeChat ≥ 0.3.2.
Tags: irc, znc, py2, py3
Added: 2016-10-30
— Updated: 2022-02-05
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | # -*- coding: utf-8 -*- # # Copyright (C) 2016 Jasper v. Blanckenburg <jasper@mezzo.de> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # # # Play back all messages the ZNC bouncer received since you last received a # message locally # (this requires the Playback module to be loaded on ZNC) # # Add znc.in/playback either to irc.server_default.capabilites or # to the servers you want to use the Playback module on, then set # plugins.var.python.zncplayback.servers # # History: # # 2022-02-02, Andreas Hackl <a@r0.at>: # v0.2.2: handle invalid json in SCRIPT_SAVEFILE # 2021-05-06, Sébastien Helleu <flashcode@flashtux.org>: # v0.2.1: add compatibility with WeeChat >= 3.2 (XDG directories) # 2019-07-09, Alyssa Ross <hi@alyssa.is>: # v0.2.0: Make script compatible with Python 3 # 2016-08-27, Jasper v. Blanckenburg <jasper@mezzo.de>: # v0.1.0: Initial release from __future__ import print_function SCRIPT_NAME = "zncplayback" SCRIPT_AUTHOR = "jazzpi" SCRIPT_VERSION = "0.2.2" SCRIPT_LICENSE = "GPL3" SCRIPT_DESCRIPTION = "Add support for the ZNC Playback module" SCRIPT_SAVEFILE = "zncplayback_times.json" import_ok = True try: import weechat except ImportError: print("This script must be run under WeeChat.") print("Get WeeChat now at: http://www.weechat.org/") import_ok = False try: import json import os.path as path from time import time except ImportError as message: print("Missing package(s) for {}: {}".format(SCRIPT_NAME, message)) import_ok = False # Script options zncplayback_settings_default = { "servers": ( "", "Comma-separated list of servers that playback should be fetched for") } zncplayback_settings = {} zncplayback_hooks = { "config": None, "connected": None, "messages": {} } zncplayback_last_times = {} def write_last_times(): """Write the last message times of all servers to disk.""" with open(SCRIPT_SAVEFILE, "w") as fh: json.dump(zncplayback_last_times, fh) def read_last_times(): """Read the last message times of all servers from disk.""" global zncplayback_last_times try: with open(SCRIPT_SAVEFILE, "r") as fh: zncplayback_last_times = json.load(fh) except (json.decoder.JSONDecodeError,FileNotFoundError): for server in zncplayback_settings["servers"].split(","): zncplayback_last_times[server] = 0 def zncplayback_config_cb(data, option, value): """Update in-memory settings when a script option is changed.""" global zncplayback_settings pos = option.rfind(".") if pos > 0: name = option[pos+1:] if name in zncplayback_settings: if name == "servers": old_servers = zncplayback_settings["servers"].split(",") new_servers = value.split(",") # Unhook signals for old servers removed_servers = \ [s for s in old_servers if s not in new_servers] for serv in removed_servers: weechat.unhook(zncplayback_hooks["messages"][serv]) del zncplayback_last_times[serv] # Hook signals for new servers added_servers = \ [s for s in new_servers if s not in old_servers] for serv in added_servers: zncplayback_hooks["messages"][serv] = weechat.hook_signal( "{},irc_raw_in_PRIVMSG".format(serv), "zncplayback_message_cb", serv) zncplayback_last_times[serv] = 0 zncplayback_settings[name] = value return weechat.WEECHAT_RC_OK def zncplayback_connected_cb(data, signal, server): """Fetch playback after connecting to a server.""" if server not in zncplayback_settings["servers"].split(","): return weechat.WEECHAT_RC_OK buf = weechat.buffer_search("irc", "server.{}".format(server)) weechat.command(buf, "/msg *playback PLAY * {}".format(zncplayback_last_times[server])) return weechat.WEECHAT_RC_OK def zncplayback_message_cb(server, signal, message): """Update last time for a server when a PRIVMSG is sent.""" global zncplayback_last_times if server not in zncplayback_settings["servers"].split(","): return weechat.WEECHAT_RC_OK zncplayback_last_times[server] = int(time()) write_last_times() return weechat.WEECHAT_RC_OK if __name__ == "__main__" and import_ok: if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESCRIPTION, "", ""): options = { 'directory': 'data', } SCRIPT_SAVEFILE = weechat.string_eval_path_home( '%%h/%s' % SCRIPT_SAVEFILE, {}, {}, options, ) # Set default settings version = weechat.info_get("version_number", "") or 0 for option, value in list(zncplayback_settings_default.items()): if weechat.config_is_set_plugin(option): zncplayback_settings[option] = weechat.config_get_plugin( option) else: weechat.config_set_plugin(option, value[0]) zncplayback_settings[option] = value[0] if int(version) >= 0x00030500: weechat.config_set_desc_plugin( option, "%s (default: \"%s\")" % (value[1], value[0])) read_last_times() zncplayback_hooks["config"] = weechat.hook_config( "plugins.var.python.%s.*" % SCRIPT_NAME, "zncplayback_config_cb", "") zncplayback_hooks["connected"] = weechat.hook_signal( "irc_server_connected", "zncplayback_connected_cb", "") for serv in zncplayback_settings["servers"].split(","): zncplayback_hooks["messages"][serv] = weechat.hook_signal( "{},irc_raw_in_PRIVMSG".format(serv), "zncplayback_message_cb", serv) # TODO: Unhook when unloading script |