Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
jordanwildon
GitHub Repository: jordanwildon/Telepathy
Path: blob/main/src/telepathy/utils.py
201 views
1
from colorama import Fore, Style
2
from googletrans import Translator
3
from src.telepathy.const import __version__, user_agent
4
import requests
5
import textwrap
6
from bs4 import BeautifulSoup
7
import random
8
import os
9
10
11
def createPlaceholdeCls():
12
class Object(object):
13
pass
14
15
a = Object()
16
return a
17
18
19
def print_banner():
20
print(
21
Fore.GREEN
22
+ """
23
______ __ __ __
24
/_ __/__ / /__ ____ ____ _/ /_/ /_ __ __
25
/ / / _ \/ / _ \/ __ \/ __ `/ __/ __ \/ / / /
26
/ / / __/ / __/ /_/ / /_/ / /_/ / / / /_/ /
27
/_/ \___/_/\___/ .___/\__,_/\__/_/ /_/\__, /
28
/_/ /____/
29
-- An OSINT toolkit for investigating Telegram chats.
30
-- Developed by @jordanwildon | Version """
31
+ __version__
32
+ """.
33
"""
34
+ Style.RESET_ALL
35
)
36
37
38
def parse_tg_date(dd):
39
year = str(format(dd.year, "02d"))
40
month = str(format(dd.month, "02d"))
41
day = str(format(dd.day, "02d"))
42
hour = str(format(dd.hour, "02d"))
43
minute = str(format(dd.minute, "02d"))
44
second = str(format(dd.second, "02d"))
45
date = year + "-" + month + "-" + day
46
mtime = hour + ":" + minute + ":" + second
47
timestamp = date + "T" + mtime + "+00:00"
48
return {"timestamp": timestamp, "date": date, "mtime": mtime}
49
50
51
def populate_user(user, group_or_chat):
52
if user.username:
53
username = user.username
54
else:
55
username = "N/A"
56
if user.first_name:
57
first_name = user.first_name
58
else:
59
first_name = ""
60
if user.last_name:
61
last_name = user.last_name
62
else:
63
last_name = ""
64
if user.phone:
65
phone = user.phone
66
else:
67
phone = "N/A"
68
if user.id:
69
user_id = user.id
70
else:
71
user_id = "N/A"
72
full_name = (first_name + " " + last_name).strip()
73
return [username, full_name, user_id, phone, group_or_chat]
74
75
76
def process_message(mess, user_lang):
77
78
if mess is not None:
79
mess_txt = '"' + mess + '"'
80
else:
81
mess_txt = "None"
82
83
if mess_txt != "None":
84
translator = Translator()
85
detection = translator.detect(mess_txt)
86
translation_confidence = detection.confidence
87
translation = translator.translate(mess_txt, dest=user_lang)
88
original_language = translation.src
89
translated_text = translation.text
90
else:
91
original_language = user_lang
92
translated_text = "N/A"
93
translation_confidence = "N/A"
94
95
return {
96
"original_language": original_language,
97
"translated_text": translated_text,
98
"translation_confidence": translation_confidence,
99
"message_text": mess_txt,
100
}
101
102
103
def process_description(desc, user_lang):
104
if desc is not None:
105
desc_txt = '"' + desc + '"'
106
else:
107
desc_txt = "None"
108
109
if desc_txt != "None":
110
translator = Translator()
111
detection = translator.detect(desc_txt)
112
translation_confidence = detection.confidence
113
translation = translator.translate(desc_txt, dest=user_lang)
114
original_language = translation.src
115
translated_text = translation.text
116
else:
117
original_language = user_lang
118
translated_text = "N/A"
119
translation_confidence = "N/A"
120
121
return {
122
"original_language": original_language,
123
"translated_text": translated_text,
124
"translation_confidence": translation_confidence,
125
"description_text": desc_txt,
126
}
127
128
129
def color_print_green(first_string, second_string):
130
print(Fore.GREEN + first_string + Style.RESET_ALL + second_string)
131
132
133
def parse_html_page(url):
134
s = requests.Session()
135
s.max_redirects = 10
136
s.headers["User-Agent"] = random.choice(user_agent)
137
URL = s.get(url)
138
URL.encoding = "utf-8"
139
html_content = URL.text
140
soup = BeautifulSoup(html_content, "html.parser")
141
name = ""
142
group_description = ""
143
total_participants = ""
144
try:
145
name = soup.find("div", {"class": ["tgme_page_title"]}).text
146
except:
147
name = "Not found"
148
try:
149
group_description = (
150
soup.find("div", {"class": ["tgme_page_description"]})
151
.getText(separator="\n")
152
.replace("\n", " ")
153
)
154
# descript = Fore.GREEN + "Description: " + Style.RESET_ALL + group_description
155
except:
156
group_description = "None"
157
# descript = Fore.GREEN + "Description: " + Style.RESET_ALL + group_description
158
try:
159
group_participants = soup.find("div", {"class": ["tgme_page_extra"]}).text
160
sep = "members"
161
stripped = group_participants.split(sep, 1)[0]
162
total_participants = (
163
stripped.replace(" ", "")
164
.replace("members", "")
165
.replace("subscribers", "")
166
.replace("member", "")
167
)
168
except:
169
total_participants = "Not found"
170
return {
171
"name": name,
172
"group_description": group_description,
173
"total_participants": total_participants,
174
}
175
176
177
def generate_textwrap(text_string, size=70):
178
trans_descript = Fore.GREEN + f"{text_string} " + Style.RESET_ALL
179
prefix = trans_descript
180
return textwrap.TextWrapper(
181
initial_indent=prefix,
182
width=size,
183
subsequent_indent=" ",
184
)
185
186
187
def print_shell(type, obj):
188
if type == "bot":
189
color_print_green(" [+] ", "Bot details for " + str(obj.id))
190
color_print_green(f" ├ Username: @{str(obj.username)}")
191
color_print_green(f" ├ Name: {str(obj.first_name)}")
192
color_print_green(f" └ Link: https://t.me/{str(obj.username)}")
193
print("\n")
194
color_print_green(" [+] ", "User related details for bot " + str(obj.id))
195
color_print_green(f" ├ User id: @{str(obj.user_id)}")
196
color_print_green(f" ├ User username: @{str(obj.user_username)}")
197
color_print_green(f" ├ User name: {str(obj.user_first_name)}")
198
color_print_green(f" └ Link: https://t.me/{str(obj.user_username)}")
199
200
if type == "user":
201
color_print_green(" [+] ", "User details for " + obj.target)
202
color_print_green(" ├ Id: ", str(obj.id))
203
color_print_green(" ├ Username: ", str(obj.username))
204
color_print_green(" ├ Name: ", str(obj.user_full_name))
205
color_print_green(" ├ Verification: ", str(obj.verified))
206
color_print_green(" ├ Photo ID: ", str(obj.user_photo))
207
color_print_green(" ├ Phone number: ", str(obj.phone))
208
color_print_green(" ├ Access hash: ", str(obj.access_hash))
209
color_print_green(" ├ Language: ", str(obj.lang_code))
210
color_print_green(" ├ Bot: ", str(obj.bot))
211
color_print_green(" ├ Scam: ", str(obj.scam))
212
color_print_green(" ├ Last seen: ", str(obj.user_status))
213
color_print_green(" └ Restrictions: ", str(obj.user_restrictions))
214
215
if type == "location_report":
216
color_print_green(" [+] Users located", "")
217
color_print_green(" ├ Users within 500m: ", str(obj.d500))
218
color_print_green(" ├ Users within 1000m: ", str(obj.d1000))
219
color_print_green(" ├ Users within 2000m: ", str(obj.d2000))
220
color_print_green(" ├ Users within 3000m: ", str(obj.d3000))
221
color_print_green(" ├ Total users found: ", str(obj.total))
222
color_print_green(" └ Location list saved to: ", obj.save_file)
223
224
if type == "channel_recap" or type == "group_recap":
225
226
d_wrapper = generate_textwrap("Description:")
227
td_wrapper = generate_textwrap("Translated Description:")
228
color_print_green(" ┬ Chat details", "")
229
color_print_green(" ├ Title: ", str(obj.title))
230
color_print_green(" ├ ", d_wrapper.fill(obj.group_description))
231
if obj.translated_description != obj.group_description:
232
color_print_green(" ├ ", td_wrapper.fill(obj.translated_description))
233
color_print_green(" ├ Total participants: ", str(obj.total_participants))
234
235
if type == "group_recap":
236
color_print_green(
237
" ├ Participants found: ",
238
str(obj.found_participants)
239
+ " ("
240
+ str(format(obj.found_percentage, ".2f"))
241
+ "%)",
242
)
243
244
color_print_green(" ├ Username: ", str(obj.group_username))
245
color_print_green(" ├ URL: ", str(obj.group_url))
246
color_print_green(" ├ Chat type: ", str(obj.chat_type))
247
color_print_green(" ├ Chat id: ", str(obj.id))
248
color_print_green(" ├ Access hash: ", str(obj.access_hash))
249
if type == "channel_recap":
250
scam_status = str(obj.scam)
251
color_print_green(" ├ Scam: ", str(scam_status))
252
color_print_green(" ├ First post date: ", str(obj.first_post))
253
if type == "group_recap":
254
color_print_green(" ├ Memberlist saved to: ", obj.memberlist_filename)
255
color_print_green(" └ Restrictions: ", (str(obj.group_status)))
256
257
if type == "group_stat":
258
color_print_green(" [+] Chat archive saved", "")
259
color_print_green(" ┬ Chat statistics", "")
260
color_print_green(" ├ Number of messages found: ", str(obj.messages_found))
261
color_print_green(" ├ Top poster 1: ", str(obj.poster_one))
262
color_print_green(" ├ Top poster 2: ", str(obj.poster_two))
263
color_print_green(" ├ Top poster 3: ", str(obj.poster_three))
264
color_print_green(" ├ Top poster 4: ", str(obj.poster_four))
265
color_print_green(" ├ Top poster 5: ", str(obj.poster_five))
266
color_print_green(" ├ Total unique posters: ", str(obj.unique_active))
267
color_print_green(" └ Archive saved to: ", str(obj.file_archive))
268
return
269
270
if type == "channel_stat":
271
color_print_green(" [+] Channel archive saved", "")
272
color_print_green(" ┬ Channel statistics", "")
273
color_print_green(" ├ Number of messages found: ", str(obj.messages_found))
274
color_print_green(" └ Archive saved to: ", str(obj.file_archive))
275
return
276
277
if type == "reply_stat":
278
middle_char = "├"
279
if obj.user_replier_list_len == 0:
280
middle_char = "└"
281
282
color_print_green(" [+] Replies analysis ", "")
283
color_print_green(" ┬ Chat statistics", "")
284
color_print_green(
285
f" {middle_char} Archive of replies saved to: ",
286
str(obj.reply_file_archive),
287
)
288
if obj.user_replier_list_len > 0:
289
color_print_green(
290
" └ Active members list who replied to messages, saved to: ",
291
str(obj.reply_memberlist_filename),
292
)
293
color_print_green(" ┬ Top replier 1: ", str(obj.replier_one))
294
color_print_green(" ├ Top replier 2: ", str(obj.replier_two))
295
color_print_green(" ├ Top replier 3: ", str(obj.replier_three))
296
color_print_green(" ├ Top replier 4: ", str(obj.replier_four))
297
color_print_green(" ├ Top replier 5: ", str(obj.replier_five))
298
color_print_green(" └ Total unique repliers: ", str(obj.replier_unique))
299
300
if type == "forwarder_stat":
301
color_print_green(" [+] Forward scrape complete", "")
302
color_print_green(" ┬ Statistics", "")
303
#color_print_green(
304
# " ├ Forwarded messages found: ", str(obj.forward_count)
305
#)
306
#color_print_green(
307
# " ├ Forwards from active public chats: ",
308
# str(obj.forwards_found),
309
#)
310
#if hasattr(object, "private_count"):
311
# color_print_green(
312
# " ├ Forwards from private (or now private) chats: ",
313
# str(obj.private_count),
314
# )
315
color_print_green(" ├ Unique forward sources: ", str(obj.unique_forwards))
316
color_print_green(" ├ Top forward source 1: ", str(obj.forward_one))
317
color_print_green(" ├ Top forward source 2: ", str(obj.forward_two))
318
color_print_green(" ├ Top forward source 3: ", str(obj.forward_three))
319
color_print_green(" ├ Top forward source 4: ", str(obj.forward_four))
320
color_print_green(" ├ Top forward source 5: ", str(obj.forward_five))
321
color_print_green(" └ Edgelist saved to: ", obj.edgelist_file)
322
323
324
def create_path(path_d):
325
if not os.path.exists(path_d):
326
os.makedirs(path_d)
327
return path_d
328
329
330
def create_file_report(save_dir, name, type, extension, file_time, append_time=True):
331
_time_append = ""
332
if append_time:
333
_time_append = "_" + file_time
334
return os.path.join(
335
"{}".format(save_dir), "{}{}_{}.{}".format(name, _time_append, type, extension)
336
)
337
338
339
def clean_private_invite(url):
340
if type(url) is not int:
341
if "https://t.me/+" in url:
342
return url.replace("https://t.me/+", "https://t.me/joinchat/")
343
return url
344
345
346
def evaluate_reactions(message, create=False):
347
total_reactions = 0
348
reactions = {}
349
if not create and message.reactions:
350
reactions_l = message.reactions.results
351
for idx, i in enumerate(reactions_l):
352
total_reactions = total_reactions + i.count
353
reactions["thumbs_up"] = i.count if i.reaction == "👍" else 0
354
reactions["thumbs_down"] = i.count if i.reaction == "👎" else 0
355
reactions["heart"] = i.count if i.reaction == "❤️" else 0
356
reactions["fire"] = i.count if i.reaction == "🔥" else 0
357
reactions["smile_with_hearts"] = i.count if i.reaction == "🥰" else 0
358
reactions["clap"] = i.count if i.reaction == "👏" else 0
359
reactions["smile"] = i.count if i.reaction == "😁" else 0
360
reactions["thinking"] = i.count if i.reaction == "🤔" else 0
361
reactions["exploding_head"] = i.count if i.reaction == "🤯" else 0
362
reactions["scream"] = i.count if i.reaction == "😱" else 0
363
reactions["angry"] = i.count if i.reaction == "🤬" else 0
364
reactions["single_tear"] = i.count if i.reaction == "😢" else 0
365
reactions["party_popper"] = i.count if i.reaction == "🎉" else 0
366
reactions["starstruck"] = i.count if i.reaction == "🤩" else 0
367
reactions["vomiting"] = i.count if i.reaction == "🤮" else 0
368
reactions["poop"] = i.count if i.reaction == "💩" else 0
369
reactions["praying"] = i.count if i.reaction == "🙏" else 0
370
else:
371
reactions["total_reactions"] = "N/A"
372
reactions["thumbs_up"] = "N/A"
373
reactions["thumbs_down"] = "N/A"
374
reactions["heart"] = "N/A"
375
reactions["fire"] = "N/A"
376
reactions["smile_with_hearts"] = "N/A"
377
reactions["clap"] = "N/A"
378
reactions["smile"] = "N/A"
379
reactions["thinking"] = "N/A"
380
reactions["exploding_head"] = "N/A"
381
reactions["scream"] = "N/A"
382
reactions["angry"] = "N/A"
383
reactions["single_tear"] = "N/A"
384
reactions["party_popper"] = "N/A"
385
reactions["starstruck"] = "N/A"
386
reactions["vomiting"] = "N/A"
387
reactions["poop"] = "N/A"
388
reactions["praying"] = "N/A"
389
return total_reactions, reactions
390
391