diff options
| author | 2023-06-21 19:38:54 +0100 | |
|---|---|---|
| committer | 2023-06-21 19:38:54 +0100 | |
| commit | 16d0dff6212d48fd7a4d2da69344d9b4f7f3b6be (patch) | |
| tree | a8160936e0ab7247083d97c48d9f8f48fceaf80a | |
| parent | Bump d.py (#181) (diff) | |
Add supported lexer validation to paste service and default the paste_url (#182)v9.9.0
Diffstat (limited to '')
| -rw-r--r-- | docs/changelog.rst | 5 | ||||
| -rw-r--r-- | pydis_core/utils/paste_service.py | 35 | ||||
| -rw-r--r-- | pyproject.toml | 2 | 
3 files changed, 37 insertions, 5 deletions
| diff --git a/docs/changelog.rst b/docs/changelog.rst index 718b868b..8ece9d69 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -3,6 +3,11 @@  Changelog  ========= +- :release:`9.9.0 <18th June 2023>` +- :feature:`182` Default pastebin url to https://paste.pythondiscord.com +- :feature:`182` Add supported lexer validation to paste service. + +  - :release:`9.8.0 <13th June 2023>`  - :support:`181` Bump Discord.py to :literal-url:`2.3.0 <https://github.com/Rapptz/discord.py/releases/tag/v2.3.0>`. diff --git a/pydis_core/utils/paste_service.py b/pydis_core/utils/paste_service.py index 227197e5..2a898fc4 100644 --- a/pydis_core/utils/paste_service.py +++ b/pydis_core/utils/paste_service.py @@ -1,3 +1,4 @@ +import json  from typing import TypedDict  from aiohttp import ClientConnectorError, ClientSession @@ -6,10 +7,14 @@ from pydis_core.utils import logging  log = logging.get_logger(__name__) +DEFAULT_PASTEBIN = "https://paste.pythondiscord.com"  FAILED_REQUEST_ATTEMPTS = 3 -MAX_PASTE_SIZE = 128 * 1024  # 128kB +MAX_PASTE_SIZE = 512 * 1024  # 512kB  """The maximum allows size of a paste, in bytes.""" +# A dict where the keys are paste services and the keys are the lists of lexers that paste service supports. +_lexers_supported_by_pastebin: dict[str,list[str]] = {} +  class PasteResponse(TypedDict):      """ @@ -27,6 +32,9 @@ class PasteResponse(TypedDict):  class PasteUploadError(Exception):      """Raised when an error is encountered uploading to the paste service.""" +class PasteUnsupportedLexerError(Exception): +    """Raised when an unsupported lexer is used.""" +  class PasteTooLongError(Exception):      """Raised when content is too large to upload to the paste service.""" @@ -35,10 +43,10 @@ class PasteTooLongError(Exception):  async def send_to_paste_service(      *,      contents: str, -    paste_url: str,      http_session: ClientSession,      file_name: str = "",      lexer: str = "python", +    paste_url: str = DEFAULT_PASTEBIN,      max_size: int = MAX_PASTE_SIZE,  ) -> PasteResponse:      """ @@ -46,10 +54,10 @@ async def send_to_paste_service(      Args:          contents: The content to upload to the paste service. -        paste_url: The base url to the paste service.          http_session (aiohttp.ClientSession): The session to use when POSTing the content to the paste service.          file_name: The name of the file to save to the paste service.          lexer: The lexer to save the content with. +        paste_url: The base url to the paste service.          max_size: The max number of bytes to be allowed. Anything larger than :obj:`MAX_PASTE_SIZE` will be rejected.      Raises: @@ -63,6 +71,18 @@ async def send_to_paste_service(      if max_size > MAX_PASTE_SIZE:          raise ValueError(f"`max_length` must not be greater than {MAX_PASTE_SIZE}") +    if paste_url not in _lexers_supported_by_pastebin: +        try: +            async with http_session.get(f"{paste_url}/api/v1/lexer") as response: +                response_json = await response.json()  # Supported lexers are the keys. +        except Exception: +            raise PasteUploadError("Could not fetch supported lexers from selected paste_url.") + +        _lexers_supported_by_pastebin[paste_url] = list(response_json) + +    if lexer not in _lexers_supported_by_pastebin[paste_url]: +        raise PasteUnsupportedLexerError(f"Lexer '{lexer}' not supported by pastebin.") +      contents_size = len(contents.encode())      if contents_size > max_size:          log.info("Contents too large to send to paste service.") @@ -79,7 +99,7 @@ async def send_to_paste_service(      for attempt in range(1, FAILED_REQUEST_ATTEMPTS + 1):          try:              async with http_session.post(f"{paste_url}/api/v1/paste", json=payload) as response: -                response_json = await response.json() +                response_text = await response.text()          except ClientConnectorError:              log.warning(                  f"Failed to connect to paste service at url {paste_url}, " @@ -93,6 +113,13 @@ async def send_to_paste_service(              )              continue +        if "Text exceeds size limit" in response_text: +            log.info("Contents too large to send to paste service after lexing.") +            raise PasteTooLongError( +                f"Contents of size {contents_size} greater than maximum size {max_size} after lexing" +            ) + +        response_json = json.loads(response_text)          if response.status == 400:              log.warning(                  f"Paste service returned error {response_json['message']} with status code {response.status}, " diff --git a/pyproject.toml b/pyproject.toml index bad9a1dc..4bd3cd59 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@  [tool.poetry]  name = "pydis_core" -version = "9.8.0" +version = "9.9.0"  description = "PyDis core provides core functionality and utility to the bots of the Python Discord community."  authors = ["Python Discord <[email protected]>"]  license = "MIT" | 
