From 7b6ad832a9b8d35e6a73e077272e745a06b18912 Mon Sep 17 00:00:00 2001 From: ostertun Date: Wed, 27 Apr 2022 13:13:41 +0200 Subject: [PATCH 1/3] new ranking calculation (via ranking DB table) --- client/scripts/database.js | 39 ++++++- server/content/rank.php | 20 +--- server/scripts/rank.js | 207 +++++++++++++++++++++++-------------- 3 files changed, 173 insertions(+), 93 deletions(-) diff --git a/client/scripts/database.js b/client/scripts/database.js index f3fe2a5..acd44f8 100644 --- a/client/scripts/database.js +++ b/client/scripts/database.js @@ -1,4 +1,4 @@ -const DB_VERSION = 7; +const DB_VERSION = 8; const USER_ID = localStorage.getItem('auth_user'); const USER_NAME = localStorage.getItem('auth_username'); @@ -262,6 +262,9 @@ function dbGetRanking(minDate, maxDate, maxAge, ageStrict, altM = 9, ageCrew = f return new Promise(async function(resolve) { var rankNoResults = []; + // TODO: remove / Abwärtskompatibilität + //if (maxAge === true) maxAge = await dbGetClassProp('youth-age'); + var sailors = await dbGetData('sailors'); var regattas = await dbGetRegattasRange(minDate, maxDate); @@ -570,7 +573,7 @@ function sync() { localTimes[entry['table']] = entry['time']; }); - syncInProgress = 12; + syncInProgress = 13; var syncOkay = true; log("[db] Sync Start"); $('#i-sync').addClass('fa-spin'); @@ -618,6 +621,33 @@ function sync() { } }); + // RANKINGS + getJSON(QUERY_URL + 'get_rankings', function (code, data) { + if (code == 200) { + var os = db.transaction('rankings', 'readwrite').objectStore('rankings'); + data.data.forEach(function (entry) { + os.put(entry); + }); + os.openCursor().onsuccess = function (event) { + var cursor = event.target.result; + if (cursor) { + if (!data.keys.includes(parseInt(cursor.key))) { + os.delete(cursor.key); + } + cursor.continue(); + } else { + syncInProgress --; + log('[db] rankings synced, remaining:', syncInProgress); + } + }; + } else { + log("[db] rankings: Something went wrong (HTTP " + code + ")"); + syncOkay = false; + syncInProgress --; + log('[db] rankings failed, remaining:', syncInProgress); + } + }); + // CLUBS if (localTimes['clubs'] < serverTimes['clubs']) { getJSON(QUERY_URL + 'get_clubs?changed-after=' + localTimes['clubs'], function (code, data) { @@ -1155,6 +1185,11 @@ function initDatabase() { var osClass = db.createObjectStore('class', { keyPath: 'key' }); } + if ((oldVersion < 8) && (newVersion >= 8)) { + log('[db] to version 8'); + var osRankings = db.createObjectStore('rankings', { keyPath: 'id' }); + } + // Force resync after db update if (oldVersion >= 1) { var osUpdateTimes = upgradeTransaction.objectStore('update_times'); diff --git a/server/content/rank.php b/server/content/rank.php index 6fcf207..e3bf140 100644 --- a/server/content/rank.php +++ b/server/content/rank.php @@ -7,28 +7,18 @@ // Title, Inputs $content = "

Ranglisten

"; - $options = ''; -// $options .= ''; -// $options .= ''; -// $options .= ''; - $content .= $tpl->load('select', ['html-id' => 'select-type', 'placeholder' => 'Rangliste', 'options' => $options, 'css-class' => 'mt-3 mb-0']); $content .= $tpl->load('select', ['html-id' => 'select-year', 'placeholder' => 'Jahr', 'css-class' => 'mt-3 mb-0']); + $content .= $tpl->load('select', ['html-id' => 'select-type', 'placeholder' => 'Rangliste', 'css-class' => 'mt-3 mb-0']); $content .= $tpl->load('input', ['html-id' => 'input-from', 'placeholder' => 'Von', 'type' => 'date', 'css-class' => 'mt-3']); $content .= $tpl->load('input', ['html-id' => 'input-to', 'placeholder' => 'Bis', 'type' => 'date']); - $chbox = $tpl->load('checkbox', ['html-id' => 'input-jugend', 'placeholder' => 'Jugend']); - $content .= '
' . $chbox . '
'; - $chbox = $tpl->load('checkbox', ['html-id' => 'input-jugstrict', 'placeholder' => 'Streng']); - $content .= '
' . $chbox . '
'; + $content .= $tpl->load('input', ['html-id' => 'input-altm', 'placeholder' => 'alt. m', 'type' => 'number']); + $content .= $tpl->load('input', ['html-id' => 'input-maxage', 'placeholder' => 'max. Alter (leer = nicht prüfen)', 'type' => 'number']); + $content .= $tpl->load('checkbox', ['html-id' => 'input-agestrict', 'placeholder' => 'unb. Jahrgänge ausschließen']); + $content .= $tpl->load('checkbox', ['html-id' => 'input-agecrew', 'placeholder' => 'Crew auch prüfen']); $content .= $tpl->load('button', ['Anzeigen', '#', 'html-id' => 'button-show']); $sp['output'] .= $tpl->load('card', [$content]); -// TODO -$content = '

Störung

'; -$content .= '

Momentan können wir Dir hier leider nur die Jahresrangliste anzeigen.
'; -$content .= 'Um die anderen Ranglisten zu sehen, besuche bitte unsere Webseite.

'; -$sp['output'] .= $tpl->load('card', [$content]); - // No Results $content = '

ACHTUNG

'; $content .= '

Zu folgenden Regatten wurden noch keine Ergebnisse hinterlegt:

'; diff --git a/server/scripts/rank.js b/server/scripts/rank.js index c90e55d..7b7713f 100644 --- a/server/scripts/rank.js +++ b/server/scripts/rank.js @@ -106,38 +106,67 @@ async function onRankingClicked(id) { $('#menu-rank').scrollTop(0); } +var rankings; + async function selectChange(callSiteScript = true) { - var type = $('#select-type').val(); - var year = parseInt($('#select-year').val()); - if (type == "user") { - $('#select-year').parent().hide(); + var year = $('#select-year').val(); + if (year == "user") { + $('#select-type').parent().hide(); $('#input-from').trigger('focusin').trigger('focusout').parent().show(); $('#input-to').trigger('focusin').trigger('focusout').parent().show(); - $('#input-jugend').parent().parent().show(); - $('#input-jugstrict').parent().parent().show(); + $('#input-altm').trigger('focusin').trigger('focusout').parent().show(); + $('#input-maxage').trigger('focusin').trigger('focusout').parent().show(); + $('#input-agestrict').parent().show(); + $('#input-agecrew').parent().show(); $('#button-show').show(); } else { - $('#select-year').parent().show(); + year = parseInt(year); + var type = $('#select-type').val(); + console.log('[rank] selected', year, type); + $('#select-type').parent().show(); $('#input-from').parent().hide(); $('#input-to').parent().hide(); - $('#input-jugend').parent().parent().hide(); - $('#input-jugstrict').parent().parent().hide(); + $('#input-altm').parent().hide(); + $('#input-maxage').parent().hide(); + $('#input-agestrict').parent().hide(); + $('#input-agecrew').parent().hide(); $('#button-show').hide(); - var from, to, jugend, jugstrict; - switch (type) { + var rankingsShow = {}; + var options = ''; + for (var i in rankings) { + if (rankings[i].year_from !== null && rankings[i].year_from > year) continue; + if (rankings[i].year_to !== null && rankings[i].year_to < year) continue; + var alias = rankings[i].alias; + options += ''; + rankingsShow[alias] = rankings[i]; + } + $('#select-type').html(options); + if (!(type in rankingsShow)) { + console.log('[rank] selected type', type, 'not found for year', year, '. Using `year`'); + type = 'year'; + } + $('#select-type').val(type).trigger('focusin').trigger('focusout'); + + var from, to, altm, maxage, agestrict, agecrew; + altm = 9; maxage = false; agestrict = false; agecrew = false; + var r = rankingsShow[type]; + console.log('[rank] type', type, '=>', r); + if (r.max_age !== null) { + maxage = r.max_age; + agestrict = r.age_strict == 1; + agecrew = r.age_crew == 1; + } + if (r.alt_m !== null) { + altm = r.alt_m; + } + switch (r.type) { case 'year': from = (year - 1) + '-12-01'; to = year + '-11-30'; - jugend = jugstrict = false; break; - case 'youth': - from = (year - 1) + '-12-01'; - to = year + '-11-30'; - jugend = jugstrict = true; - break; - case 'idjm': - var youthGermanName = await dbGetClassProp('youth-german-name'); + case 'quali': + // TODO: auslagern in function getRegattaBegin var beginn = null; var regattas = await dbGetData('regattas'); regattas.sort(function(a,b){ return b.date.localeCompare(a.date); }); @@ -147,12 +176,13 @@ async function selectChange(callSiteScript = true) { if ((date < parseDate('01.01.' + year)) || (date > parseDate('31.12.' + year))) { continue; } - if (regatta.name.indexOf(youthGermanName) >= 0) { + if (regatta.name.indexOf(r.quali_search) >= 0) { beginn = ((regatta.meldungSchluss != null) ? parseDate(regatta.meldungSchluss) : date); break; } } - if (beginn != null) { + // END OF TODO + if (beginn !== null) { from = new Date(beginn); from.setFullYear(from.getFullYear() - 1); from.setDate(from.getDate() - 13); @@ -160,23 +190,28 @@ async function selectChange(callSiteScript = true) { to = new Date(beginn); to.setDate(to.getDate() - 14); to = formatDate('Y-m-d', to); - jugend = true; - jugstrict = false; } else { - $('#div-rank').html('Keine ' + youthGermanName + ' gefunden!'); - $('#input-search').parent().hide(); - return; + from = (year - 1) + '-12-01'; + to = year + '-11-30'; + break; // TODO: bessere Fehlermeldung - keine Regatta gefunden } break; + default: // TODO: bessere Fehlermeldung - tritt nur bei Fehlkonfiguration in DB auf + from = (year - 1) + '-12-01'; + to = year + '-11-30'; + break; } + console.log('[rank] setting', from, to, altm, maxage, agestrict, agecrew); $('#input-from').val(from); $('#input-to').val(to); - $('#input-jugend').prop('checked', jugend); - $('#input-jugstrict').prop('checked', jugstrict); + $('#input-altm').val(altm); + $('#input-maxage').val(maxage == false ? '' : maxage); + $('#input-agestrict').prop('checked', agestrict); + $('#input-agecrew').prop('checked', agecrew); if (callSiteScript && (typeof siteScript === 'function')) { - history.replaceState(null, '', '?type=' + type + '&year=' + year); + history.replaceState(null, '', '?year=' + year + '&type=' + type); showLoader(); siteScript(); } @@ -185,40 +220,65 @@ async function selectChange(callSiteScript = true) { function buttonShowPressed() { if (typeof siteScript === 'function') { - var chboxes = ''; - if ($('#input-jugend').prop('checked')) chboxes += '&jugend=on' - if ($('#input-jugstrict').prop('checked')) chboxes += '&jugstrict=on' - history.replaceState(null, '', '?type=user&from=' + $('#input-from').val() + "&to=" + $('#input-to').val() + chboxes) + var additional = ''; + if ($('#input-maxage').val() != '') additional += '&maxage=' + $('#input-maxage').val(); + if ($('#input-agestrict').prop('checked')) additional += '&agestrict=on'; + if ($('#input-agecrew').prop('checked')) additional += '&agecrew=on'; + history.replaceState(null, '', '?year=user&from=' + $('#input-from').val() + "&to=" + $('#input-to').val() + "&altm=" + $('#input-altm').val() + additional) showLoader(); siteScript(); } } function initSelects() { - var type = findGetParameter('type'); - var year = findGetParameter('year'); - if (type === null) type = 'year'; - if (year === null) year = new Date().getFullYear(); + return new Promise(async function(resolve) { + var year = findGetParameter('year'); + var type = findGetParameter('type'); + if (year === null) year = new Date().getFullYear(); + if (type === null) type = 'year'; - $('#select-type').val(type); + var years = await dbGetData('years'); + years.sort(function (a, b) { + if (a['year'] > b['year']) return -1; + if (a['year'] < b['year']) return 1; + return 0; + }); + var yearFound = year == 'user'; + var options = ''; + for (id in years) { + var y = years[id]['year']; + options += ''; + if (year == y) yearFound = true; + } + $('#select-year').html(options); + $('#select-year').val(yearFound ? year : years[0]); - $('#select-year').html(''); - $('#select-year').val(year); + $('#select-type').html(''); + $('#select-type').val(type); - if (type == "user") { - var from = findGetParameter('from'); - var to = findGetParameter('to'); - if (from === null) from = formatDate('Y-m-d') - if (to === null) to = formatDate('Y-m-d') - $('#input-from').val(from).trigger('focusin').trigger('focusout'); - $('#input-to').val(to).trigger('focusin').trigger('focusout'); - var jugend = findGetParameter('jugend'); - var jugstrict = findGetParameter('jugstrict'); - $('#input-jugend').prop('checked', jugend !== null); - $('#input-jugstrict').prop('checked', jugstrict !== null); - } + if (year == "user") { + var from = findGetParameter('from'); + var to = findGetParameter('to'); + if (from === null) from = formatDate('Y-m-d'); + if (to === null) to = formatDate('Y-m-d'); + $('#input-from').val(from).trigger('focusin').trigger('focusout'); + $('#input-to').val(to).trigger('focusin').trigger('focusout'); + var altm = findGetParameter('altm'); + if (altm === null) altm = 9; + $('#input-altm').val(altm).trigger('focusin').trigger('focusout'); + var maxage = findGetParameter('maxage'); + if (maxage === null) maxage = ''; + $('#input-maxage').val(maxage).trigger('focusin').trigger('focusout'); + var agestrict = findGetParameter('agestrict'); + var agecrew = findGetParameter('agecrew'); + $('#input-agestrict').prop('checked', agestrict !== null); + $('#input-agecrew').prop('checked', agecrew !== null); + } - selectChange(false); + selectChange(false); + + resolve(); + }); } var firstCall = true; @@ -231,7 +291,12 @@ async function drawList () { var list = ''; rows.forEach(function (entry) { if (entry == null) { - list += '
Ende der Rangliste gemäß DSV-Ranglistenverordnung (min. m = 9 Wertungen)
'; + var altm = $('#input-altm').val(); if (altm == '') altm = 9; else altm = parseInt(altm); + if (altm == 9) { + list += '
Ende der Rangliste gemäß DSV-Ranglistenverordnung (min. m = 9 Wertungen)
'; + } else { + list += '
Ende der Rangliste (min. m = ' + altm + ' Wertungen)
'; + } } else if (search($('#input-search').val(), entry.keywords)) { list += entry.content; } @@ -243,27 +308,31 @@ async function drawList () { var siteScript = async function() { if (firstCall) { firstCall = false; - initSelects(); - $('#select-type').change(selectChange); + rankings = await dbGetData('rankings'); + await initSelects(); $('#select-year').change(selectChange); + $('#select-type').change(selectChange); $('#button-show').click(buttonShowPressed); $('#input-search').on('input', drawList); } var minDate = parseDate($('#input-from').val()); var maxDate = parseDate($('#input-to').val()); - var jugend = $('#input-jugend').prop('checked'); - var jugstrict = $('#input-jugstrict').prop('checked'); - var dbRanking = await dbGetRanking(minDate, maxDate, jugend, jugstrict); + var altm = $('#input-altm').val(); if (altm == '') altm = 9; else altm = parseInt(altm); + var maxage = $('#input-maxage').val(); if (maxage == '') maxage = false; else maxage = parseInt(maxage); + var agestrict = $('#input-agestrict').prop('checked'); + var agecrew = $('#input-agecrew').prop('checked'); + console.log('[rank] rank params:', minDate, maxDate, altm, maxage, agestrict, agecrew); + var dbRanking = await dbGetRanking(minDate, maxDate, maxage, agestrict, altm, agecrew); ranking = dbRanking[0]; - lastRanking = null; + lastRanking = null; // TODO: also for quali ranks if (($('#select-type').val() == 'year') || ($('#select-type').val() == 'youth')) { lastRanking = {}; var lYear = parseInt($('#select-year').val()) - 1; var lMinDate = parseDate((lYear - 1) + '-12-01'); var lMaxDate = parseDate(lYear + '-11-30'); - var lDbRanking = (await dbGetRanking(lMinDate, lMaxDate, jugend, jugstrict))[0]; + var lDbRanking = (await dbGetRanking(lMinDate, lMaxDate, maxage, agestrict, altm, agecrew))[0]; for (var i in lDbRanking) { lastRanking[lDbRanking[i].id] = lDbRanking[i].rank; } @@ -271,20 +340,6 @@ var siteScript = async function() { var selectedYear = $('#select-year').val(); - var years = await dbGetData('years'); - years.sort(function (a, b) { - if (a['year'] > b['year']) return -1; - if (a['year'] < b['year']) return 1; - return 0; - }); - var options = ''; - for (id in years) { - var year = years[id]['year']; - options += ''; - } - $('#select-year').html(options); - $('#select-year').val(selectedYear); - if (dbRanking[1].length > 0) { $('#card-noresults').show(); list = ''; @@ -326,7 +381,7 @@ var siteScript = async function() { if (entry['year'] != null) row.keywords.push(entry['year']); if (club != null) row.keywords.push(club['kurz'], club['name']); - if (!dsvEnd && (entry.m < 9)) { + if (!dsvEnd && (entry.m < altm)) { rows.push(null); dsvEnd = true; } From 2014303fae18375fda8d38c16ef04bcec88ab289 Mon Sep 17 00:00:00 2001 From: ostertun Date: Wed, 27 Apr 2022 13:34:26 +0200 Subject: [PATCH 2/3] added special rank links --- server/content/rank.php | 3 +++ server/scripts/rank.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/server/content/rank.php b/server/content/rank.php index e3bf140..76527ff 100644 --- a/server/content/rank.php +++ b/server/content/rank.php @@ -19,6 +19,9 @@ $sp['output'] .= $tpl->load('card', [$content]); + // Sepcial ranks + $sp['output'] .= $tpl->load('card', ['', 'html-id' => 'card-special-ranks']); + // No Results $content = '

ACHTUNG

'; $content .= '

Zu folgenden Regatten wurden noch keine Ergebnisse hinterlegt:

'; diff --git a/server/scripts/rank.js b/server/scripts/rank.js index 7b7713f..a6416f4 100644 --- a/server/scripts/rank.js +++ b/server/scripts/rank.js @@ -119,6 +119,7 @@ async function selectChange(callSiteScript = true) { $('#input-agestrict').parent().show(); $('#input-agecrew').parent().show(); $('#button-show').show(); + $('#card-special-ranks').hide(); } else { year = parseInt(year); var type = $('#select-type').val(); @@ -131,6 +132,7 @@ async function selectChange(callSiteScript = true) { $('#input-agestrict').parent().hide(); $('#input-agecrew').parent().hide(); $('#button-show').hide(); + $('#card-special-ranks').hide(); // first hide, show only when there are special ranks var rankingsShow = {}; var options = ''; @@ -148,6 +150,33 @@ async function selectChange(callSiteScript = true) { } $('#select-type').val(type).trigger('focusin').trigger('focusout'); + // special ranks + getJSON(QUERY_URL + 'get_special_rankings', function (code, data) { + if (code == 200) { + var specialRanks = []; + for (var i in data.data) { + var sr = data.data[i]; + if (sr.to < (year + '-01-01')) continue; + if (sr.to > (year + '-12-31')) continue; + specialRanks.push(sr); + } + if (specialRanks.length > 0) { + var btns = ''; + for (var i in specialRanks) { + var sr = specialRanks[i]; + var link = 'https://regatten.net/frame.php?class=' + BOATCLASS + '&site=special_rank&rank_id=' + sr.id; + var name = sr.title; + var cssclass = i > 0 ? ' mt-3' : ''; + btns += '' + name + ''; + } + $('#card-special-ranks').find('.content').html(btns); + $('#card-special-ranks').show(); + } + } else { + log("[rank] special_ranks: Something went wrong (HTTP " + code + ")"); + } + }); + var from, to, altm, maxage, agestrict, agecrew; altm = 9; maxage = false; agestrict = false; agecrew = false; var r = rankingsShow[type]; From 1fc7b8fe6d73e4374c59ca85cced1b07fb56d3ca Mon Sep 17 00:00:00 2001 From: ostertun Date: Wed, 27 Apr 2022 13:35:06 +0200 Subject: [PATCH 3/3] gitflow-release-stash: v_1.11.7 --- server/version.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/version.php b/server/version.php index abe2df7..9cdb496 100644 --- a/server/version.php +++ b/server/version.php @@ -1,5 +1,5 @@