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