60 lines
1.4 KiB
Python
60 lines
1.4 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import json
|
||
|
|
import re
|
||
|
|
|
||
|
|
from yuxi.channels.models import Attachment, MessageType
|
||
|
|
|
||
|
|
_MENTION_RE = re.compile(r"@(\w[\w.-]*)")
|
||
|
|
_URL_RE = re.compile(r"https?://[^\s<>\"')\]}]+")
|
||
|
|
|
||
|
|
|
||
|
|
def _parse_json_field(data: dict, field: str) -> dict:
|
||
|
|
value = data.get(field, "")
|
||
|
|
if isinstance(value, str):
|
||
|
|
try:
|
||
|
|
return json.loads(value)
|
||
|
|
except (json.JSONDecodeError, TypeError):
|
||
|
|
return {}
|
||
|
|
return value if isinstance(value, dict) else {}
|
||
|
|
|
||
|
|
|
||
|
|
def parse_post_json(data: dict) -> dict:
|
||
|
|
return _parse_json_field(data, "post")
|
||
|
|
|
||
|
|
|
||
|
|
def parse_channel_json(data: dict) -> dict:
|
||
|
|
return _parse_json_field(data, "channel")
|
||
|
|
|
||
|
|
|
||
|
|
def extract_mentions(text: str) -> list[str]:
|
||
|
|
if not text:
|
||
|
|
return []
|
||
|
|
return _MENTION_RE.findall(text)
|
||
|
|
|
||
|
|
|
||
|
|
def check_bot_mentioned(text: str, bot_username: str) -> bool:
|
||
|
|
if not text or not bot_username:
|
||
|
|
return False
|
||
|
|
return f"@{bot_username}" in text.casefold()
|
||
|
|
|
||
|
|
|
||
|
|
def extract_urls(text: str) -> list[str]:
|
||
|
|
if not text:
|
||
|
|
return []
|
||
|
|
return _URL_RE.findall(text)
|
||
|
|
|
||
|
|
|
||
|
|
def detect_message_type(post_data: dict) -> MessageType:
|
||
|
|
file_ids = post_data.get("file_ids", [])
|
||
|
|
if file_ids:
|
||
|
|
return MessageType.FILE
|
||
|
|
return MessageType.TEXT
|
||
|
|
|
||
|
|
|
||
|
|
def extract_attachments(post_data: dict) -> list[Attachment]:
|
||
|
|
file_ids = post_data.get("file_ids", [])
|
||
|
|
if not file_ids:
|
||
|
|
return []
|
||
|
|
return [Attachment(type="file", file_id=fid) for fid in file_ids]
|