# Copyright (c) 2008 Duncan Fordyce # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. """ contains helper functions for common irc commands """ import logging import random PchumLog = logging.getLogger("pchumLogger") def msg(cli, user, msg): for line in msg.split("\n"): cli.send("PRIVMSG", user, ":%s" % line) def names(cli, *channels): tmp = __builtins__["list"](channels) msglist = [] while len(tmp) > 0: msglist.append(tmp.pop()) if len(",".join(msglist)) > 490: tmp.append(msglist.pop()) cli.send("NAMES %s" % (",".join(msglist))) msglist = [] if len(msglist) > 0: cli.send("NAMES %s" % (",".join(msglist))) def channel_list(cli): cli.send("LIST") def ping(cli, token): """Why is this called ping when it pongs..""" cli.send("PONG", token) def kick(cli, handle, channel, reason=""): cli.send("KICK {} {} {}".format(channel, handle, reason)) def mode(cli, channel, mode, options=None): PchumLog.debug("mode = " + str(mode)) PchumLog.debug("options = " + str(options)) cmd = "MODE {} {}".format(channel, mode) if options: cmd += " %s" % (options) cli.send(cmd) def ctcp(cli, handle, cmd, msg=""): # Space breaks protocol if msg is absent if msg == "": cli.send("PRIVMSG", handle, "\x01%s\x01" % (cmd)) else: cli.send("PRIVMSG", handle, "\x01{} {}\x01".format(cmd, msg)) def ctcp_reply(cli, handle, cmd, msg=""): notice(cli, str(handle), "\x01{} {}\x01".format(cmd.upper(), msg)) def metadata(cli, target, subcommand, *params): # IRC metadata draft specification # https://gist.github.com/k4bek4be/92c2937cefd49990fbebd001faf2b237 cli.send("METADATA", target, subcommand, *params) def cap(cli, subcommand, *params): # Capability Negotiation # https://ircv3.net/specs/extensions/capability-negotiation.html cli.send("CAP", subcommand, *params) def msgrandom(cli, choices, dest, user=None): o = "%s: " % user if user else "" o += random.choice(choices) msg(cli, dest, o) def _makeMsgRandomFunc(choices): def func(cli, dest, user=None): msgrandom(cli, choices, dest, user) return func def ns(cli, *args): msg(cli, "NickServ", " ".join(args)) def cs(cli, *args): msg(cli, "ChanServ", " ".join(args)) def identify(cli, passwd, authuser="NickServ"): msg(cli, authuser, "IDENTIFY %s" % passwd) def quit(cli, msg): cli.send("QUIT %s" % (msg)) def nick(cli, nick): cli.send("NICK", nick) def user(cli, username, realname): cli.send("USER", username, "0", "*", ":" + realname) def join(cli, channel): """Protocol potentially allows multiple channels or keys.""" cli.send("JOIN", channel) def part(cli, channel): cli.send("PART", channel) def notice(cli, target, text): cli.send("NOTICE", target, text) def invite(cli, nick, channel): cli.send("INVITE", nick, channel) def _addNumerics(): import sys from oyoyo import ircevents def numericcmd(cmd_num, cmd_name): def f(cli, *args): cli.send(cmd_num, *args) return f m = sys.modules[__name__] for num, name in ircevents.numeric_events.items(): setattr(m, name, numericcmd(num, name)) #_addNumerics()