"""dpaste.com provider implementation.""" import base64 import requests from typing import Optional from .base import PastebinProvider class DPasteProvider(PastebinProvider): """Provider for dpaste.com pastebin service.""" BASE_URL = "https://dpaste.com" def __init__(self, api_url: Optional[str] = None): """ Initialize dpaste provider. Args: api_url: Override API URL (useful for self-hosted instances) """ self.api_url = api_url or self.BASE_URL def paste(self, content: bytes, expiry: str = "onetime", syntax: str = "text", **kwargs) -> str: """ Upload encrypted content to dpaste. Args: content: Encrypted bytes to upload expiry: Expiration time (onetime, hour, day, week, month, never) syntax: Syntax highlighting (text, python, etc.) **kwargs: Additional provider-specific options Returns: Full paste URL (without fragment) """ # Base64 encode binary content for safe transmission content_b64 = base64.b64encode(content).decode('ascii') # dpaste API expects form data data = { 'content': content_b64, 'syntax': syntax, 'expiry_days': self._convert_expiry(expiry), } # POST to create paste response = requests.post( f"{self.api_url}/api/v2/", data=data, headers={'User-Agent': 'SecPaste/0.1.0'} ) response.raise_for_status() # dpaste returns plain text URL paste_url = response.text.strip() return paste_url def fetch(self, paste_id: str) -> bytes: """ Fetch encrypted content from dpaste. Args: paste_id: Full URL or just the paste ID Returns: Encrypted bytes (base64 decoded) """ # Handle both full URLs and just IDs if paste_id.startswith('http'): url = paste_id else: url = f"{self.api_url}/{paste_id}" # Add .raw to get raw content if not url.endswith('.raw'): url = f"{url}.raw" response = requests.get(url, headers={'User-Agent': 'SecPaste/0.1.0'}) response.raise_for_status() # Decode from base64 content = base64.b64decode(response.text.strip()) return content def get_name(self) -> str: """Return provider name.""" return "dpaste" def get_base_url(self) -> str: """Return base URL.""" return self.api_url def _convert_expiry(self, expiry: str) -> str: """Convert expiry string to dpaste format.""" expiry_map = { 'onetime': '0', 'hour': '1', 'day': '1', 'week': '7', 'month': '30', 'never': '365' # dpaste max is 365 days } return expiry_map.get(expiry, '7')