From 5efb17b2abdc8b7477e6ece15b891fee88f7dd8e Mon Sep 17 00:00:00 2001 From: luk3yx Date: Thu, 21 Apr 2022 08:18:00 +1200 Subject: Initial commit --- .gitignore | 61 ++++++++++++++++++++++++++++++++++++++++++ LICENSE.md | 22 +++++++++++++++ miniirc_idc.py | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE.md create mode 100644 miniirc_idc.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b761e43 --- /dev/null +++ b/.gitignore @@ -0,0 +1,61 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Mypy +.mypy_cache/ diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..51991fb --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,22 @@ + +# The MIT License (MIT) + +Copyright © 2022 by luk3yx + +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. diff --git a/miniirc_idc.py b/miniirc_idc.py new file mode 100644 index 0000000..45d7757 --- /dev/null +++ b/miniirc_idc.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 +# +# This is very horrible and quickly written +# But it works +# + +import datetime, miniirc, re +assert miniirc.ver >= (1,8,1) + + +_LEADING_COLON = '' if miniirc.ver[0] > 2 else ':' +_esc_re = re.compile(r'\\(.)|\t') + + +idc_to_irc = { + #'MESSAGE': 'PRIVMSG', + 'RPL_LOGIN_GOOD': '001', +} + + +class IDC(miniirc.IRC): + def idc_message_parser(self, msg): + args = _esc_re.sub(lambda m: m.group(1) or '\udeff', msg).split('\udeff') + + command = args.pop(0).upper() + tags = {} + if command == 'PRIVMSG': + dt = datetime.datetime.utcfromtimestamp(float(args[0])) + tags['time'] = dt.isoformat() + 'Z' + hostmask = (args[1], args[1], f'idc/{args[1]}') + args = [self.current_nick, args[2]] + else: + hostmask = ('', '', '') + + if args and _LEADING_COLON: + args[-1] = _LEADING_COLON + args[-1] + return idc_to_irc.get(command, command), hostmask, tags, args + + # Send raw messages + def idc_send(self, *args): + line = '\t'.join(arg.replace('\\', '\\\\').replace('\t', '\\\t') + for arg in args) + super().quote(line, force=True) + + if miniirc.ver < (2, 0, 0): + @property + def _sock(self): + return self.sock + + def quote(self, *msg, force=None, tags=None) -> None: + cmd, _, tags2, args = miniirc.ircv3_message_parser(' '.join(msg)) + if miniirc.ver[0] < 2 and args and args[-1].startswith(':'): + args[-1] = args[-1][1:] + self.send(cmd, *args, force=force, tags=tags or tags2) + + def _get_idc_account(self): + if isinstance(self.ns_identity, tuple): + return self.ns_identity + else: + return self.ns_identity.split(' ', 1) + + @property + def current_nick(self): + return self._get_idc_account()[0] + + def send(self, cmd, *args, force=None, tags=None) -> None: + cmd = cmd.upper() + if cmd in ('PRIVMSG', 'NOTICE'): + target = args[0] + # TODO: Make miniirc think that SASL worked PMs to NickServ don't + # have to be blocked. + if target == 'NickServ': + return + self.idc_send('CHANMSG' if target.startswith('#') else 'PRIVMSG', + *args) + elif cmd in ('PING', 'QUIT'): + self.idc_send(cmd, *args) + elif cmd == 'USER': + user, password = self._get_idc_account() + self.idc_send('USER', user, password) + + # Override the message parser to change the default parser. + def change_parser(self, parser=None): + super().change_parser(parser or self.idc_message_parser) -- cgit v1.2.3