2 Commits

Author SHA1 Message Date
engel 400c4b970d v1.1.0: auto-update check on startup
Polls GitHub /releases/latest with a 3-second timeout. If a newer
version is available, prints a yellow notice and offers to open the
download page. Silent on offline / API errors.
2026-05-16 11:45:34 +03:00
engel a868ce3815 Update repo URLs after GitHub username change 2026-05-16 00:52:04 +03:00
2 changed files with 42 additions and 4 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
# dhcpsrv # dhcpsrv
[![Latest release](https://img.shields.io/github/v/release/engelgardt2024-lang/dhcpsrv)](https://github.com/engelgardt2024-lang/dhcpsrv/releases/latest) [![Latest release](https://img.shields.io/github/v/release/Engelgardt23/dhcpsrv)](https://github.com/Engelgardt23/dhcpsrv/releases/latest)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
A tiny portable **DHCP server** for the laptop of a storage/server engineer. A tiny portable **DHCP server** for the laptop of a storage/server engineer.
@@ -14,7 +14,7 @@ Built for the “plug the cable in, watch a BMC pop up with an IP” workflow du
## Download ## Download
Grab the latest release: [**releases page**](https://github.com/engelgardt2024-lang/dhcpsrv/releases/latest). Grab the latest release: [**releases page**](https://github.com/Engelgardt23/dhcpsrv/releases/latest).
The asset is `dhcpsrv-portable-vX.Y.Z.zip` (~12 MB). The asset is `dhcpsrv-portable-vX.Y.Z.zip` (~12 MB).
## Run ## Run
+40 -2
View File
@@ -1,5 +1,5 @@
""" """
dhcpsrv v1.0.0 - portable single-exe edition. dhcpsrv v1.1.0 - portable single-exe edition.
made by engelgardt made by engelgardt
This file combines what previously lived in dhcpsrv.ps1 + dhcpsrv.py: This file combines what previously lived in dhcpsrv.ps1 + dhcpsrv.py:
@@ -14,6 +14,7 @@ Build:
""" """
import os, sys, ctypes, json, subprocess, signal, socket, struct, threading, time import os, sys, ctypes, json, subprocess, signal, socket, struct, threading, time
import urllib.request, webbrowser
from collections import deque from collections import deque
from datetime import datetime from datetime import datetime
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
@@ -36,7 +37,8 @@ def _enable_vt():
pass pass
_enable_vt() _enable_vt()
__version__ = "1.0.0" __version__ = "1.1.0"
GITHUB_REPO = "Engelgardt23/dhcpsrv"
# Fixed heights used by the Layout — used to compute the clients table fit # Fixed heights used by the Layout — used to compute the clients table fit
HEADER_LINES = 5 HEADER_LINES = 5
@@ -82,6 +84,40 @@ def require_admin():
sys.exit(0) sys.exit(0)
# ---------- update check ----------
def _parse_version(s):
try:
s = (s or "").strip().lstrip("v")
return tuple(int(x) for x in s.split(".")[:3])
except Exception:
return (0, 0, 0)
def check_for_update():
"""Query GitHub for the latest release. If newer than __version__, prompt to open the page."""
try:
url = f"https://api.github.com/repos/{GITHUB_REPO}/releases/latest"
req = urllib.request.Request(url, headers={
"Accept": "application/vnd.github+json",
"User-Agent": f"dhcpsrv/{__version__}",
})
with urllib.request.urlopen(req, timeout=3) as r:
data = json.loads(r.read().decode("utf-8", errors="replace"))
latest = (data.get("tag_name") or "").strip()
page = data.get("html_url") or f"https://github.com/{GITHUB_REPO}/releases/latest"
if _parse_version(latest) > _parse_version(__version__):
console.rule("[bold yellow]Update available")
console.print(f"Current: [dim]v{__version__}[/] Latest: [bold green]{latest}[/]")
try:
if Confirm.ask("Open the download page in your browser?", default=True):
webbrowser.open(page)
except (EOFError, KeyboardInterrupt):
pass
console.print()
except Exception:
# Offline / GitHub rate-limit / API error — skip silently.
pass
# ---------- helpers ---------- # ---------- helpers ----------
CREATE_NO_WINDOW = 0x08000000 CREATE_NO_WINDOW = 0x08000000
def run_ps(cmd, timeout=15): def run_ps(cmd, timeout=15):
@@ -363,6 +399,8 @@ def main():
console.print("[dim]made by engelgardt[/]") console.print("[dim]made by engelgardt[/]")
console.print() console.print()
check_for_update()
nic = select_nic() nic = select_nic()
if not nic: input("Press Enter to exit"); return if not nic: input("Press Enter to exit"); return