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 bdb021d..80a30ef 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
@@ -228,8 +229,6 @@ class PlayCommands(commands.Cog):
228 229
229 async def _upload_to_copyparty_async(self, file_path: str) -> None: 230 async def _upload_to_copyparty_async(self, file_path: str) -> None:
230 """Upload file to copyparty asynchronously (fire and forget).""" 231 """Upload file to copyparty asynchronously (fire and forget)."""
231 import aiohttp
232
233 try: 232 try:
234 logger.info(f"Starting async upload: {file_path}") 233 logger.info(f"Starting async upload: {file_path}")
235 baseurl = get_uploadurl() 234 baseurl = get_uploadurl()
@@ -243,25 +242,18 @@ class PlayCommands(commands.Cog):
243 with open(file_path, "rb") as f: 242 with open(file_path, "rb") as f:
244 content = f.read() 243 content = f.read()
245 244
246 files = aiohttp.FormData() 245 files = {"f": (os.path.basename(file_path), content, "application/octet-stream")}
247 files.add_field(
248 "f",
249 content,
250 filename=os.path.basename(file_path),
251 content_type="application/octet-stream",
252 )
253 headers = {"Cookie": f"cppwd={password}"} 246 headers = {"Cookie": f"cppwd={password}"}
254 params = {"j": "1", "ck": "b2"} 247 params = {"j": "1", "ck": "b2"}
255 248
256 logger.info(f"Posting to {baseurl}") 249 logger.info(f"Posting to {baseurl}")
257 async with aiohttp.ClientSession() as session: 250 response = requests.post(baseurl, files=files, headers=headers, params=params)
258 async with session.post(baseurl, data=files, headers=headers, params=params) as response: 251 text = response.text
259 text = await response.text() 252 logger.info(f"Upload response: {response.status_code} - {text[:200] if text else 'empty'}")
260 logger.info(f"Upload response: {response.status} - {text[:200] if text else 'empty'}")
261 253
262 if response.status in [200, 201]: 254 if response.status_code in [200, 201]:
263 result = await response.json() 255 result = response.json()
264 logger.info(f"Uploaded to copyparty: {result.get('fileurl')}") 256 logger.info(f"Uploaded to copyparty: {result.get('fileurl')}")
265 except Exception as e: 257 except Exception as e:
266 logger.error(f"Async upload failed: {e}", exc_info=True) 258 logger.error(f"Async upload failed: {e}", exc_info=True)
267 259
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()