Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
39 lines
1.2 KiB
Python
39 lines
1.2 KiB
Python
from collections.abc import Mapping
|
|
|
|
from bs4 import BeautifulSoup
|
|
from django.utils.html import escape
|
|
|
|
from zerver.lib.cache import cache_with_key, open_graph_description_cache_key
|
|
|
|
|
|
def html_to_text(content: str | bytes, tags: Mapping[str, str] = {"p": " | "}) -> str:
|
|
bs = BeautifulSoup(content, features="lxml")
|
|
# Skip any admonition (warning) blocks, since they're
|
|
# usually something about users needing to be an
|
|
# organization administrator, and not useful for
|
|
# describing the page.
|
|
for tag in bs.find_all("div", class_="admonition"):
|
|
tag.clear()
|
|
|
|
# Skip tabbed-sections, which just contain navigation instructions.
|
|
for tag in bs.find_all("div", class_="tabbed-section"):
|
|
tag.clear()
|
|
|
|
text = ""
|
|
for element in bs.find_all(tags.keys()):
|
|
# Ignore empty elements
|
|
if not element.text:
|
|
continue
|
|
# .text converts it from HTML to text
|
|
if text:
|
|
text += tags[element.name]
|
|
text += element.text
|
|
if len(text) > 500:
|
|
break
|
|
return escape(" ".join(text.split()))
|
|
|
|
|
|
@cache_with_key(open_graph_description_cache_key, timeout=3600 * 24)
|
|
def get_content_description(content: bytes, request_url: str) -> str:
|
|
return html_to_text(content)
|