uniborg/stdplugins/sp_prog_rename.py

96 lines
2.7 KiB
Python
Raw Normal View History

2018-06-03 12:16:14 +00:00
import asyncio
2018-11-01 21:02:34 +00:00
import re
2019-04-27 10:15:40 +00:00
import html
2019-04-27 13:51:54 +00:00
from dataclasses import dataclass
2018-11-01 21:02:34 +00:00
2019-04-27 13:51:54 +00:00
from telethon import events, utils
2018-06-03 12:16:14 +00:00
from telethon.tl.functions.channels import EditTitleRequest
from telethon.errors.rpcerrorlist import ChatNotModifiedError
2018-06-03 12:16:14 +00:00
2019-04-27 13:51:54 +00:00
MULTI_EDIT_TIMEOUT = 80
REVERT_TIMEOUT = 2 * 60 * 60
2019-04-27 13:51:54 +00:00
@dataclass
class Group:
id: int
title: str
rename_lock = asyncio.Lock()
revert_task: asyncio.Task = None
GROUPS = {group.id: group for group in (
# Group(1040270887, 'Programming & Tech'),
2019-04-27 13:51:54 +00:00
Group(1384391544, 'Programming & Tech for girls'),
Group(1286178907, 'test supergroup')
)}
2018-06-03 12:16:14 +00:00
2018-11-01 21:04:15 +00:00
def fix_title(s):
# Ideally this would be a state machine, but ¯\_(ツ)_/¯
def replace(m):
token = m.group(1)
if token.lower() == 'and':
token = '&'
2018-11-01 21:24:17 +00:00
return token[0].upper() + token[1:] + (' ' if m.group(2) else '')
2018-11-01 21:04:15 +00:00
return re.sub(r'(\S+)(\s+)?', replace, s)
2019-04-27 10:22:23 +00:00
async def edit_title(chat, title):
try:
await borg(EditTitleRequest(
2019-04-27 10:22:23 +00:00
channel=chat, title=title
))
except ChatNotModifiedError:
pass # Everything is ok
2018-06-03 12:16:14 +00:00
2019-04-27 13:51:54 +00:00
async def wait_and_revert(chat_id, title, timeout):
2019-04-27 10:05:46 +00:00
await asyncio.sleep(timeout)
2019-04-27 13:51:54 +00:00
await edit_title(chat_id, title)
2018-06-03 12:16:14 +00:00
@borg.on(events.NewMessage(
2019-04-27 10:22:23 +00:00
pattern=re.compile(r"(?i)programming (?:&|and) (.+)"),
2019-04-27 13:51:54 +00:00
chats=list(GROUPS.keys())))
2018-06-03 12:16:14 +00:00
async def on_name(event):
2018-11-01 21:04:15 +00:00
new_topic = fix_title(event.pattern_match.group(1))
2018-06-10 19:54:00 +00:00
new_title = f"Programming & {new_topic}"
if "Tech" not in new_title:
new_title += " & Tech"
2018-06-03 12:16:14 +00:00
2019-04-27 13:51:54 +00:00
group = GROUPS[utils.get_peer_id(event.chat_id, False)] # Thanks Lonami
logger.info(f'{event.from_id} in {group.id} '
f'requested a title change to {new_title}')
if len(new_title) > 255:
logger.info('Not changing group title because new title is too long')
2018-06-03 12:16:14 +00:00
return
2019-04-27 13:51:54 +00:00
if group.rename_lock.locked():
logger.info('Not changing group title because the rename lock is already held')
return
2019-04-27 10:15:40 +00:00
2019-04-27 13:51:54 +00:00
with (await group.rename_lock):
logger.info(f'Changing group title to {new_title}')
await event.respond(
f'<a href="tg://user?id={event.from_id}">{html.escape(event.sender.first_name)}</a>'
' changed the group title!',
parse_mode='html'
)
2019-04-27 10:22:23 +00:00
await edit_title(event.chat_id, new_title)
2019-04-27 13:51:54 +00:00
logger.info(f'Holding rename lock for {MULTI_EDIT_TIMEOUT} seconds')
2019-04-27 10:05:46 +00:00
await asyncio.sleep(MULTI_EDIT_TIMEOUT)
2019-04-27 13:51:54 +00:00
if group.revert_task and not group.revert_task.done():
logger.info('Cancelling previous revert task')
group.revert_task.cancel()
logger.info('Creating revert task')
group.revert_task = asyncio.create_task(wait_and_revert(
event.chat_id,
group.title,
REVERT_TIMEOUT
))