Uhrzeit des letzten PGN-Updates und Countdown bis zum nächsten Update
This commit is contained in:
24
app.js
24
app.js
@@ -13,6 +13,7 @@ let currentGame = null;
|
|||||||
let allLaraGames = [];
|
let allLaraGames = [];
|
||||||
let refreshTimer = null;
|
let refreshTimer = null;
|
||||||
let countdown = 0;
|
let countdown = 0;
|
||||||
|
let serverLastFetch = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lädt die PGN-Datei und aktualisiert die Anzeige
|
* Lädt die PGN-Datei und aktualisiert die Anzeige
|
||||||
@@ -22,12 +23,19 @@ async function loadPGN() {
|
|||||||
hideError();
|
hideError();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Lokaler Proxy-Server (python server.py)
|
const [pgnResponse, statusResponse] = await Promise.all([
|
||||||
const response = await fetch('http://localhost:8111/pgn');
|
fetch('http://localhost:8111/pgn'),
|
||||||
|
fetch('http://localhost:8111/status').catch(() => null)
|
||||||
|
]);
|
||||||
|
|
||||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
if (!pgnResponse.ok) throw new Error(`HTTP ${pgnResponse.status}`);
|
||||||
|
|
||||||
const pgnText = await response.text();
|
if (statusResponse && statusResponse.ok) {
|
||||||
|
const status = await statusResponse.json();
|
||||||
|
serverLastFetch = status.last_fetch ? status.last_fetch * 1000 : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pgnText = await pgnResponse.text();
|
||||||
const allGames = parsePGN(pgnText);
|
const allGames = parsePGN(pgnText);
|
||||||
allLaraGames = filterLaraGames(allGames);
|
allLaraGames = filterLaraGames(allGames);
|
||||||
|
|
||||||
@@ -278,9 +286,9 @@ function formatClock(clockStr) {
|
|||||||
* Update timestamp
|
* Update timestamp
|
||||||
*/
|
*/
|
||||||
function updateTimestamp() {
|
function updateTimestamp() {
|
||||||
const now = new Date();
|
const time = serverLastFetch ? new Date(serverLastFetch) : new Date();
|
||||||
document.getElementById('last-update').textContent =
|
document.getElementById('last-update').textContent =
|
||||||
`Letztes Update: ${now.toLocaleTimeString('de-DE')}`;
|
`Letztes Update: ${time.toLocaleTimeString('de-DE')}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -293,8 +301,10 @@ function startAutoRefresh() {
|
|||||||
|
|
||||||
refreshTimer = setInterval(() => {
|
refreshTimer = setInterval(() => {
|
||||||
countdown--;
|
countdown--;
|
||||||
|
const mins = Math.floor(countdown / 60);
|
||||||
|
const secs = countdown % 60;
|
||||||
document.getElementById('refresh-timer').textContent =
|
document.getElementById('refresh-timer').textContent =
|
||||||
`Nächste Aktualisierung: ${countdown}s`;
|
`Nächstes Update in: ${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
|
||||||
|
|
||||||
if (countdown <= 0) {
|
if (countdown <= 0) {
|
||||||
countdown = REFRESH_INTERVAL / 1000;
|
countdown = REFRESH_INTERVAL / 1000;
|
||||||
|
|||||||
17
server.py
17
server.py
@@ -11,6 +11,7 @@ import sys
|
|||||||
import os
|
import os
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
import json
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
PGN_URL = "https://www.deutsche-schachjugend.de/2026/odjm-d/partien/gesamt-utf8.pgn"
|
PGN_URL = "https://www.deutsche-schachjugend.de/2026/odjm-d/partien/gesamt-utf8.pgn"
|
||||||
@@ -21,13 +22,18 @@ CACHE_TTL = 30 # Sekunden
|
|||||||
|
|
||||||
os.makedirs(CACHE_DIR, exist_ok=True)
|
os.makedirs(CACHE_DIR, exist_ok=True)
|
||||||
|
|
||||||
|
last_fetch_time = None
|
||||||
|
|
||||||
|
|
||||||
def fetch_pgn():
|
def fetch_pgn():
|
||||||
"""Lädt die PGN-Datei von der URL als Bytes."""
|
"""Lädt die PGN-Datei von der URL als Bytes."""
|
||||||
|
global last_fetch_time
|
||||||
try:
|
try:
|
||||||
req = urllib.request.Request(PGN_URL, headers={"User-Agent": "Mozilla/5.0"})
|
req = urllib.request.Request(PGN_URL, headers={"User-Agent": "Mozilla/5.0"})
|
||||||
with urllib.request.urlopen(req, timeout=30) as response:
|
with urllib.request.urlopen(req, timeout=30) as response:
|
||||||
return response.read()
|
data = response.read()
|
||||||
|
last_fetch_time = time.time()
|
||||||
|
return data
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[{datetime.now().strftime('%H:%M:%S')}] Fehler beim Laden: {e}")
|
print(f"[{datetime.now().strftime('%H:%M:%S')}] Fehler beim Laden: {e}")
|
||||||
return None
|
return None
|
||||||
@@ -83,8 +89,15 @@ class PGNHandler(http.server.BaseHTTPRequestHandler):
|
|||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
self.send_header("Content-Type", "application/json")
|
self.send_header("Content-Type", "application/json")
|
||||||
self.send_header("Access-Control-Allow-Origin", "*")
|
self.send_header("Access-Control-Allow-Origin", "*")
|
||||||
|
self.send_header("Cache-Control", "no-cache")
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write(b'{"status": "ok"}')
|
status = {
|
||||||
|
"status": "ok",
|
||||||
|
"last_fetch": last_fetch_time,
|
||||||
|
"cache_ttl": CACHE_TTL,
|
||||||
|
"server_time": time.time()
|
||||||
|
}
|
||||||
|
self.wfile.write(json.dumps(status).encode())
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Statische Dateien aus dem Verzeichnis
|
# Statische Dateien aus dem Verzeichnis
|
||||||
|
|||||||
10
style.css
10
style.css
@@ -36,6 +36,16 @@ header h1 {
|
|||||||
color: #aaa;
|
color: #aaa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#last-update, #refresh-timer {
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #4ade80;
|
||||||
|
background: rgba(0, 0, 0, 0.4);
|
||||||
|
padding: 4px 10px;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid rgba(74, 222, 128, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
#refresh-btn {
|
#refresh-btn {
|
||||||
background: #e94560;
|
background: #e94560;
|
||||||
border: none;
|
border: none;
|
||||||
|
|||||||
Reference in New Issue
Block a user