uniborg/stdplugins/sed.py

109 lines
2.9 KiB
Python
Raw Normal View History

2018-04-10 19:18:10 +00:00
from collections import defaultdict, deque
import re
from telethon import events, utils
2018-04-20 08:54:37 +00:00
from telethon.tl import types, functions
2018-08-25 08:51:50 +00:00
HEADER = "「sed」\n"
2018-04-20 08:54:37 +00:00
KNOWN_RE_BOTS = re.compile(
2018-05-31 23:54:14 +00:00
r'(regex|moku|BananaButler_|rgx|l4mR)bot',
2018-04-20 08:54:37 +00:00
flags=re.IGNORECASE
)
2018-04-10 19:18:10 +00:00
# Heavily based on
# https://github.com/SijmenSchoon/regexbot/blob/master/regexbot.py
last_msgs = defaultdict(lambda: deque(maxlen=10))
def doit(chat_id, match, original):
fr = match.group(1)
to = match.group(2)
to = to.replace('\\/', '/')
try:
fl = match.group(3)
if fl is None:
fl = ''
fl = fl[1:]
except IndexError:
fl = ''
# Build Python regex flags
count = 1
flags = 0
for f in fl:
if f == 'i':
2019-02-26 17:52:57 +00:00
flags |= re.IGNORECASE
2018-04-10 19:18:10 +00:00
elif f == 'g':
count = 0
else:
return None, f"Unknown flag: {f}"
def actually_doit(original):
try:
s = original.message
if s.startswith(HEADER):
s = s[len(HEADER):]
2019-02-26 17:52:57 +00:00
s, i = re.subn(fr, to, s, count=count, flags=flags)
2018-04-10 19:18:10 +00:00
if i > 0:
return original, s
except Exception as e:
return None, f"u dun goofed m8: {str(e)}"
return None, None
if original is not None:
return actually_doit(original)
# Try matching the last few messages
for original in last_msgs[chat_id]:
2018-04-10 19:18:10 +00:00
m, s = actually_doit(original)
if s is not None:
return m, s
return None, None
2018-06-13 18:31:48 +00:00
async def group_has_sedbot(group):
2018-04-20 08:54:37 +00:00
if isinstance(group, types.InputPeerChannel):
full = await borg(functions.channels.GetFullChannelRequest(group))
elif isinstance(group, types.InputPeerChat):
full = await borg(functions.messages.GetFullChatRequest(group.chat_id))
else:
return False
return any(KNOWN_RE_BOTS.match(x.username or '') for x in full.users)
2018-04-10 19:18:10 +00:00
@borg.on(events.NewMessage)
async def on_message(event):
last_msgs[event.chat_id].appendleft(event.message)
2018-04-10 19:18:10 +00:00
2018-07-02 13:30:21 +00:00
@borg.on(events.MessageEdited)
async def on_edit(event):
for m in last_msgs[event.chat_id]:
if m.id == event.id:
m.raw_text = event.raw_text
break
2018-04-10 19:18:10 +00:00
@borg.on(events.NewMessage(
pattern=re.compile(r"^s/((?:\\/|[^/])+)/((?:\\/|[^/])*)(/.*)?")))
async def on_regex(event):
2018-06-14 21:09:25 +00:00
if event.fwd_from:
2018-04-10 19:18:10 +00:00
return
2018-06-22 08:46:39 +00:00
if not event.is_private and\
await group_has_sedbot(await event.get_input_chat()):
2018-04-10 19:18:10 +00:00
return
2018-06-22 08:46:39 +00:00
chat_id = utils.get_peer_id(await event.get_input_chat())
2018-04-10 19:18:10 +00:00
2018-06-22 08:46:39 +00:00
m, s = doit(chat_id, event.pattern_match, await event.get_reply_message())
2018-04-10 19:18:10 +00:00
if m is not None:
s = f"{HEADER}{s}"
2018-06-22 08:46:39 +00:00
out = await borg.send_message(
await event.get_input_chat(), s, reply_to=m.id
)
last_msgs[chat_id].appendleft(out)
2018-04-10 19:18:10 +00:00
elif s is not None:
await event.reply(s)
raise events.StopPropagation