diff --git a/crawler.py b/crawler.py index 02b3563..8b711d7 100644 --- a/crawler.py +++ b/crawler.py @@ -40,6 +40,7 @@ import logging import multiprocessing as mp from collections import defaultdict from html import unescape +from pathlib import Path from urllib.parse import urljoin, urlparse, urldefrag from urllib.robotparser import RobotFileParser from dotenv import load_dotenv @@ -54,7 +55,11 @@ try: except ImportError: BeautifulSoup = None +# .env zuerst aus dem Arbeitsverzeichnis laden (Standard), zusätzlich aus +# dem Projektordner – so findet der Prozess die Konfiguration auch dann, +# wenn er von woanders gestartet wird (z. B. via systemd). load_dotenv() +load_dotenv(Path(__file__).resolve().parent / ".env") # ============================================================ diff --git a/search/api.py b/search/api.py index e4d80c3..14ac90f 100644 --- a/search/api.py +++ b/search/api.py @@ -198,10 +198,11 @@ function urlFor(page) { } function render(data) { + const query = data.query || ""; meta.textContent = data.total ? data.total + " Ergebnisse in " + data.took_ms + " ms" + (data.pages > 1 ? " – Seite " + data.page + "/" + data.pages : "") - : "Keine Ergebnisse für „" + data.query + "“"; + : "Keine Ergebnisse für „" + query + "“"; results.innerHTML = ""; @@ -271,8 +272,31 @@ function render(data) { } } +function showError(message) { + meta.textContent = message; + results.innerHTML = ""; + pagination.innerHTML = ""; +} + async function loadPage(page) { - const response = await fetch(urlFor(page)); + let response; + try { + response = await fetch(urlFor(page)); + } catch (e) { + showError("Suche fehlgeschlagen – Server nicht erreichbar."); + return; + } + + if (!response.ok) { + let message = "Suche fehlgeschlagen (HTTP " + response.status + ")."; + try { + const err = await response.json(); + if (err && err.error) message = err.error; + } catch (e) { /* Antwort war kein JSON */ } + showError(message); + return; + } + const data = await response.json(); currentPage = data.page; render(data); diff --git a/search/engine.py b/search/engine.py index f5504d2..2970a1d 100644 --- a/search/engine.py +++ b/search/engine.py @@ -35,12 +35,17 @@ import os import re import time from dataclasses import dataclass, field +from pathlib import Path from typing import List, Optional, Tuple from dotenv import load_dotenv import psycopg2 +# .env zuerst aus dem Arbeitsverzeichnis laden (Standard), zusätzlich aus +# dem Projektordner – so findet der Prozess die Konfiguration auch dann, +# wenn er von woanders gestartet wird (z. B. via systemd). load_dotenv() +load_dotenv(Path(__file__).resolve().parent.parent / ".env") # ============================================================ # KONFIGURATION