Files
SaraView/Backend/Embeds.py
T
2026-09-21 23:15:12 +02:00

106 lines
3.8 KiB
Python

from __future__ import annotations
import html
import re
from pathlib import Path
from urllib.parse import quote
from Core import ResolvePath
from Explorer import ClassifyFile, GetDirectoryNoteInfo
from Groups import GuestGroupName
from Locks import IsPathAccessible
from Preview import GetMimeType, ReadTextFile, TextFileTypes
from VarFunctions import ResolvePortals
DescriptionExcerptLength = 200
DefaultDescriptions = {
"directory": "A directory on SaraView.",
"video": "A video on SaraView.",
"image": "An image on SaraView.",
"note": "A note on SaraView.",
"file": "A file on SaraView.",
}
def _StripMarkdownForExcerpt(Text: str) -> str:
Cleaned = re.sub(r"[#*_`>~\[\]]", "", Text)
Cleaned = re.sub(r"\s+", " ", Cleaned).strip()
return Cleaned[:DescriptionExcerptLength]
def _DescribeTextFile(RootName: str, RelativePath: str, FilePath: Path, Fallback: str) -> str:
try:
Content = ReadTextFile(FilePath)
Resolved = ResolvePortals(RootName, RelativePath, Content, "", [GuestGroupName])
Excerpt = _StripMarkdownForExcerpt(Resolved)
return Excerpt or Fallback
except (OSError, UnicodeDecodeError):
return Fallback
def _MetaTag(Property: str, Content: str) -> str:
return f'<meta property="{html.escape(Property)}" content="{html.escape(Content)}" />'
def BuildOgTags(RootName: str, RelativePath: str, IsDirectoryUrl: bool, BaseUrl: str) -> str | None:
if not IsPathAccessible(RootName, RelativePath, "", [GuestGroupName]):
return None
try:
EntryPath = ResolvePath(RootName, RelativePath)
except ValueError:
return None
if not EntryPath.exists():
return None
EncodedPath = "/".join(quote(Segment) for Segment in RelativePath.split("/") if Segment)
PageUrl = f"{BaseUrl}/{quote(RootName)}/{EncodedPath}{'/' if IsDirectoryUrl else ''}"
Tags = [_MetaTag("og:url", PageUrl)]
if EntryPath.is_dir():
NoteInfo = GetDirectoryNoteInfo(EntryPath)
Description = DefaultDescriptions["directory"]
if NoteInfo is not None and NoteInfo["FileType"] in TextFileTypes:
NotePath = EntryPath / NoteInfo["Name"]
NoteRelativePath = f"{RelativePath}/{NoteInfo['Name']}" if RelativePath else NoteInfo["Name"]
Description = _DescribeTextFile(
RootName, NoteRelativePath, NotePath, DefaultDescriptions["directory"]
)
Tags.append(_MetaTag("og:title", EntryPath.name))
Tags.append(_MetaTag("og:description", Description))
Tags.append(_MetaTag("og:type", "website"))
return "\n".join(Tags)
FileType = ClassifyFile(EntryPath)
MediaUrl = f"{BaseUrl}/public/media/{quote(RootName)}/{EncodedPath}"
Tags.append(_MetaTag("og:title", EntryPath.name))
if FileType == "video":
Tags.append(_MetaTag("og:type", "video.other"))
Tags.append(_MetaTag("og:video", MediaUrl))
Tags.append(_MetaTag("og:video:url", MediaUrl))
Tags.append(_MetaTag("og:video:secure_url", MediaUrl))
Tags.append(_MetaTag("og:video:type", GetMimeType(EntryPath)))
Tags.append(_MetaTag("og:description", DefaultDescriptions["video"]))
elif FileType == "image":
Tags.append(_MetaTag("og:type", "website"))
Tags.append(_MetaTag("og:image", MediaUrl))
Tags.append(_MetaTag("og:image:type", GetMimeType(EntryPath)))
Tags.append(_MetaTag("og:description", DefaultDescriptions["image"]))
elif FileType in TextFileTypes:
Description = _DescribeTextFile(RootName, RelativePath, EntryPath, DefaultDescriptions["note"])
Tags.append(_MetaTag("og:type", "article"))
Tags.append(_MetaTag("og:description", Description))
else:
Tags.append(_MetaTag("og:type", "website"))
Tags.append(_MetaTag("og:description", DefaultDescriptions["file"]))
return "\n".join(Tags)