taslim19 commited on
Commit
8d58bbb
·
1 Parent(s): a2c0892

fix: use temp directory for all YouTube downloads to avoid permission errors

Browse files
Files changed (1) hide show
  1. DragMusic/platforms/Youtube.py +28 -7
DragMusic/platforms/Youtube.py CHANGED
@@ -1,4 +1,3 @@
1
-
2
  import asyncio
3
  import os
4
  import re
@@ -11,6 +10,8 @@ from pyrogram.types import Message
11
  from youtubesearchpython.__future__ import VideosSearch
12
  from DragMusic.utils.database import is_on_off
13
  from DragMusic.utils.formatters import time_to_seconds
 
 
14
  async def shell_cmd(cmd):
15
  proc = await asyncio.create_subprocess_shell(
16
  cmd,
@@ -24,6 +25,7 @@ async def shell_cmd(cmd):
24
  else:
25
  return errorz.decode("utf-8")
26
  return out.decode("utf-8")
 
27
  class YouTubeAPI:
28
  def __init__(self):
29
  self.base = "https://www.youtube.com/watch?v="
@@ -31,6 +33,7 @@ class YouTubeAPI:
31
  self.status = "https://www.youtube.com/oembed?url="
32
  self.listbase = "https://youtube.com/playlist?list="
33
  self.reg = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
 
34
  async def exists(self, link: str, videoid: Union[bool, str] = None):
35
  if videoid:
36
  link = self.base + link
@@ -38,6 +41,7 @@ class YouTubeAPI:
38
  return True
39
  else:
40
  return False
 
41
  async def url(self, message_1: Message) -> Union[str, None]:
42
  messages = [message_1]
43
  if message_1.reply_to_message:
@@ -61,6 +65,7 @@ class YouTubeAPI:
61
  if offset in (None,):
62
  return None
63
  return text[offset : offset + length]
 
64
  async def details(self, link: str, videoid: Union[bool, str] = None):
65
  if videoid:
66
  link = self.base + link
@@ -77,6 +82,7 @@ class YouTubeAPI:
77
  else:
78
  duration_sec = int(time_to_seconds(duration_min))
79
  return title, duration_min, duration_sec, thumbnail, vidid
 
80
  async def title(self, link: str, videoid: Union[bool, str] = None):
81
  if videoid:
82
  link = self.base + link
@@ -86,6 +92,7 @@ class YouTubeAPI:
86
  for result in (await results.next())["result"]:
87
  title = result["title"]
88
  return title
 
89
  async def duration(self, link: str, videoid: Union[bool, str] = None):
90
  if videoid:
91
  link = self.base + link
@@ -95,6 +102,7 @@ class YouTubeAPI:
95
  for result in (await results.next())["result"]:
96
  duration = result["duration"]
97
  return duration
 
98
  async def thumbnail(self, link: str, videoid: Union[bool, str] = None):
99
  if videoid:
100
  link = self.base + link
@@ -104,6 +112,7 @@ class YouTubeAPI:
104
  for result in (await results.next())["result"]:
105
  thumbnail = result["thumbnails"][0]["url"].split("?")[0]
106
  return thumbnail
 
107
  async def video(self, link: str, videoid: Union[bool, str] = None):
108
  if videoid:
109
  link = self.base + link
@@ -123,6 +132,7 @@ class YouTubeAPI:
123
  return 1, stdout.decode().split("\n")[0]
124
  else:
125
  return 0, stderr.decode()
 
126
  async def playlist(self, link, limit, user_id, videoid: Union[bool, str] = None):
127
  if videoid:
128
  link = self.listbase + link
@@ -139,6 +149,7 @@ class YouTubeAPI:
139
  except:
140
  result = []
141
  return result
 
142
  async def track(self, link: str, videoid: Union[bool, str] = None):
143
  if videoid:
144
  link = self.base + link
@@ -159,6 +170,7 @@ class YouTubeAPI:
159
  "thumb": thumbnail,
160
  }
161
  return track_details, vidid
 
162
  async def formats(self, link: str, videoid: Union[bool, str] = None):
163
  if videoid:
164
  link = self.base + link
@@ -194,6 +206,7 @@ class YouTubeAPI:
194
  }
195
  )
196
  return formats_available, link
 
