taslim19 commited on
Commit
677cbbf
·
1 Parent(s): 2f2b853

fix: use /tmp for downloads and cache

Browse files
DragMusic/core/dir.py CHANGED
@@ -4,17 +4,13 @@ from ..logging import LOGGER
4
 
5
 
6
  def dirr():
7
- for file in os.listdir():
8
- if file.endswith(".jpg"):
9
- os.remove(file)
10
- elif file.endswith(".jpeg"):
11
- os.remove(file)
12
- elif file.endswith(".png"):
13
- os.remove(file)
14
-
15
- if "downloads" not in os.listdir():
16
- os.mkdir("downloads")
17
- if "cache" not in os.listdir():
18
- os.mkdir("cache")
19
 
20
  LOGGER(__name__).info("Directories Updated.")
 
4
 
5
 
6
  def dirr():
7
+ if not os.path.isdir("/tmp/downloads"):
8
+ os.makedirs("/tmp/downloads")
9
+ if not os.path.isdir("/tmp/cache"):
10
+ os.makedirs("/tmp/cache")
11
+
12
+ for file in os.listdir("/tmp/downloads"):
13
+ if file.endswith((".jpg", ".jpeg", ".png")):
14
+ os.remove(os.path.join("/tmp/downloads", file))
 
 
 
 
15
 
16
  LOGGER(__name__).info("Directories Updated.")
DragMusic/platforms/Carbon.py CHANGED
@@ -101,6 +101,6 @@ class CarbonAPI:
101
  except client_exceptions.ClientConnectorError:
102
  raise UnableToFetchCarbon("Can not reach the Host!")
103
  resp = await request.read()
104
- with open(f"cache/carbon{user_id}.jpg", "wb") as f:
105
  f.write(resp)
106
  return realpath(f.name)
 
101
  except client_exceptions.ClientConnectorError:
102
  raise UnableToFetchCarbon("Can not reach the Host!")
103
  resp = await request.read()
104
+ with open(f"/tmp/cache/carbon{user_id}.jpg", "wb") as f:
105
  f.write(resp)
106
  return realpath(f.name)
DragMusic/platforms/Soundcloud.py CHANGED
@@ -8,7 +8,7 @@ from DragMusic.utils.formatters import seconds_to_min
8
  class SoundAPI:
9
  def __init__(self):
