ser2netweb 3.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. ser2netweb/__init__.py +20 -0
  2. ser2netweb/__main__.py +6 -0
  3. ser2netweb/accounts.py +503 -0
  4. ser2netweb/cli.py +489 -0
  5. ser2netweb/clock.py +128 -0
  6. ser2netweb/config.py +4491 -0
  7. ser2netweb/console.py +181 -0
  8. ser2netweb/datalock.py +181 -0
  9. ser2netweb/engine/__init__.py +0 -0
  10. ser2netweb/engine/access.py +173 -0
  11. ser2netweb/engine/bindhint.py +115 -0
  12. ser2netweb/engine/bridge.py +1928 -0
  13. ser2netweb/engine/cluster.py +1140 -0
  14. ser2netweb/engine/modbus.py +530 -0
  15. ser2netweb/engine/modbus_gateway.py +1465 -0
  16. ser2netweb/engine/mqtt_pub.py +632 -0
  17. ser2netweb/engine/netguard.py +805 -0
  18. ser2netweb/engine/netinfo.py +199 -0
  19. ser2netweb/engine/portdiag.py +414 -0
  20. ser2netweb/engine/portlist.py +471 -0
  21. ser2netweb/engine/protocols/__init__.py +28 -0
  22. ser2netweb/engine/protocols/base.py +117 -0
  23. ser2netweb/engine/protocols/raw.py +12 -0
  24. ser2netweb/engine/protocols/rfc2217.py +586 -0
  25. ser2netweb/engine/protocols/telnet.py +172 -0
  26. ser2netweb/engine/serial_compat.py +598 -0
  27. ser2netweb/engine/serial_io.py +210 -0
  28. ser2netweb/engine/serial_link.py +414 -0
  29. ser2netweb/engine/sockopts.py +103 -0
  30. ser2netweb/engine/sparkplug.py +538 -0
  31. ser2netweb/engine/sparkplug_node.py +550 -0
  32. ser2netweb/engine/supervisor.py +533 -0
  33. ser2netweb/engine/tls.py +232 -0
  34. ser2netweb/envvars.py +57 -0
  35. ser2netweb/explain.py +117 -0
  36. ser2netweb/healthcheck.py +78 -0
  37. ser2netweb/i18n.py +110 -0
  38. ser2netweb/importer.py +550 -0
  39. ser2netweb/layout.py +118 -0
  40. ser2netweb/licences.py +86 -0
  41. ser2netweb/locale/tr.json +1569 -0
  42. ser2netweb/logsetup.py +253 -0
  43. ser2netweb/logtext.py +23 -0
  44. ser2netweb/notify.py +761 -0
  45. ser2netweb/optional.py +76 -0
  46. ser2netweb/reload.py +295 -0
  47. ser2netweb/runtime.py +762 -0
  48. ser2netweb/sdnotify.py +85 -0
  49. ser2netweb/ser2net_import.py +2001 -0
  50. ser2netweb/signins.py +98 -0
  51. ser2netweb/standalone.py +154 -0
  52. ser2netweb/state.py +1457 -0
  53. ser2netweb/storage.py +130 -0
  54. ser2netweb/textfold.py +51 -0
  55. ser2netweb/tlsreload.py +37 -0
  56. ser2netweb/watchdog.py +201 -0
  57. ser2netweb/web/__init__.py +0 -0
  58. ser2netweb/web/api.py +793 -0
  59. ser2netweb/web/auth.py +699 -0
  60. ser2netweb/web/certinfo.py +144 -0
  61. ser2netweb/web/httpguard.py +413 -0
  62. ser2netweb/web/ldap_auth.py +556 -0
  63. ser2netweb/web/oidc_auth.py +330 -0
  64. ser2netweb/web/proxy.py +398 -0
  65. ser2netweb/web/routes/__init__.py +78 -0
  66. ser2netweb/web/routes/cluster.py +669 -0
  67. ser2netweb/web/routes/common.py +359 -0
  68. ser2netweb/web/routes/console.py +451 -0
  69. ser2netweb/web/routes/forms.py +853 -0
  70. ser2netweb/web/routes/login.py +573 -0
  71. ser2netweb/web/routes/mappings.py +470 -0
  72. ser2netweb/web/routes/ops.py +374 -0
  73. ser2netweb/web/routes/settings.py +2135 -0
  74. ser2netweb/web/routes/system.py +308 -0
  75. ser2netweb/web/routes/totp.py +282 -0
  76. ser2netweb/web/selfsigned.py +129 -0
  77. ser2netweb/web/server.py +483 -0
  78. ser2netweb/web/static/app.css +327 -0
  79. ser2netweb/web/static/app.js +1102 -0
  80. ser2netweb/web/static/htmx.min.js +1 -0
  81. ser2netweb/web/static/points.js +218 -0
  82. ser2netweb/web/static/theme.js +7 -0
  83. ser2netweb/web/static/xterm-addon-fit.js +2 -0
  84. ser2netweb/web/static/xterm.css +218 -0
  85. ser2netweb/web/static/xterm.js +2 -0
  86. ser2netweb/web/templates/_cluster_body.html +109 -0
  87. ser2netweb/web/templates/_console.html +21 -0
  88. ser2netweb/web/templates/_footer.html +13 -0
  89. ser2netweb/web/templates/_login_notice.html +8 -0
  90. ser2netweb/web/templates/_macros.html +21 -0
  91. ser2netweb/web/templates/_mapping_form.html +477 -0
  92. ser2netweb/web/templates/_mapping_log.html +28 -0
  93. ser2netweb/web/templates/_mapping_traces.html +44 -0
  94. ser2netweb/web/templates/_mappings_body.html +149 -0
  95. ser2netweb/web/templates/_modbus_read.html +18 -0
  96. ser2netweb/web/templates/_ports_table.html +37 -0
  97. ser2netweb/web/templates/_serial_port_select.html +48 -0
  98. ser2netweb/web/templates/_shell.html +41 -0
  99. ser2netweb/web/templates/audit.html +55 -0
  100. ser2netweb/web/templates/base.html +77 -0
  101. ser2netweb/web/templates/dashboard.html +72 -0
  102. ser2netweb/web/templates/licenses.html +18 -0
  103. ser2netweb/web/templates/login.html +32 -0
  104. ser2netweb/web/templates/login_totp.html +23 -0
  105. ser2netweb/web/templates/settings.html +830 -0
  106. ser2netweb/web/templates/setup.html +43 -0
  107. ser2netweb/web/templates/totp.html +41 -0
  108. ser2netweb/web/totp.py +94 -0
  109. ser2netweb/winservice.py +1793 -0
  110. ser2netweb-3.0.0.dist-info/METADATA +120 -0
  111. ser2netweb-3.0.0.dist-info/RECORD +121 -0
  112. ser2netweb-3.0.0.dist-info/WHEEL +5 -0
  113. ser2netweb-3.0.0.dist-info/entry_points.txt +2 -0
  114. ser2netweb-3.0.0.dist-info/licenses/COMMERCIAL_LICENSE.md +94 -0
  115. ser2netweb-3.0.0.dist-info/licenses/LICENSE +662 -0
  116. ser2netweb-3.0.0.dist-info/licenses/NOTICE +20 -0
  117. ser2netweb-3.0.0.dist-info/licenses/THIRD-PARTY-NOTICES.md +105 -0
  118. ser2netweb-3.0.0.dist-info/licenses/tools/licenses/npm/htmx.org.txt +13 -0
  119. ser2netweb-3.0.0.dist-info/licenses/tools/licenses/npm/xterm-addon-fit.txt +19 -0
  120. ser2netweb-3.0.0.dist-info/licenses/tools/licenses/npm/xterm.txt +21 -0
  121. ser2netweb-3.0.0.dist-info/top_level.txt +1 -0
