commit 09/02/2026
This commit is contained in:
431
html/webpage/assets/css/litepicker.css
Normal file
431
html/webpage/assets/css/litepicker.css
Normal file
@@ -0,0 +1,431 @@
|
|||||||
|
/* !
|
||||||
|
*
|
||||||
|
* ../css/litepicker.css
|
||||||
|
* Litepicker v2.0.12 (https://github.com/wakirin/Litepicker)
|
||||||
|
* Package: litepicker (https://www.npmjs.com/package/litepicker)
|
||||||
|
* License: MIT (https://github.com/wakirin/Litepicker/blob/master/LICENCE.md)
|
||||||
|
* Copyright 2019-2021 Rinat G.
|
||||||
|
*
|
||||||
|
* Hash: 2f11f1f0300ea13b17b5
|
||||||
|
* */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--litepicker-container-months-color-bg: #fff;
|
||||||
|
--litepicker-container-months-box-shadow-color: #ddd;
|
||||||
|
--litepicker-footer-color-bg: #fafafa;
|
||||||
|
--litepicker-footer-box-shadow-color: #ddd;
|
||||||
|
--litepicker-tooltip-color-bg: #fff;
|
||||||
|
--litepicker-month-header-color: #333;
|
||||||
|
--litepicker-button-prev-month-color: #9e9e9e;
|
||||||
|
--litepicker-button-next-month-color: #9e9e9e;
|
||||||
|
--litepicker-button-prev-month-color-hover: #2196f3;
|
||||||
|
--litepicker-button-next-month-color-hover: #2196f3;
|
||||||
|
--litepicker-month-width: calc(var(--litepicker-day-width) * 7);
|
||||||
|
--litepicker-month-weekday-color: #9e9e9e;
|
||||||
|
--litepicker-month-week-number-color: #9e9e9e;
|
||||||
|
--litepicker-day-width: 38px;
|
||||||
|
--litepicker-day-color: #333;
|
||||||
|
--litepicker-day-color-hover: #2196f3;
|
||||||
|
--litepicker-is-today-color: #f44336;
|
||||||
|
--litepicker-is-in-range-color: #bbdefb;
|
||||||
|
--litepicker-is-locked-color: #9e9e9e;
|
||||||
|
--litepicker-is-start-color: #fff;
|
||||||
|
--litepicker-is-start-color-bg: #2196f3;
|
||||||
|
--litepicker-is-end-color: #fff;
|
||||||
|
--litepicker-is-end-color-bg: #2196f3;
|
||||||
|
--litepicker-button-cancel-color: #fff;
|
||||||
|
--litepicker-button-cancel-color-bg: #9e9e9e;
|
||||||
|
--litepicker-button-apply-color: #fff;
|
||||||
|
--litepicker-button-apply-color-bg: #2196f3;
|
||||||
|
--litepicker-button-reset-color: #909090;
|
||||||
|
--litepicker-button-reset-color-hover: #2196f3;
|
||||||
|
--litepicker-highlighted-day-color: #333;
|
||||||
|
--litepicker-highlighted-day-color-bg: #ffeb3b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.show-week-numbers {
|
||||||
|
--litepicker-month-width: calc(var(--litepicker-day-width) * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||||
|
font-size: 0.8em;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker button {
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__main {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-ms-flex-wrap: wrap;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
background-color: var(--litepicker-container-months-color-bg);
|
||||||
|
border-radius: 5px;
|
||||||
|
-webkit-box-shadow: 0 0 5px var(--litepicker-container-months-box-shadow-color);
|
||||||
|
box-shadow: 0 0 5px var(--litepicker-container-months-box-shadow-color);
|
||||||
|
width: calc(var(--litepicker-month-width) + 10px);
|
||||||
|
-webkit-box-sizing: content-box;
|
||||||
|
box-sizing: content-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months.columns-2 {
|
||||||
|
width: calc((var(--litepicker-month-width) * 2) + 20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months.columns-3 {
|
||||||
|
width: calc((var(--litepicker-month-width) * 3) + 30px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months.columns-4 {
|
||||||
|
width: calc((var(--litepicker-month-width) * 4) + 40px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months.split-view .month-item-header .button-previous-month, .litepicker .container__months.split-view .month-item-header .button-next-month {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item {
|
||||||
|
padding: 5px;
|
||||||
|
width: var(--litepicker-month-width);
|
||||||
|
-webkit-box-sizing: content-box;
|
||||||
|
box-sizing: content-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-webkit-box-pack: justify;
|
||||||
|
-ms-flex-pack: justify;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-weight: 500;
|
||||||
|
padding: 10px 5px;
|
||||||
|
text-align: center;
|
||||||
|
-webkit-box-align: center;
|
||||||
|
-ms-flex-align: center;
|
||||||
|
align-items: center;
|
||||||
|
color: var(--litepicker-month-header-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header div {
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-ms-flex: 1;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header div > .month-item-name {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header div > .month-item-year {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header .reset-button {
|
||||||
|
color: var(--litepicker-button-reset-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header .reset-button > svg {
|
||||||
|
fill: var(--litepicker-button-reset-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header .reset-button * {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header .reset-button:hover {
|
||||||
|
color: var(--litepicker-button-reset-color-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header .reset-button:hover > svg {
|
||||||
|
fill: var(--litepicker-button-reset-color-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header .button-previous-month, .litepicker .container__months .month-item-header .button-next-month {
|
||||||
|
visibility: hidden;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 3px 5px;
|
||||||
|
border-radius: 3px;
|
||||||
|
-webkit-transition: color 0.3s, border 0.3s;
|
||||||
|
transition: color 0.3s, border 0.3s;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header .button-previous-month *, .litepicker .container__months .month-item-header .button-next-month * {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header .button-previous-month {
|
||||||
|
color: var(--litepicker-button-prev-month-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header .button-previous-month > svg, .litepicker .container__months .month-item-header .button-previous-month > img {
|
||||||
|
fill: var(--litepicker-button-prev-month-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header .button-previous-month:hover {
|
||||||
|
color: var(--litepicker-button-prev-month-color-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header .button-previous-month:hover > svg {
|
||||||
|
fill: var(--litepicker-button-prev-month-color-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header .button-next-month {
|
||||||
|
color: var(--litepicker-button-next-month-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header .button-next-month > svg, .litepicker .container__months .month-item-header .button-next-month > img {
|
||||||
|
fill: var(--litepicker-button-next-month-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header .button-next-month:hover {
|
||||||
|
color: var(--litepicker-button-next-month-color-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-header .button-next-month:hover > svg {
|
||||||
|
fill: var(--litepicker-button-next-month-color-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-weekdays-row {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
justify-self: center;
|
||||||
|
-webkit-box-pack: start;
|
||||||
|
-ms-flex-pack: start;
|
||||||
|
justify-content: flex-start;
|
||||||
|
color: var(--litepicker-month-weekday-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item-weekdays-row > div {
|
||||||
|
padding: 5px 0;
|
||||||
|
font-size: 85%;
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-ms-flex: 1;
|
||||||
|
flex: 1;
|
||||||
|
width: var(--litepicker-day-width);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item:first-child .button-previous-month {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item:last-child .button-next-month {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item.no-previous-month .button-previous-month {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__months .month-item.no-next-month .button-next-month {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__days {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-ms-flex-wrap: wrap;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-self: center;
|
||||||
|
-webkit-box-pack: start;
|
||||||
|
-ms-flex-pack: start;
|
||||||
|
justify-content: flex-start;
|
||||||
|
text-align: center;
|
||||||
|
-webkit-box-sizing: content-box;
|
||||||
|
box-sizing: content-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__days > div, .litepicker .container__days > a {
|
||||||
|
padding: 5px 0;
|
||||||
|
width: var(--litepicker-day-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__days .day-item {
|
||||||
|
color: var(--litepicker-day-color);
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 3px;
|
||||||
|
-webkit-transition: color 0.3s, border 0.3s;
|
||||||
|
transition: color 0.3s, border 0.3s;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__days .day-item:hover {
|
||||||
|
color: var(--litepicker-day-color-hover);
|
||||||
|
-webkit-box-shadow: inset 0 0 0 1px var(--litepicker-day-color-hover);
|
||||||
|
box-shadow: inset 0 0 0 1px var(--litepicker-day-color-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__days .day-item.is-today {
|
||||||
|
color: var(--litepicker-is-today-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__days .day-item.is-locked {
|
||||||
|
color: var(--litepicker-is-locked-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__days .day-item.is-locked:hover {
|
||||||
|
color: var(--litepicker-is-locked-color);
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__days .day-item.is-in-range {
|
||||||
|
background-color: var(--litepicker-is-in-range-color);
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__days .day-item.is-start-date {
|
||||||
|
color: var(--litepicker-is-start-color);
|
||||||
|
background-color: var(--litepicker-is-start-color-bg);
|
||||||
|
border-top-left-radius: 5px;
|
||||||
|
border-bottom-left-radius: 5px;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__days .day-item.is-start-date.is-flipped {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-top-right-radius: 5px;
|
||||||
|
border-bottom-right-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__days .day-item.is-end-date {
|
||||||
|
color: var(--litepicker-is-end-color);
|
||||||
|
background-color: var(--litepicker-is-end-color-bg);
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-top-right-radius: 5px;
|
||||||
|
border-bottom-right-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__days .day-item.is-end-date.is-flipped {
|
||||||
|
border-top-left-radius: 5px;
|
||||||
|
border-bottom-left-radius: 5px;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__days .day-item.is-start-date.is-end-date {
|
||||||
|
border-top-left-radius: 5px;
|
||||||
|
border-bottom-left-radius: 5px;
|
||||||
|
border-top-right-radius: 5px;
|
||||||
|
border-bottom-right-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__days .day-item.is-highlighted {
|
||||||
|
color: var(--litepicker-highlighted-day-color);
|
||||||
|
background-color: var(--litepicker-highlighted-day-color-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__days .week-number {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-webkit-box-align: center;
|
||||||
|
-ms-flex-align: center;
|
||||||
|
align-items: center;
|
||||||
|
-webkit-box-pack: center;
|
||||||
|
-ms-flex-pack: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: var(--litepicker-month-week-number-color);
|
||||||
|
font-size: 85%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__footer {
|
||||||
|
text-align: right;
|
||||||
|
padding: 10px 5px;
|
||||||
|
margin: 0 5px;
|
||||||
|
background-color: var(--litepicker-footer-color-bg);
|
||||||
|
-webkit-box-shadow: inset 0px 3px 3px 0px var(--litepicker-footer-box-shadow-color);
|
||||||
|
box-shadow: inset 0px 3px 3px 0px var(--litepicker-footer-box-shadow-color);
|
||||||
|
border-bottom-left-radius: 5px;
|
||||||
|
border-bottom-right-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__footer .preview-date-range {
|
||||||
|
margin-right: 10px;
|
||||||
|
font-size: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__footer .button-cancel {
|
||||||
|
background-color: var(--litepicker-button-cancel-color-bg);
|
||||||
|
color: var(--litepicker-button-cancel-color);
|
||||||
|
border: 0;
|
||||||
|
padding: 3px 7px 4px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__footer .button-cancel * {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__footer .button-apply {
|
||||||
|
background-color: var(--litepicker-button-apply-color-bg);
|
||||||
|
color: var(--litepicker-button-apply-color);
|
||||||
|
border: 0;
|
||||||
|
padding: 3px 7px 4px;
|
||||||
|
border-radius: 3px;
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__footer .button-apply:disabled {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__footer .button-apply * {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__tooltip {
|
||||||
|
position: absolute;
|
||||||
|
margin-top: -4px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: var(--litepicker-tooltip-color-bg);
|
||||||
|
-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.25);
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.25);
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 11px;
|
||||||
|
pointer-events: none;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__tooltip:before {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -5px;
|
||||||
|
left: calc(50% - 5px);
|
||||||
|
border-top: 5px solid rgba(0,0,0,0.12);
|
||||||
|
border-right: 5px solid transparent;
|
||||||
|
border-left: 5px solid transparent;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
.litepicker .container__tooltip:after {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -4px;
|
||||||
|
left: calc(50% - 4px);
|
||||||
|
border-top: 4px solid var(--litepicker-tooltip-color-bg);
|
||||||
|
border-right: 4px solid transparent;
|
||||||
|
border-left: 4px solid transparent;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
12
html/webpage/assets/js/litepicker.js
Normal file
12
html/webpage/assets/js/litepicker.js
Normal file
File diff suppressed because one or more lines are too long
@@ -21,7 +21,7 @@ dtLog = null;
|
|||||||
function fill_logtablebody(vv) {
|
function fill_logtablebody(vv) {
|
||||||
dtLog.clear();
|
dtLog.clear();
|
||||||
if (!Array.isArray(vv) || vv.length === 0) {
|
if (!Array.isArray(vv) || vv.length === 0) {
|
||||||
$('#btnExport').prop('disabled', true);
|
//$('#btnExport').prop('disabled', true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dtLog.rows.add(vv);
|
dtLog.rows.add(vv);
|
||||||
@@ -29,7 +29,7 @@ function fill_logtablebody(vv) {
|
|||||||
|
|
||||||
|
|
||||||
$('#tablesize').text("Table Size: " + vv.length);
|
$('#tablesize').text("Table Size: " + vv.length);
|
||||||
$('#btnExport').prop('disabled', false);
|
//$('#btnExport').prop('disabled', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,8 +43,10 @@ function reloadLogs(APIURL = "Log/", date, filter) {
|
|||||||
date: date,
|
date: date,
|
||||||
filter: filter
|
filter: filter
|
||||||
})
|
})
|
||||||
|
console.log("Loading logs with params: " + params.toString());
|
||||||
window.logdata = [];
|
window.logdata = [];
|
||||||
fetchAPI(APIURL + "List?" + params.toString(), "GET", {}, null, (okdata) => {
|
fetchAPI(APIURL + "List?" + params.toString(), "GET", {}, null, (okdata) => {
|
||||||
|
console.log("Logs loaded: " + okdata.length);
|
||||||
if (Array.isArray(okdata)) {
|
if (Array.isArray(okdata)) {
|
||||||
window.logdata.push(...okdata);
|
window.logdata.push(...okdata);
|
||||||
fill_logtablebody(window.logdata);
|
fill_logtablebody(window.logdata);
|
||||||
@@ -54,16 +56,33 @@ function reloadLogs(APIURL = "Log/", date, filter) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
datepicker = null;
|
||||||
|
$btnGet = null;
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
console.log("log.js ready");
|
console.log("log.js ready");
|
||||||
let selectedlogdate = "";
|
let selectedlogdate = "";
|
||||||
let logfilter = "";
|
let logfilter = "";
|
||||||
let APIURL = "Log/";
|
let APIURL = "Log/";
|
||||||
|
$btnGet = $('#btnGet');
|
||||||
|
|
||||||
|
datepicker = new Litepicker({
|
||||||
|
element: document.getElementById('logdate'),
|
||||||
|
format: 'DD/MM/YYYY',
|
||||||
|
lang: 'en-US',
|
||||||
|
autoApply: true,
|
||||||
|
singleMode: true,
|
||||||
|
startDate: new Date(),
|
||||||
|
onSelect: (date) => {
|
||||||
|
selectedlogdate = date.format('DD/MM/YYYY');
|
||||||
|
console.log("Selected date: " + selectedlogdate);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
if (dtLog === null) {
|
if (dtLog === null) {
|
||||||
dtLog = new DataTable('#logtable', {
|
dtLog = new DataTable('#logtable', {
|
||||||
|
dom: 'Bfrtip',
|
||||||
data: [],
|
data: [],
|
||||||
pageLength: 25,
|
pageLength: 25,
|
||||||
columns: [
|
columns: [
|
||||||
@@ -72,36 +91,42 @@ $(document).ready(function () {
|
|||||||
{ title: "Time", data: "timenya" },
|
{ title: "Time", data: "timenya" },
|
||||||
{ title: "Machine", data: "machine" },
|
{ title: "Machine", data: "machine" },
|
||||||
{ title: "Description", data: "description" }
|
{ title: "Description", data: "description" }
|
||||||
]
|
],
|
||||||
|
buttons: ['print', 'pdf', 'excel']
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// findalldate is checkbox, if checked will disable datepicker
|
||||||
if (!$('#logdate').val()) {
|
$('#findalldate').off('change').on('change', function () {
|
||||||
const today = new Date();
|
if ($(this).is(':checked')) {
|
||||||
const dd = String(today.getDate()).padStart(2, '0');
|
datepicker.disabled = true;
|
||||||
const mm = String(today.getMonth() + 1).padStart(2, '0');
|
selectedlogdate = "alldate";
|
||||||
const yyyy = today.getFullYear();
|
console.log("Find all date checked, omitting date filter");
|
||||||
$('#logdate').val(`${yyyy}-${mm}-${dd}`);
|
} else {
|
||||||
selectedlogdate = `${dd}-${mm}-${yyyy}`;
|
datepicker.disabled = false;
|
||||||
reloadLogs(APIURL, selectedlogdate, logfilter);
|
const date = datepicker.getDate();
|
||||||
}
|
selectedlogdate = date.format('DD/MM/YYYY');
|
||||||
$('#logdate').off('change').on('change', function () {
|
console.log("Find all date unchecked, selected date: " + selectedlogdate);
|
||||||
const selected = $(this).val();
|
|
||||||
if (selected) {
|
|
||||||
const [year, month, day] = selected.split('-');
|
|
||||||
selectedlogdate = `${day}-${month}-${year}`;
|
|
||||||
reloadLogs(APIURL, selectedlogdate, logfilter);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#searchfilter').off('input').on('input', function () {
|
$('#searchfilter').off('input').on('input', function () {
|
||||||
logfilter = $(this).val();
|
logfilter = $(this).val();
|
||||||
|
//reloadLogs(APIURL, selectedlogdate, logfilter);
|
||||||
|
});
|
||||||
|
$btnGet.click(function () {
|
||||||
|
let checked = $('#findalldate').is(':checked');
|
||||||
|
if (checked && logfilter.trim() === "") {
|
||||||
|
alert("Please enter a filter when 'Find All Date' is checked to avoid large data load.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//$(this).data('selectedlogdate', selectedlogdate);
|
||||||
|
//$(this).data('logfilter', logfilter);
|
||||||
reloadLogs(APIURL, selectedlogdate, logfilter);
|
reloadLogs(APIURL, selectedlogdate, logfilter);
|
||||||
});
|
});
|
||||||
$('#btnExport').off('click').on('click', function () {
|
|
||||||
DoExport(APIURL, "log.xlsx", { date: selectedlogdate, filter: logfilter });
|
|
||||||
});
|
|
||||||
|
|
||||||
|
selectedlogdate = datepicker.getDate().format('DD/MM/YYYY');
|
||||||
|
console.log("Initial selected date: " + selectedlogdate);
|
||||||
|
$btnGet.trigger('click'); // load logs on page load
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -22,6 +22,15 @@ window.schedulebankdata = [];
|
|||||||
window.selectedschedulerow = null;
|
window.selectedschedulerow = null;
|
||||||
|
|
||||||
dtScheduleBank = null;
|
dtScheduleBank = null;
|
||||||
|
dtTodaySchedule = null;
|
||||||
|
|
||||||
|
function fill_todayscheduletablebody(vv) {
|
||||||
|
dtTodaySchedule.clear();
|
||||||
|
if (!Array.isArray(vv) || vv.length === 0) return;
|
||||||
|
|
||||||
|
dtTodaySchedule.rows.add(vv);
|
||||||
|
dtTodaySchedule.draw();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill schedulebank table body with values
|
* Fill schedulebank table body with values
|
||||||
@@ -117,7 +126,19 @@ function reloadTimerBank(APIURL = "ScheduleBank/") {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reloadTodaySchedule(APIURL = "ScheduleBank/") {
|
||||||
|
fetchAPI(APIURL + "TodaySchedule", "GET", {}, null, (okdata) => {
|
||||||
|
if (Array.isArray(okdata)) {
|
||||||
|
console.log("Today's Schedule: ", okdata);
|
||||||
|
fill_todayscheduletablebody(okdata);
|
||||||
|
}
|
||||||
|
}, (errdata) => {
|
||||||
|
alert("Error loading today's schedule : " + errdata.message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
dayViewMode = 'all'; // all, everyday, monday, tuesday, wednesday, thursday, friday, saturday, sunday
|
dayViewMode = 'all'; // all, everyday, monday, tuesday, wednesday, thursday, friday, saturday, sunday
|
||||||
|
scheduledate = null; // Litepicker instance for schedule date selection
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
console.log("schedulebank.js loaded successfully");
|
console.log("schedulebank.js loaded successfully");
|
||||||
@@ -169,6 +190,26 @@ $(document).ready(function () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dtTodaySchedule === null) {
|
||||||
|
dtTodaySchedule = new DataTable('#todaytable', {
|
||||||
|
dom: 'Bfrtip',
|
||||||
|
data: [],
|
||||||
|
pageLength: 25,
|
||||||
|
columns: [
|
||||||
|
{ title: "No", data: "index" },
|
||||||
|
{ title: "Description", data: "description" },
|
||||||
|
{ title: "Day", data: "day" },
|
||||||
|
{ title: "Time", data: "time" },
|
||||||
|
{ title: "Message", data: "soundpath" },
|
||||||
|
{ title: "Repeat", data: "repeat" },
|
||||||
|
{ title: "Enable", data: "enable" },
|
||||||
|
{ title: "Broadcast Zones", data: "broadcastZones" },
|
||||||
|
{ title: "Language", data: "language" }
|
||||||
|
],
|
||||||
|
buttons: ['print', 'pdf']
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
$.fn.dataTable.ext.search.push(function (settings, data, dataIndex, rowData) {
|
$.fn.dataTable.ext.search.push(function (settings, data, dataIndex, rowData) {
|
||||||
if (settings.nTable.id !== 'schedulebanktable') return true;
|
if (settings.nTable.id !== 'schedulebanktable') return true;
|
||||||
switch (dayViewMode) {
|
switch (dayViewMode) {
|
||||||
@@ -223,16 +264,30 @@ $(document).ready(function () {
|
|||||||
let $weeklyselect = $schedulemodal.find('#weeklyselect');
|
let $weeklyselect = $schedulemodal.find('#weeklyselect');
|
||||||
// radio button for specific date
|
// radio button for specific date
|
||||||
let $schedulespecialdate = $schedulemodal.find('#schedulespecialdate');
|
let $schedulespecialdate = $schedulemodal.find('#schedulespecialdate');
|
||||||
|
|
||||||
|
scheduledate = new Litepicker({
|
||||||
|
element: document.getElementById('scheduledate'),
|
||||||
|
format: 'DD/MM/YYYY',
|
||||||
|
lang: 'en-US',
|
||||||
|
autoApply: true,
|
||||||
|
singleMode: true,
|
||||||
|
startDate: new Date(),
|
||||||
|
onSelect: (date) => {
|
||||||
|
console.log("Selected special date: " + date.format('DD/MM/YYYY'));
|
||||||
|
}
|
||||||
|
})
|
||||||
// date input
|
// date input
|
||||||
let $scheduledate = $schedulemodal.find('#scheduledate');
|
//let $scheduledate = $schedulemodal.find('#scheduledate');
|
||||||
// select2 for language
|
// select2 for language
|
||||||
let $languageselect = $schedulemodal.find('#languageselect');
|
let $languageselect = $schedulemodal.find('#languageselect');
|
||||||
|
|
||||||
$schedulespecialdate.off('change').on('change', function () {
|
$schedulespecialdate.off('change').on('change', function () {
|
||||||
if ($(this).is(':checked')) {
|
if ($(this).is(':checked')) {
|
||||||
$scheduledate.prop('disabled', false);
|
//$scheduledate.prop('disabled', false);
|
||||||
|
scheduledate.disabled = false
|
||||||
} else {
|
} else {
|
||||||
$scheduledate.prop('disabled', true);
|
//$scheduledate.prop('disabled', true);
|
||||||
|
scheduledate.disabled = true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -261,7 +316,8 @@ $(document).ready(function () {
|
|||||||
dropdownParent: $('#schedulemodal')
|
dropdownParent: $('#schedulemodal')
|
||||||
});
|
});
|
||||||
|
|
||||||
$scheduledate.prop('disabled', true).val('');
|
//$scheduledate.prop('disabled', true).val('');
|
||||||
|
scheduledate.disabled = true;
|
||||||
$schedulezones.empty().select2({
|
$schedulezones.empty().select2({
|
||||||
data: window.BroadcastZoneList.map(zone => ({ id: zone.description, text: zone.description })),
|
data: window.BroadcastZoneList.map(zone => ({ id: zone.description, text: zone.description })),
|
||||||
placeholder: 'Select broadcast zones',
|
placeholder: 'Select broadcast zones',
|
||||||
@@ -284,24 +340,28 @@ $(document).ready(function () {
|
|||||||
$scheduleeveryday.off('change').on('change', function () {
|
$scheduleeveryday.off('change').on('change', function () {
|
||||||
if ($(this).is(':checked')) {
|
if ($(this).is(':checked')) {
|
||||||
$weeklyselect.prop('disabled', true);
|
$weeklyselect.prop('disabled', true);
|
||||||
$scheduledate.prop('disabled', true);
|
//$scheduledate.prop('disabled', true);
|
||||||
|
scheduledate.disabled = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$scheduleweekly.off('change').on('change', function () {
|
$scheduleweekly.off('change').on('change', function () {
|
||||||
if ($(this).is(':checked')) {
|
if ($(this).is(':checked')) {
|
||||||
$weeklyselect.prop('disabled', false);
|
$weeklyselect.prop('disabled', false);
|
||||||
$scheduledate.prop('disabled', true);
|
//$scheduledate.prop('disabled', true);
|
||||||
|
scheduledate.disabled = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$schedulespecialdate.off('change').on('change', function () {
|
$schedulespecialdate.off('change').on('change', function () {
|
||||||
if ($(this).is(':checked')) {
|
if ($(this).is(':checked')) {
|
||||||
$weeklyselect.prop('disabled', true);
|
$weeklyselect.prop('disabled', true);
|
||||||
$scheduledate.prop('disabled', false);
|
//$scheduledate.prop('disabled', false);
|
||||||
|
scheduledate.disabled = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
reloadTimerBank(APIURL);
|
reloadTimerBank(APIURL);
|
||||||
|
reloadTodaySchedule(APIURL);
|
||||||
reloadBroadcastZones();
|
reloadBroadcastZones();
|
||||||
getLanguages();
|
getLanguages();
|
||||||
getScheduledDays();
|
getScheduledDays();
|
||||||
@@ -309,6 +369,7 @@ $(document).ready(function () {
|
|||||||
$btnClear.click(() => {
|
$btnClear.click(() => {
|
||||||
DoClear(APIURL, "Timerbank", (okdata) => {
|
DoClear(APIURL, "Timerbank", (okdata) => {
|
||||||
reloadTimerBank(APIURL);
|
reloadTimerBank(APIURL);
|
||||||
|
reloadTodaySchedule(APIURL);
|
||||||
alert("Success clear schedulebank : " + okdata.message);
|
alert("Success clear schedulebank : " + okdata.message);
|
||||||
}, (errdata) => {
|
}, (errdata) => {
|
||||||
alert("Error clear schedulebank : " + errdata.message);
|
alert("Error clear schedulebank : " + errdata.message);
|
||||||
@@ -317,7 +378,9 @@ $(document).ready(function () {
|
|||||||
});
|
});
|
||||||
$btnAdd.click(() => {
|
$btnAdd.click(() => {
|
||||||
$schedulemodal.modal('show');
|
$schedulemodal.modal('show');
|
||||||
|
|
||||||
clearScheduleModal();
|
clearScheduleModal();
|
||||||
|
$scheduleeveryday.prop('checked', true).trigger('click');
|
||||||
|
|
||||||
$schedulemodal.off('click.scheduleclose').on('click.scheduleclose', '#scheduleclose', function () {
|
$schedulemodal.off('click.scheduleclose').on('click.scheduleclose', '#scheduleclose', function () {
|
||||||
$schedulemodal.modal('hide');
|
$schedulemodal.modal('hide');
|
||||||
@@ -333,7 +396,7 @@ $(document).ready(function () {
|
|||||||
if ($scheduleeveryday.is(':checked')) {
|
if ($scheduleeveryday.is(':checked')) {
|
||||||
_Day = "Everyday";
|
_Day = "Everyday";
|
||||||
} else if ($schedulespecialdate.is(':checked')) {
|
} else if ($schedulespecialdate.is(':checked')) {
|
||||||
_Day = Convert_input_date_to_string($scheduledate.val());
|
_Day = Convert_input_date_to_string(scheduledate.getDate().format('DD/MM/YYYY'));
|
||||||
} else if ($scheduleweekly.is(':checked')) {
|
} else if ($scheduleweekly.is(':checked')) {
|
||||||
_Day = $weeklyselect.val();
|
_Day = $weeklyselect.val();
|
||||||
}
|
}
|
||||||
@@ -363,6 +426,7 @@ $(document).ready(function () {
|
|||||||
|
|
||||||
fetchAPI(APIURL + "Add", "POST", {}, scheduleObj, (okdata) => {
|
fetchAPI(APIURL + "Add", "POST", {}, scheduleObj, (okdata) => {
|
||||||
reloadTimerBank(APIURL);
|
reloadTimerBank(APIURL);
|
||||||
|
reloadTodaySchedule(APIURL);
|
||||||
alert("Success add schedule: " + okdata.message);
|
alert("Success add schedule: " + okdata.message);
|
||||||
}, (errdata) => {
|
}, (errdata) => {
|
||||||
alert("Error add schedule: " + errdata.message);
|
alert("Error add schedule: " + errdata.message);
|
||||||
@@ -393,6 +457,7 @@ $(document).ready(function () {
|
|||||||
if (confirm(`Are you sure to delete schedule [${sr.index}] Description=${sr.description}?`)) {
|
if (confirm(`Are you sure to delete schedule [${sr.index}] Description=${sr.description}?`)) {
|
||||||
fetchAPI(APIURL + "DeleteByIndex/" + sr.index, "DELETE", {}, null, (okdata) => {
|
fetchAPI(APIURL + "DeleteByIndex/" + sr.index, "DELETE", {}, null, (okdata) => {
|
||||||
reloadTimerBank(APIURL);
|
reloadTimerBank(APIURL);
|
||||||
|
reloadTodaySchedule(APIURL);
|
||||||
alert("Success delete schedule : " + okdata.message);
|
alert("Success delete schedule : " + okdata.message);
|
||||||
}, (errdata) => {
|
}, (errdata) => {
|
||||||
alert("Error delete schedule : " + errdata.message);
|
alert("Error delete schedule : " + errdata.message);
|
||||||
@@ -438,7 +503,8 @@ $(document).ready(function () {
|
|||||||
$weeklyselect.val(null).trigger('change');
|
$weeklyselect.val(null).trigger('change');
|
||||||
$weeklyselect.prop('disabled', true);
|
$weeklyselect.prop('disabled', true);
|
||||||
|
|
||||||
$scheduledate.prop('disabled', true);
|
//$scheduledate.prop('disabled', true);
|
||||||
|
scheduledate.disabled = true;
|
||||||
break;
|
break;
|
||||||
case 'Sunday':
|
case 'Sunday':
|
||||||
case 'Monday':
|
case 'Monday':
|
||||||
@@ -452,7 +518,8 @@ $(document).ready(function () {
|
|||||||
$weeklyselect.val(sr.Day).trigger('change');
|
$weeklyselect.val(sr.Day).trigger('change');
|
||||||
$weeklyselect.prop('disabled', false);
|
$weeklyselect.prop('disabled', false);
|
||||||
|
|
||||||
$scheduledate.prop('disabled', true);
|
//$scheduledate.prop('disabled', true);
|
||||||
|
scheduledate.disabled = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.log("Assuming special date for Day: ", sr.Day);
|
console.log("Assuming special date for Day: ", sr.Day);
|
||||||
@@ -461,8 +528,10 @@ $(document).ready(function () {
|
|||||||
if (/^\d{2}\/\d{2}\/\d{4}$/.test(sr.Day)) {
|
if (/^\d{2}\/\d{2}\/\d{4}$/.test(sr.Day)) {
|
||||||
$schedulespecialdate.prop('checked', true);
|
$schedulespecialdate.prop('checked', true);
|
||||||
|
|
||||||
$scheduledate.val(Convert_string_to_input_date(sr.Day));
|
//$scheduledate.val(Convert_string_to_input_date(sr.Day));
|
||||||
$scheduledate.prop('disabled', false);
|
// $scheduledate.prop('disabled', false);
|
||||||
|
scheduledate.setDate(dayjs(sr.Day,'DD/MM/YYYY'));
|
||||||
|
scheduledate.disabled = false;
|
||||||
|
|
||||||
$weeklyselect.val(null).trigger('change');
|
$weeklyselect.val(null).trigger('change');
|
||||||
$weeklyselect.prop('disabled', true);
|
$weeklyselect.prop('disabled', true);
|
||||||
@@ -484,7 +553,8 @@ $(document).ready(function () {
|
|||||||
Day = "Everyday";
|
Day = "Everyday";
|
||||||
} else if ($schedulespecialdate.is(':checked')) {
|
} else if ($schedulespecialdate.is(':checked')) {
|
||||||
// convert date from yyyy-mm-dd to dd/mm/yyyy
|
// convert date from yyyy-mm-dd to dd/mm/yyyy
|
||||||
Day = Convert_input_date_to_string($scheduledate.val());
|
//Day = Convert_input_date_to_string($scheduledate.val());
|
||||||
|
Day = scheduledate.getDate().format('DD/MM/YYYY');
|
||||||
} else if ($scheduleweekly.is(':checked')) {
|
} else if ($scheduleweekly.is(':checked')) {
|
||||||
Day = $weeklyselect.val();
|
Day = $weeklyselect.val();
|
||||||
}
|
}
|
||||||
@@ -516,6 +586,7 @@ $(document).ready(function () {
|
|||||||
fetchAPI(APIURL + "UpdateByIndex/" + sr.index, "PATCH", {}, scheduleObj, (okdata) => {
|
fetchAPI(APIURL + "UpdateByIndex/" + sr.index, "PATCH", {}, scheduleObj, (okdata) => {
|
||||||
alert("Success edit schedule: " + okdata.message);
|
alert("Success edit schedule: " + okdata.message);
|
||||||
reloadTimerBank(APIURL);
|
reloadTimerBank(APIURL);
|
||||||
|
reloadTodaySchedule(APIURL);
|
||||||
}, (errdata) => {
|
}, (errdata) => {
|
||||||
alert("Error edit schedule: " + errdata.message);
|
alert("Error edit schedule: " + errdata.message);
|
||||||
});
|
});
|
||||||
@@ -537,6 +608,7 @@ $(document).ready(function () {
|
|||||||
$btnImport.click(() => {
|
$btnImport.click(() => {
|
||||||
DoImport(APIURL, (okdata) => {
|
DoImport(APIURL, (okdata) => {
|
||||||
reloadTimerBank(APIURL);
|
reloadTimerBank(APIURL);
|
||||||
|
reloadTodaySchedule(APIURL);
|
||||||
alert("Success import schedulebank from XLSX : " + okdata.message);
|
alert("Success import schedulebank from XLSX : " + okdata.message);
|
||||||
}, (errdata) => {
|
}, (errdata) => {
|
||||||
alert("Error importing schedulebank from XLSX : " + errdata.message);
|
alert("Error importing schedulebank from XLSX : " + errdata.message);
|
||||||
|
|||||||
@@ -292,9 +292,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
||||||
<script src="assets/js/bs-init.js"></script>
|
<script src="assets/js/bs-init.js"></script>
|
||||||
|
<script src="assets/js/datatables.js"></script>
|
||||||
<script src="assets/js/soundchannel.js"></script>
|
<script src="assets/js/soundchannel.js"></script>
|
||||||
<script src="assets/js/broadcastzones.js"></script>
|
<script src="assets/js/broadcastzones.js"></script>
|
||||||
<script src="assets/js/datatables.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -159,10 +159,10 @@
|
|||||||
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
||||||
<script src="assets/js/bs-init.js"></script>
|
<script src="assets/js/bs-init.js"></script>
|
||||||
<script src="assets/js/jquery-3.7.1.min.js"></script>
|
<script src="assets/js/jquery-3.7.1.min.js"></script>
|
||||||
<script src="assets/js/script.js"></script>
|
|
||||||
<script src="assets/js/all.min.js"></script>
|
|
||||||
<script src="assets/js/datatables.js"></script>
|
|
||||||
<script src="assets/js/select2.min.js"></script>
|
<script src="assets/js/select2.min.js"></script>
|
||||||
|
<script src="assets/js/datatables.js"></script>
|
||||||
|
<script src="assets/js/all.min.js"></script>
|
||||||
|
<script src="assets/js/script.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -119,10 +119,10 @@
|
|||||||
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
||||||
<script src="assets/js/bs-init.js"></script>
|
<script src="assets/js/bs-init.js"></script>
|
||||||
<script src="assets/js/jquery-3.7.1.min.js"></script>
|
<script src="assets/js/jquery-3.7.1.min.js"></script>
|
||||||
<script src="assets/js/script.js"></script>
|
|
||||||
<script src="assets/js/all.min.js"></script>
|
|
||||||
<script src="assets/js/datatables.js"></script>
|
|
||||||
<script src="assets/js/select2.min.js"></script>
|
<script src="assets/js/select2.min.js"></script>
|
||||||
|
<script src="assets/js/datatables.js"></script>
|
||||||
|
<script src="assets/js/all.min.js"></script>
|
||||||
|
<script src="assets/js/script.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -99,8 +99,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
||||||
<script src="assets/js/bs-init.js"></script>
|
<script src="assets/js/bs-init.js"></script>
|
||||||
<script src="assets/js/languagelink.js"></script>
|
|
||||||
<script src="assets/js/datatables.js"></script>
|
<script src="assets/js/datatables.js"></script>
|
||||||
|
<script src="assets/js/languagelink.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
<link rel="stylesheet" href="assets/css/FontAwesome.css">
|
<link rel="stylesheet" href="assets/css/FontAwesome.css">
|
||||||
<link rel="stylesheet" href="assets/css/bss-overrides.css">
|
<link rel="stylesheet" href="assets/css/bss-overrides.css">
|
||||||
<link rel="stylesheet" href="assets/css/datatables.css">
|
<link rel="stylesheet" href="assets/css/datatables.css">
|
||||||
|
<link rel="stylesheet" href="assets/css/litepicker.css">
|
||||||
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
|
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
|
||||||
<link rel="stylesheet" href="assets/css/styles.css">
|
<link rel="stylesheet" href="assets/css/styles.css">
|
||||||
</head>
|
</head>
|
||||||
@@ -26,16 +27,26 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-4 col-sm-4 col-md-2 col-lg-2 col-xl-2">
|
<div class="col-5 ms-1 me-1">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-auto">
|
||||||
<p class="text-add">Select Log Date</p>
|
<p class="text-add">Select Log Date</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4 col-sm-4 col-md-2 col-lg-2 col-xl-2"><input id="logdate" class="form-control" type="date"></div>
|
<div class="col-auto"><input type="text" id="logdate" class="form-control"></div>
|
||||||
<div class="col-4 col-sm-4 col-md-2 col-lg-2 col-xl-2"><button class="btn w-100 pad-button btn-round-basic color-import" id="btnExport" type="button">Export</button></div>
|
<div class="col">
|
||||||
<div class="col-md-2 col-lg-2 col-xl-2"></div>
|
<div class="form-check w-100 h-100 align-content-center"><input class="form-check-input" type="checkbox" id="findalldate"><label class="form-check-label" for="formCheck-1">All Date</label></div>
|
||||||
<div class="col-4 col-sm-4 col-md-2 col-lg-2 col-xl-2 d-none">
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-5 ms-1 me-1">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-auto">
|
||||||
<p class="text-add">Search</p>
|
<p class="text-add">Search</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4 col-sm-4 col-md-2 col-lg-2 col-xl-2 d-none"><input type="text" id="searchfilter" class="form-control" placeholder="Search Filter"></div>
|
<div class="col"><input type="text" id="searchfilter" class="form-control" placeholder="Search Filter"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col ms-1 me-1"><button class="btn w-100 pad-button btn-round-basic color-import" id="btnGet" type="button">Get</button></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
@@ -60,8 +71,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
||||||
<script src="assets/js/bs-init.js"></script>
|
<script src="assets/js/bs-init.js"></script>
|
||||||
<script src="assets/js/log.js"></script>
|
<script src="assets/js/litepicker.js"></script>
|
||||||
<script src="assets/js/datatables.js"></script>
|
<script src="assets/js/datatables.js"></script>
|
||||||
|
<script src="assets/js/log.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -136,8 +136,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
||||||
<script src="assets/js/bs-init.js"></script>
|
<script src="assets/js/bs-init.js"></script>
|
||||||
<script src="assets/js/messagebank.js"></script>
|
|
||||||
<script src="assets/js/datatables.js"></script>
|
<script src="assets/js/datatables.js"></script>
|
||||||
|
<script src="assets/js/messagebank.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -120,8 +120,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
||||||
<script src="assets/js/bs-init.js"></script>
|
<script src="assets/js/bs-init.js"></script>
|
||||||
<script src="assets/js/soundbank.js"></script>
|
|
||||||
<script src="assets/js/datatables.js"></script>
|
<script src="assets/js/datatables.js"></script>
|
||||||
|
<script src="assets/js/soundbank.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
<link rel="stylesheet" href="assets/css/FontAwesome.css">
|
<link rel="stylesheet" href="assets/css/FontAwesome.css">
|
||||||
<link rel="stylesheet" href="assets/css/bss-overrides.css">
|
<link rel="stylesheet" href="assets/css/bss-overrides.css">
|
||||||
<link rel="stylesheet" href="assets/css/datatables.css">
|
<link rel="stylesheet" href="assets/css/datatables.css">
|
||||||
|
<link rel="stylesheet" href="assets/css/litepicker.css">
|
||||||
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
|
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
|
||||||
<link rel="stylesheet" href="assets/css/styles.css">
|
<link rel="stylesheet" href="assets/css/styles.css">
|
||||||
</head>
|
</head>
|
||||||
@@ -25,46 +26,6 @@
|
|||||||
<h2 style="text-align: center;">Schedule Bank</h2>
|
<h2 style="text-align: center;">Schedule Bank</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row d-none pad-row-search">
|
|
||||||
<div class="col-md-7 col-lg-7 col-xl-7"></div>
|
|
||||||
<div class="col-2 col-sm-2 col-md-2 col-lg-2 col-xl-2 search">
|
|
||||||
<p class="text-add">Search</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-10 col-sm-10 col-md-3 col-lg-3 col-xl-3"><input class="w-100 form-control" type="text" id="findschedule" placeholder="Search keyword" name="findsoundbank"></div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-3 col-sm-3 col-md-3 col-lg-2 col-xl-2"><button class="btn w-100 pad-button btn-round-basic color-add" id="btnClear" type="button">Clear</button></div>
|
|
||||||
<div class="col-3 col-sm-3 col-md-3 col-lg-2 col-xl-2"><button class="btn w-100 pad-button btn-round-basic color-add" id="btnAdd" type="button">Add</button></div>
|
|
||||||
<div class="col-3 col-sm-3 col-md-3 col-lg-2 col-xl-2"><button class="btn w-100 pad-button btn-round-basic color-remove" id="btnRemove" type="button">Remove</button></div>
|
|
||||||
<div class="col-3 col-sm-3 col-md-3 col-lg-2 col-xl-2"><button class="btn w-100 pad-button btn-round-basic color-edit" id="btnEdit" type="button">Edit</button></div>
|
|
||||||
<div class="col-6 col-sm-6 col-md-6 col-lg-2 col-xl-2"><button class="btn w-100 pad-button btn-round-basic color-import" id="btnExport" type="button">Export</button></div>
|
|
||||||
<div class="col-6 col-sm-6 col-md-6 col-lg-2 col-xl-2"><button class="btn w-100 pad-button btn-round-basic color-import" id="btnImport" type="button">Import</button></div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<p id="tablesize" class="text-add" style="text-align: center;">Table Length : N/A</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table" id="schedulebanktable">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="class05">No</th>
|
|
||||||
<th class="class15">Description</th>
|
|
||||||
<th class="class15">Day</th>
|
|
||||||
<th class="class10">Time</th>
|
|
||||||
<th class="class15">Sound Path</th>
|
|
||||||
<th class="class10">Repeat</th>
|
|
||||||
<th class="class05">Enable</th>
|
|
||||||
<th class="class15">Broadcast Zones</th>
|
|
||||||
<th class="class10">Language</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="schedulebanktablebody"></tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal fade" role="dialog" tabindex="-1" id="schedulemodal">
|
<div class="modal fade" role="dialog" tabindex="-1" id="schedulemodal">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
@@ -106,10 +67,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row py-2">
|
<div class="row py-2">
|
||||||
<div class="col-7 col-sm-7 col-md-7 col-lg-6 col-xl-6 pad-day">
|
<div class="col-auto pad-day">
|
||||||
<div class="form-check"><input class="form-check-input" type="radio" id="schedulespecialdate" name="dayselect"><label class="form-check-label" for="schedulespecialdate">Special Date</label></div>
|
<div class="form-check"><input class="form-check-input" type="radio" id="schedulespecialdate" name="dayselect"><label class="form-check-label" for="schedulespecialdate">Special Date</label></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-5 col-md-5 col-lg-6 col-xl-6"><input id="scheduledate" class="form-control" type="date"></div>
|
<div class="col"><input type="text" id="scheduledate" class="form-control"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -181,10 +142,80 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="accordion" role="tablist" id="accordion-1">
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header" role="tab"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#accordion-1 .item-1" aria-expanded="false" aria-controls="accordion-1 .item-1">Schedule Table</button></h2>
|
||||||
|
<div class="accordion-collapse collapse item-1" role="tabpanel" data-bs-parent="#accordion-1">
|
||||||
|
<div class="accordion-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-3 col-sm-3 col-md-3 col-lg-2 col-xl-2"><button class="btn w-100 pad-button btn-round-basic color-add" id="btnClear" type="button">Clear</button></div>
|
||||||
|
<div class="col-3 col-sm-3 col-md-3 col-lg-2 col-xl-2"><button class="btn w-100 pad-button btn-round-basic color-add" id="btnAdd" type="button">Add</button></div>
|
||||||
|
<div class="col-3 col-sm-3 col-md-3 col-lg-2 col-xl-2"><button class="btn w-100 pad-button btn-round-basic color-remove" id="btnRemove" type="button">Remove</button></div>
|
||||||
|
<div class="col-3 col-sm-3 col-md-3 col-lg-2 col-xl-2"><button class="btn w-100 pad-button btn-round-basic color-edit" id="btnEdit" type="button">Edit</button></div>
|
||||||
|
<div class="col-6 col-sm-6 col-md-6 col-lg-2 col-xl-2"><button class="btn w-100 pad-button btn-round-basic color-import" id="btnExport" type="button">Export</button></div>
|
||||||
|
<div class="col-6 col-sm-6 col-md-6 col-lg-2 col-xl-2"><button class="btn w-100 pad-button btn-round-basic color-import" id="btnImport" type="button">Import</button></div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<p id="tablesize" class="text-add" style="text-align: center;">Table Length : N/A</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table" id="schedulebanktable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="class05">No</th>
|
||||||
|
<th class="class15">Description</th>
|
||||||
|
<th class="class15">Day</th>
|
||||||
|
<th class="class10">Time</th>
|
||||||
|
<th class="class15">Sound Path</th>
|
||||||
|
<th class="class10">Repeat</th>
|
||||||
|
<th class="class05">Enable</th>
|
||||||
|
<th class="class15">Broadcast Zones</th>
|
||||||
|
<th class="class10">Language</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="schedulebanktablebody"></tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header" role="tab"><button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#accordion-1 .item-2" aria-expanded="true" aria-controls="accordion-1 .item-2">Today's Schedule</button></h2>
|
||||||
|
<div class="accordion-collapse collapse show item-2" role="tabpanel" data-bs-parent="#accordion-1">
|
||||||
|
<div class="accordion-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table" id="todaytable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="class05">No</th>
|
||||||
|
<th class="class15">Description</th>
|
||||||
|
<th class="class15">Day</th>
|
||||||
|
<th class="class10">Time</th>
|
||||||
|
<th class="class15">Sound Path</th>
|
||||||
|
<th class="class10">Repeat</th>
|
||||||
|
<th class="class05">Enable</th>
|
||||||
|
<th class="class15">Broadcast Zones</th>
|
||||||
|
<th class="class10">Language</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="schedulebanktablebody-1"></tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
||||||
<script src="assets/js/bs-init.js"></script>
|
<script src="assets/js/bs-init.js"></script>
|
||||||
<script src="assets/js/schedulebank.js"></script>
|
<script src="assets/js/litepicker.js"></script>
|
||||||
<script src="assets/js/datatables.js"></script>
|
<script src="assets/js/datatables.js"></script>
|
||||||
|
<script src="assets/js/schedulebank.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
18
src/Main.kt
18
src/Main.kt
@@ -16,6 +16,10 @@ import content.Language
|
|||||||
import content.VoiceType
|
import content.VoiceType
|
||||||
import database.data.Log
|
import database.data.Log
|
||||||
import database.MariaDB
|
import database.MariaDB
|
||||||
|
import database.table.Table_BroadcastZones
|
||||||
|
import database.table.Table_Logs
|
||||||
|
import database.table.Table_Messagebank
|
||||||
|
import database.table.Table_SoundChannel
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
@@ -44,8 +48,12 @@ const val version = "0.0.29 (09/02/2026)"
|
|||||||
const val max_channel = 64
|
const val max_channel = 64
|
||||||
|
|
||||||
val apptick : Long = System.currentTimeMillis()
|
val apptick : Long = System.currentTimeMillis()
|
||||||
// dipakai untuk ambil messagebank berdasarkan id
|
|
||||||
|
|
||||||
|
// 4 tabel utama , kepakai dimana-mana, ditaruh di root biar gampang aksesnya
|
||||||
|
lateinit var broadcastDB: Table_BroadcastZones
|
||||||
|
lateinit var soundchannelDB: Table_SoundChannel
|
||||||
|
lateinit var messageDB: Table_Messagebank
|
||||||
|
lateinit var logDB: Table_Logs
|
||||||
|
|
||||||
|
|
||||||
val contentCache = ContentCache()
|
val contentCache = ContentCache()
|
||||||
@@ -235,14 +243,14 @@ fun main(args: Array<String>) {
|
|||||||
val androidserver = TCP_Android_Command_Server()
|
val androidserver = TCP_Android_Command_Server()
|
||||||
androidserver.StartTcpServer(5003){
|
androidserver.StartTcpServer(5003){
|
||||||
Logger.info { it }
|
Logger.info { it }
|
||||||
db.logDB.Add(Log.NewLog("ANDROID", it))
|
logDB.Add(Log.NewLog("ANDROID", it))
|
||||||
}
|
}
|
||||||
|
|
||||||
val barixserver = TCP_Barix_Command_Server()
|
val barixserver = TCP_Barix_Command_Server()
|
||||||
barixserver.StartTcpServer { cmd ->
|
barixserver.StartTcpServer { cmd ->
|
||||||
val _tcp = barixserver.getSocket(cmd.ipaddress)
|
val _tcp = barixserver.getSocket(cmd.ipaddress)
|
||||||
val _streamer = StreamerOutputs[cmd.ipaddress]
|
val _streamer = StreamerOutputs[cmd.ipaddress]
|
||||||
val _sc = db.soundchannelDB.List.find { it.ip == cmd.ipaddress }
|
val _sc = soundchannelDB.List.find { it.ip == cmd.ipaddress }
|
||||||
if (_streamer == null) {
|
if (_streamer == null) {
|
||||||
|
|
||||||
// belum create BarixConnection untuk ipaddress ini
|
// belum create BarixConnection untuk ipaddress ini
|
||||||
@@ -297,13 +305,13 @@ fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
db.logDB.Add("AAS"," Application started")
|
logDB.Add("AAS"," Application started")
|
||||||
|
|
||||||
|
|
||||||
// shutdown hook
|
// shutdown hook
|
||||||
Runtime.getRuntime().addShutdownHook(Thread ({
|
Runtime.getRuntime().addShutdownHook(Thread ({
|
||||||
|
|
||||||
db.logDB.Add("AAS"," Application stopping")
|
logDB.Add("AAS"," Application stopping")
|
||||||
Logger.info { "Shutdown hook called, stopping services..." }
|
Logger.info { "Shutdown hook called, stopping services..." }
|
||||||
barixserver.StopTcpCommand()
|
barixserver.StopTcpCommand()
|
||||||
androidserver.StopTcpCommand()
|
androidserver.StopTcpCommand()
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import codes.Somecodes.Companion.IsNumber
|
|||||||
import codes.Somecodes.Companion.Make_WAV_FileName
|
import codes.Somecodes.Companion.Make_WAV_FileName
|
||||||
import codes.Somecodes.Companion.SoundbankResult_directory
|
import codes.Somecodes.Companion.SoundbankResult_directory
|
||||||
import codes.Somecodes.Companion.ValidFile
|
import codes.Somecodes.Companion.ValidFile
|
||||||
import codes.Somecodes.Companion.ValidIPV4
|
|
||||||
import codes.Somecodes.Companion.ValidString
|
import codes.Somecodes.Companion.ValidString
|
||||||
import codes.Somecodes.Companion.dateformat1
|
import codes.Somecodes.Companion.dateformat1
|
||||||
import codes.Somecodes.Companion.datetimeformat1
|
import codes.Somecodes.Companion.datetimeformat1
|
||||||
@@ -20,7 +19,6 @@ import content.VoiceType
|
|||||||
import database.data.Messagebank
|
import database.data.Messagebank
|
||||||
import database.data.QueueTable
|
import database.data.QueueTable
|
||||||
import database.data.Soundbank
|
import database.data.Soundbank
|
||||||
|
|
||||||
import org.tinylog.Logger
|
import org.tinylog.Logger
|
||||||
import java.time.DayOfWeek
|
import java.time.DayOfWeek
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
@@ -37,93 +35,7 @@ import java.time.LocalTime
|
|||||||
*/
|
*/
|
||||||
class MainExtension01 {
|
class MainExtension01 {
|
||||||
|
|
||||||
data class InvalidZoneDetail(val zonename: String, val reason: String)
|
|
||||||
data class ValidZoneDetail(
|
|
||||||
val zonename: String,
|
|
||||||
val soundchanel: String,
|
|
||||||
val ip: String,
|
|
||||||
val boxid: String,
|
|
||||||
val contacts: String
|
|
||||||
)
|
|
||||||
|
|
||||||
class CheckBroadcastZoneResult {
|
|
||||||
var allvalid: Boolean = false
|
|
||||||
var message: String? = null
|
|
||||||
var validzones = mutableListOf<ValidZoneDetail>()
|
|
||||||
var invalidzones = mutableListOf<InvalidZoneDetail>()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fungsi untuk cek apakah semua broadcast zone valid
|
|
||||||
* Valid berarti nama broadcast zone ada di tabel BroadcastZones, dan SoundChannel-nya ada di tabel SoundChannel, dan IP-nya valid
|
|
||||||
* @param bz List of broadcast zone (SoundChannel)
|
|
||||||
* @return CheckBroadcastZoneResult object containing allvalid flag and list of invalid zones
|
|
||||||
*/
|
|
||||||
fun AllBroadcastZonesValid(bz: List<String>): CheckBroadcastZoneResult {
|
|
||||||
val result = CheckBroadcastZoneResult()
|
|
||||||
if (bz.isNotEmpty()) {
|
|
||||||
bz.forEach { zz ->
|
|
||||||
if (ValidString(zz)) { // string tidak kosong
|
|
||||||
val findzone = db.broadcastDB.List.find {
|
|
||||||
ValidString(it.description) && ValidString(it.SoundChannel) && zz.equals(
|
|
||||||
it.description,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (findzone != null) { // ketemu zona dengan deskripsi sesuai
|
|
||||||
val findsc = db.soundchannelDB.List.find {
|
|
||||||
findzone.SoundChannel.equals(
|
|
||||||
it.channel,
|
|
||||||
true
|
|
||||||
) && ValidIPV4(it.ip)
|
|
||||||
}
|
|
||||||
if (findsc != null) { // ketemu soundchannel dengan channel sesuai dan IP valid
|
|
||||||
// check apakah offline atau online
|
|
||||||
if (StreamerOutputs.containsKey(findsc.ip)) {
|
|
||||||
val bc = StreamerOutputs[findsc.ip]
|
|
||||||
if (bc != null && bc.isOnline()) {
|
|
||||||
result.validzones.add(
|
|
||||||
ValidZoneDetail(
|
|
||||||
zz,
|
|
||||||
findzone.SoundChannel,
|
|
||||||
findsc.ip,
|
|
||||||
findzone.id,
|
|
||||||
findzone.bp
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else result.invalidzones.add(
|
|
||||||
InvalidZoneDetail(
|
|
||||||
zz,
|
|
||||||
"SoundChannel ${findzone.SoundChannel} with IP ${findsc.ip} is offline"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else result.invalidzones.add(
|
|
||||||
InvalidZoneDetail(
|
|
||||||
zz,
|
|
||||||
"SoundChannel ${findzone.SoundChannel} with IP ${findsc.ip} is not connected in StreamerOutputs"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else result.invalidzones.add(
|
|
||||||
InvalidZoneDetail(
|
|
||||||
zz,
|
|
||||||
"SoundChannel ${findzone.SoundChannel} not found or has invalid IP in SoundChannel table"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else result.invalidzones.add(InvalidZoneDetail(zz, "Zone $zz not found in BroadcastZones table"))
|
|
||||||
} else result.invalidzones.add(InvalidZoneDetail(zz, "Invalid broadcast zone string"))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.validzones.size == bz.size) {
|
|
||||||
result.allvalid = true
|
|
||||||
result.message = "All requested broadcast zones are valid"
|
|
||||||
} else {
|
|
||||||
result.message = "Some requested broadcast zones are not registered in BroadcastZone table"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result.message = "No Broadcast Zones checked for validity"
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -168,7 +80,7 @@ class MainExtension01 {
|
|||||||
var selected_voice = config.Get(configKeys.DEFAULT_VOICE_TYPE.key)
|
var selected_voice = config.Get(configKeys.DEFAULT_VOICE_TYPE.key)
|
||||||
if (selected_voice.isEmpty()) selected_voice = VoiceType.VOICE_1.name
|
if (selected_voice.isEmpty()) selected_voice = VoiceType.VOICE_1.name
|
||||||
languages.forEach { lang ->
|
languages.forEach { lang ->
|
||||||
db.messageDB.List
|
messageDB.List
|
||||||
.find { mb ->
|
.find { mb ->
|
||||||
mb.ANN_ID == id.toUInt() && mb.Language.equals(lang, true) && mb.Voice_Type.equals(
|
mb.ANN_ID == id.toUInt() && mb.Language.equals(lang, true) && mb.Voice_Type.equals(
|
||||||
selected_voice,
|
selected_voice,
|
||||||
@@ -771,7 +683,7 @@ class MainExtension01 {
|
|||||||
if (!ValidFile(qp.Message)) throw Exception("Invalid audio file ${qp.Message}")
|
if (!ValidFile(qp.Message)) throw Exception("Invalid audio file ${qp.Message}")
|
||||||
if (qp.BroadcastZones.isEmpty()) throw Exception("Empty broadcast zones")
|
if (qp.BroadcastZones.isEmpty()) throw Exception("Empty broadcast zones")
|
||||||
val zz = qp.BroadcastZones.split(";", ",").map { it.trim() }.filter { ValidString(it) }
|
val zz = qp.BroadcastZones.split(";", ",").map { it.trim() }.filter { ValidString(it) }
|
||||||
AllBroadcastZonesValid(zz).let { checkresult ->
|
broadcastDB.AllBroadcastZonesValid(zz).let { checkresult ->
|
||||||
if (!checkresult.allvalid) {
|
if (!checkresult.allvalid) {
|
||||||
val reasons =
|
val reasons =
|
||||||
checkresult.invalidzones.joinToString("; ") { iz -> "Zone '${iz.zonename}': ${iz.reason}" }
|
checkresult.invalidzones.joinToString("; ") { iz -> "Zone '${iz.zonename}': ${iz.reason}" }
|
||||||
@@ -793,10 +705,10 @@ class MainExtension01 {
|
|||||||
so.ActivateRelay(relays)
|
so.ActivateRelay(relays)
|
||||||
so.SendData(afi.bytes, cbOK = {
|
so.SendData(afi.bytes, cbOK = {
|
||||||
so.SetAudioFileInfo(null)
|
so.SetAudioFileInfo(null)
|
||||||
db.logDB.Add("AAS", it)
|
logDB.Add("AAS", it)
|
||||||
}, cbFail = {
|
}, cbFail = {
|
||||||
so.SetAudioFileInfo(null)
|
so.SetAudioFileInfo(null)
|
||||||
db.logDB.Add("AAS", it)
|
logDB.Add("AAS", it)
|
||||||
}, cbPlaying = { isplaying ->
|
}, cbPlaying = { isplaying ->
|
||||||
if (!isplaying) {
|
if (!isplaying) {
|
||||||
so.ClearUsedByBroadcastZones()
|
so.ClearUsedByBroadcastZones()
|
||||||
@@ -809,7 +721,7 @@ class MainExtension01 {
|
|||||||
val logmessage =
|
val logmessage =
|
||||||
"Broadcast started PAGING with Filename '${qp.Message}' to zones: ${qp.BroadcastZones}"
|
"Broadcast started PAGING with Filename '${qp.Message}' to zones: ${qp.BroadcastZones}"
|
||||||
Logger.info { logmessage }
|
Logger.info { logmessage }
|
||||||
db.logDB.Add("AAS", logmessage)
|
logDB.Add("AAS", logmessage)
|
||||||
db.queuepagingDB.DeleteByIndex(qp.index.toInt())
|
db.queuepagingDB.DeleteByIndex(qp.index.toInt())
|
||||||
db.queuepagingDB.Resort()
|
db.queuepagingDB.Resort()
|
||||||
return true
|
return true
|
||||||
@@ -819,7 +731,7 @@ class MainExtension01 {
|
|||||||
db.queuepagingDB.DeleteByIndex(qp.index.toInt())
|
db.queuepagingDB.DeleteByIndex(qp.index.toInt())
|
||||||
db.queuepagingDB.Resort()
|
db.queuepagingDB.Resort()
|
||||||
val msg = "Canceled paging message $qp due to exception: ${e.message}"
|
val msg = "Canceled paging message $qp due to exception: ${e.message}"
|
||||||
db.logDB.Add("AAS", msg)
|
logDB.Add("AAS", msg)
|
||||||
Logger.error { msg }
|
Logger.error { msg }
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@@ -840,7 +752,7 @@ class MainExtension01 {
|
|||||||
if (mblist.isEmpty()) throw Exception("ANN_ID $ann_id not found in Messagebank")
|
if (mblist.isEmpty()) throw Exception("ANN_ID $ann_id not found in Messagebank")
|
||||||
if (qp.BroadcastZones.isEmpty()) throw Exception("Empty broadcast zones")
|
if (qp.BroadcastZones.isEmpty()) throw Exception("Empty broadcast zones")
|
||||||
val zz = qp.BroadcastZones.split(";", ",").map { it.trim() }.filter { ValidString(it) }
|
val zz = qp.BroadcastZones.split(";", ",").map { it.trim() }.filter { ValidString(it) }
|
||||||
AllBroadcastZonesValid(zz).let { checkresult ->
|
broadcastDB.AllBroadcastZonesValid(zz).let { checkresult ->
|
||||||
if (!checkresult.allvalid) {
|
if (!checkresult.allvalid) {
|
||||||
val reasons =
|
val reasons =
|
||||||
checkresult.invalidzones.joinToString("; ") { iz -> "Zone '${iz.zonename}': ${iz.reason}" }
|
checkresult.invalidzones.joinToString("; ") { iz -> "Zone '${iz.zonename}': ${iz.reason}" }
|
||||||
@@ -880,7 +792,7 @@ class MainExtension01 {
|
|||||||
listafi,
|
listafi,
|
||||||
targetfile, true,
|
targetfile, true,
|
||||||
)
|
)
|
||||||
db.logDB.Add("AAS", result.message)
|
logDB.Add("AAS", result.message)
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw Exception(result.message)
|
throw Exception(result.message)
|
||||||
}
|
}
|
||||||
@@ -899,11 +811,11 @@ class MainExtension01 {
|
|||||||
targetafi.bytes,
|
targetafi.bytes,
|
||||||
{
|
{
|
||||||
so.SetAudioFileInfo(null)
|
so.SetAudioFileInfo(null)
|
||||||
db.logDB.Add("AAS", it)
|
logDB.Add("AAS", it)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
so.SetAudioFileInfo(null)
|
so.SetAudioFileInfo(null)
|
||||||
db.logDB.Add("AAS", it)
|
logDB.Add("AAS", it)
|
||||||
}, cbPlaying = { isplaying ->
|
}, cbPlaying = { isplaying ->
|
||||||
if (!isplaying) {
|
if (!isplaying) {
|
||||||
so.ClearUsedByBroadcastZones()
|
so.ClearUsedByBroadcastZones()
|
||||||
@@ -916,7 +828,7 @@ class MainExtension01 {
|
|||||||
val logmsg =
|
val logmsg =
|
||||||
"Broadcast started SHALAT message with generated file '$targetfile' to zones: ${qp.BroadcastZones}"
|
"Broadcast started SHALAT message with generated file '$targetfile' to zones: ${qp.BroadcastZones}"
|
||||||
Logger.info { logmsg }
|
Logger.info { logmsg }
|
||||||
db.logDB.Add("AAS", logmsg)
|
logDB.Add("AAS", logmsg)
|
||||||
db.queuepagingDB.DeleteByIndex(qp.index.toInt())
|
db.queuepagingDB.DeleteByIndex(qp.index.toInt())
|
||||||
db.queuepagingDB.Resort()
|
db.queuepagingDB.Resort()
|
||||||
return true
|
return true
|
||||||
@@ -926,7 +838,7 @@ class MainExtension01 {
|
|||||||
db.queuepagingDB.DeleteByIndex(qp.index.toInt())
|
db.queuepagingDB.DeleteByIndex(qp.index.toInt())
|
||||||
db.queuepagingDB.Resort()
|
db.queuepagingDB.Resort()
|
||||||
val msg = "Canceled shalat message $qp due to exception: ${e.message}"
|
val msg = "Canceled shalat message $qp due to exception: ${e.message}"
|
||||||
db.logDB.Add("AAS", msg)
|
logDB.Add("AAS", msg)
|
||||||
Logger.error { msg }
|
Logger.error { msg }
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@@ -947,7 +859,7 @@ class MainExtension01 {
|
|||||||
if (mblist.isEmpty()) throw Exception("ANN_ID $ann_id not found in Messagebank")
|
if (mblist.isEmpty()) throw Exception("ANN_ID $ann_id not found in Messagebank")
|
||||||
if (qa.BroadcastZones.isEmpty()) throw Exception("Empty broadcast zones")
|
if (qa.BroadcastZones.isEmpty()) throw Exception("Empty broadcast zones")
|
||||||
val zz = qa.BroadcastZones.split(";")
|
val zz = qa.BroadcastZones.split(";")
|
||||||
AllBroadcastZonesValid(zz).let { checkresult ->
|
broadcastDB.AllBroadcastZonesValid(zz).let { checkresult ->
|
||||||
if (!checkresult.allvalid) {
|
if (!checkresult.allvalid) {
|
||||||
val reasons =
|
val reasons =
|
||||||
checkresult.invalidzones.joinToString("; ") { iz -> "Zone '${iz.zonename}': ${iz.reason}" }
|
checkresult.invalidzones.joinToString("; ") { iz -> "Zone '${iz.zonename}': ${iz.reason}" }
|
||||||
@@ -997,13 +909,13 @@ class MainExtension01 {
|
|||||||
so.SetAudioFileInfo(null)
|
so.SetAudioFileInfo(null)
|
||||||
so.ClearUsedByBroadcastZones()
|
so.ClearUsedByBroadcastZones()
|
||||||
so.DeactivateRelay()
|
so.DeactivateRelay()
|
||||||
db.logDB.Add("AAS", it)
|
logDB.Add("AAS", it)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
so.SetAudioFileInfo(null)
|
so.SetAudioFileInfo(null)
|
||||||
so.ClearUsedByBroadcastZones()
|
so.ClearUsedByBroadcastZones()
|
||||||
so.DeactivateRelay()
|
so.DeactivateRelay()
|
||||||
db.logDB.Add("AAS", it)
|
logDB.Add("AAS", it)
|
||||||
}, cbPlaying = { isplaying ->
|
}, cbPlaying = { isplaying ->
|
||||||
if (!isplaying) {
|
if (!isplaying) {
|
||||||
so.ClearUsedByBroadcastZones()
|
so.ClearUsedByBroadcastZones()
|
||||||
@@ -1015,7 +927,7 @@ class MainExtension01 {
|
|||||||
val logmsg =
|
val logmsg =
|
||||||
"Broadcast started TIMER message with generated file '$targetfile' to zones: ${qa.BroadcastZones}"
|
"Broadcast started TIMER message with generated file '$targetfile' to zones: ${qa.BroadcastZones}"
|
||||||
Logger.info { logmsg }
|
Logger.info { logmsg }
|
||||||
db.logDB.Add("AAS", logmsg)
|
logDB.Add("AAS", logmsg)
|
||||||
db.queuetableDB.DeleteByIndex(qa.index.toInt())
|
db.queuetableDB.DeleteByIndex(qa.index.toInt())
|
||||||
db.queuetableDB.Resort()
|
db.queuetableDB.Resort()
|
||||||
return true
|
return true
|
||||||
@@ -1025,7 +937,7 @@ class MainExtension01 {
|
|||||||
db.queuetableDB.DeleteByIndex(qa.index.toInt())
|
db.queuetableDB.DeleteByIndex(qa.index.toInt())
|
||||||
db.queuetableDB.Resort()
|
db.queuetableDB.Resort()
|
||||||
val msg = "Canceled TIMER message $qa due to exception: ${e.message}"
|
val msg = "Canceled TIMER message $qa due to exception: ${e.message}"
|
||||||
db.logDB.Add("AAS", msg)
|
logDB.Add("AAS", msg)
|
||||||
Logger.error { msg }
|
Logger.error { msg }
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@@ -1045,7 +957,7 @@ class MainExtension01 {
|
|||||||
if (qa.BroadcastZones.isEmpty()) throw Exception("Empty broadcast zones")
|
if (qa.BroadcastZones.isEmpty()) throw Exception("Empty broadcast zones")
|
||||||
val zz = qa.BroadcastZones.split(";")
|
val zz = qa.BroadcastZones.split(";")
|
||||||
|
|
||||||
AllBroadcastZonesValid(zz).let { checkresult ->
|
broadcastDB.AllBroadcastZonesValid(zz).let { checkresult ->
|
||||||
if (!checkresult.allvalid) {
|
if (!checkresult.allvalid) {
|
||||||
val reasons =
|
val reasons =
|
||||||
checkresult.invalidzones.joinToString("; ") { iz -> "Zone '${iz.zonename}': ${iz.reason}" }
|
checkresult.invalidzones.joinToString("; ") { iz -> "Zone '${iz.zonename}': ${iz.reason}" }
|
||||||
@@ -1071,7 +983,7 @@ class MainExtension01 {
|
|||||||
// not available from variables, try to get from Message column
|
// not available from variables, try to get from Message column
|
||||||
// ada ini, karena protokol FIS dulu tidak ada ANN_ID tapi pake Remark
|
// ada ini, karena protokol FIS dulu tidak ada ANN_ID tapi pake Remark
|
||||||
val remark = variables?.get("REMARK").orEmpty()
|
val remark = variables?.get("REMARK").orEmpty()
|
||||||
db.logDB.Add("AAS", "Trying to get ANN_ID from REMARK field: $remark")
|
logDB.Add("AAS", "Trying to get ANN_ID from REMARK field: $remark")
|
||||||
Logger.info { "Trying to get ANN_ID from REMARK field: $remark" }
|
Logger.info { "Trying to get ANN_ID from REMARK field: $remark" }
|
||||||
when (remark) {
|
when (remark) {
|
||||||
"GOP" -> {
|
"GOP" -> {
|
||||||
@@ -1099,9 +1011,9 @@ class MainExtension01 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Logger.info { "Found ANN_ID from REMARK field: $ann_id" }
|
Logger.info { "Found ANN_ID from REMARK field: $ann_id" }
|
||||||
db.logDB.Add("AAS", "Found ANN_ID from REMARK field: $ann_id")
|
logDB.Add("AAS", "Found ANN_ID from REMARK field: $ann_id")
|
||||||
} else {
|
} else {
|
||||||
db.logDB.Add("AAS", "Found ANN_ID from SB_TAGS variables: $ann_id")
|
logDB.Add("AAS", "Found ANN_ID from SB_TAGS variables: $ann_id")
|
||||||
Logger.info { "Found ANN_ID from SB_TAGS variables: $ann_id" }
|
Logger.info { "Found ANN_ID from SB_TAGS variables: $ann_id" }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1152,13 +1064,13 @@ class MainExtension01 {
|
|||||||
so.SetAudioFileInfo(null)
|
so.SetAudioFileInfo(null)
|
||||||
so.ClearUsedByBroadcastZones()
|
so.ClearUsedByBroadcastZones()
|
||||||
so.DeactivateRelay()
|
so.DeactivateRelay()
|
||||||
db.logDB.Add("AAS", it)
|
logDB.Add("AAS", it)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
so.SetAudioFileInfo(null)
|
so.SetAudioFileInfo(null)
|
||||||
so.ClearUsedByBroadcastZones()
|
so.ClearUsedByBroadcastZones()
|
||||||
so.DeactivateRelay()
|
so.DeactivateRelay()
|
||||||
db.logDB.Add("AAS", it)
|
logDB.Add("AAS", it)
|
||||||
}, cbPlaying = { isplaying ->
|
}, cbPlaying = { isplaying ->
|
||||||
if (!isplaying) {
|
if (!isplaying) {
|
||||||
so.ClearUsedByBroadcastZones()
|
so.ClearUsedByBroadcastZones()
|
||||||
@@ -1171,7 +1083,7 @@ class MainExtension01 {
|
|||||||
val logmsg =
|
val logmsg =
|
||||||
"Broadcast started SOUNDBANK message with generated file '$targetfile' to zones: ${qa.BroadcastZones}"
|
"Broadcast started SOUNDBANK message with generated file '$targetfile' to zones: ${qa.BroadcastZones}"
|
||||||
Logger.info { logmsg }
|
Logger.info { logmsg }
|
||||||
db.logDB.Add("AAS", logmsg)
|
logDB.Add("AAS", logmsg)
|
||||||
db.queuetableDB.DeleteByIndex(qa.index.toInt())
|
db.queuetableDB.DeleteByIndex(qa.index.toInt())
|
||||||
db.queuetableDB.Resort()
|
db.queuetableDB.Resort()
|
||||||
return true
|
return true
|
||||||
@@ -1180,7 +1092,7 @@ class MainExtension01 {
|
|||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
val msg = "Canceled SOUNDBANK message $qa due to exception: ${e.message}"
|
val msg = "Canceled SOUNDBANK message $qa due to exception: ${e.message}"
|
||||||
db.logDB.Add("AAS", msg)
|
logDB.Add("AAS", msg)
|
||||||
Logger.error { msg }
|
Logger.error { msg }
|
||||||
db.queuetableDB.DeleteByIndex(qa.index.toInt())
|
db.queuetableDB.DeleteByIndex(qa.index.toInt())
|
||||||
db.queuetableDB.Resort()
|
db.queuetableDB.Resort()
|
||||||
|
|||||||
@@ -664,6 +664,14 @@ class Somecodes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get today's date as a string in the format "dd/MM/yyyy".
|
||||||
|
* @return A string representing today's date.
|
||||||
|
*/
|
||||||
|
fun Today_to_DateString() : String {
|
||||||
|
return dateformat1.format(LocalDateTime.now())
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a string is a valid time in the format "hh:mm:ss".
|
* Check if a string is a valid time in the format "hh:mm:ss".
|
||||||
* @param value The string to check.
|
* @param value The string to check.
|
||||||
@@ -709,6 +717,21 @@ class Somecodes {
|
|||||||
return sd?.name
|
return sd?.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a string is a valid language code.
|
||||||
|
* A valid language code is one that matches any of the Language enum values.
|
||||||
|
* @param value The string to check.
|
||||||
|
* @return True if the string is a valid language code, false otherwise.
|
||||||
|
*/
|
||||||
|
fun ValidLanguage(value: String) : Boolean{
|
||||||
|
value.split(";",",").forEach { ll ->
|
||||||
|
Language.entries.forEach { l ->
|
||||||
|
if (l.value.equals(ll,true)) return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a string is a valid schedule day or a valid date.
|
* Check if a string is a valid schedule day or a valid date.
|
||||||
* A valid schedule day is either one of the ScheduleDay enum names or a date in the format "dd/MM/yyyy".
|
* A valid schedule day is either one of the ScheduleDay enum names or a date in the format "dd/MM/yyyy".
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import kotlinx.coroutines.Job
|
|||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.isActive
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import messageDB
|
||||||
import org.tinylog.Logger
|
import org.tinylog.Logger
|
||||||
import tcpreceiver
|
import tcpreceiver
|
||||||
import udpreceiver
|
import udpreceiver
|
||||||
@@ -347,7 +348,7 @@ class TCP_Android_Command_Server {
|
|||||||
// iterasi setiap ANN_ID
|
// iterasi setiap ANN_ID
|
||||||
.forEach { annid ->
|
.forEach { annid ->
|
||||||
// masukin ke VARMESSAGES yang unik secara ANN_ID dan Language
|
// masukin ke VARMESSAGES yang unik secara ANN_ID dan Language
|
||||||
val xx = db.messageDB.List
|
val xx = messageDB.List
|
||||||
.asSequence()
|
.asSequence()
|
||||||
.filter{it.ANN_ID == annid.toUInt()}
|
.filter{it.ANN_ID == annid.toUInt()}
|
||||||
.distinctBy { it.ANN_ID }
|
.distinctBy { it.ANN_ID }
|
||||||
@@ -447,13 +448,13 @@ class TCP_Android_Command_Server {
|
|||||||
VARMESSAGES.forEachIndexed { index, msg ->
|
VARMESSAGES.forEachIndexed { index, msg ->
|
||||||
|
|
||||||
val ann_id = msg.ANN_ID
|
val ann_id = msg.ANN_ID
|
||||||
val msg_indo = db.messageDB.List.find {
|
val msg_indo = messageDB.List.find {
|
||||||
it.ANN_ID == ann_id && it.Language.equals(
|
it.ANN_ID == ann_id && it.Language.equals(
|
||||||
Language.INDONESIA.name,
|
Language.INDONESIA.name,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val msg_eng = db.messageDB.List.find {
|
val msg_eng = messageDB.List.find {
|
||||||
it.ANN_ID == ann_id && it.Language.equals(
|
it.ANN_ID == ann_id && it.Language.equals(
|
||||||
Language.ENGLISH.name,
|
Language.ENGLISH.name,
|
||||||
true
|
true
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package content
|
package content
|
||||||
|
|
||||||
|
import java.time.DayOfWeek
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
enum class ScheduleDay(val day: String) {
|
enum class ScheduleDay(val day: String) {
|
||||||
Sunday("Sunday"),
|
Sunday("Sunday"),
|
||||||
@@ -9,5 +11,22 @@ enum class ScheduleDay(val day: String) {
|
|||||||
Thursday("Thursday"),
|
Thursday("Thursday"),
|
||||||
Friday("Friday"),
|
Friday("Friday"),
|
||||||
Saturday("Saturday"),
|
Saturday("Saturday"),
|
||||||
Everyday("Everyday")
|
Everyday("Everyday");
|
||||||
}
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a DayOfWeek to a ScheduleDay
|
||||||
|
*/
|
||||||
|
fun from_LocalDate_DOW(value : DayOfWeek) : ScheduleDay{
|
||||||
|
return when(value){
|
||||||
|
DayOfWeek.SUNDAY -> Sunday
|
||||||
|
DayOfWeek.MONDAY -> Monday
|
||||||
|
DayOfWeek.TUESDAY -> Tuesday
|
||||||
|
DayOfWeek.WEDNESDAY -> Wednesday
|
||||||
|
DayOfWeek.THURSDAY -> Thursday
|
||||||
|
DayOfWeek.FRIDAY -> Friday
|
||||||
|
DayOfWeek.SATURDAY -> Saturday
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,34 +21,21 @@ import database.table.Table_SoundChannel
|
|||||||
import database.table.Table_Soundbank
|
import database.table.Table_Soundbank
|
||||||
import database.table.Table_Users
|
import database.table.Table_Users
|
||||||
|
|
||||||
|
import messageDB
|
||||||
|
import broadcastDB
|
||||||
|
import logDB
|
||||||
|
import soundchannelDB
|
||||||
|
|
||||||
/**
|
class MariaDB {
|
||||||
* A class to manage a connection to a MariaDB database.
|
|
||||||
*
|
|
||||||
* @property address The address of the MariaDB server.
|
|
||||||
* @property port The port number of the MariaDB server.
|
|
||||||
* @property dbName The name of the database to connect to.
|
|
||||||
* @property username The username for the database connection.
|
|
||||||
* @property password The password for the database connection.
|
|
||||||
*/
|
|
||||||
class MariaDB(
|
|
||||||
address: String = config.Get(configKeys.DATABASE_HOST.key),
|
|
||||||
port: Int = config.Get(configKeys.DATABASE_PORT.key).toInt(),
|
|
||||||
dbName: String = config.Get(configKeys.DATABASE_NAME.key),
|
|
||||||
username: String = config.Get(configKeys.DATABASE_USER.key),
|
|
||||||
password: String = config.Get(configKeys.DATABASE_PASSWORD.key)
|
|
||||||
) {
|
|
||||||
var connected: Boolean = false
|
var connected: Boolean = false
|
||||||
lateinit var connection: Connection
|
var connection: Connection? = null
|
||||||
lateinit var soundDB: Table_Soundbank
|
lateinit var soundDB: Table_Soundbank
|
||||||
lateinit var messageDB: Table_Messagebank
|
|
||||||
lateinit var languageDB: Table_LanguageLink
|
lateinit var languageDB: Table_LanguageLink
|
||||||
lateinit var scheduleDB: Table_Schedule
|
lateinit var scheduleDB: Table_Schedule
|
||||||
lateinit var broadcastDB: Table_BroadcastZones
|
|
||||||
lateinit var queuetableDB: Table_QueueSoundbank
|
lateinit var queuetableDB: Table_QueueSoundbank
|
||||||
lateinit var queuepagingDB: Table_QueuePaging
|
lateinit var queuepagingDB: Table_QueuePaging
|
||||||
lateinit var soundchannelDB: Table_SoundChannel
|
|
||||||
lateinit var logDB: Table_Logs
|
|
||||||
lateinit var userDB: Table_Users
|
lateinit var userDB: Table_Users
|
||||||
lateinit var logSemiAuto: Table_LogSemiAuto
|
lateinit var logSemiAuto: Table_LogSemiAuto
|
||||||
|
|
||||||
@@ -79,20 +66,10 @@ class MariaDB(
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
try {
|
CreateConnection()?.let { connection ->
|
||||||
connection =
|
this.connection = connection
|
||||||
DriverManager.getConnection(
|
Logger.info { "Connected to MariaDB successfully"}
|
||||||
"jdbc:mysql://$address:$port/$dbName?sslMode=REQUIRED",
|
CreateDatabase(connection)
|
||||||
username,
|
|
||||||
password
|
|
||||||
) as Connection
|
|
||||||
Logger.info("Connected to MySQL" as Any)
|
|
||||||
connected = true
|
|
||||||
|
|
||||||
// create databas 'aas' if not exists
|
|
||||||
val statement = connection.createStatement()
|
|
||||||
statement.executeUpdate("CREATE DATABASE IF NOT EXISTS aas")
|
|
||||||
statement.executeUpdate("USE aas")
|
|
||||||
|
|
||||||
soundDB = Table_Soundbank(connection)
|
soundDB = Table_Soundbank(connection)
|
||||||
messageDB = Table_Messagebank(connection)
|
messageDB = Table_Messagebank(connection)
|
||||||
@@ -123,9 +100,10 @@ class MariaDB(
|
|||||||
messageDB.Get()
|
messageDB.Get()
|
||||||
soundDB.Get()
|
soundDB.Get()
|
||||||
languageDB.Get()
|
languageDB.Get()
|
||||||
scheduleDB.Get()
|
|
||||||
broadcastDB.Get()
|
broadcastDB.Get()
|
||||||
soundchannelDB.Get()
|
soundchannelDB.Get()
|
||||||
|
scheduleDB.Get()
|
||||||
|
|
||||||
userDB.Get()
|
userDB.Get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,10 +118,6 @@ class MariaDB(
|
|||||||
Logger.info { "BroadcastZones count: ${broadcastDB.List.size}" }
|
Logger.info { "BroadcastZones count: ${broadcastDB.List.size}" }
|
||||||
Logger.info { "SoundChannel count: ${soundchannelDB.List.size}" }
|
Logger.info { "SoundChannel count: ${soundchannelDB.List.size}" }
|
||||||
Logger.info { "User count: ${userDB.List.size}" }
|
Logger.info { "User count: ${userDB.List.size}" }
|
||||||
|
|
||||||
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Logger.error("Failed to connect to MariaDB: ${e.message}" as Any)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,14 +126,59 @@ class MariaDB(
|
|||||||
*/
|
*/
|
||||||
fun close() {
|
fun close() {
|
||||||
try {
|
try {
|
||||||
connection.close()
|
this.connection?.close()
|
||||||
|
|
||||||
Logger.info("Connection to MariaDB closed" as Any)
|
Logger.info("Connection to MariaDB closed" as Any)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Logger.error("Error closing MariaDB connection: ${e.message}" as Any)
|
Logger.error("Error closing MariaDB connection: ${e.message}" as Any)
|
||||||
}
|
} finally {
|
||||||
|
this.connection = null
|
||||||
connected = false
|
connected = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new connection to the MariaDB database.
|
||||||
|
* @return A Connection object if successful, null otherwise.
|
||||||
|
*/
|
||||||
|
fun CreateConnection(): Connection? {
|
||||||
|
val address: String = config.Get(configKeys.DATABASE_HOST.key)
|
||||||
|
val port: Int = config.Get(configKeys.DATABASE_PORT.key).toInt()
|
||||||
|
val dbName: String = config.Get(configKeys.DATABASE_NAME.key)
|
||||||
|
val username: String = config.Get(configKeys.DATABASE_USER.key)
|
||||||
|
val password: String = config.Get(configKeys.DATABASE_PASSWORD.key)
|
||||||
|
connected = false
|
||||||
|
try{
|
||||||
|
val cc = DriverManager.getConnection(
|
||||||
|
"jdbc:mysql://$address:$port/$dbName?sslMode=REQUIRED",
|
||||||
|
username,
|
||||||
|
password
|
||||||
|
)
|
||||||
|
connected = true
|
||||||
|
return cc
|
||||||
|
} catch (e : Exception){
|
||||||
|
Logger.error("Failed to create connection to MariaDB: ${e.message}" as Any)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the database if it does not exist.
|
||||||
|
* @param connection The Connection object to use for creating the database.
|
||||||
|
* @return True if the database was created or already exists, false otherwise.
|
||||||
|
*/
|
||||||
|
fun CreateDatabase(connection: Connection) : Boolean{
|
||||||
|
try {
|
||||||
|
// create databas 'aas' if not exists
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
statement.executeUpdate("CREATE DATABASE IF NOT EXISTS aas")
|
||||||
|
statement.executeUpdate("USE aas")
|
||||||
|
return true
|
||||||
|
} catch (e : Exception){
|
||||||
|
Logger.error { "Error creating database: ${e.message}" }
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -6,8 +6,30 @@ import java.sql.Connection
|
|||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
|
|
||||||
@Suppress("unused", "SqlDialectInspection", "SqlSourceToSinkFlow")
|
@Suppress("unused", "SqlDialectInspection", "SqlSourceToSinkFlow")
|
||||||
abstract class dbFunctions<T>(val dbName: String, val connection: Connection, requiredcolumns: List<String>) {
|
abstract class dbFunctions<T>(val dbName: String, conn: Connection, requiredcolumns: List<String>) {
|
||||||
var List : ArrayList<T> = ArrayList()
|
var List : ArrayList<T> = ArrayList()
|
||||||
|
var connection = conn
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the database connection is valid
|
||||||
|
* @return true if valid, false otherwise
|
||||||
|
*/
|
||||||
|
fun IsConnected() : Boolean{
|
||||||
|
return try {
|
||||||
|
connection.isValid(2)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Database connection is not valid: ${e.message}" as Any)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the database connection
|
||||||
|
* @param newcon The new Connection object
|
||||||
|
*/
|
||||||
|
fun ChangeConnection(newcon: Connection){
|
||||||
|
connection = newcon
|
||||||
|
}
|
||||||
|
|
||||||
init{
|
init{
|
||||||
val columns = GetColumnInfo()
|
val columns = GetColumnInfo()
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
package database.table
|
package database.table
|
||||||
|
|
||||||
|
import StreamerOutputs
|
||||||
|
import broadcastDB
|
||||||
|
import codes.Somecodes.Companion.ValidIPV4
|
||||||
|
import codes.Somecodes.Companion.ValidString
|
||||||
import database.data.BroadcastZones
|
import database.data.BroadcastZones
|
||||||
import database.dbFunctions
|
import database.dbFunctions
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
||||||
import org.tinylog.Logger
|
import org.tinylog.Logger
|
||||||
|
import soundchannelDB
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
|
|
||||||
@@ -200,4 +205,129 @@ class Table_BroadcastZones(connection: Connection) : dbFunctions<BroadcastZones>
|
|||||||
.map { it.description }
|
.map { it.description }
|
||||||
.sorted()
|
.sorted()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class InvalidZoneDetail(val zonename: String, val reason: String)
|
||||||
|
data class ValidZoneDetail(
|
||||||
|
val zonename: String,
|
||||||
|
val soundchanel: String,
|
||||||
|
val ip: String,
|
||||||
|
val boxid: String,
|
||||||
|
val contacts: String
|
||||||
|
)
|
||||||
|
|
||||||
|
class CheckBroadcastZoneResult {
|
||||||
|
var allvalid: Boolean = false
|
||||||
|
var message: String? = null
|
||||||
|
var validzones = mutableListOf<ValidZoneDetail>()
|
||||||
|
var invalidzones = mutableListOf<InvalidZoneDetail>()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if all broadcast zones in a comma-separated string are valid
|
||||||
|
* Valid means the broadcast zone name exists in the BroadcastZones table, its SoundChannel exists in the SoundChannel table, and its IP is valid
|
||||||
|
* @param zones Comma-separated string of broadcast zones
|
||||||
|
* @param checkOnline Whether to check if the sound channel is really online, recorded in StreamerOutputs map
|
||||||
|
* @return true if all broadcast zones are valid, false otherwise
|
||||||
|
*/
|
||||||
|
fun AllBroadcastZonesValid(zones: String, checkOnline: Boolean = true) : Boolean{
|
||||||
|
val bzlist = zones.split(",",";").map { it.trim() }.filter { it.isNotEmpty() }
|
||||||
|
//println("Checking all broadcast zones validity for: $bzlist")
|
||||||
|
AllBroadcastZonesValid(bzlist, checkOnline).let { result ->
|
||||||
|
if (result.allvalid) {
|
||||||
|
//Logger.info("All broadcast zones are valid: ${bzlist.joinToString(", ")}" as Any)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
//Logger.warn("Some broadcast zones are invalid:" as Any)
|
||||||
|
result.invalidzones.forEach { iz ->
|
||||||
|
Logger.warn(" - Zone '${iz.zonename}' is invalid: ${iz.reason}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//return AllBroadcastZonesValid(bzlist).allvalid
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fungsi untuk cek apakah semua broadcast zone valid
|
||||||
|
* Valid berarti nama broadcast zone ada di tabel BroadcastZones, dan SoundChannel-nya ada di tabel SoundChannel, dan IP-nya valid
|
||||||
|
* @param bz List of broadcast zone (SoundChannel)
|
||||||
|
* @param checkOnline Whether to check if the sound channel is really online, recorded in StreamerOutputs map
|
||||||
|
* @return CheckBroadcastZoneResult object containing allvalid flag and list of invalid zones
|
||||||
|
*/
|
||||||
|
fun AllBroadcastZonesValid(bz: List<String>, checkOnline: Boolean = true): CheckBroadcastZoneResult {
|
||||||
|
val result = CheckBroadcastZoneResult()
|
||||||
|
if (bz.isNotEmpty()) {
|
||||||
|
bz.forEach { zz ->
|
||||||
|
if (ValidString(zz)) { // string tidak kosong
|
||||||
|
val findzone = List.find{
|
||||||
|
ValidString(it.description) && ValidString(it.SoundChannel) && it.description.equals(zz,true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findzone != null) { // ketemu zona dengan deskripsi sesuai
|
||||||
|
val findsc = soundchannelDB.List.find {
|
||||||
|
findzone.SoundChannel.equals(
|
||||||
|
it.channel,
|
||||||
|
true
|
||||||
|
) && ValidIPV4(it.ip)
|
||||||
|
}
|
||||||
|
if (findsc != null) { // ketemu soundchannel dengan channel sesuai dan IP valid
|
||||||
|
// check apakah offline atau online
|
||||||
|
if (checkOnline){
|
||||||
|
if (StreamerOutputs.containsKey(findsc.ip)) {
|
||||||
|
val bc = StreamerOutputs[findsc.ip]
|
||||||
|
if (bc != null && bc.isOnline()) {
|
||||||
|
result.validzones.add(
|
||||||
|
ValidZoneDetail(
|
||||||
|
zz,
|
||||||
|
findzone.SoundChannel,
|
||||||
|
findsc.ip,
|
||||||
|
findzone.id,
|
||||||
|
findzone.bp
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else result.invalidzones.add(
|
||||||
|
InvalidZoneDetail(
|
||||||
|
zz,
|
||||||
|
"SoundChannel ${findzone.SoundChannel} with IP ${findsc.ip} is offline"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else result.invalidzones.add(
|
||||||
|
InvalidZoneDetail(
|
||||||
|
zz,
|
||||||
|
"SoundChannel ${findzone.SoundChannel} with IP ${findsc.ip} is not connected in StreamerOutputs"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
result.validzones.add(
|
||||||
|
ValidZoneDetail(
|
||||||
|
zz,
|
||||||
|
findzone.SoundChannel,
|
||||||
|
findsc.ip,
|
||||||
|
findzone.id,
|
||||||
|
findzone.bp
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else result.invalidzones.add(
|
||||||
|
InvalidZoneDetail(
|
||||||
|
zz,
|
||||||
|
"SoundChannel ${findzone.SoundChannel} not found or has invalid IP in SoundChannel table"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else result.invalidzones.add(InvalidZoneDetail(zz, "Zone $zz not found in BroadcastZones table"))
|
||||||
|
} else result.invalidzones.add(InvalidZoneDetail(zz, "Invalid broadcast zone string"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.validzones.size == bz.size) {
|
||||||
|
result.allvalid = true
|
||||||
|
result.message = "All requested broadcast zones are valid"
|
||||||
|
} else {
|
||||||
|
result.message = "Some requested broadcast zones are not registered in BroadcastZone table"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.message = "No Broadcast Zones checked for validity"
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,10 +2,14 @@ package database.table
|
|||||||
|
|
||||||
import database.data.Log
|
import database.data.Log
|
||||||
import database.dbFunctions
|
import database.dbFunctions
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
||||||
import org.tinylog.Logger
|
import org.tinylog.Logger
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
import java.sql.Date
|
import java.sql.Date
|
||||||
|
import java.sql.Statement
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
@@ -47,6 +51,12 @@ class Table_Logs(connection: Connection) : dbFunctions<Log>("logs", connection,l
|
|||||||
|
|
||||||
fun GetLogForHtml(date: String, filter: String?, cbOK: Consumer<ArrayList<Log>>?, cbFail: Consumer<String>?){
|
fun GetLogForHtml(date: String, filter: String?, cbOK: Consumer<ArrayList<Log>>?, cbFail: Consumer<String>?){
|
||||||
try{
|
try{
|
||||||
|
var statement : Statement?
|
||||||
|
if ("alldate" == date){
|
||||||
|
if (filter.isNullOrEmpty()) throw Exception("Filter is required when date is 'alldate'")
|
||||||
|
statement = connection.prepareStatement("SELECT * FROM ${super.dbName} WHERE description LIKE ?")
|
||||||
|
statement?.setString(1, "%$filter%")
|
||||||
|
} else {
|
||||||
val valid_date : Date? = when{
|
val valid_date : Date? = when{
|
||||||
dateformat1.matches(date) -> {
|
dateformat1.matches(date) -> {
|
||||||
Date.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern("dd/MM/yyyy")))
|
Date.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern("dd/MM/yyyy")))
|
||||||
@@ -64,7 +74,7 @@ class Table_Logs(connection: Connection) : dbFunctions<Log>("logs", connection,l
|
|||||||
}
|
}
|
||||||
if (valid_date!=null){
|
if (valid_date!=null){
|
||||||
// use coalescing for different datenya formats
|
// use coalescing for different datenya formats
|
||||||
val statement = if (filter.isNullOrEmpty()){
|
statement = if (filter.isNullOrEmpty()){
|
||||||
connection.prepareStatement("SELECT * FROM ${super.dbName} WHERE COALESCE(STR_TO_DATE(datenya,'%d/%m/%Y'), STR_TO_DATE(datenya,'%d-%m-%Y'), STR_TO_DATE(datenya,'%Y/%m/%d'), STR_TO_DATE(datenya,'%Y-%m-%d')) = ?")
|
connection.prepareStatement("SELECT * FROM ${super.dbName} WHERE COALESCE(STR_TO_DATE(datenya,'%d/%m/%Y'), STR_TO_DATE(datenya,'%d-%m-%Y'), STR_TO_DATE(datenya,'%Y/%m/%d'), STR_TO_DATE(datenya,'%Y-%m-%d')) = ?")
|
||||||
} else {
|
} else {
|
||||||
connection.prepareStatement("SELECT * FROM ${super.dbName} WHERE COALESCE(STR_TO_DATE(datenya,'%d/%m/%Y'), STR_TO_DATE(datenya,'%d-%m-%Y'), STR_TO_DATE(datenya,'%Y/%m/%d'), STR_TO_DATE(datenya,'%Y-%m-%d')) = ? AND description LIKE ?")
|
connection.prepareStatement("SELECT * FROM ${super.dbName} WHERE COALESCE(STR_TO_DATE(datenya,'%d/%m/%Y'), STR_TO_DATE(datenya,'%d-%m-%Y'), STR_TO_DATE(datenya,'%Y/%m/%d'), STR_TO_DATE(datenya,'%Y-%m-%d')) = ? AND description LIKE ?")
|
||||||
@@ -73,7 +83,10 @@ class Table_Logs(connection: Connection) : dbFunctions<Log>("logs", connection,l
|
|||||||
if (!filter.isNullOrEmpty()){
|
if (!filter.isNullOrEmpty()){
|
||||||
statement?.setString(2, "%$filter%")
|
statement?.setString(2, "%$filter%")
|
||||||
}
|
}
|
||||||
val resultSet = statement?.executeQuery()
|
} else throw Exception("Invalid date")
|
||||||
|
}
|
||||||
|
if (statement!=null){
|
||||||
|
val resultSet = statement.executeQuery()
|
||||||
val tempList = ArrayList<Log>()
|
val tempList = ArrayList<Log>()
|
||||||
while (resultSet?.next() == true) {
|
while (resultSet?.next() == true) {
|
||||||
val log = Log(
|
val log = Log(
|
||||||
@@ -86,7 +99,7 @@ class Table_Logs(connection: Connection) : dbFunctions<Log>("logs", connection,l
|
|||||||
tempList.add(log)
|
tempList.add(log)
|
||||||
}
|
}
|
||||||
cbOK?.accept(tempList)
|
cbOK?.accept(tempList)
|
||||||
} else throw Exception("Invalid date")
|
} else throw Exception("Failed to prepare statement")
|
||||||
} catch (e : Exception){
|
} catch (e : Exception){
|
||||||
if (filter.isNullOrEmpty()){
|
if (filter.isNullOrEmpty()){
|
||||||
cbFail?.accept("Failed to Get logs for date $date: ${e.message}")
|
cbFail?.accept("Failed to Get logs for date $date: ${e.message}")
|
||||||
@@ -94,9 +107,16 @@ class Table_Logs(connection: Connection) : dbFunctions<Log>("logs", connection,l
|
|||||||
cbFail?.accept("Failed to Get logs for date $date with filter $filter: ${e.message}")
|
cbFail?.accept("Failed to Get logs for date $date with filter $filter: ${e.message}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****
|
||||||
|
* Fetches all log entries from the database and populates the local List.
|
||||||
|
* @param cbOK Optional callback invoked upon successful retrieval.
|
||||||
|
* @param cbFail Optional callback invoked upon failure with an error message.
|
||||||
|
*/
|
||||||
override fun Get(cbOK: Consumer<Unit>?, cbFail: Consumer<String>?) {
|
override fun Get(cbOK: Consumer<Unit>?, cbFail: Consumer<String>?) {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
List.clear()
|
List.clear()
|
||||||
try {
|
try {
|
||||||
val statement = connection.createStatement()
|
val statement = connection.createStatement()
|
||||||
@@ -119,6 +139,8 @@ class Table_Logs(connection: Connection) : dbFunctions<Log>("logs", connection,l
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
fun Add(machine: String, description: String): Boolean {
|
fun Add(machine: String, description: String): Boolean {
|
||||||
val log = Log.NewLog(machine, description)
|
val log = Log.NewLog(machine, description)
|
||||||
return Add(log)
|
return Add(log)
|
||||||
|
|||||||
@@ -236,4 +236,26 @@ class Table_Messagebank(connection: Connection) : dbFunctions<Messagebank>("mess
|
|||||||
.map { it.ANN_ID }
|
.map { it.ANN_ID }
|
||||||
.sorted()
|
.sorted()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// valid messagedetail is message_name [ann_id]
|
||||||
|
// so we need regex to check if messagedetail matches that format
|
||||||
|
private val messageDetailRegex = """^(.*?)\s*\[(\d+)]$""".toRegex()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a messagebank entry exists based on messagedetail and languages
|
||||||
|
* @param messagedetail the messagedetail in format "message_name [ann_id]"
|
||||||
|
* @param languages a comma or semicolon separated string of languages to check
|
||||||
|
* @return true if the messagebank entry exists for all specified languages, false otherwise
|
||||||
|
*/
|
||||||
|
fun Messagebank_Exists(messagedetail: String, languages: String) : Boolean{
|
||||||
|
val match = messageDetailRegex.find(messagedetail)
|
||||||
|
val ll = languages.split(",",";").map { it.trim() }
|
||||||
|
if (match != null){
|
||||||
|
val msg = match.groupValues[1].trim()
|
||||||
|
val annid = match.groupValues[2].toUIntOrNull() ?: return false // kalau bukan number, return false
|
||||||
|
val ff = List.filter{ it.ANN_ID == annid && it.Description == msg }
|
||||||
|
return ll.all{ lang -> ff.any{ it.Language.equals(lang, ignoreCase = true) } }
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
package database.table
|
package database.table
|
||||||
|
|
||||||
|
import codes.Somecodes.Companion.ValidLanguage
|
||||||
import codes.Somecodes.Companion.ValidScheduleDay
|
import codes.Somecodes.Companion.ValidScheduleDay
|
||||||
|
import codes.Somecodes.Companion.ValidScheduleTime
|
||||||
|
import content.ScheduleDay
|
||||||
import database.MariaDB.Companion.ValidTime
|
import database.MariaDB.Companion.ValidTime
|
||||||
import database.data.ScheduleBank
|
import database.data.ScheduleBank
|
||||||
import database.dbFunctions
|
import database.dbFunctions
|
||||||
@@ -9,7 +12,54 @@ import org.tinylog.Logger
|
|||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
|
|
||||||
|
import broadcastDB
|
||||||
|
import codes.Somecodes
|
||||||
|
import messageDB
|
||||||
|
import java.time.LocalDate
|
||||||
|
|
||||||
class Table_Schedule(connection: Connection) : dbFunctions<ScheduleBank>("schedulebank", connection, listOf("index", "Description", "Day", "Time", "Soundpath", "Repeat", "Enable", "BroadcastZones", "Language")) {
|
class Table_Schedule(connection: Connection) : dbFunctions<ScheduleBank>("schedulebank", connection, listOf("index", "Description", "Day", "Time", "Soundpath", "Repeat", "Enable", "BroadcastZones", "Language")) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list to hold today's schedule entries.
|
||||||
|
*/
|
||||||
|
val todaySchedule = ArrayList<ScheduleBank>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update today's schedule
|
||||||
|
*/
|
||||||
|
fun UpdateTodaySchedule(){
|
||||||
|
todaySchedule.clear()
|
||||||
|
|
||||||
|
fun Find_Enabled_Schedules() : List<ScheduleBank>{
|
||||||
|
return List
|
||||||
|
.filter{it.Enable} // yang enabled saja
|
||||||
|
.filter{ValidScheduleTime(it.Time)} // yang timenya dalam format HH:MM
|
||||||
|
.filter{ValidLanguage(it.Language)} // yang bahasanya valid
|
||||||
|
.filter{broadcastDB.AllBroadcastZonesValid(it.BroadcastZones, false)} // yang broadcastzonesnya valid
|
||||||
|
// Soundpath ini coding typo, aslinya Messagebank description
|
||||||
|
.filter{messageDB.Messagebank_Exists(it.Soundpath, it.Language)}
|
||||||
|
}
|
||||||
|
val eligibleSchedule = Find_Enabled_Schedules()
|
||||||
|
|
||||||
|
val tempMap = mutableMapOf<String, ScheduleBank>()
|
||||||
|
|
||||||
|
// prioritas paling rendah adalah everyday
|
||||||
|
eligibleSchedule.filter { it.Day == ScheduleDay.Everyday.day }.forEach { tempMap[it.Time] = it }
|
||||||
|
|
||||||
|
// lebih tinggi adalah weekly, akan replace everyday jika time nya sama
|
||||||
|
val today_DOW = ScheduleDay.from_LocalDate_DOW(LocalDate.now().dayOfWeek)
|
||||||
|
eligibleSchedule.filter { it.Day == today_DOW.day }.forEach { tempMap[it.Time] = it }
|
||||||
|
|
||||||
|
// paling tinggi adalah specific date, akan replace yang lain jika time nya sama
|
||||||
|
val today = Somecodes.Today_to_DateString()
|
||||||
|
eligibleSchedule.filter { it.Day == today }.forEach { tempMap[it.Time] = it }
|
||||||
|
|
||||||
|
// masukin ke todaySchedule yang sudah di sort by Time
|
||||||
|
todaySchedule.addAll(tempMap.values.sortedBy { it.Time })
|
||||||
|
|
||||||
|
println("Todays schedule : $todaySchedule")
|
||||||
|
}
|
||||||
|
|
||||||
override fun Create() {
|
override fun Create() {
|
||||||
val tabledefinition = "CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
val tabledefinition = "CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
||||||
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
||||||
@@ -44,6 +94,7 @@ class Table_Schedule(connection: Connection) : dbFunctions<ScheduleBank>("schedu
|
|||||||
)
|
)
|
||||||
List.add(schedulebank)
|
List.add(schedulebank)
|
||||||
}
|
}
|
||||||
|
UpdateTodaySchedule()
|
||||||
cbOK?.accept(Unit)
|
cbOK?.accept(Unit)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Logger.error("Error fetching ${super.dbName}: ${e.message}" as Any)
|
Logger.error("Error fetching ${super.dbName}: ${e.message}" as Any)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package web
|
|||||||
|
|
||||||
import StreamerOutputs
|
import StreamerOutputs
|
||||||
import barix.BarixConnection
|
import barix.BarixConnection
|
||||||
|
import broadcastDB
|
||||||
import codes.Somecodes
|
import codes.Somecodes
|
||||||
import codes.Somecodes.Companion.GetAppUpTime
|
import codes.Somecodes.Companion.GetAppUpTime
|
||||||
import codes.Somecodes.Companion.GetSensorsInfo
|
import codes.Somecodes.Companion.GetSensorsInfo
|
||||||
@@ -49,7 +50,10 @@ import google.GoogleTTS
|
|||||||
import google.autoadd
|
import google.autoadd
|
||||||
import google.fileoperation
|
import google.fileoperation
|
||||||
import io.javalin.websocket.WsCloseStatus
|
import io.javalin.websocket.WsCloseStatus
|
||||||
|
import logDB
|
||||||
|
import messageDB
|
||||||
import org.tinylog.Logger
|
import org.tinylog.Logger
|
||||||
|
import soundchannelDB
|
||||||
import version
|
import version
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
@@ -730,7 +734,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
db.soundDB.Resort()
|
db.soundDB.Resort()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
|
|
||||||
db.logDB.Add("AAS", "Deleted sound bank with index $index")
|
logDB.Add("AAS", "Deleted sound bank with index $index")
|
||||||
} else {
|
} else {
|
||||||
it.status(500)
|
it.status(500)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Failed to delete soundbank with index $index")))
|
.result(objectmapper.writeValueAsString(resultMessage("Failed to delete soundbank with index $index")))
|
||||||
@@ -863,15 +867,15 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
path("MessageBank") {
|
path("MessageBank") {
|
||||||
get("List") { ctx ->
|
get("List") { ctx ->
|
||||||
// get messagebank list
|
// get messagebank list
|
||||||
db.messageDB.Get({
|
messageDB.Get({
|
||||||
ctx.result(MariaDB.ArrayListtoString(db.messageDB.List))
|
ctx.result(MariaDB.ArrayListtoString(messageDB.List))
|
||||||
}, { msgFail ->
|
}, { msgFail ->
|
||||||
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
get("MessageIDs") { ctx ->
|
get("MessageIDs") { ctx ->
|
||||||
val value = db.messageDB.List
|
val value = messageDB.List
|
||||||
.distinctBy { it.ANN_ID }
|
.distinctBy { it.ANN_ID }
|
||||||
.sortedBy { it.ANN_ID }
|
.sortedBy { it.ANN_ID }
|
||||||
.map { KeyValueMessage(it.ANN_ID.toString(), it.Description) }
|
.map { KeyValueMessage(it.ANN_ID.toString(), it.Description) }
|
||||||
@@ -902,10 +906,10 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
message_tags
|
message_tags
|
||||||
)
|
)
|
||||||
val existed =
|
val existed =
|
||||||
db.messageDB.List.any { it.ANN_ID == mb.ANN_ID && it.Language == mb.Language && it.Voice_Type == mb.Voice_Type }
|
messageDB.List.any { it.ANN_ID == mb.ANN_ID && it.Language == mb.Language && it.Voice_Type == mb.Voice_Type }
|
||||||
if (!existed) {
|
if (!existed) {
|
||||||
if (db.messageDB.Add(mb)) {
|
if (messageDB.Add(mb)) {
|
||||||
db.messageDB.Resort()
|
messageDB.Resort()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
} else it.status(500)
|
} else it.status(500)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Failed to add messagebank to database")))
|
.result(objectmapper.writeValueAsString(resultMessage("Failed to add messagebank to database")))
|
||||||
@@ -926,8 +930,8 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
}
|
}
|
||||||
delete("List") {
|
delete("List") {
|
||||||
// truncate messagebank table
|
// truncate messagebank table
|
||||||
if (db.messageDB.Clear()) {
|
if (messageDB.Clear()) {
|
||||||
db.messageDB.Get()
|
messageDB.Get()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
} else {
|
} else {
|
||||||
it.status(500)
|
it.status(500)
|
||||||
@@ -941,10 +945,10 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
it.status(400)
|
it.status(400)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Invalid index")))
|
.result(objectmapper.writeValueAsString(resultMessage("Invalid index")))
|
||||||
} else {
|
} else {
|
||||||
if (db.messageDB.DeleteByIndex(index.toInt())) {
|
if (messageDB.DeleteByIndex(index.toInt())) {
|
||||||
db.messageDB.Resort()
|
messageDB.Resort()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
db.logDB.Add("AAS", "Deleted message bank with index $index")
|
logDB.Add("AAS", "Deleted message bank with index $index")
|
||||||
} else {
|
} else {
|
||||||
it.status(500)
|
it.status(500)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Failed to delete messagebank with index $index")))
|
.result(objectmapper.writeValueAsString(resultMessage("Failed to delete messagebank with index $index")))
|
||||||
@@ -958,7 +962,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
it.status(400)
|
it.status(400)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Invalid index")))
|
.result(objectmapper.writeValueAsString(resultMessage("Invalid index")))
|
||||||
} else {
|
} else {
|
||||||
val mb = db.messageDB.List.find { xx -> xx.index == index }
|
val mb = messageDB.List.find { xx -> xx.index == index }
|
||||||
if (mb == null) {
|
if (mb == null) {
|
||||||
it.status(404)
|
it.status(404)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Messagebank with index $index not found")))
|
.result(objectmapper.writeValueAsString(resultMessage("Messagebank with index $index not found")))
|
||||||
@@ -1007,8 +1011,8 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
changed = true
|
changed = true
|
||||||
}
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
if (db.messageDB.UpdateByIndex(index.toInt(), mb)) {
|
if (messageDB.UpdateByIndex(index.toInt(), mb)) {
|
||||||
db.messageDB.Resort()
|
messageDB.Resort()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
} else it.status(500)
|
} else it.status(500)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Failed to update messagebank with index $index")))
|
.result(objectmapper.writeValueAsString(resultMessage("Failed to update messagebank with index $index")))
|
||||||
@@ -1019,7 +1023,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
get("ExportXLSX") {
|
get("ExportXLSX") {
|
||||||
val xlsxdata = db.messageDB.Export_XLSX()
|
val xlsxdata = messageDB.Export_XLSX()
|
||||||
if (xlsxdata != null) {
|
if (xlsxdata != null) {
|
||||||
it.header(
|
it.header(
|
||||||
"Content-Type",
|
"Content-Type",
|
||||||
@@ -1043,8 +1047,8 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
val xlsx = XSSFWorkbook(uploaded.content())
|
val xlsx = XSSFWorkbook(uploaded.content())
|
||||||
if (db.messageDB.Import_XLSX(xlsx)) {
|
if (messageDB.Import_XLSX(xlsx)) {
|
||||||
db.messageDB.Resort()
|
messageDB.Resort()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
} else {
|
} else {
|
||||||
it.status(500)
|
it.status(500)
|
||||||
@@ -1133,7 +1137,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
if (db.languageDB.DeleteByIndex(index.toInt())) {
|
if (db.languageDB.DeleteByIndex(index.toInt())) {
|
||||||
db.languageDB.Resort()
|
db.languageDB.Resort()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
db.logDB.Add("AAS", "Deleted language link with index $index")
|
logDB.Add("AAS", "Deleted language link with index $index")
|
||||||
} else {
|
} else {
|
||||||
it.status(500)
|
it.status(500)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Failed to delete language link with index $index")))
|
.result(objectmapper.writeValueAsString(resultMessage("Failed to delete language link with index $index")))
|
||||||
@@ -1219,11 +1223,14 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
path("ScheduleBank") {
|
path("ScheduleBank") {
|
||||||
|
get("TodaySchedule"){ ctx ->
|
||||||
|
ctx.json(db.scheduleDB.todaySchedule)
|
||||||
|
}
|
||||||
get("List") { ctx ->
|
get("List") { ctx ->
|
||||||
|
|
||||||
db.scheduleDB.Get({
|
db.scheduleDB.Get({
|
||||||
// get timer list
|
// get timer list
|
||||||
ctx.result(MariaDB.ArrayListtoString(db.scheduleDB.List))
|
ctx.json(db.scheduleDB.List)
|
||||||
}, { msgFail ->
|
}, { msgFail ->
|
||||||
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
||||||
})
|
})
|
||||||
@@ -1257,7 +1264,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
if (ValidString(broadcast_zones)) {
|
if (ValidString(broadcast_zones)) {
|
||||||
val zones = broadcast_zones.split(";")
|
val zones = broadcast_zones.split(";")
|
||||||
if (zones.all { zz ->
|
if (zones.all { zz ->
|
||||||
db.broadcastDB.List.any { xx ->
|
broadcastDB.List.any { xx ->
|
||||||
xx.description.equals(
|
xx.description.equals(
|
||||||
zz,
|
zz,
|
||||||
true
|
true
|
||||||
@@ -1318,7 +1325,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
if (db.scheduleDB.DeleteByIndex(index.toInt())) {
|
if (db.scheduleDB.DeleteByIndex(index.toInt())) {
|
||||||
db.scheduleDB.Resort()
|
db.scheduleDB.Resort()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
db.logDB.Add("AAS", "Deleted schedule bank with index $index")
|
logDB.Add("AAS", "Deleted schedule bank with index $index")
|
||||||
} else {
|
} else {
|
||||||
it.status(500)
|
it.status(500)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Failed to delete schedule with index $index")))
|
.result(objectmapper.writeValueAsString(resultMessage("Failed to delete schedule with index $index")))
|
||||||
@@ -1407,21 +1414,21 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
}
|
}
|
||||||
get("GetMessageAndBroadcastZones") {
|
get("GetMessageAndBroadcastZones") {
|
||||||
val result = object {
|
val result = object {
|
||||||
val messages = db.messageDB.List
|
val messages = messageDB.List
|
||||||
.filter { mb ->
|
.filter { mb ->
|
||||||
!mb.Message_Detail.contains("[") && !mb.Message_Detail.contains(
|
!mb.Message_Detail.contains("[") && !mb.Message_Detail.contains(
|
||||||
"]"
|
"]"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.map { mb -> "${mb.Description} [${mb.ANN_ID}]" }
|
.map { mb -> "${mb.Description} [${mb.ANN_ID}]" }
|
||||||
val broadcastzones = db.broadcastDB.List
|
val broadcastzones = broadcastDB.List
|
||||||
}
|
}
|
||||||
it.result(objectmapper.writeValueAsString(result))
|
it.result(objectmapper.writeValueAsString(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kirim list language dari Messagebank berdasarkan ANN_ID
|
// Kirim list language dari Messagebank berdasarkan ANN_ID
|
||||||
get("GetLanguageList/{ANN_ID}") { get1 ->
|
get("GetLanguageList/{ANN_ID}") { get1 ->
|
||||||
val langlist = db.messageDB.List
|
val langlist = messageDB.List
|
||||||
.filter { it.ANN_ID == get1.pathParam("ANN_ID").toInt().toUInt() }
|
.filter { it.ANN_ID == get1.pathParam("ANN_ID").toInt().toUInt() }
|
||||||
.map { it.Language }.distinct()
|
.map { it.Language }.distinct()
|
||||||
get1.result(objectmapper.writeValueAsString(langlist))
|
get1.result(objectmapper.writeValueAsString(langlist))
|
||||||
@@ -1525,7 +1532,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
.map { it.trim() }
|
.map { it.trim() }
|
||||||
.filter { it.isNotEmpty() }.distinct()
|
.filter { it.isNotEmpty() }.distinct()
|
||||||
.mapNotNull { it.toUIntOrNull() }
|
.mapNotNull { it.toUIntOrNull() }
|
||||||
val mbankids = db.messageDB.Get_MessageID_List()
|
val mbankids = messageDB.Get_MessageID_List()
|
||||||
if (!mbids.all { id -> mbankids.any { it == id } }) {
|
if (!mbids.all { id -> mbankids.any { it == id } }) {
|
||||||
ctx.status(400)
|
ctx.status(400)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Some ANN_ID not found in Messagebank")))
|
.result(objectmapper.writeValueAsString(resultMessage("Some ANN_ID not found in Messagebank")))
|
||||||
@@ -1537,7 +1544,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
val bzdesc =
|
val bzdesc =
|
||||||
broadcastzones.split(";").map { it.trim() }
|
broadcastzones.split(";").map { it.trim() }
|
||||||
.filter { it.isNotEmpty() }.distinct()
|
.filter { it.isNotEmpty() }.distinct()
|
||||||
val bzlist = db.broadcastDB.Get_BroadcastZone_List()
|
val bzlist = broadcastDB.Get_BroadcastZone_List()
|
||||||
val missing_broadcastzones = ArrayList<String>()
|
val missing_broadcastzones = ArrayList<String>()
|
||||||
bzdesc.forEach { bz ->
|
bzdesc.forEach { bz ->
|
||||||
if (!bzlist.any { it.equals(bz, true) }) {
|
if (!bzlist.any { it.equals(bz, true) }) {
|
||||||
@@ -1594,7 +1601,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
if (db.userDB.DeleteByIndex(index.toInt())) {
|
if (db.userDB.DeleteByIndex(index.toInt())) {
|
||||||
db.userDB.Resort()
|
db.userDB.Resort()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
db.logDB.Add("AAS", "Deleted user with index $index")
|
logDB.Add("AAS", "Deleted user with index $index")
|
||||||
} else it.status(500)
|
} else it.status(500)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Failed to delete user with index $index")))
|
.result(objectmapper.writeValueAsString(resultMessage("Failed to delete user with index $index")))
|
||||||
}
|
}
|
||||||
@@ -1700,7 +1707,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
.map { it.trim() }
|
.map { it.trim() }
|
||||||
.filter { it.isNotEmpty() }.distinct()
|
.filter { it.isNotEmpty() }.distinct()
|
||||||
.mapNotNull { it.toUIntOrNull() }
|
.mapNotNull { it.toUIntOrNull() }
|
||||||
val mbankids = db.messageDB.Get_MessageID_List()
|
val mbankids = messageDB.Get_MessageID_List()
|
||||||
val missing_broadcastids = ArrayList<UInt>()
|
val missing_broadcastids = ArrayList<UInt>()
|
||||||
mbids.forEach { mbid ->
|
mbids.forEach { mbid ->
|
||||||
if (!mbankids.any { it == mbid }) {
|
if (!mbankids.any { it == mbid }) {
|
||||||
@@ -1727,7 +1734,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
|
|
||||||
val bzdesc = _broadcastzones.split(";").map { it.trim() }
|
val bzdesc = _broadcastzones.split(";").map { it.trim() }
|
||||||
.filter { it.isNotEmpty() }.distinct()
|
.filter { it.isNotEmpty() }.distinct()
|
||||||
val bzlist = db.broadcastDB.Get_BroadcastZone_List()
|
val bzlist = broadcastDB.Get_BroadcastZone_List()
|
||||||
val missing_broadcastzones = ArrayList<String>()
|
val missing_broadcastzones = ArrayList<String>()
|
||||||
bzdesc.forEach { bz ->
|
bzdesc.forEach { bz ->
|
||||||
if (!bzlist.any { it.equals(bz, true) }) {
|
if (!bzlist.any { it.equals(bz, true) }) {
|
||||||
@@ -1832,8 +1839,8 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
|
|
||||||
get("GetMessageAndBroadcastZones") {
|
get("GetMessageAndBroadcastZones") {
|
||||||
val result = object {
|
val result = object {
|
||||||
val messages = db.messageDB.List
|
val messages = messageDB.List
|
||||||
val broadcastzones = db.broadcastDB.List
|
val broadcastzones = broadcastDB.List
|
||||||
}
|
}
|
||||||
it.result(objectmapper.writeValueAsString(result))
|
it.result(objectmapper.writeValueAsString(result))
|
||||||
}
|
}
|
||||||
@@ -1842,8 +1849,10 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
get("List") { get1 ->
|
get("List") { get1 ->
|
||||||
val logdate = get1.queryParam("date") ?: ""
|
val logdate = get1.queryParam("date") ?: ""
|
||||||
val logfilter = get1.queryParam("filter")
|
val logfilter = get1.queryParam("filter")
|
||||||
db.logDB.GetLogForHtml(logdate, logfilter, { loglist ->
|
Logger.info{"Client ${get1.ip()} requested log list for date $logdate with filter $logfilter"}
|
||||||
get1.result(objectmapper.writeValueAsString(loglist))
|
logDB.GetLogForHtml(logdate, logfilter, { loglist ->
|
||||||
|
get1.contentType("application/json")
|
||||||
|
get1.json(loglist)
|
||||||
}, { msgFail ->
|
}, { msgFail ->
|
||||||
get1.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
get1.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
||||||
})
|
})
|
||||||
@@ -1853,9 +1862,9 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
val logfilter = get1.queryParam("filter") ?: ""
|
val logfilter = get1.queryParam("filter") ?: ""
|
||||||
if (ValiDateForLogHtml(logdate)) {
|
if (ValiDateForLogHtml(logdate)) {
|
||||||
val xlsxdata = if (ValidString(logfilter)) {
|
val xlsxdata = if (ValidString(logfilter)) {
|
||||||
db.logDB.Export_Log_XLSX(logdate.replace('-', '/'), logfilter)
|
logDB.Export_Log_XLSX(logdate.replace('-', '/'), logfilter)
|
||||||
} else {
|
} else {
|
||||||
db.logDB.Export_Log_XLSX(logdate.replace('-', '/'), "")
|
logDB.Export_Log_XLSX(logdate.replace('-', '/'), "")
|
||||||
}
|
}
|
||||||
if (xlsxdata != null) {
|
if (xlsxdata != null) {
|
||||||
get1.header(
|
get1.header(
|
||||||
@@ -1876,22 +1885,22 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
}
|
}
|
||||||
path("BroadcastZones") {
|
path("BroadcastZones") {
|
||||||
get("List") { ctx ->
|
get("List") { ctx ->
|
||||||
db.broadcastDB.Get({
|
broadcastDB.Get({
|
||||||
ctx.result(MariaDB.ArrayListtoString(db.broadcastDB.List))
|
ctx.json(broadcastDB.List)
|
||||||
}, { msgFail ->
|
}, { msgFail ->
|
||||||
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
get("BroadcastZoneDescriptions") { ctx ->
|
get("BroadcastZoneDescriptions") { ctx ->
|
||||||
val value = db.broadcastDB.List
|
val value = broadcastDB.List
|
||||||
.distinctBy { it.description }
|
.distinctBy { it.description }
|
||||||
.map { it.description }
|
.map { it.description }
|
||||||
ctx.result(objectmapper.writeValueAsString(value))
|
ctx.result(objectmapper.writeValueAsString(value))
|
||||||
}
|
}
|
||||||
delete("List") {
|
delete("List") {
|
||||||
// truncate broadcast zones table
|
// truncate broadcast zones table
|
||||||
if (db.broadcastDB.Clear()) {
|
if (broadcastDB.Clear()) {
|
||||||
db.broadcastDB.Get()
|
broadcastDB.Get()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
} else {
|
} else {
|
||||||
it.status(500)
|
it.status(500)
|
||||||
@@ -1910,8 +1919,8 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
if (ValidString(_relay)) {
|
if (ValidString(_relay)) {
|
||||||
val newbp =
|
val newbp =
|
||||||
BroadcastZones(0u, _description, _soundchannel, _box, _relay)
|
BroadcastZones(0u, _description, _soundchannel, _box, _relay)
|
||||||
if (db.broadcastDB.Add(newbp)) {
|
if (broadcastDB.Add(newbp)) {
|
||||||
db.broadcastDB.Resort()
|
broadcastDB.Resort()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
} else it.status(500)
|
} else it.status(500)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Failed to add broadcast zone to database")))
|
.result(objectmapper.writeValueAsString(resultMessage("Failed to add broadcast zone to database")))
|
||||||
@@ -1931,10 +1940,10 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
it.status(400)
|
it.status(400)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Invalid index")))
|
.result(objectmapper.writeValueAsString(resultMessage("Invalid index")))
|
||||||
} else {
|
} else {
|
||||||
if (db.broadcastDB.DeleteByIndex(index.toInt())) {
|
if (broadcastDB.DeleteByIndex(index.toInt())) {
|
||||||
db.broadcastDB.Resort()
|
broadcastDB.Resort()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
db.logDB.Add("AAS", "Deleted broadcast zone with index $index")
|
logDB.Add("AAS", "Deleted broadcast zone with index $index")
|
||||||
} else {
|
} else {
|
||||||
it.status(500)
|
it.status(500)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Failed to delete broadcast zone with index $index")))
|
.result(objectmapper.writeValueAsString(resultMessage("Failed to delete broadcast zone with index $index")))
|
||||||
@@ -1948,7 +1957,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
it.status(400)
|
it.status(400)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Invalid index")))
|
.result(objectmapper.writeValueAsString(resultMessage("Invalid index")))
|
||||||
} else {
|
} else {
|
||||||
val bz = db.broadcastDB.List.find { xx -> xx.index == index }
|
val bz = broadcastDB.List.find { xx -> xx.index == index }
|
||||||
if (bz == null) {
|
if (bz == null) {
|
||||||
it.status(404)
|
it.status(404)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Broadcast zone with index $index not found")))
|
.result(objectmapper.writeValueAsString(resultMessage("Broadcast zone with index $index not found")))
|
||||||
@@ -1980,8 +1989,8 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
changed = true
|
changed = true
|
||||||
}
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
if (db.broadcastDB.UpdateByIndex(index.toInt(), bz)) {
|
if (broadcastDB.UpdateByIndex(index.toInt(), bz)) {
|
||||||
db.broadcastDB.Resort()
|
broadcastDB.Resort()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
} else it.status(500)
|
} else it.status(500)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Failed to update broadcast zone with index $index")))
|
.result(objectmapper.writeValueAsString(resultMessage("Failed to update broadcast zone with index $index")))
|
||||||
@@ -1993,7 +2002,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
|
|
||||||
}
|
}
|
||||||
get("ExportXLSX") {
|
get("ExportXLSX") {
|
||||||
val xlsxdata = db.broadcastDB.Export_XLSX()
|
val xlsxdata = broadcastDB.Export_XLSX()
|
||||||
if (xlsxdata != null) {
|
if (xlsxdata != null) {
|
||||||
it.header(
|
it.header(
|
||||||
"Content-Type",
|
"Content-Type",
|
||||||
@@ -2017,8 +2026,8 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
val xlsx = XSSFWorkbook(uploaded.content())
|
val xlsx = XSSFWorkbook(uploaded.content())
|
||||||
if (db.broadcastDB.Import_XLSX(xlsx)) {
|
if (broadcastDB.Import_XLSX(xlsx)) {
|
||||||
db.broadcastDB.Resort()
|
broadcastDB.Resort()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
} else {
|
} else {
|
||||||
it.status(500)
|
it.status(500)
|
||||||
@@ -2033,20 +2042,20 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
}
|
}
|
||||||
path("SoundChannel") {
|
path("SoundChannel") {
|
||||||
get("List") { ctx ->
|
get("List") { ctx ->
|
||||||
db.soundchannelDB.Get({
|
soundchannelDB.Get({
|
||||||
ctx.result(MariaDB.ArrayListtoString(db.soundchannelDB.List))
|
ctx.json(soundchannelDB.List)
|
||||||
}, { msgFail ->
|
}, { msgFail ->
|
||||||
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
get("SoundChannelDescriptions") {
|
get("SoundChannelDescriptions") {
|
||||||
it.result(objectmapper.writeValueAsString(db.soundchannelDB.Get_SoundChannel_List()))
|
it.result(objectmapper.writeValueAsString(soundchannelDB.Get_SoundChannel_List()))
|
||||||
}
|
}
|
||||||
delete("List") {
|
delete("List") {
|
||||||
// truncate sound channel table
|
// truncate sound channel table
|
||||||
if (db.soundchannelDB.Clear()) {
|
if (soundchannelDB.Clear()) {
|
||||||
db.soundchannelDB.Get()
|
soundchannelDB.Get()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
} else {
|
} else {
|
||||||
it.status(500)
|
it.status(500)
|
||||||
@@ -2060,7 +2069,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
it.status(400)
|
it.status(400)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Invalid index")))
|
.result(objectmapper.writeValueAsString(resultMessage("Invalid index")))
|
||||||
} else {
|
} else {
|
||||||
val sc = db.soundchannelDB.List.find { xx -> xx.index == index }
|
val sc = soundchannelDB.List.find { xx -> xx.index == index }
|
||||||
if (sc == null) {
|
if (sc == null) {
|
||||||
it.status(404)
|
it.status(404)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Sound channel with index $index not found")))
|
.result(objectmapper.writeValueAsString(resultMessage("Sound channel with index $index not found")))
|
||||||
@@ -2082,7 +2091,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
|
|
||||||
// cek apakah ada soundchannel lain yang pakai ip dan channel yang sama
|
// cek apakah ada soundchannel lain yang pakai ip dan channel yang sama
|
||||||
val othersc =
|
val othersc =
|
||||||
db.soundchannelDB.List.filter { sc -> sc.ip == _ip }
|
soundchannelDB.List.filter { sc -> sc.ip == _ip }
|
||||||
.filter { sc -> sc.index != index }
|
.filter { sc -> sc.index != index }
|
||||||
if (othersc.isNotEmpty()) {
|
if (othersc.isNotEmpty()) {
|
||||||
it.status(400)
|
it.status(400)
|
||||||
@@ -2090,8 +2099,8 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
} else {
|
} else {
|
||||||
// ada sesuatu yang ganti
|
// ada sesuatu yang ganti
|
||||||
val newsc = SoundChannel(0u, _channel, _ip)
|
val newsc = SoundChannel(0u, _channel, _ip)
|
||||||
if (db.soundchannelDB.UpdateByIndex(index.toInt(), newsc)) {
|
if (soundchannelDB.UpdateByIndex(index.toInt(), newsc)) {
|
||||||
db.soundchannelDB.Resort()
|
soundchannelDB.Resort()
|
||||||
it.result(
|
it.result(
|
||||||
objectmapper.writeValueAsString(
|
objectmapper.writeValueAsString(
|
||||||
resultMessage(
|
resultMessage(
|
||||||
@@ -2128,7 +2137,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
|
|
||||||
}
|
}
|
||||||
get("ExportXLSX") {
|
get("ExportXLSX") {
|
||||||
val xlsxdata = db.soundchannelDB.Export_XLSX()
|
val xlsxdata = soundchannelDB.Export_XLSX()
|
||||||
if (xlsxdata != null) {
|
if (xlsxdata != null) {
|
||||||
it.header(
|
it.header(
|
||||||
"Content-Type",
|
"Content-Type",
|
||||||
@@ -2152,8 +2161,8 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
val xlsx = XSSFWorkbook(uploaded.content())
|
val xlsx = XSSFWorkbook(uploaded.content())
|
||||||
if (db.soundchannelDB.Import_XLSX(xlsx)) {
|
if (soundchannelDB.Import_XLSX(xlsx)) {
|
||||||
db.soundchannelDB.Resort()
|
soundchannelDB.Resort()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
} else {
|
} else {
|
||||||
it.status(500)
|
it.status(500)
|
||||||
@@ -2169,7 +2178,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
path("QueuePaging") {
|
path("QueuePaging") {
|
||||||
get("List") { ctx ->
|
get("List") { ctx ->
|
||||||
db.queuepagingDB.Get({
|
db.queuepagingDB.Get({
|
||||||
ctx.result(MariaDB.ArrayListtoString(db.queuepagingDB.List))
|
ctx.json(db.queuepagingDB.List)
|
||||||
}, { msgFail ->
|
}, { msgFail ->
|
||||||
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
||||||
})
|
})
|
||||||
@@ -2195,7 +2204,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
if (db.queuepagingDB.DeleteByIndex(index.toInt())) {
|
if (db.queuepagingDB.DeleteByIndex(index.toInt())) {
|
||||||
db.queuepagingDB.Resort()
|
db.queuepagingDB.Resort()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
db.logDB.Add("AAS", "Deleted queue paging with index $index")
|
logDB.Add("AAS", "Deleted queue paging with index $index")
|
||||||
} else {
|
} else {
|
||||||
it.status(500)
|
it.status(500)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Failed to delete queue paging with index $index")))
|
.result(objectmapper.writeValueAsString(resultMessage("Failed to delete queue paging with index $index")))
|
||||||
@@ -2207,7 +2216,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
path("QueueTable") {
|
path("QueueTable") {
|
||||||
get("List") { ctx ->
|
get("List") { ctx ->
|
||||||
db.queuetableDB.Get({
|
db.queuetableDB.Get({
|
||||||
ctx.result(MariaDB.ArrayListtoString(db.queuetableDB.List))
|
ctx.json(db.queuetableDB.List)
|
||||||
}, { msgFail ->
|
}, { msgFail ->
|
||||||
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
||||||
})
|
})
|
||||||
@@ -2233,7 +2242,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
if (db.queuetableDB.DeleteByIndex(index.toInt())) {
|
if (db.queuetableDB.DeleteByIndex(index.toInt())) {
|
||||||
db.queuetableDB.Resort()
|
db.queuetableDB.Resort()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
db.logDB.Add("AAS", "Deleted queue sound with index $index")
|
logDB.Add("AAS", "Deleted queue sound with index $index")
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
it.status(500)
|
it.status(500)
|
||||||
@@ -2521,7 +2530,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
_config.Set(configKeys.DEFAULT_VOICE_TYPE.key, defaultvoice)
|
_config.Set(configKeys.DEFAULT_VOICE_TYPE.key, defaultvoice)
|
||||||
_config.Save()
|
_config.Save()
|
||||||
Logger.info { "Changed FIS Codes" }
|
Logger.info { "Changed FIS Codes" }
|
||||||
db.logDB.Add(
|
logDB.Add(
|
||||||
"AAS",
|
"AAS",
|
||||||
"Save FIS Codes Message: GOP=$_gop, GBD=$_gbd, GFC=$_gfc, FLD=$_fld, DefaultVoice=$defaultvoice"
|
"Save FIS Codes Message: GOP=$_gop, GBD=$_gbd, GFC=$_gfc, FLD=$_fld, DefaultVoice=$defaultvoice"
|
||||||
)
|
)
|
||||||
@@ -2636,7 +2645,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
// messages
|
// messages
|
||||||
String_To_List(user.messagebank_ann_id).forEach { msg ->
|
String_To_List(user.messagebank_ann_id).forEach { msg ->
|
||||||
//println("Looking for message ANN_ID: $msg")
|
//println("Looking for message ANN_ID: $msg")
|
||||||
db.messageDB.List.filter { it.ANN_ID == msg.toUInt() }.forEach { xx ->
|
messageDB.List.filter { it.ANN_ID == msg.toUInt() }.forEach { xx ->
|
||||||
//println("Adding message: ${xx.ANN_ID};${xx.Description};${xx.Language};${xx.Message_Detail}")
|
//println("Adding message: ${xx.ANN_ID};${xx.Description};${xx.Language};${xx.Message_Detail}")
|
||||||
result.messages.add("${xx.ANN_ID};${xx.Description};${xx.Language};${xx.Message_Detail}")
|
result.messages.add("${xx.ANN_ID};${xx.Description};${xx.Language};${xx.Message_Detail}")
|
||||||
}
|
}
|
||||||
@@ -2755,9 +2764,9 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
val logfilter = get1.queryParam("filter") ?: ""
|
val logfilter = get1.queryParam("filter") ?: ""
|
||||||
if (ValiDateForLogHtml(logdate)) {
|
if (ValiDateForLogHtml(logdate)) {
|
||||||
val xlsxdata = if (ValidString(logfilter)) {
|
val xlsxdata = if (ValidString(logfilter)) {
|
||||||
db.logDB.Export_Log_XLSX(logdate.replace('-', '/'), logfilter)
|
logDB.Export_Log_XLSX(logdate.replace('-', '/'), logfilter)
|
||||||
} else {
|
} else {
|
||||||
db.logDB.Export_Log_XLSX(logdate.replace('-', '/'), "")
|
logDB.Export_Log_XLSX(logdate.replace('-', '/'), "")
|
||||||
}
|
}
|
||||||
if (xlsxdata != null) {
|
if (xlsxdata != null) {
|
||||||
get1.header(
|
get1.header(
|
||||||
@@ -2780,7 +2789,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
val datelog = ctx.pathParam("datelog")
|
val datelog = ctx.pathParam("datelog")
|
||||||
println("Request log for date: $datelog")
|
println("Request log for date: $datelog")
|
||||||
db.logSemiAuto.GetLogSemiAutoForHtml(datelog, null, {
|
db.logSemiAuto.GetLogSemiAutoForHtml(datelog, null, {
|
||||||
ctx.result(MariaDB.ArrayListtoString(it))
|
ctx.json(it)
|
||||||
}, { err ->
|
}, { err ->
|
||||||
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(err)))
|
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(err)))
|
||||||
})
|
})
|
||||||
@@ -2829,8 +2838,8 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
|
|
||||||
fun Get_Barix_Connection_by_ZoneName(zonename: String): BarixConnection? {
|
fun Get_Barix_Connection_by_ZoneName(zonename: String): BarixConnection? {
|
||||||
if (ValidString(zonename)) {
|
if (ValidString(zonename)) {
|
||||||
val bz = db.broadcastDB.List.find { it.description == zonename }
|
val bz = broadcastDB.List.find { it.description == zonename }
|
||||||
val sc = if (bz != null) db.soundchannelDB.List.find { it.channel == bz.SoundChannel } else null
|
val sc = if (bz != null) soundchannelDB.List.find { it.channel == bz.SoundChannel } else null
|
||||||
val ip = sc?.ip ?: ""
|
val ip = sc?.ip ?: ""
|
||||||
if (ValidIPV4(ip)) {
|
if (ValidIPV4(ip)) {
|
||||||
// ketemu ip-nya
|
// ketemu ip-nya
|
||||||
|
|||||||
Reference in New Issue
Block a user