index fertig bis auf rank
This commit is contained in:
@@ -27,13 +27,6 @@
|
||||
define('DB_TABLE_NEWS', 'news');
|
||||
define('DB_TABLE_UPDATETIMES', '_updatetimes');
|
||||
|
||||
// PERMISSIONS
|
||||
define('PERM_ALL', 0);
|
||||
define('PERM_REGISTERED', 1);
|
||||
define('PERM_READ', 2);
|
||||
define('PERM_WRITE', 4);
|
||||
define('PERM_ADMIN', 8);
|
||||
|
||||
// OUTGOING MAILS - Credentials for outgoing mails
|
||||
define('MAIL_SMTP_HOST', 'ssl://ostertun.net'); // SMTP Server address
|
||||
define('MAIL_SMTP_PORT', 465); // port to use
|
||||
|
||||
450
api/functions.php
Normal file
450
api/functions.php
Normal file
@@ -0,0 +1,450 @@
|
||||
<?php
|
||||
|
||||
function get_db_entry($mysqli, $table, $id = false, $order = false) {
|
||||
if ($id === false) {
|
||||
return db_get_data($mysqli, $table, '*', ($order !== false ? ('1=1 ORDER BY ' . $order) : false));
|
||||
} else {
|
||||
$result = db_get_data($mysqli, $table, '*', '`id` = "' . mysqli_real_escape_string($mysqli, $id) . '"', 1);
|
||||
if (($result === false) or (count($result) != 1))
|
||||
return false;
|
||||
else
|
||||
return array_values($result)[0];
|
||||
}
|
||||
}
|
||||
|
||||
function get_club($mysqli, $id = false) {
|
||||
return get_db_entry($mysqli, DB_TABLE_CLUBS, $id, '`kurz` ASC');
|
||||
}
|
||||
|
||||
function get_boat($mysqli, $id = false) {
|
||||
return get_db_entry($mysqli, BOATCLASS . DB_TABLE_SUFFIX_BOATS, $id, '`sailnumber` ASC');
|
||||
}
|
||||
|
||||
function get_sailor($mysqli, $id = false) {
|
||||
return get_db_entry($mysqli, BOATCLASS . DB_TABLE_SUFFIX_SAILORS, $id, '`name` ASC');
|
||||
}
|
||||
|
||||
function get_planning($mysqli, $userId = false, $regattaId = false) {
|
||||
$where = '';
|
||||
$limit = false;
|
||||
if ($userId !== false) {
|
||||
$where .= '(`user`="' . mysqli_real_escape_string($mysqli, $userId) . '")';
|
||||
}
|
||||
if (($userId !== false) and ($regattaId !== false)) {
|
||||
$where .= ' AND ';
|
||||
$limit = 1;
|
||||
}
|
||||
if ($regattaId !== false) {
|
||||
$where .= '(`regatta`="' . mysqli_real_escape_string($mysqli, $regattaId) . '")';
|
||||
}
|
||||
if ($where == '') $where = false;
|
||||
if ($limit === false) {
|
||||
return db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_PLANNING, '*', $where);
|
||||
} else {
|
||||
$result = db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_PLANNING, '*', $where, 1);
|
||||
if (($result === false) or (count($result) != 1))
|
||||
return false;
|
||||
else
|
||||
return array_values($result)[0];
|
||||
}
|
||||
}
|
||||
|
||||
function get_regatta($mysqli, $id = false) {
|
||||
return get_db_entry($mysqli, BOATCLASS . DB_TABLE_SUFFIX_REGATTAS, $id, '`date` ASC');
|
||||
}
|
||||
|
||||
function get_result($mysqli, $regattaId = false) {
|
||||
if ($regattaId === false) {
|
||||
return db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_RESULTS);
|
||||
} else {
|
||||
return db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_RESULTS, '*', '`regatta` = "' . mysqli_real_escape_string($mysqli, $regattaId) . '"');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function get_regattas_range($mysqli, $from, $to) {
|
||||
return db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_REGATTAS, '*', '(`date` >= "' . date('Y-m-d', $from) . '") AND (`date` <= "' . date('Y-m-d', $to) . '") ORDER BY `date`');
|
||||
}
|
||||
|
||||
function get_regatta_years($mysqli) {
|
||||
$query = 'SELECT DISTINCT(YEAR(`date`)) as year FROM ' . BOATCLASS . DB_TABLE_SUFFIX_REGATTAS . ' ORDER BY `date`;';
|
||||
$response = mysqli_query($mysqli, $query);
|
||||
|
||||
if ($response !== false) {
|
||||
$result = array();
|
||||
if ($response->num_rows > 0) {
|
||||
while ($row = $response->fetch_assoc()) {
|
||||
$result[] = $row['year'];
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
} else {
|
||||
logE("functions", "get_data\nInvalid request\n" . $query . "\n" . mysqli_error($mysqli));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function get_result_calculated($mysqli, $regatta_id) {
|
||||
$regatta = get_regatta($mysqli, $regatta_id);
|
||||
if ($regatta === false) {
|
||||
return false;
|
||||
}
|
||||
$results = get_result($mysqli, $regatta_id);
|
||||
if ($results !== false) {
|
||||
|
||||
// *** Replace , with .
|
||||
foreach ($results as $key => $value) {
|
||||
for ($i = 1; $i <= $regatta['races']; $i ++) {
|
||||
$results[$key]['race' . $i] = str_replace(',', '.', $results[$key]['race' . $i]);
|
||||
}
|
||||
}
|
||||
|
||||
// *** Calculation ***
|
||||
$gemeldet = count($results);
|
||||
|
||||
$sortarray = array();
|
||||
foreach ($results as $key => $value) {
|
||||
$results[$key]['finished'] = false;
|
||||
$results[$key]['values'] = array();
|
||||
$results[$key]['values_all'] = array();
|
||||
$results[$key]['texts'] = array();
|
||||
$copy = array();
|
||||
for ($i = 1; $i <= $regatta['races']; $i ++) {
|
||||
if (is_numeric($value['race' . $i])) {
|
||||
$results[$key]['values'][$i] = $value['race' . $i];
|
||||
$results[$key]['texts'][$i] = $value['race' . $i];
|
||||
$copy[$i] = $value['race' . $i];
|
||||
$results[$key]['finished'] = true;
|
||||
} else {
|
||||
switch ($value['race' . $i]) {
|
||||
// Nicht gestartet
|
||||
case 'DNC': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; break; // Did not come
|
||||
case 'DNS': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; break; // Did not started
|
||||
// Startfehler
|
||||
case 'OCS': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; /*$results[$key]['finished'] = true;*/ break; // On course site
|
||||
// Muss v. Hand case 'ZFP': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; $results[$key]['finished'] = true; break; // Z-Flag penalty (20% nach 30.2)
|
||||
case 'UFD': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; /*$results[$key]['finished'] = true;*/ break; // Uniform Flag Disqualified (disqu. nach 30.3)
|
||||
case 'BFD': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; /*$results[$key]['finished'] = true;*/ break; // Black Flag Disqualified (disqu. nach 30.4)
|
||||
// Nicht durch Ziel gegangen
|
||||
case 'DNF': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; break; // Did not finish
|
||||
case 'RET': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; break; // Retired (Aufgegeben)
|
||||
case 'RAF': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; /*$results[$key]['finished'] = true;*/ break; // Retired after finish
|
||||
// Disqualifizierun
|
||||
case 'DSQ': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; /*$results[$key]['finished'] = true;*/ break; // Disqualified
|
||||
case 'DNE': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = -1; /*$results[$key]['finished'] = true;*/ break; // Disqualified, not excludable (disqu. kann nach 90.3(b) nicht gestrichen werden)
|
||||
case 'DGM': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = -2; /*$results[$key]['finished'] = true;*/ break; // Disqualification Gross Missconduct (kann nach 69.1(b)(2) nicht gestr. werden, grobes Fehlverhalten)
|
||||
// Wiedergutmachung
|
||||
// Muss v. Hand case 'RDG': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; $results[$key]['finished'] = true; break; // Redress given (Wiedergutmachung gewährt)
|
||||
// Strafen
|
||||
// Muss v. Hand case 'SCP': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; $results[$key]['finished'] = true; break; // Wertungsstrafe nach 44.3(a) (20%)
|
||||
// Muss v. Hand case 'DPI': $results[$key]['values'][$i] = $gemeldet + 1; $copy[$i] = $gemeldet + 1; $results[$key]['finished'] = true; break; // Punktstrafe nach Ermessen der Jury
|
||||
// Unbekannt
|
||||
default: $results[$key]['values'][$i] = 0; $copy[$i] = 0; break;
|
||||
}
|
||||
|
||||
if ($results[$key]['values'][$i] != 0) {
|
||||
$results[$key]['texts'][$i] = $value['race' . $i] . ' (' . $results[$key]['values'][$i] . ')';
|
||||
} else {
|
||||
$results[$key]['texts'][$i] = $value['race' . $i] . ' (Unknown - 0)';
|
||||
}
|
||||
}
|
||||
}
|
||||
$results[$key]['values_all'] = $results[$key]['values'];
|
||||
for ($s = 0; $s < $regatta['streicher']; $s ++) {
|
||||
$max = max($copy);
|
||||
for ($i = 1; $i <= $regatta['races']; $i ++) {
|
||||
if ($copy[$i] == $max) {
|
||||
$copy[$i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$brutto = $netto = 0;
|
||||
for ($i = 1; $i <= $regatta['races']; $i ++) {
|
||||
$brutto += $results[$key]['values_all'][$i];
|
||||
if ($copy[$i] == -1) { $results[$key]['values'][$i] = $gemeldet + 1; }
|
||||
elseif ($copy[$i] == -2) { $results[$key]['values'][$i] = $gemeldet + 1; }
|
||||
else { $results[$key]['values'][$i] = $copy[$i]; }
|
||||
if ($results[$key]['values'][$i] == 0) {
|
||||
$results[$key]['texts'][$i] = '[' . $results[$key]['texts'][$i] . ']';
|
||||
}
|
||||
$netto += $results[$key]['values'][$i];
|
||||
}
|
||||
$results[$key]['brutto'] = $brutto;
|
||||
$results[$key]['netto'] = $netto;
|
||||
|
||||
if ($results[$key]['finished']) {
|
||||
$sortarray[$key] = 0;
|
||||
} else {
|
||||
$sortarray[$key] = 1;
|
||||
}
|
||||
$sortarray[$key] /*.*/= sprintf("%08.2f", $netto);
|
||||
$temp = $results[$key]['values'];
|
||||
sort($temp);
|
||||
$i = 0;
|
||||
foreach ($temp as $val) {
|
||||
if ($i < $regatta['races']) {
|
||||
$sortarray[$key] .= sprintf("%07.2f", $val);
|
||||
}
|
||||
$i ++;
|
||||
}
|
||||
for ($i = $regatta['races']; $i > 0; $i --) {
|
||||
$sortarray[$key] .= sprintf("%07.2f", $results[$key]['values_all'][$i]);
|
||||
}
|
||||
$results[$key]['sortvalue'] = $sortarray[$key];
|
||||
}
|
||||
array_multisort($sortarray, $results);
|
||||
$i = 1;
|
||||
foreach ($results as $key => $value) {
|
||||
if (($i > 1) and ($sortarray[$key] == $sortarray[$lastkey])) {
|
||||
$results[$key]['place'] = $results[$lastkey]['place'];
|
||||
} else {
|
||||
$results[$key]['place'] = $i;
|
||||
}
|
||||
$i ++;
|
||||
$lastkey = $key;
|
||||
}
|
||||
unset ($sortarray);
|
||||
|
||||
return $results;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function update_result_cache($mysqli, $regatta_id) {
|
||||
$regatta = get_regatta($mysqli, $regatta_id);
|
||||
if ($regatta === false) return;
|
||||
$results = get_result_calculated($mysqli, $regatta['id']);
|
||||
if ($results === false) return;
|
||||
|
||||
// count finished boats
|
||||
$fb = 0;
|
||||
foreach ($results as $result) {
|
||||
if ($result['finished']) {
|
||||
$fb ++;
|
||||
}
|
||||
}
|
||||
|
||||
db_update_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_REGATTAS, ['finishedBoats' => $fb], '`id`="' . $regatta['id'] . '"', 1);
|
||||
|
||||
foreach ($results as $result) {
|
||||
if ($fb == 0) {
|
||||
$rlp = 0;
|
||||
} else {
|
||||
$rlp = 100 * $regatta['rlf'] * (($fb + 1 - $result['place']) / $fb);
|
||||
}
|
||||
db_update_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_RESULTS, ['place' => $result['place'], 'rlp' => $rlp], '`id`="' . $result['id'] . '"', 1);
|
||||
}
|
||||
}
|
||||
|
||||
function get_ranking($mysqli, $from, $to, $jugend = false, $jugstrict = false) {
|
||||
global $rankNoResults, $_CLASSES;
|
||||
$rankNoResults = array();
|
||||
|
||||
$sailors = get_sailor($mysqli);
|
||||
$regattas = get_regattas_range($mysqli, $from, $to);
|
||||
|
||||
if (($sailors !== false) and ($regattas !== false)) {
|
||||
foreach ($sailors as $key => $sailor) {
|
||||
$sailors[$key]['regattas'] = array();
|
||||
$sailors[$key]['tmp_rlp'] = array();
|
||||
}
|
||||
|
||||
foreach ($regattas as $regatta) {
|
||||
$date = strtotime($regatta['date']);
|
||||
|
||||
// regatta has to be min. 2 days to be ranking-regatta
|
||||
if ($regatta['length'] < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$results = get_result($mysqli, $regatta['id']);
|
||||
if ($results === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (count($results) <= 0) {
|
||||
if (strtotime('+' . ($regatta['length']-1) . ' days', $date) <= time()) {
|
||||
if (!$regatta['canceled']) {
|
||||
$rankNoResults[] = $regatta;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// in one race there must be at least 10 boats started
|
||||
$ok = false;
|
||||
for ($i = 1; $i <= $regatta['races']; $i ++) {
|
||||
$temp = 0;
|
||||
foreach ($results as $result) {
|
||||
if (($result['race' . $i] != 'DNC') and ($result['race' . $i] != 'DNS')) {
|
||||
$temp ++;
|
||||
}
|
||||
}
|
||||
if ($temp >= 10) {
|
||||
$ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$ok) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fb = $regatta['finishedBoats'];
|
||||
|
||||
// add regatta to each sailor
|
||||
foreach ($results as $result) {
|
||||
if ($result['rlp'] == 0) {
|
||||
continue;
|
||||
}
|
||||
// check if crew is youth
|
||||
//if ($jugend) {
|
||||
// $crew = explode(',', $result['crew']);
|
||||
// $okay = true;
|
||||
// foreach ($crew as $sailor) {
|
||||
// if (($sailor == '') or !isset($sailors[$sailor])) continue;
|
||||
// $sailor = $sailors[$sailor];
|
||||
// if ((($sailor['year'] !== null) and ($sailor['year'] < (date('Y', $date) - $_CLASSES[BOATCLASS]['youth-age']))) or
|
||||
// (($sailor['year'] === null) and ($jugstrict))) {
|
||||
// $okay = false;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (!$okay) continue;
|
||||
//}
|
||||
// calc m
|
||||
if ($regatta['m'] > 0) {
|
||||
$m = $regatta['m'];
|
||||
} elseif ($regatta['races'] <= 4) {
|
||||
$m = $regatta['races'];
|
||||
} else {
|
||||
if (($regatta['length'] > 2) and ($regatta['races'] >= 6)) {
|
||||
$m = 5;
|
||||
} else {
|
||||
$m = 4;
|
||||
}
|
||||
}
|
||||
$rlp = $result['rlp'];
|
||||
$sailors[$result['steuermann']]['regattas'][$regatta['id']] = array(
|
||||
'regatta' => $regatta['id'],
|
||||
'boat' => $result['boat'],
|
||||
'crew' => $result['crew'],
|
||||
'place' => $result['place'],
|
||||
'fb' => $fb,
|
||||
'rlp' => $rlp,
|
||||
'used' => 0,
|
||||
'm' => $m
|
||||
);
|
||||
for ($i = 0; $i < $m; $i ++) {
|
||||
array_push($sailors[$result['steuermann']]['tmp_rlp'], array($regatta['id'], $rlp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($sailors as $key => $sailor) {
|
||||
if ($sailor['german'] == 0) {
|
||||
unset($sailors[$key]);
|
||||
} elseif ($jugend) {
|
||||
if ((($sailor['year'] !== null) and ($sailor['year'] < (date('Y', $to) - $_CLASSES[BOATCLASS]['youth-age']))) or
|
||||
(($sailor['year'] === null) and ($jugstrict))) {
|
||||
unset($sailors[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sortarray = array();
|
||||
|
||||
foreach ($sailors as $key => $sailor) {
|
||||
// sort rlps desc
|
||||
$sort = array();
|
||||
foreach ($sailor['tmp_rlp'] as $key2 => $value) {
|
||||
$sort[$key2] = $value[1];
|
||||
}
|
||||
array_multisort($sort, SORT_DESC, $sailors[$key]['tmp_rlp']);
|
||||
// calc mean. rlp
|
||||
$sum = 0;
|
||||
$cnt = 0;
|
||||
foreach ($sailors[$key]['tmp_rlp'] as $value) {
|
||||
$sum += $value[1];
|
||||
$sailors[$key]['regattas'][$value[0]]['used'] ++;
|
||||
$cnt ++;
|
||||
if ($cnt >= 9) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
unset($sailors[$key]['tmp_rlp']);
|
||||
if ($cnt > 0) {
|
||||
$rlp = $sum / $cnt;
|
||||
$sailors[$key]['rlp'] = $rlp;
|
||||
$sailors[$key]['m'] = $cnt;
|
||||
} else {
|
||||
unset($sailors[$key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($rlp == 0) {
|
||||
$sortarray[$key] = $cnt;
|
||||
} else {
|
||||
$sortarray[$key] = $cnt * 1000 + $rlp;
|
||||
}
|
||||
}
|
||||
array_multisort($sortarray, SORT_DESC, $sailors);
|
||||
unset($sortarray);
|
||||
|
||||
$i = 1;
|
||||
foreach ($sailors as $key => $sailor) {
|
||||
$sailors[$key]['rank'] = $i;
|
||||
$i ++;
|
||||
}
|
||||
|
||||
return $sailors;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function get_trim_boat($mysqli, $id = false) {
|
||||
return get_db_entry($mysqli, DB_TABLE_TRIM_BOATS, $id);
|
||||
}
|
||||
|
||||
function get_trim_boat_users($mysqli, $id) {
|
||||
$result = db_get_data($mysqli, DB_TABLE_TRIM_USERS, '*', '`boat` = "' . mysqli_real_escape_string($mysqli, $id) . '"');
|
||||
if ($result === false)
|
||||
return false;
|
||||
else
|
||||
return $result;
|
||||
}
|
||||
|
||||
function get_trim_user_boats($mysqli, $id) {
|
||||
$boats = db_get_data($mysqli, DB_TABLE_TRIM_USERS, '*', '`user` = "' . mysqli_real_escape_string($mysqli, $id) . '"');
|
||||
if ($boats === false) {
|
||||
return false;
|
||||
} else {
|
||||
$result = [];
|
||||
foreach ($boats as $value) {
|
||||
$result[$value['boat']] = get_trim_boat($mysqli, $value['boat']);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
function trim_is_boat_user($mysqli, $user, $boat) {
|
||||
$res = db_get_data($mysqli, DB_TABLE_TRIM_USERS, '*', '`user` = "' . mysqli_real_escape_string($mysqli, $user) . '" AND `boat` = "' . mysqli_real_escape_string($mysqli, $boat) . '"');
|
||||
return ($res !== false) and (count($res) == 1);
|
||||
}
|
||||
|
||||
function get_trim_trim($mysqli, $id = false) {
|
||||
return get_db_entry($mysqli, DB_TABLE_TRIM_TRIMS, $id);
|
||||
}
|
||||
|
||||
function get_trim_boat_trims($mysqli, $id) {
|
||||
$result = db_get_data($mysqli, DB_TABLE_TRIM_TRIMS, '*', '`boat` = "' . mysqli_real_escape_string($mysqli, $id) . '"');
|
||||
if ($result === false) {
|
||||
return false;
|
||||
} else {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
357
api/index.php
357
api/index.php
@@ -5,6 +5,7 @@
|
||||
require_once(__DIR__ . '/../server/log.php');
|
||||
require_once(__DIR__ . '/database.php');
|
||||
require_once(__DIR__ . '/login.php');
|
||||
require_once(__DIR__ . '/functions.php');
|
||||
|
||||
$request = false;
|
||||
if (isset($_GET['request'])) {
|
||||
@@ -76,15 +77,14 @@
|
||||
} else {
|
||||
$user_id = false;
|
||||
}
|
||||
$perm = get_perm($mysqli, $user_id);
|
||||
|
||||
function has_perm($permission) {
|
||||
global $perm;
|
||||
return ($perm & $permission) == $permission;
|
||||
function isLoggedIn() {
|
||||
global $user_id;
|
||||
return $user_id !== false;
|
||||
}
|
||||
|
||||
function checkPermission($perm) {
|
||||
if (!has_perm($perm)) done(DONE_UNAUTHORIZED, ['error' => 'permission denied']);
|
||||
function checkLoggedIn() {
|
||||
if (!isLoggedIn()) done(DONE_UNAUTHORIZED, ['error' => 'permission denied']);
|
||||
}
|
||||
|
||||
function checkRequest($param) {
|
||||
@@ -98,6 +98,35 @@
|
||||
}, $array);
|
||||
}
|
||||
|
||||
$whereString = false;
|
||||
if (isset($_REQUEST['index'], $_REQUEST['value'])) {
|
||||
$whereString = '`' . mysqli_real_escape_string($mysqli, $_REQUEST['index']) . '`="' . mysqli_real_escape_string($mysqli, $_REQUEST['value']) . '"';
|
||||
}
|
||||
|
||||
function sendEntries($table) {
|
||||
global $mysqli, $whereString;
|
||||
$response = db_get_data($mysqli, $table, '*', $whereString);
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
$keys = array_keys($response);
|
||||
if (isset($_REQUEST['changed-after'])) {
|
||||
$response = db_get_data($mysqli, $table, '*', '`changed` > "' . mysqli_real_escape_string($mysqli, date('Y-m-d H:i:s', $_REQUEST['changed-after'])) . '"' . ($whereString ? (' AND ' . $whereString) : ''));
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
}
|
||||
$response = array_values($response);
|
||||
done(DONE_OKAY, array('data' => replaceChanged($response), 'keys' => $keys));
|
||||
}
|
||||
|
||||
function sendEntry($table) {
|
||||
global $mysqli;
|
||||
checkRequest('id');
|
||||
$response = db_get_data($mysqli, $table, '*', '`id` = "' . mysqli_real_escape_string($mysqli, $_REQUEST['id']) . '"');
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
if (count($response) != 1) done(DONE_BAD_REQUEST, ['error' => 'id not found']);
|
||||
$response = array_values($response)[0];
|
||||
unset($response['changed']);
|
||||
done(DONE_OKAY, ['data' => $response]);
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
|
||||
case 'login':
|
||||
@@ -110,11 +139,325 @@
|
||||
break;
|
||||
|
||||
case 'logout':
|
||||
checkPermission(PERM_REGISTERED);
|
||||
checkLoggedIn();
|
||||
auth_logout($mysqli, $_REQUEST['auth']['id']);
|
||||
done(DONE_OKAY);
|
||||
break;
|
||||
|
||||
case 'get_update_time':
|
||||
$times = array();
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . DB_TABLE_CLUBS . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['clubs'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . BOATCLASS . DB_TABLE_SUFFIX_BOATS . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['boats'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . BOATCLASS . DB_TABLE_SUFFIX_SAILORS . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['sailors'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . BOATCLASS . DB_TABLE_SUFFIX_REGATTAS . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['regattas'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . BOATCLASS . DB_TABLE_SUFFIX_RESULTS . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['results'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . BOATCLASS . DB_TABLE_SUFFIX_PLANNING . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['plannings'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . DB_TABLE_TRIM_BOATS . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['trim_boats'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . DB_TABLE_TRIM_USERS . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['trim_users'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . DB_TABLE_TRIM_TRIMS . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['trim_trims'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_UPDATETIMES, '`update`', '`table` = "' . DB_TABLE_USERS . '"', 1);
|
||||
if (($response !== false) and (count($response) > 0)) {
|
||||
$times['users'] = strtotime(array_values($response)[0]['update']);
|
||||
} else {
|
||||
done(DONE_DATABASE);
|
||||
}
|
||||
done(DONE_OKAY, $times);
|
||||
break;
|
||||
|
||||
case 'get_clubs':
|
||||
sendEntries(DB_TABLE_CLUBS);
|
||||
break;
|
||||
|
||||
case 'get_club':
|
||||
sendEntry(DB_TABLE_CLUBS);
|
||||
break;
|
||||
|
||||
case 'get_boats':
|
||||
sendEntries(BOATCLASS . DB_TABLE_SUFFIX_BOATS);
|
||||
break;
|
||||
|
||||
case 'get_boat':
|
||||
sendEntry(BOATCLASS . DB_TABLE_SUFFIX_BOATS);
|
||||
break;
|
||||
|
||||
case 'get_sailors':
|
||||
sendEntries(BOATCLASS . DB_TABLE_SUFFIX_SAILORS);
|
||||
break;
|
||||
|
||||
case 'get_sailor':
|
||||
sendEntry(BOATCLASS . DB_TABLE_SUFFIX_SAILORS);
|
||||
break;
|
||||
|
||||
case 'get_years':
|
||||
$response = get_regatta_years($mysqli);
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
foreach ($response as $key => $value)
|
||||
$response[$key] = ['year' => $value];
|
||||
done(DONE_OKAY, ['data' => $response]);
|
||||
break;
|
||||
|
||||
case 'get_regattas':
|
||||
sendEntries(BOATCLASS . DB_TABLE_SUFFIX_REGATTAS);
|
||||
break;
|
||||
|
||||
case 'get_regatta':
|
||||
sendEntry(BOATCLASS . DB_TABLE_SUFFIX_REGATTAS);
|
||||
break;
|
||||
|
||||
case 'get_results':
|
||||
sendEntries(BOATCLASS . DB_TABLE_SUFFIX_RESULTS);
|
||||
break;
|
||||
|
||||
case 'get_result':
|
||||
sendEntry(BOATCLASS . DB_TABLE_SUFFIX_RESULTS);
|
||||
break;
|
||||
|
||||
case 'get_plannings':
|
||||
$response = db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_PLANNING, '*', $whereString);
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
$keys = array_keys($response);
|
||||
if (isset($_REQUEST['changed-after'])) {
|
||||
$response = db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_PLANNING, '*', '`changed` > "' . mysqli_real_escape_string($mysqli, date('Y-m-d H:i:s', $_REQUEST['changed-after'])) . '"' . ($whereString ? (' AND ' . $whereString) : ''));
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
}
|
||||
$response = array_map(function ($entry) {
|
||||
global $user_id;
|
||||
if (($user_id === false) or ($entry['user'] != $user_id)) {
|
||||
unset($entry['gemeldet'], $entry['bezahlt']);
|
||||
}
|
||||
return $entry;
|
||||
}, $response);
|
||||
$response = array_values($response);
|
||||
done(DONE_OKAY, array('data' => replaceChanged($response), 'keys' => $keys));
|
||||
break;
|
||||
|
||||
case 'get_planning':
|
||||
checkRequest('id');
|
||||
$response = db_get_data($mysqli, BOATCLASS . DB_TABLE_SUFFIX_PLANNING, '*', '`id` = "' . mysqli_real_escape_string($mysqli, $_REQUEST['id']) . '"');
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
if (count($response) != 1) done(DONE_BAD_REQUEST, ['error' => 'id not found']);
|
||||
$response = array_values($response)[0];
|
||||
if (($user_id === false) or ($response['user'] != $user_id)) {
|
||||
unset($response['gemeldet'], $response['bezahlt']);
|
||||
}
|
||||
unset($response['changed']);
|
||||
done(DONE_OKAY, ['data' => $response]);
|
||||
break;
|
||||
|
||||
case 'get_trim_boats':
|
||||
checkLoggedIn();
|
||||
$users = db_get_data($mysqli, DB_TABLE_TRIM_USERS, 'boat', '`user`="' . $user_id . '"');
|
||||
$boats = implode(',', array_column($users, 'boat'));
|
||||
if ($boats == '') {
|
||||
done(DONE_OKAY, array('data' => [], 'keys' => []));
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_TRIM_BOATS, '*', '`id` IN (' . $boats . ')' . ($whereString ? (' AND ' . $whereString) : ''));
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
$keys = array_keys($response);
|
||||
if (isset($_REQUEST['changed-after'])) {
|
||||
$response = db_get_data($mysqli, DB_TABLE_TRIM_BOATS, '*', '`id` IN (' . $boats . ') AND `changed` > "' . mysqli_real_escape_string($mysqli, date('Y-m-d H:i:s', $_REQUEST['changed-after'])) . '"' . ($whereString ? (' AND ' . $whereString) : ''));
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
}
|
||||
$response = array_values($response);
|
||||
done(DONE_OKAY, array('data' => replaceChanged($response), 'keys' => $keys));
|
||||
break;
|
||||
|
||||
case 'get_trim_boat':
|
||||
checkLoggedIn();
|
||||
checkRequest('id');
|
||||
$response = db_get_data($mysqli, DB_TABLE_TRIM_BOATS, '*', '`id` = "' . mysqli_real_escape_string($mysqli, $_REQUEST['id']) . '"');
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
if (count($response) != 1) done(DONE_BAD_REQUEST, ['error' => 'id not found']);
|
||||
$response = array_values($response)[0];
|
||||
if (count(db_get_data($mysqli, DB_TABLE_TRIM_USERS, 'id', '`user`="' . $user_id . '" AND `boat`="' . $response['id'] . '"')) != 1)
|
||||
done(DONE_BAD_REQUEST, ['error' => 'id not found']);
|
||||
unset($response['changed']);
|
||||
done(DONE_OKAY, ['data' => $response]);
|
||||
break;
|
||||
|
||||
case 'get_trim_users':
|
||||
checkLoggedIn();
|
||||
$users = db_get_data($mysqli, DB_TABLE_TRIM_USERS, 'boat', '`user`="' . $user_id . '"');
|
||||
$boats = implode(',', array_column($users, 'boat'));
|
||||
if ($boats == '') {
|
||||
done(DONE_OKAY, array('data' => [], 'keys' => []));
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_TRIM_USERS, '*', '`boat` IN (' . $boats . ')' . ($whereString ? (' AND ' . $whereString) : ''));
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
$keys = array_keys($response);
|
||||
if (isset($_REQUEST['changed-after'])) {
|
||||
$response = db_get_data($mysqli, DB_TABLE_TRIM_USERS, '*', '`boat` IN (' . $boats . ') AND `changed` > "' . mysqli_real_escape_string($mysqli, date('Y-m-d H:i:s', $_REQUEST['changed-after'])) . '"' . ($whereString ? (' AND ' . $whereString) : ''));
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
}
|
||||
$response = array_values($response);
|
||||
done(DONE_OKAY, array('data' => replaceChanged($response), 'keys' => $keys));
|
||||
break;
|
||||
|
||||
case 'get_trim_user':
|
||||
checkLoggedIn();
|
||||
checkRequest('id');
|
||||
$response = db_get_data($mysqli, DB_TABLE_TRIM_USERS, '*', '`id` = "' . mysqli_real_escape_string($mysqli, $_REQUEST['id']) . '"');
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
if (count($response) != 1) done(DONE_BAD_REQUEST, ['error' => 'id not found']);
|
||||
$response = array_values($response)[0];
|
||||
if (count(db_get_data($mysqli, DB_TABLE_TRIM_USERS, 'id', '`user`="' . $user_id . '" AND `boat`="' . $response['boat'] . '"')) != 1)
|
||||
done(DONE_BAD_REQUEST, ['error' => 'id not found']);
|
||||
unset($response['changed']);
|
||||
done(DONE_OKAY, ['data' => $response]);
|
||||
break;
|
||||
|
||||
case 'get_trim_trims':
|
||||
checkLoggedIn();
|
||||
$users = db_get_data($mysqli, DB_TABLE_TRIM_USERS, 'boat', '`user`="' . $user_id . '"');
|
||||
$boats = implode(',', array_column($users, 'boat'));
|
||||
if ($boats == '') {
|
||||
done(DONE_OKAY, array('data' => [], 'keys' => []));
|
||||
}
|
||||
$response = db_get_data($mysqli, DB_TABLE_TRIM_TRIMS, '*', '`boat` IN (' . $boats . ')' . ($whereString ? (' AND ' . $whereString) : ''));
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
$keys = array_keys($response);
|
||||
if (isset($_REQUEST['changed-after'])) {
|
||||
$response = db_get_data($mysqli, DB_TABLE_TRIM_TRIMS, '*', '`boat` IN (' . $boats . ') AND `changed` > "' . mysqli_real_escape_string($mysqli, date('Y-m-d H:i:s', $_REQUEST['changed-after'])) . '"' . ($whereString ? (' AND ' . $whereString) : ''));
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
}
|
||||
$response = array_values($response);
|
||||
done(DONE_OKAY, array('data' => replaceChanged($response), 'keys' => $keys));
|
||||
break;
|
||||
|
||||
case 'get_trim_trim':
|
||||
checkLoggedIn();
|
||||
checkRequest('id');
|
||||
$response = db_get_data($mysqli, DB_TABLE_TRIM_TRIMS, '*', '`id` = "' . mysqli_real_escape_string($mysqli, $_REQUEST['id']) . '"');
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
if (count($response) != 1) done(DONE_BAD_REQUEST, ['error' => 'id not found']);
|
||||
$response = array_values($response)[0];
|
||||
if (count(db_get_data($mysqli, DB_TABLE_TRIM_USERS, 'id', '`user`="' . $user_id . '" AND `boat`="' . $response['boat'] . '"')) != 1)
|
||||
done(DONE_BAD_REQUEST, ['error' => 'id not found']);
|
||||
unset($response['changed']);
|
||||
done(DONE_OKAY, ['data' => $response]);
|
||||
break;
|
||||
|
||||
case 'get_users':
|
||||
$followFields = '';
|
||||
for ($i = 1; $i <= 5; $i ++) $followFields .= ',' . BOATCLASS . '_sailor' . $i . ' AS sailor' . $i;
|
||||
$response = db_get_data($mysqli, DB_TABLE_USERS, 'id,username,email' . $followFields, $whereString);
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
$keys = array_keys($response);
|
||||
if (isset($_REQUEST['changed-after'])) {
|
||||
$response = db_get_data($mysqli, DB_TABLE_USERS, 'id,username,email,' . $followFields, '`changed` > "' . mysqli_real_escape_string($mysqli, date('Y-m-d H:i:s', $_REQUEST['changed-after'])) . '"' . ($whereString ? (' AND ' . $whereString) : ''));
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
}
|
||||
$response = array_map(function ($entry) {
|
||||
global $user_id;
|
||||
if ($entry['id'] != $user_id) {
|
||||
$entry = ['id' => $entry['id'], 'username' => $entry['username']];
|
||||
}
|
||||
return $entry;
|
||||
}, $response);
|
||||
$response = array_values($response);
|
||||
done(DONE_OKAY, array('data' => replaceChanged($response), 'keys' => $keys));
|
||||
break;
|
||||
|
||||
case 'get_user':
|
||||
checkRequest('id');
|
||||
$followFields = '';
|
||||
for ($i = 1; $i <= 5; $i ++) $followFields .= ',' . BOATCLASS . '_sailor' . $i . ' AS sailor' . $i;
|
||||
$response = db_get_data($mysqli, DB_TABLE_USERS, 'id,username,email' . $followFields, '`id` = "' . mysqli_real_escape_string($mysqli, $_REQUEST['id']) . '"');
|
||||
if ($response === false) done(DONE_DATABASE);
|
||||
if (count($response) != 1) done(DONE_BAD_REQUEST, ['error' => 'id not found']);
|
||||
$response = array_values($response)[0];
|
||||
if ($response['id'] != $user_id) {
|
||||
$response = ['id' => $response['id'], 'username' => $response['username']];
|
||||
}
|
||||
unset($response['changed']);
|
||||
done(DONE_OKAY, ['data' => $response]);
|
||||
break;
|
||||
|
||||
case 'add_subscription':
|
||||
checkRequest('subscription');
|
||||
$data = [
|
||||
'auth' => PUSH_AUTH,
|
||||
'subscription' => $_REQUEST['subscription']
|
||||
];
|
||||
$ch = curl_init('https://push.ostertun.net/add_subscription');
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||||
$result = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
if ($result == "OK")
|
||||
done(DONE_OKAY);
|
||||
else {
|
||||
logE('add_subscription', $result);
|
||||
done(DONE_SERVER_ERROR);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'remove_subscription':
|
||||
checkRequest('subscription');
|
||||
$data = [
|
||||
'auth' => PUSH_AUTH,
|
||||
'subscription' => $_REQUEST['subscription']
|
||||
];
|
||||
$ch = curl_init('https://push.ostertun.net/remove_subscription');
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||||
$result = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
if ($result == "OK")
|
||||
done(DONE_OKAY);
|
||||
else {
|
||||
logE('remove_subscription', $result);
|
||||
done(DONE_SERVER_ERROR);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
done(DONE_BAD_REQUEST, ['error' => 'action invalid']);
|
||||
|
||||
|
||||
799
client/scripts/database.js
Normal file
799
client/scripts/database.js
Normal file
@@ -0,0 +1,799 @@
|
||||
const DB_VERSION = 3;
|
||||
|
||||
const USER_ID = localStorage.getItem('auth_user');
|
||||
const USER_NAME = localStorage.getItem('auth_username');
|
||||
|
||||
var canUseLocalDB = false;
|
||||
var syncTimer = null;
|
||||
var updateSyncStatusTimer;
|
||||
var syncInProgress = 0;
|
||||
var db;
|
||||
var user = null;
|
||||
|
||||
var getJSON = function(url, callback) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', url, true);
|
||||
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 60000;
|
||||
xhr.onload = function() {
|
||||
callback(xhr.status, xhr.response);
|
||||
};
|
||||
xhr.ontimeout = function () {
|
||||
console.log("getJSON: timeout");
|
||||
callback(0, null);
|
||||
}
|
||||
xhr.onerror = function () {
|
||||
console.log("getJSON: error");
|
||||
callback(0, null);
|
||||
}
|
||||
if (USER_ID != null) {
|
||||
authString = 'auth[id]=' + localStorage.getItem('auth_id');
|
||||
authString += '&auth[hash]=' + encodeURIComponent(localStorage.getItem('auth_hash'));
|
||||
xhr.send(authString);
|
||||
} else {
|
||||
xhr.send();
|
||||
}
|
||||
};
|
||||
|
||||
function isLoggedIn() {
|
||||
return USER_ID !== null;
|
||||
}
|
||||
|
||||
function search(string, fields) {
|
||||
var keywords = string.split(' ');
|
||||
for (kid in keywords) {
|
||||
var keyword = keywords[kid].toLowerCase();
|
||||
var found = false;
|
||||
for (fid in fields) {
|
||||
var field = fields[fid].toLowerCase();
|
||||
if (field.indexOf(keyword) >= 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function dbGetData(table, id = null) {
|
||||
return new Promise(function(resolve) {
|
||||
if (canUseLocalDB) {
|
||||
if (id == null) {
|
||||
db.transaction(table).objectStore(table).getAll().onsuccess = function (event) {
|
||||
resolve(event.target.result);
|
||||
};
|
||||
} else {
|
||||
var request = db.transaction(table).objectStore(table).get(id.toString());
|
||||
request.onsuccess = function (event) {
|
||||
resolve(typeof request.result != 'undefined' ? request.result : null);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (id == null) {
|
||||
getJSON(QUERY_URL + 'get_' + table, function (code, data) {
|
||||
if (code == 200) {
|
||||
resolve(data.data);
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
fail(strings.error_network, 5000);
|
||||
resolve([]);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
getJSON(QUERY_URL + 'get_' + table.substr(0, table.length - 1) + '?id=' + id, function (code, data) {
|
||||
if (code == 200) {
|
||||
resolve(data.data);
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
fail(strings.error_network, 5000);
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function dbGetDataIndex(table, indexName, value) {
|
||||
return new Promise(function(resolve) {
|
||||
if (canUseLocalDB) {
|
||||
var request = db.transaction(table).objectStore(table).index(indexName).getAll(IDBKeyRange.only(value.toString()));
|
||||
request.onsuccess = function (event) {
|
||||
resolve(request.result);
|
||||
}
|
||||
} else {
|
||||
getJSON(QUERY_URL + 'get_' + table + '?index=' + indexName + '&value=' + value, function (code, data) {
|
||||
if (code == 200) {
|
||||
resolve(data.data);
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
fail(strings.error_network, 5000);
|
||||
resolve([]);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function dbGetRegattasRange(minDate, maxDate) {
|
||||
return new Promise(async function(resolve) {
|
||||
var regattas = await dbGetData('regattas');
|
||||
var result = [];
|
||||
for (id in regattas) {
|
||||
var regatta = regattas[id];
|
||||
var dateFrom = parseDate(regatta['date']);
|
||||
var dateTo = parseDate(regatta['date']);
|
||||
dateTo.setDate(dateTo.getDate() + parseInt(regatta['length']) - 1);
|
||||
if ((minDate <= dateTo) && (maxDate >= dateFrom)) {
|
||||
regatta['dateFrom'] = dateFrom;
|
||||
regatta['dateTo'] = dateTo;
|
||||
result.push(regatta);
|
||||
}
|
||||
}
|
||||
result.sort(function (a, b) {
|
||||
if (a['date'] < b['date']) return -1;
|
||||
if (a['date'] > b['date']) return 1;
|
||||
return 0;
|
||||
});
|
||||
resolve(result);
|
||||
});
|
||||
}
|
||||
|
||||
var compareResultsRaceCount;
|
||||
function compareResults (a, b) {
|
||||
if (a['netto'] != b['netto']) return (a['netto'] < b['netto']) ? -1 : 1;
|
||||
var tempA = [...a['values']];
|
||||
tempA.sort();
|
||||
var tempB = [...b['values']];
|
||||
tempB.sort();
|
||||
for (var i = 0; i < compareResultsRaceCount; i ++) {
|
||||
if (tempA[i] != tempB[i]) return (tempA[i] < tempB[i]) ? -1 : 1;
|
||||
}
|
||||
for (var i = compareResultsRaceCount - 1; i >= 0; i --) {
|
||||
if (a['values_all'][i] != b['values_all'][i]) return (a['values_all'][i] < b['values_all'][i]) ? -1 : 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function dbGetResultCalculated(regatta) {
|
||||
return new Promise(async function(resolve) {
|
||||
var results = await dbGetDataIndex('results', 'regatta', regatta.id);
|
||||
if (results.length > 0) {
|
||||
|
||||
var gemeldet = results.length;
|
||||
|
||||
for (id in results) {
|
||||
results[id]['finished'] = false;
|
||||
results[id]['values'] = [];
|
||||
results[id]['values_all'] = [];
|
||||
results[id]['texts'] = [];
|
||||
var copy = [];
|
||||
|
||||
for (var i = 0; i < regatta['races']; i ++) {
|
||||
var race = results[id]['race' + (i + 1)].replace(',', '.');
|
||||
|
||||
if (!isNaN(race)) {
|
||||
copy[i] = results[id]['values'][i] = parseFloat(race);
|
||||
results[id]['texts'][i] = race;
|
||||
results[id]['finished'] = true;
|
||||
} else {
|
||||
switch (race.toUpperCase()) {
|
||||
// Nicht gestartet
|
||||
case 'DNC': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Did not come
|
||||
case 'DNS': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Did not started
|
||||
// Startfehler
|
||||
case 'OCS': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // On course site
|
||||
case 'UFD': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Uniform Flag Disqualified (disqu. nach 30.3)
|
||||
case 'BFD': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Black Flag Disqualified (disqu. nach 30.4)
|
||||
// Nicht durch Ziel gegangen
|
||||
case 'DNF': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Did not finish
|
||||
case 'RET': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Retired (Aufgegeben)
|
||||
case 'RAF': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Retired after finish
|
||||
// Disqualifizierun
|
||||
case 'DSQ': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Disqualified
|
||||
case 'DNE': results[id]['values'][i] = gemeldet + 1; copy[i] = -1; break; // Disqualified, not excludable (disqu. kann nach 90.3(b) nicht gestrichen werden)
|
||||
case 'DGM': results[id]['values'][i] = gemeldet + 1; copy[i] = -2; break; // Disqualification Gross Missconduct (kann nach 69.1(b)(2) nicht gestr. werden, grobes Fehlverhalten)
|
||||
// Unbekannt
|
||||
default: results[id]['values'][i] = 0; copy[i] = 0; break;
|
||||
}
|
||||
|
||||
if (results[id]['values'][i] != 0) {
|
||||
results[id]['texts'][i] = race + ' (' + results[id]['values'][i] + ')';
|
||||
} else {
|
||||
results[id]['texts'][i] = race + ' (Unknown - 0)';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
results[id]['values_all'] = [...results[id]['values']];
|
||||
for (var s = 0; s < regatta['streicher']; s ++) {
|
||||
var max = Math.max(...copy);
|
||||
for (var i = 0; i < regatta['races']; i ++) {
|
||||
if (copy[i] == max) {
|
||||
copy[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var brutto = 0;
|
||||
var netto = 0;
|
||||
for (var i = 0; i < regatta['races']; i ++) {
|
||||
brutto += results[id]['values_all'][i];
|
||||
if (copy[i] == -1) { results[id]['values'][i] = gemeldet + 1; }
|
||||
else if (copy[i] == -2) { results[id]['values'][i] = gemeldet + 1; }
|
||||
else { results[id]['values'][i] = copy[i]; }
|
||||
if (results[id]['values'][i] == 0) {
|
||||
results[id]['texts'][i] = '[' + results[id]['texts'][i] + ']';
|
||||
}
|
||||
netto += results[id]['values'][i];
|
||||
}
|
||||
results[id]['brutto'] = brutto;
|
||||
results[id]['netto'] = netto;
|
||||
}
|
||||
|
||||
compareResultsRaceCount = regatta['races'];
|
||||
|
||||
results.sort(compareResults);
|
||||
|
||||
var place = 1;
|
||||
for (id in results) {
|
||||
if ((id > 0) && (compareResults(results[id], results[id - 1]) == 0)) {
|
||||
results[id]['place'] = results[id - 1]['place'];
|
||||
} else {
|
||||
results[id]['place'] = place;
|
||||
}
|
||||
place ++;
|
||||
}
|
||||
|
||||
resolve(results);
|
||||
|
||||
} else {
|
||||
resolve([]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function updateSyncStatus() { // TODO
|
||||
// var syncStatus = document.getElementById('syncstatus');
|
||||
// var lastSync = await dbGetData('update_times', 'last_sync');
|
||||
// lastSync = new Date(lastSync.time * 1000);
|
||||
// var now = new Date();
|
||||
// var diff = Math.round((now - lastSync) / 1000);
|
||||
// var txt = '';
|
||||
//
|
||||
// if (diff < 30) { // 30 sec
|
||||
// txt = 'jetzt';
|
||||
// } else if (diff < 3600) { // 60 min
|
||||
// diff = Math.round(diff / 60);
|
||||
// txt = 'vor ' + diff + ' ' + (diff == 1 ? 'Minute' : 'Minuten');
|
||||
// } else if (diff < 86400) { // 24 std
|
||||
// diff = Math.round(diff / 3600);
|
||||
// txt = 'vor ' + diff + ' ' + (diff == 1 ? 'Stunde' : 'Stunden');
|
||||
// } else {
|
||||
// diff = Math.round(diff / 86400);
|
||||
// txt = 'vor ' + diff + ' ' + (diff == 1 ? 'Tag' : 'Tagen');
|
||||
// }
|
||||
//
|
||||
// var btn = '<a href="#" onclick="setLoading(true); sync(); return false;"><i class="fas fa-sync"></i> Sync</a>';
|
||||
// syncStatus.innerHTML = 'Zuletzt aktualisiert: ' + txt + btn;
|
||||
}
|
||||
|
||||
async function runPageScript() {
|
||||
if (canUseLocalDB) {
|
||||
updateSyncStatus();
|
||||
}
|
||||
if (typeof updateSyncStatusTimer == 'undefined') { // TODO
|
||||
// var syncStatus = document.getElementById('syncstatus');
|
||||
if (canUseLocalDB) {
|
||||
updateSyncStatusTimer = window.setInterval(updateSyncStatus, 10000);
|
||||
} else {
|
||||
// syncStatus.innerHTML = 'Keine Offline-Nutzung möglich.';
|
||||
updateSyncStatusTimer = null;
|
||||
}
|
||||
// syncStatus.style.display = 'block';
|
||||
}
|
||||
|
||||
if (typeof siteScript === 'function') {
|
||||
siteScript();
|
||||
}
|
||||
hideLoader();
|
||||
}
|
||||
|
||||
function sync() {
|
||||
if (!canUseLocalDB) return false;
|
||||
if (syncInProgress > 0) return false;
|
||||
|
||||
var now = Math.floor(Date.now() / 1000);
|
||||
|
||||
db.transaction('update_times').objectStore('update_times').getAll().onsuccess = function (event) {
|
||||
var localTimes = {};
|
||||
event.target.result.forEach(function (entry) {
|
||||
localTimes[entry['table']] = entry['time'];
|
||||
});
|
||||
|
||||
syncInProgress = 10;
|
||||
var syncOkay = true;
|
||||
console.log("Sync Start");
|
||||
|
||||
var interval = window.setInterval(function () {
|
||||
if (syncInProgress <= 0) {
|
||||
window.clearInterval(interval);
|
||||
if (syncOkay) {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'last_sync', time: now });
|
||||
}
|
||||
console.log("Sync Stop");
|
||||
|
||||
runPageScript();
|
||||
}
|
||||
}, 100);
|
||||
|
||||
getJSON(QUERY_URL + 'get_update_time', function (code, serverTimes) {
|
||||
if (code == 200) {
|
||||
|
||||
// CLUBS
|
||||
if (localTimes['clubs'] < serverTimes['clubs']) {
|
||||
getJSON(QUERY_URL + 'get_clubs?changer-after=' + localTimes['clubs'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('clubs', 'readwrite').objectStore('clubs');
|
||||
console.log(data);
|
||||
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 {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'clubs', time: serverTimes['clubs'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
// BOATS
|
||||
if (localTimes['boats'] < serverTimes['boats']) {
|
||||
getJSON(QUERY_URL + 'get_boats?changer-after=' + localTimes['boats'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('boats', 'readwrite').objectStore('boats');
|
||||
console.log(data);
|
||||
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 {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'boats', time: serverTimes['boats'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
// SAILORS
|
||||
if (localTimes['sailors'] < serverTimes['sailors']) {
|
||||
getJSON(QUERY_URL + 'get_sailors?changer-after=' + localTimes['sailors'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('sailors', 'readwrite').objectStore('sailors');
|
||||
console.log(data);
|
||||
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 {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'sailors', time: serverTimes['sailors'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
// REGATTAS
|
||||
if (localTimes['regattas'] < serverTimes['regattas']) {
|
||||
getJSON(QUERY_URL + 'get_regattas?changer-after=' + localTimes['regattas'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('regattas', 'readwrite').objectStore('regattas');
|
||||
console.log(data);
|
||||
data.data.forEach(function (entry) {
|
||||
os.put(entry);
|
||||
});
|
||||
os.openCursor().onsuccess = async function (event) {
|
||||
var cursor = event.target.result;
|
||||
if (cursor) {
|
||||
if (!data.keys.includes(parseInt(cursor.key))) {
|
||||
os.delete(cursor.key);
|
||||
}
|
||||
cursor.continue();
|
||||
} else {
|
||||
// update years
|
||||
var regattas = await dbGetData('regattas');
|
||||
var years = {};
|
||||
for (id in regattas) {
|
||||
var entry = regattas[id];
|
||||
var date = parseDate(entry['date']);
|
||||
var y = date.getFullYear();
|
||||
years[y] = y;
|
||||
}
|
||||
var osYears = db.transaction('years', 'readwrite').objectStore('years');
|
||||
osYears.clear().onsuccess = function (event) {
|
||||
for (var y in years) {
|
||||
osYears.put({ year: y });
|
||||
}
|
||||
}
|
||||
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'regattas', time: serverTimes['regattas'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
// RESULTS
|
||||
if (localTimes['results'] < serverTimes['results']) {
|
||||
getJSON(QUERY_URL + 'get_results?changer-after=' + localTimes['results'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('results', 'readwrite').objectStore('results');
|
||||
console.log(data);
|
||||
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 {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'results', time: serverTimes['results'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
// PLANNINGS
|
||||
if (localTimes['plannings'] < serverTimes['plannings']) {
|
||||
getJSON(QUERY_URL + 'get_plannings?changer-after=' + localTimes['plannings'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('plannings', 'readwrite').objectStore('plannings');
|
||||
console.log(data);
|
||||
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 {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'plannings', time: serverTimes['plannings'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
if (isLoggedIn()) {
|
||||
// TRIM_BOATS
|
||||
if (localTimes['trim_boats'] < serverTimes['trim_boats']) {
|
||||
getJSON(QUERY_URL + 'get_trim_boats?changer-after=' + localTimes['trim_boats'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('trim_boats', 'readwrite').objectStore('trim_boats');
|
||||
console.log(data);
|
||||
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 {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'trim_boats', time: serverTimes['trim_boats'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
// TRIM_USERS
|
||||
if (localTimes['trim_users'] < serverTimes['trim_users']) {
|
||||
getJSON(QUERY_URL + 'get_trim_users?changer-after=' + localTimes['trim_users'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('trim_users', 'readwrite').objectStore('trim_users');
|
||||
console.log(data);
|
||||
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 {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'trim_users', time: serverTimes['trim_users'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
// TRIM_TRIMS
|
||||
if (localTimes['trim_trims'] < serverTimes['trim_trims']) {
|
||||
getJSON(QUERY_URL + 'get_trim_trims?changer-after=' + localTimes['trim_trims'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('trim_trims', 'readwrite').objectStore('trim_trims');
|
||||
console.log(data);
|
||||
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 {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'trim_trims', time: serverTimes['trim_trims'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
} else {
|
||||
syncInProgress -= 3;
|
||||
}
|
||||
|
||||
// USERS
|
||||
if (localTimes['users'] < serverTimes['users']) {
|
||||
getJSON(QUERY_URL + 'get_users?changer-after=' + localTimes['users'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('users', 'readwrite').objectStore('users');
|
||||
console.log(data);
|
||||
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 {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'users', time: serverTimes['users'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress = 0;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function checkSync() {
|
||||
if (!canUseLocalDB) return;
|
||||
var osUpdateTimes = db.transaction('update_times').objectStore('update_times');
|
||||
osUpdateTimes.get('last_sync').onsuccess = function (event) {
|
||||
var lastSync = event.target.result.time;
|
||||
var now = Math.floor(Date.now() / 1000);
|
||||
if ((lastSync + 600) < now) { // sync max all 10 minutes
|
||||
sync();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function initDatabase() {
|
||||
if (window.indexedDB) {
|
||||
var request = window.indexedDB.open('regatten_app_db_' + BOATCLASS, DB_VERSION);
|
||||
request.onerror = function (event) {
|
||||
console.log("Cannot open DB: " + event.target.errorCode);
|
||||
|
||||
runPageScript();
|
||||
};
|
||||
request.onsuccess = function (event) {
|
||||
console.log("Database loaded");
|
||||
db = event.target.result;
|
||||
|
||||
db.onversionchange = function (event) {
|
||||
if (syncTimer != null) window.clearInterval(syncTimer);
|
||||
if (updateSyncStatusTimer != null) window.clearInterval(updateSyncStatusTimer);
|
||||
// TODO document.getElementById('syncstatus').innerHTML = '';
|
||||
canUseLocalDB = false;
|
||||
db.close();
|
||||
location.reload;
|
||||
}
|
||||
|
||||
db.onerror = function (event) {
|
||||
console.log("DB Error: " + event.target.errorCode);
|
||||
};
|
||||
|
||||
canUseLocalDB = true;
|
||||
|
||||
db.transaction('update_times').objectStore('update_times').get('last_sync').onsuccess = function (event) {
|
||||
var lastSync = event.target.result.time;
|
||||
if (lastSync > 0) {
|
||||
runPageScript();
|
||||
}
|
||||
};
|
||||
|
||||
checkSync();
|
||||
|
||||
syncTimer = window.setInterval(checkSync, 300000); // 5 min
|
||||
|
||||
window.ononline = function () {
|
||||
checkSync();
|
||||
}
|
||||
};
|
||||
request.onupgradeneeded = function (event) {
|
||||
var db = event.target.result;
|
||||
var upgradeTransaction = event.target.transaction;
|
||||
var oldVersion = event.oldVersion;
|
||||
var newVersion = event.newVersion;
|
||||
|
||||
console.log("Datenbank Version Upgrade von " + oldVersion + " auf " + newVersion);
|
||||
|
||||
if ((oldVersion < 1) && (newVersion >= 1)) {
|
||||
console.log('to version 1');
|
||||
var osClubs = db.createObjectStore('clubs', { keyPath: 'id' });
|
||||
var osBoats = db.createObjectStore('boats', { keyPath: 'id' });
|
||||
var osSailors = db.createObjectStore('sailors', { keyPath: 'id' });
|
||||
var osRegattas = db.createObjectStore('regattas', { keyPath: 'id' });
|
||||
var osResults = db.createObjectStore('results', { keyPath: 'id' });
|
||||
osResults.createIndex('regatta', 'regatta', { unique: false });
|
||||
var osPlannings = db.createObjectStore('plannings', { keyPath: 'id' });
|
||||
osPlannings.createIndex('user', 'user', { unique: false });
|
||||
osPlannings.createIndex('regatta', 'regatta', { unique: false });
|
||||
var osTrimBoats = db.createObjectStore('trim_boats', { keyPath: 'id' });
|
||||
var osTrimUsers = db.createObjectStore('trim_users', { keyPath: 'id' });
|
||||
osTrimUsers.createIndex('boat', 'boat', { unique: false });
|
||||
var osTrimTrims = db.createObjectStore('trim_trims', { keyPath: 'id' });
|
||||
osTrimTrims.createIndex('boat', 'boat', { unique: false });
|
||||
var osUpdateTimes = db.createObjectStore('update_times', { keyPath: 'table' });
|
||||
osUpdateTimes.add({ table: 'last_sync', time: 0 });
|
||||
osUpdateTimes.add({ table: 'clubs', time: 0 });
|
||||
osUpdateTimes.add({ table: 'boats', time: 0 });
|
||||
osUpdateTimes.add({ table: 'sailors', time: 0 });
|
||||
osUpdateTimes.add({ table: 'regattas', time: 0 });
|
||||
osUpdateTimes.add({ table: 'results', time: 0 });
|
||||
osUpdateTimes.add({ table: 'plannings', time: 0 });
|
||||
osUpdateTimes.add({ table: 'trim_boats', time: 0 });
|
||||
osUpdateTimes.add({ table: 'trim_users', time: 0 });
|
||||
osUpdateTimes.add({ table: 'trim_trims', time: 0 });
|
||||
}
|
||||
|
||||
if ((oldVersion < 2) && (newVersion >= 2)) {
|
||||
console.log('to version 2');
|
||||
var osUsers = db.createObjectStore('users', { keyPath: 'id' });
|
||||
osUsers.createIndex('username', 'username', { unique: true });
|
||||
var osUpdateTimes = upgradeTransaction.objectStore('update_times');
|
||||
osUpdateTimes.add({ table: 'users', time: 0 });
|
||||
}
|
||||
|
||||
if ((oldVersion < 3) && (newVersion >= 3)) {
|
||||
console.log('to version 3');
|
||||
var osYears = db.createObjectStore('years', { keyPath: 'year' });
|
||||
var osUpdateTimes = upgradeTransaction.objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'regattas', time: 0 });
|
||||
}
|
||||
|
||||
var osUpdateTimes = upgradeTransaction.objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'last_sync', time: 0 });
|
||||
}
|
||||
} else {
|
||||
runPageScript();
|
||||
}
|
||||
}
|
||||
87
client/scripts/datetime.js
Normal file
87
client/scripts/datetime.js
Normal file
@@ -0,0 +1,87 @@
|
||||
function parseDate(string) {
|
||||
var year, month, day;
|
||||
if (string.includes('.')) {
|
||||
var split = string.split('.');
|
||||
if (split.length != 3) return null;
|
||||
year = parseInt(split[2]);
|
||||
month = parseInt(split[1]);
|
||||
day = parseInt(split[0]);
|
||||
} else if (string.includes('/')) {
|
||||
var split = string.split('/');
|
||||
if (split.length != 3) return null;
|
||||
year = parseInt(split[2]);
|
||||
month = parseInt(split[0]);
|
||||
day = parseInt(split[1]);
|
||||
} else if (string.includes('-')) {
|
||||
var split = string.split('-');
|
||||
if (split.length != 3) return null;
|
||||
if (split[2].length > 2) {
|
||||
year = parseInt(split[2]);
|
||||
month = parseInt(split[1]);
|
||||
day = parseInt(split[0]);
|
||||
} else {
|
||||
year = parseInt(split[0]);
|
||||
month = parseInt(split[1]);
|
||||
day = parseInt(split[2]);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isNaN(year) || isNaN(month) || isNaN(day)) return null;
|
||||
if (year.toString().length == 2) year = (year < 70 ? 2000 : 1900) + year;
|
||||
if ((year < 1970) || (year > 3000)) return null;
|
||||
if ((month < 1) || (month > 12)) return null;
|
||||
if ((day < 1) || (day > 31)) return null;
|
||||
|
||||
var date = new Date(Date.UTC(year, month - 1, day));
|
||||
return date;
|
||||
}
|
||||
|
||||
function getToday() {
|
||||
var date = new Date();
|
||||
date = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
|
||||
return date;
|
||||
}
|
||||
|
||||
function formatDate(format, date = null) {
|
||||
if (date === null) {
|
||||
date = new Date();
|
||||
} else {
|
||||
date = new Date(date.valueOf());
|
||||
date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
|
||||
}
|
||||
|
||||
format = format.replace("M", "%1%");
|
||||
format = format.replace("F", "%2%");
|
||||
format = format.replace("D", "%3%");
|
||||
format = format.replace("l", "%4%");
|
||||
|
||||
var tmp = date.getFullYear().toString();
|
||||
var tmp2 = tmp.substr(2);
|
||||
format = format.replace("Y", tmp);
|
||||
format = format.replace('y', tmp2);
|
||||
|
||||
tmp = (date.getMonth() + 1).toString();
|
||||
tmp2 = (tmp.length > 1 ? tmp : ('0' + tmp));
|
||||
format = format.replace('n', tmp);
|
||||
format = format.replace('m', tmp2);
|
||||
|
||||
tmp = date.getDate().toString();
|
||||
tmp2 = (tmp.length > 1 ? tmp : ('0' + tmp));
|
||||
format = format.replace('j', tmp);
|
||||
format = format.replace('d', tmp2);
|
||||
|
||||
tmp = date.getDay();
|
||||
tmp2 = (tmp == 0 ? 7 : tmp);
|
||||
format = format.replace('w', tmp);
|
||||
format = format.replace('N', tmp2);
|
||||
|
||||
format = format.replace('%1%', strings.months_short[date.getMonth()]);
|
||||
format = format.replace('%2%', strings.months_long[date.getMonth()]);
|
||||
|
||||
format = format.replace('%3%', strings.weekdays_short[date.getDay()]);
|
||||
format = format.replace('%4%', strings.weekdays_long[date.getDay()]);
|
||||
|
||||
return format;
|
||||
}
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
?>
|
||||
|
||||
const apiUrl = '<?php echo SERVER_ADDR; ?>/api/';
|
||||
const QUERY_URL = '<?php echo SERVER_ADDR; ?>/api/';
|
||||
const BOATCLASS = '<?php echo BOATCLASS; ?>';
|
||||
|
||||
var randomId = function() { return '_' + Math.random().toString(36).substr(2, 9); }
|
||||
|
||||
@@ -181,33 +182,53 @@ var logout = function() {
|
||||
});
|
||||
}
|
||||
|
||||
var initRegatten = function() {
|
||||
loggedin = (localStorage.getItem('auth_id') !== null);
|
||||
|
||||
if (loggedin) {
|
||||
var auth = {
|
||||
id: localStorage.getItem('auth_id'),
|
||||
hash: localStorage.getItem('auth_hash')
|
||||
}
|
||||
var user = {
|
||||
id: localStorage.getItem('auth_user'),
|
||||
name: localStorage.getItem('auth_username')
|
||||
}
|
||||
if ((auth.hash === null) || (user.id === null) || (user.name === null)) {
|
||||
logoutClearStorage();
|
||||
return;
|
||||
function resetDb() {
|
||||
$('#menu-developer').hideMenu();
|
||||
if (canUseLocalDB) {
|
||||
showLoader();
|
||||
var request = window.indexedDB.deleteDatabase('regatten_app_db_' + BOATCLASS);
|
||||
request.onerror = function (event) {
|
||||
console.log("Cannot open DB: " + event.target.errorCode);
|
||||
toastError('There was an error deleting your database.<br>Please report this to <a href="mailto:dev@regatten.net">dev@regatten.net</a>');
|
||||
hideLoader();
|
||||
};
|
||||
request.onsuccess = function (event) {
|
||||
console.log('DB deleted');
|
||||
toastInfo('The database was deleted. Please reload or close this tab.<br>At the next visit, a new database will be created.');
|
||||
hideLoader();
|
||||
}
|
||||
} else {
|
||||
toastWarn('Your device does not support storing data locally. All data is fetched directly from our server.<br>As a result, you can not reset your database.');
|
||||
}
|
||||
}
|
||||
|
||||
if (loggedin) {
|
||||
function resetCache() {
|
||||
$('#menu-developer').hideMenu();
|
||||
navigator.serviceWorker.getRegistrations().then(function (registrations) {
|
||||
for (let registration of registrations) {
|
||||
console.log('Unregister sW:', registration);
|
||||
registration.unregister();
|
||||
}
|
||||
});
|
||||
caches.keys().then((keyList) => {
|
||||
return Promise.all(keyList.map((key) => {
|
||||
console.log('Cache deleted:', key);
|
||||
return caches.delete(key);
|
||||
}));
|
||||
});
|
||||
toastInfo('The serviceWorker and the cache were deleted. A new serviceWorker will be generated on the next refresh.');
|
||||
}
|
||||
|
||||
var initRegatten = function() {
|
||||
showLoader();
|
||||
|
||||
initDatabase();
|
||||
|
||||
if (isLoggedIn) {
|
||||
$('.show-notloggedin').css('display', 'none');
|
||||
$('.replace-userid-href').attr('href', $('.replace-userid-href').attr('href').replace('%USERID%', user.id));
|
||||
$('.replace-username').html(user.name);
|
||||
$('.replace-userid-href').attr('href', $('.replace-userid-href').attr('href').replace('%USERID%', USER_ID));
|
||||
$('.replace-username').html(USER_NAME);
|
||||
} else {
|
||||
$('.show-loggedin').css('display', 'none');
|
||||
}
|
||||
|
||||
if (typeof siteScript !== 'undefined') {
|
||||
siteScript();
|
||||
}
|
||||
}
|
||||
@@ -8,4 +8,51 @@
|
||||
const strings = {
|
||||
inetMsgOffline: "Keine Internet-Verbindung erkannt",
|
||||
inetMsgOnline: "Du bist wieder online",
|
||||
error_network: "Verbindung fehlgeschlagen.<br>Stelle sicher, dass Du mit dem Internet verbunden bist und versuche es erneut!",
|
||||
months_short: [
|
||||
'Jan.',
|
||||
'Feb.',
|
||||
'März',
|
||||
'Apr.',
|
||||
'Mai',
|
||||
'Juni',
|
||||
'Juli',
|
||||
'Aug.',
|
||||
'Sep.',
|
||||
'Okt.',
|
||||
'Nov.',
|
||||
'Dez.'
|
||||
],
|
||||
months_long: [
|
||||
'Januar',
|
||||
'Februar',
|
||||
'März',
|
||||
'April',
|
||||
'Mai',
|
||||
'Juni',
|
||||
'Juli',
|
||||
'August',
|
||||
'September',
|
||||
'Oktober',
|
||||
'November',
|
||||
'Dezember'
|
||||
],
|
||||
weekdays_short: [
|
||||
'So',
|
||||
'Mo',
|
||||
'Di',
|
||||
'Mi',
|
||||
'Do',
|
||||
'Fr',
|
||||
'Sa'
|
||||
],
|
||||
weekdays_long: [
|
||||
'Sonntag',
|
||||
'Montag',
|
||||
'Dienstag',
|
||||
'Mittwoch',
|
||||
'Donnerstag',
|
||||
'Freitag',
|
||||
'Samstag'
|
||||
],
|
||||
}
|
||||
@@ -7,30 +7,52 @@
|
||||
$sp['output'] .= $tpl->load('card', [$content]);
|
||||
|
||||
// Favorites
|
||||
$content = "<h2>Deine Favoriten</h2>";
|
||||
$thead = "<tr><th>Segler</th><th>Rangliste 2020</th></tr>";
|
||||
$content = '<h2>Deine Favoriten</h2>';
|
||||
$thead = '<tr><th>Segler</th><th id="th-ranking">Rangliste</th></tr>';
|
||||
$content .= $tpl->load('table', [$thead, 'html-id' => 'table-favorites', 'css-class' => 'mb-0 mt-3']);
|
||||
$content .= '<p id="p-favorites" class="mt-3">';
|
||||
$content .= 'Du folgst <b>keinen</b> Seglern.<br>';
|
||||
$content .= 'Um jemandem zu folgen, gehe zur <a href="' . LINK_PRE . 'sailors">Segler-Liste</a> und wähle bis zu fünf Segler aus.';
|
||||
$content .= '</p>';
|
||||
|
||||
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-favorites']);
|
||||
|
||||
// Planning next
|
||||
$content = "<h2>Deine nächsten Regatten</h2>";
|
||||
$thead = "<tr><th>Datum</th><th>Regatta</th><th>Informationen</th><th>RLF</th><th>Segler</th></tr>";
|
||||
$content = '<h2>Deine nächsten Regatten</h2>';
|
||||
$thead = '<tr><th>Datum</th><th>Regatta</th><th>Informationen</th><th>RLF</th><th>Segler</th></tr>';
|
||||
$content .= $tpl->load('table', [$thead, 'html-id' => 'table-yournext', 'css-class' => 'mb-0 mt-3']);
|
||||
$content .= '<p id="p-yournext" class="mt-3">';
|
||||
$content .= 'Du fährst in den nächsten vier Wochen auf keine Regatta!';
|
||||
$content .= '</p>';
|
||||
|
||||
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-yournext']);
|
||||
|
||||
// Not logged in
|
||||
$content = '<h2>Nicht angemeldet</h2>';
|
||||
$content .= '<p class="mt-3">';
|
||||
$content .= 'Um alle Funktionen dieser Seite nutzen zu können, <a href="#" data-menu="menu-login">logge Dich bitte ein</a>.<br>';
|
||||
$content .= 'Solltest Du noch kein Benutzerkonto haben, kannst Du Dich kostenlos <a href="#" data-menu="menu-signup">registrieren</a>.';
|
||||
$content .= '</p>';
|
||||
|
||||
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-notloggedin']);
|
||||
|
||||
// Next
|
||||
$content = "<h2>Nächste Regatten</h2>";
|
||||
$thead = "<tr><th>Datum</th><th>Regatta</th><th>Informationen</th><th>RLF</th></tr>";
|
||||
$content = '<h2>Nächste Regatten</h2>';
|
||||
$thead = '<tr><th>Datum</th><th>Regatta</th><th>Informationen</th><th>RLF</th></tr>';
|
||||
$content .= $tpl->load('table', [$thead, 'html-id' => 'table-next', 'css-class' => 'mb-0 mt-3']);
|
||||
$content .= '<p id="p-next" class="mt-3">';
|
||||
$content .= 'Keine Regatten in den nächsten zwei Wochen!';
|
||||
$content .= '</p>';
|
||||
|
||||
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-next']);
|
||||
|
||||
// Last
|
||||
$content = "<h2>Letzte Regatten</h2>";
|
||||
$thead = "<tr><th>Datum</th><th>Regatta</th><th>Ergebnisse</th><th>RLF</th></tr>";
|
||||
$content = '<h2>Letzte Regatten</h2>';
|
||||
$thead = '<tr><th>Datum</th><th>Regatta</th><th>Ergebnisse</th><th>RLF</th></tr>';
|
||||
$content .= $tpl->load('table', [$thead, 'html-id' => 'table-last', 'css-class' => 'mb-0 mt-3']);
|
||||
$content .= '<p id="p-last" class="mt-3">';
|
||||
$content .= 'Keine Regatten in den letzten zwei Wochen!';
|
||||
$content .= '</p>';
|
||||
|
||||
$sp['output'] .= $tpl->load('card', [$content, 'html-id' => 'card-last']);
|
||||
|
||||
@@ -46,20 +68,6 @@
|
||||
|
||||
$sp['output'] .= $tpl->load('card', [$content]);
|
||||
|
||||
$sp['scripts'] = '
|
||||
<script>
|
||||
var siteScript = function() {
|
||||
if (loggedin) {
|
||||
$(\'#table-favorites\').find(\'tbody\').html(\'<tr><td>Finn Soetebier</td><td>noch nicht verfügbar</td></tr>\');
|
||||
$(\'#table-yournext\').find(\'tbody\').html(\'<tr><td style="white-space:nowrap;">10. Oct \\\'20<br>14. Oct \\\'20</td><td><a href="#">BSC</a><br>VERSCHOBEN: IDJM, Blankenese</td><td><a href="#">Informationen</a><br><a href="#">Meldung</a> <font style="color:red;">(noch 5 Tage)</a></td><td>1,26</td><td>Finn Soetebier<br>Timon Ostertun</td></tr>\');
|
||||
} else {
|
||||
$(\'#card-favorites\').hide();
|
||||
$(\'#card-yournext\').hide();
|
||||
}
|
||||
$(\'#table-next\').find(\'tbody\').html(\'<tr><td style="white-space:nowrap;">10. Oct \\\'20<br>14. Oct \\\'20</td><td><a href="#">BSC</a><br>VERSCHOBEN: IDJM, Blankenese</td><td><a href="#">Informationen</a><br><a href="#">Meldung</a> <font style="color:red;">(noch 5 Tage)</a></td><td>1,26</td></tr>\');
|
||||
$(\'#table-last\').find(\'tbody\').html(\'<tr><td style="white-space:nowrap;">10. Oct \\\'20<br>14. Oct \\\'20</td><td><a href="#">BSC</a><br>VERSCHOBEN: IDJM, Blankenese</td><td><i style="color:green;" class="fas fa-check"></i> <a href="#">Ergebnisse</a></td><td>1,26</td></tr>\');
|
||||
}
|
||||
</script>
|
||||
';
|
||||
$sp['scripts'] = '<!-- DEBUG -->' . $scripts->load('index');
|
||||
|
||||
?>
|
||||
@@ -3,6 +3,7 @@
|
||||
require_once(__DIR__ . '/server/config.php');
|
||||
require_once(__DIR__ . '/server/log.php');
|
||||
require_once(__DIR__ . '/server/templates.php');
|
||||
require_once(__DIR__ . '/server/scripts.php');
|
||||
|
||||
$request = false;
|
||||
if (isset($_GET['request'])) {
|
||||
@@ -36,6 +37,7 @@
|
||||
];
|
||||
|
||||
$tpl = new Templates(__DIR__ . '/server/templates/');
|
||||
$scripts = new Scripts(__DIR__ . '/server/scripts/');
|
||||
|
||||
require_once(__DIR__ . '/content/' . $site . '.php');
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
else
|
||||
echo '<a href="' . LINK_PRE . $sp['backbutton'] . '" class="header-icon header-icon-1"><i class="fas fa-arrow-left"></i></a>';
|
||||
} ?>
|
||||
<a href="#" data-menu="menu-developer" class="header-icon header-icon-3"><i class="fas fa-code"></i></a>
|
||||
<a href="#" data-menu="menu-settings" class="header-icon header-icon-4"><i class="fas fa-cog"></i></a>
|
||||
</div>
|
||||
<div id="footer-bar" class="footer-bar-1">
|
||||
|
||||
@@ -129,6 +129,35 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="menu-developer" class="menu menu-box-bottom menu-box-detached rounded-m" data-menu-height="310">
|
||||
<div class="menu-title"><h1>Entwickler-Optionen</h1><p class="color-highlight"> </p><a href="#" class="close-menu"><i class="fa fa-times"></i></a></div>
|
||||
<div class="divider divider-margins mb-n2"></div>
|
||||
<div class="content">
|
||||
<div class="list-group list-custom-small">
|
||||
<a href="https://info.ostertun.net/regatten/beta">
|
||||
<i class="fa font-14 fa-info rounded-s bg-highlight color-white"></i>
|
||||
<span>Infos zur BETA</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<a href="javascript:resetDb();">
|
||||
<i class="fa font-14 fa-database rounded-s bg-highlight color-white"></i>
|
||||
<span>Reset Database</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<a href="javascript:resetCache();">
|
||||
<i class="fa font-14 fa-trash-alt rounded-s bg-highlight color-white"></i>
|
||||
<span>Reset Cache</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<a href="https://report.regatten.net/" class="border-0">
|
||||
<i class="fa font-14 fa-bug rounded-s bg-highlight color-white"></i>
|
||||
<span>Problem melden</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="menu-login" class="menu menu-box-top menu-box-detached rounded-m" data-menu-height="270">
|
||||
<div class="content bottom-0">
|
||||
<h1 class="text-center mt-5 font-900">Login</h1>
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
<script type="text/javascript" src="<?php echo SERVER_ADDR; ?>/client/scripts/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="<?php echo SERVER_ADDR; ?>/client/scripts/strings.js.php"></script>
|
||||
<script type="text/javascript" src="<?php echo SERVER_ADDR; ?>/client/scripts/regatten.js.php"></script>
|
||||
<script type="text/javascript" src="<?php echo SERVER_ADDR; ?>/client/scripts/datetime.js"></script>
|
||||
<script type="text/javascript" src="<?php echo SERVER_ADDR; ?>/client/scripts/database.js"></script>
|
||||
<script type="text/javascript" src="<?php echo SERVER_ADDR; ?>/client/scripts/custom.js.php"></script>
|
||||
<script type="text/javascript" src="<?php echo SERVER_ADDR; ?>/client/scripts/pwa.js.php"></script>
|
||||
</body>
|
||||
|
||||
37
server/scripts.php
Normal file
37
server/scripts.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
class Scripts {
|
||||
|
||||
private $path;
|
||||
private $scripts;
|
||||
|
||||
function __construct($path) {
|
||||
if (substr($path, -1) != '/') $path .= '/';
|
||||
$this->path = $path;
|
||||
$this->scripts = [];
|
||||
}
|
||||
|
||||
function load($name, $params = []) {
|
||||
if (!isset($this->scripts[$name])) {
|
||||
$filename = $this->path . $name . '.js';
|
||||
if (file_exists($filename) and is_file($filename)) {
|
||||
$this->scripts[$name] = file_get_contents($filename);
|
||||
} else {
|
||||
return "<p>Script '$name' not found!</p>";
|
||||
}
|
||||
}
|
||||
|
||||
$script = $this->scripts[$name];
|
||||
while (($pos = strpos($script, '$$')) !== false) {
|
||||
$pos += 2;
|
||||
$pos2 = strpos($script, ';', $pos);
|
||||
if ($pos2 === false) return "<p>Syntax error in script '$name'!</p>";
|
||||
$ph = substr($script, $pos, $pos2 - $pos);
|
||||
if (!isset($params[$ph])) $params[$ph] = '';
|
||||
$script = str_replace('$$' . $ph . ';', $params[$ph], $script);
|
||||
}
|
||||
return '<script>' . $script . '</script>';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
323
server/scripts/index.js
Normal file
323
server/scripts/index.js
Normal file
@@ -0,0 +1,323 @@
|
||||
var siteScript = async function() {
|
||||
if (isLoggedIn()) {
|
||||
$('#card-notloggedin').hide();
|
||||
|
||||
var user = await dbGetData('users', localStorage.getItem('auth_user'));
|
||||
var today = getToday();
|
||||
|
||||
// Favorites
|
||||
var watched = [];
|
||||
for (var i = 1; i <= 5; i ++) {
|
||||
sailor_id = user['sailor' + i];
|
||||
if (sailor_id != null) {
|
||||
watched.push(await dbGetData('sailors', sailor_id));
|
||||
}
|
||||
}
|
||||
if (watched.length > 0) {
|
||||
var year = (new Date()).getFullYear();
|
||||
$('#th-ranking').html('Rangliste ' + year);
|
||||
// TODO: get ranking
|
||||
tbody = '';
|
||||
for (i in watched) {
|
||||
sailor = watched[i];
|
||||
tbody += '<tr><td>' + sailor.name + '</td><td>';
|
||||
// TODO: check if ranking and output
|
||||
//tbody += '<i>nicht in der Rangliste</i>';
|
||||
tbody += '<i>Ranglisten werden aktuell noch nicht unterstützt</i>';
|
||||
tbody += '</td></tr>';
|
||||
}
|
||||
$('#table-favorites').find('tbody').html(tbody);
|
||||
$('#p-favorites').hide();
|
||||
$('#table-favorites').show();
|
||||
} else {
|
||||
$('#table-favorites').hide();
|
||||
$('#p-favorites').show();
|
||||
}
|
||||
$('#card-favorites').show();
|
||||
|
||||
// Your next
|
||||
var planningsDB = await dbGetDataIndex('plannings', 'user', user.id);
|
||||
var minDate = getToday();
|
||||
minDate.setDate(minDate.getDate() - 1);
|
||||
var maxDate = getToday();
|
||||
maxDate.setDate(maxDate.getDate() + 28);
|
||||
var regattas = await dbGetRegattasRange(minDate, maxDate);
|
||||
var plannings = [];
|
||||
for (i = planningsDB.length - 1; i >= 0; i --) {
|
||||
var planning = planningsDB[i];
|
||||
for (j in regattas) {
|
||||
var regatta = regattas[j];
|
||||
if (regatta.id == planning.regatta) {
|
||||
planning.regatta = regatta;
|
||||
plannings.push(planning);
|
||||
}
|
||||
}
|
||||
}
|
||||
plannings.sort(function (a, b) {
|
||||
if (a.regatta.date < b.regatta.date) return -1;
|
||||
if (a.regatta.date > b.regatta.date) return 1;
|
||||
return 0;
|
||||
});
|
||||
if (plannings.length > 0) {
|
||||
tbody = '';
|
||||
for (i in plannings) {
|
||||
var planning = plannings[i];
|
||||
var regatta = planning.regatta;
|
||||
var club = null;
|
||||
if (regatta['club'] != null)
|
||||
club = await dbGetData('clubs', regatta['club']);
|
||||
var dateFrom = regatta['dateFrom'];
|
||||
var dateTo = regatta['dateTo'];
|
||||
// TODO: get steuermann and crew
|
||||
var steuermann = '<i>noch unklar</i>';
|
||||
if (planning.steuermann !== null) {
|
||||
steuermann = (await dbGetData('sailors', planning.steuermann)).name;
|
||||
}
|
||||
var crew = [];
|
||||
if (planning.crew !== '') {
|
||||
crewIds = planning.crew.split(',');
|
||||
for (j in crewIds) {
|
||||
crew.push((await dbGetData('sailors', crewIds[j])).name);
|
||||
}
|
||||
}
|
||||
|
||||
// output
|
||||
tbody += '<tr>';
|
||||
|
||||
tbody += '<td><span style="white-space:nowrap;">' + formatDate("j. M 'y", dateFrom) + '<br>' + formatDate("j. M 'y", dateTo) + '</span></td>';
|
||||
|
||||
var content = '';
|
||||
if (club != null) {
|
||||
content = club['kurz'];
|
||||
if (club['website'] != '') {
|
||||
content = '<a href="' + club['website'] + '" target="_blank">' + content + '</a>';
|
||||
}
|
||||
}
|
||||
tbody += '<td>' + content + '<br>' + (regatta['canceled'] == 1 ? '<s>' : '') + regatta['name'] + (regatta['canceled'] == 1 ? '</s>' : '') + '</td>';
|
||||
|
||||
var buf = '';
|
||||
if (regatta['info'] != '') {
|
||||
buf += '<a target="_blank" href="' + regatta['info'] + '">Informationen</a>';
|
||||
}
|
||||
if ((regatta['meldung'] != '') && (dateTo >= today)) {
|
||||
buf += '<br><a target="_blank" href="' + regatta['meldung'] + '">Meldung</a>';
|
||||
|
||||
if ((planning != null) && (planning['gemeldet'] == "1")) {
|
||||
buf += ' <i>(du hast gemeldet)</i>';
|
||||
} else if (regatta['meldungOffen'] == "0") {
|
||||
buf += ' <i>(geschlossen)</i>';
|
||||
} else if (regatta['meldungSchluss'] != null) {
|
||||
early = false;
|
||||
if (regatta['meldungEarly'] != null) {
|
||||
ms = parseDate(regatta['meldungEarly']);
|
||||
if (ms >= today) {
|
||||
early = true;
|
||||
}
|
||||
}
|
||||
if (!early)
|
||||
ms = parseDate(regatta['meldungSchluss']);
|
||||
if (ms >= today) {
|
||||
diff = Math.round((ms - today) / 86400000);
|
||||
red = (diff < 7);
|
||||
if (diff <= 14) {
|
||||
txt = 'noch ' + diff + ' Tag' + (diff != 1 ? 'e' : '');
|
||||
} else if (diff < 35) {
|
||||
diff = Math.floor(diff / 7);
|
||||
txt = 'noch ' + diff + ' Woche' + (diff != 1 ? 'n' : '');
|
||||
} else {
|
||||
diff = Math.floor(diff / 30.5);
|
||||
txt = 'noch ' + diff + ' Monat' + (diff != 1 ? 'e' : '');
|
||||
}
|
||||
buf += ' <i>' + (red ? '<b><font style="color:red;">(' : '(') + txt + (early ? ' vergünstigt' : '') + (red ? ')</font></b>' : ')') + '</i>';
|
||||
} else {
|
||||
buf += ' <i>(Meldeschluss abgelaufen)</i>';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (regatta['bericht'] != '') {
|
||||
buf += '<br><a target="_blank" href="' + regatta['bericht'] + '">Bericht</a>';
|
||||
}
|
||||
if (regatta['oresults'] != '') {
|
||||
buf += '<br><a target="_blank" href="' + regatta['oresults'] + '">off. Ergebnisse</a>';
|
||||
}
|
||||
tbody += '<td>' + buf + '</td>';
|
||||
|
||||
tbody += '<td><span style="white-space:nowrap;">' + parseFloat(regatta['rlf']).toFixed(2) + '</span></td>';
|
||||
|
||||
tbody += '<td>' + steuermann + '<br>' + crew.join('<br>') + '</td>';
|
||||
|
||||
tbody += '</tr>';
|
||||
}
|
||||
$('#table-yournext').find('tbody').html(tbody);
|
||||
$('#p-yournext').hide();
|
||||
$('#table_yournext').show();
|
||||
} else {
|
||||
$('#table-yournext').hide();
|
||||
$('#p-yournext').show();
|
||||
}
|
||||
$('#card-yournext').show();
|
||||
} else {
|
||||
$('#card-favorites').hide();
|
||||
$('#card-yournext').hide();
|
||||
$('#card-notloggedin').show();
|
||||
}
|
||||
|
||||
// Next
|
||||
var minDate = getToday();
|
||||
minDate.setDate(minDate.getDate() - 1);
|
||||
var maxDate = getToday();
|
||||
maxDate.setDate(maxDate.getDate() + 14);
|
||||
var regattas = await dbGetRegattasRange(minDate, maxDate);
|
||||
if (regattas.length > 0) {
|
||||
tbody = '';
|
||||
for (i in regattas) {
|
||||
var regatta = regattas[i];
|
||||
var club = null;
|
||||
if (regatta['club'] != null)
|
||||
club = await dbGetData('clubs', regatta['club']);
|
||||
var plannings = await dbGetDataIndex('plannings', 'regatta', regatta['id']);
|
||||
var dateFrom = regatta['dateFrom'];
|
||||
var dateTo = regatta['dateTo'];
|
||||
|
||||
// output
|
||||
tbody += '<tr>';
|
||||
|
||||
tbody += '<td><span style="white-space:nowrap;">' + formatDate("j. M 'y", dateFrom) + '<br>' + formatDate("j. M 'y", dateTo) + '</span></td>';
|
||||
|
||||
var content = '';
|
||||
if (club != null) {
|
||||
content = club['kurz'];
|
||||
if (club['website'] != '') {
|
||||
content = '<a href="' + club['website'] + '" target="_blank">' + content + '</a>';
|
||||
}
|
||||
}
|
||||
tbody += '<td>' + content + '<br>' + (regatta['canceled'] == 1 ? '<s>' : '') + regatta['name'] + (regatta['canceled'] == 1 ? '</s>' : '') + '</td>';
|
||||
|
||||
var buf = '';
|
||||
if (regatta['info'] != '') {
|
||||
buf += '<a target="_blank" href="' + regatta['info'] + '">Informationen</a>';
|
||||
}
|
||||
if ((regatta['meldung'] != '') && (dateTo >= today)) {
|
||||
buf += '<br><a target="_blank" href="' + regatta['meldung'] + '">Meldung</a>';
|
||||
var planning = null;
|
||||
if (isLoggedIn()) {
|
||||
for (id in plannings) {
|
||||
if (plannings[id]['user'] == USER_ID) {
|
||||
planning = plannings[id];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((planning != null) && (planning['gemeldet'] == "1")) {
|
||||
buf += ' <i>(du hast gemeldet)</i>';
|
||||
} else if (regatta['meldungOffen'] == "0") {
|
||||
buf += ' <i>(geschlossen)</i>';
|
||||
} else if (regatta['meldungSchluss'] != null) {
|
||||
early = false;
|
||||
if (regatta['meldungEarly'] != null) {
|
||||
ms = parseDate(regatta['meldungEarly']);
|
||||
if (ms >= today) {
|
||||
early = true;
|
||||
}
|
||||
}
|
||||
if (!early)
|
||||
ms = parseDate(regatta['meldungSchluss']);
|
||||
if (ms >= today) {
|
||||
diff = Math.round((ms - today) / 86400000);
|
||||
red = (diff < 7);
|
||||
if (diff <= 14) {
|
||||
txt = 'noch ' + diff + ' Tag' + (diff != 1 ? 'e' : '');
|
||||
} else if (diff < 35) {
|
||||
diff = Math.floor(diff / 7);
|
||||
txt = 'noch ' + diff + ' Woche' + (diff != 1 ? 'n' : '');
|
||||
} else {
|
||||
diff = Math.floor(diff / 30.5);
|
||||
txt = 'noch ' + diff + ' Monat' + (diff != 1 ? 'e' : '');
|
||||
}
|
||||
buf += ' <i>' + (red ? '<b><font style="color:red;">(' : '(') + txt + (early ? ' vergünstigt' : '') + (red ? ')</font></b>' : ')') + '</i>';
|
||||
} else {
|
||||
buf += ' <i>(Meldeschluss abgelaufen)</i>';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (regatta['bericht'] != '') {
|
||||
buf += '<br><a target="_blank" href="' + regatta['bericht'] + '">Bericht</a>';
|
||||
}
|
||||
if (regatta['oresults'] != '') {
|
||||
buf += '<br><a target="_blank" href="' + regatta['oresults'] + '">off. Ergebnisse</a>';
|
||||
}
|
||||
tbody += '<td>' + buf + '</td>';
|
||||
|
||||
tbody += '<td><span style="white-space:nowrap;">' + parseFloat(regatta['rlf']).toFixed(2) + '</span></td>';
|
||||
|
||||
tbody += '</tr>';
|
||||
}
|
||||
$('#table-next').find('tbody').html(tbody);
|
||||
$('#p-next').hide();
|
||||
$('#table-next').show();
|
||||
} else {
|
||||
$('#table-next').hide();
|
||||
$('#p-next').show();
|
||||
}
|
||||
|
||||
// Last
|
||||
var minDate = getToday();
|
||||
minDate.setDate(minDate.getDate() - 14);
|
||||
var maxDate = getToday();
|
||||
maxDate.setDate(maxDate.getDate() - 1);
|
||||
var regattas = await dbGetRegattasRange(minDate, maxDate);
|
||||
var regattaResults = [];
|
||||
for (id in regattas) {
|
||||
var entry = regattas[id];
|
||||
var results = await dbGetDataIndex('results', 'regatta', entry['id']);
|
||||
regattaResults[entry['id']] = (results.length > 0);
|
||||
}
|
||||
if (regattas.length > 0) {
|
||||
tbody = '';
|
||||
for (i in regattas) {
|
||||
var regatta = regattas[i];
|
||||
var club = null;
|
||||
if (regatta['club'] != null)
|
||||
club = await dbGetData('clubs', regatta['club']);
|
||||
var dateFrom = regatta['dateFrom'];
|
||||
var dateTo = regatta['dateTo'];
|
||||
|
||||
// output
|
||||
tbody += '<tr>';
|
||||
|
||||
tbody += '<td><span style="white-space:nowrap;">' + formatDate("j. M 'y", dateFrom) + '<br>' + formatDate("j. M 'y", dateTo) + '</span></td>';
|
||||
|
||||
var content = '';
|
||||
if (club != null) {
|
||||
content = club['kurz'];
|
||||
if (club['website'] != '') {
|
||||
content = '<a href="' + club['website'] + '" target="_blank">' + content + '</a>';
|
||||
}
|
||||
}
|
||||
tbody += '<td>' + content + '<br>' + (regatta['canceled'] == 1 ? '<s>' : '') + regatta['name'] + (regatta['canceled'] == 1 ? '</s>' : '') + '</td>';
|
||||
|
||||
var buf = '';
|
||||
if (regatta['canceled'] == "1") {
|
||||
buf = '<i style="color:red;" class="fas fa-times"></i> Ausgefallen</td>';
|
||||
} else {
|
||||
if (regattaResults[regatta['id']]) {
|
||||
buf = '<i style="color:green;" class="fas fa-check"></i> <a href="' + LINK_PRE + 'result?regatta=' + regatta['id'] + '">Ergebnisse</a></td>';
|
||||
} else {
|
||||
buf = 'Nicht verfügbar';
|
||||
}
|
||||
}
|
||||
tbody += '<td>' + buf + '</td>';
|
||||
|
||||
tbody += '<td><span style="white-space:nowrap;">' + parseFloat(regatta['rlf']).toFixed(2) + '</span></td>';
|
||||
|
||||
tbody += '</tr>';
|
||||
}
|
||||
$('#table-last').find('tbody').html(tbody);
|
||||
$('#p-last').hide();
|
||||
$('#table-last').show();
|
||||
} else {
|
||||
$('#table-last').hide();
|
||||
$('#p-last').show();
|
||||
}
|
||||
}
|
||||
@@ -22,13 +22,13 @@
|
||||
}
|
||||
|
||||
$template = $this->templates[$name];
|
||||
while (($pos = strpos($template, '$')) !== false) {
|
||||
$pos ++;
|
||||
while (($pos = strpos($template, '$$')) !== false) {
|
||||
$pos += 2;
|
||||
$pos2 = strpos($template, ';', $pos);
|
||||
if ($pos2 === false) return "<p>Syntax error in template '$name'!</p>";
|
||||
$ph = substr($template, $pos, $pos2 - $pos);
|
||||
if (!isset($params[$ph])) $params[$ph] = '';
|
||||
$template = str_replace('$' . $ph . ';', $params[$ph], $template);
|
||||
$template = str_replace('$$' . $ph . ';', $params[$ph], $template);
|
||||
}
|
||||
return $template;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<a id="$html-id;" class="btn btn-full rounded-s text-uppercase font-900 shadow-m bg-highlight $css-class;" href="$1;">
|
||||
$0;
|
||||
<a id="$$html-id;" class="btn btn-full rounded-s text-uppercase font-900 shadow-m bg-highlight $$css-class;" href="$$1;">
|
||||
$$0;
|
||||
</a>
|
||||
@@ -1,5 +1,5 @@
|
||||
<div id="$html-id;" class="card card-style">
|
||||
<div class="content $css-class;">
|
||||
$0;
|
||||
<div id="$$html-id;" class="card card-style">
|
||||
<div class="content $$css-class;">
|
||||
$$0;
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,3 +1,3 @@
|
||||
<i class="fa fa-exclamation-triangle fa-8x color-red2-dark"></i>
|
||||
<h1 class="fa-6x mt-5 font-900">$0;</h1>
|
||||
<h4 class="mb-5 mt-3">$1;</h4>
|
||||
<h1 class="fa-6x mt-5 font-900">$$0;</h1>
|
||||
<h4 class="mb-5 mt-3">$$1;</h4>
|
||||
@@ -1,10 +1,10 @@
|
||||
<div style="width: 100%; overflow-x: auto;">
|
||||
<table id="$html-id;" class="table table-striped table-bordered $css-class;">
|
||||
<table id="$$html-id;" class="table table-striped table-bordered $$css-class;">
|
||||
<thead>
|
||||
$0;
|
||||
$$0;
|
||||
</thead>
|
||||
<tbody>
|
||||
$1;
|
||||
$$1;
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
Reference in New Issue
Block a user