diff --git a/bot/pleroma_service.py b/bot/pleroma_service.py index 4ec3496..d7c52b6 100644 --- a/bot/pleroma_service.py +++ b/bot/pleroma_service.py @@ -159,67 +159,35 @@ class PleromaService(FediverseService): def upload_file(self, file_data: Union[BinaryIO, bytes], filename: Optional[str] = None) -> FediverseFile: """Upload a file to Pleroma instance""" try: - import requests - - # Convert file_data to bytes if it's a stream + # Convert file_data to bytes if it's a stream for MIME detection if hasattr(file_data, 'read'): - file_bytes = file_data.read() + # Check if we can seek back + try: + current_pos = file_data.tell() + header = file_data.read(8) + file_data.seek(current_pos) + except (io.UnsupportedOperation, OSError): + # Non-seekable stream, read all data + remaining_data = file_data.read() + file_bytes = header + remaining_data + file_data = io.BytesIO(file_bytes) + header = file_bytes[:8] else: - file_bytes = file_data + header = file_data[:8] if len(file_data) >= 8 else file_data # Determine mime type from file header - mime_type = 'image/jpeg' # default - if file_bytes.startswith(b'\xff\xd8\xff'): + if header.startswith(b'\xff\xd8\xff'): mime_type = 'image/jpeg' - ext = '.jpg' - elif file_bytes.startswith(b'\x89PNG\r\n\x1a\n'): + elif header.startswith(b'\x89PNG\r\n\x1a\n'): mime_type = 'image/png' - ext = '.png' - elif file_bytes.startswith(b'GIF8'): + elif header.startswith(b'GIF8'): mime_type = 'image/gif' - ext = '.gif' - elif file_bytes.startswith(b'RIFF') and b'WEBP' in file_bytes[:12]: + elif header.startswith(b'RIFF') and len(header) >= 8 and b'WEBP' in header: mime_type = 'image/webp' - ext = '.webp' else: - ext = '.jpg' + mime_type = 'image/jpeg' # Default fallback - # Create a filename if none provided - if not filename: - filename = f"upload{ext}" - - # Direct HTTP POST to /api/v1/media with headers matching browser behavior - headers = { - 'Authorization': f'Bearer {self.client.access_token}', - 'Accept': '*/*', - 'Cache-Control': 'no-cache', - 'Pragma': 'no-cache', - 'User-Agent': 'Kemoverse-Bot/1.0' - } - - # Use files parameter to let requests handle multipart/form-data and content-type - files = { - 'file': (filename, file_bytes, mime_type) - } - - url = f"{self.client.api_base_url}/api/v1/media" - - # Debug logging - print(f"DEBUG: Making POST request to: {url}") - print(f"DEBUG: Headers: {headers}") - print(f"DEBUG: Files keys: {list(files.keys())}") - - response = requests.post(url, headers=headers, files=files) - - print(f"DEBUG: Response status: {response.status_code}") - print(f"DEBUG: Response headers: {dict(response.headers)}") - print(f"DEBUG: Request method was: {response.request.method}") - - if response.status_code in (200, 201): - media = response.json() - return self._convert_mastodon_file(media) - else: - raise Exception(f"Upload failed with {response.status_code}: {response.text}") - + media = self.client.media_post(file_data, mime_type=mime_type, description=filename) + return self._convert_mastodon_file(media) except Exception as e: raise RuntimeError(f"Failed to upload file to Pleroma: {e}") from e \ No newline at end of file