Initial commit for RedAirsoft VK to TG and MAX poster
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import html
|
||||
import re
|
||||
from typing import Optional
|
||||
from .config import settings
|
||||
|
||||
|
||||
def split_message_chunks(text: str, limit: int = 4000) -> list[str]:
|
||||
text = str(text or "").strip()
|
||||
if not text:
|
||||
return []
|
||||
chunks: list[str] = []
|
||||
while len(text) > limit:
|
||||
split_at = text.rfind("\n", 0, limit)
|
||||
if split_at < limit // 2:
|
||||
split_at = text.rfind(" ", 0, limit)
|
||||
if split_at < limit // 2:
|
||||
split_at = limit
|
||||
chunks.append(text[:split_at].strip())
|
||||
text = text[split_at:].strip()
|
||||
if text:
|
||||
chunks.append(text)
|
||||
return chunks
|
||||
|
||||
|
||||
def clean_dividers(lines: list[str]) -> list[str]:
|
||||
sep_pattern = re.compile(r"^\s*[━—─\-=\*\#_]{2,}\s*$")
|
||||
return ["" if sep_pattern.match(line) else line for line in lines]
|
||||
|
||||
|
||||
def strip_trailing_hashtags(text: str) -> str:
|
||||
lines = text.rstrip().splitlines()
|
||||
while lines and not lines[-1].strip():
|
||||
lines.pop()
|
||||
if not lines:
|
||||
return ""
|
||||
parts = lines[-1].split()
|
||||
if parts and all(part.startswith("#") for part in parts):
|
||||
lines.pop()
|
||||
return "\n".join(lines).rstrip()
|
||||
|
||||
|
||||
def format_post_text(
|
||||
raw_text: str,
|
||||
*,
|
||||
parse_mode: str = "html", # "html" or "plain"
|
||||
header: Optional[str] = None,
|
||||
footer: Optional[str] = None,
|
||||
tags: Optional[str] = None,
|
||||
bold_first_line: bool = True,
|
||||
vk_url: Optional[str] = None,
|
||||
) -> str:
|
||||
header = (settings.header_text if header is None else header).strip()
|
||||
footer = (settings.footer_text if footer is None else footer).strip()
|
||||
tags = (settings.common_tags if tags is None else tags).strip()
|
||||
|
||||
body = strip_trailing_hashtags(raw_text)
|
||||
lines = clean_dividers(body.splitlines())
|
||||
|
||||
title_idx: Optional[int] = None
|
||||
for idx, line in enumerate(lines):
|
||||
if line.strip():
|
||||
title_idx = idx
|
||||
break
|
||||
|
||||
formatted_lines: list[str] = []
|
||||
for idx, line in enumerate(lines):
|
||||
if idx == title_idx and bold_first_line and line.strip():
|
||||
if parse_mode == "html":
|
||||
escaped = html.escape(line.strip())
|
||||
formatted_lines.append(f"<b>{escaped}</b>")
|
||||
else:
|
||||
formatted_lines.append(f"**{line.strip()}**")
|
||||
# Blank line after header if next line is not empty
|
||||
if idx + 1 < len(lines) and lines[idx + 1].strip() != "":
|
||||
formatted_lines.append("")
|
||||
else:
|
||||
if parse_mode == "html":
|
||||
formatted_lines.append(html.escape(line))
|
||||
else:
|
||||
formatted_lines.append(line)
|
||||
|
||||
normalized_body = re.sub(r"\n{3,}", "\n\n", "\n".join(formatted_lines)).strip()
|
||||
|
||||
parts: list[str] = []
|
||||
if header:
|
||||
parts.append(html.escape(header) if parse_mode == "html" else header)
|
||||
if normalized_body:
|
||||
parts.append(normalized_body)
|
||||
if footer:
|
||||
parts.append(html.escape(footer) if parse_mode == "html" else footer)
|
||||
if tags:
|
||||
parts.append(html.escape(tags) if parse_mode == "html" else tags)
|
||||
|
||||
return "\n\n".join(part for part in parts if part).strip()
|
||||
Reference in New Issue
Block a user