diff options
| author | salmonik <raisersoft@proton.me> | 2026-05-16 18:07:07 +0200 |
|---|---|---|
| committer | salmonik <raisersoft@proton.me> | 2026-05-16 18:07:07 +0200 |
| commit | a769cf0ac5c20a2f4b4cb72bab3ed438480d9a98 (patch) | |
| tree | fcb74264d843c584099ddffe14f779b292d82f40 | |
| parent | Merge branch 'dev' (diff) | |
| download | senator-sperma-a769cf0ac5c20a2f4b4cb72bab3ed438480d9a98.tar.gz senator-sperma-a769cf0ac5c20a2f4b4cb72bab3ed438480d9a98.zip | |
fix naming not resolving things like %20
Signed-off-by: salmonik <raisersoft@proton.me>
Diffstat (limited to '')
| -rw-r--r-- | TODO.md | 9 | ||||
| -rw-r--r-- | cogs/compression.py | 1 | ||||
| -rw-r--r-- | cogs/conversion.py | 1 | ||||
| -rw-r--r-- | cogs/music/play_commands.py | 24 | ||||
| -rw-r--r-- | cogs/uploader.py | 1 | ||||
| -rw-r--r-- | tests/cogs/test_music_external_play.py | 21 |
6 files changed, 25 insertions, 32 deletions
| @@ -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 | |||
| 10 | from os import PathLike | 10 | from os import PathLike |
| 11 | from typing import Awaitable, Callable, List, Tuple | 11 | from typing import Awaitable, Callable, List, Tuple |
| 12 | import re | 12 | import re |
| 13 | import requests | ||
| 13 | from yt_dlp import YoutubeDL | 14 | from yt_dlp import YoutubeDL |
| 14 | 15 | ||
| 15 | import discord | 16 | import 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() |