10
  self.opts = {
11
- "outtmpl": "downloads/%(id)s.%(ext)s",
12
  "format": "best",
13
  "retries": 3,
14
  "nooverwrites": False,
@@ -27,7 +27,7 @@ class SoundAPI:
27
  info = d.extract_info(url)
28
  except:
29
  return False
30
- xyz = path.join("downloads", f"{info['id']}.{info['ext']}")
31
  duration_min = seconds_to_min(info["duration"])
32
  track_details = {
33
  "title": info["title"],
 
8
  class SoundAPI:
9
  def __init__(self):
10
  self.opts = {
11
+ "outtmpl": "/tmp/downloads/%(id)s.%(ext)s",
12
  "format": "best",
13
  "retries": 3,
14
  "nooverwrites": False,
 
27
  info = d.extract_info(url)
28
  except:
29
  return False
30
+ xyz = path.join("/tmp/downloads", f"{info['id']}.{info['ext']}")
31
  duration_min = seconds_to_min(info["duration"])
32
  track_details = {
33
  "title": info["title"],
DragMusic/platforms/Telegram.py CHANGED
@@ -80,7 +80,7 @@ class TeleAPI:
80
  )
81
  except:
82
  file_name = audio.file_unique_id + "." + "ogg"
83
- file_name = os.path.join(os.path.realpath("downloads"), file_name)
84
  if video:
85
  try:
86
  file_name = (
@@ -88,7 +88,7 @@ class TeleAPI:
88
  )
89
  except:
90
  file_name = video.file_unique_id + "." + "mp4"
91
- file_name = os.path.join(os.path.realpath("downloads"), file_name)
92
  return file_name
93
 
94
  async def download(self, _, message, mystic, fname):
 
80
  )
81
  except:
82
  file_name = audio.file_unique_id + "." + "ogg"
83
+ file_name = os.path.join(os.path.realpath("/tmp/downloads"), file_name)
84
  if video:
85
  try:
86
  file_name = (
 
88
  )
89
  except:
90
  file_name = video.file_unique_id + "." + "mp4"
91
+ file_name = os.path.join(os.path.realpath("/tmp/downloads"), file_name)
92
  return file_name
93
 
94
  async def download(self, _, message, mystic, fname):
DragMusic/platforms/Youtube.py CHANGED
@@ -30,7 +30,7 @@ def cookie_txt_file():
30
  async def download_song(link: str):
31
  video_id = link.split('v=')[-1].split('&')[0]
32
 
33
- download_folder = "downloads"
34
  for ext in ["mp3", "m4a", "webm"]:
35
  file_path = f"{download_folder}/{video_id}.{ext}"
36
  if os.path.exists(file_path):
@@ -67,7 +67,7 @@ async def download_song(link: str):
67
  file_format = data.get("format", "mp3")
68
  file_extension = file_format.lower()
69
  file_name = f"{video_id}.{file_extension}"
70
- download_folder = "downloads"
71
  os.makedirs(download_folder, exist_ok=True)
72
  file_path = os.path.join(download_folder, file_name)
73
 
@@ -250,17 +250,31 @@ class YouTubeAPI:
250
  link = self.listbase + link
251
  if "&" in link:
252
  link = link.split("&")[0]
253
- playlist = await shell_cmd(
254
- f"yt-dlp -i --get-id --flat-playlist --cookies {cookie_txt_file()} --playlist-end {limit} --skip-download {link}"
 
 
 
 
 
 
 
 
255
  )
 
 
 
 
 
256
  try:
257
- result = playlist.split("\n")
258
- for key in result:
259
- if key == "":
260
- result.remove(key)
261
- except:
262
- result = []
263
- return result
 
264
 
265
  async def track(self, link: str, videoid: Union[bool, str] = None):
266
  if videoid:
@@ -270,54 +284,18 @@ class YouTubeAPI:
270
  results = VideosSearch(link, limit=1)
271
  for result in (await results.next())["result"]:
272
  title = result["title"]
273
- duration_min = result["duration"]
274
  vidid = result["id"]
275
- yturl = result["link"]
276
- thumbnail = result["thumbnails"][0]["url"].split("?")[0]
277
- track_details = {
278
- "title": title,
279
- "link": yturl,
280
- "vidid": vidid,
281
- "duration_min": duration_min,
282
- "thumb": thumbnail,
283
- }
284
- return track_details, vidid
285
 
286
  async def formats(self, link: str, videoid: Union[bool, str] = None):
287
  if videoid:
288
  link = self.base + link
289
  if "&" in link:
290
  link = link.split("&")[0]
291
- ytdl_opts = {"quiet": True, "cookiefile" : cookie_txt_file()}
292
- ydl = yt_dlp.YoutubeDL(ytdl_opts)
293
- with ydl:
294
- formats_available = []
295
- r = ydl.extract_info(link, download=False)
296
- for format in r["formats"]:
297
- try:
298
- str(format["format"])
299
- except:
300
- continue
301
- if not "dash" in str(format["format"]).lower():
302
- try:
303
- format["format"]
304
- format["filesize"]
305
- format["format_id"]
306
- format["ext"]
307
- format["format_note"]
308
- except:
309
- continue
310
- formats_available.append(
311
- {
312
- "format": format["format"],
313
- "filesize": format["filesize"],
314
- "format_id": format["format_id"],
315
- "ext": format["ext"],
316
- "format_note": format["format_note"],
317
- "yturl": link,
318
- }
319
- )
320
- return formats_available, link
321
 
322
  async def slider(
323
  self,
@@ -327,15 +305,12 @@ class YouTubeAPI:
327
  ):
328
  if videoid:
329
  link = self.base + link
330
- if "&" in link:
331
- link = link.split("&")[0]
332
- a = VideosSearch(link, limit=10)
333
- result = (await a.next()).get("result")
334
- title = result[query_type]["title"]
335
- duration_min = result[query_type]["duration"]
336
- vidid = result[query_type]["id"]
337
- thumbnail = result[query_type]["thumbnails"][0]["url"].split("?")[0]
338
- return title, duration_min, thumbnail, vidid
339
 
340
  async def download(
341
  self,
@@ -350,121 +325,84 @@ class YouTubeAPI:
350
  ) -> str:
351
  if videoid:
352
  link = self.base + link
353
- loop = asyncio.get_running_loop()
354
  def audio_dl():
355
- ydl_optssx = {
356
- "format": "bestaudio/best",
357
- "outtmpl": "downloads/%(id)s.%(ext)s",
358
  "geo_bypass": True,
359
  "nocheckcertificate": True,
360
- "quiet": True,
361
- "cookiefile" : cookie_txt_file(),
362
- "no_warnings": True,
363
  }
364
- x = yt_dlp.YoutubeDL(ydl_optssx)
365
- info = x.extract_info(link, False)
366
- xyz = os.path.join("downloads", f"{info['id']}.{info['ext']}")
367
- if os.path.exists(xyz):
368
- return xyz
369
- x.download([link])
370
- return xyz
371
 
372
  def video_dl():
373
- ydl_optssx = {
374
- "format": "(bestvideo[height<=?720][width<=?1280][ext=mp4])+(bestaudio[ext=m4a])",
375
- "outtmpl": "downloads/%(id)s.%(ext)s",
376
  "geo_bypass": True,
377
  "nocheckcertificate": True,
378
- "quiet": True,
379
- "cookiefile" : cookie_txt_file(),
380
- "no_warnings": True,
381
  }
382
- x = yt_dlp.YoutubeDL(ydl_optssx)
383
- info = x.extract_info(link, False)
384
- xyz = os.path.join("downloads", f"{info['id']}.{info['ext']}")
385
- if os.path.exists(xyz):
386
- return xyz
387
- x.download([link])
388
- return xyz
389
 
390
  def song_video_dl():
391
- formats = f"{format_id}+140"
392
- fpath = f"downloads/{title}"
393
- ydl_optssx = {
394
- "format": formats,
395
- "outtmpl": fpath,
396
  "geo_bypass": True,
397
  "nocheckcertificate": True,
398
- "quiet": True,
399
- "no_warnings": True,
400
- "cookiefile" : cookie_txt_file(),
401
- "prefer_ffmpeg": True,
402
- "merge_output_format": "mp4",
403
  }
404
- x = yt_dlp.YoutubeDL(ydl_optssx)
405
- x.download([link])
406
 
407
  def song_audio_dl():
408
- fpath = f"downloads/{title}.%(ext)s"
409
- ydl_optssx = {
410
- "format": format_id,
411
- "outtmpl": fpath,
412
  "geo_bypass": True,
413
  "nocheckcertificate": True,
414
- "quiet": True,
415
- "no_warnings": True,
416
- "cookiefile" : cookie_txt_file(),
417
- "prefer_ffmpeg": True,
418
- "postprocessors": [
419
- {
420
- "key": "FFmpegExtractAudio",
421
- "preferredcodec": "mp3",
422
- "preferredquality": "192",
423
- }
424
- ],
425
  }
426
- x = yt_dlp.YoutubeDL(ydl_optssx)
427
- x.download([link])
428
 
429
  if songvideo:
430
- await download_song(link)
431
- fpath = f"downloads/{link}.mp3"
432
- return fpath
433
  elif songaudio:
434
- await download_song(link)
435
- fpath = f"downloads/{link}.mp3"
436
- return fpath
437
  elif video:
438
- if await is_on_off(1):
439
- direct = True
440
- downloaded_file = await download_song(link)
441
- else:
442
- proc = await asyncio.create_subprocess_exec(
443
- "yt-dlp",
444
- "--cookies",cookie_txt_file(),
445
- "-g",
446
- "-f",
447
- "best[height<=?720][width<=?1280]",
448
- f"{link}",
449
- stdout=asyncio.subprocess.PIPE,
450
- stderr=asyncio.subprocess.PIPE,
451
- )
452
- stdout, stderr = await proc.communicate()
453
- if stdout:
454
- downloaded_file = stdout.decode().split("\n")[0]
455
- direct = False
456
- else:
457
- file_size = await check_file_size(link)
458
- if not file_size:
459
- print("None file Size")
460
- return
461
- total_size_mb = file_size / (1024 * 1024)
462
- if total_size_mb > 250:
463
- print(f"File size {total_size_mb:.2f} MB exceeds the 100MB limit.")
464
- return None
465
- direct = True
466
- downloaded_file = await loop.run_in_executor(None, video_dl)
467
  else:
468
- direct = True
469
- downloaded_file = await download_song(link)
470
- return downloaded_file, direct
 
 
 
 
 
30
  async def download_song(link: str):
31
  video_id = link.split('v=')[-1].split('&')[0]
32
 
33
+ download_folder = "/tmp/downloads"
34
  for ext in ["mp3", "m4a", "webm"]:
35
  file_path = f"{download_folder}/{video_id}.{ext}"
36
  if os.path.exists(file_path):
 
67
  file_format = data.get("format", "mp3")
68
  file_extension = file_format.lower()
69
  file_name = f"{video_id}.{file_extension}"
70
+ download_folder = "/tmp/downloads"
71
  os.makedirs(download_folder, exist_ok=True)
72
  file_path = os.path.join(download_folder, file_name)
73
 
 
250
  link = self.listbase + link
251
  if "&" in link:
252
  link = link.split("&")[0]
253
+
254
+ ydl_opts = {"ignoreerrors": True, "quiet": True, "dump_single_json": True, "flat_playlist": True, "playlist_items": f"1-{limit}"}
255
+
256
+ proc = await asyncio.create_subprocess_exec(
257
+ "yt-dlp",
258
+ "--cookies", cookie_txt_file(),
259
+ *yt_dlp.utils.shell_quote(ydl_opts),
260
+ link,
261
+ stdout=asyncio.subprocess.PIPE,
262
+ stderr=asyncio.subprocess.PIPE,
263
  )
264
+ stdout, stderr = await proc.communicate()
265
+
266
+ if stderr and "ERROR" in stderr.decode():
267
+ return 0, f"Error fetching playlist: {stderr.decode()}"
268
+
269
  try:
270
+ playlist_data = json.loads(stdout)
271
+ entries = playlist_data.get("entries", [])
272
+ if not entries:
273
+ return 0, "No videos found in the playlist."
274
+ except json.JSONDecodeError:
275
+ return 0, "Failed to parse playlist data."
276
+
277
+ return 1, entries
278
 
279
  async def track(self, link: str, videoid: Union[bool, str] = None):
280
  if videoid:
 
284
  results = VideosSearch(link, limit=1)
285
  for result in (await results.next())["result"]:
286
  title = result["title"]
287
+ duration = result["duration"]
288
  vidid = result["id"]
289
+ return title, duration, vidid
 
 
 
 
 
 
 
 
 
290
 
291
  async def formats(self, link: str, videoid: Union[bool, str] = None):
292
  if videoid:
293
  link = self.base + link
294
  if "&" in link:
295
  link = link.split("&")[0]
296
+ cmd = f'yt-dlp -F "{link}"'
297
+ out = await shell_cmd(cmd)
298
+ return out
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
 
300
  async def slider(
301
  self,
 
305
  ):
306
  if videoid:
307
  link = self.base + link
308
+ if query_type == 1:
309
+ cmd = f'yt-dlp -F "{link}"'
310
+ else:
311
+ cmd = f'yt-dlp -F "ytsearch:{link}"'
312
+ out = await shell_cmd(cmd)
313
+ return out
 
 
 
314
 
315
  async def download(
316
  self,
 
325
  ) -> str:
326
  if videoid:
327
  link = self.base + link
328
+
329
  def audio_dl():
330
+ opts = {
331
+ "format": "bestaudio",
332
+ "addmetadata": True,
333
  "geo_bypass": True,
334
  "nocheckcertificate": True,
335
+ "outtmpl": f"/tmp/downloads/%(id)s.%(ext)s",
336
+ "quiet": False,
337
+ "logtostderr": False,
338
  }
339
+ return opts
 
 
 
 
 
 
340
 
341
  def video_dl():
342
+ opts = {
343
+ "format": "best",
344
+ "addmetadata": True,
345
  "geo_bypass": True,
346
  "nocheckcertificate": True,
347
+ "outtmpl": f"/tmp/downloads/%(id)s.%(ext)s",
348
+ "quiet": False,
349
+ "logtostderr": False,
350
  }
351
+ return opts
 
 
 
 
 
 
352
 
353
  def song_video_dl():
354
+ opts = {
355
+ "format": "best",
356
+ "addmetadata": True,
 
 
357
  "geo_bypass": True,
358
  "nocheckcertificate": True,
359
+ "outtmpl": f"/tmp/downloads/{title}.%(ext)s",
360
+ "quiet": False,
361
+ "logtostderr": False,
 
 
362
  }
363
+ return opts
 
364
 
365
  def song_audio_dl():
366
+ opts = {
367
+ "format": "bestaudio",
368
+ "addmetadata": True,
 
369
  "geo_bypass": True,
370
  "nocheckcertificate": True,
371
+ "outtmpl": f"/tmp/downloads/{title}.%(ext)s",
372
+ "quiet": False,
373
+ "logtostderr": False,
 
 
 
 
 
 
 
 
374
  }
375
+ return opts
 
376
 
377
  if songvideo:
378
+ opts = song_video_dl()
 
 
379
  elif songaudio:
380
+ opts = song_audio_dl()
 
 
381
  elif video:
382
+ opts = video_dl()
383
+ else:
384
+ opts = audio_dl()
385
+ if format_id:
386
+ opts["format"] = format_id
387
+ with yt_dlp.YoutubeDL(opts) as ydl:
388
+ try:
389
+ await mystic.edit("📥 **downloading...**")
390
+ ydl.download([link])
391
+ except Exception as y:
392
+ return await mystic.edit(f"**Failed to download this video.**\n\n**Reason:** {y}")
393
+ if songvideo:
394
+ for file in os.listdir("/tmp/downloads"):
395
+ if file.startswith(title):
396
+ return f"/tmp/downloads/{file}"
397
+ elif songaudio:
398
+ for file in os.listdir("/tmp/downloads"):
399
+ if file.startswith(title):
400
+ return f"/tmp/downloads/{file}"
 
 
 
 
 
 
 
 
 
 
401
  else:
402
+ for file in os.listdir("/tmp/downloads"):
403
+ if file.endswith(".webm"):
404
+ return f"/tmp/downloads/{file}"
405
+ elif file.endswith(".m4a"):
406
+ return f"/tmp/downloads/{file}"
407
+ elif file.endswith(".mp3"):
408
+ return f"/tmp/downloads/{file}"
DragMusic/plugins/sudo/restart.py CHANGED
@@ -126,12 +126,23 @@ async def restart_(_, message):
126
  pass
127
 
128
  try:
129
- shutil.rmtree("downloads")
130
- shutil.rmtree("raw_files")
131
- shutil.rmtree("cache")
132
  except:
133
  pass
134
- await response.edit_text(
135
- "» ʀᴇsᴛᴀʀᴛ ᴘʀᴏᴄᴇss sᴛᴀʀᴛᴇᴅ, ᴘʟᴇᴀsᴇ ᴡᴀɪᴛ ғᴏʀ ғᴇᴡ sᴇᴄᴏɴᴅs ᴜɴᴛɪʟ ᴛʜᴇ ʙᴏᴛ sᴛᴀʀᴛs..."
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  )
137
  os.system(f"kill -9 {os.getpid()} && bash start")
 
126
  pass
127
 
128
  try:
129
+ shutil.rmtree("/tmp/cache")
 
 
130
  except:
131
  pass
132
+ try:
133
+ shutil.rmtree("/tmp/downloads")
134
+ except:
135
+ pass
136
+ try:
137
+ os.mkdir("/tmp/cache")
138
+ except:
139
+ pass
140
+ try:
141
+ os.mkdir("/tmp/downloads")
142
+ except:
143
+ pass
144
+ await asyncio.sleep(2)
145
+ await message.reply_text(
146
+ "**✅ Restarted **\n\n**Bot has been restarted successfully.**\n\n"
147
  )
148
  os.system(f"kill -9 {os.getpid()} && bash start")
DragMusic/plugins/tools/afk.py CHANGED
@@ -1,4 +1,4 @@
1
- import time, re
2
  from config import BOT_USERNAME
3
  from pyrogram.enums import MessageEntityType
4
  from pyrogram import filters
@@ -47,12 +47,12 @@ async def active_afk(_, message: Message):
47
  if afktype == "photo":
48
  if str(reasonafk) == "None":
49
  send = await message.reply_photo(
50
- photo=f"downloads/{user_id}.jpg",
51
  caption=f"{message.from_user.first_name} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ {seenago}",
52
  )
53
  else:
54
  send = await message.reply_photo(
55
- photo=f"downloads/{user_id}.jpg",
56
  caption=f"{message.from_user.first_name} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ {seenago}\n\nReason: {reasonafk}",
57
  )
58
  except Exception:
@@ -95,7 +95,7 @@ async def active_afk(_, message: Message):
95
  }
96
  elif len(message.command) == 1 and message.reply_to_message.photo:
97
  await app.download_media(
98
- message.reply_to_message, file_name=f"{user_id}.jpg"
99
  )
100
  details = {
101
  "type": "photo",
@@ -105,7 +105,7 @@ async def active_afk(_, message: Message):
105
  }
106
  elif len(message.command) > 1 and message.reply_to_message.photo:
107
  await app.download_media(
108
- message.reply_to_message, file_name=f"{user_id}.jpg"
109
  )
110
  _reason = message.text.split(None, 1)[1].strip()
111
  details = {
@@ -124,7 +124,7 @@ async def active_afk(_, message: Message):
124
  }
125
  else:
126
  await app.download_media(
127
- message.reply_to_message, file_name=f"{user_id}.jpg"
128
  )
129
  details = {
130
  "type": "photo",
@@ -143,7 +143,7 @@ async def active_afk(_, message: Message):
143
  }
144
  else:
145
  await app.download_media(
146
- message.reply_to_message, file_name=f"{user_id}.jpg"
147
  )
148
  details = {
149
  "type": "photo",
@@ -217,12 +217,12 @@ async def chat_watcher_func(_, message):
217
  if afktype == "photo":
218
  if str(reasonafk) == "None":
219
  send = await message.reply_photo(
220
- photo=f"downloads/{userid}.jpg",
221
  caption=f"{user_name[:25]} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ {seenago}\n\n",
222
  )
223
  else:
224
  send = await message.reply_photo(
225
- photo=f"downloads/{userid}.jpg",
226
  caption=f"{user_name[:25]} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ {seenago}\n\nReason: {reasonafk}\n\n",
227
  )
228
  except:
@@ -261,12 +261,12 @@ async def chat_watcher_func(_, message):
261
  if afktype == "photo":
262
  if str(reasonafk) == "None":
263
  send = await message.reply_photo(
264
- photo=f"downloads/{replied_user_id}.jpg",
265
  caption=f"{replied_first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\n",
266
  )
267
  else:
268
  send = await message.reply_photo(
269
- photo=f"downloads/{replied_user_id}.jpg",
270
  caption=f"{replied_first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\nReason: {reasonafk}\n\n",
271
  )
272
  except Exception:
@@ -317,12 +317,12 @@ async def chat_watcher_func(_, message):
317
  if afktype == "photo":
318
  if str(reasonafk) == "None":
319
  send = await message.reply_photo(
320
- photo=f"downloads/{user.id}.jpg",
321
  caption=f"{user.first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\n",
322
  )
323
  else:
324
  send = await message.reply_photo(
325
- photo=f"downloads/{user.id}.jpg",
326
  caption=f"{user.first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\nAlasan: {reasonafk}\n\n",
327
  )
328
  except:
@@ -363,12 +363,12 @@ async def chat_watcher_func(_, message):
363
  if afktype == "photo":
364
  if str(reasonafk) == "None":
365
  send = await message.reply_photo(
366
- photo=f"downloads/{user_id}.jpg",
367
  caption=f"{first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\n",
368
  )
369
  else:
370
  send = await message.reply_photo(
371
- photo=f"downloads/{user_id}.jpg",
372
  caption=f"{first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\nAlasan: {reasonafk}\n\n",
373
  )
374
  except:
 
1
+ import time, re, os
2
  from config import BOT_USERNAME
3
  from pyrogram.enums import MessageEntityType
4
  from pyrogram import filters
 
47
  if afktype == "photo":
48
  if str(reasonafk) == "None":
49
  send = await message.reply_photo(
50
+ photo=f"/tmp/downloads/{user_id}.jpg",
51
  caption=f"{message.from_user.first_name} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ {seenago}",
52
  )
53
  else:
54
  send = await message.reply_photo(
55
+ photo=f"/tmp/downloads/{user_id}.jpg",
56
  caption=f"{message.from_user.first_name} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ {seenago}\n\nReason: {reasonafk}",
57
  )
58
  except Exception:
 
95
  }
96
  elif len(message.command) == 1 and message.reply_to_message.photo:
97
  await app.download_media(
98
+ message.reply_to_message, file_name=f"/tmp/downloads/{user_id}.jpg"
99
  )
100
  details = {
101
  "type": "photo",
 
105
  }
106
  elif len(message.command) > 1 and message.reply_to_message.photo:
107
  await app.download_media(
108
+ message.reply_to_message, file_name=f"/tmp/downloads/{user_id}.jpg"
109
  )
110
  _reason = message.text.split(None, 1)[1].strip()
111
  details = {
 
124
  }
125
  else:
126
  await app.download_media(
127
+ message.reply_to_message, file_name=f"/tmp/downloads/{user_id}.jpg"
128
  )
129
  details = {
130
  "type": "photo",
 
143
  }
144
  else:
145
  await app.download_media(
146
+ message.reply_to_message, file_name=f"/tmp/downloads/{user_id}.jpg"
147
  )
148
  details = {
149
  "type": "photo",
 
217
  if afktype == "photo":
218
  if str(reasonafk) == "None":
219
  send = await message.reply_photo(
220
+ photo=f"/tmp/downloads/{userid}.jpg",
221
  caption=f"{user_name[:25]} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ {seenago}\n\n",
222
  )
223
  else:
224
  send = await message.reply_photo(
225
+ photo=f"/tmp/downloads/{userid}.jpg",
226
  caption=f"{user_name[:25]} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ {seenago}\n\nReason: {reasonafk}\n\n",
227
  )
228
  except:
 
261
  if afktype == "photo":
262
  if str(reasonafk) == "None":
263
  send = await message.reply_photo(
264
+ photo=f"/tmp/downloads/{replied_user_id}.jpg",
265
  caption=f"{replied_first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\n",
266
  )
267
  else:
268
  send = await message.reply_photo(
269
+ photo=f"/tmp/downloads/{replied_user_id}.jpg",
270
  caption=f"{replied_first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\nReason: {reasonafk}\n\n",
271
  )
272
  except Exception:
 
317
  if afktype == "photo":
318
  if str(reasonafk) == "None":
319
  send = await message.reply_photo(
320
+ photo=f"/tmp/downloads/{user.id}.jpg",
321
  caption=f"{user.first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\n",
322
  )
323
  else:
324
  send = await message.reply_photo(
325
+ photo=f"/tmp/downloads/{user.id}.jpg",
326
  caption=f"{user.first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\nAlasan: {reasonafk}\n\n",
327
  )
328
  except:
 
363
  if afktype == "photo":
364
  if str(reasonafk) == "None":
365
  send = await message.reply_photo(
366
+ photo=f"/tmp/downloads/{user_id}.jpg",
367
  caption=f"{first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\n",
368
  )
369
  else:
370
  send = await message.reply_photo(
371
+ photo=f"/tmp/downloads/{user_id}.jpg",
372
  caption=f"{first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\nAlasan: {reasonafk}\n\n",
373
  )
374
  except:
DragMusic/plugins/tools/welcome.py CHANGED
@@ -4,6 +4,8 @@ from pyrogram import *
4
  from pyrogram.types import *
5
  from logging import getLogger
6
  from DragMusic import app
 
 
7
 
8
 
9
 
@@ -19,8 +21,7 @@ class WelDatabase:
19
  return chat_id in self.data
20
 
21
  async def add_wlcm(self, chat_id):
22
- self.data[chat_id] = {} # You can store additional information related to the chat
23
- # For example, self.data[chat_id]['some_key'] = 'some_value'
24
 
25
  async def rm_wlcm(self, chat_id):
26
  if chat_id in self.data:
@@ -62,15 +63,15 @@ def welcomepic(pic, user, chatname, id, uname):
62
  draw.text((2100, 1420), f'ID: {id}', fill=(12000, 12000, 12000), font=font)
63
  pfp_position = (1990, 435)
64
  background.paste(pfp, pfp_position, pfp)
65
- background.save(f"downloads/welcome#{id}.png")
66
- return f"downloads/welcome#{id}.png"
67
 
68
  # FUCK you bhosadiwale
69
 
70
 
71
  @app.on_message(filters.command("wel") & ~filters.private)
72
  async def auto_state(_, message):
73
- usage = "**Usage:**\n⦿/wel [on|off]\n➤ᴀᴜʀ ʜᴀᴀɴ ᴋᴀɴɢᴇʀs ᴋᴀʀᴏ ᴀʙ ᴄᴏᴘʏ ʙʜᴏsᴀᴅɪᴡᴀʟᴇ\n➤sᴀʟᴏɴ ᴀᴜʀ ʜᴀᴀɴ sᴛʏʟɪsʜ ғᴏɴᴛ ɴᴏᴛ ᴀʟʟᴏᴡᴇᴅ ɪɴ ᴛʜᴇ ᴛʜᴜᴍʙɴᴀɪʟ.!\ᴀᴜʀ ʜᴀᴀɴ ᴀɢʀ ᴋʜᴜᴅ ᴋɪ ᴋᴀʀɴɪ ʜᴀɪ ᴛᴏ ɢᴀᴀɴᴅ ᴍᴀʀᴀᴏ ʙᴇᴛɪᴄʜᴏᴅ"
74
  if len(message.command) == 1:
75
  return await message.reply_text(usage)
76
  chat_id = message.chat.id
@@ -103,7 +104,7 @@ async def auto_state(_, message):
103
  @app.on_chat_member_updated(filters.group, group=-3)
104
  async def greet_group(_, member: ChatMemberUpdated):
105
  chat_id = member.chat.id
106
- A = await wlcm.find_one(chat_id) # Corrected this line
107
  if not A:
108
  return
109
  if (
@@ -115,7 +116,7 @@ async def greet_group(_, member: ChatMemberUpdated):
115
  user = member.new_chat_member.user if member.new_chat_member else member.from_user
116
  try:
117
  pic = await app.download_media(
118
- user.photo.big_file_id, file_name=f"pp{user.id}.png"
119
  )
120
  except AttributeError:
121
  pic = "DragMusic/assets/upic.png"
@@ -137,15 +138,14 @@ async def greet_group(_, member: ChatMemberUpdated):
137
  ๏ ɴᴀᴍᴇ ➛ {user.mention}
138
  ๏ ɪᴅ ➛ {user.id}
139
  ๏ ᴜsᴇʀɴᴀᴍᴇ ➛ @{user.username}
140
- ๏ ᴍᴀᴅᴇ ʙʏ ➛ [ʀᴏʏ-ᴇᴅɪᴛx](https://t.me/BTSChinna**
141
  """,
142
- reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(f"ᴀᴅᴅ ᴍᴇ ʙᴀʙʏ", url=f"https://t.me/alexaprobot?startgroup=true")]])
143
  )
144
  except Exception as e:
145
  LOGGER.error(e)
146
  try:
147
- os.remove(f"downloads/welcome#{user.id}.png")
148
- os.remove(f"downloads/pp{user.id}.png")
149
  except Exception as e:
150
  pass
151
 
@@ -155,11 +155,158 @@ async def greet_group(_, member: ChatMemberUpdated):
155
  async def bot_wel(_, message):
156
  for u in message.new_chat_members:
157
  if u.id == app.me.id:
158
- await app.send_message(LOG_CHANNEL_ID, f"""
159
- **NEW GROUP
160
- ➖➖➖➖➖➖➖➖➖➖➖➖
161
- NAME: {message.chat.title}
162
- ID: {message.chat.id}
163
- USERNAME: @{message.chat.username}
164
- ➖➖➖➖➖➖➖➖➖➖➖➖**
165
- """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  from pyrogram.types import *
5
  from logging import getLogger
6
  from DragMusic import app
7
+ from typing import Union
8
+ import textwrap
9
 
10
 
11
 
 
21
  return chat_id in self.data
22
 
23
  async def add_wlcm(self, chat_id):
24
+ self.data[chat_id] = {}
 
25
 
26
  async def rm_wlcm(self, chat_id):
27
  if chat_id in self.data:
 
63
  draw.text((2100, 1420), f'ID: {id}', fill=(12000, 12000, 12000), font=font)
64
  pfp_position = (1990, 435)
65
  background.paste(pfp, pfp_position, pfp)
66
+ background.save(f"/tmp/downloads/welcome#{id}.png")
67
+ return f"/tmp/downloads/welcome#{id}.png"
68
 
69
  # FUCK you bhosadiwale
70
 
71
 
72
  @app.on_message(filters.command("wel") & ~filters.private)
73
  async def auto_state(_, message):
74
+ usage = "**Usage:**\n⦿/wel [on|off]"
75
  if len(message.command) == 1:
76
  return await message.reply_text(usage)
77
  chat_id = message.chat.id
 
104
  @app.on_chat_member_updated(filters.group, group=-3)
105
  async def greet_group(_, member: ChatMemberUpdated):
106
  chat_id = member.chat.id
107
+ A = await wlcm.find_one(chat_id)
108
  if not A:
109
  return
110
  if (
 
116
  user = member.new_chat_member.user if member.new_chat_member else member.from_user
117
  try:
118
  pic = await app.download_media(
119
+ user.photo.big_file_id, file_name=f"/tmp/downloads/pp{user.id}.png"
120
  )
121
  except AttributeError:
122
  pic = "DragMusic/assets/upic.png"
 
138
  ๏ ɴᴀᴍᴇ ➛ {user.mention}
139
  ๏ ɪᴅ ➛ {user.id}
140
  ๏ ᴜsᴇʀɴᴀᴍᴇ ➛ @{user.username}
 
141
  """,
142
+ reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(f"ᴀᴅᴅ ᴍᴇ ʙᴀʙʏ", url=f"https://t.me/{(await app.get_me()).username}?startgroup=true")]])
143
  )
