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