PESTERCHUM: via TAGMSG (incl. Client Capability Negotiation + Message Tags)
This commit is contained in:
parent
91b09e270d
commit
979173c33d
5 changed files with 79 additions and 4 deletions
41
irc.py
41
irc.py
|
@ -23,6 +23,11 @@ PchumLog = logging.getLogger('pchumLogger')
|
|||
# Python 3
|
||||
QString = str
|
||||
|
||||
# Copied from pesterchum.py
|
||||
CUSTOMBOTS = ["CALSPRITE", "RANDOMENCOUNTER"]
|
||||
BOTNAMES = ["NICKSERV", "CHANSERV", "MEMOSERV", "OPERSERV", "HELPSERV", "HOSTSERV", "BOTSERV"]
|
||||
BOTNAMES.extend(CUSTOMBOTS)
|
||||
|
||||
#if ostools.isOSXBundle():
|
||||
# logging.basicConfig(level=logging.WARNING)
|
||||
#else:
|
||||
|
@ -400,6 +405,33 @@ class PesterHandler(DefaultCommandHandler):
|
|||
mood = Mood(int(value))
|
||||
self.parent.moodUpdated.emit(nick, mood)
|
||||
|
||||
def tagmsg(self, prefix, tags, *args):
|
||||
PchumLog.info('TAGMSG: %s %s %s' % (prefix, tags, str(args)))
|
||||
message_tags = tags[1:].split(';')
|
||||
for m in message_tags:
|
||||
if m.startswith("+pesterchum"):
|
||||
# Pesterchum tag
|
||||
try:
|
||||
key, value = m.split('=')
|
||||
except ValueError:
|
||||
return
|
||||
PchumLog.info('Pesterchum tag: %s=%s' % (key, value))
|
||||
# Uses PESTERCHUM: syntax?
|
||||
if ((value.upper().startswith("BEGIN") == False)
|
||||
& (value.upper().startswith("BLOCK") == False)
|
||||
& (value.upper().startswith("CEASE") == False)
|
||||
& (value.upper().startswith("TIME") == False)):
|
||||
# Invalid syntax
|
||||
PchumLog.warning("TAGMSG with invalid syntax.")
|
||||
return
|
||||
|
||||
# Process like it's a PESTERCHUM: message
|
||||
# Easiest option since we gotta be backwards compatible anyway :"3
|
||||
msg = "PESTERCHUM:" + value
|
||||
self.privmsg(prefix, args[0], msg)
|
||||
|
||||
|
||||
|
||||
def privmsg(self, nick, chan, msg):
|
||||
handle = nick[0:nick.find("!")]
|
||||
if len(msg) == 0:
|
||||
|
@ -496,6 +528,8 @@ class PesterHandler(DefaultCommandHandler):
|
|||
# Backwards compatible moods
|
||||
helpers.msg(self.client, "#pesterchum", "MOOD >%d" % (mymood))
|
||||
|
||||
helpers.cap(self.client, "REQ", "message-tags")
|
||||
|
||||
def keyvalue(self, target, handle_us, handle_owner, key, visibility, *value):
|
||||
# The format of the METADATA server notication is:
|
||||
# METADATA <Target> <Key> <Visibility> <Value>
|
||||
|
@ -734,6 +768,13 @@ class PesterHandler(DefaultCommandHandler):
|
|||
# Try to get mood via metadata get.
|
||||
# If it fails the old code is excecuted.
|
||||
|
||||
# If services/bot, assume mood 18.
|
||||
for c in chums:
|
||||
if c.handle.upper() in BOTNAMES:
|
||||
print("True")
|
||||
print(c.handle)
|
||||
PchumLog.info("%s is a bot, setting mood to 18." % (c.handle))
|
||||
self.parent.moodUpdated.emit(c.handle, Mood(18))
|
||||
# Wait for server to send welcome to verify RPL_ISUPPORT has been send.
|
||||
# Apparently 005 is send after 001 so nvm we gotta wait longer :"3
|
||||
timeout = 0
|
||||
|
|
|
@ -234,8 +234,12 @@ class IRCClient:
|
|||
|
||||
for el in data:
|
||||
PchumLog.debug("el=%s, data=%s" % (el,data))
|
||||
prefix, command, args = parse_raw_irc_command(el)
|
||||
tags, prefix, command, args = parse_raw_irc_command(el)
|
||||
try:
|
||||
# Only need tags with tagmsg
|
||||
if command.upper() == "TAGMSG":
|
||||
self.command_handler.run(command, prefix, tags, *args)
|
||||
else:
|
||||
self.command_handler.run(command, prefix, *args)
|
||||
except CommandError as e:
|
||||
PchumLog.debug("CommandError %s" % str(e))
|
||||
|
|
|
@ -71,6 +71,11 @@ def metadata(cli, target, subcommand, *params):
|
|||
# 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)
|
||||
|
|
|
@ -215,7 +215,8 @@ protocol_events = [
|
|||
"quit",
|
||||
"invite",
|
||||
"pong",
|
||||
"metadata" # Metadata specification
|
||||
"metadata", # Metadata specification
|
||||
"tagmsg", # IRCv3 message tags extension
|
||||
]
|
||||
|
||||
all_events = generated_events + protocol_events + list(numeric_events.values())
|
||||
|
|
|
@ -26,6 +26,7 @@ logging.config.fileConfig(_datadir + "logging.ini")
|
|||
PchumLog = logging.getLogger('pchumLogger')
|
||||
|
||||
def parse_raw_irc_command(element):
|
||||
print(element)
|
||||
"""
|
||||
This function parses a raw irc command and returns a tuple
|
||||
of (prefix, command, args).
|
||||
|
@ -43,6 +44,21 @@ def parse_raw_irc_command(element):
|
|||
NUL or CR or LF>
|
||||
|
||||
<crlf> ::= CR LF
|
||||
"""
|
||||
"""
|
||||
When message-tags are enabled, the message pseudo-BNF,
|
||||
as defined in RFC 1459, section 2.3.1 is extended as follows:
|
||||
|
||||
<message> ::= ['@' <tags> <SPACE>] [':' <prefix> <SPACE> ] <command> [params] <crlf>
|
||||
<tags> ::= <tag> [';' <tag>]*
|
||||
<tag> ::= <key> ['=' <escaped_value>]
|
||||
<key> ::= [ <client_prefix> ] [ <vendor> '/' ] <key_name>
|
||||
<client_prefix> ::= '+'
|
||||
<key_name> ::= <non-empty sequence of ascii letters, digits, hyphens ('-')>
|
||||
<escaped_value> ::= <sequence of zero or more utf8 characters except NUL, CR, LF, semicolon (`;`) and SPACE>
|
||||
<vendor> ::= <host>
|
||||
|
||||
|
||||
"""
|
||||
|
||||
try:
|
||||
|
@ -53,10 +69,18 @@ def parse_raw_irc_command(element):
|
|||
|
||||
parts = element.strip().split(" ")
|
||||
if parts[0].startswith(':'):
|
||||
tags = None
|
||||
prefix = parts[0][1:]
|
||||
command = parts[1]
|
||||
args = parts[2:]
|
||||
elif parts[0].startswith('@'):
|
||||
# Message tag
|
||||
tags = parts[0]
|
||||
prefix = parts[1][1:]
|
||||
command = parts[2]
|
||||
args = parts[3:]
|
||||
else:
|
||||
tags = None
|
||||
prefix = None
|
||||
command = parts[0]
|
||||
args = parts[1:]
|
||||
|
@ -76,7 +100,7 @@ def parse_raw_irc_command(element):
|
|||
args = args[:idx] + [" ".join(args[idx:])[1:]]
|
||||
break
|
||||
|
||||
return (prefix, command, args)
|
||||
return (tags, prefix, command, args)
|
||||
|
||||
|
||||
def parse_nick(name):
|
||||
|
|
Loading…
Reference in a new issue