144
  except Exception as e:
145
  LOGGER.error(e)
146
  try:
147
+ os.remove(f"/tmp/downloads/welcome#{user.id}.png")
148
+ os.remove(f"/tmp/downloads/pp{user.id}.png")
149
  except Exception as e:
150
  pass
151
 
 
155
  async def bot_wel(_, message):
156
  for u in message.new_chat_members:
157
  if u.id == app.me.id:
158
+ await app.send_message(message.chat.id, "Thanks for adding me to your group.")
159
+
160
+ async def welcome_captcha(
161
+ _, message: Message, cb_data: dict, failed: bool = False
162
+ ) -> Union[int, bool]:
163
+ if failed:
164
+ photo = (
165
+ "https://telegra.ph/file/223695233211590f7ac71.jpg"
166
+ )
167
+ else:
168
+ photo = (
169
+ "https://telegra.ph/file/223695233211590f7ac71.jpg"
170
+ )
171
+ background = Image.open(photo)
172
+ background = background.resize((1280, 720))
173
+
174
+ #
175
+ image3 = Image.new("RGBA", (1280, 720))
176
+ image3.paste(background, (0, 0))
177
+ #
178
+
179
+ # Drawing with Impact Font
180
+ draw = ImageDraw.Draw(image3)
181
+ font = ImageFont.truetype("DragMusic/assets/font.ttf", 60)
182
+ font2 = ImageFont.truetype("DragMusic/assets/font2.ttf", 70)
183
+ arial = ImageFont.truetype("DragMusic/assets/font2.ttf", 40)
184
+ gfont = ImageFont.truetype("DragMusic/assets/font2.tf", 40)
185
+ para = textwrap.wrap(title, width=32)
186
+ j = 0
187
+ try:
188
+ if para[0]:
189
+ draw.text(
190
+ (5, 5),
191
+ f"{para[0]}",
192
+ fill="white",
193
+ stroke_width=3,
194
+ stroke_fill="black",
195
+ font=font,
196
+ )
197
+ if para[1]:
198
+ draw.text(
199
+ (5, 70),
200
+ f"{para[1]}",
201
+ fill="white",
202
+ stroke_width=3,
203
+ stroke_fill="black",
204
+ font=font,
205
+ )
206
+ except:
207
+ pass
208
+ text_w, text_h = draw.textsize(f"Welcome to {ctitle}", font=gfont)
209
+ draw.text(
210
+ ((1280 - text_w) / 2, 615),
211
+ f"Welcome to {ctitle}",
212
+ fill="white",
213
+ font=gfont,
214
+ )
215
+ draw.text((740, 480), "NAME:", fill="white", font=arial)
216
+ draw.text(
217
+ (915, 480),
218
+ f"{fullname}",
219
+ fill="white",
220
+ font=arial,
221
+ )
222
+ draw.text(
223
+ (740, 530),
224
+ f"USERNAME : @{uname}",
225
+ (255, 255, 255),
226
+ font=arial,
227
+ )
228
+
229
+ background.save(f"/tmp/downloads/welcome#{id}.png")
230
+ return f"/tmp/downloads/welcome#{id}.png"
231
+
232
+
233
+ async def on_new_chat_member(client, message: Message):
234
+ if not await is_approved(message.chat.id):
235
+ return await message.reply_text(
236
+ f"Greetings {message.from_user.mention}, and welcome to {message.chat.title}.\n\n{app.mention} do not have permission to work here. You must request permission from my owner."
237
+ )
238
+ if message.from_user.id in BANNED_USERS:
239
+ return
240
+ if (await client.get_me()).id in [user.id for user in message.new_chat_members]:
241
+ return
242
+ for user in message.new_chat_members:
243
+ if await is_gbanned_user(user.id):
244
+ await message.chat.ban_member(user.id)
245
+ await message.reply_text(
246
+ f"{user.mention} was globally banned, so I'm kicking them. Sorry for the inconvenience."
247
+ )
248
+ return
249
+ if user.is_bot:
250
+ return
251
+ if not await is_welcome_on(message.chat.id):
252
+ continue
253
+ # Check if the user is a bot
254
+ if user.is_bot:
255
+ return # Do not send a welcome message to bots
256
+
257
+ # Get the welcome message and buttons for the chat
258
+ welcome, buttons = await get_welcome(str(message.chat.id))
259
+
260
+ # Replace placeholders in the welcome message with user and chat information
261
+ mention = user.mention
262
+ title = message.chat.title
263
+ fullname = user.first_name + " " + user.last_name if user.last_name else user.first_name
264
+ username = f"@{user.username}" if user.username else "NO USERNAME"
265
+ user_id = user.id
266
+ # Send the welcome message with the custom buttons
267
+ await client.send_message(
268
+ chat_id=message.chat.id,
269
+ text=welcome.format(
270
+ mention=mention,
271
+ title=title,
272
+ fullname=fullname,
273
+ username=username,
274
+ id=user_id,
275
+ ),
276
+ reply_markup=InlineKeyboardMarkup(buttons),
277
+ disable_web_page_preview=True,
278
+ )
279
+
280
+
281
+ async def on_user_left(client, message: Message):
282
+ if not await is_goodbye_on(message.chat.id):
283
+ return
284
+ if await is_gbanned_user(message.left_chat_member.id):
285
+ return
286
+
287
+ left = message.left_chat_member
288
+ if left.is_bot:
289
+ return # Do not send a goodbye message to bots
290
+
291
+ # Get the goodbye message and buttons for the chat
292
+ goodbye, buttons = await get_goodbye(str(message.chat.id))
293
+
294
+ # Replace placeholders in the goodbye message with user and chat information
295
+ mention = left.mention
296
+ title = message.chat.title
297
+ fullname = left.first_name + " " + left.last_name if left.last_name else left.first_name
298
+ username = f"@{left.username}" if left.username else "NO USERNAME"
299
+ user_id = left.id
300
+ # Send the goodbye message with the custom buttons
301
+ await client.send_message(
302
+ chat_id=message.chat.id,
303
+ text=goodbye.format(
304
+ mention=mention,
305
+ title=title,
306
+ fullname=fullname,
307
+ username=username,
308
+ id=user_id,
309
+ ),
310
+ reply_markup=InlineKeyboardMarkup(buttons),
311
+ disable_web_page_preview=True,
312
+ )
DragMusic/utils/thumbnails.py CHANGED
@@ -1,5 +1,6 @@
1
  import os
