Bot & Automation
jorgasisten
/root/hermes-projects/jorgasisten
apps/jorgasisten/services/text.py
text
import re
from collections.abc import Iterable
from typing import Any
TOKEN_RE = re.compile(r"[a-z0-9]+", re.IGNORECASE)
SEARCH_NOISE_TOKENS = {
"ada",
"admin",
"aku",
"apakah",
"barang",
"bantu",
"bantuin",
"berapa",
"bisa",
"buat",
"cari",
"cariin",
"carikan",
"cek",
"cekin",
"chatbot",
"data",
"detail",
"dari",
"dimana",
"dong",
"dongss",
"gua",
"gue",
"gw",
"haloo",
"halo",
"hai",
"harga",
"info",
"informasi",
"ini",
"itu",
"kasih",
"lihat",
"liat",
"lokasi",
"mana",
"mau",
"minta",
"produk",
"sekarang",
"saja",
"saya",
"sebutin",
"sheet",
"siapa",
"stok",
"stoknya",
"suppliernya",
"tampilkan",
"tentang",
"terbaru",
"tolong",
"untuk",
"yang",
"yaa",
"ya",
}
VOICE_SEARCH_TOKEN_ALIASES = {
"asalnya": "asal",
"block": "blok",
"brapa": "berapa",
"dimna": "dimana",
"fedral": "federal",
"fario": "vario",
"harganya": "harga",
"forjet": "forged",
"forjid": "forged",
"kasting": "casting",
"lokasinya": "lokasi",
"pederal": "federal",
"recing": "racing",
"resing": "racing",
"secher": "seher",
"statusnya": "status",
"seker": "seher",
"stoknya": "stok",
"suppliernya": "supplier",
"tanggalnya": "tanggal",
}
VOICE_SEARCH_PHRASE_ALIASES = (
(re.compile(r"\ber\s+e(?:ks|x)\s*(?:7|tujuh)\b", re.IGNORECASE), "rx7"),
(re.compile(r"\berex\s*(?:7|tujuh)\b", re.IGNORECASE), "rx7"),
(re.compile(r"\bem\s+pe\s+(?:eks|ex)\b", re.IGNORECASE), "mpx"),
)
def normalize_key(value: str) -> str:
return "".join(TOKEN_RE.findall(value.lower()))
def tokenize(value: str) -> set[str]:
return {token.lower() for token in TOKEN_RE.findall(value)}
def normalize_voice_search_text(value: str) -> str:
normalized = value
for pattern, replacement in VOICE_SEARCH_PHRASE_ALIASES:
normalized = pattern.sub(replacement, normalized)
return normalized
def search_token_sequence(value: str) -> list[str]:
normalized = normalize_voice_search_text(value)
return [
VOICE_SEARCH_TOKEN_ALIASES.get(token.lower(), token.lower())
for token in TOKEN_RE.findall(normalized)
]
def compact_search_token_sequence(value: str) -> list[str]:
return [token for token in search_token_sequence(value) if token not in SEARCH_NOISE_TOKENS]
def search_tokens(value: str) -> set[str]:
return set(search_token_sequence(value))
def normalize_search_key(value: str) -> str:
return "".join(search_token_sequence(value))
def normalize_compact_search_key(value: str) -> str:
return "".join(compact_search_token_sequence(value))
def safe_string(value: Any) -> str:
if value is None:
return ""
return str(value).strip()
def compact_jsonable_rows(rows: Iterable[dict[str, Any]], limit: int = 5) -> list[dict[str, str]]:
compacted: list[dict[str, str]] = []
for row in rows:
compacted.append({safe_string(key): safe_string(value) for key, value in row.items()})
if len(compacted) >= limit:
break
return compacted
def split_long_message(message: str, limit: int = 3900) -> list[str]:
if len(message) <= limit:
return [message]
chunks: list[str] = []
current = ""
for line in message.splitlines():
if len(current) + len(line) + 1 > limit:
if current:
chunks.append(current.rstrip())
current = line + "\n"
else:
current += line + "\n"
if current:
chunks.append(current.rstrip())
return chunks