generated from Dicken/dickendock
round19: Startseite aufgeraeumt, Favicon-Fallback ueber Ports, Favicon-Picker, Live-Status per Ping
This commit is contained in:
@@ -77,9 +77,15 @@ function extractFaviconUrl(html: string, baseUrl: string): string | undefined {
|
||||
/<link[^>]+rel=["'](?:shortcut icon|icon)["'][^>]*href=["']([^"']+)["']/i
|
||||
);
|
||||
const href = match?.[1];
|
||||
// Kein <link rel="icon"> im HTML gefunden -> hier NICHT mehr blind auf
|
||||
// "/favicon.ico" raten (das täuscht ein bestätigtes Favicon vor, das oft
|
||||
// gar nicht existiert - 404). Der Aufrufer (scanDeviceServices) entscheidet
|
||||
// die Fallback-Reihenfolge: erst ein Favicon eines anderen Dienstes auf
|
||||
// demselben Gerät übernehmen, erst danach selbst raten.
|
||||
if (!href) return undefined;
|
||||
|
||||
try {
|
||||
return new URL(href ?? "/favicon.ico", baseUrl).toString();
|
||||
return new URL(href, baseUrl).toString();
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -136,5 +136,17 @@ export async function scanDeviceServices(
|
||||
});
|
||||
}
|
||||
|
||||
// Fallback-Reihenfolge für Dienste ohne bestätigtes Favicon (kein
|
||||
// <link rel="icon"> im HTML gefunden): zuerst das Favicon eines ANDEREN
|
||||
// Dienstes auf demselben Gerät übernehmen (typischerweise dieselbe
|
||||
// Software/dasselbe Gerät, das Icon passt meist trotzdem) - erst wenn auch
|
||||
// das fehlt, wird als letzter Ausweg "/favicon.ico" am eigenen Port
|
||||
// geraten (kann ins Leere laufen, ist aber besser als gar kein Versuch).
|
||||
const firstSiblingFavicon = found.find((s) => s.favicon)?.favicon;
|
||||
for (const service of found) {
|
||||
if (service.favicon) continue;
|
||||
service.favicon = firstSiblingFavicon ?? `${service.url}/favicon.ico`;
|
||||
}
|
||||
|
||||
return { services: found, suggestedHostname };
|
||||
}
|
||||
|
||||
23
apps/backend/src/scanner/ping.ts
Normal file
23
apps/backend/src/scanner/ping.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { exec } from "node:child_process";
|
||||
import { platform } from "node:os";
|
||||
|
||||
/**
|
||||
* Prüft per System-Ping (ICMP), ob eine IP erreichbar ist. Bewusst NICHT über
|
||||
* einen Port-Connect (wie isPortOpen in ports.ts) - ein Gerät kann online
|
||||
* sein, ohne einen der bekannten Ports offen zu haben (z. B. ein Drucker
|
||||
* ohne Web-UI), ein echter Ping ist hier das treffendere Signal.
|
||||
*
|
||||
* Nutzt den System-ping-Befehl statt eines rohen ICMP-Sockets, da Node dafür
|
||||
* root-Rechte bräuchte - für einen einzelnen Zwischencheck reicht das völlig.
|
||||
* Timeout: 1 Sekunde, ein einzelnes Paket.
|
||||
*/
|
||||
export function pingHost(ip: string): Promise<boolean> {
|
||||
const isWindows = platform() === "win32";
|
||||
const command = isWindows ? `ping -n 1 -w 1000 ${ip}` : `ping -c 1 -W 1 ${ip}`;
|
||||
|
||||
return new Promise((resolve) => {
|
||||
exec(command, { timeout: 2000 }, (error) => {
|
||||
resolve(!error);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user