aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/quarg/quassel/formatter.py
diff options
context:
space:
mode:
Diffstat (limited to 'quarg/quassel/formatter.py')
-rw-r--r--quarg/quassel/formatter.py139
1 files changed, 139 insertions, 0 deletions
diff --git a/quarg/quassel/formatter.py b/quarg/quassel/formatter.py
new file mode 100644
index 0000000..1297288
--- /dev/null
+++ b/quarg/quassel/formatter.py
@@ -0,0 +1,139 @@
+import datetime
+
+# from functools import partial
+from typing import NamedTuple
+from quarg.quassel.types import MessageType
+
+class User(NamedTuple):
+ nick: str
+ host: str
+ prefix: str
+
+ @classmethod
+ def from_sender(cls, sender, prefixes=''):
+ nick, *host = sender.split('!', 1)
+ prefix = prefixes[0] if prefixes else ''
+ return cls(nick, host[0] if host else '', prefix)
+
+ def __repr__(self):
+ return f'{self.prefix}{self.nick}'
+
+class Message(NamedTuple):
+ type: MessageType
+ time: datetime.datetime
+ buffer: str
+ user: User
+ message: str
+
+ @classmethod
+ def from_backlog(cls, backlog):
+ return cls(MessageType(backlog.type), backlog.time, backlog.buffer.buffername,
+ User.from_sender(backlog.sender.sender, backlog.senderprefixes), backlog.message)
+
+def format_from(backlog_row):
+ message = Message.from_backlog(backlog_row)
+ formatter = FORMATTERS[message.type]
+ timestamp = message.time.isoformat(sep=' ', timespec='seconds')
+
+ return f'{timestamp}\t{message.buffer}\t{formatter(message)}'
+
+def format_privmsg(msg):
+ return f'<{msg.user}> {msg.message}'
+
+def format_notice(msg):
+ return f'[{msg.user}] {msg.message}'
+
+def format_action(msg):
+ return f'-*- {msg.user} {msg.message}'
+
+def format_nick(msg):
+ return f'<-> {msg.user} is now known as {msg.message}'
+
+def format_mode(msg):
+ return f'*** Mode {msg.message} by {msg.user}'
+
+def format_join(msg):
+ return f'--> {msg.user} ({msg.user.host}) has joined {msg.buffer}'
+
+def format_part(msg):
+ if msg.message:
+ return f'<-- {msg.user} has left {msg.buffer} ({msg.message})'
+
+ return f'<-- {msg.user} has left {msg.buffer}'
+
+def format_quit(msg):
+ if msg.message:
+ return f'<-- {msg.user} has quit ({msg.message})'
+
+ return f'<-- {msg.user} has quit'
+
+def format_kick(msg):
+ target, *kickmsg = msg.message.split(' ', 1)
+
+ if kickmsg:
+ return f'<-* {msg.user} has kicked {target} from {msg.buffer} ({kickmsg[0]})'
+
+ return f'<-* {msg.user} has kicked {target} from {msg.buffer}'
+
+def format_kill(msg):
+ # pylint: disable=line-too-long
+
+ # As of 2021-04-24 not even Quassel implements printing this message [1].
+ # They do have a symbol [2] for it, however, so use that along with the message
+ # [1] https://github.com/quassel/quassel/blob/285215315e6f2420724532323a4b1bccae156cb1/src/uisupport/uistyle.cpp#L950
+ # [2] https://github.com/quassel/quassel/blob/285215315e6f2420724532323a4b1bccae156cb1/src/uisupport/uistyle.cpp#L1079-L1080
+ return f'<-x {msg.message}'
+
+def format_generic(msg):
+ return f'* {msg.message}'
+
+def parse_netsplit(splitmsg):
+ # splitmsg contains user!host separated by #:# ...
+ elements = splitmsg.split('#:#')
+
+ # ... however, the last element contains the split servers instead
+ servers = elements.pop().split(' ', 1)
+
+ # TODO: This takes ages if the netsplit was large
+ users = [User.from_sender(e) for e in elements]
+
+ return users, servers
+
+def format_netsplit_join(msg):
+ users, (srv_left, srv_right) = parse_netsplit(msg.message)
+ have_joined = ', '.join(user.nick for user in users)
+ return f'=> Netsplit between {srv_left} and {srv_right} ended. Users joined: {have_joined}'
+
+def format_netsplit_quit(msg):
+ users, (srv_left, srv_right) = parse_netsplit(msg.message)
+ have_quit = ', '.join(user.nick for user in users)
+ return f'<= Netsplit between {srv_left} and {srv_right}. Users quit: {have_quit}'
+
+# TODO inline the format strings here and have a wrapper function that gives msg?
+# TODO also <string>.format(**msg)
+
+def format_from_string(string, msg):
+ return string.format(**msg._asdict())
+
+# MessageType.PART: partial(format_from_string, '<-- {user} has left {buffer}'),
+
+FORMATTERS = {
+ MessageType.PRIVMSG: format_privmsg,
+ MessageType.NOTICE: format_notice,
+ MessageType.ACTION: format_action,
+ MessageType.NICK: format_nick,
+ MessageType.MODE: format_mode,
+ MessageType.JOIN: format_join,
+ MessageType.PART: format_part,
+ MessageType.QUIT: format_quit,
+ MessageType.KICK: format_kick,
+ MessageType.KILL: format_kill,
+ MessageType.SERVER: format_generic,
+ MessageType.INFO: format_generic,
+ MessageType.ERROR: format_generic,
+ MessageType.DAYCHANGE: format_generic,
+ MessageType.TOPIC: format_generic,
+ MessageType.NETSPLIT_JOIN: format_netsplit_join,
+ MessageType.NETSPLIT_QUIT: format_netsplit_quit,
+ MessageType.INVITE: format_generic,
+}