feat: implement multilingual SEO support and enhance map UI with data synchronization updates

This commit is contained in:
David Fencl
2026-06-06 17:24:30 +02:00
parent 66021e001e
commit 6395df1992
30 changed files with 3036 additions and 280 deletions
+28 -61
View File
@@ -78,70 +78,37 @@ async function scrapeLake(lakeId: string, oid: string, internalId: string) {
});
const records: DataRecord[] = [];
let dataTable = null;
$('table').each((i, tbl) => {
if ($(tbl).text().includes('Datum') && $(tbl).text().includes('Odtok')) {
dataTable = $(tbl);
}
});
const parseTable = (htmlContent: string) => {
const _$ = cheerio.load(htmlContent);
let dataTable = null;
_$('table').each((i, tbl) => {
if (_$(tbl).text().includes('Datum') && _$(tbl).text().includes('Odtok')) {
dataTable = _$(tbl);
if (dataTable) {
dataTable.find('tr').each((i, row) => {
if (i === 0) return; // skip header
const cols = $(row).find('td');
if (cols.length >= 3) {
const rawDate = $(cols[0]).text().trim();
const levelStr = $(cols[1]).text().trim().replace(',', '.');
let flowStr = $(cols[2]).text().trim().replace(',', '.');
if (flowStr === '' && cols.length >= 4) {
flowStr = $(cols[3]).text().trim().replace(',', '.');
}
const parsedDateStr = parseDateString(rawDate);
if (parsedDateStr) {
records.push({
timestamp: parsedDateStr,
level: parseFloat(levelStr) || 0,
flow: parseFloat(flowStr) || 0,
inflow: 0,
volume: 0
});
}
}
});
if (dataTable) {
dataTable.find('tr').each((i, row) => {
if (i === 0) return; // skip header
const cols = _$(row).find('td');
if (cols.length >= 3) {
const rawDate = _$(cols[0]).text().trim();
const levelStr = _$(cols[1]).text().trim().replace(',', '.');
let flowStr = _$(cols[2]).text().trim().replace(',', '.');
if (flowStr === '' && cols.length >= 4) {
flowStr = _$(cols[3]).text().trim().replace(',', '.');
}
const parsedDateStr = parseDateString(rawDate);
if (parsedDateStr) {
records.push({
timestamp: parsedDateStr,
level: parseFloat(levelStr) || 0,
flow: parseFloat(flowStr) || 0,
inflow: 0,
volume: 0
});
}
}
});
}
};
// 1. Zpracování týdenních dat (GET)
parseTable(response.data);
// 2. Získání a zpracování měsíčních dat (POST)
try {
const viewstate = $('#__VIEWSTATE').val();
const viewstategenerator = $('#__VIEWSTATEGENERATOR').val();
const eventvalidation = $('#__EVENTVALIDATION').val();
if (viewstate && viewstategenerator && eventvalidation) {
const postData = new URLSearchParams();
postData.append('__EVENTTARGET', 'ctl00$ObsahCPH$PrechodNaBilancniData');
postData.append('__EVENTARGUMENT', '');
postData.append('__VIEWSTATE', viewstate as string);
postData.append('__VIEWSTATEGENERATOR', viewstategenerator as string);
postData.append('__EVENTVALIDATION', eventvalidation as string);
const postRes = await axios.post(URL, postData.toString(), {
httpsAgent: agent,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
timeout: 10000
});
parseTable(postRes.data);
}
} catch (err: any) {
console.warn(`Failed to fetch monthly data for ${internalId}:`, err.message);
}
if (records.length > 0) {