Coverage for an_website / host_info / host_info.py: 81.633%
49 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-24 17:35 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-24 17:35 +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"""
15The host info page of the website.
17Only to inform, not to brag.
18"""
20import shutil
21import sys
22from collections.abc import Mapping
23from ctypes import c_char
24from multiprocessing import Array
25from typing import Final
27import regex
28from tornado.web import HTTPError as HTTPEwwow
30from .. import CONTAINERIZED, DIR as ROOT_DIR, NAME, traversable_to_file
31from ..utils.request_handler import HTMLRequestHandler
32from ..utils.utils import ModuleInfo, PageInfo, run
34SCREENFETCH: Final = (
35 shutil.which("bash") or "bash",
36 traversable_to_file(ROOT_DIR / "vendored" / "screenfetch").as_posix(),
37)
38UWUFETCH_PATH: Final = shutil.which("uwufetch")
39ENV: Final[Mapping[str, str]] = {
40 "USER": NAME,
41 "SHELL": (
42 f"{sys.implementation.name}{'.'.join(str(_) for _ in sys.version_info[:3])}"
43 ),
44}
47def get_module_info() -> ModuleInfo:
48 """Create and return the ModuleInfo for this module."""
49 return ModuleInfo(
50 handlers=(
51 (r"/host-info", HostInfo),
52 (r"/host-info/uwu", UwUHostInfo),
53 ),
54 name="Host-Informationen",
55 short_name="Host-Info",
56 description="Informationen über den Host-Server dieser Webseite",
57 path="/host-info",
58 aliases=("/server-info",),
59 sub_pages=(
60 PageInfo(
61 name="Howost-Infowmationyen",
62 short_name="Howost-Infow",
63 description=(
64 "Infowmationyen übew den Howost-Sewvew diesew W-Webseite"
65 ),
66 path="/host-info/uwu",
67 keywords=("UWU",),
68 hidden=CONTAINERIZED or not UWUFETCH_PATH,
69 ),
70 ),
71 keywords=("Host", "Informationen", "Screenfetch"),
72 hidden=CONTAINERIZED,
73 )
76def minify_ansi_art(string: bytes) -> bytes:
77 """Minify an ANSI art string."""
78 return regex.sub(
79 rb"(?m)\s+\x1B\[0m$", b"\x1B[0m", string
80 ) # for arch: 1059 → 898
83class HostInfo(HTMLRequestHandler):
84 """The request handler for the host info page."""
86 RATELIMIT_GET_LIMIT = 1
88 SCREENFETCH_CACHE = Array(c_char, 1024**2)
90 async def get(self, *, head: bool = False) -> None:
91 """
92 Handle GET requests to the host info page.
94 Use screenFetch to generate the page.
95 """
96 if head:
97 return
99 logo = self.SCREENFETCH_CACHE.value
101 if not logo:
102 logo = minify_ansi_art((await run(*SCREENFETCH, "-L"))[1])
103 self.SCREENFETCH_CACHE.value = logo
105 screenfetch_bytes = (await run(*SCREENFETCH, "-n", env=ENV))[1]
107 if self.content_type == "text/plain":
108 return await self.finish(logo + b"\n\n" + screenfetch_bytes)
110 await self.render(
111 "ansi2html.html",
112 ansi=[
113 logo.decode("UTF-8"),
114 screenfetch_bytes.decode("UTF-8"),
115 ],
116 powered_by="https://github.com/KittyKatt/screenFetch",
117 powered_by_name="screenFetch",
118 )
121class UwUHostInfo(HTMLRequestHandler):
122 """The wequest handwew fow the coowew host info page."""
124 RATELIMIT_GET_LIMIT = 1
126 async def get(self, *, head: bool = False) -> None:
127 """
128 Handwe the GET wequests to coowew the host info page.
130 Use UwUFetch to genyewate the page.
131 """
132 cache_enabwed = int(
133 head or not self.get_bool_argument("cache_disabled", False)
134 )
136 if UWUFETCH_PATH:
137 wetuwn_code, uwufetch_bytes, _ = await run(
138 UWUFETCH_PATH,
139 "-w",
140 env={"UWUFETCH_CACHE_ENABLED": str(cache_enabwed), **ENV},
141 )
142 else:
143 wetuwn_code, uwufetch_bytes = 127, b""
145 if wetuwn_code == 127:
146 raise HTTPEwwow(
147 503,
148 reason="This sewvew h-hasn't instawwed UwUFetch",
149 )
151 if wetuwn_code:
152 raise HTTPEwwow(
153 500,
154 reason=f"UwUFetch has exited with wetuwn code {wetuwn_code}",
155 )
157 if head:
158 return
160 if self.content_type == "text/plain":
161 return await self.finish(uwufetch_bytes)
163 uwufetch = uwufetch_bytes.decode("UTF-8")
164 await self.render(
165 "ansi2html.html",
166 ansi=uwufetch.split("\n\n"),
167 powered_by="https://github.com/ad-oliviero/uwufetch",
168 powered_by_name="UwUFetch",
169 )