197
  async def slider(
198
  self,
199
  link: str,
@@ -211,6 +224,7 @@ class YouTubeAPI:
211
  vidid = result[query_type]["id"]
212
  thumbnail = result[query_type]["thumbnails"][0]["url"].split("?")[0]
213
  return title, duration_min, thumbnail, vidid
 
214
  async def get_video_info_from_bitflow(self, url: str, video: bool):
215
  api_url = "https://bitflow.in/api/youtube"
216
  params = {
@@ -226,6 +240,7 @@ class YouTubeAPI:
226
  return response.json()
227
  else:
228
  return {"status": "error", "message": "Failed to fetch data from Bitflow API."}
 
229
  async def download(
230
  self,
231
  link: str,
@@ -244,7 +259,8 @@ class YouTubeAPI:
244
  loop = asyncio.get_running_loop()
245
  bitflow_info = await self.get_video_info_from_bitflow(link, video)
246
  def audio_dl(bitflow_info):
247
- xyz = os.path.join("downloads", f"{bitflow_info['videoid']}.{bitflow_info['ext']}")
 
248
  ydl_optssx = {
249
  "format": "bestaudio/best",
250
  "outtmpl": xyz,
@@ -259,7 +275,8 @@ class YouTubeAPI:
259
  x.download([bitflow_info['url']])
260
  return xyz
261
  def video_dl(bitflow_info):
262
- xyz = os.path.join("downloads", f"{bitflow_info['videoid']}.{bitflow_info['ext']}")
 
263
  ydl_optssx = {
264
  "format": "(bestvideo[height<=?720][width<=?1280][ext=mp4])+(bestaudio[ext=m4a])",
265
  "outtmpl": xyz,
@@ -274,8 +291,9 @@ class YouTubeAPI:
274
  x.download([bitflow_info['url']])
275
  return xyz
276
  def song_video_dl():
 
 
277
  formats = f"{format_id}+140"
278
- fpath = f"downloads/{title}"
279
  ydl_optssx = {
280
  "format": formats,
281
  "outtmpl": fpath,
@@ -289,7 +307,8 @@ class YouTubeAPI:
289
  x = yt_dlp.YoutubeDL(ydl_optssx)
290
  x.download([link])
291
  def song_audio_dl():
292
- fpath = f"downloads/{title}.%(ext)s"
 
293
  ydl_optssx = {
294
  "format": format_id,
295
  "outtmpl": fpath,
@@ -310,11 +329,13 @@ class YouTubeAPI:
310
  x.download([link])
311
  if songvideo:
312
  await loop.run_in_executor(None, song_video_dl)
313
- fpath = f"downloads/{title}.mp4"
 
314
  return fpath
315
  elif songaudio:
316
  await loop.run_in_executor(None, song_audio_dl)
317
- fpath = f"downloads/{title}.mp3"
 
318
  return fpath
319
  elif video:
320
  direct = True
 
 
1
  import asyncio
2
  import os
3
  import re
 
10
  from youtubesearchpython.__future__ import VideosSearch
11
  from DragMusic.utils.database import is_on_off
12
  from DragMusic.utils.formatters import time_to_seconds
13
+ import tempfile
14
+
15
  async def shell_cmd(cmd):
16
  proc = await asyncio.create_subprocess_shell(
17
  cmd,
 
25
  else:
26
  return errorz.decode("utf-8")
27
  return out.decode("utf-8")
28
+
29
  class YouTubeAPI:
30
  def __init__(self):
31
  self.base = "https://www.youtube.com/watch?v="
 
33
  self.status = "https://www.youtube.com/oembed?url="
34
  self.listbase = "https://youtube.com/playlist?list="
35
  self.reg = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
36
+
37
  async def exists(self, link: str, videoid: Union[bool, str] = None):
38
  if videoid:
39
  link = self.base + link
 
41
  return True
42
  else:
43
  return False
44
+
45
  async def url(self, message_1: Message) -> Union[str, None]:
46
  messages = [message_1]
47
  if message_1.reply_to_message:
 
65
  if offset in (None,):
66
  return None
67
  return text[offset : offset + length]
68
+
69
  async def details(self, link: str, videoid: Union[bool, str] = None):
70
  if videoid:
71
  link = self.base + link
 
82
  else:
83
  duration_sec = int(time_to_seconds(duration_min))
84
  return title, duration_min, duration_sec, thumbnail, vidid
85
+
86
  async def title(self, link: str, videoid: Union[bool, str] = None):
87
  if videoid:
88
  link = self.base + link
 
92
  for result in (await results.next())["result"]:
93
  title = result["title"]
94
  return title
95
+
96
  async def duration(self, link: str, videoid: Union[bool, str] = None):
97
  if videoid:
98
  link = self.base + link
 
102
  for result in (await results.next())["result"]:
103
  duration = result["duration"]
104
  return duration
105
+
106
  async def thumbnail(self, link: str, videoid: Union[bool, str] = None):
107
  if videoid:
108
  link = self.base + link
 
112
  for result in (await results.next())["result"]:
113
  thumbnail = result["thumbnails"][0]["url"].split("?")[0]
114
  return thumbnail
115
+
116
  async def video(self, link: str, videoid: Union[bool, str] = None):
117
  if videoid:
118
  link = self.base + link
 
132
  return 1, stdout.decode().split("\n")[0]
133
  else:
134
  return 0, stderr.decode()
135
+
136
  async def playlist(self, link, limit, user_id, videoid: Union[bool, str] = None):
137
  if videoid:
138
  link = self.listbase + link
 
149
  except:
150
  result = []
151
  return result
152
+
153
  async def track(self, link: str, videoid: Union[bool, str] = None):
154
  if videoid:
155
  link = self.base + link
 
170
  "thumb": thumbnail,
171
  }
172
  return track_details, vidid
173
+
174
  async def formats(self, link: str, videoid: Union[bool, str] = None):
175
  if videoid:
176
  link = self.base + link
 
206
  }
207
  )
208
  return formats_available, link
209
+
210
  async def slider(
211
  self,
212
  link: str,
 
224
  vidid = result[query_type]["id"]
225
  thumbnail = result[query_type]["thumbnails"][0]["url"].split("?")[0]
226
  return title, duration_min, thumbnail, vidid
227
+
228
  async def get_video_info_from_bitflow(self, url: str, video: bool):
229
  api_url = "https://bitflow.in/api/youtube"
230
  params = {
 
240
  return response.json()
241
  else:
242
  return {"status": "error", "message": "Failed to fetch data from Bitflow API."}
243
+
244
  async def download(
245
  self,
246
  link: str,
 
259
  loop = asyncio.get_running_loop()
260
  bitflow_info = await self.get_video_info_from_bitflow(link, video)
261
  def audio_dl(bitflow_info):
262
+ temp_dir = tempfile.gettempdir()
263
+ xyz = os.path.join(temp_dir, f"{bitflow_info['videoid']}.{bitflow_info['ext']}")
264
  ydl_optssx = {
265
  "format": "bestaudio/best",
266
  "outtmpl": xyz,
 
275
  x.download([bitflow_info['url']])
276
  return xyz
277
  def video_dl(bitflow_info):
278
+ temp_dir = tempfile.gettempdir()
279
+ xyz = os.path.join(temp_dir, f"{bitflow_info['videoid']}.{bitflow_info['ext']}")
280
  ydl_optssx = {
281
  "format": "(bestvideo[height<=?720][width<=?1280][ext=mp4])+(bestaudio[ext=m4a])",
282
  "outtmpl": xyz,
 
291
  x.download([bitflow_info['url']])
292
  return xyz
293
  def song_video_dl():
294
+ temp_dir = tempfile.gettempdir()
295
+ fpath = os.path.join(temp_dir, f"{title}")
296
  formats = f"{format_id}+140"
 
297
  ydl_optssx = {
298
  "format": formats,
299
  "outtmpl": fpath,
 
307
  x = yt_dlp.YoutubeDL(ydl_optssx)
308
  x.download([link])
309
  def song_audio_dl():
310
+ temp_dir = tempfile.gettempdir()
311
+ fpath = os.path.join(temp_dir, f"{title}.%(ext)s")
312
  ydl_optssx = {
313
  "format": format_id,
314
  "outtmpl": fpath,
 
329
  x.download([link])
330
  if songvideo:
331
  await loop.run_in_executor(None, song_video_dl)
332
+ temp_dir = tempfile.gettempdir()
333
+ fpath = os.path.join(temp_dir, f"{title}.mp4")
334
  return fpath
335
  elif songaudio:
336
  await loop.run_in_executor(None, song_audio_dl)
337
+ temp_dir = tempfile.gettempdir()
338
+ fpath = os.path.join(temp_dir, f"{title}.mp3")
339
  return fpath
340
  elif video:
341
  direct = True