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 Locks import IsPathAccessible from Portals import ResolvePortals from Preview import GetMimeType, ReadTextFile, TextFileTypes 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, "", []) Excerpt = _StripMarkdownForExcerpt(Resolved) return Excerpt or Fallback except (OSError, UnicodeDecodeError): return Fallback def _MetaTag(Property: str, Content: str) -> str: return f'' def BuildOgTags(RootName: str, RelativePath: str, IsDirectoryUrl: bool, BaseUrl: str) -> str | None: if not IsPathAccessible(RootName, RelativePath, "", []): 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)