aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO.md9
-rw-r--r--cogs/compression.py1
-rw-r--r--cogs/conversion.py1
-rw-r--r--cogs/music/play_commands.py24
-rw-r--r--cogs/uploader.py1
-rw-r--r--tests/cogs/test_music_external_play.py21
6 files changed, 25 insertions, 32 deletions
diff --git a/TODO.md b/TODO.md
index 36584a7..25f87e8 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,5 +1,10 @@
1# NEAR FUTURE
2## repetition count to @cogs/cron.py
3 after X repetitions of a cronjob, it will be deleted from db
4 defaults to 0, which is infinite
5
1# WILL DO SOMEDAY 6# WILL DO SOMEDAY
2## userbot features 7## userbot features
3 why not make the bot allow users to benefit from it outside of the server? 8 why not make the bot allow users to benefit from it outside of the server?
4 9
5 for example, let's allow the user to download, search the copyparty instance or compress in DMs/other servers 10 for example, let's allow the user to download, search the copyparty instance or compress in DMs/other servers
diff --git a/cogs/compression.py b/cogs/compression.py
index 7171abb..71348dc 100644
--- a/cogs/compression.py
+++ b/cogs/compression.py
@@ -62,6 +62,7 @@ class Compression(commands.Cog):
62 return None 62 return None
63 63
64 filename = url.split('/')[-1].split('?')[0] 64 filename = url.split('/')[-1].split('?')[0]
65 filename = urllib.parse.unquote(filename)
65 file_path = os.path.join(self.temp_dir, filename) 66 file_path = os.path.join(self.temp_dir, filename)
66 67
67 async with aiofiles.open(file_path, 'wb') as f: 68 async with aiofiles.open(file_path, 'wb') as f:
diff --git a/cogs/conversion.py b/cogs/conversion.py
index 455bfde..f9e4c84 100644
--- a/cogs/conversion.py
+++ b/cogs/conversion.py
@@ -63,6 +63,7 @@ class Conversion(commands.Cog):
63 return None 63 return None
64 64
65 filename = url.split('/')[-1].split('?')[0] 65 filename = url.split('/')[-1].split('?')[0]
66 filename = urllib.parse.unquote(filename)
66 file_path = os.path.join(self.temp_dir, filename) 67 file_path = os.path.join(self.temp_dir, filename)
67 68
68 async with aiofiles.open(file_path, 'wb') as f: 69 async with aiofiles.open(file_path, 'wb') as f:
diff --git a/cogs/music/play_commands.py b/cogs/music/play_commands.py
index a90f901..c6a55b0 100644
--- a/cogs/music/play_commands.py
+++ b/cogs/music/play_commands.py
@@ -10,6 +10,7 @@ import asyncio
10from os import PathLike 10from os import PathLike
11from typing import Awaitable, Callable, List, Tuple 11from typing import Awaitable, Callable, List, Tuple
12import re 12import re
13import requests
13from yt_dlp import YoutubeDL 14from yt_dlp import YoutubeDL
14 15
15import discord 16import discord
@@ -229,8 +230,6 @@ class PlayCommands(commands.Cog):
229 230
230 async def _upload_to_copyparty_async(self, file_path: str) -> None: 231 async def _upload_to_copyparty_async(self, file_path: str) -> None:
231 """Upload file to copyparty asynchronously (fire and forget).""" 232 """Upload file to copyparty asynchronously (fire and forget)."""
232 import aiohttp
233
234 try: 233 try:
235 logger.info(f"Starting async upload: {file_path}") 234 logger.info(f"Starting async upload: {file_path}")
236 baseurl = get_uploadurl() 235 baseurl = get_uploadurl()
@@ -244,25 +243,18 @@ class PlayCommands(commands.Cog):
244 with open(file_path, "rb") as f: 243 with open(file_path, "rb") as f:
245 content = f.read() 244 content = f.read()
246 245
247 files = aiohttp.FormData() 246 files = {"f": (os.path.basename(file_path), content, "application/octet-stream")}
248 files.add_field(
249 "f",
250 content,
251 filename=os.path.basename(file_path),
252 content_type="application/octet-stream",
253 )
254 headers = {"Cookie": f"cppwd={password}"} 247 headers = {"Cookie": f"cppwd={password}"}
255 params = {"j": "1", "ck": "b2"} 248 params = {"j": "1", "ck": "b2"}
256 249
257 logger.info(f"Posting to {baseurl}") 250 logger.info(f"Posting to {baseurl}")
258 async with aiohttp.ClientSession() as session: 251 response = requests.post(baseurl, files=files, headers=headers, params=params)
259 async with session.post(baseurl, data=files, headers=headers, params=params) as response: 252 text = response.text
260 text = await response.text() 253 logger.info(f"Upload response: {response.status_code} - {text[:200] if text else 'empty'}")
261 logger.info(f"Upload response: {response.status} - {text[:200] if text else 'empty'}")
262 254
263 if response.status in [200, 201]: 255 if response.status_code in [200, 201]:
264 result = await response.json() 256 result = response.json()
265 logger.info(f"Uploaded to copyparty: {result.get('fileurl')}") 257 logger.info(f"Uploaded to copyparty: {result.get('fileurl')}")
266 except Exception as e: 258 except Exception as e:
267 logger.error(f"Async upload failed: {e}", exc_info=True) 259 logger.error(f"Async upload failed: {e}", exc_info=True)
268 260
diff --git a/cogs/uploader.py b/cogs/uploader.py
index df6908e..a5d0e05 100644
--- a/cogs/uploader.py
+++ b/cogs/uploader.py
@@ -48,6 +48,7 @@ class Uploader(commands.Cog):
48 return None 48 return None
49 49
50 filename = url.split('/')[-1].split('?')[0] 50 filename = url.split('/')[-1].split('?')[0]
51 filename = urllib.parse.unquote(filename)
51 file_path = os.path.join(self.temp_dir, filename) 52 file_path = os.path.join(self.temp_dir, filename)
52 53
53 async with aiofiles.open(file_path, 'wb') as f: 54 async with aiofiles.open(file_path, 'wb') as f:
diff --git a/tests/cogs/test_music_external_play.py b/tests/cogs/test_music_external_play.py
index 2e9c5b1..8e19423 100644
--- a/tests/cogs/test_music_external_play.py
+++ b/tests/cogs/test_music_external_play.py
@@ -99,18 +99,11 @@ async def test_upload_to_copyparty_async(play_commands_cog, temp_mp3_file, monke
99 monkeypatch.setenv("COPYPARTY_URL_UPLOAD", "https://catbox.2137697.xyz/sperma/") 99 monkeypatch.setenv("COPYPARTY_URL_UPLOAD", "https://catbox.2137697.xyz/sperma/")
100 monkeypatch.setenv("COPYPARTY_PASSWORD", "testpassword") 100 monkeypatch.setenv("COPYPARTY_PASSWORD", "testpassword")
101 101
102 mock_response = AsyncMock() 102 mock_response = MagicMock()
103 mock_response.status = 200 103 mock_response.status_code = 200
104 mock_response.text = AsyncMock(return_value="") 104 mock_response.text = '{"fileurl": "https://example.com/file.mp3"}'
105 mock_response.json = AsyncMock(return_value={"fileurl": "https://example.com/file.mp3"}) 105 mock_response.json = MagicMock(return_value={"fileurl": "https://example.com/file.mp3"})
106 mock_response.__aenter__ = AsyncMock(return_value=mock_response) 106
107 mock_response.__aexit__ = AsyncMock() 107 with patch('cogs.music.play_commands.requests.post', return_value=mock_response) as mock_post:
108
109 mock_session_context = AsyncMock()
110 mock_session_context.__aenter__ = AsyncMock(return_value=mock_session_context)
111 mock_session_context.__aexit__ = AsyncMock()
112 mock_session_context.post = MagicMock(return_value=mock_response)
113
114 with patch('aiohttp.ClientSession', return_value=mock_session_context):
115 await play_commands_cog._upload_to_copyparty_async(temp_mp3_file) 108 await play_commands_cog._upload_to_copyparty_async(temp_mp3_file)
116 mock_session_context.post.assert_called_once() 109 mock_post.assert_called_once()