async def answer(message, response, **kwargs): """Use this to give the response to a command""" cont_msg = "[continued]\n" ret = [message] if isinstance(response, str) and not kwargs.get("asfile", False): txt, ent = html.parse(response) await message.edit(html.unparse(txt[:4096], ent)) txt = txt[4096:] _fix_entities(ent, cont_msg, True) while len(txt) > 0: txt = cont_msg + txt message.message = txt[:4096] message.entities = ent message.text = html.unparse(message.message, message.entities) txt = txt[4096:] _fix_entities(ent, cont_msg) ret.append(await message.respond(message, parse_mode="HTML", **kwargs)) else: if message.media is not None: await message.edit(file=response, **kwargs) else: await message.edit("<code>Loading media...</code>") ret = [ await message.client.send_file(message.chat_id, response, reply_to=message.reply_to_msg_id, **kwargs) ] await message.delete() return ret
async def answer(message, answer, **kwargs): CONT_MSG = "[continued]\n" ret = [message] if isinstance(answer, str) and not kwargs.get("asfile", False): txt, ent = html.parse(answer) await message.edit(html.unparse(txt[:4096], ent)) txt = txt[4096:] for e in ent: e.offset -= 4096 - len(CONT_MSG) while len(txt) > 0: txt = CONT_MSG + txt message.message = txt[:4096] message.entities = ent message.text = html.unparse(message.message, message.entities) txt = txt[4096:] for e in ent: e.offset -= 4096 - len(CONT_MSG) ret.append(await message.respond(message, parse_mode="HTML", **kwargs)) else: if message.media is not None: await message.edit(file=answer, **kwargs) else: await message.edit("<code>Loading media...</code>") ret = [ await message.client.send_file(message.to_id, answer, reply_to=message.reply_to_msg_id, **kwargs) ] await message.delete()
def html_to_telegram_split( html: str, length_limit_head: int = 4096, head_count: int = -1, length_limit_tail: int = 4096 ) -> list[tuple[str, list[TypeMessageEntity]]]: full_text, all_entities = parse(html) return text_and_format_entities_split(full_text, all_entities, length_limit_head, head_count, length_limit_tail)
def test_entities_together(): """ Test that an entity followed immediately by a different one behaves well. """ original = '<strong>⚙️</strong><em>Settings</em>' stripped = '⚙️Settings' text, entities = html.parse(original) assert text == stripped assert entities == [MessageEntityBold(0, 2), MessageEntityItalic(2, 8)] text = html.unparse(text, entities) assert text == original
def test_offset_at_emoji(): """ Tests that an entity starting at a emoji preserves the emoji. """ text = 'Hi\n👉 See example' entities = [ MessageEntityBold(0, 2), MessageEntityItalic(3, 2), MessageEntityBold(10, 7) ] parsed = '<strong>Hi</strong>\n<em>👉</em> See <strong>example</strong>' assert html.parse(parsed) == (text, entities) assert html.unparse(text, entities) == parsed
async def subscribe(event): """Send a message when the command /subscribe is issued.""" # insert chat_id chat_id = event.message.chat.id find = utils.db.user.get_or_none(chat_id=chat_id) user_id = find if not find: # 不存在用户信息 await event.respond('Failed. Please input /start') raise events.StopPropagation text = event.message.text text = text.replace(',', ',') # 替换掉中文逗号 text = regex.sub( '\s*,\s*', ',', text ) # 确保英文逗号间隔中间都没有空格 如 "https://t.me/xiaobaiup, https://t.me/com9ji" splitd = [i for i in regex.split('\s+', text) if i] # 删除空元素 if len(splitd) <= 1: await event.respond( '输入需要订阅的关键字,支持js正则语法:`/[\s\S]*/ig`\n\nInput the keyword that needs to subscribe, support JS regular syntax:`/[\s\S]*/ig`' ) cache.set('status_{}'.format(chat_id), { 'current_status': '/subscribe keywords', 'record_value': text }, expire=5 * 60) #设置5m后过期 elif len(splitd) == 3: command, keywords, channels = splitd result = await join_channel_insert_subscribe( user_id, parse_full_command(command, keywords, channels)) if isinstance(result, str): logger.error('join_channel_insert_subscribe 错误:' + result) await event.respond(result, parse_mode=None) # 提示错误消息 else: msg = '' for key, channel, _chat_id in result: if _chat_id: _chat_id, peer_type = telethon_utils.resolve_id( int(_chat_id)) if not channel: channel = f'<a href="t.me/c/{_chat_id}/-1">{_chat_id}</a>' msg += f'keyword:{key} channel:{channel}\n' if msg: msg = 'success subscribe:\n' + msg text, entities = html.parse(msg) # 解析超大文本 分批次发送 避免输出报错 for text, entities in telethon_utils.split_text( text, entities): await event.respond(text, formatting_entities=entities) #await event.respond('success subscribe:\n'+msg,parse_mode = None) raise events.StopPropagation
def get_plain_text_length(html: str) -> int: return len(parse(html)[0])
async def _list(event): chat_id = event.message.chat.id find = utils.db.user.get_or_none(**{ 'chat_id': chat_id, }) if find: find = utils.db.connect.execute_sql( 'select id,keywords,channel_name,chat_id from user_subscribe_list where user_id = %d and status = %d' % (find.id, 0)).fetchall() if find: msg = '' for sub_id, keywords, channel_name, chat_id in find: _type = 'regex' if is_regex_str(keywords) else 'keyword' channel_url = get_channel_url(channel_name, chat_id) channel_entity = None # TODO 不执行实体信息读取 否则会无响应 # _entity = int(chat_id) if chat_id else channel_name # # channel_entity1 = await client.get_entity('tianfutong') # # channel_entity2 = await client.get_entity('@tianfutong') # # channel_entity3 = await client.get_entity(-1001242421091) # # channel_entity4 = await client.get_entity(1242421091) # try: # channel_entity = await client.get_entity(_entity)# 获取频道相关信息 # except ValueError as _e:# 频道不存在报错 # pass # # logger.info(f'delete user_subscribe_list channel id:{sub_id} _entity:{_entity}') # # re_update = utils.db.user_subscribe_list.update(status = 1 ).where(utils.User_subscribe_list.id == sub_id) # # re_update.execute() # class channel_entity: username='';title='' channel_title = '' if channel_entity and channel_entity.title: channel_title = f'channel title: {channel_entity.title}\n' if channel_name: if channel_entity: if channel_entity.username: if channel_entity.username != channel_name: channel_name += '\t[CHANNEL NAME EXPIRED]' # 标记频道名称过期 # channel_name = '' # 不显示 logger.info( f'channel username:{channel_name} expired.' ) else: channel_name += '\t[CHANNEL NONE EXPIRED]' # 标记频道名称过期.当前不存在 # channel_name = '' # 不显示 logger.info( f'channel username:{channel_name} expired. current none' ) elif chat_id: # 只有chat_id if channel_entity and channel_entity.username: channel_name = channel_entity.username logger.info( f'channel chat_id:{chat_id} username:{channel_name}' ) channel_username = '' if channel_entity: # 有实体信息才显示频道名 if channel_name: channel_username = f'channel username: {channel_name}\n' channel_url = f'<a href="{channel_url}-1">{"https://t.me/"+channel_name if channel_name else channel_url}</a>' msg += f'id:{sub_id}\n{_type}: {keywords}\n{channel_title}{channel_username}channel url: {channel_url}\n---\n' text, entities = html.parse(msg) # 解析超大文本 分批次发送 避免输出报错 for text, entities in telethon_utils.split_text(text, entities): # await client.send_message(chat, text, formatting_entities=entities) await event.respond(text, formatting_entities=entities) else: await event.respond('not found list') else: await event.respond('please /start') raise events.StopPropagation
async def common(event): """Echo the user message.""" chat_id = event.message.chat.id text = event.text text = text.replace(',', ',') # 替换掉中文逗号 text = regex.sub( '\s*,\s*', ',', text ) # 确保英文逗号间隔中间都没有空格 如 "https://t.me/xiaobaiup, https://t.me/com9ji" find = cache.get('status_{}'.format(chat_id)) if find: # 执行订阅 if find['current_status'] == '/subscribe keywords': # 当前输入关键字 await event.respond( '输入需要订阅的频道url或者name:\n\nEnter the url or name of the channel to subscribe to:' ) cache.set('status_{}'.format(chat_id), { 'current_status': '/subscribe channels', 'record_value': find['record_value'] + ' ' + text }, expire=5 * 60) # 记录输入的关键字 raise events.StopPropagation elif find['current_status'] == '/subscribe channels': # 当前输入频道 full_command = find['record_value'] + ' ' + text splitd = [i for i in regex.split('\s+', full_command) if i] # 删除空元素 if len(splitd) != 3: await event.respond( '关键字请不要包含空格 可使用正则表达式解决\n\nThe keyword must not contain Spaces.' ) raise events.StopPropagation command, keywords, channels = splitd user_id = utils.db.user.get_or_none(chat_id=chat_id) result = await join_channel_insert_subscribe( user_id, parse_full_command(command, keywords, channels)) if isinstance(result, str): await event.respond(result, parse_mode=None) # 提示错误消息 else: msg = '' for key, channel, _chat_id in result: if _chat_id: _chat_id, peer_type = telethon_utils.resolve_id( int(_chat_id)) if not channel: channel = f'<a href="t.me/c/{_chat_id}/-1">{_chat_id}</a>' msg += f'keyword:{key} channel:{channel}\n' if msg: # await event.respond('success subscribe:\n'+msg,parse_mode = None) msg = 'success subscribe:\n' + msg text, entities = html.parse(msg) # 解析超大文本 分批次发送 避免输出报错 for text, entities in telethon_utils.split_text( text, entities): await event.respond(text, formatting_entities=entities) cache.delete('status_{}'.format(chat_id)) raise events.StopPropagation #取消订阅 elif find['current_status'] == '/unsubscribe keywords': # 当前输入关键字 await event.respond( '输入需要**取消订阅**的频道url或者name:\n\nEnter the url or name of the channel where ** unsubscribe **is required:' ) cache.set('status_{}'.format(chat_id), { 'current_status': '/unsubscribe channels', 'record_value': find['record_value'] + ' ' + text }, expire=5 * 60) # 记录输入的关键字 raise events.StopPropagation elif find['current_status'] == '/unsubscribe channels': # 当前输入频道 full_command = find['record_value'] + ' ' + text splitd = [i for i in regex.split('\s+', full_command) if i] # 删除空元素 if len(splitd) != 3: await event.respond( '关键字请不要包含空格 可使用正则表达式解决\n\nThe keyword must not contain Spaces.' ) raise events.StopPropagation command, keywords, channels = splitd user_id = utils.db.user.get_or_none(chat_id=chat_id) result = update_subscribe( user_id, parse_full_command(command, keywords, channels)) # msg = '' # for key,channel in result: # msg += '{},{}\n'.format(key,channel) # if msg: # await event.respond('success:\n'+msg,parse_mode = None) await event.respond('success unsubscribe..') cache.delete('status_{}'.format(chat_id)) raise events.StopPropagation elif find['current_status'] == '/unsubscribe_id ids': # 当前输入订阅id splitd = text.strip().split(',') user_id = utils.db.user.get_or_none(chat_id=chat_id) result = [] for i in splitd: if not i.isdigit(): continue i = int(i) re_update = utils.db.user_subscribe_list.update( status=1).where( utils.User_subscribe_list.id == i, utils.User_subscribe_list.user_id == user_id) #更新状态 re_update = re_update.execute() # 更新成功返回1,不管是否重复执行 if re_update: result.append(i) await event.respond('success unsubscribe id:{}'.format( result if result else 'None')) raise events.StopPropagation