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