aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsalmonik <raisersoft@proton.me>2026-04-20 15:04:54 +0200
committersalmonik <raisersoft@proton.me>2026-04-20 15:04:54 +0200
commitaba75b63c23fe863c52bb4e4f054a1820ec9777c (patch)
tree8dc1d058db625b80ddb4fa817d8db4c9834239a7
parentfix: proper aiohttp async context manager mocking in test (diff)
downloadsenator-sperma-aba75b63c23fe863c52bb4e4f054a1820ec9777c.tar.gz
senator-sperma-aba75b63c23fe863c52bb4e4f054a1820ec9777c.zip
fix filename handling in downloader.py
Signed-off-by: salmonik <raisersoft@proton.me>
Diffstat (limited to '')
-rw-r--r--cogs/downloader.py21
1 files changed, 17 insertions, 4 deletions
diff --git a/cogs/downloader.py b/cogs/downloader.py
index 36bd723..d829ed7 100644
--- a/cogs/downloader.py
+++ b/cogs/downloader.py
@@ -71,7 +71,7 @@ class Downloader(commands.Cog):
71 logger.info(f"Downloading {url} as {fformat}") 71 logger.info(f"Downloading {url} as {fformat}")
72 72
73 with tempfile.TemporaryDirectory(delete=False) as temp_dir: 73 with tempfile.TemporaryDirectory(delete=False) as temp_dir:
74 ydl_opts = Downloader._get_ydl_options(fformat, temp_dir) 74 ydl_opts = Downloader._get_ydl_options(filename_user, fformat, temp_dir)
75 75
76 with yt_dlp.YoutubeDL(ydl_opts) as ydl: 76 with yt_dlp.YoutubeDL(ydl_opts) as ydl:
77 ydl.download([url]) 77 ydl.download([url])
@@ -87,15 +87,23 @@ class Downloader(commands.Cog):
87 return Downloader._create_error_response("Download failed", str(e), None) 87 return Downloader._create_error_response("Download failed", str(e), None)
88 88
89 @staticmethod 89 @staticmethod
90 def _get_ydl_options(fformat: str, temp_dir: str) -> dict: 90 def _sanitize_filename(name: str) -> str:
91 invalid = '<>:"/\\|?*'
92 for c in invalid:
93 name = name.replace(c, '')
94 return name.strip()
95
96 @staticmethod
97 def _get_ydl_options(filename: str = None, fformat: str = None, temp_dir: str = None) -> dict:
98 if filename:
99 filename = Downloader._sanitize_filename(filename)[:100]
91 ydl_opts = { 100 ydl_opts = {
92 'outtmpl': os.path.join(temp_dir, '%(title)s.%(ext)s'), 101 'outtmpl': os.path.join(temp_dir, filename if filename is not None else '%(title).100s.%(ext)s'),
93 'format': 'bestaudio/best' if fformat in ['mp3', 'wav', 'm4a'] else 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best', 102 'format': 'bestaudio/best' if fformat in ['mp3', 'wav', 'm4a'] else 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
94 'merge_output_format': 'mp4', 103 'merge_output_format': 'mp4',
95 'postprocessors': [], 104 'postprocessors': [],
96 'remote-components': 'ejs:github', 105 'remote-components': 'ejs:github',
97 'js-runtimes': {'deno': {'path': '/usr/bin/deno'}}, 106 'js-runtimes': {'deno': {'path': '/usr/bin/deno'}},
98 'o': '"%(title)s.%(ext)s"'
99 } 107 }
100 108
101 if fformat in ['mp3', 'wav', 'm4a']: 109 if fformat in ['mp3', 'wav', 'm4a']:
@@ -120,10 +128,15 @@ class Downloader(commands.Cog):
120 128
121 actual_file = os.path.join(temp_dir, files[0]) 129 actual_file = os.path.join(temp_dir, files[0])
122 extension = actual_file.split('.')[-1] 130 extension = actual_file.split('.')[-1]
131 extension = Downloader._sanitize_filename(extension)
123 132
124 if not filename_user: 133 if not filename_user:
125 filename = os.path.basename(actual_file) 134 filename = os.path.basename(actual_file)
135 filename = Downloader._sanitize_filename(filename)
136 if len(filename) > 100:
137 filename = filename[:100]
126 else: 138 else:
139 filename_user = Downloader._sanitize_filename(filename_user)[:100]
127 filename = filename_user + '.' + extension 140 filename = filename_user + '.' + extension
128 actual_file = os.path.join(temp_dir, filename) 141 actual_file = os.path.join(temp_dir, filename)
129 142