Create Relay Bot MVP
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
import csv
|
||||
import io
|
||||
from pathlib import Path
|
||||
|
||||
from docx import Document
|
||||
from pypdf import PdfReader
|
||||
|
||||
SUPPORTED_EXTENSIONS = {".txt", ".md", ".json", ".yaml", ".yml", ".csv", ".pdf", ".docx"}
|
||||
|
||||
|
||||
def extract_text(filename: str, content: bytes, max_chars: int = 60_000) -> str:
|
||||
suffix = Path(filename).suffix.lower()
|
||||
if suffix not in SUPPORTED_EXTENSIONS:
|
||||
raise ValueError("Этот тип файла пока не поддерживается")
|
||||
if suffix in {".txt", ".md", ".json", ".yaml", ".yml"}:
|
||||
text = content.decode("utf-8", errors="replace")
|
||||
elif suffix == ".csv":
|
||||
rows = csv.reader(io.StringIO(content.decode("utf-8", errors="replace")))
|
||||
text = "\n".join(" | ".join(row) for row in rows)
|
||||
elif suffix == ".pdf":
|
||||
text = "\n".join(page.extract_text() or "" for page in PdfReader(io.BytesIO(content)).pages)
|
||||
else:
|
||||
text = "\n".join(p.text for p in Document(io.BytesIO(content)).paragraphs)
|
||||
return text[:max_chars]
|
||||
@@ -0,0 +1,30 @@
|
||||
from pathlib import Path
|
||||
|
||||
from app.attachments.extractors import SUPPORTED_EXTENSIONS, extract_text
|
||||
|
||||
|
||||
def explicitly_requested(
|
||||
*,
|
||||
is_private: bool,
|
||||
caption: str | None,
|
||||
replied_with_request: bool,
|
||||
command: bool,
|
||||
bot_username: str | None,
|
||||
) -> bool:
|
||||
mention = bool(caption and bot_username and f"@{bot_username.lower()}" in caption.lower())
|
||||
return is_private or mention or replied_with_request or command
|
||||
|
||||
|
||||
class AttachmentService:
|
||||
def __init__(self, max_bytes: int):
|
||||
self.max_bytes = max_bytes
|
||||
|
||||
def validate(self, filename: str, size: int) -> None:
|
||||
if size > self.max_bytes:
|
||||
raise ValueError("Файл слишком большой")
|
||||
if Path(filename).suffix.lower() not in SUPPORTED_EXTENSIONS:
|
||||
raise ValueError("Неподдерживаемый или небезопасный файл")
|
||||
|
||||
def extract(self, filename: str, content: bytes) -> str:
|
||||
self.validate(filename, len(content))
|
||||
return extract_text(filename, content)
|
||||
Reference in New Issue
Block a user