Add exclam module to handle channel/chat commands begining with exclamation mark (!)
patch 5b2c938f7967a3345435fe21b2127999d0975f50
Author: E. Bosch <presidev@AT@gmail.com>
Date: Mon Jun 26 00:17:22 CEST 2023
* Add exclam module to handle channel/chat commands begining with exclamation mark (!)
Implement reply (!re) as first exclam command
diff -rN -u old-irgramd/exclam.py new-irgramd/exclam.py
--- old-irgramd/exclam.py 1970-01-01 01:00:00.000000000 +0100
+++ new-irgramd/exclam.py 2024-05-18 08:59:50.985377264 +0200
@@ -0,0 +1,49 @@
+# irgramd: IRC-Telegram gateway
+# exclam.py: IRC exclamation command handlers
+#
+# Copyright (c) 2023 E. Bosch <presidev@AT@gmail.com>
+#
+# Use of this source code is governed by a MIT style license that
+# can be found in the LICENSE file included in this project.
+
+from utils import command, HELP
+
+class exclam(command):
+ def __init__(self, telegram):
+ self.commands = \
+ { # Command Handler Arguments Min Max Maxsplit
+ '!re': (self.handle_command_re, 2, 2, 2),
+ }
+ self.tg = telegram
+ self.irc = telegram.irc
+ self.tmp_ircnick = None
+ self.tmp_telegram_id = None
+ self.tmp_tg_msg = None
+
+ async def command(self, message, telegram_id, user):
+ self.tmp_telegram_id = telegram_id
+ res = await self.parse_command(message, nick=None)
+ if isinstance(res, tuple):
+ await self.irc.send_msg(self.irc.service_user, None, res[0], user)
+ res = False
+ return res, self.tmp_tg_msg
+
+ async def handle_command_re(self, cid=None, msg=None, help=None):
+ if not help:
+ id = self.tg.mid.id_to_num_offset(self.tmp_telegram_id, cid)
+ chk_msg = await self.tg.telegram_client.get_messages(entity=self.tmp_telegram_id, ids=id)
+ if chk_msg is not None:
+ self.tmp_tg_msg = await self.tg.telegram_client.send_message(self.tmp_telegram_id, msg, reply_to=id)
+ reply = True
+ else:
+ reply = ('Unknown message to reply',)
+ else: # HELP.brief or HELP.desc (first line)
+ reply = (' !re Reply to a message',)
+ if help == HELP.desc: # rest of HELP.desc
+ reply += \
+ (
+ ' !re <compact_id> <message>',
+ 'Reply with <message> to a message with <compact_id> on current',
+ 'channel/chat.'
+ )
+ return reply
diff -rN -u old-irgramd/irc.py new-irgramd/irc.py
--- old-irgramd/irc.py 2024-05-18 08:59:50.981377255 +0200
+++ new-irgramd/irc.py 2024-05-18 08:59:50.985377264 +0200
@@ -22,6 +22,7 @@
from irc_replies import irc_codes
from utils import chunks, set_replace, split_lines
from service import service
+from exclam import exclam
# Constants
@@ -109,6 +110,7 @@
def set_telegram(self, tg):
self.tg = tg
self.service = service(self.conf, self.tg)
+ self.exclam = exclam(self.tg)
# IRC
@@ -408,14 +410,18 @@
if tgt in self.iid_to_tid:
message = self.tg.replace_mentions(message, me_nick='', received=False)
telegram_id = self.iid_to_tid[tgt]
- tg_msg = await self.tg.telegram_client.send_message(telegram_id, message)
-
- mid = self.tg.mid.num_to_id_offset(telegram_id, tg_msg.id)
- text = '[{}] {}'.format(mid, message)
- self.tg.to_cache(tg_msg.id, mid, text, message, user, chan, media=None)
+ if message[0] == '!':
+ cont, tg_msg = await self.exclam.command(message, telegram_id, user)
+ else:
+ tg_msg = await self.tg.telegram_client.send_message(telegram_id, message)
+ cont = True
+ if cont:
+ mid = self.tg.mid.num_to_id_offset(telegram_id, tg_msg.id)
+ text = '[{}] {}'.format(mid, message)
+ self.tg.to_cache(tg_msg.id, mid, text, message, user, chan, media=None)
- if defered_send:
- await defered_send(user, defered_target, text)
+ if defered_send:
+ await defered_send(user, defered_target, text)
else:
await self.reply_code(user, 'ERR_NOSUCHNICK', (target,))
diff -rN -u old-irgramd/service.py new-irgramd/service.py
--- old-irgramd/service.py 2024-05-18 08:59:50.981377255 +0200
+++ new-irgramd/service.py 2024-05-18 08:59:50.985377264 +0200
@@ -6,19 +6,19 @@
# Use of this source code is governed by a MIT style license that
# can be found in the LICENSE file included in this project.
-from utils import compact_date, command
+from utils import compact_date, command, HELP
from telethon import utils as tgutils
class service(command):
def __init__(self, settings, telegram):
self.commands = \
- { # Command Handler Arguments Min Max
- 'code': (self.handle_command_code, 1, 1),
- 'dialog': (self.handle_command_dialog, 1, 2),
- 'get': (self.handle_command_get, 2, 2),
- 'help': (self.handle_command_help, 0, 1),
- 'history': (self.handle_command_history, 1, 3),
- 'mark_read': (self.handle_command_mark_read, 1, 1),
+ { # Command Handler Arguments Min Max Maxsplit
+ 'code': (self.handle_command_code, 1, 1, -1),
+ 'dialog': (self.handle_command_dialog, 1, 2, -1),
+ 'get': (self.handle_command_get, 2, 2, -1),
+ 'help': (self.handle_command_help, 0, 1, -1),
+ 'history': (self.handle_command_history, 1, 3, -1),
+ 'mark_read': (self.handle_command_mark_read, 1, 1, -1),
}
self.ask_code = settings['ask_code']
self.tg = telegram
@@ -144,12 +144,20 @@
help_text += await handler(help=HELP.brief)
help_text += \
(
+ 'The commands begining with ! (exclamation) must be used directly',
+ 'in channels or chats. The following ! commands are available:',
+ )
+ for command in self.irc.exclam.commands.values():
+ handler = command[0]
+ help_text += await handler(help=HELP.brief)
+ help_text += \
+ (
'If you need more information about a specific command you can use',
'help <command>',
)
help_text += end_help
- elif help_command in self.commands.keys():
- handler = self.commands[help_command][0]
+ elif help_command in (all_commands := dict(**self.commands, **self.irc.exclam.commands)).keys():
+ handler = all_commands[help_command][0]
help_text = start_help
help_text += await handler(help=HELP.desc)
help_text += end_help
@@ -250,7 +258,3 @@
peer_id = None
reply = ('Unknown user or channel',)
return peer_id, reply
-
-class HELP:
- desc = 1
- brief = 2
diff -rN -u old-irgramd/utils.py new-irgramd/utils.py
--- old-irgramd/utils.py 2024-05-18 08:59:50.981377255 +0200
+++ new-irgramd/utils.py 2024-05-18 08:59:50.985377264 +0200
@@ -23,11 +23,11 @@
class command:
async def parse_command(self, line, nick):
- words = line.split()
- command = words.pop(0).lower()
+ command = line.partition(' ')[0].lower()
self.tmp_ircnick = nick
if command in self.commands.keys():
- handler, min_args, max_args = self.commands[command]
+ handler, min_args, max_args, maxsplit = self.commands[command]
+ words = line.split(maxsplit=maxsplit)[1:]
num_words = len(words)
if num_words < min_args or num_words > max_args:
reply = ('Wrong number of arguments',)
@@ -38,6 +38,10 @@
return reply
+class HELP:
+ desc = 1
+ brief = 2
+
def chunks(iterable, n, fillvalue=None):
''' Return iterable consisting of a sequence of n-length chunks '''
args = [iter(iterable)] * n