Files
lara-schach-live/js/data.js

190 lines
7.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Lara Kiesewetter Live Schachturnier
* Data fetching, PGN loading, standings, auto-refresh
*/
/* global parsePGN, filterLaraGames, getLiveGame, getTodaysGames, getLatestGame */
async function fetchRoundPGN(round) {
try {
const res = await fetch(`https://www.deutsche-schachjugend.de/2026/odjm-d/partien/${round}.pgn?t=${Date.now()}`);
if (!res.ok) {
console.error(`Fehler beim Abrufen der Runde ${round}: HTTP ${res.status}`);
return null;
}
const buf = await res.arrayBuffer();
let text = new TextDecoder('utf-8').decode(buf);
if (text.includes('\uFFFD')) {
text = new TextDecoder('iso-8859-1').decode(buf);
}
return text;
} catch (error) {
console.error(`Fehler beim Abrufen der Runde ${round}:`, error);
return null;
}
}
async function loadPGN(showOverlay = true) {
const currentPollId = pollId;
if (showOverlay) showLoading(true);
hideError();
try {
if (currentRound === 0) {
if (showOverlay) showLoading(false);
return;
}
const maxRound = currentRound + 1;
const isFirstLoad = Object.keys(roundPgns).length === 0;
const startRound = isFirstLoad ? 1 : currentRound;
for (let r = startRound; r <= maxRound; r++) {
const text = await fetchRoundPGN(r);
if (currentPollId !== pollId) return;
if (text !== null) roundPgns[r] = text;
}
const combinedPgn = Object.values(roundPgns).join('\n\n');
const allGames = parsePGN(combinedPgn);
allLaraGames = filterLaraGames(allGames);
if (allLaraGames.length === 0) {
console.warn('Keine Spiele gefunden für die aktuellen Runden');
return;
}
if (!userSelectedGame) {
const liveGame = getLiveGame(allLaraGames);
const todaysGames = getTodaysGames(allLaraGames);
currentGame = liveGame || (todaysGames.length > 0 ? getLatestGame(todaysGames) : getLatestGame(allLaraGames));
} else if (currentGame) {
const updatedGame = allLaraGames.find(g =>
g.white === currentGame.white &&
g.black === currentGame.black &&
g.round === currentGame.round
);
if (updatedGame) currentGame = updatedGame;
}
updateBoard();
updatePlayerInfo();
updateMovesList();
updateAllGamesList();
updatePGNDisplay();
updateTimestamp();
showLoading(false);
} catch (error) {
if (currentPollId !== pollId) return;
console.error('Fehler beim Laden der PGN-Daten:', error);
showError('Fehler beim Aktualisieren der Daten. Bitte versuche es später erneut.');
showLoading(false);
}
}
async function updateStandings() {
try {
const res = await fetch(`https://www.deutsche-schachjugend.de/2026/odjm-d/tabelle/?t=${Date.now()}`);
if (!res.ok) {
console.error('Fehler beim Abrufen der Tabellenstände:', res.status);
throw new Error(`HTTP Fehler: ${res.status}`);
}
const html = await res.text();
const roundMatch = html.match(/Tabellenstand\s+nach\s+der\s+(\d+)\.\s*Runde/);
if (roundMatch) {
currentRound = parseInt(roundMatch[1]);
}
const rows = html.matchAll(/<tr[^>]*>(.*?)<\/tr>/gs);
for (const row of rows) {
if (!row[1].includes('Lara Kiesewetter')) continue;
const cells = row[1].matchAll(/<td[^>]*>(.*?)<\/td>/gs);
const clean = [];
for (const cell of cells) {
clean.push(cell[1].replace(/<[^>]+>/g, '').trim());
}
if (clean.length >= 9) {
const data = {
rank: clean[0],
player: 'Lara Kiesewetter',
wins: clean[5],
draws: clean[6],
losses: clean[7],
points: clean[8],
round_info: roundMatch ? `nach der ${roundMatch[1]}. Runde` : '',
round: currentRound,
};
const container = document.getElementById('standings-content');
container.innerHTML = `
<div class="standings-rank">${data.rank}.</div>
<div class="standings-rank-label"><a href="https://www.deutsche-schachjugend.de/2026/odjm-d/tabelle/" target="_blank" rel="noopener">Tabellenplatz</a></div>
<div class="standings-header">${data.round_info || 'nach Runde 1'}</div>
<div class="standings-row">
<span class="standings-label">Punkte</span>
<span class="standings-value">${data.points}</span>
</div>
<div class="standings-row">
<span class="standings-label">Siege</span>
<span class="standings-value">${data.wins}</span>
</div>
<div class="standings-row">
<span class="standings-label">Unentschieden</span>
<span class="standings-value">${data.draws}</span>
</div>
<div class="standings-row">
<span class="standings-label">Niederlagen</span>
<span class="standings-value">${data.losses}</span>
</div>
`;
return;
}
}
document.getElementById('standings-content').innerHTML = '<div class="standings-loading">Daten nicht verfügbar</div>';
} catch (error) {
console.error('Fehler beim Aktualisieren der Tabellenstände:', error);
document.getElementById('standings-content').innerHTML = '<div class="standings-loading">Daten nicht verfügbar</div>';
}
}
function updateTimestamp() {
const time = new Date();
document.getElementById('last-update').textContent =
`Letztes Update: ${time.toLocaleTimeString('de-DE')}`;
}
async function startAutoRefresh() {
clearInterval(pollInterval);
clearInterval(updateTimer);
clearInterval(standingsInterval);
const myId = ++pollId;
let lastUpdate = Date.now();
document.getElementById('refresh-timer').textContent = '0s';
document.getElementById('refresh-timer').style.color = '#4ade80';
await updateStandings();
loadPGN(true);
pollInterval = setInterval(() => {
if (pollId !== myId) { clearInterval(pollInterval); clearInterval(updateTimer); clearInterval(standingsInterval); return; }
loadPGN(false);
lastUpdate = Date.now();
}, 15000);
updateTimer = setInterval(() => {
if (pollId !== myId) { clearInterval(pollInterval); clearInterval(updateTimer); clearInterval(standingsInterval); return; }
const elapsed = Date.now() - lastUpdate;
const remaining = Math.max(0, 15000 - elapsed);
const s = Math.floor(remaining / 1000);
document.getElementById('refresh-timer').textContent = `${s}s`;
}, 1000);
standingsInterval = setInterval(() => {
if (pollId !== myId) { clearInterval(pollInterval); clearInterval(updateTimer); clearInterval(standingsInterval); return; }
updateStandings();
}, 1800000);
}