ser2netweb/sdnotify.py ADDED
@@ -0,0 +1,85 @@
1
+ """systemd's notification protocol (sd_notify), standard library only.
2
+
3
+ Under a unit with Type=notify (the optional drop-in systemd/ser2netweb.service.d/notify.conf)
4
+ systemd waits for READY=1 before it counts ser2netweb as started, and with WatchdogSec= it
5
+ restarts ser2netweb when the WATCHDOG=1 pings stop (they come from the event loop, so a
6
+ loop that is stuck stops them). Everything here does nothing without $NOTIFY_SOCKET, so
7
+ the default unit (Type=simple), Docker, Windows and a start by hand are not affected.
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import os
12
+ import socket
13
+ import sys
14
+ import time
15
+ from typing import Mapping, Optional
16
+
17
+
18
+ def _address(env: Mapping[str, str]) -> Optional[str]:
19
+ addr = env.get("NOTIFY_SOCKET") or ""
20
+ if not addr or not hasattr(socket, "AF_UNIX"):
21
+ return None
22
+ if addr.startswith("@"): # an abstract socket (Linux)
23
+ return "\0" + addr[1:]
24
+ return addr if addr.startswith("/") else None
25
+
26
+
27
+ def notify(*fields: str, env: Optional[Mapping[str, str]] = None) -> bool:
28
+ """Send ``fields`` ("READY=1", "STATUS=..."), one per line, to systemd. True when sent;
29
+ False without $NOTIFY_SOCKET or when it can't be (never raises). It never waits: this
30
+ runs on the event loop, and a socket whose queue is full (nobody reads it) would hold
31
+ it up; that message is lost instead."""
32
+ addr = _address(os.environ if env is None else env)
33
+ if addr is None or sys.platform == "win32": # (no systemd there)
34
+ return False
35
+ try:
36
+ with socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) as s:
37
+ s.setblocking(False)
38
+ s.connect(addr)
39
+ s.sendall("\n".join(fields).encode("utf-8", "replace"))
40
+ except OSError:
41
+ return False
42
+ return True
43
+
44
+
45
+ def ready(status: str = "", env: Optional[Mapping[str, str]] = None) -> bool:
46
+ """ser2netweb has started: its mappings run and its admin UI listens."""
47
+ return notify("READY=1", *([f"STATUS={status}"] if status else []), env=env)
48
+
49
+
50
+ def reloading(env: Optional[Mapping[str, str]] = None) -> bool:
51
+ """ser2netweb reads config.json again (systemctl reload, SIGHUP); ready() follows when it
52
+ is done (also what Type=notify-reload waits for)."""
53
+ fields = ["RELOADING=1"]
54
+ if sys.platform != "win32": # (no CLOCK_MONOTONIC on Windows, which has no systemd)
55
+ try:
56
+ fields.append(f"MONOTONIC_USEC={time.clock_gettime_ns(time.CLOCK_MONOTONIC) // 1000}")
57
+ except (AttributeError, OSError):
58
+ pass
59
+ return notify(*fields, env=env)
60
+
61
+
62
+ def stopping(env: Optional[Mapping[str, str]] = None) -> bool:
63
+ return notify("STOPPING=1", env=env)
64
+
65
+
66
+ def watchdog(env: Optional[Mapping[str, str]] = None) -> bool:
67
+ return notify("WATCHDOG=1", env=env)
68
+
69
+
70
+ def watchdog_interval(env: Optional[Mapping[str, str]] = None) -> Optional[float]:
71
+ """How often to send WATCHDOG=1 (half of WatchdogSec=, as systemd advises), or None
72
+ when systemd doesn't watch this process."""
73
+ env = os.environ if env is None else env
74
+ if _address(env) is None:
75
+ return None
76
+ # meant for this process: its pid, or its parent's when that is the standalone
77
+ # binary's launcher, which runs ser2netweb in a child process (NotifyAccess=all)
78
+ pid = (env.get("WATCHDOG_PID") or "").strip()
79
+ if pid and pid not in (str(os.getpid()), str(os.getppid())):
80
+ return None
81
+ try:
82
+ usec = int((env.get("WATCHDOG_USEC") or "").strip())
83
+ except ValueError:
84
+ return None
85
+ return usec / 2e6 if usec > 0 else None