Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
anasty17
GitHub Repository: anasty17/mirror-leech-telegram-bot
Path: blob/master/bot/modules/mirror_leech.py
1626 views
1
from aiofiles.os import path as aiopath
2
from base64 import b64encode
3
from re import match as re_match
4
5
from .. import LOGGER, bot_loop, task_dict_lock, DOWNLOAD_DIR
6
from ..helper.ext_utils.bot_utils import (
7
get_content_type,
8
sync_to_async,
9
arg_parser,
10
COMMAND_USAGE,
11
)
12
from ..helper.ext_utils.exceptions import DirectDownloadLinkException
13
from ..helper.ext_utils.links_utils import (
14
is_url,
15
is_magnet,
16
is_gdrive_link,
17
is_rclone_path,
18
is_telegram_link,
19
is_gdrive_id,
20
)
21
from ..helper.listeners.task_listener import TaskListener
22
from ..helper.mirror_leech_utils.download_utils.aria2_download import (
23
add_aria2_download,
24
)
25
from ..helper.mirror_leech_utils.download_utils.direct_downloader import (
26
add_direct_download,
27
)
28
from ..helper.mirror_leech_utils.download_utils.direct_link_generator import (
29
direct_link_generator,
30
)
31
from ..helper.mirror_leech_utils.download_utils.gd_download import add_gd_download
32
from ..helper.mirror_leech_utils.download_utils.jd_download import add_jd_download
33
from ..helper.mirror_leech_utils.download_utils.qbit_download import add_qb_torrent
34
from ..helper.mirror_leech_utils.download_utils.nzb_downloader import add_nzb
35
from ..helper.mirror_leech_utils.download_utils.rclone_download import (
36
add_rclone_download,
37
)
38
from ..helper.mirror_leech_utils.download_utils.telegram_download import (
39
TelegramDownloadHelper,
40
)
41
from ..helper.telegram_helper.message_utils import send_message, get_tg_link_message
42
43
44
class Mirror(TaskListener):
45
def __init__(
46
self,
47
client,
48
message,
49
is_qbit=False,
50
is_leech=False,
51
is_jd=False,
52
is_nzb=False,
53
same_dir=None,
54
bulk=None,
55
multi_tag=None,
56
options="",
57
):
58
if same_dir is None:
59
same_dir = {}
60
if bulk is None:
61
bulk = []
62
self.message = message
63
self.client = client
64
self.multi_tag = multi_tag
65
self.options = options
66
self.same_dir = same_dir
67
self.bulk = bulk
68
super().__init__()
69
self.is_qbit = is_qbit
70
self.is_leech = is_leech
71
self.is_jd = is_jd
72
self.is_nzb = is_nzb
73
74
async def new_event(self):
75
text = self.message.text.split("\n")
76
input_list = text[0].split(" ")
77
78
args = {
79
"-doc": False,
80
"-med": False,
81
"-d": False,
82
"-j": False,
83
"-s": False,
84
"-b": False,
85
"-e": False,
86
"-z": False,
87
"-sv": False,
88
"-ss": False,
89
"-f": False,
90
"-fd": False,
91
"-fu": False,
92
"-hl": False,
93
"-bt": False,
94
"-ut": False,
95
"-i": 0,
96
"-sp": 0,
97
"link": "",
98
"-n": "",
99
"-m": "",
100
"-up": "",
101
"-rcf": "",
102
"-au": "",
103
"-ap": "",
104
"-h": [],
105
"-t": "",
106
"-ca": "",
107
"-cv": "",
108
"-ns": "",
109
"-tl": "",
110
"-ff": set(),
111
}
112
113
arg_parser(input_list[1:], args)
114
115
self.select = args["-s"]
116
self.seed = args["-d"]
117
self.name = args["-n"]
118
self.up_dest = args["-up"]
119
self.rc_flags = args["-rcf"]
120
self.link = args["link"]
121
self.compress = args["-z"]
122
self.extract = args["-e"]
123
self.join = args["-j"]
124
self.thumb = args["-t"]
125
self.split_size = args["-sp"]
126
self.sample_video = args["-sv"]
127
self.screen_shots = args["-ss"]
128
self.force_run = args["-f"]
129
self.force_download = args["-fd"]
130
self.force_upload = args["-fu"]
131
self.convert_audio = args["-ca"]
132
self.convert_video = args["-cv"]
133
self.name_sub = args["-ns"]
134
self.hybrid_leech = args["-hl"]
135
self.thumbnail_layout = args["-tl"]
136
self.as_doc = args["-doc"]
137
self.as_med = args["-med"]
138
self.folder_name = f"/{args["-m"]}".rstrip("/") if len(args["-m"]) > 0 else ""
139
self.bot_trans = args["-bt"]
140
self.user_trans = args["-ut"]
141
self.ffmpeg_cmds = args["-ff"]
142
143
headers = args["-h"]
144
if headers:
145
headers = headers.split("|")
146
is_bulk = args["-b"]
147
148
bulk_start = 0
149
bulk_end = 0
150
ratio = None
151
seed_time = None
152
reply_to = None
153
file_ = None
154
session = ""
155
156
try:
157
self.multi = int(args["-i"])
158
except:
159
self.multi = 0
160
161
if not isinstance(self.seed, bool):
162
dargs = self.seed.split(":")
163
ratio = dargs[0] or None
164
if len(dargs) == 2:
165
seed_time = dargs[1] or None
166
self.seed = True
167
168
if not isinstance(is_bulk, bool):
169
dargs = is_bulk.split(":")
170
bulk_start = dargs[0] or "0"
171
if len(dargs) == 2:
172
bulk_end = dargs[1] or "0"
173
is_bulk = True
174
175
if not is_bulk:
176
if self.multi > 0:
177
if self.folder_name:
178
async with task_dict_lock:
179
if self.folder_name in self.same_dir:
180
self.same_dir[self.folder_name]["tasks"].add(self.mid)
181
for fd_name in self.same_dir:
182
if fd_name != self.folder_name:
183
self.same_dir[fd_name]["total"] -= 1
184
elif self.same_dir:
185
self.same_dir[self.folder_name] = {
186
"total": self.multi,
187
"tasks": {self.mid},
188
}
189
for fd_name in self.same_dir:
190
if fd_name != self.folder_name:
191
self.same_dir[fd_name]["total"] -= 1
192
else:
193
self.same_dir = {
194
self.folder_name: {
195
"total": self.multi,
196
"tasks": {self.mid},
197
}
198
}
199
elif self.same_dir:
200
async with task_dict_lock:
201
for fd_name in self.same_dir:
202
self.same_dir[fd_name]["total"] -= 1
203
else:
204
await self.init_bulk(input_list, bulk_start, bulk_end, Mirror)
205
return
206
207
if len(self.bulk) != 0:
208
del self.bulk[0]
209
210
await self.run_multi(input_list, Mirror)
211
212
await self.get_tag(text)
213
214
path = f"{DOWNLOAD_DIR}{self.mid}{self.folder_name}"
215
216
if not self.link and (reply_to := self.message.reply_to_message):
217
if reply_to.text:
218
self.link = reply_to.text.split("\n", 1)[0].strip()
219
if is_telegram_link(self.link):
220
try:
221
reply_to, session = await get_tg_link_message(self.link)
222
except Exception as e:
223
await send_message(self.message, f"ERROR: {e}")
224
await self.remove_from_same_dir()
225
return
226
227
if isinstance(reply_to, list):
228
self.bulk = reply_to
229
b_msg = input_list[:1]
230
self.options = " ".join(input_list[1:])
231
b_msg.append(f"{self.bulk[0]} -i {len(self.bulk)} {self.options}")
232
nextmsg = await send_message(self.message, " ".join(b_msg))
233
nextmsg = await self.client.get_messages(
234
chat_id=self.message.chat.id, message_ids=nextmsg.id
235
)
236
if self.message.from_user:
237
nextmsg.from_user = self.user
238
else:
239
nextmsg.sender_chat = self.user
240
await Mirror(
241
self.client,
242
nextmsg,
243
self.is_qbit,
244
self.is_leech,
245
self.is_jd,
246
self.is_nzb,
247
self.same_dir,
248
self.bulk,
249
self.multi_tag,
250
self.options,
251
).new_event()
252
return
253
254
if reply_to:
255
file_ = (
256
reply_to.document
257
or reply_to.photo
258
or reply_to.video
259
or reply_to.audio
260
or reply_to.voice
261
or reply_to.video_note
262
or reply_to.sticker
263
or reply_to.animation
264
or None
265
)
266
267
if file_ is None:
268
if reply_text := reply_to.text:
269
self.link = reply_text.split("\n", 1)[0].strip()
270
else:
271
reply_to = None
272
elif reply_to.document and (
273
file_.mime_type == "application/x-bittorrent"
274
or file_.file_name.endswith((".torrent", ".dlc", ".nzb"))
275
):
276
self.link = await reply_to.download()
277
file_ = None
278
279
if (
280
not self.link
281
and file_ is None
282
or is_telegram_link(self.link)
283
and reply_to is None
284
or file_ is None
285
and not is_url(self.link)
286
and not is_magnet(self.link)
287
and not await aiopath.exists(self.link)
288
and not is_rclone_path(self.link)
289
and not is_gdrive_id(self.link)
290
and not is_gdrive_link(self.link)
291
):
292
await send_message(
293
self.message, COMMAND_USAGE["mirror"][0], COMMAND_USAGE["mirror"][1]
294
)
295
await self.remove_from_same_dir()
296
return
297
298
if len(self.link) > 0:
299
LOGGER.info(self.link)
300
301
try:
302
await self.before_start()
303
except Exception as e:
304
await send_message(self.message, e)
305
await self.remove_from_same_dir()
306
return
307
308
if (
309
not self.is_jd
310
and not self.is_nzb
311
and not self.is_qbit
312
and not is_magnet(self.link)
313
and not is_rclone_path(self.link)
314
and not is_gdrive_link(self.link)
315
and not self.link.endswith(".torrent")
316
and file_ is None
317
and not is_gdrive_id(self.link)
318
):
319
content_type = await get_content_type(self.link)
320
if content_type is None or re_match(r"text/html|text/plain", content_type):
321
try:
322
self.link = await sync_to_async(direct_link_generator, self.link)
323
if isinstance(self.link, tuple):
324
self.link, headers = self.link
325
elif isinstance(self.link, str):
326
LOGGER.info(f"Generated link: {self.link}")
327
except DirectDownloadLinkException as e:
328
e = str(e)
329
if "This link requires a password!" not in e:
330
LOGGER.info(e)
331
if e.startswith("ERROR:"):
332
await send_message(self.message, e)
333
await self.remove_from_same_dir()
334
return
335
except Exception as e:
336
await send_message(self.message, e)
337
await self.remove_from_same_dir()
338
return
339
340
if file_ is not None:
341
await TelegramDownloadHelper(self).add_download(
342
reply_to, f"{path}/", session
343
)
344
elif isinstance(self.link, dict):
345
await add_direct_download(self, path)
346
elif self.is_jd:
347
await add_jd_download(self, path)
348
elif self.is_qbit:
349
await add_qb_torrent(self, path, ratio, seed_time)
350
elif self.is_nzb:
351
await add_nzb(self, path)
352
elif is_rclone_path(self.link):
353
await add_rclone_download(self, f"{path}/")
354
elif is_gdrive_link(self.link) or is_gdrive_id(self.link):
355
await add_gd_download(self, path)
356
else:
357
ussr = args["-au"]
358
pssw = args["-ap"]
359
if ussr or pssw:
360
auth = f"{ussr}:{pssw}"
361
headers.extend(
362
[f"authorization: Basic {b64encode(auth.encode()).decode('ascii')}"]
363
)
364
await add_aria2_download(self, path, headers, ratio, seed_time)
365
366
367
async def mirror(client, message):
368
bot_loop.create_task(Mirror(client, message).new_event())
369
370
371
async def qb_mirror(client, message):
372
bot_loop.create_task(Mirror(client, message, is_qbit=True).new_event())
373
374
375
async def jd_mirror(client, message):
376
bot_loop.create_task(Mirror(client, message, is_jd=True).new_event())
377
378
379
async def nzb_mirror(client, message):
380
bot_loop.create_task(Mirror(client, message, is_nzb=True).new_event())
381
382
383
async def leech(client, message):
384
bot_loop.create_task(Mirror(client, message, is_leech=True).new_event())
385
386
387
async def qb_leech(client, message):
388
bot_loop.create_task(
389
Mirror(client, message, is_qbit=True, is_leech=True).new_event()
390
)
391
392
393
async def jd_leech(client, message):
394
bot_loop.create_task(Mirror(client, message, is_leech=True, is_jd=True).new_event())
395
396
397
async def nzb_leech(client, message):
398
bot_loop.create_task(
399
Mirror(client, message, is_leech=True, is_nzb=True).new_event()
400
)
401
402