фикс заявок с гцупом
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
parent
43607bf9d0
commit
585cc374ed
2 changed files with 26 additions and 8 deletions
|
|
@ -56,7 +56,10 @@ def _build_full_text(
|
|||
result += "\n\n🆕 *Новое:*\n" + "\n".join(newest)
|
||||
|
||||
if responsible:
|
||||
names = ", ".join(r["user_name"] for r in responsible)
|
||||
names = ", ".join(
|
||||
formatter.escape_markdown(r["user_name"]) or r["user_name"]
|
||||
for r in responsible
|
||||
)
|
||||
result += _RESP_SEP + f"\n🙋 В работе: {names}"
|
||||
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -87,6 +87,15 @@ def _shorten_name(name: str | None) -> str | None:
|
|||
return name
|
||||
|
||||
|
||||
def escape_markdown(text: str | None) -> str | None:
|
||||
"""Escape user-provided text for Telegram legacy Markdown parse mode."""
|
||||
if text is None:
|
||||
return None
|
||||
escaped = str(text).replace("\\", "\\\\")
|
||||
for ch in ("_", "*", "`", "["):
|
||||
escaped = escaped.replace(ch, f"\\{ch}")
|
||||
return escaped
|
||||
|
||||
def _strip_quote(text: str) -> tuple[str, bool]:
|
||||
"""Убирает блоки цитирования. Возвращает (cleaned_text, had_quote)."""
|
||||
cleaned, n = _QUOTE_RE.subn("", text)
|
||||
|
|
@ -146,6 +155,7 @@ def _parse_single_event(event: dict, username: str = "") -> ParsedEvent | None:
|
|||
etype = event.get("type")
|
||||
blockname = event.get("blockname", "")
|
||||
short_user = _shorten_name(username) or "Неизвестный"
|
||||
short_user = escape_markdown(short_user) or short_user
|
||||
|
||||
# ── Комментарии ──────────────────────────────────────────────────────────
|
||||
if etype in (50, 55):
|
||||
|
|
@ -155,6 +165,7 @@ def _parse_single_event(event: dict, username: str = "") -> ParsedEvent | None:
|
|||
text, had_quote = _strip_quote(text)
|
||||
if not text:
|
||||
return None
|
||||
text = escape_markdown(text) or ""
|
||||
prefix = "Ответ на прошлое: " if had_quote else ""
|
||||
lock = " 🔒" if etype == 55 else ""
|
||||
return ParsedEvent("comment", f"*{short_user}*{lock}: {prefix}{text}")
|
||||
|
|
@ -187,8 +198,8 @@ def _parse_single_event(event: dict, username: str = "") -> ParsedEvent | None:
|
|||
if entity_data:
|
||||
val_new = entity_data.get("valuenew") or {}
|
||||
val_old = entity_data.get("valueold")
|
||||
new_str = _extract_name(val_new, blockname)
|
||||
old_str = _extract_name(val_old, blockname) if val_old else None
|
||||
new_str = escape_markdown(_extract_name(val_new, blockname))
|
||||
old_str = escape_markdown(_extract_name(val_old, blockname)) if val_old else None
|
||||
if not new_str and not old_str:
|
||||
return None
|
||||
if new_str and old_str:
|
||||
|
|
@ -205,11 +216,14 @@ def _parse_single_event(event: dict, username: str = "") -> ParsedEvent | None:
|
|||
if isinstance(attach, dict):
|
||||
fname = attach.get("Name", "")
|
||||
uploader = _shorten_name(attach.get("UploadedBy", "").strip() or None) or "?"
|
||||
fname = escape_markdown(fname) or ""
|
||||
uploader = escape_markdown(uploader) or "?"
|
||||
return ParsedEvent("change", f"• 📎 {uploader} прикрепил: {fname}")
|
||||
m = _FILE_EXT_RE.search(str_val.strip())
|
||||
ext = m.group(1).upper() if m else "файл"
|
||||
return ParsedEvent("change", f"• 📎 Добавлен файл .{ext}")
|
||||
truncated = str_val[:80] + ("…" if len(str_val) > 80 else "")
|
||||
truncated = escape_markdown(truncated) or ""
|
||||
return ParsedEvent("change", f"• {label}: *{truncated}*")
|
||||
|
||||
# ── Событие без значения ──────────────────────────────────────────────────
|
||||
|
|
@ -230,6 +244,7 @@ def get_description_event(fields: dict) -> str | None:
|
|||
if not description:
|
||||
return None
|
||||
truncated = description[:100] + ('…' if len(description) > 100 else '')
|
||||
truncated = escape_markdown(truncated) or ""
|
||||
return f"📝 {truncated}"
|
||||
|
||||
|
||||
|
|
@ -374,12 +389,12 @@ def format_notification(payload: dict) -> str:
|
|||
op_type = payload.get("Event", {}).get("OperationType", "")
|
||||
fields = payload.get("Fields", {})
|
||||
number = fields.get("Number", "?")
|
||||
name = _scalar(fields.get("name")) or "—"
|
||||
applicant = get_initiator(fields)
|
||||
executors = get_all_executors(fields)
|
||||
obj_name = get_object_name(fields)
|
||||
name = escape_markdown(_scalar(fields.get("name")) or "—") or "-"
|
||||
applicant = escape_markdown(get_initiator(fields))
|
||||
executors = [escape_markdown(x) or "" for x in get_all_executors(fields)]
|
||||
obj_name = escape_markdown(get_object_name(fields))
|
||||
to_flag = is_to(fields)
|
||||
status = _resolve_field(fields, "status", "statuses")
|
||||
status = escape_markdown(_resolve_field(fields, "status", "statuses"))
|
||||
|
||||
header = f"🆕 *Новая #{number}*" if op_type == "Created" \
|
||||
else f"🔄 *#{number} обновлена*"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue