Coverage for an_website / __init__.py: 79.167%
72 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-15 14:36 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-15 14:36 +0000
1# This program is free software: you can redistribute it and/or modify
2# it under the terms of the GNU Affero General Public License as
3# published by the Free Software Foundation, either version 3 of the
4# License, or (at your option) any later version.
5#
6# This program is distributed in the hope that it will be useful,
7# but WITHOUT ANY WARRANTY; without even the implied warranty of
8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9# GNU Affero General Public License for more details.
10#
11# You should have received a copy of the GNU Affero General Public License
12# along with this program. If not, see <https://www.gnu.org/licenses/>.
14"""The website of the AN."""
17import multiprocessing
18import os
19import sys
20import time
21from asyncio import Event
22from collections.abc import Mapping
23from importlib.metadata import Distribution
24from importlib.resources import files
25from importlib.resources.abc import Traversable
26from pathlib import Path
27from typing import Final, TypedDict
29try:
30 import orjson as json
32 if "spam" not in json.loads('{"spam":"eggs"}'):
33 from marshal import dumps, loads
35 _loads = json.loads
36 json.loads = lambda *args, **kwargs: loads( # nosec: B302
37 dumps(_loads(*args, **kwargs))
38 )
39except ModuleNotFoundError:
40 from . import fake_orjson as json # type: ignore[no-redef] # noqa: F811
42 sys.modules["orjson"] = json
44try:
45 from pytest_is_running import is_running as pytest_is_running
46except ModuleNotFoundError:
48 def pytest_is_running() -> bool: # noqa: D103
49 # pylint: disable=missing-function-docstring
50 return "pytest" in sys.modules
53class MediaType(TypedDict, total=False):
54 # pylint: disable=missing-class-docstring
55 charset: str
56 compressible: bool
57 extensions: list[str]
58 source: str
61class UptimeTimer:
62 """UptimeTimer class used for timing the uptime."""
64 __slots__ = ("_start_time",)
66 def __init__(self) -> None:
67 self.reset()
69 def get(self) -> float:
70 """Get the time since start in seconds."""
71 return self.get_ns() / 1_000_000_000
73 def get_ns(self) -> int:
74 """Get the time since start in nanoseconds."""
75 return time.monotonic_ns() - self._start_time
77 def reset(self) -> None:
78 """Reset the timer."""
79 self._start_time = time.monotonic_ns()
82UPTIME: Final = UptimeTimer()
84EPOCH: Final[int] = 1651075200
85EPOCH_MS: Final[int] = EPOCH * 1000
87DIR: Final[Traversable] = files(__name__)
89MEDIA_TYPES: Final[Mapping[str, MediaType]] = json.loads(
90 (DIR / "vendored" / "mime-db.json").read_bytes()
91)
93NAME = "an-website" # pylint: disable=invalid-name
96def get_version() -> str:
97 """Get the version of the package."""
98 if isinstance(DIR, Path):
99 # pylint: disable-next=import-outside-toplevel
100 from get_version import get_version as gv
102 return gv(__file__, vcs="git")
104 return Distribution.from_name(NAME).version
107VERSION: Final[str] = get_version()
109GH_ORG_URL: Final[str] = "https://github.com/asozialesnetzwerk"
110GH_REPO_URL: Final[str] = f"{GH_ORG_URL}/{NAME}"
111GH_PAGES_URL: Final[str] = f"https://github.asozial.org/{NAME}"
113CACHE_DIR: Final[Path] = Path("~/.cache/", NAME).expanduser().absolute()
114STATIC_DIR: Final[Traversable] = DIR / "static"
115TEMPLATES_DIR: Final[Traversable] = DIR / "templates"
117ORJSON_OPTIONS: Final[int] = (
118 json.OPT_SERIALIZE_NUMPY | json.OPT_NAIVE_UTC | json.OPT_UTC_Z
119)
121CONTAINERIZED: Final[bool] = "container" in os.environ or os.path.exists(
122 "/.dockerenv"
123)
126def traversable_to_file(traversable: Traversable) -> Path:
127 """Convert a traversable to a path to a file directly in the fs."""
128 if isinstance(traversable, Path):
129 return traversable
130 folder = CACHE_DIR / "temp"
131 folder.mkdir(parents=True, exist_ok=True)
132 file = folder / traversable.name
133 file.write_bytes(traversable.read_bytes())
134 return file
137CA_BUNDLE_PATH: Final[str] = traversable_to_file(
138 DIR / "ca-bundle.crt"
139).as_posix()
142if pytest_is_running():
143 NAME += "-test"
144elif sys.flags.dev_mode:
145 NAME += "-dev"
147EVENT_SHUTDOWN: Final = multiprocessing.Event()
149EVENT_ELASTICSEARCH: Final = Event()
150EVENT_REDIS: Final = Event()
152__all__ = (
153 "CONTAINERIZED",
154 "DIR",
155 "EPOCH",
156 "EPOCH_MS",
157 "EVENT_ELASTICSEARCH",
158 "EVENT_REDIS",
159 "EVENT_SHUTDOWN",
160 "GH_ORG_URL",
161 "GH_PAGES_URL",
162 "GH_REPO_URL",
163 "MEDIA_TYPES",
164 "NAME",
165 "ORJSON_OPTIONS",
166 "STATIC_DIR",
167 "TEMPLATES_DIR",
168 "UPTIME",
169 "VERSION",
170 "pytest_is_running",
171)
173__version__ = VERSION