2
  import re
 
3
 
4
  import aiofiles
5
  import aiohttp
@@ -8,7 +9,9 @@ from unidecode import unidecode
8
  from youtubesearchpython.__future__ import VideosSearch
9
 
10
  from DragMusic import app
 
11
  from config import YOUTUBE_IMG_URL
 
12
 
13
 
14
  def changeImageSize(maxWidth, maxHeight, image):
@@ -30,8 +33,8 @@ def clear(text):
30
 
31
 
32
  async def get_thumb(videoid):
33
- if os.path.isfile(f"cache/{videoid}.png"):
34
- return f"cache/{videoid}.png"
35
 
36
  url = f"https://www.youtube.com/watch?v={videoid}"
37
  try:
@@ -39,7 +42,7 @@ async def get_thumb(videoid):
39
  for result in (await results.next())["result"]:
40
  try:
41
  title = result["title"]
42
- title = re.sub("\W+", " ", title)
43
  title = title.title()
44
  except:
45
  title = "Unsupported Title"
@@ -60,11 +63,11 @@ async def get_thumb(videoid):
60
  async with aiohttp.ClientSession() as session:
61
  async with session.get(thumbnail) as resp:
62
  if resp.status == 200:
63
- f = await aiofiles.open(f"cache/thumb{videoid}.png", mode="wb")
64
  await f.write(await resp.read())
