-
-
Notifications
You must be signed in to change notification settings - Fork 346
/
Copy pathupload_dl.py
407 lines (383 loc) · 15.7 KB
/
upload_dl.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
# © By StarkGang™ And IndianBot™
# For F.r.i.d.a.y And Indianbot ™
""" Userbot module which contains everything related to \
downloading/uploading from/to the server. """
import json
import os
import subprocess
import time
import math
from pySmartDL import SmartDL
import asyncio
from hachoir.metadata import extractMetadata
from hachoir.parser import createParser
from telethon.tl.types import DocumentAttributeVideo
from ULTRA import LOGS, CMD_HELP, TEMP_DOWNLOAD_DIRECTORY
from ULTRA.events import register
async def progress(current, total, event, start, type_of_ps, file_name=None):
"""Generic progress_callback for uploads and downloads."""
now = time.time()
diff = now - start
if round(diff % 10.00) == 0 or current != total:
percentage = current * 100 / total
speed = current / diff
elapsed_time = round(diff) * 1000
time_to_completion = round((total - current) / speed) * 1000
estimated_total_time = elapsed_time + time_to_completion
progress_str = "[{0}{1}] {2}%\n".format(
''.join(["▰" for i in range(math.floor(percentage / 10))]),
''.join(["▱" for i in range(10 - math.floor(percentage / 10))]),
round(percentage, 2))
tmp = progress_str + \
"{0} of {1}\nETA: {2}".format(
humanbytes(current),
humanbytes(total),
time_formatter(estimated_total_time)
)
if file_name:
await event.edit("{}\nFile Name: `{}`\n{}".format(
type_of_ps, file_name, tmp))
else:
await event.edit("{}\n{}".format(type_of_ps, tmp))
def humanbytes(size):
"""Input size in bytes,
outputs in a human readable format"""
# https://stackoverflow.com/a/49361727/4723940
if not size:
return ""
# 2 ** 10 = 1024
power = 2**10
raised_to_pow = 0
dict_power_n = {0: "", 1: "Ki", 2: "Mi", 3: "Gi", 4: "Ti"}
while size > power:
size /= power
raised_to_pow += 1
return str(round(size, 2)) + " " + dict_power_n[raised_to_pow] + "B"
def time_formatter(milliseconds: int) -> str:
"""Inputs time in milliseconds, to get beautified time,
as string"""
seconds, milliseconds = divmod(int(milliseconds), 1000)
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
days, hours = divmod(hours, 24)
tmp = ((str(days) + " day(s), ") if days else "") + \
((str(hours) + " hour(s), ") if hours else "") + \
((str(minutes) + " minute(s), ") if minutes else "") + \
((str(seconds) + " second(s), ") if seconds else "") + \
((str(milliseconds) + " millisecond(s), ") if milliseconds else "")
return tmp[:-2]
@register(pattern=r".dl(?: |$)(.*)", outgoing=True)
async def download(target_file):
""" For .dl command, download files to the userbot's server. """
await target_file.edit("Processing using userbot server ( ◜‿◝ )♡")
input_str = target_file.pattern_match.group(1)
if not os.path.isdir(TEMP_DOWNLOAD_DIRECTORY):
os.makedirs(TEMP_DOWNLOAD_DIRECTORY)
if "|" in input_str:
url, file_name = input_str.split("|")
url = url.strip()
# https://stackoverflow.com/a/761825/4723940
file_name = file_name.strip()
head, tail = os.path.split(file_name)
if head:
if not os.path.isdir(os.path.join(TEMP_DOWNLOAD_DIRECTORY, head)):
os.makedirs(os.path.join(TEMP_DOWNLOAD_DIRECTORY, head))
file_name = os.path.join(head, tail)
downloaded_file_name = TEMP_DOWNLOAD_DIRECTORY + "" + file_name
downloader = SmartDL(url, downloaded_file_name, progress_bar=False)
downloader.start(blocking=False)
c_time = time.time()
display_message = None
while not downloader.isFinished():
status = downloader.get_status().capitalize()
total_length = downloader.filesize if downloader.filesize else None
downloaded = downloader.get_dl_size()
now = time.time()
diff = now - c_time
percentage = downloader.get_progress() * 100
speed = downloader.get_speed()
elapsed_time = round(diff) * 1000
progress_str = "[{0}{1}] {2}%".format(
''.join(["▰" for i in range(math.floor(percentage / 10))]),
''.join(["▱"
for i in range(10 - math.floor(percentage / 10))]),
round(percentage, 2))
estimated_total_time = downloader.get_eta(human=True)
try:
current_message = f"{status}..\
\nFOR : F.R.I.D.A.Y™ AND INDIANBOT™\
\nURL: {url}\
\nFile Name: {file_name}\
\n{progress_str}\
\n{humanbytes(downloaded)} of {humanbytes(total_length)}\
\nETA: {estimated_total_time}"
if round(diff %
10.00) == 0 and current_message != display_message:
await target_file.edit(current_message)
display_message = current_message
except Exception as e:
LOGS.info(str(e))
if downloader.isSuccessful():
await target_file.edit("Downloaded to `{}` successfully !!".format(
downloaded_file_name))
else:
await target_file.edit("Incorrect URL\n{}".format(url))
elif target_file.reply_to_msg_id:
try:
c_time = time.time()
downloaded_file_name = await target_file.client.download_media(
await target_file.get_reply_message(),
TEMP_DOWNLOAD_DIRECTORY,
progress_callback=lambda d, t: asyncio.get_event_loop(
).create_task(
progress(d, t, target_file, c_time, "Downloading...")))
except Exception as e: # pylint:disable=C0103,W0703
await target_file.edit(str(e))
else:
await target_file.edit("Downloaded to `{}` successfully !!".format(
downloaded_file_name))
else:
await target_file.edit(
"Reply to a message to download to my local server.")
@register(pattern=r".uploadir (.*)", outgoing=True)
async def uploadir(udir_event):
""" For .uploadir command, allows you to upload everything from a folder in the server"""
input_str = udir_event.pattern_match.group(1)
if os.path.exists(input_str):
await udir_event.edit("Downloading Using Userbot Server....")
lst_of_files = []
for r, d, f in os.walk(input_str):
for file in f:
lst_of_files.append(os.path.join(r, file))
for file in d:
lst_of_files.append(os.path.join(r, file))
LOGS.info(lst_of_files)
uploaded = 0
await udir_event.edit(
"Found {} files. Uploading will start soon. Please wait!".format(
len(lst_of_files)))
for single_file in lst_of_files:
if os.path.exists(single_file):
# https://stackoverflow.com/a/678242/4723940
caption_rts = os.path.basename(single_file)
c_time = time.time()
if not caption_rts.lower().endswith(".mp4"):
await udir_event.client.send_file(
udir_event.chat_id,
single_file,
caption=caption_rts,
force_document=False,
allow_cache=False,
reply_to=udir_event.message.id,
progress_callback=lambda d, t: asyncio.get_event_loop(
).create_task(
progress(d, t, udir_event, c_time, "Uploading in Progress.......",
single_file)))
else:
thumb_image = os.path.join(input_str, "thumb.jpg")
c_time = time.time()
metadata = extractMetadata(createParser(single_file))
duration = 0
width = 0
height = 0
if metadata.has("duration"):
duration = metadata.get("duration").seconds
if metadata.has("width"):
width = metadata.get("width")
if metadata.has("height"):
height = metadata.get("height")
await udir_event.client.send_file(
udir_event.chat_id,
single_file,
caption=caption_rts,
thumb=thumb_image,
force_document=False,
allow_cache=False,
reply_to=udir_event.message.id,
attributes=[
DocumentAttributeVideo(
duration=duration,
w=width,
h=height,
round_message=False,
supports_streaming=True,
)
],
progress_callback=lambda d, t: asyncio.get_event_loop(
).create_task(
progress(d, t, udir_event, c_time, "Uploading...",
single_file)))
os.remove(single_file)
uploaded = uploaded + 1
await udir_event.edit(
"Uploaded {} files successfully !!".format(uploaded))
else:
await udir_event.edit("404: Directory Not Found")
@register(pattern=r".upload (.*)", outgoing=True)
async def upload(u_event):
""" For .upload command, allows you to upload a file from the userbot's server """
await u_event.edit("Processing ...")
input_str = u_event.pattern_match.group(1)
if input_str in ("userbot.session", "config.env"):
await u_event.edit("`That's a dangerous operation! Not Permitted!`")
return
if os.path.exists(input_str):
c_time = time.time()
await u_event.client.send_file(
u_event.chat_id,
input_str,
force_document=True,
allow_cache=False,
reply_to=u_event.message.id,
progress_callback=lambda d, t: asyncio.get_event_loop(
).create_task(
progress(d, t, u_event, c_time, "Uploading...", input_str)))
await u_event.edit("Uploaded successfully !!")
else:
await u_event.edit("404: File Not Found")
def get_video_thumb(file, output=None, width=90):
""" Get video thumbnail """
metadata = extractMetadata(createParser(file))
popen = subprocess.Popen(
[
"ffmpeg",
"-i",
file,
"-ss",
str(
int((0, metadata.get("duration").seconds
)[metadata.has("duration")] / 2)),
"-filter:v",
"scale={}:-1".format(width),
"-vframes",
"1",
output,
],
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
)
if not popen.returncode and os.path.lexists(file):
return output
return None
def extract_w_h(file):
""" Get width and height of media """
command_to_run = [
"ffprobe",
"-v",
"quiet",
"-print_format",
"json",
"-show_format",
"-show_streams",
file,
]
# https://stackoverflow.com/a/11236144/4723940
try:
t_response = subprocess.check_output(command_to_run,
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as exc:
LOGS.warning(exc)
else:
x_reponse = t_response.decode("UTF-8")
response_json = json.loads(x_reponse)
width = int(response_json["streams"][0]["width"])
height = int(response_json["streams"][0]["height"])
return width, height
@register(pattern=r".uploadas(stream|vn|all) (.*)", outgoing=True)
async def uploadas(uas_event):
""" For .uploadas command, allows you to specify some arguments for upload. """
await uas_event.edit("Processing ...")
type_of_upload = uas_event.pattern_match.group(1)
supports_streaming = False
round_message = False
spam_big_messages = False
if type_of_upload == "stream":
supports_streaming = True
if type_of_upload == "vn":
round_message = True
if type_of_upload == "all":
spam_big_messages = True
input_str = uas_event.pattern_match.group(2)
thumb = None
file_name = None
if "|" in input_str:
file_name, thumb = input_str.split("|")
file_name = file_name.strip()
thumb = thumb.strip()
else:
file_name = input_str
thumb_path = "a_random_f_file_name" + ".jpg"
thumb = get_video_thumb(file_name, output=thumb_path)
if os.path.exists(file_name):
metadata = extractMetadata(createParser(file_name))
duration = 0
width = 0
height = 0
if metadata.has("duration"):
duration = metadata.get("duration").seconds
if metadata.has("width"):
width = metadata.get("width")
if metadata.has("height"):
height = metadata.get("height")
try:
if supports_streaming:
c_time = time.time()
await uas_event.client.send_file(
uas_event.chat_id,
file_name,
thumb=thumb,
caption=input_str,
force_document=False,
allow_cache=False,
reply_to=uas_event.message.id,
attributes=[
DocumentAttributeVideo(
duration=duration,
w=width,
h=height,
round_message=False,
supports_streaming=True,
)
],
progress_callback=lambda d, t: asyncio.get_event_loop(
).create_task(
progress(d, t, uas_event, c_time, "Uploading...",
file_name)))
elif round_message:
c_time = time.time()
await uas_event.client.send_file(
uas_event.chat_id,
file_name,
thumb=thumb,
allow_cache=False,
reply_to=uas_event.message.id,
video_note=True,
attributes=[
DocumentAttributeVideo(
duration=0,
w=1,
h=1,
round_message=True,
supports_streaming=True,
)
],
progress_callback=lambda d, t: asyncio.get_event_loop(
).create_task(
progress(d, t, uas_event, c_time, "Uploading...",
file_name)))
elif spam_big_messages:
await uas_event.edit("TBD: Not (yet) Implemented")
return
os.remove(thumb)
await uas_event.edit("Uploaded successfully !!")
except FileNotFoundError as err:
await uas_event.edit(str(err))
else:
await uas_event.edit("404: File Not Found")
CMD_HELP.update({
"download":
".dl <link|filename> or reply to media\
\nUsage: Downloads file to the server.\
\n\n.upload <path in server>\
\nUsage: Uploads a locally stored file to the chat."
})