telegram: Limit text length for reactions to twice as replies
Annotate for file telegram.py
2022-02-20 E. 1 # irgramd: IRC-Telegram gateway
01:25:27 ' 2 # telegram.py: Interface to Telethon Telegram library
' 3 #
' 4 # Copyright (c) 2019 Peter Bui <pbui@bx612.space>
2024-04-07 E. 5 # Copyright (c) 2020-2024 E. Bosch <presidev@AT@gmail.com>
2022-02-20 E. 6 #
01:25:27 ' 7 # Use of this source code is governed by a MIT style license that
' 8 # can be found in the LICENSE file included in this project.
2020-11-21 E. 9
01:12:30 ' 10 import logging
' 11 import os
2021-02-12 E. 12 import re
2022-02-16 E. 13 import aioconsole
2022-03-19 E. 14 import asyncio
2023-04-08 E. 15 import collections
2020-11-21 E. 16 import telethon
2023-03-22 E. 17 from telethon import types as tgty, utils as tgutils
2023-04-25 E. 18 from telethon.tl.functions.messages import GetMessagesReactionsRequest
2020-11-21 E. 19
2021-01-27 E. 20 # Local modules
19:51:33 ' 21
2024-09-07 E. 22 from include import CHAN_MAX_LENGTH, NICK_MAX_LENGTH
2021-01-31 E. 23 from irc import IRCUser
2024-08-29 E. 24 from utils import sanitize_filename, add_filename, is_url_equiv, extract_url, get_human_size, get_human_duration
23:58:06 ' 25 from utils import get_highlighted, fix_braces, format_timestamp, pretty, current_date
2023-04-29 E. 26 import emoji2emoticon as e
2020-11-21 E. 27
2022-02-22 E. 28 # Test IP table
01:37:33 ' 29
' 30 TEST_IPS = { 1: '149.154.175.10',
' 31 2: '149.154.167.40',
2024-08-29 E. 32 3: '149.154.175.117',
2022-02-22 E. 33 }
01:37:33 ' 34
2020-11-21 E. 35 # Telegram
01:12:30 ' 36
' 37 class TelegramHandler(object):
2021-12-12 E. 38 def __init__(self, irc, settings):
2020-11-21 E. 39 self.logger = logging.getLogger()
2021-12-12 E. 40 self.config_dir = settings['config_dir']
2024-04-14 E. 41 self.cache_dir = settings['cache_dir']
2023-10-15 E. 42 self.download = settings['download_media']
2023-10-15 E. 43 self.notice_size = settings['download_notice'] * 1048576
2023-06-05 E. 44 self.media_dir = settings['media_dir']
2022-01-30 E. 45 self.media_url = settings['media_url']
2024-04-14 E. 46 self.upload_dir = settings['upload_dir']
2022-02-16 E. 47 self.api_id = settings['api_id']
01:18:10 ' 48 self.api_hash = settings['api_hash']
2022-02-16 E. 49 self.phone = settings['phone']
2022-02-22 E. 50 self.test = settings['test']
01:37:33 ' 51 self.test_dc = settings['test_datacenter']
' 52 self.test_ip = settings['test_host'] if settings['test_host'] else TEST_IPS[self.test_dc]
' 53 self.test_port = settings['test_port']
2022-03-08 E. 54 self.ask_code = settings['ask_code']
2023-04-26 E. 55 self.quote_len = settings['quote_length']
2023-05-06 E. 56 self.hist_fmt = settings['hist_timestamp_format']
23:31:34 ' 57 self.timezone = settings['timezone']
2023-07-20 E. 58 self.geo_url = settings['geo_url']
2023-04-29 E. 59 if not settings['emoji_ascii']:
18:47:52 ' 60 e.emo = {}
2022-01-30 E. 61 self.media_cn = 0
2020-11-21 E. 62 self.irc = irc
2021-01-27 E. 63 self.authorized = False
2021-02-02 E. 64 self.id = None
22:52:41 ' 65 self.tg_username = None
2021-02-12 E. 66 self.channels_date = {}
2022-01-26 E. 67 self.mid = mesg_id('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$%+./_~')
2022-02-08 E. 68 self.webpending = {}
2023-03-28 E. 69 self.refwd_me = False
2023-04-08 E. 70 self.cache = collections.OrderedDict()
2024-08-30 E. 71 self.volatile_cache = collections.OrderedDict()
19:53:13 ' 72 self.prev_id = {}
2023-07-07 E. 73 self.sorted_len_usernames = []
2024-09-28 E. 74 self.last_reaction = None
2022-03-19 E. 75 # Set event to be waited by irc.check_telegram_auth()
05:11:26 ' 76 self.auth_checked = asyncio.Event()
2021-01-27 E. 77
23:13:48 ' 78 async def initialize_telegram(self):
2020-11-21 E. 79 # Setup media folder
2024-04-14 E. 80 self.telegram_media_dir = os.path.expanduser(self.media_dir or os.path.join(self.cache_dir, 'media'))
2020-11-21 E. 81 if not os.path.exists(self.telegram_media_dir):
01:12:30 ' 82 os.makedirs(self.telegram_media_dir)
' 83
2024-04-14 E. 84 # Setup upload folder
20:48:30 ' 85 self.telegram_upload_dir = os.path.expanduser(self.upload_dir or os.path.join(self.cache_dir, 'upload'))
' 86 if not os.path.exists(self.telegram_upload_dir):
' 87 os.makedirs(self.telegram_upload_dir)
' 88
2020-11-21 E. 89 # Setup session folder
01:12:30 ' 90 self.telegram_session_dir = os.path.join(self.config_dir, 'session')
' 91 if not os.path.exists(self.telegram_session_dir):
' 92 os.makedirs(self.telegram_session_dir)
' 93
' 94 # Construct Telegram client
2022-02-22 E. 95 if self.test:
01:37:33 ' 96 self.telegram_client = telethon.TelegramClient(None, self.api_id, self.api_hash)
' 97 self.telegram_client.session.set_dc(self.test_dc, self.test_ip, self.test_port)
' 98 else:
' 99 telegram_session = os.path.join(self.telegram_session_dir, 'telegram')
' 100 self.telegram_client = telethon.TelegramClient(telegram_session, self.api_id, self.api_hash)
2020-11-21 E. 101
01:12:30 ' 102 # Initialize Telegram ID to IRC nick mapping
' 103 self.tid_to_iid = {}
' 104
' 105 # Register Telegram callbacks
' 106 callbacks = (
' 107 (self.handle_telegram_message , telethon.events.NewMessage),
2024-08-29 E. 108 (self.handle_raw , telethon.events.Raw),
2020-11-21 E. 109 (self.handle_telegram_chat_action, telethon.events.ChatAction),
2023-04-10 E. 110 (self.handle_telegram_deleted , telethon.events.MessageDeleted),
2024-08-29 E. 111 (self.handle_telegram_edited , telethon.events.MessageEdited),
2020-11-21 E. 112 )
01:12:30 ' 113 for handler, event in callbacks:
' 114 self.telegram_client.add_event_handler(handler, event)
' 115
' 116 # Start Telegram client
2022-02-22 E. 117 if self.test:
01:37:33 ' 118 await self.telegram_client.start(self.phone, code_callback=lambda: str(self.test_dc) * 5)
' 119 else:
' 120 await self.telegram_client.connect()
2021-01-27 E. 121
2022-02-16 E. 122 while not await self.telegram_client.is_user_authorized():
2022-03-08 E. 123 self.logger.info('Telegram account not authorized')
2022-02-16 E. 124 await self.telegram_client.send_code_request(self.phone)
2022-03-19 E. 125 self.auth_checked.set()
2022-03-08 E. 126 if not self.ask_code:
21:58:55 ' 127 return
' 128 self.logger.info('You must provide the Login code that Telegram will '
' 129 'sent you via SMS or another connected client')
2022-02-16 E. 130 code = await aioconsole.ainput('Login code: ')
22:22:04 ' 131 try:
' 132 await self.telegram_client.sign_in(code=code)
' 133 except:
' 134 pass
' 135
2022-03-08 E. 136 await self.continue_auth()
21:58:55 ' 137
' 138 async def continue_auth(self):
2022-02-16 E. 139 self.logger.info('Telegram account authorized')
22:22:04 ' 140 self.authorized = True
2022-03-19 E. 141 self.auth_checked.set()
2022-02-16 E. 142 await self.init_mapping()
2021-01-27 E. 143
23:13:48 ' 144 async def init_mapping(self):
2020-11-21 E. 145 # Update IRC <-> Telegram mapping
2021-02-02 E. 146 tg_user = await self.telegram_client.get_me()
22:52:41 ' 147 self.id = tg_user.id
' 148 self.tg_username = self.get_telegram_nick(tg_user)
2023-07-07 E. 149 self.add_sorted_len_usernames(self.tg_username)
2022-02-19 E. 150 self.set_ircuser_from_telegram(tg_user)
2021-01-27 E. 151 async for dialog in self.telegram_client.iter_dialogs():
2020-11-22 E. 152 chat = dialog.entity
2021-02-01 E. 153 if isinstance(chat, tgty.User):
2021-02-02 E. 154 self.set_ircuser_from_telegram(chat)
2020-11-22 E. 155 else:
2021-01-31 E. 156 await self.set_irc_channel_from_telegram(chat)
19:23:45 ' 157
' 158 def set_ircuser_from_telegram(self, user):
' 159 if user.id not in self.tid_to_iid:
' 160 tg_nick = self.get_telegram_nick(user)
2021-02-02 E. 161 tg_ni = tg_nick.lower()
22:52:41 ' 162 if not user.is_self:
2023-06-14 E. 163 irc_user = IRCUser(None, ('Telegram',''), tg_nick, user.id, self.get_telegram_display_name(user))
2021-02-02 E. 164 self.irc.users[tg_ni] = irc_user
2023-07-07 E. 165 self.add_sorted_len_usernames(tg_ni)
2021-01-31 E. 166 self.tid_to_iid[user.id] = tg_nick
2021-02-02 E. 167 self.irc.iid_to_tid[tg_ni] = user.id
2021-01-31 E. 168 else:
19:23:45 ' 169 tg_nick = self.tid_to_iid[user.id]
' 170 return tg_nick
' 171
' 172 async def set_irc_channel_from_telegram(self, chat):
' 173 channel = self.get_telegram_channel(chat)
2023-03-17 E. 174 self.tid_to_iid[chat.id] = channel
2021-02-01 E. 175 chan = channel.lower()
2023-03-17 E. 176 self.irc.iid_to_tid[chan] = chat.id
2023-03-18 E. 177 self.irc.irc_channels[chan] = set()
2021-01-31 E. 178 # Add users from the channel
2021-02-01 E. 179 async for user in self.telegram_client.iter_participants(chat.id):
2021-01-31 E. 180 user_nick = self.set_ircuser_from_telegram(user)
2021-02-01 E. 181 if not user.is_self:
22:18:25 ' 182 self.irc.irc_channels[chan].add(user_nick)
' 183 # Add admin users as ops in irc
' 184 if isinstance(user.participant, tgty.ChatParticipantAdmin):
' 185 self.irc.irc_channels_ops[chan].add(user_nick)
' 186 # Add creator users as founders in irc
' 187 elif isinstance(user.participant, tgty.ChatParticipantCreator):
2021-02-04 E. 188 self.irc.irc_channels_founder[chan].add(user_nick)
2020-11-21 E. 189
01:12:30 ' 190 def get_telegram_nick(self, user):
' 191 nick = (user.username
2021-01-31 E. 192 or self.get_telegram_display_name(user)
2020-11-21 E. 193 or str(user.id))
2021-01-31 E. 194 nick = nick[:NICK_MAX_LENGTH]
2020-11-21 E. 195 while nick in self.irc.iid_to_tid:
01:12:30 ' 196 nick += '_'
' 197 return nick
2021-01-31 E. 198
19:23:45 ' 199 def get_telegram_display_name(self, user):
' 200 name = telethon.utils.get_display_name(user)
' 201 name = name.replace(' ', '_')
' 202 return name
2020-11-21 E. 203
2022-02-05 E. 204 async def get_telegram_display_name_me(self):
02:30:31 ' 205 tg_user = await self.telegram_client.get_me()
' 206 return self.get_telegram_display_name(tg_user)
' 207
2020-11-21 E. 208 def get_telegram_channel(self, chat):
2023-03-18 E. 209 chan = '#' + chat.title.replace(' ', '-').replace(',', '-')
03:43:35 ' 210 while chan.lower() in self.irc.iid_to_tid:
' 211 chan += '_'
' 212 return chan
2020-11-21 E. 213
2021-02-01 E. 214 def get_irc_user_from_telegram(self, tid):
18:48:42 ' 215 nick = self.tid_to_iid[tid]
2021-02-02 E. 216 if nick == self.tg_username: return None
2021-02-01 E. 217 return self.irc.users[nick.lower()]
18:48:42 ' 218
2023-12-02 E. 219 def get_irc_name_from_telegram_id(self, tid):
19:41:44 ' 220 if tid in self.tid_to_iid.keys():
' 221 name_in_irc = self.tid_to_iid[tid]
' 222 else:
' 223 name_in_irc = '<Unknown>'
' 224 return name_in_irc
' 225
2023-06-07 E. 226 async def get_irc_name_from_telegram_forward(self, fwd, saved):
22:26:21 ' 227 from_id = fwd.saved_from_peer if saved else fwd.from_id
' 228 if from_id is None:
2023-04-29 E. 229 # telegram user has privacy options to show only the name
2023-06-07 E. 230 # or was a broadcast from a channel (no user)
22:26:21 ' 231 name = fwd.from_name
2023-04-29 E. 232 else:
2023-06-07 E. 233 peer_id, type = self.get_peer_id_and_type(from_id)
22:26:21 ' 234 if type == 'user':
2023-06-23 E. 235 try:
21:49:58 ' 236 user = self.get_irc_user_from_telegram(peer_id)
' 237 except:
' 238 name = str(peer_id)
2023-06-07 E. 239 else:
2023-06-23 E. 240 if user is None:
21:49:58 ' 241 name = '{}'
' 242 self.refwd_me = True
' 243 else:
' 244 name = user.irc_nick
2023-04-29 E. 245 else:
2023-06-07 E. 246 try:
22:26:21 ' 247 name = await self.get_irc_channel_from_telegram_id(peer_id)
' 248 except:
' 249 name = ''
' 250 return name
2023-04-29 E. 251
2020-11-21 E. 252 async def get_irc_nick_from_telegram_id(self, tid, entity=None):
01:12:30 ' 253 if tid not in self.tid_to_iid:
' 254 user = entity or await self.telegram_client.get_entity(tid)
' 255 nick = self.get_telegram_nick(user)
' 256 self.tid_to_iid[tid] = nick
' 257 self.irc.iid_to_tid[nick] = tid
' 258
' 259 return self.tid_to_iid[tid]
' 260
' 261 async def get_irc_channel_from_telegram_id(self, tid, entity=None):
2023-03-22 E. 262 rtid, type = tgutils.resolve_id(tid)
21:15:41 ' 263 if rtid not in self.tid_to_iid:
2020-11-21 E. 264 chat = entity or await self.telegram_client.get_entity(tid)
01:12:30 ' 265 channel = self.get_telegram_channel(chat)
2023-03-22 E. 266 self.tid_to_iid[rtid] = channel
21:15:41 ' 267 self.irc.iid_to_tid[channel] = rtid
' 268
' 269 return self.tid_to_iid[rtid]
2020-11-21 E. 270
01:12:30 ' 271 async def get_telegram_channel_participants(self, tid):
' 272 channel = self.tid_to_iid[tid]
' 273 nicks = []
' 274 async for user in self.telegram_client.iter_participants(tid):
' 275 user_nick = await self.get_irc_nick_from_telegram_id(user.id, user)
' 276
' 277 nicks.append(user_nick)
' 278 self.irc.irc_channels[channel].add(user_nick)
' 279
2020-11-24 E. 280 return nicks
2020-11-21 E. 281
2021-02-07 E. 282 async def get_telegram_idle(self, irc_nick, tid=None):
2022-02-26 E. 283 if self.irc.users[irc_nick].is_service:
23:47:48 ' 284 return None
2021-02-07 E. 285 tid = self.get_tid(irc_nick, tid)
02:14:36 ' 286 user = await self.telegram_client.get_entity(tid)
' 287 if isinstance(user.status,tgty.UserStatusRecently) or \
' 288 isinstance(user.status,tgty.UserStatusOnline):
' 289 idle = 0
' 290 elif isinstance(user.status,tgty.UserStatusOffline):
' 291 last = user.status.was_online
2024-08-29 E. 292 current = current_date()
2021-02-07 E. 293 idle = int((current - last).total_seconds())
02:14:36 ' 294 elif isinstance(user.status,tgty.UserStatusLastWeek):
' 295 idle = 604800
' 296 elif isinstance(user.status,tgty.UserStatusLastMonth):
' 297 idle = 2678400
' 298 else:
' 299 idle = None
' 300 return idle
' 301
2022-01-30 E. 302 async def get_channel_topic(self, channel, entity_cache):
2021-02-12 E. 303 tid = self.get_tid(channel)
2022-01-30 E. 304 # entity_cache should be a list to be a persistent and by reference value
2021-02-12 E. 305 if entity_cache[0]:
02:09:58 ' 306 entity = entity_cache[0]
' 307 else:
' 308 entity = await self.telegram_client.get_entity(tid)
' 309 entity_cache[0] = entity
2023-04-11 E. 310 entity_type = self.get_entity_type(entity, format='long')
2021-02-12 E. 311 return 'Telegram ' + entity_type + ' ' + str(tid) + ': ' + entity.title
02:09:58 ' 312
2022-01-30 E. 313 async def get_channel_creation(self, channel, entity_cache):
2021-02-12 E. 314 tid = self.get_tid(channel)
02:09:58 ' 315 if tid in self.channels_date.keys():
' 316 timestamp = self.channels_date[tid]
' 317 else:
2022-01-30 E. 318 # entity_cache should be a list to be a persistent and by reference value
2021-02-12 E. 319 if entity_cache[0]:
02:09:58 ' 320 entity = entity_cache[0]
' 321 else:
' 322 entity = await self.telegram_client.get_entity(tid)
' 323 entity_cache[0] = entity
' 324 timestamp = entity.date.timestamp()
' 325 self.channels_date[tid] = timestamp
' 326 return int(timestamp)
' 327
' 328 def get_tid(self, irc_item, tid=None):
' 329 it = irc_item.lower()
2021-02-07 E. 330 if tid:
02:14:36 ' 331 pass
2021-02-12 E. 332 elif it in self.irc.iid_to_tid:
02:09:58 ' 333 tid = self.irc.iid_to_tid[it]
2021-02-07 E. 334 else:
02:14:36 ' 335 tid = self.id
' 336 return tid
' 337
2023-04-11 E. 338 def get_entity_type(self, entity, format):
22:43:22 ' 339 if isinstance(entity, tgty.User):
' 340 short = long = 'User'
' 341 elif isinstance(entity, tgty.Chat):
' 342 short = 'Chat'
' 343 long = 'Chat/Basic Group'
' 344 elif isinstance(entity, tgty.Channel):
' 345 if entity.broadcast:
' 346 short = 'Broad'
' 347 long = 'Broadcast Channel'
' 348 elif entity.megagroup:
' 349 short = 'Mega'
' 350 long = 'Super/Megagroup Channel'
' 351 elif entity.gigagroup:
' 352 short = 'Giga'
' 353 long = 'Broadcast Gigagroup Channel'
' 354
' 355 return short if format == 'short' else long
2021-02-12 E. 356
2023-06-07 E. 357 def get_peer_id_and_type(self, peer):
22:26:21 ' 358 if isinstance(peer, tgty.PeerChannel):
' 359 id = peer.channel_id
' 360 type = 'chan'
' 361 elif isinstance(peer, tgty.PeerChat):
' 362 id = peer.chat_id
' 363 type = 'chan'
' 364 elif isinstance(peer, tgty.PeerUser):
' 365 id = peer.user_id
' 366 type = 'user'
' 367 else:
' 368 id = peer
' 369 type = ''
' 370 return id, type
' 371
2023-04-19 E. 372 async def is_bot(self, irc_nick, tid=None):
23:49:15 ' 373 user = self.irc.users[irc_nick]
' 374 if user.stream or user.is_service:
' 375 bot = False
' 376 else:
' 377 bot = user.bot
' 378 if bot == None:
' 379 tid = self.get_tid(irc_nick, tid)
' 380 tg_user = await self.telegram_client.get_entity(tid)
' 381 bot = tg_user.bot
' 382 user.bot = bot
' 383 return bot
' 384
2023-04-25 E. 385 async def edition_case(self, msg):
20:34:42 ' 386 def msg_edited(m):
' 387 return m.id in self.cache and \
' 388 ( m.message != self.cache[m.id]['text']
' 389 or m.media != self.cache[m.id]['media']
' 390 )
' 391 async def get_reactions(m):
' 392 react = await self.telegram_client(GetMessagesReactionsRequest(m.peer_id, id=[m.id]))
2024-09-14 E. 393 updates = react.updates
23:23:24 ' 394 r = next((x for x in updates if type(x) is tgty.UpdateMessageReactions), None)
' 395 return r.reactions.recent_reactions if r else None
2023-04-25 E. 396
20:34:42 ' 397 react = None
' 398 if msg.reactions is None:
' 399 case = 'edition'
' 400 elif (reactions := await get_reactions(msg)) is None:
' 401 if msg_edited(msg):
' 402 case = 'edition'
' 403 else:
' 404 case = 'react-del'
2024-09-24 E. 405 elif react := max(reactions, key=lambda y: y.date):
2023-04-25 E. 406 case = 'react-add'
20:34:42 ' 407 else:
' 408 if msg_edited(msg):
' 409 case = 'edition'
' 410 else:
' 411 case = 'react-del'
' 412 react = None
' 413 return case, react
' 414
' 415 def to_cache(self, id, mid, message, proc_message, user, chan, media):
2024-08-30 E. 416 self.limit_cache(self.cache)
2023-04-08 E. 417 self.cache[id] = {
10:30:10 ' 418 'mid': mid,
2023-04-15 E. 419 'text': message,
23:13:07 ' 420 'rendered_text': proc_message,
2023-04-08 E. 421 'user': user,
2023-04-25 E. 422 'channel': chan,
2024-08-29 E. 423 'media': media,
2023-04-08 E. 424 }
10:30:10 ' 425
2024-08-30 E. 426 def to_volatile_cache(self, prev_id, id, ev, user, chan, date):
19:53:13 ' 427 if chan in prev_id:
' 428 prid = prev_id[chan] if chan else prev_id[user]
' 429 self.limit_cache(self.volatile_cache)
' 430 elem = {
' 431 'id': id,
' 432 'rendered_event': ev,
' 433 'user': user,
' 434 'channel': chan,
' 435 'date': date,
' 436 }
' 437 if prid not in self.volatile_cache:
' 438 self.volatile_cache[prid] = [elem]
' 439 else:
' 440 self.volatile_cache[prid].append(elem)
' 441
' 442 def limit_cache(self, cache):
' 443 if len(cache) >= 10000:
' 444 cache.popitem(last=False)
' 445
2023-06-15 E. 446 def replace_mentions(self, text, me_nick='', received=True):
18:08:03 ' 447 # For received replace @mention to ~mention~
' 448 # For sent replace mention: to @mention
' 449 rargs = {}
2023-07-07 E. 450 def repl_mentioned(text, me_nick, received, mark, repl_pref, repl_suff):
23:58:26 ' 451 new_text = text
' 452
' 453 for user in self.sorted_len_usernames:
' 454 if user == self.tg_username:
' 455 if me_nick:
' 456 username = me_nick
' 457 else:
' 458 continue
' 459 else:
' 460 username = self.irc.users[user].irc_nick
' 461
2023-06-15 E. 462 if received:
2023-07-07 E. 463 mention = mark + user
23:58:26 ' 464 mention_case = mark + username
' 465 else: # sent
' 466 mention = user + mark
' 467 mention_case = username + mark
' 468 replcmnt = repl_pref + username + repl_suff
' 469
' 470 # Start of the text
' 471 for ment in (mention, mention_case):
' 472 if new_text.startswith(ment):
' 473 new_text = new_text.replace(ment, replcmnt, 1)
' 474
' 475 # Next words (with space as separator)
' 476 mention = ' ' + mention
' 477 mention_case = ' ' + mention_case
' 478 replcmnt = ' ' + replcmnt
' 479 new_text = new_text.replace(mention, replcmnt).replace(mention_case, replcmnt)
' 480
' 481 return new_text
2023-06-15 E. 482
18:08:03 ' 483 if received:
' 484 mark = '@'
' 485 rargs['repl_pref'] = '~'
' 486 rargs['repl_suff'] = '~'
2023-07-07 E. 487 else: # sent
2023-06-15 E. 488 mark = ':'
18:08:03 ' 489 rargs['repl_pref'] = '@'
' 490 rargs['repl_suff'] = ''
' 491
' 492 if text.find(mark) != -1:
2023-07-07 E. 493 text_replaced = repl_mentioned(text, me_nick, received, mark, **rargs)
2023-05-20 E. 494 else:
21:39:03 ' 495 text_replaced = text
' 496 return text_replaced
' 497
' 498 def filters(self, text):
' 499 filtered = e.replace_mult(text, e.emo)
' 500 filtered = self.replace_mentions(filtered)
' 501 return filtered
' 502
2023-07-07 E. 503 def add_sorted_len_usernames(self, username):
23:58:26 ' 504 self.sorted_len_usernames.append(username)
' 505 self.sorted_len_usernames.sort(key=lambda k: len(k), reverse=True)
' 506
2024-09-27 E. 507 def format_reaction(self, msg, message_rendered, edition_case, reaction):
2024-10-13 E. 508 react_quote_len = self.quote_len * 2
21:00:24 ' 509 if len(message_rendered) > react_quote_len:
' 510 text_old = '{}...'.format(message_rendered[:react_quote_len])
2024-09-27 E. 511 text_old = fix_braces(text_old)
09:05:53 ' 512 else:
' 513 text_old = message_rendered
' 514
' 515 if edition_case == 'react-add':
' 516 user = self.get_irc_user_from_telegram(reaction.peer_id.user_id)
' 517 emoji = reaction.reaction.emoticon
' 518 react_action = '+'
' 519 react_icon = e.emo[emoji] if emoji in e.emo else emoji
' 520 elif edition_case == 'react-del':
2024-10-06 E. 521 user = self.get_irc_user_from_telegram(msg.sender_id)
2024-09-27 E. 522 react_action = '-'
09:05:53 ' 523 react_icon = ''
' 524 return text_old, '{}{}'.format(react_action, react_icon), user
' 525
2023-04-15 E. 526 async def handle_telegram_edited(self, event):
2024-08-24 E. 527 self.logger.debug('Handling Telegram Message Edited: %s', pretty(event))
2023-04-15 E. 528
23:13:07 ' 529 id = event.message.id
2023-05-15 E. 530 mid = self.mid.num_to_id_offset(event.message.peer_id, id)
2023-04-15 E. 531 fmid = '[{}]'.format(mid)
2023-05-20 E. 532 message = self.filters(event.message.message)
2023-05-02 E. 533 message_rendered = await self.render_text(event.message, mid, upd_to_webpend=None)
2023-04-15 E. 534
2023-04-25 E. 535 edition_case, reaction = await self.edition_case(event.message)
20:34:42 ' 536 if edition_case == 'edition':
' 537 action = 'Edited'
' 538 user = self.get_irc_user_from_telegram(event.sender_id)
' 539 if id in self.cache:
2023-05-20 E. 540 t = self.filters(self.cache[id]['text'])
2023-04-25 E. 541 rt = self.cache[id]['rendered_text']
20:34:42 ' 542
' 543 ht, is_ht = get_highlighted(t, message)
' 544 else:
' 545 rt = fmid
' 546 is_ht = False
' 547
' 548 if is_ht:
' 549 edition_react = ht
' 550 text_old = fmid
' 551 else:
' 552 edition_react = message
' 553 text_old = rt
' 554 if user is None:
' 555 self.refwd_me = True
' 556
' 557 # Reactions
2023-04-15 E. 558 else:
2024-10-06 E. 559 if reaction:
21:59:23 ' 560 if self.last_reaction == reaction.date:
' 561 return
' 562 self.last_reaction = reaction.date
2023-04-25 E. 563 action = 'React'
2024-09-27 E. 564 text_old, edition_react, user = self.format_reaction(event.message, message_rendered, edition_case, reaction)
2023-04-25 E. 565
20:34:42 ' 566 text = '|{} {}| {}'.format(action, text_old, edition_react)
' 567
2023-04-15 E. 568 chan = await self.relay_telegram_message(event, user, text)
23:13:07 ' 569
2023-04-25 E. 570 self.to_cache(id, mid, message, message_rendered, user, chan, event.message.media)
2024-08-30 E. 571 self.to_volatile_cache(self.prev_id, id, text, user, chan, current_date())
2023-04-15 E. 572
2024-09-27 E. 573 async def handle_next_reaction(self, event):
09:05:53 ' 574 self.logger.debug('Handling Telegram Next Reaction (2nd, 3rd, ...): %s', pretty(event))
' 575
' 576 reactions = event.reactions.recent_reactions
' 577 react = max(reactions, key=lambda y: y.date)
2024-09-28 E. 578
00:53:06 ' 579 if self.last_reaction != react.date:
' 580 self.last_reaction = react.date
' 581 id = event.msg_id
' 582 msg = await self.telegram_client.get_messages(entity=event.peer, ids=id)
' 583 mid = self.mid.num_to_id_offset(msg.peer_id, id)
' 584 message = self.filters(msg.message)
' 585 message_rendered = await self.render_text(msg, mid, upd_to_webpend=None)
' 586
' 587 text_old, edition_react, user = self.format_reaction(msg, message_rendered, edition_case='react-add', reaction=react)
' 588
' 589 text = '|React {}| {}'.format(text_old, edition_react)
' 590
' 591 chan = await self.relay_telegram_message(msg, user, text)
' 592
' 593 self.to_cache(id, mid, message, message_rendered, user, chan, msg.media)
' 594 self.to_volatile_cache(self.prev_id, id, text, user, chan, current_date())
2024-09-27 E. 595
2023-04-10 E. 596 async def handle_telegram_deleted(self, event):
2024-08-24 E. 597 self.logger.debug('Handling Telegram Message Deleted: %s', pretty(event))
2023-04-10 E. 598
21:31:19 ' 599 for deleted_id in event.original_update.messages:
' 600 if deleted_id in self.cache:
' 601 recovered_text = self.cache[deleted_id]['rendered_text']
' 602 text = '|Deleted| {}'.format(recovered_text)
' 603 user = self.cache[deleted_id]['user']
' 604 chan = self.cache[deleted_id]['channel']
2023-05-06 E. 605 await self.relay_telegram_message(message=None, user=user, text=text, channel=chan)
2024-08-30 E. 606 self.to_volatile_cache(self.prev_id, deleted_id, text, user, chan, current_date())
2023-04-10 E. 607 else:
2023-05-15 E. 608 text = 'Message id {} deleted not in cache'.format(deleted_id)
2023-04-10 E. 609 await self.relay_telegram_private_message(self.irc.service_user, text)
21:31:19 ' 610
2022-02-08 E. 611 async def handle_raw(self, update):
2024-08-24 E. 612 self.logger.debug('Handling Telegram Raw Event: %s', pretty(update))
2023-03-31 E. 613
2022-02-08 E. 614 if isinstance(update, tgty.UpdateWebPage) and isinstance(update.webpage, tgty.WebPage):
2023-05-02 E. 615 message = self.webpending.pop(update.webpage.id, None)
21:37:17 ' 616 if message:
' 617 await self.handle_telegram_message(event=None, message=message, upd_to_webpend=update.webpage)
' 618
2024-09-27 E. 619 elif isinstance(update, tgty.UpdateMessageReactions):
09:05:53 ' 620 await self.handle_next_reaction(update)
' 621
2023-05-06 E. 622 async def handle_telegram_message(self, event, message=None, upd_to_webpend=None, history=False):
2024-08-24 E. 623 self.logger.debug('Handling Telegram Message: %s', pretty(event or message))
2023-05-02 E. 624
2023-05-04 E. 625 msg = event.message if event else message
2023-05-02 E. 626
21:37:17 ' 627 user = self.get_irc_user_from_telegram(msg.sender_id)
2023-05-15 E. 628 mid = self.mid.num_to_id_offset(msg.peer_id, msg.id)
2023-10-15 E. 629 text = await self.render_text(msg, mid, upd_to_webpend, user)
2023-11-26 E. 630 text_send = self.set_history_timestamp(text, history, msg.date, msg.action)
2023-05-06 E. 631 chan = await self.relay_telegram_message(msg, user, text_send)
2024-08-30 E. 632 await self.history_search_volatile(history, msg.id)
2023-05-02 E. 633
21:37:17 ' 634 self.to_cache(msg.id, mid, msg.message, text, user, chan, msg.media)
2024-08-30 E. 635 peer = chan if chan else user
19:53:13 ' 636 self.prev_id[peer] = msg.id
2023-04-15 E. 637
23:13:07 ' 638 self.refwd_me = False
' 639
2023-10-15 E. 640 async def render_text(self, message, mid, upd_to_webpend, user=None):
2022-02-08 E. 641 if upd_to_webpend:
2023-12-17 E. 642 text = await self.handle_webpage(upd_to_webpend, message, mid)
2023-05-02 E. 643 elif message.media:
2023-10-15 E. 644 text = await self.handle_telegram_media(message, user, mid)
2022-01-30 E. 645 else:
2023-05-02 E. 646 text = message.message
21:37:17 ' 647
2023-11-26 E. 648 if message.action:
2023-12-17 E. 649 final_text = await self.handle_telegram_action(message, mid)
2023-11-26 E. 650 return final_text
19:07:44 ' 651 elif message.is_reply:
2023-05-02 E. 652 refwd_text = await self.handle_telegram_reply(message)
21:37:17 ' 653 elif message.forward:
' 654 refwd_text = await self.handle_telegram_forward(message)
2023-03-28 E. 655 else:
21:32:36 ' 656 refwd_text = ''
' 657
2023-12-02 E. 658 target_mine = self.handle_target_mine(message.peer_id, user)
19:41:44 ' 659
' 660 final_text = '[{}] {}{}{}'.format(mid, target_mine, refwd_text, text)
2023-05-20 E. 661 final_text = self.filters(final_text)
2023-05-02 E. 662 return final_text
21:37:17 ' 663
2023-11-26 E. 664 def set_history_timestamp(self, text, history, date, action):
2023-05-06 E. 665 if history and self.hist_fmt:
23:31:34 ' 666 timestamp = format_timestamp(self.hist_fmt, self.timezone, date)
2023-11-26 E. 667 if action:
19:07:44 ' 668 res = '{} {}'.format(text, timestamp)
' 669 else:
' 670 res = '{} {}'.format(timestamp, text)
2023-05-06 E. 671 else:
23:31:34 ' 672 res = text
' 673 return res
' 674
2024-08-30 E. 675 async def history_search_volatile(self, history, id):
19:53:13 ' 676 if history:
' 677 if id in self.volatile_cache:
' 678 for item in self.volatile_cache[id]:
' 679 user = item['user']
' 680 text = item['rendered_event']
' 681 chan = item['channel']
' 682 date = item['date']
' 683 text_send = self.set_history_timestamp(text, history=True, date=date, action=False)
' 684 await self.relay_telegram_message(None, user, text_send, chan)
' 685
2023-05-02 E. 686 async def relay_telegram_message(self, message, user, text, channel=None):
21:37:17 ' 687 private = (message and message.is_private) or (not message and not channel)
2023-11-26 E. 688 action = (message and message.action)
2023-04-08 E. 689 if private:
2023-11-26 E. 690 await self.relay_telegram_private_message(user, text, action)
2023-04-08 E. 691 chan = None
2020-11-21 E. 692 else:
2023-11-26 E. 693 chan = await self.relay_telegram_channel_message(message, user, text, channel, action)
2023-04-08 E. 694 return chan
2023-03-28 E. 695
2023-11-26 E. 696 async def relay_telegram_private_message(self, user, message, action=None):
2024-09-15 E. 697 self.logger.debug('Relaying Telegram Private Message: %s, %s', user, message)
2022-01-24 E. 698
2023-11-26 E. 699 if action:
19:07:44 ' 700 await self.irc.send_action(user, None, message)
' 701 else:
' 702 await self.irc.send_msg(user, None, message)
' 703
' 704 async def relay_telegram_channel_message(self, message, user, text, channel, action):
2023-05-02 E. 705 if message:
21:37:17 ' 706 entity = await message.get_chat()
' 707 chan = await self.get_irc_channel_from_telegram_id(message.chat_id, entity)
2023-04-08 E. 708 else:
23:07:35 ' 709 chan = channel
2023-11-26 E. 710
2024-09-15 E. 711 self.logger.debug('Relaying Telegram Channel Message: %s, %s', chan, text)
21:50:10 ' 712
2023-11-26 E. 713 if action:
19:07:44 ' 714 await self.irc.send_action(user, chan, text)
' 715 else:
' 716 await self.irc.send_msg(user, chan, text)
' 717
2023-04-08 E. 718 return chan
2020-11-21 E. 719
01:12:30 ' 720 async def handle_telegram_chat_action(self, event):
2024-08-24 E. 721 self.logger.debug('Handling Telegram Chat Action: %s', pretty(event))
2020-11-21 E. 722
01:12:30 ' 723 try:
' 724 tid = event.action_message.to_id.channel_id
' 725 except AttributeError:
' 726 tid = event.action_message.to_id.chat_id
' 727 finally:
' 728 irc_channel = await self.get_irc_channel_from_telegram_id(tid)
' 729 await self.get_telegram_channel_participants(tid)
' 730
' 731 try: # Join Chats
' 732 irc_nick = await self.get_irc_nick_from_telegram_id(event.action_message.action.users[0])
' 733 except (IndexError, AttributeError):
' 734 try: # Kick
' 735 irc_nick = await self.get_irc_nick_from_telegram_id(event.action_message.action.user_id)
' 736 except (IndexError, AttributeError): # Join Channels
' 737 irc_nick = await self.get_irc_nick_from_telegram_id(event.action_message.sender_id)
' 738
' 739 if event.user_added or event.user_joined:
2023-03-24 E. 740 await self.irc.join_irc_channel(irc_nick, irc_channel, full_join=False)
2020-11-21 E. 741 elif event.user_kicked or event.user_left:
01:12:30 ' 742 await self.irc.part_irc_channel(irc_nick, irc_channel)
' 743
' 744 async def join_all_telegram_channels(self):
' 745 async for dialog in self.telegram_client.iter_dialogs():
' 746 chat = dialog.entity
2021-02-01 E. 747 if not isinstance(chat, tgty.User):
2020-11-21 E. 748 channel = self.get_telegram_channel(chat)
01:12:30 ' 749 self.tid_to_iid[chat.id] = channel
' 750 self.irc.iid_to_tid[channel] = chat.id
2023-03-24 E. 751 await self.irc.join_irc_channel(self.irc.irc_nick, channel, full_join=True)
2020-11-21 E. 752
2023-12-17 E. 753 async def handle_telegram_action(self, message, mid):
2023-11-26 E. 754 if isinstance(message.action, tgty.MessageActionPinMessage):
19:07:44 ' 755 replied = await message.get_reply_message()
' 756 cid = self.mid.num_to_id_offset(replied.peer_id, replied.id)
' 757 action_text = 'has pinned message [{}]'.format(cid)
2023-11-26 E. 758 elif isinstance(message.action, tgty.MessageActionChatEditPhoto):
22:13:52 ' 759 _, media_type = self.scan_photo_attributes(message.action.photo)
2023-12-17 E. 760 photo_url = await self.download_telegram_media(message, mid)
2023-11-26 E. 761 action_text = 'has changed chat [{}] {}'.format(media_type, photo_url)
2023-11-26 E. 762 else:
19:07:44 ' 763 action_text = ''
' 764 return action_text
' 765
2023-05-02 E. 766 async def handle_telegram_reply(self, message):
2023-07-22 E. 767 space = ' '
2023-03-28 E. 768 trunc = ''
2023-05-02 E. 769 replied = await message.get_reply_message()
2024-08-14 E. 770 if replied:
23:30:54 ' 771 replied_msg = replied.message
' 772 cid = self.mid.num_to_id_offset(replied.peer_id, replied.id)
' 773 replied_user = self.get_irc_user_from_telegram(replied.sender_id)
' 774 else:
' 775 replied_id = message.reply_to.reply_to_msg_id
' 776 cid = self.mid.num_to_id_offset(message.peer_id, replied_id)
' 777 if replied_id in self.cache:
' 778 text = self.cache[replied_id]['text']
' 779 replied_user = self.cache[replied_id]['user']
' 780 sp = ' '
' 781 else:
' 782 text = ''
' 783 replied_user = ''
' 784 sp = ''
' 785 replied_msg = '|Deleted|{}{}'.format(sp, text)
2023-05-02 E. 786 if not replied_msg:
2023-07-22 E. 787 replied_msg = ''
18:32:19 ' 788 space = ''
2023-05-02 E. 789 elif len(replied_msg) > self.quote_len:
21:37:17 ' 790 replied_msg = replied_msg[:self.quote_len]
2023-03-28 E. 791 trunc = '...'
21:32:36 ' 792 if replied_user is None:
' 793 replied_nick = '{}'
' 794 self.refwd_me = True
2024-08-14 E. 795 elif replied_user == '':
23:30:54 ' 796 replied_nick = ''
2023-03-28 E. 797 else:
21:32:36 ' 798 replied_nick = replied_user.irc_nick
' 799
2023-07-22 E. 800 return '|Re {}: [{}]{}{}{}| '.format(replied_nick, cid, space, replied_msg, trunc)
2023-05-02 E. 801
21:37:17 ' 802 async def handle_telegram_forward(self, message):
2023-06-07 E. 803 space = space2 = ' '
22:26:21 ' 804 if not (forwarded_peer_name := await self.get_irc_name_from_telegram_forward(message.fwd_from, saved=False)):
' 805 space = ''
' 806 saved_peer_name = await self.get_irc_name_from_telegram_forward(message.fwd_from, saved=True)
' 807 if saved_peer_name and saved_peer_name != forwarded_peer_name:
' 808 secondary_name = saved_peer_name
2023-03-28 E. 809 else:
21:32:36 ' 810 # if it's from me I want to know who was the destination of a message (user)
2024-04-07 E. 811 if self.refwd_me and (saved_from_peer := message.fwd_from.saved_from_peer) is not None:
17:48:33 ' 812 secondary_name = self.get_irc_user_from_telegram(saved_from_peer.user_id).irc_nick
2023-03-28 E. 813 else:
2023-06-07 E. 814 secondary_name = ''
22:26:21 ' 815 space2 = ''
' 816
' 817 return '|Fwd{}{}{}{}| '.format(space, forwarded_peer_name, space2, secondary_name)
2023-03-28 E. 818
2023-10-15 E. 819 async def handle_telegram_media(self, message, user, mid):
2022-01-30 E. 820 caption = ' | {}'.format(message.message) if message.message else ''
00:29:08 ' 821 to_download = True
' 822 media_url_or_data = ''
2023-10-15 E. 823 size = 0
2023-11-18 E. 824 filename = None
23:43:04 ' 825
' 826 def scan_doc_attributes(document):
2023-12-14 E. 827 attrib_file = attrib_av = filename = None
2023-11-18 E. 828 size = document.size
23:43:04 ' 829 h_size = get_human_size(size)
' 830 for x in document.attributes:
2023-12-14 E. 831 if isinstance(x, tgty.DocumentAttributeVideo) or isinstance(x, tgty.DocumentAttributeAudio):
23:00:44 ' 832 attrib_av = x
2023-11-18 E. 833 if isinstance(x, tgty.DocumentAttributeFilename):
23:43:04 ' 834 attrib_file = x
' 835 filename = attrib_file.file_name if attrib_file else None
' 836
2023-12-14 E. 837 return size, h_size, attrib_av, filename
2022-01-30 E. 838
2022-02-08 E. 839 if isinstance(message.media, tgty.MessageMediaWebPage):
2022-01-30 E. 840 to_download = False
2022-02-08 E. 841 if isinstance(message.media.webpage, tgty.WebPage):
01:04:55 ' 842 # web
2023-12-17 E. 843 return await self.handle_webpage(message.media.webpage, message, mid)
2022-02-08 E. 844 elif isinstance(message.media.webpage, tgty.WebPagePending):
01:04:55 ' 845 media_type = 'webpending'
' 846 media_url_or_data = message.message
' 847 caption = ''
2023-05-02 E. 848 self.webpending[message.media.webpage.id] = message
2022-01-30 E. 849 else:
2022-02-08 E. 850 media_type = 'webunknown'
01:04:55 ' 851 media_url_or_data = message.message
2022-01-30 E. 852 caption = ''
2022-01-30 E. 853 elif message.photo:
2023-11-26 E. 854 size, media_type = self.scan_photo_attributes(message.media.photo)
2023-12-14 E. 855 elif message.audio:
23:00:44 ' 856 size, h_size, attrib_audio, filename = scan_doc_attributes(message.media.document)
' 857 dur = get_human_duration(attrib_audio.duration) if attrib_audio else ''
' 858 per = attrib_audio.performer or ''
' 859 tit = attrib_audio.title or ''
' 860 theme = ',{}/{}'.format(per, tit) if per or tit else ''
' 861 media_type = 'audio:{},{}{}'.format(h_size, dur, theme)
' 862 elif message.voice:
' 863 size, _, attrib_audio, filename = scan_doc_attributes(message.media.document)
' 864 dur = get_human_duration(attrib_audio.duration) if attrib_audio else ''
' 865 media_type = 'rec:{}'.format(dur)
2022-02-09 E. 866 elif message.video:
2023-11-18 E. 867 size, h_size, attrib_video, filename = scan_doc_attributes(message.media.document)
23:43:04 ' 868 dur = get_human_duration(attrib_video.duration) if attrib_video else ''
2023-10-15 E. 869 media_type = 'video:{},{}'.format(h_size, dur)
2022-01-30 E. 870 elif message.video_note: media_type = 'videorec'
00:29:08 ' 871 elif message.gif: media_type = 'anim'
' 872 elif message.sticker: media_type = 'sticker'
2022-02-09 E. 873 elif message.document:
2023-11-18 E. 874 size, h_size, _, filename = scan_doc_attributes(message.media.document)
2023-10-15 E. 875 media_type = 'file:{}'.format(h_size)
2022-01-30 E. 876 elif message.contact:
00:29:08 ' 877 media_type = 'contact'
' 878 caption = ''
' 879 to_download = False
2023-06-01 E. 880 if message.media.first_name:
17:55:14 ' 881 media_url_or_data += message.media.first_name + ' '
' 882 if message.media.last_name:
' 883 media_url_or_data += message.media.last_name + ' '
' 884 if message.media.phone_number:
' 885 media_url_or_data += message.media.phone_number
2022-01-30 E. 886
00:29:08 ' 887 elif message.game:
' 888 media_type = 'game'
' 889 caption = ''
' 890 to_download = False
' 891 if message.media.game.title:
' 892 media_url_or_data = message.media.game.title
' 893
' 894 elif message.geo:
' 895 media_type = 'geo'
' 896 caption = ''
' 897 to_download = False
2023-07-20 E. 898 if self.geo_url:
23:12:18 ' 899 geo_url = ' | ' + self.geo_url
' 900 else:
' 901 geo_url = ''
' 902 lat_long_template = 'lat: {lat}, long: {long}' + geo_url
' 903 media_url_or_data = lat_long_template.format(lat=message.media.geo.lat, long=message.media.geo.long)
2022-01-30 E. 904
00:29:08 ' 905 elif message.invoice:
' 906 media_type = 'invoice'
' 907 caption = ''
' 908 to_download = False
' 909 media_url_or_data = ''
' 910
' 911 elif message.poll:
' 912 media_type = 'poll'
' 913 caption = ''
' 914 to_download = False
2023-10-10 E. 915 media_url_or_data = self.handle_poll(message.media.poll)
2022-01-30 E. 916
00:29:08 ' 917 elif message.venue:
' 918 media_type = 'venue'
' 919 caption = ''
' 920 to_download = False
' 921 media_url_or_data = ''
2022-02-08 E. 922 else:
01:04:55 ' 923 media_type = 'unknown'
' 924 caption = ''
' 925 to_download = False
' 926 media_url_or_data = message.message
2022-01-30 E. 927
00:29:08 ' 928 if to_download:
2023-11-18 E. 929 relay_attr = (message, user, mid, media_type)
2023-12-17 E. 930 media_url_or_data = await self.download_telegram_media(message, mid, filename, size, relay_attr)
2022-01-30 E. 931
2022-02-08 E. 932 return self.format_media(media_type, media_url_or_data, caption)
01:04:55 ' 933
2023-10-10 E. 934 def handle_poll(self, poll):
22:35:28 ' 935 text = poll.question
' 936 for ans in poll.answers:
' 937 text += '\n* ' + ans.text
' 938 return text
' 939
2023-12-02 E. 940 def handle_target_mine(self, target, user):
19:41:44 ' 941 # Add the target of messages sent by self user (me)
' 942 # received in other clients
' 943 target_id, target_type = self.get_peer_id_and_type(target)
' 944 if user is None and target_type == 'user' and target_id != self.id:
' 945 # self user^
' 946 # as sender
' 947 irc_id = self.get_irc_name_from_telegram_id(target_id)
' 948 target_mine = '[T: {}] '.format(irc_id)
' 949 else:
' 950 target_mine = ''
' 951 return target_mine
' 952
2023-12-17 E. 953 async def handle_webpage(self, webpage, message, mid):
2022-02-08 E. 954 media_type = 'web'
2023-12-17 E. 955 logo = await self.download_telegram_media(message, mid)
2022-02-19 E. 956 if is_url_equiv(webpage.url, webpage.display_url):
01:10:00 ' 957 url_data = webpage.url
2022-02-08 E. 958 else:
2022-02-19 E. 959 url_data = '{} | {}'.format(webpage.url, webpage.display_url)
2022-02-08 E. 960 if message:
01:04:55 ' 961 # sometimes the 1st line of message contains the title, don't repeat it
' 962 message_line = message.message.splitlines()[0]
' 963 if message_line != webpage.title:
' 964 title = webpage.title
' 965 else:
' 966 title = ''
2022-02-19 E. 967 # extract the URL in the message, don't repeat it
01:10:00 ' 968 message_url = extract_url(message.message)
' 969 if is_url_equiv(message_url, webpage.url):
' 970 if is_url_equiv(message_url, webpage.display_url):
' 971 media_url_or_data = message.message
' 972 else:
' 973 media_url_or_data = '{} | {}'.format(message.message, webpage.display_url)
' 974 else:
' 975 media_url_or_data = '{} | {}'.format(message.message, url_data)
2022-02-08 E. 976 else:
01:04:55 ' 977 title = webpage.title
2022-02-19 E. 978 media_url_or_data = url_data
2022-02-08 E. 979
01:04:55 ' 980 if title and logo:
' 981 caption = ' | {} | {}'.format(title, logo)
' 982 elif title:
' 983 caption = ' | {}'.format(title)
' 984 elif logo:
' 985 caption = ' | {}'.format(logo)
' 986 else:
' 987 caption = ''
' 988
' 989 return self.format_media(media_type, media_url_or_data, caption)
' 990
' 991 def format_media(self, media_type, media_url_or_data, caption):
2022-01-30 E. 992 return '[{}] {}{}'.format(media_type, media_url_or_data, caption)
00:29:08 ' 993
2023-11-26 E. 994 def scan_photo_attributes(self, photo):
22:13:52 ' 995 size = 0
' 996 sizes = photo.sizes
' 997 ph_size = sizes[-1]
' 998 if isinstance(ph_size, tgty.PhotoSizeProgressive):
' 999 size = ph_size.sizes[-1]
' 1000 else:
' 1001 for x in sizes:
' 1002 if isinstance(x, tgty.PhotoSize):
' 1003 if x.size > size:
' 1004 size = x.size
' 1005 ph_size = x
' 1006 if hasattr(ph_size, 'w') and hasattr(ph_size, 'h'):
' 1007 media_type = 'photo:{}x{}'.format(ph_size.w, ph_size.h)
' 1008 else:
' 1009 media_type = 'photo'
' 1010
' 1011 return size, media_type
' 1012
2023-12-17 E. 1013 async def download_telegram_media(self, message, mid, filename=None, size=0, relay_attr=None):
2023-11-18 E. 1014 if not self.download:
23:43:04 ' 1015 return ''
' 1016 if filename:
2023-12-17 E. 1017 idd_file = add_filename(filename, mid)
01:49:18 ' 1018 new_file = sanitize_filename(idd_file)
2023-11-18 E. 1019 new_path = os.path.join(self.telegram_media_dir, new_file)
23:43:04 ' 1020 if os.path.exists(new_path):
' 1021 local_path = new_path
' 1022 else:
' 1023 await self.notice_downloading(size, relay_attr)
' 1024 local_path = await message.download_media(new_path)
' 1025 if not local_path: return ''
' 1026 else:
' 1027 await self.notice_downloading(size, relay_attr)
2023-10-15 E. 1028 local_path = await message.download_media(self.telegram_media_dir)
2023-11-18 E. 1029 if not local_path: return ''
2022-01-30 E. 1030 filetype = os.path.splitext(local_path)[1]
2023-12-17 E. 1031 gen_file = str(self.media_cn) + filetype
01:49:18 ' 1032 idd_file = add_filename(gen_file, mid)
' 1033 new_file = sanitize_filename(idd_file)
2022-01-30 E. 1034 self.media_cn += 1
2023-11-18 E. 1035 new_path = os.path.join(self.telegram_media_dir, new_file)
23:43:04 ' 1036
2022-01-30 E. 1037 if local_path != new_path:
00:29:08 ' 1038 os.replace(local_path, new_path)
' 1039 if self.media_url[-1:] != '/':
' 1040 self.media_url += '/'
' 1041 return self.media_url + new_file
2022-01-26 E. 1042
2023-11-18 E. 1043 async def notice_downloading(self, size, relay_attr):
23:43:04 ' 1044 if relay_attr and size > self.notice_size:
' 1045 message, user, mid, media_type = relay_attr
' 1046 await self.relay_telegram_message(message, user, '[{}] [{}] [Downloading]'.format(mid, media_type))
' 1047
2022-01-26 E. 1048 class mesg_id:
21:30:58 ' 1049 def __init__(self, alpha):
' 1050 self.alpha = alpha
' 1051 self.base = len(alpha)
' 1052 self.alphaval = { i:v for v, i in enumerate(alpha) }
2023-05-15 E. 1053 self.mesg_base = {}
2022-01-26 E. 1054
21:30:58 ' 1055 def num_to_id(self, num, neg=''):
' 1056 if num < 0: return self.num_to_id(-num, '-')
' 1057 (high, low) = divmod(num, self.base)
' 1058 if high >= self.base:
' 1059 aux = self.num_to_id(high)
' 1060 return neg + aux + self.alpha[low]
' 1061 else:
' 1062 return neg + self.alpha[high] + self.alpha[low]
' 1063
2023-05-15 E. 1064 def num_to_id_offset(self, peer, num):
19:27:05 ' 1065 peer_id = self.get_peer_id(peer)
' 1066 if peer_id not in self.mesg_base:
' 1067 self.mesg_base[peer_id] = num
' 1068 return self.num_to_id(num - self.mesg_base[peer_id])
2023-04-10 E. 1069
2022-01-26 E. 1070 def id_to_num(self, id, n=1):
21:30:58 ' 1071 if id:
' 1072 if id[0] == '-': return self.id_to_num(id[1:], -1)
' 1073 aux = self.alphaval[id[-1:]] * n
' 1074 sum = self.id_to_num(id[:-1], n * self.base)
' 1075 return sum + aux
' 1076 else:
' 1077 return 0
2023-05-13 E. 1078
2023-05-15 E. 1079 def id_to_num_offset(self, peer, mid):
19:27:05 ' 1080 peer_id = self.get_peer_id(peer)
' 1081 if peer_id in self.mesg_base:
2023-05-13 E. 1082 id_rel = self.id_to_num(mid)
2023-05-15 E. 1083 id = id_rel + self.mesg_base[peer_id]
2023-05-13 E. 1084 else:
22:39:42 ' 1085 id = None
2023-05-15 E. 1086 return id
19:27:05 ' 1087
' 1088 def get_peer_id(self, peer):
' 1089 if isinstance(peer, tgty.PeerChannel):
' 1090 id = peer.channel_id
' 1091 elif isinstance(peer, tgty.PeerChat):
' 1092 id = peer.chat_id
' 1093 elif isinstance(peer, tgty.PeerUser):
' 1094 id = peer.user_id
' 1095 else:
' 1096 id = peer
2023-05-13 E. 1097 return id