65
  await f.close()
66
 
67
- youtube = Image.open(f"cache/thumb{videoid}.png")
68
  image1 = changeImageSize(1280, 720, youtube)
69
  image2 = image1.convert("RGBA")
70
  background = image2.filter(filter=ImageFilter.BoxBlur(10))
@@ -111,11 +114,204 @@ async def get_thumb(videoid):
111
  font=arial,
112
  )
113
  try:
114
- os.remove(f"cache/thumb{videoid}.png")
115
  except:
116
  pass
117
- background.save(f"cache/{videoid}.png")
118
- return f"cache/{videoid}.png"
119
  except Exception as e:
120
  print(e)
121
  return YOUTUBE_IMG_URL
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import os
2
  import re
3
+ import textwrap
4
 
5
  import aiofiles
6
  import aiohttp
 
9
  from youtubesearchpython.__future__ import VideosSearch
10
 
11
  from DragMusic import app
12
+ from DragMusic.core.mongo import db
13
  from config import YOUTUBE_IMG_URL
14
+ from DragMusic.logging import LOGGER
15
 
16
 
17
  def changeImageSize(maxWidth, maxHeight, image):
 
33
 
34
 
35
  async def get_thumb(videoid):
36
+ if os.path.isfile(f"/tmp/cache/{videoid}.png"):
37
+ return f"/tmp/cache/{videoid}.png"
38
 
