commit 09/02/2026
This commit is contained in:
11
src/Main.kt
11
src/Main.kt
@@ -14,7 +14,7 @@ import commandServer.TCP_Android_Command_Server
|
|||||||
import content.Category
|
import content.Category
|
||||||
import content.Language
|
import content.Language
|
||||||
import content.VoiceType
|
import content.VoiceType
|
||||||
import database.Log
|
import database.data.Log
|
||||||
import database.MariaDB
|
import database.MariaDB
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -45,14 +45,7 @@ const val max_channel = 64
|
|||||||
|
|
||||||
val apptick : Long = System.currentTimeMillis()
|
val apptick : Long = System.currentTimeMillis()
|
||||||
// dipakai untuk ambil messagebank berdasarkan id
|
// dipakai untuk ambil messagebank berdasarkan id
|
||||||
val urutan_bahasa = listOf(
|
|
||||||
Language.INDONESIA.name,
|
|
||||||
Language.LOCAL.name,
|
|
||||||
Language.ENGLISH.name,
|
|
||||||
Language.CHINESE.name,
|
|
||||||
Language.JAPANESE.name,
|
|
||||||
Language.ARABIC.name
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
val contentCache = ContentCache()
|
val contentCache = ContentCache()
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ import content.Category
|
|||||||
import content.Language
|
import content.Language
|
||||||
import content.ScheduleDay
|
import content.ScheduleDay
|
||||||
import content.VoiceType
|
import content.VoiceType
|
||||||
import database.Messagebank
|
import database.data.Messagebank
|
||||||
import database.QueueTable
|
import database.data.QueueTable
|
||||||
import database.Soundbank
|
import database.data.Soundbank
|
||||||
|
|
||||||
import org.tinylog.Logger
|
import org.tinylog.Logger
|
||||||
import java.time.DayOfWeek
|
import java.time.DayOfWeek
|
||||||
@@ -163,7 +163,7 @@ class MainExtension01 {
|
|||||||
* @param languages List of language yang diinginkan, default urutan_bahasa
|
* @param languages List of language yang diinginkan, default urutan_bahasa
|
||||||
* @return List of Messagebank
|
* @return List of Messagebank
|
||||||
*/
|
*/
|
||||||
fun Get_MessageBank_by_id(id: Int, languages: List<String> = urutan_bahasa): ArrayList<Messagebank> {
|
fun Get_MessageBank_by_id(id: Int, languages: List<String> = Language.LanguageOrder()): ArrayList<Messagebank> {
|
||||||
val mb_list = ArrayList<Messagebank>()
|
val mb_list = ArrayList<Messagebank>()
|
||||||
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
|
||||||
|
|||||||
@@ -3,12 +3,11 @@ package commandServer
|
|||||||
import audioPlayer
|
import audioPlayer
|
||||||
import codes.Somecodes.Companion.ValidString
|
import codes.Somecodes.Companion.ValidString
|
||||||
import codes.Somecodes.Companion.datetimeformat1
|
import codes.Somecodes.Companion.datetimeformat1
|
||||||
import content.Category
|
|
||||||
import content.Language
|
import content.Language
|
||||||
import database.Messagebank
|
import database.data.Messagebank
|
||||||
import database.QueuePaging
|
import database.data.QueuePaging
|
||||||
import database.QueueTable
|
import database.data.QueueTable
|
||||||
import database.Soundbank
|
import database.data.Soundbank
|
||||||
import db
|
import db
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -367,11 +366,7 @@ class TCP_Android_Command_Server {
|
|||||||
.map { it.trim() }
|
.map { it.trim() }
|
||||||
.filter { it.isNotBlank() }
|
.filter { it.isNotBlank() }
|
||||||
.forEach { al ->
|
.forEach { al ->
|
||||||
val sb = db.soundDB.List
|
VARAPTOTAL.addAll(db.soundDB.Find_AirlineName_By_TAG(al))
|
||||||
.filter { it.Category.equals(Category.Airplane_Name.name, true) }
|
|
||||||
.filter { it.TAG.equals(al, true)}
|
|
||||||
.distinctBy { it.TAG }
|
|
||||||
VARAPTOTAL.addAll(sb)
|
|
||||||
}
|
}
|
||||||
result.append(VARAPTOTAL.size).append("@")
|
result.append(VARAPTOTAL.size).append("@")
|
||||||
cb.accept(result.toString())
|
cb.accept(result.toString())
|
||||||
@@ -385,11 +380,7 @@ class TCP_Android_Command_Server {
|
|||||||
.map { it.trim() }
|
.map { it.trim() }
|
||||||
.filter { it.isNotBlank() }
|
.filter { it.isNotBlank() }
|
||||||
.forEach { ct ->
|
.forEach { ct ->
|
||||||
val sb = db.soundDB.List
|
VARCITYTOTAL.addAll(db.soundDB.Find_City_By_TAG(ct))
|
||||||
.filter { it.Category.equals(Category.City.name, true) }
|
|
||||||
.filter { it.TAG.equals(ct, true)}
|
|
||||||
.distinctBy { it.TAG }
|
|
||||||
VARCITYTOTAL.addAll(sb)
|
|
||||||
}
|
}
|
||||||
result.append(VARCITYTOTAL.size).append("@")
|
result.append(VARCITYTOTAL.size).append("@")
|
||||||
cb.accept(result.toString())
|
cb.accept(result.toString())
|
||||||
@@ -397,104 +388,56 @@ class TCP_Android_Command_Server {
|
|||||||
// kirim VARPLACESTOTAL
|
// kirim VARPLACESTOTAL
|
||||||
result.clear()
|
result.clear()
|
||||||
result.append("VARPLACESTOTAL;")
|
result.append("VARPLACESTOTAL;")
|
||||||
val VARPLACESTOTAL = mutableListOf<Soundbank>()
|
val VARPLACESTOTAL = db.soundDB.Get_Places()
|
||||||
db.soundDB.List
|
|
||||||
.filter { it.Category.equals(Category.Places.name, true) }
|
|
||||||
.distinctBy { it.TAG }
|
|
||||||
.forEach {
|
|
||||||
VARPLACESTOTAL.add(it)
|
|
||||||
}
|
|
||||||
result.append(VARPLACESTOTAL.size).append("@")
|
result.append(VARPLACESTOTAL.size).append("@")
|
||||||
cb.accept(result.toString())
|
cb.accept(result.toString())
|
||||||
|
|
||||||
// kirim VARSHALATTOTAL
|
// kirim VARSHALATTOTAL
|
||||||
result.clear()
|
result.clear()
|
||||||
result.append("VARSHALATTOTAL;")
|
result.append("VARSHALATTOTAL;")
|
||||||
val VARSHALATTOTAL = mutableListOf<Soundbank>()
|
val VARSHALATTOTAL = db.soundDB.Get_Shalat()
|
||||||
db.soundDB.List
|
|
||||||
.filter { it.Category.equals(Category.Shalat.name, true) }
|
|
||||||
.distinctBy { it.TAG }
|
|
||||||
.forEach {
|
|
||||||
VARSHALATTOTAL.add(it)
|
|
||||||
}
|
|
||||||
result.append(VARSHALATTOTAL.size).append("@")
|
result.append(VARSHALATTOTAL.size).append("@")
|
||||||
cb.accept(result.toString())
|
cb.accept(result.toString())
|
||||||
|
|
||||||
// kirim VARSEQUENCETOTAL
|
// kirim VARSEQUENCETOTAL
|
||||||
result.clear()
|
result.clear()
|
||||||
result.append("VARSEQUENCETOTAL;")
|
result.append("VARSEQUENCETOTAL;")
|
||||||
val VARSEQUENCETOTAL = mutableListOf<Soundbank>()
|
val VARSEQUENCETOTAL = db.soundDB.Get_Sequences()
|
||||||
db.soundDB.List
|
|
||||||
.filter { it.Category.equals(Category.Sequence.name, true) }
|
|
||||||
.distinctBy { it.TAG }
|
|
||||||
.forEach {
|
|
||||||
VARSEQUENCETOTAL.add(it)
|
|
||||||
}
|
|
||||||
result.append(VARSEQUENCETOTAL.size).append("@")
|
result.append(VARSEQUENCETOTAL.size).append("@")
|
||||||
cb.accept(result.toString())
|
cb.accept(result.toString())
|
||||||
|
|
||||||
// kirim VARREASONTOTAL
|
// kirim VARREASONTOTAL
|
||||||
result.clear()
|
result.clear()
|
||||||
result.append("VARREASONTOTAL;")
|
result.append("VARREASONTOTAL;")
|
||||||
val VARREASONTOTAL = mutableListOf<Soundbank>()
|
val VARREASONTOTAL = db.soundDB.Get_Reasons()
|
||||||
db.soundDB.List
|
|
||||||
.filter { it.Category.equals(Category.Reason.name, true) }
|
|
||||||
.distinctBy { it.TAG }
|
|
||||||
.forEach {
|
|
||||||
VARREASONTOTAL.add(it)
|
|
||||||
}
|
|
||||||
result.append(VARREASONTOTAL.size).append("@")
|
result.append(VARREASONTOTAL.size).append("@")
|
||||||
cb.accept(result.toString())
|
cb.accept(result.toString())
|
||||||
|
|
||||||
// kirim VARPROCEDURETOTAL
|
// kirim VARPROCEDURETOTAL
|
||||||
val VARPROCEDURETOTAL = mutableListOf<Soundbank>()
|
|
||||||
result.clear()
|
result.clear()
|
||||||
result.append("VARPROCEDURETOTAL;")
|
result.append("VARPROCEDURETOTAL;")
|
||||||
db.soundDB.List
|
val VARPROCEDURETOTAL = db.soundDB.Get_Procedures()
|
||||||
.filter { it.Category.equals(Category.Procedure.name, true) }
|
|
||||||
.distinctBy { it.TAG }
|
|
||||||
.forEach {
|
|
||||||
VARPROCEDURETOTAL.add(it)
|
|
||||||
}
|
|
||||||
result.append(VARPROCEDURETOTAL.size).append("@")
|
result.append(VARPROCEDURETOTAL.size).append("@")
|
||||||
cb.accept(result.toString())
|
cb.accept(result.toString())
|
||||||
|
|
||||||
// kirim VARGATETOTAL
|
// kirim VARGATETOTAL
|
||||||
val VARGATETOTAL = mutableListOf<Soundbank>()
|
|
||||||
result.clear()
|
result.clear()
|
||||||
result.append("VARGATETOTAL;")
|
result.append("VARGATETOTAL;")
|
||||||
db.soundDB.List
|
val VARGATETOTAL = db.soundDB.Get_Gates()
|
||||||
.filter { it.Category.equals(Category.Gate.name, true) }
|
|
||||||
.distinctBy { it.TAG }
|
|
||||||
.forEach {
|
|
||||||
VARGATETOTAL.add(it)
|
|
||||||
}
|
|
||||||
result.append(VARGATETOTAL.size).append("@")
|
result.append(VARGATETOTAL.size).append("@")
|
||||||
cb.accept(result.toString())
|
cb.accept(result.toString())
|
||||||
|
|
||||||
// kirim VARCOMPENSATIONTOTAL
|
// kirim VARCOMPENSATIONTOTAL
|
||||||
result.clear()
|
result.clear()
|
||||||
result.append("VARCOMPENSATIONTOTAL;")
|
result.append("VARCOMPENSATIONTOTAL;")
|
||||||
val VARCOMPENSATIONTOTAL = mutableListOf<Soundbank>()
|
val VARCOMPENSATIONTOTAL = db.soundDB.Get_Compensation()
|
||||||
db.soundDB.List
|
|
||||||
.filter { it.Category.equals(Category.Compensation.name, true) }
|
|
||||||
.distinctBy { it.TAG }
|
|
||||||
.forEach {
|
|
||||||
VARCOMPENSATIONTOTAL.add(it)
|
|
||||||
}
|
|
||||||
result.append(VARCOMPENSATIONTOTAL.size).append("@")
|
result.append(VARCOMPENSATIONTOTAL.size).append("@")
|
||||||
cb.accept(result.toString())
|
cb.accept(result.toString())
|
||||||
|
|
||||||
// kirim VARGREETINGTOTAL
|
// kirim VARGREETINGTOTAL
|
||||||
result.clear()
|
result.clear()
|
||||||
result.append("VARGREETINGTOTAL;")
|
result.append("VARGREETINGTOTAL;")
|
||||||
val VARGREETINGTOTAL = mutableListOf<Soundbank>()
|
val VARGREETINGTOTAL = db.soundDB.Get_Greeting()
|
||||||
db.soundDB.List
|
|
||||||
.filter { it.Category.equals(Category.Greeting.name, true) }
|
|
||||||
.distinctBy { it.TAG }
|
|
||||||
.forEach {
|
|
||||||
VARGREETINGTOTAL.add(it)
|
|
||||||
}
|
|
||||||
result.append(VARGREETINGTOTAL.size).append("@")
|
result.append(VARGREETINGTOTAL.size).append("@")
|
||||||
cb.accept(result.toString())
|
cb.accept(result.toString())
|
||||||
|
|
||||||
|
|||||||
@@ -12,9 +12,30 @@ enum class Language(name: String) {
|
|||||||
LOCAL("LOCAL"),
|
LOCAL("LOCAL"),
|
||||||
JAPANESE("JAPANESE"),
|
JAPANESE("JAPANESE"),
|
||||||
CHINESE("CHINESE"),
|
CHINESE("CHINESE"),
|
||||||
ARABIC("ARABIC");
|
ARABIC("ARABIC"),
|
||||||
|
DEFAULT(INDONESIA.name); // default language
|
||||||
|
|
||||||
companion object{
|
companion object{
|
||||||
|
/**
|
||||||
|
* Default language link string
|
||||||
|
*/
|
||||||
|
fun DefaultLanguageLink() : String {
|
||||||
|
return DEFAULT.name+";"+ENGLISH.name
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default language order
|
||||||
|
*/
|
||||||
|
fun LanguageOrder() : List<String> {
|
||||||
|
return listOf(
|
||||||
|
INDONESIA.name,
|
||||||
|
LOCAL.name,
|
||||||
|
ENGLISH.name,
|
||||||
|
CHINESE.name,
|
||||||
|
JAPANESE.name,
|
||||||
|
ARABIC.name
|
||||||
|
)
|
||||||
|
}
|
||||||
fun from_GoogleTTSLanguage(lang: google.GoogleTTSLanguage) : Language {
|
fun from_GoogleTTSLanguage(lang: google.GoogleTTSLanguage) : Language {
|
||||||
return when(lang) {
|
return when(lang) {
|
||||||
google.GoogleTTSLanguage.Indonesia -> INDONESIA
|
google.GoogleTTSLanguage.Indonesia -> INDONESIA
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
|||||||
package database
|
package database.data
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
data class BroadcastZones(var index: UInt, var description: String, var SoundChannel: String, var id: String, var bp: String){
|
data class BroadcastZones(var index: UInt, var description: String, var SoundChannel: String, var id: String, var bp: String){
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package database
|
package database.data
|
||||||
|
|
||||||
data class LanguageLink(var index: UInt, var TAG: String, var Language: String){
|
data class LanguageLink(var index: UInt, var TAG: String, var Language: String){
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package database
|
package database.data
|
||||||
|
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.LocalTime
|
import java.time.LocalTime
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package database
|
package database.data
|
||||||
|
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.LocalTime
|
import java.time.LocalTime
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package database
|
package database.data
|
||||||
|
|
||||||
data class Messagebank(
|
data class Messagebank(
|
||||||
var index : UInt,
|
var index : UInt,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package database
|
package database.data
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
data class QueueFids(var index: UInt, var ALCODE: String, var FLNUM: String, var ORIGIN: String, var ETAD: String, var FREMARK: String){
|
data class QueueFids(var index: UInt, var ALCODE: String, var FLNUM: String, var ORIGIN: String, var ETAD: String, var FREMARK: String){
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
package database
|
package database.data
|
||||||
|
|
||||||
|
import codes.Somecodes
|
||||||
|
import java.time.Duration
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
data class QueuePaging(var index: UInt, var Date_Time: String, var Source: String, var Type: String, var Message: String, var BroadcastZones: String){
|
data class QueuePaging(var index: UInt, var Date_Time: String, var Source: String, var Type: String, var Message: String, var BroadcastZones: String){
|
||||||
fun isNotEmpty(): Boolean {
|
fun isNotEmpty(): Boolean {
|
||||||
@@ -18,8 +22,8 @@ data class QueuePaging(var index: UInt, var Date_Time: String, var Source: Strin
|
|||||||
*/
|
*/
|
||||||
fun isExpired(qt: QueuePaging) : Boolean{
|
fun isExpired(qt: QueuePaging) : Boolean{
|
||||||
try{
|
try{
|
||||||
val t1 = java.time.LocalDateTime.parse(qt.Date_Time, codes.Somecodes.datetimeformat1)
|
val t1 = LocalDateTime.parse(qt.Date_Time, Somecodes.datetimeformat1)
|
||||||
val delta = java.time.Duration.between(t1, java.time.LocalDateTime.now())
|
val delta = Duration.between(t1, LocalDateTime.now())
|
||||||
return delta.seconds > 5
|
return delta.seconds > 5
|
||||||
} catch (_: Exception){
|
} catch (_: Exception){
|
||||||
return false
|
return false
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package database
|
package database.data
|
||||||
|
|
||||||
import codes.Somecodes.Companion.datetimeformat1
|
import codes.Somecodes.Companion.datetimeformat1
|
||||||
|
import java.time.Duration
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
data class QueueTable(var index: UInt, var Date_Time: String, var Source: String, var Type: String, var Message: String, var SB_TAGS: String, var BroadcastZones: String, var Repeat: UInt, var Language: String){
|
data class QueueTable(var index: UInt, var Date_Time: String, var Source: String, var Type: String, var Message: String, var SB_TAGS: String, var BroadcastZones: String, var Repeat: UInt, var Language: String){
|
||||||
@@ -25,7 +26,7 @@ data class QueueTable(var index: UInt, var Date_Time: String, var Source: String
|
|||||||
fun isExpired(qt: QueueTable) : Boolean{
|
fun isExpired(qt: QueueTable) : Boolean{
|
||||||
try{
|
try{
|
||||||
val t1 = LocalDateTime.parse(qt.Date_Time, datetimeformat1)
|
val t1 = LocalDateTime.parse(qt.Date_Time, datetimeformat1)
|
||||||
val delta = java.time.Duration.between(t1, LocalDateTime.now())
|
val delta = Duration.between(t1, LocalDateTime.now())
|
||||||
// expired if more than 5 seconds
|
// expired if more than 5 seconds
|
||||||
return delta.seconds > 5
|
return delta.seconds > 5
|
||||||
} catch (_: Exception){
|
} catch (_: Exception){
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package database
|
package database.data
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
data class ScheduleBank(
|
data class ScheduleBank(
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package database
|
package database.data
|
||||||
|
|
||||||
data class SoundChannel(val index: UInt, val channel: String, val ip: String) {
|
data class SoundChannel(val index: UInt, val channel: String, val ip: String) {
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
package database
|
package database.data
|
||||||
|
|
||||||
|
|
||||||
data class Soundbank(
|
data class Soundbank(
|
||||||
var index: UInt,
|
var index: UInt,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package database
|
package database.data
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
data class UserDB(var index: UInt, var username: String, var password: String, var location: String, var airline_tags: String, var city_tags: String, var messagebank_ann_id: String, var broadcastzones: String){
|
data class UserDB(var index: UInt, var username: String, var password: String, var location: String, var airline_tags: String, var city_tags: String, var messagebank_ann_id: String, var broadcastzones: String){
|
||||||
@@ -26,6 +26,3 @@ data class UserDB(var index: UInt, var username: String, var password: String, v
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
203
src/database/table/Table_BroadcastZones.kt
Normal file
203
src/database/table/Table_BroadcastZones.kt
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
package database.table
|
||||||
|
|
||||||
|
import database.data.BroadcastZones
|
||||||
|
import database.dbFunctions
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
||||||
|
import org.tinylog.Logger
|
||||||
|
import java.sql.Connection
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
|
class Table_BroadcastZones(connection: Connection) : dbFunctions<BroadcastZones>("broadcastzones", connection, listOf("index", "description", "SoundChannel", "id", "bp")) {
|
||||||
|
override fun Create() {
|
||||||
|
val tabledefinition = "CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
||||||
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
||||||
|
"description VARCHAR(512) NOT NULL," + // Description of the broadcast zone
|
||||||
|
"SoundChannel VARCHAR(45) NOT NULL," + // Sound channel of the broadcast zone
|
||||||
|
"id VARCHAR(45) NOT NULL," + // Box of the broadcast zone
|
||||||
|
"bp VARCHAR(45) NOT NULL" + // Relay of the broadcast zone
|
||||||
|
")"
|
||||||
|
super.Create(tabledefinition)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Get(cbOK: Consumer<Unit>?, cbFail: Consumer<String>?) {
|
||||||
|
List.clear()
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val zone = BroadcastZones(
|
||||||
|
resultSet.getLong("index").toUInt(),
|
||||||
|
resultSet.getString("description"),
|
||||||
|
resultSet.getString("SoundChannel"),
|
||||||
|
resultSet.getString("id"),
|
||||||
|
resultSet.getString("bp")
|
||||||
|
)
|
||||||
|
List.add(zone)
|
||||||
|
}
|
||||||
|
cbOK?.accept(Unit)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error fetching ${super.dbName} : ${e.message}" as Any)
|
||||||
|
cbFail?.accept("Error fetching ${super.dbName} : ${e.message}" )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Add(data: BroadcastZones): Boolean {
|
||||||
|
try {
|
||||||
|
val statement =
|
||||||
|
connection.prepareStatement("INSERT INTO ${super.dbName} (description, SoundChannel, id, bp) VALUES (?, ?, ?, ?)")
|
||||||
|
statement?.setString(1, data.description)
|
||||||
|
statement?.setString(2, data.SoundChannel)
|
||||||
|
statement?.setString(3, data.id)
|
||||||
|
statement?.setString(4, data.bp)
|
||||||
|
val rowsAffected = statement?.executeUpdate()
|
||||||
|
if (rowsAffected != null && rowsAffected > 0) {
|
||||||
|
Logger.info("Broadcast zone added: ${data.description}" as Any)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
Logger.warn("No broadcast zone entry added for: ${data.description}" as Any)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error adding broadcast zone entry: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun AddAll(data: ArrayList<BroadcastZones>): Boolean {
|
||||||
|
try {
|
||||||
|
connection.autoCommit = false
|
||||||
|
val sql =
|
||||||
|
"INSERT INTO ${super.dbName} (description, SoundChannel, id, bp) VALUES (?, ?, ?, ?)"
|
||||||
|
val statement = connection.prepareStatement(sql)
|
||||||
|
for (bz in data) {
|
||||||
|
statement.setString(1, bz.description)
|
||||||
|
statement.setString(2, bz.SoundChannel)
|
||||||
|
statement.setString(3, bz.id)
|
||||||
|
statement.setString(4, bz.bp)
|
||||||
|
statement.addBatch()
|
||||||
|
}
|
||||||
|
statement.executeBatch()
|
||||||
|
connection.commit()
|
||||||
|
Logger.info("Bulk ${super.dbName} insert successful: ${data.size} entries" as Any)
|
||||||
|
connection.autoCommit = true
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error adding ${super.dbName} entries: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun UpdateByIndex(index: Int, data: BroadcastZones): Boolean {
|
||||||
|
try {
|
||||||
|
val statement =
|
||||||
|
connection.prepareStatement("UPDATE ${super.dbName} SET description = ?, SoundChannel = ?, id = ?, bp = ? WHERE `index` = ?")
|
||||||
|
statement?.setString(1, data.description)
|
||||||
|
statement?.setString(2, data.SoundChannel)
|
||||||
|
statement?.setString(3, data.id)
|
||||||
|
statement?.setString(4, data.bp)
|
||||||
|
statement?.setLong(5, index.toLong())
|
||||||
|
val rowsAffected = statement?.executeUpdate()
|
||||||
|
if (rowsAffected != null && rowsAffected > 0) {
|
||||||
|
Logger.info("Broadcast zone updated at index $index: ${data.description}" as Any)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
Logger.warn("No broadcast zone entry updated at index $index for: ${data.description}" as Any)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error updating broadcast zone entry at index $index: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Resort(): Boolean {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val tempdb_name = "temp_${super.dbName}"
|
||||||
|
// use a temporary table to reorder the index
|
||||||
|
statement?.executeUpdate("CREATE TABLE IF NOT EXISTS $tempdb_name LIKE ${super.dbName}")
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE $tempdb_name")
|
||||||
|
statement?.executeUpdate("INSERT INTO $tempdb_name (description, SoundChannel, id, bp) SELECT description, SoundChannel, id, bp FROM ${super.dbName} ORDER BY description ")
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
||||||
|
statement?.executeUpdate("INSERT INTO ${super.dbName} (description, SoundChannel, id, bp) SELECT description, SoundChannel, id, bp FROM $tempdb_name")
|
||||||
|
statement?.executeUpdate("DROP TABLE $tempdb_name")
|
||||||
|
Logger.info("${super.dbName} table resorted by description" as Any)
|
||||||
|
// reload the local list
|
||||||
|
Get()
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error resorting ${super.dbName} table by description: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Import_XLSX(workbook: XSSFWorkbook): Boolean {
|
||||||
|
try {
|
||||||
|
val sheet = workbook.getSheet("BroadcastZones")
|
||||||
|
?: throw Exception("No sheet named 'BroadcastZones' found")
|
||||||
|
val headerRow = sheet.getRow(0) ?: throw Exception("No header row found")
|
||||||
|
val headers = arrayOf("Index", "description", "SoundChannel", "id", "bp")
|
||||||
|
for ((colIndex, header) in headers.withIndex()) {
|
||||||
|
val cell = headerRow.getCell(colIndex) ?: throw Exception("Header '$header' not found")
|
||||||
|
if (cell.stringCellValue != header) throw Exception("Header '$header' not found")
|
||||||
|
}
|
||||||
|
// clear existing broadcast_zones
|
||||||
|
Clear()
|
||||||
|
// read each row and insert into database
|
||||||
|
val _broadcastZonesList = ArrayList<BroadcastZones>()
|
||||||
|
for (rowIndex in 1..sheet.lastRowNum) {
|
||||||
|
val row = sheet.getRow(rowIndex) ?: continue
|
||||||
|
val description = row.getCell(1)?.stringCellValue ?: continue
|
||||||
|
val soundChannel = row.getCell(2)?.stringCellValue ?: continue
|
||||||
|
val id = row.getCell(3)?.stringCellValue ?: continue
|
||||||
|
val bp = row.getCell(4)?.stringCellValue ?: continue
|
||||||
|
val broadcastZone = BroadcastZones(0u, description, soundChannel, id, bp)
|
||||||
|
_broadcastZonesList.add(broadcastZone)
|
||||||
|
}
|
||||||
|
return AddAll(_broadcastZonesList)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error { "Error importing BroadcastZones, Msg: ${e.message}" }
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Export_XLSX(): XSSFWorkbook? {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
||||||
|
val workbook = XSSFWorkbook()
|
||||||
|
val sheet = workbook.createSheet("BroadcastZones")
|
||||||
|
val headerRow = sheet.createRow(0)
|
||||||
|
val headers = arrayOf("Index", "description", "SoundChannel", "id", "bp")
|
||||||
|
for ((colIndex, header) in headers.withIndex()) {
|
||||||
|
val cell = headerRow.createCell(colIndex)
|
||||||
|
cell.setCellValue(header)
|
||||||
|
}
|
||||||
|
var rowIndex = 1
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val row = sheet.createRow(rowIndex++)
|
||||||
|
row.createCell(0).setCellValue(resultSet.getString("index"))
|
||||||
|
row.createCell(1).setCellValue(resultSet.getString("description"))
|
||||||
|
row.createCell(2).setCellValue(resultSet.getString("SoundChannel"))
|
||||||
|
row.createCell(3).setCellValue(resultSet.getString("id"))
|
||||||
|
row.createCell(4).setCellValue(resultSet.getString("bp"))
|
||||||
|
}
|
||||||
|
for (i in headers.indices) {
|
||||||
|
sheet.autoSizeColumn(i)
|
||||||
|
}
|
||||||
|
return workbook
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error { "Error exporting BroadcastZones, Msg: ${e.message}" }
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all distinct broadcast zone descriptions from broadcastDB
|
||||||
|
* @return a list of distinct broadcast zone descriptions sorted alphabetically
|
||||||
|
*/
|
||||||
|
fun Get_BroadcastZone_List(): List<String> {
|
||||||
|
return List
|
||||||
|
.distinctBy { it.description }
|
||||||
|
.map { it.description }
|
||||||
|
.sorted()
|
||||||
|
}
|
||||||
|
}
|
||||||
180
src/database/table/Table_LanguageLink.kt
Normal file
180
src/database/table/Table_LanguageLink.kt
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
package database.table
|
||||||
|
|
||||||
|
import database.data.LanguageLink
|
||||||
|
import database.dbFunctions
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
||||||
|
import org.tinylog.Logger
|
||||||
|
import java.sql.Connection
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
|
class Table_LanguageLink(connection: Connection) : dbFunctions<LanguageLink>("languagelinking", connection, listOf("index", "TAG", "Language")) {
|
||||||
|
override fun Create() {
|
||||||
|
val tabledefinition = "CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
||||||
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
||||||
|
"TAG VARCHAR(45) NOT NULL," + // Language tag (e.g., EN, FR)
|
||||||
|
"Language VARCHAR(128) NOT NULL" + // Full language name (e.g., English, French)
|
||||||
|
")"
|
||||||
|
|
||||||
|
super.Create(tabledefinition)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Get(cbOK: Consumer<Unit>?, cbFail: Consumer<String>?) {
|
||||||
|
List.clear()
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val languageLink = LanguageLink(
|
||||||
|
resultSet.getLong("index").toUInt(),
|
||||||
|
resultSet.getString("TAG"),
|
||||||
|
resultSet.getString("Language")
|
||||||
|
)
|
||||||
|
List.add(languageLink)
|
||||||
|
}
|
||||||
|
cbOK?.accept(Unit)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error fetching ${super.dbName} : ${e.message}" as Any)
|
||||||
|
cbFail?.accept("Error fetching ${super.dbName} : ${e.message}" )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Add(data: LanguageLink): Boolean {
|
||||||
|
try {
|
||||||
|
val statement = connection.prepareStatement("INSERT INTO ${super.dbName} (TAG, Language) VALUES (?, ?)")
|
||||||
|
statement.setString(1, data.TAG)
|
||||||
|
statement.setString(2, data.Language)
|
||||||
|
val rowsAffected = statement.executeUpdate()
|
||||||
|
if (rowsAffected > 0) {
|
||||||
|
Logger.info("Language link added: ${data.TAG} -> ${data.Language}" as Any)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
Logger.warn("No language link entry added for: ${data.TAG} -> ${data.Language}" as Any)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error adding language link entry: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun AddAll(data: ArrayList<LanguageLink>): Boolean {
|
||||||
|
try {
|
||||||
|
connection.autoCommit = false
|
||||||
|
val sql = "INSERT INTO ${super.dbName} (TAG, Language) VALUES (?, ?)"
|
||||||
|
val statement = connection.prepareStatement(sql)
|
||||||
|
|
||||||
|
//for (ll in List) {
|
||||||
|
for (ll in data) {
|
||||||
|
statement.setString(1, ll.TAG)
|
||||||
|
statement.setString(2, ll.Language)
|
||||||
|
statement.addBatch()
|
||||||
|
}
|
||||||
|
statement.executeBatch()
|
||||||
|
connection.commit()
|
||||||
|
Logger.info("Bulk languagelinking insert successful: ${List.size} entries" as Any)
|
||||||
|
connection.autoCommit = true
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error adding languagelinking entries: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun UpdateByIndex(index: Int, data: LanguageLink): Boolean {
|
||||||
|
try {
|
||||||
|
val statement =
|
||||||
|
connection.prepareStatement("UPDATE ${super.dbName} SET TAG = ?, Language = ? WHERE `index` = ?")
|
||||||
|
statement?.setString(1, data.TAG)
|
||||||
|
statement?.setString(2, data.Language)
|
||||||
|
statement?.setLong(3, index.toLong())
|
||||||
|
val rowsAffected = statement?.executeUpdate()
|
||||||
|
if (rowsAffected != null && rowsAffected > 0) {
|
||||||
|
Logger.info("Language link updated at index $index: ${data.TAG} -> ${data.Language}" as Any)
|
||||||
|
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
Logger.warn("No language link entry updated at index $index for: ${data.TAG} -> ${data.Language}" as Any)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error updating language link entry at index $index: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Resort(): Boolean {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val tempdb_name = "temp_${super.dbName}"
|
||||||
|
// use a temporary table to reorder the index
|
||||||
|
statement?.executeUpdate("CREATE TABLE IF NOT EXISTS $tempdb_name LIKE ${super.dbName}")
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE $tempdb_name")
|
||||||
|
statement?.executeUpdate("INSERT INTO $tempdb_name (TAG, Language) SELECT TAG, Language FROM ${super.dbName} ORDER BY TAG")
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
||||||
|
statement?.executeUpdate("INSERT INTO ${super.dbName} (TAG, Language) SELECT TAG, Language FROM $tempdb_name")
|
||||||
|
statement?.executeUpdate("DROP TABLE $tempdb_name")
|
||||||
|
Logger.info("${super.dbName} table resorted by TAG" as Any)
|
||||||
|
// reload the local list
|
||||||
|
Get()
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error resorting ${super.dbName} table by TAG: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Import_XLSX(workbook: XSSFWorkbook): Boolean {
|
||||||
|
try {
|
||||||
|
val sheet =
|
||||||
|
workbook.getSheet("LanguageLink") ?: throw Exception("No sheet named 'LanguageLink' found")
|
||||||
|
val headerRow = sheet.getRow(0) ?: throw Exception("No header row found")
|
||||||
|
val headers = arrayOf("Index", "TAG", "Language")
|
||||||
|
for ((colIndex, header) in headers.withIndex()) {
|
||||||
|
val cell = headerRow.getCell(colIndex) ?: throw Exception("Header '$header' not found")
|
||||||
|
if (cell.stringCellValue != header) throw Exception("Header '$header' not found")
|
||||||
|
}
|
||||||
|
// clear existing languagelink
|
||||||
|
Clear()
|
||||||
|
// read each row and insert into database
|
||||||
|
val _languageLinkList = ArrayList<LanguageLink>()
|
||||||
|
for (rowIndex in 1..sheet.lastRowNum) {
|
||||||
|
val row = sheet.getRow(rowIndex) ?: continue
|
||||||
|
val tag = row.getCell(1)?.stringCellValue ?: continue
|
||||||
|
val language = row.getCell(2)?.stringCellValue ?: continue
|
||||||
|
val languageLink = LanguageLink(0u, tag, language)
|
||||||
|
_languageLinkList.add(languageLink)
|
||||||
|
}
|
||||||
|
return AddAll(_languageLinkList)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error { "Error importing LanguageLink, Msg: ${e.message}" }
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Export_XLSX(): XSSFWorkbook? {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
||||||
|
val workbook = XSSFWorkbook()
|
||||||
|
val sheet = workbook.createSheet("LanguageLink")
|
||||||
|
val headerRow = sheet.createRow(0)
|
||||||
|
val headers = arrayOf("Index", "TAG", "Language")
|
||||||
|
for ((colIndex, header) in headers.withIndex()) {
|
||||||
|
val cell = headerRow.createCell(colIndex)
|
||||||
|
cell.setCellValue(header)
|
||||||
|
}
|
||||||
|
var rowIndex = 1
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val row = sheet.createRow(rowIndex++)
|
||||||
|
row.createCell(0).setCellValue(resultSet.getString("index"))
|
||||||
|
row.createCell(1).setCellValue(resultSet.getString("TAG"))
|
||||||
|
row.createCell(2).setCellValue(resultSet.getString("Language"))
|
||||||
|
}
|
||||||
|
for (i in headers.indices) {
|
||||||
|
sheet.autoSizeColumn(i)
|
||||||
|
}
|
||||||
|
return workbook
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error { "Error exporting languagelinking, Msg: ${e.message}" }
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
package database
|
package database.table
|
||||||
|
|
||||||
|
import database.data.LogSemiauto
|
||||||
|
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 java.sql.Connection
|
import java.sql.Connection
|
||||||
|
import java.sql.Date
|
||||||
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
|
||||||
@@ -92,18 +95,18 @@ class Table_LogSemiAuto(connection: Connection) : dbFunctions<LogSemiauto>("logs
|
|||||||
|
|
||||||
fun GetLogSemiAutoForHtml(date: String, filter: String?, cbOK: Consumer<ArrayList<LogSemiauto>>?, cbFail: Consumer<String>?){
|
fun GetLogSemiAutoForHtml(date: String, filter: String?, cbOK: Consumer<ArrayList<LogSemiauto>>?, cbFail: Consumer<String>?){
|
||||||
try{
|
try{
|
||||||
val valid_date : java.sql.Date? = when{
|
val valid_date : Date? = when{
|
||||||
dateformat1.matches(date) -> {
|
dateformat1.matches(date) -> {
|
||||||
java.sql.Date.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern("dd/MM/yyyy")))
|
Date.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern("dd/MM/yyyy")))
|
||||||
}
|
}
|
||||||
dateformat2.matches(date) -> {
|
dateformat2.matches(date) -> {
|
||||||
java.sql.Date.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern("dd-MM-yyyy")))
|
Date.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern("dd-MM-yyyy")))
|
||||||
}
|
}
|
||||||
dateformat3.matches(date) -> {
|
dateformat3.matches(date) -> {
|
||||||
java.sql.Date.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy/MM/dd")))
|
Date.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy/MM/dd")))
|
||||||
}
|
}
|
||||||
dateformat4.matches(date) -> {
|
dateformat4.matches(date) -> {
|
||||||
java.sql.Date.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd")))
|
Date.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd")))
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
package database
|
package database.table
|
||||||
|
|
||||||
|
import database.data.Log
|
||||||
|
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 java.sql.Connection
|
import java.sql.Connection
|
||||||
|
import java.sql.Date
|
||||||
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
|
||||||
|
|
||||||
class Table_Logs(connection: Connection) : dbFunctions<Log> ("logs", connection,listOf("index", "datenya", "timenya", "machine", "description")) {
|
class Table_Logs(connection: Connection) : dbFunctions<Log>("logs", connection,listOf("index", "datenya", "timenya", "machine", "description")) {
|
||||||
/**
|
/**
|
||||||
* dateformat1 is regex for DD/MM/YYYY
|
* dateformat1 is regex for DD/MM/YYYY
|
||||||
*/
|
*/
|
||||||
@@ -44,18 +47,18 @@ class Table_Logs(connection: Connection) : dbFunctions<Log> ("logs", connection,
|
|||||||
|
|
||||||
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{
|
||||||
val valid_date : java.sql.Date? = when{
|
val valid_date : Date? = when{
|
||||||
dateformat1.matches(date) -> {
|
dateformat1.matches(date) -> {
|
||||||
java.sql.Date.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern("dd/MM/yyyy")))
|
Date.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern("dd/MM/yyyy")))
|
||||||
}
|
}
|
||||||
dateformat2.matches(date) -> {
|
dateformat2.matches(date) -> {
|
||||||
java.sql.Date.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern("dd-MM-yyyy")))
|
Date.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern("dd-MM-yyyy")))
|
||||||
}
|
}
|
||||||
dateformat3.matches(date) -> {
|
dateformat3.matches(date) -> {
|
||||||
java.sql.Date.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy/MM/dd")))
|
Date.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy/MM/dd")))
|
||||||
}
|
}
|
||||||
dateformat4.matches(date) -> {
|
dateformat4.matches(date) -> {
|
||||||
java.sql.Date.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd")))
|
Date.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd")))
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
@@ -202,6 +205,74 @@ class Table_Logs(connection: Connection) : dbFunctions<Log> ("logs", connection,
|
|||||||
throw Exception("Importing Logs from XLSX is not supported")
|
throw Exception("Importing Logs from XLSX is not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exports the log table to an XLSX workbook for a specific date and optional filter.
|
||||||
|
* @param logDate The date string in format "dd/MM/yyyy".
|
||||||
|
* @param logFilter The filter string for the description or machine. If empty, exports all logs for the date.
|
||||||
|
* @return An XSSFWorkbook containing the filtered log data, or null if an error occurred.
|
||||||
|
*/
|
||||||
|
fun Export_Log_XLSX(logDate: String, logFilter: String): XSSFWorkbook? {
|
||||||
|
try {
|
||||||
|
val valid_date : Date? = when{
|
||||||
|
dateformat1.matches(logDate) -> {
|
||||||
|
Date.valueOf(LocalDate.parse(logDate, DateTimeFormatter.ofPattern("dd/MM/yyyy")))
|
||||||
|
}
|
||||||
|
dateformat2.matches(logDate) -> {
|
||||||
|
Date.valueOf(LocalDate.parse(logDate, DateTimeFormatter.ofPattern("dd-MM-yyyy")))
|
||||||
|
}
|
||||||
|
dateformat3.matches(logDate) -> {
|
||||||
|
Date.valueOf(LocalDate.parse(logDate, DateTimeFormatter.ofPattern("yyyy/MM/dd")))
|
||||||
|
}
|
||||||
|
dateformat4.matches(logDate) -> {
|
||||||
|
Date.valueOf(LocalDate.parse(logDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")))
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid_date!=null){
|
||||||
|
// use coalescing for different datenya formats
|
||||||
|
val statement = if (logFilter.isEmpty()){
|
||||||
|
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 {
|
||||||
|
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 ?")
|
||||||
|
}
|
||||||
|
statement?.setDate(1, valid_date)
|
||||||
|
if (logFilter.isNotEmpty()){
|
||||||
|
statement?.setString(2, "%$logFilter%")
|
||||||
|
}
|
||||||
|
val resultSet = statement?.executeQuery()
|
||||||
|
|
||||||
|
val workbook = XSSFWorkbook()
|
||||||
|
val sheet = workbook.createSheet("Log")
|
||||||
|
val headerRow = sheet.createRow(0)
|
||||||
|
val headers = arrayOf("Index", "datenya", "timenya", "machine", "description")
|
||||||
|
for ((colIndex, header) in headers.withIndex()) {
|
||||||
|
val cell = headerRow.createCell(colIndex)
|
||||||
|
cell.setCellValue(header)
|
||||||
|
}
|
||||||
|
var rowIndex = 1
|
||||||
|
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val row = sheet.createRow(rowIndex++)
|
||||||
|
row.createCell(0).setCellValue(resultSet.getString("index"))
|
||||||
|
row.createCell(1).setCellValue(resultSet.getString("datenya"))
|
||||||
|
row.createCell(2).setCellValue(resultSet.getString("timenya"))
|
||||||
|
row.createCell(3).setCellValue(resultSet.getString("machine"))
|
||||||
|
row.createCell(4).setCellValue(resultSet.getString("description"))
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i in headers.indices) {
|
||||||
|
sheet.autoSizeColumn(i)
|
||||||
|
}
|
||||||
|
return workbook
|
||||||
|
} else throw Exception("Invalid date")
|
||||||
|
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error { "Error exporting Log, Msg: ${e.message}" }
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
override fun Export_XLSX(): XSSFWorkbook? {
|
override fun Export_XLSX(): XSSFWorkbook? {
|
||||||
try {
|
try {
|
||||||
val statement = connection.createStatement()
|
val statement = connection.createStatement()
|
||||||
239
src/database/table/Table_Messagebank.kt
Normal file
239
src/database/table/Table_Messagebank.kt
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
package database.table
|
||||||
|
|
||||||
|
import database.data.Messagebank
|
||||||
|
import database.dbFunctions
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
||||||
|
import org.tinylog.Logger
|
||||||
|
import java.sql.Connection
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
|
class Table_Messagebank(connection: Connection) : dbFunctions<Messagebank>("messagebank", connection, listOf("index", "Description", "Language", "ANN_ID", "Voice_Type", "Message_Detail", "Message_TAGS")) {
|
||||||
|
override fun Create() {
|
||||||
|
val tabledefinition = "CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
||||||
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
||||||
|
"Description VARCHAR(512) NOT NULL," + // Description of the message
|
||||||
|
"Language VARCHAR(45) NOT NULL," + // Language of the message
|
||||||
|
"ANN_ID INT NOT NULL," + // ANN ID of the message
|
||||||
|
"Voice_Type VARCHAR(45) NOT NULL," + // Voice type of the message
|
||||||
|
"Message_Detail VARCHAR(1024) NOT NULL," + // Full message text
|
||||||
|
"Message_TAGS VARCHAR(1024)" + // Comma-separated tags for the message
|
||||||
|
")"
|
||||||
|
super.Create(tabledefinition)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Get(cbOK: Consumer<Unit>?, cbFail: Consumer<String>?) {
|
||||||
|
List.clear()
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val messagebank = Messagebank(
|
||||||
|
resultSet.getLong("index").toUInt(),
|
||||||
|
resultSet.getString("Description"),
|
||||||
|
resultSet.getString("Language"),
|
||||||
|
resultSet.getInt("ANN_ID").toUInt(),
|
||||||
|
resultSet.getString("Voice_Type"),
|
||||||
|
resultSet.getString("Message_Detail"),
|
||||||
|
resultSet.getString("Message_TAGS")
|
||||||
|
)
|
||||||
|
|
||||||
|
List.add(messagebank)
|
||||||
|
}
|
||||||
|
cbOK?.accept(Unit)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error fetching ${super.dbName} : ${e.message}" as Any)
|
||||||
|
cbFail?.accept("Error fetching ${super.dbName} : ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Add(data: Messagebank): Boolean {
|
||||||
|
try {
|
||||||
|
val statement =
|
||||||
|
connection.prepareStatement("INSERT INTO ${super.dbName} (Description, Language, ANN_ID, Voice_Type, Message_Detail, Message_TAGS) VALUES (?, ?, ?, ?, ?, ?)")
|
||||||
|
statement?.setString(1, data.Description)
|
||||||
|
statement?.setString(2, data.Language)
|
||||||
|
statement?.setInt(3, data.ANN_ID.toInt())
|
||||||
|
statement?.setString(4, data.Voice_Type)
|
||||||
|
statement?.setString(5, data.Message_Detail)
|
||||||
|
statement?.setString(6, data.Message_TAGS)
|
||||||
|
val rowsAffected = statement?.executeUpdate()
|
||||||
|
if (rowsAffected != null && rowsAffected > 0) {
|
||||||
|
Logger.info("Messagebank added: ${data.Description}" as Any)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
Logger.warn("No messagebank entry added for: ${data.Description}" as Any)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error adding messagebank entry: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun AddAll(data: ArrayList<Messagebank>): Boolean {
|
||||||
|
try {
|
||||||
|
connection.autoCommit = false
|
||||||
|
val sql =
|
||||||
|
"INSERT INTO ${super.dbName} (Description, Language, ANN_ID, Voice_Type, Message_Detail, Message_TAGS) VALUES (?, ?, ?, ?, ?, ?)"
|
||||||
|
val statement = connection.prepareStatement(sql)
|
||||||
|
for (mb in data) {
|
||||||
|
statement.setString(1, mb.Description)
|
||||||
|
statement.setString(2, mb.Language)
|
||||||
|
statement.setInt(3, mb.ANN_ID.toInt())
|
||||||
|
statement.setString(4, mb.Voice_Type)
|
||||||
|
statement.setString(5, mb.Message_Detail)
|
||||||
|
statement.setString(6, mb.Message_TAGS)
|
||||||
|
statement.addBatch()
|
||||||
|
}
|
||||||
|
statement.executeBatch()
|
||||||
|
connection.commit()
|
||||||
|
Logger.info("Bulk messagebank insert successful: ${data.size} entries" as Any)
|
||||||
|
connection.autoCommit = true
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error adding messagebank entries: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun UpdateByIndex(index: Int, data: Messagebank): Boolean {
|
||||||
|
try {
|
||||||
|
val statement =
|
||||||
|
connection.prepareStatement("UPDATE ${super.dbName} SET Description = ?, Language = ?, ANN_ID = ?, Voice_Type = ?, Message_Detail = ?, Message_TAGS = ? WHERE `index` = ?")
|
||||||
|
statement?.setString(1, data.Description)
|
||||||
|
statement?.setString(2, data.Language)
|
||||||
|
statement?.setInt(3, data.ANN_ID.toInt())
|
||||||
|
statement?.setString(4, data.Voice_Type)
|
||||||
|
statement?.setString(5, data.Message_Detail)
|
||||||
|
statement?.setString(6, data.Message_TAGS)
|
||||||
|
statement?.setLong(7, index.toLong())
|
||||||
|
val rowsAffected = statement?.executeUpdate()
|
||||||
|
if (rowsAffected != null && rowsAffected > 0) {
|
||||||
|
Logger.info("Messagebank updated at index $index: ${data.Description}" as Any)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
Logger.warn("No messagebank entry updated at index $index for: ${data.Description}" as Any)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error updating messagebank entry at index $index: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Resort(): Boolean {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val tempdb_name = "temp_${super.dbName}"
|
||||||
|
// use a temporary table to reorder the index
|
||||||
|
statement?.executeUpdate("CREATE TABLE IF NOT EXISTS $tempdb_name LIKE ${super.dbName}")
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE $tempdb_name")
|
||||||
|
statement?.executeUpdate("INSERT INTO $tempdb_name (Description, Language, ANN_ID, Voice_Type, Message_Detail, Message_TAGS) SELECT Description, Language, ANN_ID, Voice_Type, Message_Detail, Message_TAGS FROM ${super.dbName} ORDER BY ANN_ID ")
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
||||||
|
statement?.executeUpdate("INSERT INTO ${super.dbName} (Description, Language, ANN_ID, Voice_Type, Message_Detail, Message_TAGS) SELECT Description, Language, ANN_ID, Voice_Type, Message_Detail, Message_TAGS FROM $tempdb_name")
|
||||||
|
statement?.executeUpdate("DROP TABLE $tempdb_name")
|
||||||
|
Logger.info("${super.dbName} table resorted by Description" as Any)
|
||||||
|
// reload the local list
|
||||||
|
Get()
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error resorting ${super.dbName} table by Description: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Import_XLSX(workbook: XSSFWorkbook): Boolean {
|
||||||
|
try {
|
||||||
|
// check if there is sheet named "Messagebank"
|
||||||
|
val sheet =
|
||||||
|
workbook.getSheet("Messagebank") ?: throw Exception("No sheet named 'Messagebank' found")
|
||||||
|
// check if the sheet contains header named "Index", "Description", "Language", "ANN_ID", "Voice_Type", "Message_Detail", "Message_TAGS"
|
||||||
|
val headerRow = sheet.getRow(0) ?: throw Exception("No header row found")
|
||||||
|
val headers =
|
||||||
|
arrayOf(
|
||||||
|
"Index",
|
||||||
|
"Description",
|
||||||
|
"Language",
|
||||||
|
"ANN_ID",
|
||||||
|
"Voice_Type",
|
||||||
|
"Message_Detail",
|
||||||
|
"Message_TAGS"
|
||||||
|
)
|
||||||
|
for ((colIndex, header) in headers.withIndex()) {
|
||||||
|
val cell = headerRow.getCell(colIndex) ?: throw Exception("Header '$header' not found")
|
||||||
|
if (cell.stringCellValue != header) throw Exception("Header '$header' not found")
|
||||||
|
}
|
||||||
|
// clear existing messagebank
|
||||||
|
Clear()
|
||||||
|
// read each row and insert into database
|
||||||
|
val _messagebankList = ArrayList<Messagebank>()
|
||||||
|
for (rowIndex in 1..sheet.lastRowNum) {
|
||||||
|
val row = sheet.getRow(rowIndex) ?: continue
|
||||||
|
val description = row.getCell(1)?.stringCellValue ?: continue
|
||||||
|
val language = row.getCell(2)?.stringCellValue ?: continue
|
||||||
|
val annId = row.getCell(3)?.stringCellValue?.toUIntOrNull() ?: continue
|
||||||
|
val voiceType = row.getCell(4)?.stringCellValue ?: continue
|
||||||
|
val messageDetail = row.getCell(5)?.stringCellValue ?: continue
|
||||||
|
val messageTags = row.getCell(6)?.stringCellValue ?: continue
|
||||||
|
val messagebank =
|
||||||
|
Messagebank(0u, description, language, annId, voiceType, messageDetail, messageTags)
|
||||||
|
_messagebankList.add(messagebank)
|
||||||
|
}
|
||||||
|
return AddAll(_messagebankList)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error { "Error importing Messagebank, Msg: ${e.message}" }
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Export_XLSX(): XSSFWorkbook? {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
||||||
|
val workbook = XSSFWorkbook()
|
||||||
|
val sheet = workbook.createSheet("Messagebank")
|
||||||
|
val headerRow = sheet.createRow(0)
|
||||||
|
val headers =
|
||||||
|
arrayOf(
|
||||||
|
"Index",
|
||||||
|
"Description",
|
||||||
|
"Language",
|
||||||
|
"ANN_ID",
|
||||||
|
"Voice_Type",
|
||||||
|
"Message_Detail",
|
||||||
|
"Message_TAGS"
|
||||||
|
)
|
||||||
|
for ((colIndex, header) in headers.withIndex()) {
|
||||||
|
val cell = headerRow.createCell(colIndex)
|
||||||
|
cell.setCellValue(header)
|
||||||
|
}
|
||||||
|
var rowIndex = 1
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val row = sheet.createRow(rowIndex++)
|
||||||
|
row.createCell(0).setCellValue(resultSet.getString("index"))
|
||||||
|
row.createCell(1).setCellValue(resultSet.getString("Description"))
|
||||||
|
row.createCell(2).setCellValue(resultSet.getString("Language"))
|
||||||
|
row.createCell(3).setCellValue(resultSet.getString("ANN_ID"))
|
||||||
|
row.createCell(4).setCellValue(resultSet.getString("Voice_Type"))
|
||||||
|
row.createCell(5).setCellValue(resultSet.getString("Message_Detail"))
|
||||||
|
row.createCell(6).setCellValue(resultSet.getString("Message_TAGS"))
|
||||||
|
}
|
||||||
|
for (i in headers.indices) {
|
||||||
|
sheet.autoSizeColumn(i)
|
||||||
|
}
|
||||||
|
return workbook
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error { "Error exporting Messagebank, Msg: ${e.message}" }
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all distinct message ID from messagebank
|
||||||
|
* @return a list of distinct ANN_ID sorted numerically
|
||||||
|
*/
|
||||||
|
fun Get_MessageID_List(): List<UInt> {
|
||||||
|
return List
|
||||||
|
.distinctBy { it.ANN_ID }
|
||||||
|
.map { it.ANN_ID }
|
||||||
|
.sorted()
|
||||||
|
}
|
||||||
|
}
|
||||||
156
src/database/table/Table_QueuePaging.kt
Normal file
156
src/database/table/Table_QueuePaging.kt
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
package database.table
|
||||||
|
|
||||||
|
import database.data.QueuePaging
|
||||||
|
import database.dbFunctions
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
||||||
|
import org.tinylog.Logger
|
||||||
|
import java.sql.Connection
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
|
class Table_QueuePaging(connection : Connection) : dbFunctions<QueuePaging>("queue_paging", connection, listOf("index", "Date_Time", "Source", "Type", "Message", "BroadcastZones")) {
|
||||||
|
override fun Create() {
|
||||||
|
val tabledefinition ="CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
||||||
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
||||||
|
"Date_Time VARCHAR(45) NOT NULL," + // Date and time of the entry
|
||||||
|
"Source VARCHAR(45) NOT NULL," + // Source of the entry
|
||||||
|
"Type VARCHAR(45) NOT NULL," + // Type of the entry
|
||||||
|
"Message VARCHAR(1024) NOT NULL," + // Message content
|
||||||
|
"BroadcastZones VARCHAR(1024)" + // Comma-separated soundbank tags
|
||||||
|
")"
|
||||||
|
super.Create(tabledefinition)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Get(cbOK: Consumer<Unit>?, cbFail: Consumer<String>?) {
|
||||||
|
List.clear()
|
||||||
|
val queueList = ArrayList<QueuePaging>()
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val queuePaging = QueuePaging(
|
||||||
|
resultSet.getLong("index").toUInt(),
|
||||||
|
resultSet.getString("Date_Time"),
|
||||||
|
resultSet.getString("Source"),
|
||||||
|
resultSet.getString("Type"),
|
||||||
|
resultSet.getString("Message"),
|
||||||
|
resultSet.getString("BroadcastZones"),
|
||||||
|
)
|
||||||
|
queueList.add(queuePaging)
|
||||||
|
List.add(queuePaging)
|
||||||
|
}
|
||||||
|
cbOK?.accept(Unit)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error fetching ${super.dbName} : ${e.message}" as Any)
|
||||||
|
cbFail?.accept("Error fetching ${super.dbName} : ${e.message}" )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Add(data: QueuePaging): Boolean {
|
||||||
|
try {
|
||||||
|
val statement = connection.prepareStatement(
|
||||||
|
"INSERT INTO ${super.dbName} (Date_Time, Source, Type, Message, BroadcastZones) VALUES (?, ?, ?, ?, ?)"
|
||||||
|
)
|
||||||
|
statement?.setString(1, data.Date_Time)
|
||||||
|
statement?.setString(2, data.Source)
|
||||||
|
statement?.setString(3, data.Type)
|
||||||
|
statement?.setString(4, data.Message)
|
||||||
|
statement?.setString(5, data.BroadcastZones)
|
||||||
|
val rowsAffected = statement?.executeUpdate()
|
||||||
|
if (rowsAffected != null && rowsAffected > 0) {
|
||||||
|
Logger.info("QueuePaging added: ${data.Message}" as Any)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
Logger.warn("No QueuePaging entry added for: ${data.Message}" as Any)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error adding QueuePaging entry: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun AddAll(data: ArrayList<QueuePaging>): Boolean {
|
||||||
|
return try {
|
||||||
|
connection.autoCommit = false
|
||||||
|
val sql =
|
||||||
|
"INSERT INTO ${super.dbName} (Date_Time, Source, Type, Message, BroadcastZones) VALUES (?, ?, ?, ?, ?)"
|
||||||
|
val statement = connection.prepareStatement(sql)
|
||||||
|
for (qp in data) {
|
||||||
|
statement.setString(1, qp.Date_Time)
|
||||||
|
statement.setString(2, qp.Source)
|
||||||
|
statement.setString(3, qp.Type)
|
||||||
|
statement.setString(4, qp.Message)
|
||||||
|
statement.setString(5, qp.BroadcastZones)
|
||||||
|
statement.addBatch()
|
||||||
|
}
|
||||||
|
statement.executeBatch()
|
||||||
|
connection.commit()
|
||||||
|
Logger.info("Bulk QueuePaging insert successful: ${data.size} entries" as Any)
|
||||||
|
connection.autoCommit = true
|
||||||
|
true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error adding QueuePaging entries: ${e.message}" as Any)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun UpdateByIndex(index: Int, data: QueuePaging): Boolean {
|
||||||
|
throw Exception("Update not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Resort(): Boolean {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val tempdb_name = "temp_${super.dbName}"
|
||||||
|
// use a temporary table to reorder the index
|
||||||
|
statement?.executeUpdate("CREATE TABLE IF NOT EXISTS $tempdb_name LIKE ${super.dbName}")
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE $tempdb_name")
|
||||||
|
statement?.executeUpdate("INSERT INTO $tempdb_name (Date_Time, Source, Type, Message, BroadcastZones) SELECT Date_Time, Source, Type, Message, BroadcastZones FROM ${super.dbName} ")
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
||||||
|
statement?.executeUpdate("INSERT INTO ${super.dbName} (Date_Time, Source, Type, Message, BroadcastZones) SELECT Date_Time, Source, Type, Message, BroadcastZones FROM $tempdb_name")
|
||||||
|
statement?.executeUpdate("DROP TABLE $tempdb_name")
|
||||||
|
Logger.info("${super.dbName} table resorted by index" as Any)
|
||||||
|
// reload the local list
|
||||||
|
Get()
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error resorting ${super.dbName} table by index: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Import_XLSX(workbook: XSSFWorkbook): Boolean {
|
||||||
|
throw Exception("Importing QueuePaging from XLSX is not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Export_XLSX(): XSSFWorkbook? {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
||||||
|
val workbook = XSSFWorkbook()
|
||||||
|
val sheet = workbook.createSheet("QueuePaging")
|
||||||
|
val headerRow = sheet.createRow(0)
|
||||||
|
val headers = arrayOf("Index", "Date_Time", "Source", "Type", "Message", "BroadcastZones")
|
||||||
|
for ((colIndex, header) in headers.withIndex()) {
|
||||||
|
val cell = headerRow.createCell(colIndex)
|
||||||
|
cell.setCellValue(header)
|
||||||
|
}
|
||||||
|
var rowIndex = 1
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val row = sheet.createRow(rowIndex++)
|
||||||
|
row.createCell(0).setCellValue(resultSet.getString("index"))
|
||||||
|
row.createCell(1).setCellValue(resultSet.getString("Date_Time"))
|
||||||
|
row.createCell(2).setCellValue(resultSet.getString("Source"))
|
||||||
|
row.createCell(3).setCellValue(resultSet.getString("Type"))
|
||||||
|
row.createCell(4).setCellValue(resultSet.getString("Message"))
|
||||||
|
row.createCell(5).setCellValue(resultSet.getString("BroadcastZones"))
|
||||||
|
}
|
||||||
|
for (i in headers.indices) {
|
||||||
|
sheet.autoSizeColumn(i)
|
||||||
|
}
|
||||||
|
return workbook
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error { "Error exporting QueuePaging, Msg: ${e.message}" }
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
181
src/database/table/Table_QueueSoundbank.kt
Normal file
181
src/database/table/Table_QueueSoundbank.kt
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
package database.table
|
||||||
|
|
||||||
|
import database.data.QueueTable
|
||||||
|
import database.dbFunctions
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
||||||
|
import org.tinylog.Logger
|
||||||
|
import java.sql.Connection
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
|
class Table_QueueSoundbank(connection: Connection) : dbFunctions<QueueTable>("queue_table", connection, listOf("index", "Date_Time", "Source", "Type", "Message", "SB_TAGS", "BroadcastZones", "Repeat", "Language")) {
|
||||||
|
override fun Create() {
|
||||||
|
val tabledefinition = "CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
||||||
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
||||||
|
"Date_Time VARCHAR(45) NOT NULL," + // Date and time of the entry
|
||||||
|
"Source VARCHAR(45) NOT NULL," + // Source of the entry
|
||||||
|
"Type VARCHAR(45) NOT NULL," + // Type of the entry
|
||||||
|
"Message VARCHAR(1024) NOT NULL," + // Message content
|
||||||
|
"SB_TAGS VARCHAR(1024)," + // Comma-separated soundbank tags
|
||||||
|
"BroadcastZones VARCHAR(1024) NOT NULL," + // Comma-separated broadcast zones
|
||||||
|
"`Repeat` INT NOT NULL," + // Number of repeats
|
||||||
|
"Language VARCHAR(100) NOT NULL" + // Language of the message
|
||||||
|
")"
|
||||||
|
super.Create(tabledefinition)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Get(cbOK: Consumer<Unit>?, cbFail: Consumer<String>?) {
|
||||||
|
List.clear()
|
||||||
|
val queueList = ArrayList<QueueTable>()
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val queueTable = QueueTable(
|
||||||
|
resultSet.getLong("index").toUInt(),
|
||||||
|
resultSet.getString("Date_Time"),
|
||||||
|
resultSet.getString("Source"),
|
||||||
|
resultSet.getString("Type"),
|
||||||
|
resultSet.getString("Message"),
|
||||||
|
resultSet.getString("SB_TAGS"),
|
||||||
|
resultSet.getString("BroadcastZones"),
|
||||||
|
resultSet.getInt("Repeat").toUInt(),
|
||||||
|
resultSet.getString("Language")
|
||||||
|
)
|
||||||
|
queueList.add(queueTable)
|
||||||
|
List.add(queueTable)
|
||||||
|
}
|
||||||
|
cbOK?.accept(Unit)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error fetching ${super.dbName} : ${e.message}" as Any)
|
||||||
|
cbFail?.accept("Error fetching ${super.dbName} : ${e.message}" )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Add(data: QueueTable): Boolean {
|
||||||
|
try {
|
||||||
|
val statement = connection.prepareStatement(
|
||||||
|
"INSERT INTO ${super.dbName} (`Date_Time`, `Source`, `Type`, `Message`, `SB_TAGS`, `BroadcastZones`, `Repeat`, `Language`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
|
||||||
|
)
|
||||||
|
statement?.setString(1, data.Date_Time)
|
||||||
|
statement?.setString(2, data.Source)
|
||||||
|
statement?.setString(3, data.Type)
|
||||||
|
statement?.setString(4, data.Message)
|
||||||
|
statement?.setString(5, data.SB_TAGS)
|
||||||
|
statement?.setString(6, data.BroadcastZones)
|
||||||
|
statement?.setInt(7, data.Repeat.toInt())
|
||||||
|
statement?.setString(8, data.Language)
|
||||||
|
val rowsAffected = statement?.executeUpdate()
|
||||||
|
if (rowsAffected != null && rowsAffected > 0) {
|
||||||
|
Logger.info("QueueTable added Source=${data.Source} Type=${data.Type} Message=${data.Message}, Languages=${data.Language} Variables=${data.SB_TAGS}, BroadcastZones=${data.BroadcastZones}" as Any)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
Logger.warn("No QueueTable entry added for: ${data.Message}" as Any)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error adding QueueTable entry: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun AddAll(data: ArrayList<QueueTable>): Boolean {
|
||||||
|
try {
|
||||||
|
connection.autoCommit = false
|
||||||
|
val sql =
|
||||||
|
"INSERT INTO ${super.dbName} (`Date_Time`, `Source`, `Type`, `Message`, `SB_TAGS`, `BroadcastZones`, `Repeat`, `Language`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
|
||||||
|
val statement = connection.prepareStatement(sql)
|
||||||
|
for (qt in data) {
|
||||||
|
statement.setString(1, qt.Date_Time)
|
||||||
|
statement.setString(2, qt.Source)
|
||||||
|
statement.setString(3, qt.Type)
|
||||||
|
statement.setString(4, qt.Message)
|
||||||
|
statement.setString(5, qt.SB_TAGS)
|
||||||
|
statement.setString(6, qt.BroadcastZones)
|
||||||
|
statement.setInt(7, qt.Repeat.toInt())
|
||||||
|
statement.setString(8, qt.Language)
|
||||||
|
statement.addBatch()
|
||||||
|
}
|
||||||
|
statement.executeBatch()
|
||||||
|
connection.commit()
|
||||||
|
Logger.info("Bulk QueueTable insert successful: ${data.size} entries" as Any)
|
||||||
|
connection.autoCommit = true
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error adding QueueTable entries: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun UpdateByIndex(index: Int, data: QueueTable): Boolean {
|
||||||
|
throw Exception("Update not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Resort(): Boolean {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val tempdb_name = "temp_${super.dbName}"
|
||||||
|
// use a temporary table to reorder the index
|
||||||
|
statement?.executeUpdate("CREATE TABLE IF NOT EXISTS $tempdb_name LIKE ${super.dbName}")
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE $tempdb_name")
|
||||||
|
statement?.executeUpdate("INSERT INTO $tempdb_name (Date_Time, Source, Type, Message, SB_TAGS, BroadcastZones, `Repeat`, Language) SELECT Date_Time, Source, Type, Message, SB_TAGS, BroadcastZones, `Repeat`, Language FROM ${super.dbName} ORDER BY `index` ")
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
||||||
|
statement?.executeUpdate("INSERT INTO ${super.dbName} (Date_Time, Source, Type, Message, SB_TAGS, BroadcastZones, `Repeat`, Language) SELECT Date_Time, Source, Type, Message, SB_TAGS, BroadcastZones, `Repeat`, Language FROM $tempdb_name")
|
||||||
|
statement?.executeUpdate("DROP TABLE $tempdb_name")
|
||||||
|
Logger.info("${super.dbName} table resorted by index" as Any)
|
||||||
|
// reload the local list
|
||||||
|
Get()
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error resorting ${super.dbName} table by index: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Import_XLSX(workbook: XSSFWorkbook): Boolean {
|
||||||
|
throw Exception("Import XLSX not supported for QueueTable")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Export_XLSX(): XSSFWorkbook? {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
||||||
|
val workbook = XSSFWorkbook()
|
||||||
|
val sheet = workbook.createSheet("QueueTable")
|
||||||
|
val headerRow = sheet.createRow(0)
|
||||||
|
val headers = arrayOf(
|
||||||
|
"Index",
|
||||||
|
"Date_Time",
|
||||||
|
"Source",
|
||||||
|
"Type",
|
||||||
|
"Message",
|
||||||
|
"SB_TAGS",
|
||||||
|
"BroadcastZones",
|
||||||
|
"Repeat",
|
||||||
|
"Language"
|
||||||
|
)
|
||||||
|
for ((colIndex, header) in headers.withIndex()) {
|
||||||
|
val cell = headerRow.createCell(colIndex)
|
||||||
|
cell.setCellValue(header)
|
||||||
|
}
|
||||||
|
var rowIndex = 1
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val row = sheet.createRow(rowIndex++)
|
||||||
|
row.createCell(0).setCellValue(resultSet.getString("index"))
|
||||||
|
row.createCell(1).setCellValue(resultSet.getString("Date_Time"))
|
||||||
|
row.createCell(2).setCellValue(resultSet.getString("Source"))
|
||||||
|
row.createCell(3).setCellValue(resultSet.getString("Type"))
|
||||||
|
row.createCell(4).setCellValue(resultSet.getString("Message"))
|
||||||
|
row.createCell(5).setCellValue(resultSet.getString("SB_TAGS"))
|
||||||
|
row.createCell(6).setCellValue(resultSet.getString("BroadcastZones"))
|
||||||
|
row.createCell(7).setCellValue(resultSet.getString("Repeat"))
|
||||||
|
row.createCell(8).setCellValue(resultSet.getString("Language"))
|
||||||
|
}
|
||||||
|
for (i in headers.indices) {
|
||||||
|
sheet.autoSizeColumn(i)
|
||||||
|
}
|
||||||
|
return workbook
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error { "Error exporting QueueTable, Msg: ${e.message}" }
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
287
src/database/table/Table_Schedule.kt
Normal file
287
src/database/table/Table_Schedule.kt
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
package database.table
|
||||||
|
|
||||||
|
import codes.Somecodes.Companion.ValidScheduleDay
|
||||||
|
import database.MariaDB.Companion.ValidTime
|
||||||
|
import database.data.ScheduleBank
|
||||||
|
import database.dbFunctions
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
||||||
|
import org.tinylog.Logger
|
||||||
|
import java.sql.Connection
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
|
class Table_Schedule(connection: Connection) : dbFunctions<ScheduleBank>("schedulebank", connection, listOf("index", "Description", "Day", "Time", "Soundpath", "Repeat", "Enable", "BroadcastZones", "Language")) {
|
||||||
|
override fun Create() {
|
||||||
|
val tabledefinition = "CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
||||||
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
||||||
|
"Description VARCHAR(128) NOT NULL," + // Description of the schedule
|
||||||
|
"Day VARCHAR(255) NOT NULL," + // Day in format DD/MM/YYYY
|
||||||
|
"Time VARCHAR(20) NOT NULL," + // Time in format HH:MM:SS
|
||||||
|
"Soundpath VARCHAR(512) NOT NULL," + // Path to the sound file
|
||||||
|
"`Repeat` TINYINT UNSIGNED NOT NULL," + // Repeat type (0=Once, 1=Daily, 2=Weekly, 3=Monthly, 4=Yearly)
|
||||||
|
"Enable BOOLEAN NOT NULL," + // Enable or disable the schedule
|
||||||
|
"BroadcastZones TEXT NOT NULL," + // Comma-separated list of broadcast zones
|
||||||
|
"Language VARCHAR(45) NOT NULL" + // Language code (e.g., EN, FR)
|
||||||
|
")"
|
||||||
|
super.Create(tabledefinition)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Get(cbOK: Consumer<Unit>?, cbFail: Consumer<String>?) {
|
||||||
|
List.clear()
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val schedulebank = ScheduleBank(
|
||||||
|
resultSet.getLong("index").toUInt(),
|
||||||
|
resultSet.getString("Description"),
|
||||||
|
resultSet.getString("Day"),
|
||||||
|
resultSet.getString("Time"),
|
||||||
|
resultSet.getString("Soundpath"),
|
||||||
|
resultSet.getInt("Repeat").toUByte(),
|
||||||
|
resultSet.getBoolean("Enable"),
|
||||||
|
resultSet.getString("BroadcastZones"),
|
||||||
|
resultSet.getString("Language")
|
||||||
|
)
|
||||||
|
List.add(schedulebank)
|
||||||
|
}
|
||||||
|
cbOK?.accept(Unit)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error fetching ${super.dbName}: ${e.message}" as Any)
|
||||||
|
cbFail?.accept("Error fetching ${super.dbName}: ${e.message}" )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Add(data: ScheduleBank): Boolean {
|
||||||
|
if (!ValidScheduleDay(data.Day)) {
|
||||||
|
Logger.error("Error adding schedulebank entry: Invalid date format ${data.Day}" as Any)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (!ValidTime(data.Time)) {
|
||||||
|
Logger.error("Error adding schedulebank entry: Invalid time format ${data.Time}" as Any)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
val statement =
|
||||||
|
connection.prepareStatement("INSERT INTO ${super.dbName} (Description, Day, Time, Soundpath, `Repeat`, Enable, BroadcastZones, Language) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")
|
||||||
|
statement?.setString(1, data.Description)
|
||||||
|
statement?.setString(2, data.Day)
|
||||||
|
statement?.setString(3, data.Time)
|
||||||
|
statement?.setString(4, data.Soundpath)
|
||||||
|
statement?.setInt(5, data.Repeat.toInt())
|
||||||
|
statement?.setBoolean(6, data.Enable)
|
||||||
|
statement?.setString(7, data.BroadcastZones)
|
||||||
|
statement?.setString(8, data.Language)
|
||||||
|
val rowsAffected = statement?.executeUpdate()
|
||||||
|
if (rowsAffected != null && rowsAffected > 0) {
|
||||||
|
Logger.info("Schedulebank added: ${data.Description}" as Any)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
Logger.warn("No schedulebank entry added for: ${data.Description}" as Any)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error adding schedulebank entry: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun AddAll(data: ArrayList<ScheduleBank>): Boolean {
|
||||||
|
try {
|
||||||
|
connection.autoCommit = false
|
||||||
|
val sql =
|
||||||
|
"INSERT INTO ${super.dbName} (Description, Day, Time, Soundpath, `Repeat`, Enable, BroadcastZones, Language) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
|
||||||
|
val statement = connection.prepareStatement(sql)
|
||||||
|
for (sb in data) {
|
||||||
|
if (!ValidScheduleDay(sb.Day) || !ValidTime(sb.Time)) {
|
||||||
|
Logger.error("Invalid date or time format for schedulebank: ${sb.Description}" as Any)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
statement.setString(1, sb.Description)
|
||||||
|
statement.setString(2, sb.Day)
|
||||||
|
statement.setString(3, sb.Time)
|
||||||
|
statement.setString(4, sb.Soundpath)
|
||||||
|
statement.setInt(5, sb.Repeat.toInt())
|
||||||
|
statement.setBoolean(6, sb.Enable)
|
||||||
|
statement.setString(7, sb.BroadcastZones)
|
||||||
|
statement.setString(8, sb.Language)
|
||||||
|
statement.addBatch()
|
||||||
|
}
|
||||||
|
statement.executeBatch()
|
||||||
|
connection.commit()
|
||||||
|
Logger.info("Bulk schedulebank insert successful: ${data.size} entries" as Any)
|
||||||
|
connection.autoCommit = true
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error adding schedulebank entries: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun UpdateByIndex(index: Int, data: ScheduleBank): Boolean {
|
||||||
|
if (!ValidScheduleDay(data.Day)) {
|
||||||
|
Logger.error("Error updating schedulebank entry: Invalid date format ${data.Day}" as Any)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (!ValidTime(data.Time)) {
|
||||||
|
Logger.error("Error updating schedulebank entry: Invalid time format ${data.Time}" as Any)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
val statement =
|
||||||
|
connection.prepareStatement("UPDATE ${super.dbName} SET Description = ?, Day = ?, Time = ?, Soundpath = ?, `Repeat` = ?, Enable = ?, BroadcastZones = ?, Language = ? WHERE `index` = ?")
|
||||||
|
statement?.setString(1, data.Description)
|
||||||
|
statement?.setString(2, data.Day)
|
||||||
|
statement?.setString(3, data.Time)
|
||||||
|
statement?.setString(4, data.Soundpath)
|
||||||
|
statement?.setInt(5, data.Repeat.toInt())
|
||||||
|
statement?.setBoolean(6, data.Enable)
|
||||||
|
statement?.setString(7, data.BroadcastZones)
|
||||||
|
statement?.setString(8, data.Language)
|
||||||
|
statement?.setLong(9, index.toLong())
|
||||||
|
val rowsAffected = statement?.executeUpdate()
|
||||||
|
if (rowsAffected != null && rowsAffected > 0) {
|
||||||
|
Logger.info("Schedulebank updated at index $index: ${data.Description}" as Any)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
Logger.warn("No schedulebank entry updated at index $index for: ${data.Description}" as Any)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error updating schedulebank entry at index $index: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Resort(): Boolean {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val tempdb_name = "temp_${super.dbName}"
|
||||||
|
// use a temporary table to reorder the index
|
||||||
|
statement?.executeUpdate("CREATE TABLE IF NOT EXISTS $tempdb_name LIKE ${super.dbName}")
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE $tempdb_name")
|
||||||
|
statement?.executeUpdate("INSERT INTO $tempdb_name (Description, Day, Time, Soundpath, `Repeat`, Enable, BroadcastZones, Language) SELECT Description, Day, Time, Soundpath, `Repeat`, Enable, BroadcastZones, Language FROM ${super.dbName} ORDER BY Day , Time ")
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
||||||
|
statement?.executeUpdate("INSERT INTO ${super.dbName} (Description, Day, Time, Soundpath, `Repeat`, Enable, BroadcastZones, Language) SELECT Description, Day, Time, Soundpath, `Repeat`, Enable, BroadcastZones, Language FROM $tempdb_name")
|
||||||
|
statement?.executeUpdate("DROP TABLE $tempdb_name")
|
||||||
|
Logger.info("${super.dbName} table resorted by Day and Time" as Any)
|
||||||
|
// reload the local list
|
||||||
|
Get()
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error resorting ${super.dbName} table by Day and Time: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Import_XLSX(workbook: XSSFWorkbook): Boolean {
|
||||||
|
try {
|
||||||
|
val sheet =
|
||||||
|
workbook.getSheet("Schedulebank") ?: throw Exception("No sheet named 'Schedulebank' found")
|
||||||
|
val headerRow = sheet.getRow(0) ?: throw Exception("No header row found")
|
||||||
|
val headers = arrayOf(
|
||||||
|
"Index",
|
||||||
|
"Description",
|
||||||
|
"Day",
|
||||||
|
"Time",
|
||||||
|
"Soundpath",
|
||||||
|
"Repeat",
|
||||||
|
"Enable",
|
||||||
|
"BroadcastZones",
|
||||||
|
"Language"
|
||||||
|
)
|
||||||
|
for ((colIndex, header) in headers.withIndex()) {
|
||||||
|
val cell = headerRow.getCell(colIndex) ?: throw Exception("Header '$header' not found")
|
||||||
|
if (cell.stringCellValue != header) throw Exception("Header '$header' not found")
|
||||||
|
}
|
||||||
|
// clear existing schedulebank
|
||||||
|
Clear()
|
||||||
|
// read each row and insert into database
|
||||||
|
val _schedulebankList = ArrayList<ScheduleBank>()
|
||||||
|
//Logger.info{"Sheet last row num: ${sheet.lastRowNum}"}
|
||||||
|
for (rowIndex in 1..sheet.lastRowNum) {
|
||||||
|
val row = sheet.getRow(rowIndex) ?: continue
|
||||||
|
//println(row)
|
||||||
|
val description = row.getCell(1)?.stringCellValue ?: continue
|
||||||
|
//println(description.toString())
|
||||||
|
val day = row.getCell(2)?.stringCellValue ?: continue
|
||||||
|
//println(day.toString())
|
||||||
|
val time = row.getCell(3)?.stringCellValue ?: continue
|
||||||
|
//println(time.toString())
|
||||||
|
val soundpath = row.getCell(4)?.stringCellValue ?: continue
|
||||||
|
//println(soundpath.toString())
|
||||||
|
val repeat = row.getCell(5)?.stringCellValue?.toUByteOrNull() ?: continue
|
||||||
|
// println(repeat.toString())
|
||||||
|
//val enable = row.getCell(6)?.stringCellValue?.toBooleanStrictOrNull() ?: continue
|
||||||
|
val enable = row.getCell(6)?.stringCellValue?.toBoolean() ?: continue
|
||||||
|
//println(enable.toString())
|
||||||
|
val broadcastZones = row.getCell(7)?.stringCellValue ?: continue
|
||||||
|
//println(broadcastZones.toString())
|
||||||
|
val language = row.getCell(8)?.stringCellValue ?: continue
|
||||||
|
//println(language.toString())
|
||||||
|
val schedulebank =
|
||||||
|
ScheduleBank(
|
||||||
|
0u,
|
||||||
|
description,
|
||||||
|
day,
|
||||||
|
time,
|
||||||
|
soundpath,
|
||||||
|
repeat,
|
||||||
|
enable,
|
||||||
|
broadcastZones,
|
||||||
|
language
|
||||||
|
)
|
||||||
|
Logger.info{"SchedulebankList added 1"}
|
||||||
|
|
||||||
|
_schedulebankList.add(schedulebank)
|
||||||
|
}
|
||||||
|
return AddAll(_schedulebankList)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error { "Error importing Schedulebank, Msg: ${e.message}" }
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Export_XLSX(): XSSFWorkbook? {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
||||||
|
val workbook = XSSFWorkbook()
|
||||||
|
val sheet = workbook.createSheet("Schedulebank")
|
||||||
|
val headerRow = sheet.createRow(0)
|
||||||
|
val headers = arrayOf(
|
||||||
|
"Index",
|
||||||
|
"Description",
|
||||||
|
"Day",
|
||||||
|
"Time",
|
||||||
|
"Soundpath",
|
||||||
|
"Repeat",
|
||||||
|
"Enable",
|
||||||
|
"BroadcastZones",
|
||||||
|
"Language"
|
||||||
|
)
|
||||||
|
for ((colIndex, header) in headers.withIndex()) {
|
||||||
|
val cell = headerRow.createCell(colIndex)
|
||||||
|
cell.setCellValue(header)
|
||||||
|
}
|
||||||
|
var rowIndex = 1
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val row = sheet.createRow(rowIndex++)
|
||||||
|
row.createCell(0).setCellValue(resultSet.getString("index"))
|
||||||
|
row.createCell(1).setCellValue(resultSet.getString("Description"))
|
||||||
|
row.createCell(2).setCellValue(resultSet.getString("Day"))
|
||||||
|
row.createCell(3).setCellValue(resultSet.getString("Time"))
|
||||||
|
row.createCell(4).setCellValue(resultSet.getString("Soundpath"))
|
||||||
|
row.createCell(5).setCellValue(resultSet.getString("Repeat"))
|
||||||
|
row.createCell(6).setCellValue(resultSet.getString("Enable"))
|
||||||
|
row.createCell(7).setCellValue(resultSet.getString("BroadcastZones"))
|
||||||
|
row.createCell(8).setCellValue(resultSet.getString("Language"))
|
||||||
|
}
|
||||||
|
for (i in headers.indices) {
|
||||||
|
sheet.autoSizeColumn(i)
|
||||||
|
}
|
||||||
|
return workbook
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error { "Error exporting Schedulebank, Msg: ${e.message}" }
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
256
src/database/table/Table_SoundChannel.kt
Normal file
256
src/database/table/Table_SoundChannel.kt
Normal file
@@ -0,0 +1,256 @@
|
|||||||
|
package database.table
|
||||||
|
|
||||||
|
import database.data.SoundChannel
|
||||||
|
import database.dbFunctions
|
||||||
|
import max_channel
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
||||||
|
import org.tinylog.Logger
|
||||||
|
import java.sql.Connection
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
|
class Table_SoundChannel(connection: Connection) : dbFunctions<SoundChannel>("soundchannel", connection, listOf("index", "channel", "ip")) {
|
||||||
|
override fun Create() {
|
||||||
|
val tableDefinition = "CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
||||||
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
||||||
|
"channel VARCHAR(45) NOT NULL," + // Channel 01 to Channel 64
|
||||||
|
"ip VARCHAR(45) NOT NULL" + // IP address or empty string
|
||||||
|
")"
|
||||||
|
|
||||||
|
super.Create(tableDefinition)
|
||||||
|
|
||||||
|
// Check if table is empty, if so, populate with 64 channels
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val countResult = statement?.executeQuery("SELECT COUNT(*) AS count FROM ${super.dbName}")
|
||||||
|
if (countResult?.next() == true) {
|
||||||
|
val count = countResult.getInt("count")
|
||||||
|
if (count < max_channel) {
|
||||||
|
Logger.info("SoundChannel table is empty, populating with default channels" as Any)
|
||||||
|
Clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error creating SoundChannel table: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Get(cbOK: Consumer<Unit>?, cbFail: Consumer<String>?) {
|
||||||
|
List.clear()
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName} ORDER BY `index` ")
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val channel = SoundChannel(
|
||||||
|
resultSet.getLong("index").toUInt(),
|
||||||
|
resultSet.getString("channel"),
|
||||||
|
resultSet.getString("ip")
|
||||||
|
)
|
||||||
|
List.add(channel)
|
||||||
|
}
|
||||||
|
cbOK?.accept(Unit)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error fetching sound channels: ${e.message}" as Any)
|
||||||
|
cbFail?.accept("Error fetching sound channels: ${e.message}" )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Add(data: SoundChannel): Boolean {
|
||||||
|
try {
|
||||||
|
val statement = connection.prepareStatement("UPDATE ${super.dbName} SET ip = ? WHERE channel = ?")
|
||||||
|
statement?.setString(1, data.ip)
|
||||||
|
statement?.setString(2, data.channel)
|
||||||
|
val rowsAffected = statement?.executeUpdate()
|
||||||
|
if (rowsAffected != null && rowsAffected > 0) {
|
||||||
|
Logger.info("SoundChannel updated: ${data.channel} -> ${data.ip}" as Any)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
Logger.warn("No SoundChannel entry updated for: ${data.channel} -> ${data.ip}" as Any)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error updating SoundChannel entry: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun AddAll(data: ArrayList<SoundChannel>): Boolean {
|
||||||
|
return try {
|
||||||
|
connection.autoCommit = false
|
||||||
|
val sql = "UPDATE ${super.dbName} SET ip = ? WHERE channel = ?"
|
||||||
|
val statement = connection.prepareStatement(sql)
|
||||||
|
for (sc in data) {
|
||||||
|
statement.setString(1, sc.ip)
|
||||||
|
statement.setString(2, sc.channel)
|
||||||
|
statement.addBatch()
|
||||||
|
}
|
||||||
|
statement.executeBatch()
|
||||||
|
connection.commit()
|
||||||
|
Logger.info("Bulk SoundChannel update successful: ${data.size} entries" as Any)
|
||||||
|
connection.autoCommit = true
|
||||||
|
true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error updating SoundChannel entries: ${e.message}" as Any)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun UpdateByIndex(index: Int, data: SoundChannel): Boolean {
|
||||||
|
try {
|
||||||
|
val statement =
|
||||||
|
connection.prepareStatement("UPDATE ${super.dbName} SET channel = ?, ip = ? WHERE `index` = ?")
|
||||||
|
statement?.setString(1, data.channel)
|
||||||
|
statement?.setString(2, data.ip)
|
||||||
|
statement?.setLong(3, index.toLong())
|
||||||
|
val rowsAffected = statement?.executeUpdate()
|
||||||
|
if (rowsAffected != null && rowsAffected > 0) {
|
||||||
|
Logger.info("SoundChannel updated at index $index: ${data.channel} -> ${data.ip}" as Any)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
Logger.warn("No Sound Channel entry updated at index $index for: ${data.channel} -> ${data.ip}" as Any)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error updating SoundChannel entry at index $index: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Resort(): Boolean {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val tempdb_name = "temp_${super.dbName}"
|
||||||
|
// use a temporary table to reorder the index
|
||||||
|
statement?.executeUpdate("CREATE TABLE IF NOT EXISTS $tempdb_name LIKE ${super.dbName}")
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE $tempdb_name")
|
||||||
|
statement?.executeUpdate("INSERT INTO $tempdb_name (channel, ip) SELECT channel, ip FROM ${super.dbName} ORDER BY `index` ")
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
||||||
|
statement?.executeUpdate("INSERT INTO ${super.dbName} (channel, ip) SELECT channel, ip FROM $tempdb_name")
|
||||||
|
statement?.executeUpdate("DROP TABLE $tempdb_name")
|
||||||
|
Logger.info("${super.dbName} table resorted by index" as Any)
|
||||||
|
// reload the local list
|
||||||
|
Get()
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error resorting ${super.dbName} table by index: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Clear(): Boolean {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
// use TRUNCATE to reset auto increment index
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
||||||
|
Logger.info("${super.dbName} table cleared" as Any)
|
||||||
|
List.clear()
|
||||||
|
// create new rows from 1 to 64 with description "Channel 1" to "Channel 64" and empty ip
|
||||||
|
for (i in 1..max_channel) {
|
||||||
|
val channel = String.format("Channel %d", i)
|
||||||
|
val insertStatement =
|
||||||
|
connection.prepareStatement("INSERT INTO ${super.dbName} (channel, ip) VALUES (?, ?)")
|
||||||
|
insertStatement?.setString(1, channel)
|
||||||
|
insertStatement?.setString(2, "")
|
||||||
|
insertStatement?.executeUpdate()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error clearing soundchannel table: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Import_XLSX(workbook: XSSFWorkbook): Boolean {
|
||||||
|
try {
|
||||||
|
val sheet =
|
||||||
|
workbook.getSheet("SoundChannel") ?: throw Exception("No sheet named 'SoundChannel' found")
|
||||||
|
val headerRow = sheet.getRow(0) ?: throw Exception("No header row found")
|
||||||
|
val headers = arrayOf("Index", "channel", "ip")
|
||||||
|
for ((colIndex, header) in headers.withIndex()) {
|
||||||
|
val cell = headerRow.getCell(colIndex) ?: throw Exception("Header '$header' not found")
|
||||||
|
if (cell.stringCellValue != header) throw Exception("Header '$header' not found")
|
||||||
|
}
|
||||||
|
// clear existing soundchannel
|
||||||
|
Clear()
|
||||||
|
// read each row and insert into database
|
||||||
|
val _soundChannelList = ArrayList<SoundChannel>()
|
||||||
|
for (rowIndex in 1..sheet.lastRowNum) {
|
||||||
|
val row = sheet.getRow(rowIndex) ?: continue
|
||||||
|
val channel = row.getCell(1)?.stringCellValue ?: continue
|
||||||
|
val ip = row.getCell(2)?.stringCellValue ?: continue
|
||||||
|
val soundChannel = SoundChannel(0u, channel, ip)
|
||||||
|
_soundChannelList.add(soundChannel)
|
||||||
|
}
|
||||||
|
// Bulk update IPs for channels
|
||||||
|
var success = true
|
||||||
|
for (sc in _soundChannelList) {
|
||||||
|
if (!Add(sc)) {
|
||||||
|
success = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error { "Error importing SoundChannel, Msg: ${e.message}" }
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Export_XLSX(): XSSFWorkbook? {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
||||||
|
val workbook = XSSFWorkbook()
|
||||||
|
val sheet = workbook.createSheet("SoundChannel")
|
||||||
|
val headerRow = sheet.createRow(0)
|
||||||
|
val headers = arrayOf("Index", "channel", "ip")
|
||||||
|
for ((colIndex, header) in headers.withIndex()) {
|
||||||
|
val cell = headerRow.createCell(colIndex)
|
||||||
|
cell.setCellValue(header)
|
||||||
|
}
|
||||||
|
var rowIndex = 1
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val row = sheet.createRow(rowIndex++)
|
||||||
|
row.createCell(0).setCellValue(resultSet.getString("index"))
|
||||||
|
row.createCell(1).setCellValue(resultSet.getString("channel"))
|
||||||
|
row.createCell(2).setCellValue(resultSet.getString("ip"))
|
||||||
|
}
|
||||||
|
for (i in headers.indices) {
|
||||||
|
sheet.autoSizeColumn(i)
|
||||||
|
}
|
||||||
|
return workbook
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error { "Error exporting SoundChannel, Msg: ${e.message}" }
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete entry by index, but only clear the IP field
|
||||||
|
* @param index The index of the entry to delete
|
||||||
|
* @return true if successful, false otherwise
|
||||||
|
*/
|
||||||
|
override fun DeleteByIndex(index: Int): Boolean {
|
||||||
|
try {
|
||||||
|
val statement = connection.prepareStatement("UPDATE ${super.dbName} SET ip = '' WHERE `index` = ?")
|
||||||
|
statement?.setLong(1, index.toLong())
|
||||||
|
val rowsAffected = statement?.executeUpdate()
|
||||||
|
if (rowsAffected != null && rowsAffected > 0) {
|
||||||
|
Logger.info("${super.dbName} IP cleared for index $index" as Any)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
Logger.warn("No ${super.dbName} entry cleared for index $index" as Any)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error clearing ${super.dbName} entry for index $index: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all distinct sound channel from soundchannelDB
|
||||||
|
* @return a list of distinct sound channel sorted alphabetically
|
||||||
|
*/
|
||||||
|
fun Get_SoundChannel_List(): List<String> {
|
||||||
|
return List
|
||||||
|
.distinctBy { it.channel }
|
||||||
|
.map { it.channel }
|
||||||
|
.sorted()
|
||||||
|
}
|
||||||
|
}
|
||||||
308
src/database/table/Table_Soundbank.kt
Normal file
308
src/database/table/Table_Soundbank.kt
Normal file
@@ -0,0 +1,308 @@
|
|||||||
|
package database.table
|
||||||
|
|
||||||
|
import content.Category
|
||||||
|
import database.data.Soundbank
|
||||||
|
import database.dbFunctions
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
||||||
|
import org.tinylog.Logger
|
||||||
|
import java.sql.Connection
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
|
class Table_Soundbank(connection: Connection) : dbFunctions<Soundbank>("soundbank", connection, listOf("index", "Description", "TAG", "Category", "Language", "VoiceType", "Path")) {
|
||||||
|
override fun Create() {
|
||||||
|
val tabledefinition = "CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
||||||
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
||||||
|
"Description VARCHAR(1024) NOT NULL," + // Description of the soundbank
|
||||||
|
"TAG VARCHAR(45) NOT NULL," + // TAG of the soundbank
|
||||||
|
"Category VARCHAR(45) NOT NULL," + // Category of the soundbank
|
||||||
|
"Language VARCHAR(45) NOT NULL," + // Language of the soundbank
|
||||||
|
"VoiceType VARCHAR(45) NOT NULL," + // VoiceType of the soundbank
|
||||||
|
"Path VARCHAR(1024) NOT NULL" + // Path to the sound file
|
||||||
|
")"
|
||||||
|
super.Create(tabledefinition)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Get(cbOK: Consumer<Unit>?, cbFail: Consumer<String>?) {
|
||||||
|
List.clear()
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName} ORDER BY Category, Language, VoiceType, TAG")
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val soundbank = Soundbank(
|
||||||
|
resultSet.getLong("index").toUInt(),
|
||||||
|
resultSet.getString("Description"),
|
||||||
|
resultSet.getString("TAG"),
|
||||||
|
resultSet.getString("Category"),
|
||||||
|
resultSet.getString("Language"),
|
||||||
|
resultSet.getString("VoiceType"),
|
||||||
|
resultSet.getString("Path")
|
||||||
|
)
|
||||||
|
List.add(soundbank)
|
||||||
|
}
|
||||||
|
cbOK?.accept(Unit)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error fetching soundbanks: ${e.message}" as Any)
|
||||||
|
cbFail?.accept("Error fetching ${super.dbName} : ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Add(data: Soundbank): Boolean {
|
||||||
|
try {
|
||||||
|
val statement =
|
||||||
|
connection.prepareStatement("INSERT INTO ${super.dbName} (Description, TAG, Category, Language, VoiceType, Path) VALUES (?, ?, ?, ?, ?, ?)")
|
||||||
|
statement?.setString(1, data.Description)
|
||||||
|
statement?.setString(2, data.TAG)
|
||||||
|
statement?.setString(3, data.Category)
|
||||||
|
statement?.setString(4, data.Language)
|
||||||
|
statement?.setString(5, data.VoiceType)
|
||||||
|
statement?.setString(6, data.Path)
|
||||||
|
val rowsAffected = statement?.executeUpdate()
|
||||||
|
if (rowsAffected != null && rowsAffected > 0) {
|
||||||
|
Logger.info("Soundbank added: ${data.Description}" as Any)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
Logger.warn("No soundbank entry added for: ${data.Description}" as Any)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error adding soundbank entry: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun AddAll(data: ArrayList<Soundbank>): Boolean {
|
||||||
|
// use mysql bulk insert
|
||||||
|
try {
|
||||||
|
connection.autoCommit = false
|
||||||
|
val sql =
|
||||||
|
"INSERT INTO ${super.dbName} (Description, TAG, Category, Language, VoiceType, Path) VALUES (?, ?, ?, ?, ?, ?)"
|
||||||
|
val statement = connection.prepareStatement(sql)
|
||||||
|
for (sb in data) {
|
||||||
|
statement.setString(1, sb.Description)
|
||||||
|
statement.setString(2, sb.TAG)
|
||||||
|
statement.setString(3, sb.Category)
|
||||||
|
statement.setString(4, sb.Language)
|
||||||
|
statement.setString(5, sb.VoiceType)
|
||||||
|
statement.setString(6, sb.Path)
|
||||||
|
statement.addBatch()
|
||||||
|
}
|
||||||
|
statement.executeBatch()
|
||||||
|
connection.commit()
|
||||||
|
Logger.info("Bulk soundbank insert successful: ${data.size} entries" as Any)
|
||||||
|
connection.autoCommit = true
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error adding soundbank entries: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun UpdateByIndex(index: Int, data: Soundbank): Boolean {
|
||||||
|
try {
|
||||||
|
val statement =
|
||||||
|
connection.prepareStatement("UPDATE ${super.dbName} SET Description = ?, TAG = ?, Category = ?, Language = ?, VoiceType = ?, Path = ? WHERE `index` = ?")
|
||||||
|
statement?.setString(1, data.Description)
|
||||||
|
statement?.setString(2, data.TAG)
|
||||||
|
statement?.setString(3, data.Category)
|
||||||
|
statement?.setString(4, data.Language)
|
||||||
|
statement?.setString(5, data.VoiceType)
|
||||||
|
statement?.setString(6, data.Path)
|
||||||
|
statement?.setLong(7, index.toLong())
|
||||||
|
val rowsAffected = statement?.executeUpdate()
|
||||||
|
if (rowsAffected != null && rowsAffected > 0) {
|
||||||
|
Logger.info("Soundbank updated at index $index: ${data.Description}" as Any)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
Logger.warn("No soundbank entry updated at index $index for: ${data.Description}" as Any)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error updating soundbank entry at index $index: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Resort(): Boolean {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val tempdb_name = "temp_${super.dbName}"
|
||||||
|
|
||||||
|
// use a temporary table to reorder the index
|
||||||
|
statement?.executeUpdate("CREATE TABLE IF NOT EXISTS $tempdb_name LIKE ${super.dbName}")
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE $tempdb_name")
|
||||||
|
statement?.executeUpdate("INSERT INTO $tempdb_name (Description, TAG, Category, Language, VoiceType, Path) SELECT Description, TAG, Category, Language, VoiceType, Path FROM ${super.dbName} ORDER BY Category, Language, VoiceType, TAG ")
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
||||||
|
statement?.executeUpdate("INSERT INTO ${super.dbName} (Description, TAG, Category, Language, VoiceType, Path) SELECT Description, TAG, Category, Language, VoiceType, Path FROM $tempdb_name")
|
||||||
|
statement?.executeUpdate("DROP TABLE $tempdb_name")
|
||||||
|
Logger.info("${super.dbName} table resorted by Description" as Any)
|
||||||
|
// reload the local list
|
||||||
|
Get()
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error resorting ${super.dbName} table by Description: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Import_XLSX(workbook: XSSFWorkbook): Boolean {
|
||||||
|
try {
|
||||||
|
// check if there is sheet named "Soundbank"
|
||||||
|
val sheet =
|
||||||
|
workbook.getSheet("Soundbank") ?: throw Exception("No sheet named 'Soundbank' found")
|
||||||
|
// check if the sheet contains header named "index", "Description", "TAG", "Category", "Language", "VoiceType", "Path"
|
||||||
|
val headerRow = sheet.getRow(0) ?: throw Exception("No header row found")
|
||||||
|
val headers =
|
||||||
|
arrayOf("Index", "Description", "TAG", "Category", "Language", "VoiceType", "Path")
|
||||||
|
for ((colIndex, header) in headers.withIndex()) {
|
||||||
|
val cell = headerRow.getCell(colIndex) ?: throw Exception("Header '$header' not found")
|
||||||
|
if (cell.stringCellValue != header) throw Exception("Header '$header' not found")
|
||||||
|
}
|
||||||
|
// clear existing soundbank
|
||||||
|
Clear()
|
||||||
|
// read each row and insert into database
|
||||||
|
val _soundbankList = ArrayList<Soundbank>()
|
||||||
|
for (rowIndex in 1..sheet.lastRowNum) {
|
||||||
|
val row = sheet.getRow(rowIndex) ?: continue
|
||||||
|
val description = row.getCell(1)?.stringCellValue ?: continue
|
||||||
|
val tag = row.getCell(2)?.stringCellValue ?: continue
|
||||||
|
val category = row.getCell(3)?.stringCellValue ?: continue
|
||||||
|
val language = row.getCell(4)?.stringCellValue ?: continue
|
||||||
|
val voiceType = row.getCell(5)?.stringCellValue ?: continue
|
||||||
|
val path = row.getCell(6)?.stringCellValue ?: continue
|
||||||
|
val soundbank = Soundbank(0u, description, tag, category, language, voiceType, path)
|
||||||
|
_soundbankList.add(soundbank)
|
||||||
|
}
|
||||||
|
return AddAll(_soundbankList)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error { "Error importing Soundbank, Msg: ${e.message}" }
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Export_XLSX(): XSSFWorkbook? {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
||||||
|
val workbook = XSSFWorkbook()
|
||||||
|
val sheet = workbook.createSheet("Soundbank")
|
||||||
|
val headerRow = sheet.createRow(0)
|
||||||
|
val headers =
|
||||||
|
arrayOf("Index", "Description", "TAG", "Category", "Language", "VoiceType", "Path")
|
||||||
|
for ((colIndex, header) in headers.withIndex()) {
|
||||||
|
val cell = headerRow.createCell(colIndex)
|
||||||
|
cell.setCellValue(header)
|
||||||
|
}
|
||||||
|
var rowIndex = 1
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val row = sheet.createRow(rowIndex++)
|
||||||
|
row.createCell(0).setCellValue(resultSet.getString("index"))
|
||||||
|
row.createCell(1).setCellValue(resultSet.getString("Description"))
|
||||||
|
row.createCell(2).setCellValue(resultSet.getString("TAG"))
|
||||||
|
row.createCell(3).setCellValue(resultSet.getString("Category"))
|
||||||
|
row.createCell(4).setCellValue(resultSet.getString("Language"))
|
||||||
|
row.createCell(5).setCellValue(resultSet.getString("VoiceType"))
|
||||||
|
row.createCell(6).setCellValue(resultSet.getString("Path"))
|
||||||
|
}
|
||||||
|
for (i in 0 until headers.size) {
|
||||||
|
sheet.autoSizeColumn(i)
|
||||||
|
}
|
||||||
|
return workbook
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error { "Error exporting Soundbank, Msg: ${e.message}" }
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all distinct airline code tags from soundbank
|
||||||
|
* @return a list of distinct airline code tags sorted alphabetically
|
||||||
|
*/
|
||||||
|
fun Get_AirlineCode_Tags(): List<String> {
|
||||||
|
|
||||||
|
return List
|
||||||
|
.filter { it.Category.equals(Category.Airline_Code.name,true) }
|
||||||
|
.distinctBy { it.TAG }
|
||||||
|
.map { it.TAG }
|
||||||
|
.sorted()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all distinct city tags from soundbank
|
||||||
|
* @return a list of distinct city tags sorted alphabetically
|
||||||
|
*/
|
||||||
|
fun Get_City_Tags(): List<String> {
|
||||||
|
return List
|
||||||
|
.filter { it.Category.equals(Category.City.name,true) }
|
||||||
|
.distinctBy { it.TAG }
|
||||||
|
.map { it.TAG }
|
||||||
|
.sorted()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Find_City_By_TAG(tag: String) : List<Soundbank> {
|
||||||
|
return List
|
||||||
|
.filter {it.Category.equals(Category.City.name,true) }
|
||||||
|
.filter { it.TAG.equals(tag, true) }
|
||||||
|
.distinctBy { it.TAG }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Find_AirlineName_By_TAG(tag: String) : List<Soundbank> {
|
||||||
|
return List
|
||||||
|
.filter {it.Category.equals(Category.Airplane_Name.name,true) }
|
||||||
|
.filter { it.TAG.equals(tag, true) }
|
||||||
|
.distinctBy { it.TAG }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Get_Places(): List<Soundbank> {
|
||||||
|
return List
|
||||||
|
.filter { it.Category.equals(Category.Places.name,true) }
|
||||||
|
.distinctBy { it.TAG }
|
||||||
|
.sortedBy { it.TAG }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Get_Shalat() : List<Soundbank> {
|
||||||
|
return List
|
||||||
|
.filter { it.Category.equals(Category.Shalat.name,true) }
|
||||||
|
.distinctBy { it.TAG }
|
||||||
|
.sortedBy { it.TAG }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Get_Sequences() : List<Soundbank> {
|
||||||
|
return List
|
||||||
|
.filter { it.Category.equals(Category.Sequence.name,true) }
|
||||||
|
.distinctBy { it.TAG }
|
||||||
|
.sortedBy { it.TAG }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Get_Reasons() : List<Soundbank> {
|
||||||
|
return List
|
||||||
|
.filter { it.Category.equals(Category.Reason.name,true) }
|
||||||
|
.distinctBy { it.TAG }
|
||||||
|
.sortedBy { it.TAG }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Get_Gates(): List<Soundbank> {
|
||||||
|
return List
|
||||||
|
.filter { it.Category.equals(Category.Gate.name,true) }
|
||||||
|
.distinctBy { it.TAG }
|
||||||
|
.sortedBy { it.TAG }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Get_Compensation(): List<Soundbank> {
|
||||||
|
return List
|
||||||
|
.filter { it.Category.equals(Category.Compensation.name,true) }
|
||||||
|
.distinctBy { it.TAG }
|
||||||
|
.sortedBy { it.TAG }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Get_Greeting() : List<Soundbank> {
|
||||||
|
return List
|
||||||
|
.filter { it.Category.equals(Category.Greeting.name,true) }
|
||||||
|
.distinctBy { it.TAG }
|
||||||
|
.sortedBy { it.TAG }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Get_Procedures(): List<Soundbank> {
|
||||||
|
return List
|
||||||
|
.filter { it.Category.equals(Category.Procedure.name,true) }
|
||||||
|
.distinctBy { it.TAG }
|
||||||
|
.sortedBy { it.TAG }
|
||||||
|
}
|
||||||
|
}
|
||||||
225
src/database/table/Table_Users.kt
Normal file
225
src/database/table/Table_Users.kt
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
package database.table
|
||||||
|
|
||||||
|
import database.data.UserDB
|
||||||
|
import database.dbFunctions
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
||||||
|
import org.tinylog.Logger
|
||||||
|
import java.sql.Connection
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
|
class Table_Users(connection : Connection) : dbFunctions<UserDB>("newuser", connection, listOf("index", "username", "password", "location", "airline_tags", "city_tags", "messagebank_ann_id", "broadcastzones")) {
|
||||||
|
override fun Create() {
|
||||||
|
val tableDefinition = "CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
||||||
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
||||||
|
"username VARCHAR(100) NOT NULL," +
|
||||||
|
"password VARCHAR(100) NOT NULL," +
|
||||||
|
"location VARCHAR(100) NOT NULL," +
|
||||||
|
"airline_tags TEXT NOT NULL,"+ // Comma-separated soundbank tags
|
||||||
|
"city_tags TEXT NOT NULL,"+ // Comma-separated soundbank tags
|
||||||
|
"messagebank_ann_id TEXT NOT NULL,"+ // Comma-separated messagebank announcement index
|
||||||
|
"broadcastzones TEXT NOT NULL"+ // Comma-separated broadcast zones
|
||||||
|
")"
|
||||||
|
super.Create(tableDefinition)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Get(cbOK: Consumer<Unit>?, cbFail: Consumer<String>?) {
|
||||||
|
List.clear()
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val user = UserDB(
|
||||||
|
resultSet.getLong("index").toUInt(),
|
||||||
|
resultSet.getString("username"),
|
||||||
|
resultSet.getString("password"),
|
||||||
|
resultSet.getString("location"),
|
||||||
|
resultSet.getString("airline_tags"),
|
||||||
|
resultSet.getString("city_tags"),
|
||||||
|
resultSet.getString("messagebank_ann_id"),
|
||||||
|
resultSet.getString("broadcastzones")
|
||||||
|
)
|
||||||
|
List.add(user)
|
||||||
|
}
|
||||||
|
cbOK?.accept(Unit)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error fetching users: ${e.message}" as Any)
|
||||||
|
cbFail?.accept("Error fetching users: ${e.message}" )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Add(data: UserDB): Boolean {
|
||||||
|
try {
|
||||||
|
val statement = connection.prepareStatement("INSERT INTO ${super.dbName} (username, password, location, airline_tags, city_tags, messagebank_ann_id, broadcastzones) VALUES (?, ?, ?, ?,?, ?, ?)")
|
||||||
|
statement?.setString(1, data.username)
|
||||||
|
statement?.setString(2, data.password)
|
||||||
|
statement?.setString(3, data.location)
|
||||||
|
statement?.setString(4, data.airline_tags)
|
||||||
|
statement?.setString(5, data.city_tags)
|
||||||
|
statement?.setString(6, data.messagebank_ann_id)
|
||||||
|
statement?.setString(7, data.broadcastzones)
|
||||||
|
val rowsAffected = statement?.executeUpdate()
|
||||||
|
if (rowsAffected != null && rowsAffected > 0) {
|
||||||
|
Logger.info("User added: ${data.username}" as Any)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
Logger.warn("No user entry added for: ${data.username}" as Any)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error adding user entry: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun AddAll(data: ArrayList<UserDB>): Boolean {
|
||||||
|
return try {
|
||||||
|
connection.autoCommit = false
|
||||||
|
val sql = "INSERT INTO ${super.dbName} (username, password, location,airline_tags,city_tags, messagebank_ann_id, broadcastzones) VALUES (?, ?, ?,?, ?, ?, ?)"
|
||||||
|
val statement = connection.prepareStatement(sql)
|
||||||
|
for (user in data) {
|
||||||
|
statement.setString(1, user.username)
|
||||||
|
statement.setString(2, user.password)
|
||||||
|
statement.setString(3, user.location)
|
||||||
|
statement.setString(4, user.airline_tags)
|
||||||
|
statement.setString(5, user.city_tags)
|
||||||
|
statement.setString(6, user.messagebank_ann_id)
|
||||||
|
statement.setString(7, user.broadcastzones)
|
||||||
|
statement.addBatch()
|
||||||
|
}
|
||||||
|
statement.executeBatch()
|
||||||
|
connection.commit()
|
||||||
|
Logger.info("Bulk user insert successful: ${data.size} entries" as Any)
|
||||||
|
connection.autoCommit = true
|
||||||
|
true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error adding user entries: ${e.message}" as Any)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun UpdateByIndex(index: Int, data: UserDB): Boolean {
|
||||||
|
try {
|
||||||
|
val statement = connection.prepareStatement("UPDATE ${super.dbName} SET username = ?, password = ?, location = ?, airline_tags = ?,city_tags=?, messagebank_ann_id = ?, broadcastzones = ? WHERE `index` = ?")
|
||||||
|
statement?.setString(1, data.username)
|
||||||
|
statement?.setString(2, data.password)
|
||||||
|
statement?.setString(3, data.location)
|
||||||
|
statement?.setString(4, data.airline_tags)
|
||||||
|
statement?.setString(5, data.city_tags)
|
||||||
|
statement?.setString(6, data.messagebank_ann_id)
|
||||||
|
statement?.setString(7, data.broadcastzones)
|
||||||
|
statement?.setLong(8, index.toLong())
|
||||||
|
val rowsAffected = statement?.executeUpdate()
|
||||||
|
if (rowsAffected != null && rowsAffected > 0) {
|
||||||
|
Logger.info("User updated at index $index: ${data.username}" as Any)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
Logger.warn("No user entry updated at index $index for: ${data.username}" as Any)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error updating user entry at index $index: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Resort(): Boolean {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val tempdb_name = "temp_${super.dbName}"
|
||||||
|
// use a temporary table to reorder the index
|
||||||
|
statement?.executeUpdate("CREATE TABLE IF NOT EXISTS $tempdb_name LIKE ${super.dbName}")
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE $tempdb_name")
|
||||||
|
statement?.executeUpdate("INSERT INTO $tempdb_name (username, password, location, airline_tags, city_tags, messagebank_ann_id, broadcastzones) SELECT username, password, location, airline_tags, city_tags, messagebank_ann_id, broadcastzones FROM ${super.dbName} ORDER BY username ")
|
||||||
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
||||||
|
statement?.executeUpdate("INSERT INTO ${super.dbName} (username, password, location, airline_tags, city_tags, messagebank_ann_id, broadcastzones) SELECT username, password, location, airline_tags, city_tags, messagebank_ann_id, broadcastzones FROM $tempdb_name")
|
||||||
|
statement?.executeUpdate("DROP TABLE $tempdb_name")
|
||||||
|
Logger.info("${super.dbName} table resorted by index" as Any)
|
||||||
|
// reload the local list
|
||||||
|
Get()
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error("Error resorting ${super.dbName} table by index: ${e.message}" as Any)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Import_XLSX(workbook: XSSFWorkbook): Boolean {
|
||||||
|
try {
|
||||||
|
val sheet = workbook.getSheet("User") ?: throw Exception("No sheet named 'User' found")
|
||||||
|
val headerRow = sheet.getRow(0) ?: throw Exception("No header row found")
|
||||||
|
val headers = arrayOf("Index", "username", "password", "location", "airline_tags", "city_tags", "messagebank_ann_id", "broadcastzones")
|
||||||
|
for ((colIndex, header) in headers.withIndex()) {
|
||||||
|
val cell = headerRow.getCell(colIndex) ?: throw Exception("Header '$header' not found")
|
||||||
|
if (cell.stringCellValue != header) throw Exception("Header '$header' not found")
|
||||||
|
}
|
||||||
|
// clear existing users
|
||||||
|
Clear()
|
||||||
|
// read each row and insert into database
|
||||||
|
val _userList = ArrayList<UserDB>()
|
||||||
|
for (rowIndex in 1..sheet.lastRowNum) {
|
||||||
|
val row = sheet.getRow(rowIndex) ?: continue
|
||||||
|
val username = row.getCell(1)?.stringCellValue ?: continue
|
||||||
|
val password = row.getCell(2)?.stringCellValue ?: continue
|
||||||
|
val location = row.getCell(3)?.stringCellValue ?: continue
|
||||||
|
val airline_tags = row.getCell(4)?.stringCellValue ?: continue
|
||||||
|
val city_tags = row.getCell(5)?.stringCellValue ?: continue
|
||||||
|
val messagebank_ann_id = row.getCell(6)?.stringCellValue ?: continue
|
||||||
|
val broadcastzones = row.getCell(7)?.stringCellValue ?: continue
|
||||||
|
val user = UserDB(
|
||||||
|
0u,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
location,
|
||||||
|
airline_tags,
|
||||||
|
city_tags,
|
||||||
|
messagebank_ann_id,
|
||||||
|
broadcastzones
|
||||||
|
)
|
||||||
|
_userList.add(user)
|
||||||
|
}
|
||||||
|
return AddAll(_userList)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error { "Error importing User, Msg: ${e.message}" }
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Export_XLSX(): XSSFWorkbook? {
|
||||||
|
try {
|
||||||
|
val statement = connection.createStatement()
|
||||||
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
||||||
|
val workbook = XSSFWorkbook()
|
||||||
|
val sheet = workbook.createSheet("User")
|
||||||
|
val headerRow = sheet.createRow(0)
|
||||||
|
val headers = arrayOf("Index", "username", "password", "location", "airline_tags","city_tags", "messagebank_ann_id", "broadcastzones")
|
||||||
|
for ((colIndex, header) in headers.withIndex()) {
|
||||||
|
val cell = headerRow.createCell(colIndex)
|
||||||
|
cell.setCellValue(header)
|
||||||
|
}
|
||||||
|
var rowIndex = 1
|
||||||
|
while (resultSet?.next() == true) {
|
||||||
|
val row = sheet.createRow(rowIndex++)
|
||||||
|
row.createCell(0).setCellValue(resultSet.getString("index"))
|
||||||
|
row.createCell(1).setCellValue(resultSet.getString("username"))
|
||||||
|
row.createCell(2).setCellValue(resultSet.getString("password"))
|
||||||
|
row.createCell(3).setCellValue(resultSet.getString("location"))
|
||||||
|
row.createCell(4).setCellValue(resultSet.getString("airline_tags"))
|
||||||
|
row.createCell(5).setCellValue(resultSet.getString("city_tags"))
|
||||||
|
row.createCell(6).setCellValue(resultSet.getString("messagebank_ann_id"))
|
||||||
|
row.createCell(7).setCellValue(resultSet.getString("broadcastzones"))
|
||||||
|
}
|
||||||
|
for (i in headers.indices) {
|
||||||
|
sheet.autoSizeColumn(i)
|
||||||
|
}
|
||||||
|
return workbook
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error { "Error exporting User, Msg: ${e.message}" }
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a username already exists in the userDB (case-insensitive)
|
||||||
|
*/
|
||||||
|
fun Username_exists(username: String): Boolean {
|
||||||
|
return List.any { it.username.equals(username, ignoreCase = true) }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@ import com.google.cloud.texttospeech.v1.VoiceSelectionParams
|
|||||||
import content.Category
|
import content.Category
|
||||||
import content.Language
|
import content.Language
|
||||||
import content.VoiceType
|
import content.VoiceType
|
||||||
import database.Soundbank
|
import database.data.Soundbank
|
||||||
import org.tinylog.Logger
|
import org.tinylog.Logger
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.util.function.BiConsumer
|
import java.util.function.BiConsumer
|
||||||
|
|||||||
@@ -24,14 +24,14 @@ import content.Category
|
|||||||
import content.Language
|
import content.Language
|
||||||
import content.ScheduleDay
|
import content.ScheduleDay
|
||||||
import content.VoiceType
|
import content.VoiceType
|
||||||
import database.BroadcastZones
|
import database.data.BroadcastZones
|
||||||
import database.LanguageLink
|
import database.data.LanguageLink
|
||||||
import database.MariaDB
|
import database.MariaDB
|
||||||
import database.Messagebank
|
import database.data.Messagebank
|
||||||
import database.ScheduleBank
|
import database.data.ScheduleBank
|
||||||
import database.SoundChannel
|
import database.data.SoundChannel
|
||||||
import database.Soundbank
|
import database.data.Soundbank
|
||||||
import database.UserDB
|
import database.data.UserDB
|
||||||
import db
|
import db
|
||||||
import io.javalin.Javalin
|
import io.javalin.Javalin
|
||||||
import io.javalin.apibuilder.ApiBuilder.*
|
import io.javalin.apibuilder.ApiBuilder.*
|
||||||
@@ -43,8 +43,8 @@ import java.nio.file.Files
|
|||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import codes.configKeys
|
import codes.configKeys
|
||||||
import config
|
import config
|
||||||
import database.LogSemiauto
|
import database.data.LogSemiauto
|
||||||
import database.QueueTable
|
import database.data.QueueTable
|
||||||
import google.GoogleTTS
|
import google.GoogleTTS
|
||||||
import google.autoadd
|
import google.autoadd
|
||||||
import google.fileoperation
|
import google.fileoperation
|
||||||
@@ -128,7 +128,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
//it.sessionAttribute("user", user.first)
|
//it.sessionAttribute("user", user.first)
|
||||||
it.cookie("aas-user", user.first)
|
it.cookie("aas-user", user.first)
|
||||||
// Redirect to home page
|
// Redirect to home page
|
||||||
if (user.first== GetAdminUserFromConfig()){
|
if (user.first == GetAdminUserFromConfig()) {
|
||||||
it.redirect("homeadmin.html")
|
it.redirect("homeadmin.html")
|
||||||
} else {
|
} else {
|
||||||
it.redirect("homeviewer.html")
|
it.redirect("homeviewer.html")
|
||||||
@@ -149,9 +149,10 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
val cmd =
|
val cmd =
|
||||||
objectmapper.readValue(wsMessageContext.message(), WebsocketCommand::class.java)
|
objectmapper.readValue(wsMessageContext.message(), WebsocketCommand::class.java)
|
||||||
when (cmd.command) {
|
when (cmd.command) {
|
||||||
"getAppVersion" ->{
|
"getAppVersion" -> {
|
||||||
SendReply(wsMessageContext, cmd.command, version)
|
SendReply(wsMessageContext, cmd.command, version)
|
||||||
}
|
}
|
||||||
|
|
||||||
"getSystemTime" -> {
|
"getSystemTime" -> {
|
||||||
|
|
||||||
val systemtime = LocalDateTime.now().format(datetimeformat1)
|
val systemtime = LocalDateTime.now().format(datetimeformat1)
|
||||||
@@ -184,11 +185,19 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
}
|
}
|
||||||
|
|
||||||
"getMemoryStatus" -> {
|
"getMemoryStatus" -> {
|
||||||
SendReply(wsMessageContext, cmd.command, objectmapper.writeValueAsString(Somecodes.getMemoryUsage()))
|
SendReply(
|
||||||
|
wsMessageContext,
|
||||||
|
cmd.command,
|
||||||
|
objectmapper.writeValueAsString(Somecodes.getMemoryUsage())
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
"getDiskStatus" -> {
|
"getDiskStatus" -> {
|
||||||
SendReply(wsMessageContext, cmd.command, objectmapper.writeValueAsString(Somecodes.getDiskUsage()))
|
SendReply(
|
||||||
|
wsMessageContext,
|
||||||
|
cmd.command,
|
||||||
|
objectmapper.writeValueAsString(Somecodes.getDiskUsage())
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
"getNetworkStatus" -> {
|
"getNetworkStatus" -> {
|
||||||
@@ -223,8 +232,8 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
SendReply(wsMessageContext, cmd.command, objectmapper.writeValueAsString(reply))
|
SendReply(wsMessageContext, cmd.command, objectmapper.writeValueAsString(reply))
|
||||||
}
|
}
|
||||||
|
|
||||||
"start_generate_tts" ->{
|
"start_generate_tts" -> {
|
||||||
val js : JsonNode = objectmapper.readTree(cmd.data)
|
val js: JsonNode = objectmapper.readTree(cmd.data)
|
||||||
SendReply(wsMessageContext, cmd.command, "ok")
|
SendReply(wsMessageContext, cmd.command, "ok")
|
||||||
val voicetype = js.get("voicetype")?.asText("Wavenet-A") ?: "Wavenet-A"
|
val voicetype = js.get("voicetype")?.asText("Wavenet-A") ?: "Wavenet-A"
|
||||||
val languagecode = js.get("languagecode")?.asText("id-ID") ?: "id-ID"
|
val languagecode = js.get("languagecode")?.asText("id-ID") ?: "id-ID"
|
||||||
@@ -232,21 +241,27 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
val targetas = js.get("targetas")?.asText("VOICE_2") ?: "VOICE_2"
|
val targetas = js.get("targetas")?.asText("VOICE_2") ?: "VOICE_2"
|
||||||
val fop = js.get("fileoperation")?.asText("overwrite") ?: "overwrite"
|
val fop = js.get("fileoperation")?.asText("overwrite") ?: "overwrite"
|
||||||
val aa = js.get("autoadd")?.asText("add") ?: "add"
|
val aa = js.get("autoadd")?.asText("add") ?: "add"
|
||||||
Logger.info {"Starting TTS Soundbank Generation, VoiceType=$voicetype, Language"}
|
Logger.info { "Starting TTS Soundbank Generation, VoiceType=$voicetype, Language" }
|
||||||
ttsjob.GenerateSoundbank(voicetype, Language.from_GoogleTTSLanguage(languagecode),
|
ttsjob.GenerateSoundbank(
|
||||||
|
voicetype, Language.from_GoogleTTSLanguage(languagecode),
|
||||||
VoiceType.fromString(databasesource),
|
VoiceType.fromString(databasesource),
|
||||||
VoiceType.fromString(targetas), fileoperation.fromString(fop),
|
VoiceType.fromString(targetas), fileoperation.fromString(fop),
|
||||||
autoadd.fromString(aa)){ progress, message ->
|
autoadd.fromString(aa)
|
||||||
SendReply(wsMessageContext, "tts_generate_progress", objectmapper.writeValueAsString(
|
) { progress, message ->
|
||||||
|
SendReply(
|
||||||
|
wsMessageContext,
|
||||||
|
"tts_generate_progress",
|
||||||
|
objectmapper.writeValueAsString(
|
||||||
mapOf(
|
mapOf(
|
||||||
"progress" to progress,
|
"progress" to progress,
|
||||||
"message" to message
|
"message" to message
|
||||||
)
|
)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"stop_generate_tts" ->{
|
"stop_generate_tts" -> {
|
||||||
SendReply(wsMessageContext, cmd.command, "ok")
|
SendReply(wsMessageContext, cmd.command, "ok")
|
||||||
ttsjob.StopGenerate()
|
ttsjob.StopGenerate()
|
||||||
|
|
||||||
@@ -311,11 +326,19 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
}
|
}
|
||||||
|
|
||||||
"getMemoryStatus" -> {
|
"getMemoryStatus" -> {
|
||||||
SendReply(wsMessageContext, cmd.command, objectmapper.writeValueAsString(Somecodes.getMemoryUsage()))
|
SendReply(
|
||||||
|
wsMessageContext,
|
||||||
|
cmd.command,
|
||||||
|
objectmapper.writeValueAsString(Somecodes.getMemoryUsage())
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
"getDiskStatus" -> {
|
"getDiskStatus" -> {
|
||||||
SendReply(wsMessageContext, cmd.command, objectmapper.writeValueAsString(Somecodes.getDiskUsage()))
|
SendReply(
|
||||||
|
wsMessageContext,
|
||||||
|
cmd.command,
|
||||||
|
objectmapper.writeValueAsString(Somecodes.getDiskUsage())
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
"getNetworkStatus" -> {
|
"getNetworkStatus" -> {
|
||||||
@@ -367,7 +390,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
before {
|
before {
|
||||||
val user = CheckUsers(it)
|
val user = CheckUsers(it)
|
||||||
// only admin user can access soundbank page
|
// only admin user can access soundbank page
|
||||||
if (GetAdminUserFromConfig() != user){
|
if (GetAdminUserFromConfig() != user) {
|
||||||
it.redirect("overview.html")
|
it.redirect("overview.html")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -376,7 +399,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
before {
|
before {
|
||||||
val user = CheckUsers(it)
|
val user = CheckUsers(it)
|
||||||
// only admin user can access messagebank page
|
// only admin user can access messagebank page
|
||||||
if (GetAdminUserFromConfig() != user){
|
if (GetAdminUserFromConfig() != user) {
|
||||||
it.redirect("overview.html")
|
it.redirect("overview.html")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -397,7 +420,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
before {
|
before {
|
||||||
val user = CheckUsers(it)
|
val user = CheckUsers(it)
|
||||||
// only admin user can access settings page
|
// only admin user can access settings page
|
||||||
if (GetAdminUserFromConfig() != user){
|
if (GetAdminUserFromConfig() != user) {
|
||||||
it.redirect("overview.html")
|
it.redirect("overview.html")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -406,7 +429,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
before {
|
before {
|
||||||
val user = CheckUsers(it)
|
val user = CheckUsers(it)
|
||||||
// only admin user can access timer page
|
// only admin user can access timer page
|
||||||
if (GetAdminUserFromConfig() != user){
|
if (GetAdminUserFromConfig() != user) {
|
||||||
it.redirect("overview.html")
|
it.redirect("overview.html")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -415,7 +438,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
before {
|
before {
|
||||||
val user = CheckUsers(it)
|
val user = CheckUsers(it)
|
||||||
// only admin user can access file management page
|
// only admin user can access file management page
|
||||||
if (GetAdminUserFromConfig() != user){
|
if (GetAdminUserFromConfig() != user) {
|
||||||
it.redirect("overview.html")
|
it.redirect("overview.html")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -424,7 +447,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
before {
|
before {
|
||||||
val user = CheckUsers(it)
|
val user = CheckUsers(it)
|
||||||
// only admin user can access broadcast zones page
|
// only admin user can access broadcast zones page
|
||||||
if (GetAdminUserFromConfig() != user){
|
if (GetAdminUserFromConfig() != user) {
|
||||||
it.redirect("overview.html")
|
it.redirect("overview.html")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -441,7 +464,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
before {
|
before {
|
||||||
val user = CheckUsers(it)
|
val user = CheckUsers(it)
|
||||||
// only admin user can access user management page
|
// only admin user can access user management page
|
||||||
if (GetAdminUserFromConfig() != user){
|
if (GetAdminUserFromConfig() != user) {
|
||||||
it.redirect("overview.html")
|
it.redirect("overview.html")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -449,23 +472,26 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
path("api") {
|
path("api") {
|
||||||
//TODO https://stackoverflow.com/questions/70002015/streaming-into-audio-element
|
//TODO https://stackoverflow.com/questions/70002015/streaming-into-audio-element
|
||||||
path("LiveAudio") {
|
path("LiveAudio") {
|
||||||
post{ ctx->
|
post { ctx ->
|
||||||
val json : JsonNode = objectmapper.readTree(ctx.body())
|
val json: JsonNode = objectmapper.readTree(ctx.body())
|
||||||
val broadcastzone = json.get("broadcastzone")?.asText("") ?: ""
|
val broadcastzone = json.get("broadcastzone")?.asText("") ?: ""
|
||||||
val command = json.get("command")?.asText("") ?: ""
|
val command = json.get("command")?.asText("") ?: ""
|
||||||
if (command == "Open" || command == "Close"){
|
if (command == "Open" || command == "Close") {
|
||||||
if (broadcastzone.isNotEmpty()){
|
if (broadcastzone.isNotEmpty()) {
|
||||||
val bc = Get_Barix_Connection_by_ZoneName(broadcastzone)
|
val bc = Get_Barix_Connection_by_ZoneName(broadcastzone)
|
||||||
if (bc!=null){
|
if (bc != null) {
|
||||||
val key = ctx.cookie("client-stream-id")
|
val key = ctx.cookie("client-stream-id")
|
||||||
if (command == "Open"){
|
if (command == "Open") {
|
||||||
// open command
|
// open command
|
||||||
if (!key.isNullOrEmpty()){
|
if (!key.isNullOrEmpty()) {
|
||||||
// ada connection sebelumnya, kemungkinan reconnect
|
// ada connection sebelumnya, kemungkinan reconnect
|
||||||
val prev = WsContextMap[key]
|
val prev = WsContextMap[key]
|
||||||
if (prev!=null){
|
if (prev != null) {
|
||||||
prev.bc?.Remove_Mp3_Consumer(key)
|
prev.bc?.Remove_Mp3_Consumer(key)
|
||||||
prev.ws?.closeSession(WsCloseStatus.NORMAL_CLOSURE, "Reopen Live Audio Stream")
|
prev.ws?.closeSession(
|
||||||
|
WsCloseStatus.NORMAL_CLOSURE,
|
||||||
|
"Reopen Live Audio Stream"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
WsContextMap.remove(key)
|
WsContextMap.remove(key)
|
||||||
ctx.cookie("client-stream-id", "")
|
ctx.cookie("client-stream-id", "")
|
||||||
@@ -478,12 +504,15 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// close command
|
// close command
|
||||||
if (!key.isNullOrEmpty()){
|
if (!key.isNullOrEmpty()) {
|
||||||
// close connection
|
// close connection
|
||||||
val prev = WsContextMap[key]
|
val prev = WsContextMap[key]
|
||||||
if (prev!=null){
|
if (prev != null) {
|
||||||
prev.bc?.Remove_Mp3_Consumer(key)
|
prev.bc?.Remove_Mp3_Consumer(key)
|
||||||
prev.ws?.closeSession(WsCloseStatus.NORMAL_CLOSURE, "Close Live Audio Stream")
|
prev.ws?.closeSession(
|
||||||
|
WsCloseStatus.NORMAL_CLOSURE,
|
||||||
|
"Close Live Audio Stream"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
WsContextMap.remove(key)
|
WsContextMap.remove(key)
|
||||||
ctx.cookie("client-stream-id", "")
|
ctx.cookie("client-stream-id", "")
|
||||||
@@ -495,42 +524,42 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
} else ResultMessageString(ctx, 400, "Invalid command")
|
} else ResultMessageString(ctx, 400, "Invalid command")
|
||||||
|
|
||||||
}
|
}
|
||||||
ws("ws"){ wscontext ->
|
ws("ws") { wscontext ->
|
||||||
wscontext.onConnect {
|
wscontext.onConnect {
|
||||||
val key = it.cookie("client-stream-id")
|
val key = it.cookie("client-stream-id")
|
||||||
if (!key.isNullOrEmpty()){
|
if (!key.isNullOrEmpty()) {
|
||||||
val lld = WsContextMap[key]
|
val lld = WsContextMap[key]
|
||||||
if (lld!=null){
|
if (lld != null) {
|
||||||
it.enableAutomaticPings()
|
it.enableAutomaticPings()
|
||||||
lld.ws = it
|
lld.ws = it
|
||||||
lld.bc?.Add_Mp3_Consumer(key){ mp3data->
|
lld.bc?.Add_Mp3_Consumer(key) { mp3data ->
|
||||||
try {
|
try {
|
||||||
if (it.session.isOpen){
|
if (it.session.isOpen) {
|
||||||
it.send(ByteBuffer.wrap(mp3data))
|
it.send(ByteBuffer.wrap(mp3data))
|
||||||
}
|
}
|
||||||
} catch (e: Exception){
|
} catch (e: Exception) {
|
||||||
Logger.error {"Error sending LiveAudio mp3 data for key $key, Message: ${e.message}"}
|
Logger.error { "Error sending LiveAudio mp3 data for key $key, Message: ${e.message}" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
it.closeSession(WsCloseStatus.POLICY_VIOLATION, "WsContextMap key not found")
|
it.closeSession(WsCloseStatus.POLICY_VIOLATION, "WsContextMap key not found")
|
||||||
Logger.info{"LiveAudio WebSocket connection rejected, WsContextMap key not found"}
|
Logger.info { "LiveAudio WebSocket connection rejected, WsContextMap key not found" }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
it.closeSession(WsCloseStatus.POLICY_VIOLATION, "Invalid client-stream-id")
|
it.closeSession(WsCloseStatus.POLICY_VIOLATION, "Invalid client-stream-id")
|
||||||
Logger.info{"LiveAudio WebSocket connection rejected, invalid client-stream-id"}
|
Logger.info { "LiveAudio WebSocket connection rejected, invalid client-stream-id" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wscontext.onClose {
|
wscontext.onClose {
|
||||||
val key = it.cookie("client-stream-id")
|
val key = it.cookie("client-stream-id")
|
||||||
if (!key.isNullOrEmpty()){
|
if (!key.isNullOrEmpty()) {
|
||||||
val lld = WsContextMap[key]
|
val lld = WsContextMap[key]
|
||||||
lld?.bc?.Remove_Mp3_Consumer(key)
|
lld?.bc?.Remove_Mp3_Consumer(key)
|
||||||
lld?.ws?.closeSession()
|
lld?.ws?.closeSession()
|
||||||
lld?.bc = null
|
lld?.bc = null
|
||||||
lld?.ws= null
|
lld?.ws = null
|
||||||
WsContextMap.remove(key)
|
WsContextMap.remove(key)
|
||||||
Logger.info{"LiveAudio WebSocket closed for key $key"}
|
Logger.info { "LiveAudio WebSocket closed for key $key" }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -538,7 +567,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
wscontext.onError {
|
wscontext.onError {
|
||||||
val key = it.cookie("client-stream-id")
|
val key = it.cookie("client-stream-id")
|
||||||
val msg = it.error()?.message ?: ""
|
val msg = it.error()?.message ?: ""
|
||||||
Logger.info{"LiveAudio WebSocket error for key $key, Message: $msg"}
|
Logger.info { "LiveAudio WebSocket error for key $key, Message: $msg" }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -595,7 +624,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
get("List") { ctx ->
|
get("List") { ctx ->
|
||||||
db.soundDB.Get({
|
db.soundDB.Get({
|
||||||
ctx.result(MariaDB.ArrayListtoString(db.soundDB.List))
|
ctx.result(MariaDB.ArrayListtoString(db.soundDB.List))
|
||||||
},{msgFail ->
|
}, { msgFail ->
|
||||||
ctx.status(500)
|
ctx.status(500)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
.result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
||||||
})
|
})
|
||||||
@@ -623,11 +652,11 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
.result(objectmapper.writeValueAsString(resultMessage("Invalid Language")))
|
.result(objectmapper.writeValueAsString(resultMessage("Invalid Language")))
|
||||||
}
|
}
|
||||||
get("AirlineTags") { ctx ->
|
get("AirlineTags") { ctx ->
|
||||||
val tags = db.Get_AirlineCode_Tags()
|
val tags = db.soundDB.Get_AirlineCode_Tags()
|
||||||
val value = db.soundDB.List
|
val value = db.soundDB.List
|
||||||
.asSequence()
|
.asSequence()
|
||||||
.filter { f1 -> f1.Category.equals(Category.Airplane_Name.name,true) }
|
.filter { f1 -> f1.Category.equals(Category.Airplane_Name.name, true) }
|
||||||
.filter { f2 -> tags.any{t -> t.equals(f2.TAG,true)}}
|
.filter { f2 -> tags.any { t -> t.equals(f2.TAG, true) } }
|
||||||
.distinctBy { it.TAG }
|
.distinctBy { it.TAG }
|
||||||
.sortedBy { it.TAG }
|
.sortedBy { it.TAG }
|
||||||
.map { KeyValueMessage(it.TAG, it.Description) }
|
.map { KeyValueMessage(it.TAG, it.Description) }
|
||||||
@@ -831,7 +860,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
// get messagebank list
|
// get messagebank list
|
||||||
db.messageDB.Get({
|
db.messageDB.Get({
|
||||||
ctx.result(MariaDB.ArrayListtoString(db.messageDB.List))
|
ctx.result(MariaDB.ArrayListtoString(db.messageDB.List))
|
||||||
},{msgFail ->
|
}, { msgFail ->
|
||||||
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -867,8 +896,9 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
message_detail,
|
message_detail,
|
||||||
message_tags
|
message_tags
|
||||||
)
|
)
|
||||||
val existed = db.messageDB.List.any{ it.ANN_ID== mb.ANN_ID && it.Language == mb.Language && it.Voice_Type == mb.Voice_Type }
|
val existed =
|
||||||
if (!existed){
|
db.messageDB.List.any { it.ANN_ID == mb.ANN_ID && it.Language == mb.Language && it.Voice_Type == mb.Voice_Type }
|
||||||
|
if (!existed) {
|
||||||
if (db.messageDB.Add(mb)) {
|
if (db.messageDB.Add(mb)) {
|
||||||
db.messageDB.Resort()
|
db.messageDB.Resort()
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
@@ -1026,11 +1056,21 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
db.languageDB.Get({
|
db.languageDB.Get({
|
||||||
// get language link list
|
// get language link list
|
||||||
ctx.result(MariaDB.ArrayListtoString(db.languageDB.List))
|
ctx.result(MariaDB.ArrayListtoString(db.languageDB.List))
|
||||||
},{
|
}, { msgFail ->
|
||||||
msgFail ->
|
|
||||||
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
post("DefaultInit") { ctx ->
|
||||||
|
// clear languageDB and init with default values
|
||||||
|
// default value : every CITY in soundDB will have language linked to
|
||||||
|
db.languageDB.Clear()
|
||||||
|
db.soundDB.Get_City_Tags().forEach { city ->
|
||||||
|
val newvalue = LanguageLink(0u, city, Language.DefaultLanguageLink())
|
||||||
|
db.languageDB.Add(newvalue)
|
||||||
|
}
|
||||||
|
db.languageDB.Resort()
|
||||||
|
|
||||||
}
|
}
|
||||||
post("Add") {
|
post("Add") {
|
||||||
// Parse JSON from request body
|
// Parse JSON from request body
|
||||||
@@ -1179,8 +1219,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
db.scheduleDB.Get({
|
db.scheduleDB.Get({
|
||||||
// get timer list
|
// get timer list
|
||||||
ctx.result(MariaDB.ArrayListtoString(db.scheduleDB.List))
|
ctx.result(MariaDB.ArrayListtoString(db.scheduleDB.List))
|
||||||
},{
|
}, { msgFail ->
|
||||||
msgFail ->
|
|
||||||
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
||||||
})
|
})
|
||||||
// get timer list
|
// get timer list
|
||||||
@@ -1388,8 +1427,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
get("List") { ctx ->
|
get("List") { ctx ->
|
||||||
db.userDB.Get({
|
db.userDB.Get({
|
||||||
ctx.result(objectmapper.writeValueAsString(db.userDB.List))
|
ctx.result(objectmapper.writeValueAsString(db.userDB.List))
|
||||||
},{
|
}, { msgFail ->
|
||||||
msgFail ->
|
|
||||||
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1416,54 +1454,73 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
// city, airline, messagebank_ann_id boleh kosong, untuk user yang paging saja
|
// city, airline, messagebank_ann_id boleh kosong, untuk user yang paging saja
|
||||||
// location juga optional
|
// location juga optional
|
||||||
// yang wajib ada adalah username, password, broadcastzones
|
// yang wajib ada adalah username, password, broadcastzones
|
||||||
if (ValidStrings(username, password, broadcastzones ))
|
if (ValidStrings(username, password, broadcastzones)) {
|
||||||
{
|
if (!db.userDB.Username_exists(username)) {
|
||||||
if (!db.Username_exists(username)) {
|
if (ValidString(airline_tags)) {
|
||||||
if (ValidString(airline_tags)){
|
|
||||||
// ada airline_tags, berarti harus di cek apakah ada di table soundbank
|
// ada airline_tags, berarti harus di cek apakah ada di table soundbank
|
||||||
// kalau tidak ada airline_tags, tidak perlu cek
|
// kalau tidak ada airline_tags, tidak perlu cek
|
||||||
val atags = airline_tags.split(";").map { it.trim() }
|
val atags = airline_tags.split(";").map { it.trim() }
|
||||||
.filter { it.isNotEmpty() }.distinct()
|
.filter { it.isNotEmpty() }.distinct()
|
||||||
val airlinetags = db.Get_AirlineCode_Tags()
|
val airlinetags = db.soundDB.Get_AirlineCode_Tags()
|
||||||
val missing_airlinetags = ArrayList<String>()
|
val missing_airlinetags = ArrayList<String>()
|
||||||
atags.forEach { tag ->
|
atags.forEach { tag ->
|
||||||
if (!airlinetags.any { it.equals(tag,true) }) {
|
if (!airlinetags.any { it.equals(tag, true) }) {
|
||||||
missing_airlinetags.add(tag)
|
missing_airlinetags.add(tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (missing_airlinetags.isNotEmpty()){
|
if (missing_airlinetags.isNotEmpty()) {
|
||||||
ctx.status(400)
|
ctx.status(400)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Airline tags not found in soundbank: ${missing_airlinetags.joinToString(", ")}")))
|
.result(
|
||||||
|
objectmapper.writeValueAsString(
|
||||||
|
resultMessage(
|
||||||
|
"Airline tags not found in soundbank: ${
|
||||||
|
missing_airlinetags.joinToString(
|
||||||
|
", "
|
||||||
|
)
|
||||||
|
}"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
return@post
|
return@post
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ValidString(city_tags)){
|
if (ValidString(city_tags)) {
|
||||||
// ada city_tags, berarti harus di cek apakah ada di table soundbank
|
// ada city_tags, berarti harus di cek apakah ada di table soundbank
|
||||||
// kalau tidak ada city_tags, tidak perlu cek
|
// kalau tidak ada city_tags, tidak perlu cek
|
||||||
val ctags = city_tags.split(";").map { it.trim() }
|
val ctags = city_tags.split(";").map { it.trim() }
|
||||||
.filter { it.isNotEmpty() }.distinct()
|
.filter { it.isNotEmpty() }.distinct()
|
||||||
val citytags = db.Get_City_Tags()
|
val citytags = db.soundDB.Get_City_Tags()
|
||||||
val missing_citytags = ArrayList<String>()
|
val missing_citytags = ArrayList<String>()
|
||||||
ctags.forEach { tag ->
|
ctags.forEach { tag ->
|
||||||
if (!citytags.any { it.equals(tag,true) }) {
|
if (!citytags.any { it.equals(tag, true) }) {
|
||||||
missing_citytags.add(tag)
|
missing_citytags.add(tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (missing_citytags.isNotEmpty()){
|
if (missing_citytags.isNotEmpty()) {
|
||||||
ctx.status(400)
|
ctx.status(400)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("City tags not found in soundbank: ${missing_citytags.joinToString(", ")}")))
|
.result(
|
||||||
|
objectmapper.writeValueAsString(
|
||||||
|
resultMessage(
|
||||||
|
"City tags not found in soundbank: ${
|
||||||
|
missing_citytags.joinToString(
|
||||||
|
", "
|
||||||
|
)
|
||||||
|
}"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
return@post
|
return@post
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (ValidString(messagebank_ann_id)){
|
if (ValidString(messagebank_ann_id)) {
|
||||||
// ada messagebank_ann_id, berarti harus di cek apakah ada di table messagebank
|
// ada messagebank_ann_id, berarti harus di cek apakah ada di table messagebank
|
||||||
// kalau tidak ada messagebank_ann_id, tidak perlu cek
|
// kalau tidak ada messagebank_ann_id, tidak perlu cek
|
||||||
val mbids = messagebank_ann_id.split(";")
|
val mbids = messagebank_ann_id.split(";")
|
||||||
.map { it.trim() }
|
.map { it.trim() }
|
||||||
.filter { it.isNotEmpty() }.distinct()
|
.filter { it.isNotEmpty() }.distinct()
|
||||||
.mapNotNull { it.toUIntOrNull() }
|
.mapNotNull { it.toUIntOrNull() }
|
||||||
val mbankids = db.Get_MessageID_List()
|
val mbankids = db.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")))
|
||||||
@@ -1475,16 +1532,26 @@ 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.Get_BroadcastZone_List()
|
val bzlist = db.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) }) {
|
||||||
missing_broadcastzones.add(bz)
|
missing_broadcastzones.add(bz)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (missing_broadcastzones.isNotEmpty()){
|
if (missing_broadcastzones.isNotEmpty()) {
|
||||||
ctx.status(400)
|
ctx.status(400)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Broadcast zone tags not found in soundbank: ${missing_broadcastzones.joinToString(", ")}")))
|
.result(
|
||||||
|
objectmapper.writeValueAsString(
|
||||||
|
resultMessage(
|
||||||
|
"Broadcast zone tags not found in soundbank: ${
|
||||||
|
missing_broadcastzones.joinToString(
|
||||||
|
", "
|
||||||
|
)
|
||||||
|
}"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
return@post
|
return@post
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1546,16 +1613,15 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
// city, airline, messagebank_ann_id boleh kosong, untuk user yang paging saja
|
// city, airline, messagebank_ann_id boleh kosong, untuk user yang paging saja
|
||||||
// location juga optional
|
// location juga optional
|
||||||
// yang wajib ada adalah username, password, broadcastzones
|
// yang wajib ada adalah username, password, broadcastzones
|
||||||
if (ValidStrings(_username, _password, _broadcastzones))
|
if (ValidStrings(_username, _password, _broadcastzones)) {
|
||||||
{
|
|
||||||
val _otherusername = db.userDB.List.find { xx ->
|
val _otherusername = db.userDB.List.find { xx ->
|
||||||
xx.username.equals(
|
xx.username.equals(
|
||||||
_username,
|
_username,
|
||||||
true
|
true
|
||||||
) && xx.index != index
|
) && xx.index != index
|
||||||
}
|
}
|
||||||
if (_otherusername!=null){
|
if (_otherusername != null) {
|
||||||
Logger.info{"Found other username with same name: ${_otherusername.username} at index ${_otherusername.index}"}
|
Logger.info { "Found other username with same name: ${_otherusername.username} at index ${_otherusername.index}" }
|
||||||
ctx.status(400).result(
|
ctx.status(400).result(
|
||||||
objectmapper.writeValueAsString(
|
objectmapper.writeValueAsString(
|
||||||
resultMessage("Username already exists for another user")
|
resultMessage("Username already exists for another user")
|
||||||
@@ -1564,60 +1630,91 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
return@patch
|
return@patch
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ValidString(_airline_tags)){
|
if (ValidString(_airline_tags)) {
|
||||||
// ada airline_tags, berarti harus di cek apakah ada di table soundbank
|
// ada airline_tags, berarti harus di cek apakah ada di table soundbank
|
||||||
// kalau tidak ada airline_tags, tidak perlu cek
|
// kalau tidak ada airline_tags, tidak perlu cek
|
||||||
val atags = _airline_tags.split(";").map { it.trim() }
|
val atags = _airline_tags.split(";").map { it.trim() }
|
||||||
.filter { it.isNotEmpty() }.distinct()
|
.filter { it.isNotEmpty() }.distinct()
|
||||||
val airlinetags = db.Get_AirlineCode_Tags()
|
val airlinetags = db.soundDB.Get_AirlineCode_Tags()
|
||||||
val missing_airlinetags = ArrayList<String>()
|
val missing_airlinetags = ArrayList<String>()
|
||||||
atags.forEach { tag ->
|
atags.forEach { tag ->
|
||||||
if (!airlinetags.any { it.equals(tag,true) }) {
|
if (!airlinetags.any { it.equals(tag, true) }) {
|
||||||
missing_airlinetags.add(tag)
|
missing_airlinetags.add(tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (missing_airlinetags.isNotEmpty()){
|
if (missing_airlinetags.isNotEmpty()) {
|
||||||
ctx.status(400)
|
ctx.status(400)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Airline tags not found in soundbank: ${missing_airlinetags.joinToString(", ")}")))
|
.result(
|
||||||
|
objectmapper.writeValueAsString(
|
||||||
|
resultMessage(
|
||||||
|
"Airline tags not found in soundbank: ${
|
||||||
|
missing_airlinetags.joinToString(
|
||||||
|
", "
|
||||||
|
)
|
||||||
|
}"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
return@patch
|
return@patch
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (ValidString(_city_tags)){
|
if (ValidString(_city_tags)) {
|
||||||
// ada city_tags, berarti harus di cek apakah ada di table soundbank
|
// ada city_tags, berarti harus di cek apakah ada di table soundbank
|
||||||
// kalau tidak ada city_tags, tidak perlu cek
|
// kalau tidak ada city_tags, tidak perlu cek
|
||||||
val ctags = _city_tags.split(";").map { it.trim() }
|
val ctags = _city_tags.split(";").map { it.trim() }
|
||||||
.filter { it.isNotEmpty() }.distinct()
|
.filter { it.isNotEmpty() }.distinct()
|
||||||
val citytags = db.Get_City_Tags()
|
val citytags = db.soundDB.Get_City_Tags()
|
||||||
val missing_citytags = ArrayList<String>()
|
val missing_citytags = ArrayList<String>()
|
||||||
ctags.forEach { tag ->
|
ctags.forEach { tag ->
|
||||||
if (!citytags.any { it.equals(tag,true) }) {
|
if (!citytags.any { it.equals(tag, true) }) {
|
||||||
missing_citytags.add(tag)
|
missing_citytags.add(tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (missing_citytags.isNotEmpty()){ ctx.status(400)
|
if (missing_citytags.isNotEmpty()) {
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("City tags not found in soundbank: ${missing_citytags.joinToString(", ")}")))
|
ctx.status(400)
|
||||||
|
.result(
|
||||||
|
objectmapper.writeValueAsString(
|
||||||
|
resultMessage(
|
||||||
|
"City tags not found in soundbank: ${
|
||||||
|
missing_citytags.joinToString(
|
||||||
|
", "
|
||||||
|
)
|
||||||
|
}"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
return@patch
|
return@patch
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (ValidString(_messagebank_ann_id)){
|
if (ValidString(_messagebank_ann_id)) {
|
||||||
// ada messagebank_ann_id, berarti harus di cek apakah ada di table messagebank
|
// ada messagebank_ann_id, berarti harus di cek apakah ada di table messagebank
|
||||||
// kalau tidak ada messagebank_ann_id, tidak perlu cek
|
// kalau tidak ada messagebank_ann_id, tidak perlu cek
|
||||||
val mbids = _messagebank_ann_id.split(";")
|
val mbids = _messagebank_ann_id.split(";")
|
||||||
.map { it.trim() }
|
.map { it.trim() }
|
||||||
.filter { it.isNotEmpty() }.distinct()
|
.filter { it.isNotEmpty() }.distinct()
|
||||||
.mapNotNull { it.toUIntOrNull() }
|
.mapNotNull { it.toUIntOrNull() }
|
||||||
val mbankids = db.Get_MessageID_List()
|
val mbankids = db.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 }) {
|
||||||
missing_broadcastids.add(mbid)
|
missing_broadcastids.add(mbid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (missing_broadcastids.isNotEmpty()){
|
if (missing_broadcastids.isNotEmpty()) {
|
||||||
ctx.status(400)
|
ctx.status(400)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("ANN_ID not found in Messagebank: ${missing_broadcastids.joinToString(", ")}")))
|
.result(
|
||||||
|
objectmapper.writeValueAsString(
|
||||||
|
resultMessage(
|
||||||
|
"ANN_ID not found in Messagebank: ${
|
||||||
|
missing_broadcastids.joinToString(
|
||||||
|
", "
|
||||||
|
)
|
||||||
|
}"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
return@patch
|
return@patch
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1625,16 +1722,26 @@ 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.Get_BroadcastZone_List()
|
val bzlist = db.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) }) {
|
||||||
missing_broadcastzones.add(bz)
|
missing_broadcastzones.add(bz)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (missing_broadcastzones.isNotEmpty()){
|
if (missing_broadcastzones.isNotEmpty()) {
|
||||||
ctx.status(400)
|
ctx.status(400)
|
||||||
.result(objectmapper.writeValueAsString(resultMessage("Broadcast zone tags not found in soundbank: ${missing_broadcastzones.joinToString(", ")}")))
|
.result(
|
||||||
|
objectmapper.writeValueAsString(
|
||||||
|
resultMessage(
|
||||||
|
"Broadcast zone tags not found in soundbank: ${
|
||||||
|
missing_broadcastzones.joinToString(
|
||||||
|
", "
|
||||||
|
)
|
||||||
|
}"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
return@patch
|
return@patch
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1741,9 +1848,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.Export_Log_XLSX(logdate.replace('-', '/'), logfilter)
|
db.logDB.Export_Log_XLSX(logdate.replace('-', '/'), logfilter)
|
||||||
} else {
|
} else {
|
||||||
db.Export_Log_XLSX(logdate.replace('-', '/'), "")
|
db.logDB.Export_Log_XLSX(logdate.replace('-', '/'), "")
|
||||||
}
|
}
|
||||||
if (xlsxdata != null) {
|
if (xlsxdata != null) {
|
||||||
get1.header(
|
get1.header(
|
||||||
@@ -1766,8 +1873,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
get("List") { ctx ->
|
get("List") { ctx ->
|
||||||
db.broadcastDB.Get({
|
db.broadcastDB.Get({
|
||||||
ctx.result(MariaDB.ArrayListtoString(db.broadcastDB.List))
|
ctx.result(MariaDB.ArrayListtoString(db.broadcastDB.List))
|
||||||
},{
|
}, { msgFail ->
|
||||||
msgFail ->
|
|
||||||
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1924,14 +2030,13 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
get("List") { ctx ->
|
get("List") { ctx ->
|
||||||
db.soundchannelDB.Get({
|
db.soundchannelDB.Get({
|
||||||
ctx.result(MariaDB.ArrayListtoString(db.soundchannelDB.List))
|
ctx.result(MariaDB.ArrayListtoString(db.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.Get_SoundChannel_List()))
|
it.result(objectmapper.writeValueAsString(db.soundchannelDB.Get_SoundChannel_List()))
|
||||||
}
|
}
|
||||||
delete("List") {
|
delete("List") {
|
||||||
// truncate sound channel table
|
// truncate sound channel table
|
||||||
@@ -2060,8 +2165,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
get("List") { ctx ->
|
get("List") { ctx ->
|
||||||
db.queuepagingDB.Get({
|
db.queuepagingDB.Get({
|
||||||
ctx.result(MariaDB.ArrayListtoString(db.queuepagingDB.List))
|
ctx.result(MariaDB.ArrayListtoString(db.queuepagingDB.List))
|
||||||
},{
|
}, { msgFail ->
|
||||||
msgFail ->
|
|
||||||
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -2099,8 +2203,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
get("List") { ctx ->
|
get("List") { ctx ->
|
||||||
db.queuetableDB.Get({
|
db.queuetableDB.Get({
|
||||||
ctx.result(MariaDB.ArrayListtoString(db.queuetableDB.List))
|
ctx.result(MariaDB.ArrayListtoString(db.queuetableDB.List))
|
||||||
},{
|
}, { msgFail ->
|
||||||
msgFail ->
|
|
||||||
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(msgFail)))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -2424,7 +2527,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
path("WebAccess"){
|
path("WebAccess") {
|
||||||
get {
|
get {
|
||||||
val value = object {
|
val value = object {
|
||||||
val adminpass = _config.Get(configKeys.WEBAPP_ADMIN_PASSWORD.key)
|
val adminpass = _config.Get(configKeys.WEBAPP_ADMIN_PASSWORD.key)
|
||||||
@@ -2432,19 +2535,25 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
}
|
}
|
||||||
it.result(objectmapper.writeValueAsString(value))
|
it.result(objectmapper.writeValueAsString(value))
|
||||||
}
|
}
|
||||||
post{
|
post {
|
||||||
val json : JsonNode = objectmapper.readTree(it.body())
|
val json: JsonNode = objectmapper.readTree(it.body())
|
||||||
val adminpass = json.get("adminpass").asText("")
|
val adminpass = json.get("adminpass").asText("")
|
||||||
val viewerpass = json.get("viewerpass").asText("")
|
val viewerpass = json.get("viewerpass").asText("")
|
||||||
if(ValidString(adminpass) && ValidString(viewerpass)){
|
if (ValidString(adminpass) && ValidString(viewerpass)) {
|
||||||
_config.Set(configKeys.WEBAPP_ADMIN_PASSWORD.key, adminpass)
|
_config.Set(configKeys.WEBAPP_ADMIN_PASSWORD.key, adminpass)
|
||||||
_config.Set(configKeys.WEBAPP_VIEWER_PASSWORD.key, viewerpass)
|
_config.Set(configKeys.WEBAPP_VIEWER_PASSWORD.key, viewerpass)
|
||||||
_config.Save()
|
_config.Save()
|
||||||
Logger.info { "Changed Web Access Passwords" }
|
Logger.info { "Changed Web Access Passwords" }
|
||||||
// update userlist
|
// update userlist
|
||||||
userlist = listOf(
|
userlist = listOf(
|
||||||
Pair(_config.Get(configKeys.WEBAPP_ADMIN_USERNAME.key), _config.Get(configKeys.WEBAPP_ADMIN_PASSWORD.key)),
|
Pair(
|
||||||
Pair(_config.Get(configKeys.WEBAPP_VIEWER_USERNAME.key), _config.Get(configKeys.WEBAPP_VIEWER_PASSWORD.key))
|
_config.Get(configKeys.WEBAPP_ADMIN_USERNAME.key),
|
||||||
|
_config.Get(configKeys.WEBAPP_ADMIN_PASSWORD.key)
|
||||||
|
),
|
||||||
|
Pair(
|
||||||
|
_config.Get(configKeys.WEBAPP_VIEWER_USERNAME.key),
|
||||||
|
_config.Get(configKeys.WEBAPP_VIEWER_PASSWORD.key)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
} else {
|
} else {
|
||||||
@@ -2469,7 +2578,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
config.staticFiles.add("/semiauto")
|
config.staticFiles.add("/semiauto")
|
||||||
config.jsonMapper(JavalinJackson(jacksonObjectMapper()))
|
config.jsonMapper(JavalinJackson(jacksonObjectMapper()))
|
||||||
config.router.apiBuilder {
|
config.router.apiBuilder {
|
||||||
before{
|
before {
|
||||||
//Logger.info{"${it.ip()} method ${it.method()} connect to ${it.path()}"}
|
//Logger.info{"${it.ip()} method ${it.method()} connect to ${it.path()}"}
|
||||||
}
|
}
|
||||||
path("/") {
|
path("/") {
|
||||||
@@ -2494,7 +2603,12 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
it.cookie("semiauto-user", user.username)
|
it.cookie("semiauto-user", user.username)
|
||||||
it.redirect("index.html")
|
it.redirect("index.html")
|
||||||
|
|
||||||
db.logSemiAuto.Add(LogSemiauto.NewLog("SEMIAUTOWEB", "User logged in: ${user.username} from ip ${it.ip()}"))
|
db.logSemiAuto.Add(
|
||||||
|
LogSemiauto.NewLog(
|
||||||
|
"SEMIAUTOWEB",
|
||||||
|
"User logged in: ${user.username} from ip ${it.ip()}"
|
||||||
|
)
|
||||||
|
)
|
||||||
} else ResultMessageString(it, 400, "Invalid username or password")
|
} else ResultMessageString(it, 400, "Invalid username or password")
|
||||||
} else ResultMessageString(it, 400, "Username or password cannot be empty")
|
} else ResultMessageString(it, 400, "Username or password cannot be empty")
|
||||||
}
|
}
|
||||||
@@ -2580,7 +2694,12 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx.result(objectmapper.writeValueAsString(result))
|
ctx.result(objectmapper.writeValueAsString(result))
|
||||||
db.logSemiAuto.Add(LogSemiauto.NewLog("SEMIAUTOWEB", "Initialized Web variables for user: ${user.username}"))
|
db.logSemiAuto.Add(
|
||||||
|
LogSemiauto.NewLog(
|
||||||
|
"SEMIAUTOWEB",
|
||||||
|
"Initialized Web variables for user: ${user.username}"
|
||||||
|
)
|
||||||
|
)
|
||||||
} else ResultMessageString(ctx, 400, "User not found")
|
} else ResultMessageString(ctx, 400, "User not found")
|
||||||
} else ResultMessageString(ctx, 400, "Username is empty")
|
} else ResultMessageString(ctx, 400, "Username is empty")
|
||||||
}
|
}
|
||||||
@@ -2612,7 +2731,12 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
db.queuetableDB.Resort()
|
db.queuetableDB.Resort()
|
||||||
Logger.info { "SemiAutoWeb added to queue table: $qt" }
|
Logger.info { "SemiAutoWeb added to queue table: $qt" }
|
||||||
ctx.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
ctx.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||||
db.logSemiAuto.Add(LogSemiauto.NewLog("SEMIAUTOWEB", "Added to queue table: $qt"))
|
db.logSemiAuto.Add(
|
||||||
|
LogSemiauto.NewLog(
|
||||||
|
"SEMIAUTOWEB",
|
||||||
|
"Added to queue table: $qt"
|
||||||
|
)
|
||||||
|
)
|
||||||
} else ResultMessageString(ctx, 500, "Failed to add to queue table")
|
} else ResultMessageString(ctx, 500, "Failed to add to queue table")
|
||||||
} else ResultMessageString(ctx, 400, "Broadcast zones cannot be empty")
|
} else ResultMessageString(ctx, 400, "Broadcast zones cannot be empty")
|
||||||
} else ResultMessageString(ctx, 400, "Tags cannot be empty")
|
} else ResultMessageString(ctx, 400, "Tags cannot be empty")
|
||||||
@@ -2626,9 +2750,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.Export_Log_XLSX(logdate.replace('-', '/'), logfilter)
|
db.logDB.Export_Log_XLSX(logdate.replace('-', '/'), logfilter)
|
||||||
} else {
|
} else {
|
||||||
db.Export_Log_XLSX(logdate.replace('-', '/'), "")
|
db.logDB.Export_Log_XLSX(logdate.replace('-', '/'), "")
|
||||||
}
|
}
|
||||||
if (xlsxdata != null) {
|
if (xlsxdata != null) {
|
||||||
get1.header(
|
get1.header(
|
||||||
@@ -2652,7 +2776,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
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.result(MariaDB.ArrayListtoString(it))
|
||||||
},{ err ->
|
}, { err ->
|
||||||
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(err)))
|
ctx.status(500).result(objectmapper.writeValueAsString(resultMessage(err)))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -2678,7 +2802,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun CheckUsers(ctx: Context) : String? {
|
fun CheckUsers(ctx: Context): String? {
|
||||||
//val user = ctx.sessionAttribute<String?>("user")
|
//val user = ctx.sessionAttribute<String?>("user")
|
||||||
val user = ctx.cookie("aas-user")
|
val user = ctx.cookie("aas-user")
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
@@ -2693,12 +2817,11 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
|||||||
return foundUser.first
|
return foundUser.first
|
||||||
}
|
}
|
||||||
|
|
||||||
fun GetAdminUserFromConfig() : String{
|
fun GetAdminUserFromConfig(): String {
|
||||||
return config.Get(configKeys.WEBAPP_ADMIN_USERNAME.key)
|
return config.Get(configKeys.WEBAPP_ADMIN_USERNAME.key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 = db.broadcastDB.List.find { it.description == zonename }
|
||||||
|
|||||||
Reference in New Issue
Block a user