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