39
  url = f"https://www.youtube.com/watch?v={videoid}"
40
  try:
 
42
  for result in (await results.next())["result"]:
43
  try:
44
  title = result["title"]
45
+ title = re.sub("\\W+", " ", title)
46
  title = title.title()
47
  except:
48
  title = "Unsupported Title"
 
63
  async with aiohttp.ClientSession() as session:
64
  async with session.get(thumbnail) as resp:
65
  if resp.status == 200:
66
+ f = await aiofiles.open(f"/tmp/cache/thumb{videoid}.png", mode="wb")
67
  await f.write(await resp.read())
68
  await f.close()
69
 
70
+ youtube = Image.open(f"/tmp/cache/thumb{videoid}.png")
71
  image1 = changeImageSize(1280, 720, youtube)
72
  image2 = image1.convert("RGBA")
73
  background = image2.filter(filter=ImageFilter.BoxBlur(10))
 
114
  font=arial,
115
  )
116
  try:
117
+ os.remove(f"/tmp/cache/thumb{videoid}.png")
118
  except:
119
  pass
120
+ background.save(f"/tmp/cache/{videoid}.png")
121
+ return f"/tmp/cache/{videoid}.png"
122
  except Exception as e:
123
  print(e)
124
  return YOUTUBE_IMG_URL
