patch 1d3ba8cce2f25104ebe89e202143ac27bfec87fa Author: E. Bosch Date: Tue Apr 25 22:34:42 CEST 2023 * telegram: Add support for showing reactions to messages Add conversion of UTF-8 emojis to ASCII emoticons diff -rN -u old-irgramd/emoji2emoticon.py new-irgramd/emoji2emoticon.py --- old-irgramd/emoji2emoticon.py 1970-01-01 01:00:00.000000000 +0100 +++ new-irgramd/emoji2emoticon.py 2024-11-22 21:43:58.542091727 +0100 @@ -0,0 +1,88 @@ +# irgramd: IRC-Telegram gateway +# emoji2emoticon.py: UTF-8 Emoji to ASCII emoticon replacement +# +# (C) Copyright 2019,2023 E. Bosch +# +# Use of this source code is governed by a MIT style license that +# can be found in the LICENSE file included in this project. + +emo = { + '\U0000270c': '"V"', + '\U00002764': '"<3"', + '\U0001f389': '"<*``"', + '\U0001f44c': '"ok"', + '\U0001f44d': '"+1"', + '\U0001f44e': '"-1"', + '\U0001f44f': '"m_m"', + '\U0001f525': '"\^^^/"', + '\U0001f600': '":D"', + '\U0001f601': '"xD"', + '\U0001f602': '"x_D"', + '\U0001f603': '":D"', + '\U0001f604': '"xD"', + '\U0001f605': '"x`D"', + '\U0001f606': '"xD"', + '\U0001f607': '"O:)"', + '\U0001f608': '"}:)"', + '\U0001f609': '";)"', + '\U0001f60a': '"x)"', + '\U0001f60b': '"xP"', + '\U0001f60c': '":)"', + '\U0001f60d': '"E>)"', + '\U0001f60e': '"B)"', + '\U0001f60f': '"- -,"', + '\U0001f610': '":|"', + '\U0001f611': '":|"', + '\U0001f612': '"-. -."', + '\U0001f613': '":`|"', + '\U0001f614': '":|"', + '\U0001f615': '":/"', + '\U0001f616': '":S"', + '\U0001f617': '":*"', + '\U0001f618': '":**"', + '\U0001f619': '"x*"', + '\U0001f61a': '"x*"', + '\U0001f61b': '":P"', + '\U0001f61c': '";P"', + '\U0001f61d': '"xP"', + '\U0001f61e': '":("', + '\U0001f61f': '":(("', + '\U0001f620': '":("', + '\U0001f621': '":("', + '\U0001f622': '":_("', + '\U0001f623': '"x("', + '\U0001f624': '":<("', + '\U0001f625': '":`("', + '\U0001f626': '":(|"', + '\U0001f627': '":(||"', + '\U0001f628': '"||:("', + '\U0001f629': '"::("', + '\U0001f62a': '":`("', + '\U0001f62b': '"x("', + '\U0001f62c': '":E"', + '\U0001f62d': '":__(|"', + '\U0001f62e': '":O"', + '\U0001f62f': '":o"', + '\U0001f630': '":`O"', + '\U0001f631': '":O>"', + '\U0001f632': '"8-O"', + '\U0001f633': '":8|"', + '\U0001f634': '":.zz"', + '\U0001f635': '"6)"', + '\U0001f636': '":"', + '\U0001f637': '":W"', + '\U0001f638': '">:D"', + '\U0001f639': '":_D"', + '\U0001f63a': '">:D"', + '\U0001f63b': '">E>D"', + '\U0001f63c': '">- -,"', + '\U0001f63d': '">:*"', + '\U0001f63e': '">:("', + '\U0001f63f': '">:_("', + '\U0001f640': '">:(|"', + '\U0001f641': '":("', + '\U0001f642': '":)"', + '\U0001f643': '"(:"', + '\U0001f644': '"o o,"', + '\U0001f970': '":)e>"' + } diff -rN -u old-irgramd/irc.py new-irgramd/irc.py --- old-irgramd/irc.py 2024-11-22 21:43:58.538091734 +0100 +++ new-irgramd/irc.py 2024-11-22 21:43:58.542091727 +0100 @@ -411,7 +411,7 @@ mid = self.tg.mid.num_to_id_offset(tg_msg.id) text = '[{}] {}'.format(mid, message) - self.tg.add_to_cache(tg_msg.id, mid, text, message, user, chan) + self.tg.to_cache(tg_msg.id, mid, text, message, user, chan, media=None) if defered_send: await defered_send(user, defered_target, text) diff -rN -u old-irgramd/telegram.py new-irgramd/telegram.py --- old-irgramd/telegram.py 2024-11-22 21:43:58.542091727 +0100 +++ new-irgramd/telegram.py 2024-11-22 21:43:58.542091727 +0100 @@ -16,12 +16,14 @@ import collections import telethon from telethon import types as tgty, utils as tgutils +from telethon.tl.functions.messages import GetMessagesReactionsRequest # Local modules from include import CHAN_MAX_LENGHT, NICK_MAX_LENGTH from irc import IRCUser from utils import sanitize_filename, is_url_equiv, extract_url, get_human_size, get_human_duration, get_highlighted +from emoji2emoticon import emo # Test IP table @@ -311,7 +313,35 @@ user.bot = bot return bot - def add_to_cache(self, id, mid, message, proc_message, user, chan): + async def edition_case(self, msg): + def msg_edited(m): + return m.id in self.cache and \ + ( m.message != self.cache[m.id]['text'] + or m.media != self.cache[m.id]['media'] + ) + async def get_reactions(m): + react = await self.telegram_client(GetMessagesReactionsRequest(m.peer_id, id=[m.id])) + return react.updates[0].reactions.recent_reactions + + react = None + if msg.reactions is None: + case = 'edition' + elif (reactions := await get_reactions(msg)) is None: + if msg_edited(msg): + case = 'edition' + else: + case = 'react-del' + elif react := next((x for x in reactions if x.date == msg.edit_date), None): + case = 'react-add' + else: + if msg_edited(msg): + case = 'edition' + else: + case = 'react-del' + react = None + return case, react + + def to_cache(self, id, mid, message, proc_message, user, chan, media): if len(self.cache) >= 10000: self.cache.popitem(last=False) self.cache[id] = { @@ -319,45 +349,65 @@ 'text': message, 'rendered_text': proc_message, 'user': user, - 'channel': chan + 'channel': chan, + 'media': media } async def handle_telegram_edited(self, event): self.logger.debug('Handling Telegram Message Edited: %s', event) id = event.message.id - user = self.get_irc_user_from_telegram(event.sender_id) mid = self.mid.num_to_id_offset(id) fmid = '[{}]'.format(mid) message = event.message.message message_rendered = await self.render_text(event, mid, upd_to_webpend=None) - if id in self.cache: - t = self.cache[id]['text'] - rt = self.cache[id]['rendered_text'] + edition_case, reaction = await self.edition_case(event.message) + if edition_case == 'edition': + action = 'Edited' + user = self.get_irc_user_from_telegram(event.sender_id) + if id in self.cache: + t = self.cache[id]['text'] + rt = self.cache[id]['rendered_text'] - ht, is_ht = get_highlighted(t, message) + ht, is_ht = get_highlighted(t, message) + else: + rt = fmid + is_ht = False - self.cache[id]['text'] = message - self.cache[id]['rendered_text'] = message_rendered - else: - rt = fmid - is_ht = False + if is_ht: + edition_react = ht + text_old = fmid + else: + edition_react = message + text_old = rt + if user is None: + self.refwd_me = True - if is_ht: - text_edited = ht - text_old = fmid + # Reactions else: - text_edited = message - text_old = rt - if user is None: - self.refwd_me = True + action = 'React' + if len(message_rendered) > 50: + text_old = '{}...'.format(message_rendered[:50]) + else: + text_old = message_rendered + + if edition_case == 'react-add': + user = self.get_irc_user_from_telegram(reaction.peer_id.user_id) + emoji = reaction.reaction.emoticon + react_action = '+' + react_icon = emo[emoji] if emoji in emo else emoji + elif edition_case == 'react-del': + user = self.get_irc_user_from_telegram(event.sender_id) + react_action = '-' + react_icon = '' + edition_react = '{}{}'.format(react_action, react_icon) + + text = '|{} {}| {}'.format(action, text_old, edition_react) - text = '|Edited {}| {}'.format(text_old, text_edited) chan = await self.relay_telegram_message(event, user, text) - if id not in self.cache: - self.add_to_cache(id, mid, message, message_rendered, user, chan) + self.to_cache(id, mid, message, message_rendered, user, chan, event.message.media) async def handle_telegram_deleted(self, event): self.logger.debug('Handling Telegram Message Deleted: %s', event) @@ -392,7 +442,7 @@ chan = await self.relay_telegram_message(event, user, message) - self.add_to_cache(event.message.id, mid, event.message.message, message, user, chan) + self.to_cache(event.message.id, mid, event.message.message, message, user, chan, event.message.media) self.refwd_me = False