tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

utils.py (2377B)


      1 import os
      2 import subprocess
      3 import sys
      4 from typing import Any, Callable, Generic, Optional, Text, TypeVar
      5 T = TypeVar("T")
      6 
      7 
      8 def rel_path_to_url(rel_path: Text, url_base: Text = "/") -> Text:
      9    assert not os.path.isabs(rel_path), rel_path
     10    if url_base[0] != "/":
     11        url_base = "/" + url_base
     12    if url_base[-1] != "/":
     13        url_base += "/"
     14    return url_base + rel_path.replace(os.sep, "/")
     15 
     16 
     17 def from_os_path(path: Text) -> Text:
     18    assert os.path.sep == "/" or sys.platform == "win32"
     19    if "/" == os.path.sep:
     20        rv = path
     21    else:
     22        rv = path.replace(os.path.sep, "/")
     23    if "\\" in rv:
     24        raise ValueError("path contains \\ when separator is %s" % os.path.sep)
     25    return rv
     26 
     27 
     28 def to_os_path(path: Text) -> Text:
     29    assert os.path.sep == "/" or sys.platform == "win32"
     30    if "\\" in path:
     31        raise ValueError("normalised path contains \\")
     32    if "/" == os.path.sep:
     33        return path
     34    return path.replace("/", os.path.sep)
     35 
     36 
     37 def git(path: Text) -> Optional[Callable[..., Text]]:
     38    def gitfunc(cmd: Text, *args: Text) -> Text:
     39        full_cmd = ["git", cmd] + list(args)
     40        try:
     41            return subprocess.check_output(full_cmd, cwd=path, stderr=subprocess.STDOUT).decode('utf8')
     42        except Exception as e:
     43            if sys.platform == "win32" and isinstance(e, WindowsError):
     44                full_cmd[0] = "git.bat"
     45                return subprocess.check_output(full_cmd, cwd=path, stderr=subprocess.STDOUT).decode('utf8')
     46            else:
     47                raise
     48 
     49    try:
     50        # this needs to be a command that fails if we aren't in a git repo
     51        gitfunc("rev-parse", "--show-toplevel")
     52    except (subprocess.CalledProcessError, OSError):
     53        return None
     54    else:
     55        return gitfunc
     56 
     57 
     58 class cached_property(Generic[T]):
     59    def __init__(self, func: Callable[[Any], T]) -> None:
     60        self.func = func
     61        self.__doc__ = getattr(func, "__doc__")
     62        self.name = func.__name__
     63 
     64    def __get__(self, obj: Any, cls: Optional[type] = None) -> T:
     65        if obj is None:
     66            return self  # type: ignore
     67 
     68        # we can unconditionally assign as next time this won't be called
     69        assert self.name not in obj.__dict__
     70        rv = obj.__dict__[self.name] = self.func(obj)
     71        obj.__dict__.setdefault("__cached_properties__", set()).add(self.name)
     72        return rv