Files
SaraView/Backend/VarFunctions.py
T

66 lines
2.5 KiB
Python

"""The server's side of SaraView's variables: VarEngine.py (shared with the
desktop client) with file access that follows the configured roots and the
locks, so a portal can't show what you couldn't open yourself."""
from __future__ import annotations
from Core import ResolvePath
from Explorer import ClassifyFile, ListDirectory
from Locks import IsPathAccessible
from Preview import ReadTextFile
from VarEngine import MarkerPattern, PortalFileTypes # MarkerPattern: Graph.py finds links with it
from VarEngine import ResolvePortals as _ResolvePortals
from VarEngine import ResolveSpans as _ResolveSpans
__all__ = ["MarkerPattern", "ResolvePortals", "ResolveSpans"]
class ServerAccess:
def __init__(self, RootName: str, Username: str, UserGroups: list[str]):
self.RootName = RootName
self.Username = Username
self.UserGroups = UserGroups
def _Allowed(self, RelativePath: str) -> bool:
return IsPathAccessible(self.RootName, RelativePath, self.Username, self.UserGroups)
def ReadText(self, RelativePath: str) -> str | None:
if not self._Allowed(RelativePath):
return None
try:
FilePath = ResolvePath(self.RootName, RelativePath)
except ValueError:
return None
if not FilePath.is_file() or ClassifyFile(FilePath) not in PortalFileTypes:
return None
try:
return ReadTextFile(FilePath)
except (OSError, UnicodeDecodeError):
return None
def List(self, DirectoryPath: str) -> list[dict] | None:
if not self._Allowed(DirectoryPath):
return None
try:
Entries = ListDirectory(self.RootName, DirectoryPath, False, False)
except (ValueError, NotADirectoryError, FileNotFoundError):
return None
return [
Entry for Entry in Entries
if self._Allowed(f"{DirectoryPath}/{Entry['Name']}" if DirectoryPath else Entry["Name"])
]
def IsDirectory(self, RelativePath: str) -> bool:
try:
return ResolvePath(self.RootName, RelativePath).is_dir()
except ValueError:
return False
def ResolvePortals(RootName: str, RelativePath: str, Content: str, Username: str, UserGroups: list[str]) -> str:
return _ResolvePortals(RelativePath, Content, ServerAccess(RootName, Username, UserGroups))
def ResolveSpans(RootName: str, RelativePath: str, Content: str, Username: str, UserGroups: list[str]) -> list[dict]:
return _ResolveSpans(RelativePath, Content, ServerAccess(RootName, Username, UserGroups))