Compare commits

..

No commits in common. "fc78927fa6d3a67603a63adec7f4c4781002f049" and "a3981e0994a578e7e6ef56789ab5311dad2b23fd" have entirely different histories.

2 changed files with 39 additions and 55 deletions

View File

@ -1,30 +1,17 @@
import asyncio import asyncio
import re import re
import html
from dataclasses import dataclass
from telethon import events, utils from telethon import events
from telethon.tl.functions.channels import EditTitleRequest from telethon.tl.functions.channels import EditTitleRequest
from telethon.errors.rpcerrorlist import ChatNotModifiedError from telethon.errors.rpcerrorlist import ChatNotModifiedError
MULTI_EDIT_TIMEOUT = 80 MULTI_EDIT_TIMEOUT = 80
REVERT_TIMEOUT = 2 * 60 * 60 REVERT_TIMEOUT = 2 * 60 * 60
CHANNEL_ID = 1040270887
DEFAULT_TITLE = "Programming & Tech"
@dataclass prog_tech_channel = None
class Group: rename_lock = asyncio.Lock()
id: int revert_task = None
title: str
rename_lock = asyncio.Lock()
revert_task: asyncio.Task = None
GROUPS = {group.id: group for group in (
# Group(1040270887, 'Programming & Tech'),
Group(1384391544, 'Programming & Tech for girls'),
Group(1286178907, 'test supergroup')
)}
def fix_title(s): def fix_title(s):
@ -37,59 +24,56 @@ def fix_title(s):
return re.sub(r'(\S+)(\s+)?', replace, s) return re.sub(r'(\S+)(\s+)?', replace, s)
async def edit_title(chat, title): async def edit_title(title):
global prog_tech_channel
if prog_tech_channel is None:
prog_tech_channel = await borg.get_entity(CHANNEL_ID)
try: try:
await borg(EditTitleRequest( await borg(EditTitleRequest(
channel=chat, title=title channel=prog_tech_channel, title=title
)) ))
except ChatNotModifiedError: except ChatNotModifiedError:
pass # Everything is ok pass # Everything is ok
async def wait_and_revert(chat_id, title, timeout): async def wait_for_delete(deleted_fut, timeout):
await asyncio.sleep(timeout) try:
await edit_title(chat_id, title) await asyncio.wait_for(deleted_fut, timeout)
return True
except asyncio.TimeoutError:
pass
return False
async def wait_and_revert(deleted_fut, timeout):
await wait_for_delete(deleted_fut, timeout)
await edit_title(DEFAULT_TITLE)
@borg.on(events.NewMessage( @borg.on(events.NewMessage(
pattern=re.compile(r"(?i)programming (?:&|and) (.+)"), pattern=re.compile(r"(?i)programming (?:&|and) (.+)"), chats=CHANNEL_ID))
chats=list(GROUPS.keys())))
async def on_name(event): async def on_name(event):
global revert_task
new_topic = fix_title(event.pattern_match.group(1)) new_topic = fix_title(event.pattern_match.group(1))
new_title = f"Programming & {new_topic}" new_title = f"Programming & {new_topic}"
if "Tech" not in new_title: if "Tech" not in new_title:
new_title += " & Tech" new_title += " & Tech"
group = GROUPS[utils.get_peer_id(event.chat_id, False)] # Thanks Lonami if len(new_title) > 255 or rename_lock.locked():
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')
return return
if group.rename_lock.locked(): with (await rename_lock):
logger.info('Not changing group title because the rename lock is already held') await edit_title(new_title)
return deleted_fut = borg.await_event(events.MessageDeleted(
chats=CHANNEL_ID,
with (await group.rename_lock): func=lambda e: e.deleted_id == event.message.id
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'
)
await edit_title(event.chat_id, new_title)
logger.info(f'Holding rename lock for {MULTI_EDIT_TIMEOUT} seconds')
await asyncio.sleep(MULTI_EDIT_TIMEOUT)
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
)) ))
if await wait_for_delete(asyncio.shield(deleted_fut), MULTI_EDIT_TIMEOUT):
await edit_title(DEFAULT_TITLE)
await asyncio.sleep(MULTI_EDIT_TIMEOUT)
return
if revert_task and not revert_task.done():
revert_task.cancel()
revert_task = asyncio.create_task(wait_and_revert(deleted_fut, REVERT_TIMEOUT))