50 lines
1.2 KiB
Python
50 lines
1.2 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import re
|
||
|
|
|
||
|
|
_CODE_BLOCK_PATTERN = re.compile(r"```[\s\S]*?```", re.DOTALL)
|
||
|
|
_TABLE_PATTERN = re.compile(r"\|[^\n]+\|", re.DOTALL)
|
||
|
|
_LARGE_OUTPUT_THRESHOLD = 1500
|
||
|
|
_URL_PATTERN = re.compile(r"https?://[^\s<>\"{}|\\^`\[\]]+")
|
||
|
|
|
||
|
|
|
||
|
|
def should_use_card(content: str, buttons: list | None = None) -> bool:
|
||
|
|
if buttons:
|
||
|
|
return True
|
||
|
|
|
||
|
|
if len(content) > _LARGE_OUTPUT_THRESHOLD:
|
||
|
|
return True
|
||
|
|
|
||
|
|
if _CODE_BLOCK_PATTERN.search(content):
|
||
|
|
return True
|
||
|
|
|
||
|
|
if _TABLE_PATTERN.search(content):
|
||
|
|
return True
|
||
|
|
|
||
|
|
return False
|
||
|
|
|
||
|
|
|
||
|
|
def dispatch_render(content: str, *, buttons: list | None = None, render_mode: str = "auto") -> str:
|
||
|
|
if render_mode == "card":
|
||
|
|
return "card"
|
||
|
|
if render_mode == "raw":
|
||
|
|
return "text"
|
||
|
|
|
||
|
|
if should_use_card(content, buttons):
|
||
|
|
return "card"
|
||
|
|
return "text"
|
||
|
|
|
||
|
|
|
||
|
|
def extract_urls(content: str, max_urls: int = 5) -> list[str]:
|
||
|
|
urls = _URL_PATTERN.findall(content)
|
||
|
|
seen: set[str] = set()
|
||
|
|
result: list[str] = []
|
||
|
|
for url in urls:
|
||
|
|
url = url.rstrip(".,;:)!?\"'")
|
||
|
|
if url not in seen:
|
||
|
|
seen.add(url)
|
||
|
|
result.append(url)
|
||
|
|
if len(result) >= max_urls:
|
||
|
|
break
|
||
|
|
return result
|