125
+
126
+
127
+ async def gen_thumb(videoid: str, user_id: int) -> str:
128
+ if os.path.isfile(f"/tmp/cache/{videoid}.png"):
129
+ return f"/tmp/cache/{videoid}.png"
130
+ url = f"https://www.youtube.com/watch?v={videoid}"
131
+ try:
132
+ results = VideosSearch(url, limit=1)
133
+ for result in (await results.next())["result"]:
134
+ try:
135
+ title = result["title"]
136
+ title = re.sub("\\W+", " ", title)
137
+ title = title.title()
138
+ except:
139
+ title = "Unsupported Title"
140
+ try:
141
+ duration = result["duration"]
142
+ except:
143
+ duration = "Unknown Mins"
144
+ thumbnail = result["thumbnails"][0]["url"].split("?")[0]
145
+ try:
146
+ views = result["viewCount"]["short"]
147
+ except:
148
+ views = "Unknown Views"
149
+ try:
150
+ channel = result["channel"]["name"]
151
+ except:
152
+ channel = "Unknown Channel"
153
+
154
+ async with aiohttp.ClientSession() as session:
155
+ async with session.get(thumbnail) as resp:
156
+ if resp.status == 200:
157
+ ctitle = (await app.get_chat(user_id)).title
158
+ ctitle = await crop_title(ctitle)
159
+ try:
160
+ f = await aiofiles.open(f"/tmp/cache/thumb{videoid}.png", mode="wb")
161
+ await f.write(await resp.read())
162
+ await f.close()
163
+ youtube = Image.open(f"/tmp/cache/thumb{videoid}.png")
164
+ image1 = changeImageSize(1280, 720, youtube)
165
+ image2 = image1.convert("RGBA")
166
+ background = image2.filter(filter=ImageFilter.BoxBlur(30))
167
+ enhancer = ImageEnhance.Brightness(background)
168
+ background = enhancer.enhance(0.5)
169
+ draw = ImageDraw.Draw(background)
170
+ arial = ImageFont.truetype("DragMusic/assets/font2.ttf", 40)
171
+ font = ImageFont.truetype("DragMusic/assets/font.ttf", 30)
172
+ draw.text((1110, 8), unidecode(app.name), fill="white", font=arial)
173
+ draw.text(
174
+ (55, 560),
175
+ f"{channel} | {views[:23]}",
176
+ (255, 255, 255),
177
+ font=arial,
178
+ )
179
+ draw.text(
180
+ (57, 600),
181
+ clear(title),
182
+ (255, 255, 255),
183
+ font=font,
184
+ )
185
+ draw.line(
186
+ [(55, 660), (1220, 660)],
187
+ fill="white",
188
+ width=5,
189
+ joint="curve",
190
+ )
191
+ draw.ellipse(
192
+ [(918, 648), (942, 672)],
193
+ outline="white",
194
+ fill="white",
195
+ width=15,
196
+ )
197
+ draw.text(
198
+ (36, 685),
199
+ "00:00",
200
+ (255, 255, 255),
201
+ font=arial,
202
+ )
203
+ draw.text(
204
+ (1185, 685),
205
+ f"{duration[:23]}",
206
+ (255, 255, 255),
207
+ font=arial,
208
+ )
209
+ except Exception:
210
+ pass
211
+ circle = Image.open("DragMusic/assets/circle.png")
212
+ try:
213
+ pfp = Image.open(
214
+ await app.download_media(
215
+ (await app.get_chat(user_id)).photo.big_file_id,
216
+ file_name=f"pfp{user_id}.png",
217
+ )
218
+ )
219
+ except Exception:
220
+ pfp = Image.open("DragMusic/assets/profile.png")
221
+ pfp = pfp.resize((450, 450))
222
+ pfp = crop_center(pfp, 450, 450)
223
+ pfp = mask_circle_solid(pfp, (0, 0, 0, 0), 225)
224
+
225
+ #
226
+ image3 = Image.new("RGBA", (1280, 720))
227
+ image3.paste(background, (0, 0))
228
+ image3.paste(youtube, (200, 70), mask=youtube)
229
+ image3.paste(pfp, (410, 420), mask=pfp)
230
+ image3.paste(circle, (410, 420), mask=circle)
231
+
232
+ # Drawing with Impact Font
233
+ draw = ImageDraw.Draw(image3)
234
+ font = ImageFont.truetype("DragMusic/assets/font.ttf", 60)
235
+ font2 = ImageFont.truetype("DragMusic/assets/font2.ttf", 70)
236
+ arial = ImageFont.truetype("DragMusic/assets/font2.ttf", 40)
237
+ gfont = ImageFont.truetype("DragMusic/assets/font2.ttf", 40)
238
+ para = textwrap.wrap(title, width=32)
239
+ j = 0
240
+ try:
241
+ if para[0]:
242
+ draw.text(
243
+ (5, 5),
244
+ f"{para[0]}",
245
+ fill="white",
246
+ stroke_width=3,
247
+ stroke_fill="black",
248
+ font=font,
249
+ )
250
+ if para[1]:
251
+ draw.text(
252
+ (5, 70),
253
+ f"{para[1]}",
254
+ fill="white",
255
+ stroke_width=3,
256
+ stroke_fill="black",
257
+ font=font,
258
+ )
259
+ except:
260
+ pass
261
+ text_w, text_h = draw.textsize(f"Playing on: {ctitle}", font=gfont)
262
+ draw.text(
263
+ ((1280 - text_w) / 2, 615),
264
+ f"Playing on: {ctitle}",
265
+ fill="white",
266
+ font=gfont,
267
+ )
268
+ draw.text((740, 480), "Duration:", fill="white", font=arial)
269
+ draw.text(
270
+ (915, 480),
271
+ f"{duration} Mins",
272
+ fill="white",
273
+ font=arial,
274
+ )
275
+ draw.text(
276
+ (740, 530),
277
+ f"Views : {views}",
278
+ (255, 255, 255),
279
+ font=arial,
280
+ )
281
+
282
+ try:
283
+ os.remove(f"/tmp/cache/thumb{videoid}.png")
284
+ except:
285
+ pass
286
+ background.save(f"/tmp/cache/{videoid}.png")
287
+ return f"/tmp/cache/{videoid}.png"
288
+ except Exception as e:
289
+ LOGGER(__name__).error(e)
290
+ return ""
291
+
292
+
293
+ def crop_center(pil_img, crop_width, crop_height):
294
+ img_width, img_height = pil_img.size
295
+ return pil_img.crop(
296
+ (
297
+ (img_width - crop_width) // 2,
298
+ (img_height - crop_height) // 2,
299
+ (img_width + crop_width) // 2,
300
+ (img_height + crop_height) // 2,
301
+ )
302
+ )
303
+
304
+
305
+ def mask_circle_solid(im, a, size):
306
+ output = Image.new("RGBA", (size, size), (0, 0, 0, 0))
307
+ draw = ImageDraw.Draw(output)
308
+ draw.ellipse((0, 0, size, size), fill=a)
309
+ output.putalpha(220)
310
+ return output
311
+
312
+
313
+ async def crop_title(title):
314
+ if len(title) > 20:
315
+ return f"{title[:20]}..."
316
+ else:
317
+ return title