commit 06/10/2025
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -30,3 +30,8 @@ bin/
|
|||||||
|
|
||||||
### Mac OS ###
|
### Mac OS ###
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
## Soundbank directories ##
|
||||||
|
/PagingResult/
|
||||||
|
/SoundBanks/
|
||||||
|
/SoundbankResult/
|
||||||
53
src/Main.kt
53
src/Main.kt
@@ -1,7 +1,9 @@
|
|||||||
|
import audio.AudioFileInfo
|
||||||
import audio.AudioPlayer
|
import audio.AudioPlayer
|
||||||
import audio.UDPReceiver
|
import audio.UDPReceiver
|
||||||
import barix.BarixConnection
|
import barix.BarixConnection
|
||||||
import barix.TCP_Barix_Command_Server
|
import barix.TCP_Barix_Command_Server
|
||||||
|
import codes.Somecodes
|
||||||
import com.sun.jna.Platform
|
import com.sun.jna.Platform
|
||||||
import commandServer.TCP_Android_Command_Server
|
import commandServer.TCP_Android_Command_Server
|
||||||
import content.Language
|
import content.Language
|
||||||
@@ -16,7 +18,9 @@ import kotlinx.coroutines.launch
|
|||||||
import org.tinylog.Logger
|
import org.tinylog.Logger
|
||||||
import oshi.util.GlobalConfig
|
import oshi.util.GlobalConfig
|
||||||
import web.WebApp
|
import web.WebApp
|
||||||
|
import java.nio.file.Files
|
||||||
import kotlin.concurrent.fixedRateTimer
|
import kotlin.concurrent.fixedRateTimer
|
||||||
|
import kotlin.io.path.absolutePathString
|
||||||
|
|
||||||
lateinit var db: MariaDB
|
lateinit var db: MariaDB
|
||||||
lateinit var audioPlayer: AudioPlayer
|
lateinit var audioPlayer: AudioPlayer
|
||||||
@@ -39,6 +43,49 @@ val urutan_bahasa = listOf(
|
|||||||
Language.ARABIC.name
|
Language.ARABIC.name
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common audio files, seperti chimeup, chimedown, silence1s, silencehalf
|
||||||
|
*/
|
||||||
|
val commonAudio : MutableMap<String, AudioFileInfo> = HashMap()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create necessary folders if not exist
|
||||||
|
*/
|
||||||
|
fun folder_preparation(){
|
||||||
|
Files.createDirectories(Somecodes.SoundbankResult_directory)
|
||||||
|
Files.createDirectories(Somecodes.PagingResult_directory)
|
||||||
|
Files.createDirectories(Somecodes.Soundbank_directory)
|
||||||
|
Somecodes.Soundbank_Languages_directory.forEach {
|
||||||
|
Files.createDirectories(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract necessary wav files from classpath to soundbank directory
|
||||||
|
* and Load them
|
||||||
|
*/
|
||||||
|
fun files_preparation(){
|
||||||
|
val list = listOf("chimeup.wav", "chimedown.wav", "silence1s.wav", "silencehalf.wav")
|
||||||
|
list.forEach {
|
||||||
|
Somecodes.ExtractFilesFromClassPath("/$it", Somecodes.Soundbank_directory)
|
||||||
|
val pp = Somecodes.Soundbank_directory.resolve(it)
|
||||||
|
if (Files.isRegularFile(pp)){
|
||||||
|
val afi = audioPlayer.LoadAudioFile(pp.absolutePathString())
|
||||||
|
if (afi.isValid()){
|
||||||
|
Logger.info { "Common audio $it loaded from ${pp.toAbsolutePath()}" }
|
||||||
|
val key = it.substring(0, it.length - 4) // buang .wav
|
||||||
|
commonAudio[key] = afi
|
||||||
|
} else {
|
||||||
|
Logger.error { "Failed to load common audio $it from ${pp.toAbsolutePath()}" }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Logger.error { "Common audio $it not found at ${pp.toAbsolutePath()}" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Application start here
|
// Application start here
|
||||||
fun main() {
|
fun main() {
|
||||||
if (Platform.isWindows()) {
|
if (Platform.isWindows()) {
|
||||||
@@ -46,8 +93,14 @@ fun main() {
|
|||||||
GlobalConfig.set(GlobalConfig.OSHI_OS_WINDOWS_CPU_UTILITY, true)
|
GlobalConfig.set(GlobalConfig.OSHI_OS_WINDOWS_CPU_UTILITY, true)
|
||||||
}
|
}
|
||||||
Logger.info { "Starting AAS New Generation version $version" }
|
Logger.info { "Starting AAS New Generation version $version" }
|
||||||
|
|
||||||
|
folder_preparation()
|
||||||
|
|
||||||
audioPlayer = AudioPlayer(44100) // 44100 Hz sampling rate
|
audioPlayer = AudioPlayer(44100) // 44100 Hz sampling rate
|
||||||
audioPlayer.InitAudio(1)
|
audioPlayer.InitAudio(1)
|
||||||
|
|
||||||
|
files_preparation()
|
||||||
|
|
||||||
db = MariaDB()
|
db = MariaDB()
|
||||||
|
|
||||||
val subcode01 = MainExtension01()
|
val subcode01 = MainExtension01()
|
||||||
|
|||||||
@@ -580,7 +580,7 @@ class MainExtension01 {
|
|||||||
).toString()
|
).toString()
|
||||||
audioPlayer.WavWriter(
|
audioPlayer.WavWriter(
|
||||||
listafi,
|
listafi,
|
||||||
targetfile
|
targetfile, true,
|
||||||
) { success, message ->
|
) { success, message ->
|
||||||
db.Add_Log("AAS", message)
|
db.Add_Log("AAS", message)
|
||||||
if (success) {
|
if (success) {
|
||||||
@@ -662,11 +662,8 @@ class MainExtension01 {
|
|||||||
val zz = qa.BroadcastZones.split(";")
|
val zz = qa.BroadcastZones.split(";")
|
||||||
|
|
||||||
if (AllBroadcastZonesValid(zz)) {
|
if (AllBroadcastZonesValid(zz)) {
|
||||||
println("All broadcast zones valid")
|
|
||||||
val ips = BroadcastZones_to_SoundChannel_IP(zz)
|
val ips = BroadcastZones_to_SoundChannel_IP(zz)
|
||||||
println("Broadcast zones $zz converted to SoundChannel IPs: $ips")
|
|
||||||
if (AllStreamerOutputIdle(ips)) {
|
if (AllStreamerOutputIdle(ips)) {
|
||||||
println("All broadcast zones idle")
|
|
||||||
if (qa.Type == "SOUNDBANK") {
|
if (qa.Type == "SOUNDBANK") {
|
||||||
val variables = Get_Soundbank_Data(qa.SB_TAGS)
|
val variables = Get_Soundbank_Data(qa.SB_TAGS)
|
||||||
val languages = qa.Language.split(";")
|
val languages = qa.Language.split(";")
|
||||||
@@ -708,17 +705,14 @@ class MainExtension01 {
|
|||||||
val listafi = mutableListOf<AudioFileInfo>()
|
val listafi = mutableListOf<AudioFileInfo>()
|
||||||
|
|
||||||
mblist.forEach { mb ->
|
mblist.forEach { mb ->
|
||||||
println("Getting soundbank files for messagebank id ${mb.ANN_ID} voice=${mb.Voice_Type} lang=${mb.Language}, variables=$variables")
|
|
||||||
Get_Soundbank_Files(mb, variables ?: emptyMap(), {
|
Get_Soundbank_Files(mb, variables ?: emptyMap(), {
|
||||||
listfile ->
|
listfile ->
|
||||||
println("Got soundbank files: $listfile")
|
|
||||||
listfile.forEach { filenya ->
|
listfile.forEach { filenya ->
|
||||||
val afi = audioPlayer.LoadAudioFile(filenya)
|
val afi = audioPlayer.LoadAudioFile(filenya)
|
||||||
if (afi.isValid()) {
|
if (afi.isValid()) {
|
||||||
listafi.add(afi)
|
listafi.add(afi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println("Loaded AudioFileInfo list: $listafi")
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
err ->
|
err ->
|
||||||
@@ -728,27 +722,30 @@ class MainExtension01 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (listafi.isNotEmpty()){
|
if (listafi.isNotEmpty()){
|
||||||
|
db.queuetableDB.DeleteByIndex(qa.index.toInt())
|
||||||
|
|
||||||
val targetfile = SoundbankResult_directory.resolve(Make_WAV_FileName("Soundbank","")).toString()
|
val targetfile = SoundbankResult_directory.resolve(Make_WAV_FileName("Soundbank","")).toString()
|
||||||
println("Writing to target WAV file: $targetfile")
|
println("Writing to target WAV file: $targetfile")
|
||||||
audioPlayer.WavWriter(listafi, targetfile
|
audioPlayer.WavWriter(listafi, targetfile, true,
|
||||||
) { success, message ->
|
) { success, message ->
|
||||||
if (success) {
|
if (success) {
|
||||||
// file siap broadcast
|
// file siap broadcast
|
||||||
println("Successfully wrote WAV file: $targetfile")
|
println("Successfully wrote WAV file: $targetfile")
|
||||||
val targetafi = audioPlayer.LoadAudioFile(targetfile)
|
val targetafi = audioPlayer.LoadAudioFile(targetfile)
|
||||||
if (targetafi.isValid()) {
|
if (targetafi.isValid()) {
|
||||||
zz.forEach { z1 ->
|
ips.forEach { ip ->
|
||||||
StreamerOutputs.values.find { it.channel == z1 }
|
StreamerOutputs[ip].let{ sc ->
|
||||||
?.SendData(
|
sc?.SendData(targetafi.bytes,
|
||||||
targetafi.bytes,
|
{ db.Add_Log("AAS", it) },
|
||||||
{ db.Add_Log("AAS", it) },
|
{ db.Add_Log("AAS", it) } )
|
||||||
{ db.Add_Log("AAS", it) })
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val logmsg =
|
val logmsg =
|
||||||
"Broadcast started SOUNDBANK message with generated file '$targetfile' to zones: ${qa.BroadcastZones}"
|
"Broadcast started SOUNDBANK message with generated file '$targetfile' to zones: ${qa.BroadcastZones}"
|
||||||
Logger.info { logmsg }
|
Logger.info { logmsg }
|
||||||
db.Add_Log("AAS", logmsg)
|
db.Add_Log("AAS", logmsg)
|
||||||
db.queuetableDB.DeleteByIndex(qa.index.toInt())
|
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -783,7 +780,7 @@ class MainExtension01 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val targetfile = SoundbankResult_directory.resolve(Make_WAV_FileName("Timer","")).toString()
|
val targetfile = SoundbankResult_directory.resolve(Make_WAV_FileName("Timer","")).toString()
|
||||||
audioPlayer.WavWriter(listafi, targetfile
|
audioPlayer.WavWriter(listafi, targetfile, true,
|
||||||
) { success, message ->
|
) { success, message ->
|
||||||
if (success) {
|
if (success) {
|
||||||
// file siap broadcast
|
// file siap broadcast
|
||||||
|
|||||||
@@ -11,9 +11,13 @@ import audio.BassEnc.BASS_ENCODE_PCM
|
|||||||
import codes.Somecodes.Companion.ValidFile
|
import codes.Somecodes.Companion.ValidFile
|
||||||
import codes.Somecodes.Companion.ValidString
|
import codes.Somecodes.Companion.ValidString
|
||||||
import com.sun.jna.Memory
|
import com.sun.jna.Memory
|
||||||
|
import com.sun.jna.Pointer
|
||||||
|
import commonAudio
|
||||||
import kotlinx.coroutines.CoroutineName
|
import kotlinx.coroutines.CoroutineName
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.isActive
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.tinylog.Logger
|
import org.tinylog.Logger
|
||||||
import java.util.function.BiConsumer
|
import java.util.function.BiConsumer
|
||||||
@@ -126,21 +130,28 @@ class AudioPlayer (var samplingrate: Int) {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the audio data from a byte array to a WAV file.
|
||||||
|
* @param data The byte array containing the audio data.
|
||||||
|
* @param target The target file name for the WAV file.
|
||||||
|
* @param callback A BiConsumer that accepts a Boolean indicating success or failure and a String message.
|
||||||
|
*/
|
||||||
fun WavWriter(data: ByteArray, target: String, callback: BiConsumer<Boolean, String>) {
|
fun WavWriter(data: ByteArray, target: String, callback: BiConsumer<Boolean, String>) {
|
||||||
val source = AudioFileInfo()
|
val source = AudioFileInfo()
|
||||||
source.bytes = data
|
source.bytes = data
|
||||||
source.fileName = "In-Memory Data"
|
source.fileName = "In-Memory Data"
|
||||||
val sources = listOf(source)
|
val sources = listOf(source)
|
||||||
WavWriter(sources, target, callback)
|
WavWriter(sources, target, false, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the audio data from the sources to a WAV file.
|
* Writes the audio data from the sources to a WAV file.
|
||||||
* @param sources List of AudioFileInfo objects containing the audio data to write.
|
* @param sources List of AudioFileInfo objects containing the audio data to write.
|
||||||
* @param target The target file name for the WAV file.
|
* @param target The target file name for the WAV file.
|
||||||
|
* @param withChime If true, adds a chime sound at the beginning and end of the audio.
|
||||||
* @param callback A BiConsumer that accepts a Boolean indicating success or failure and a String message.
|
* @param callback A BiConsumer that accepts a Boolean indicating success or failure and a String message.
|
||||||
*/
|
*/
|
||||||
fun WavWriter(sources: List<AudioFileInfo>, target: String, callback: BiConsumer<Boolean, String>) {
|
fun WavWriter(sources: List<AudioFileInfo>, target: String, withChime: Boolean, callback: BiConsumer<Boolean, String>) {
|
||||||
if (sources.isEmpty()) {
|
if (sources.isEmpty()) {
|
||||||
callback.accept(false, " Invalid sources")
|
callback.accept(false, " Invalid sources")
|
||||||
return
|
return
|
||||||
@@ -150,10 +161,10 @@ class AudioPlayer (var samplingrate: Int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val job = CoroutineScope(Dispatchers.Default)
|
|
||||||
job.launch(CoroutineName("WavWriter $target")) {
|
val job = CoroutineScope(Dispatchers.IO).launch(CoroutineName("WavWriter $target")) {
|
||||||
bass.BASS_SetDevice(0) // Set to No Sound device for writing
|
bass.BASS_SetDevice(0) // Set to No Sound device for writing
|
||||||
val streamhandle = bass.BASS_StreamCreate(samplingrate, 1, BASS_STREAM_DECODE, STREAMPROC_PUSH, null)
|
val streamhandle = bass.BASS_StreamCreate(samplingrate, 1, BASS_STREAM_DECODE, Pointer(-1), null)
|
||||||
if (streamhandle==0){
|
if (streamhandle==0){
|
||||||
callback.accept(false, "Failed to create stream: ${bass.BASS_ErrorGetCode()}")
|
callback.accept(false, "Failed to create stream: ${bass.BASS_ErrorGetCode()}")
|
||||||
return@launch
|
return@launch
|
||||||
@@ -164,46 +175,82 @@ class AudioPlayer (var samplingrate: Int) {
|
|||||||
callback.accept(false, "Failed to start encoding: ${bass.BASS_ErrorGetCode()}")
|
callback.accept(false, "Failed to start encoding: ${bass.BASS_ErrorGetCode()}")
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
val playresult = bass.BASS_ChannelPlay(streamhandle,false)
|
|
||||||
if (!playresult) {
|
fun pushData(data: ByteArray): Boolean {
|
||||||
bassenc.BASS_Encode_Stop(encodehandle)
|
val mem = Memory(data.size.toLong())
|
||||||
bass.BASS_StreamFree(streamhandle)
|
mem.write(0, data, 0, data.size)
|
||||||
callback.accept(false, "BASS_ChannelPlay failed: ${bass.BASS_ErrorGetCode()}")
|
val pushresult = bass.BASS_StreamPutData(streamhandle, mem, data.size)
|
||||||
return@launch
|
if (pushresult==-1){
|
||||||
|
val errcode = bass.BASS_ErrorGetCode()
|
||||||
|
println("BASS_StreamPutData failed: $errcode")
|
||||||
|
}
|
||||||
|
return pushresult != -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var allsuccess = true
|
var allsuccess = true
|
||||||
|
if (withChime){
|
||||||
|
val chup = commonAudio["chimeup"]
|
||||||
|
if (chup!=null && chup.isValid()){
|
||||||
|
if (pushData(chup.bytes)){
|
||||||
|
println("Chime up pushed")
|
||||||
|
} else {
|
||||||
|
allsuccess = false
|
||||||
|
println("Chime up failed")
|
||||||
|
}
|
||||||
|
} else println("Chime Up not valid")
|
||||||
|
}
|
||||||
sources.forEach { source ->
|
sources.forEach { source ->
|
||||||
if (source.isValid()) {
|
if (source.isValid()) {
|
||||||
// write the bytes to the stream
|
// write the bytes to the stream
|
||||||
val mem = Memory(source.bytes.size.toLong())
|
if (pushData(source.bytes)){
|
||||||
mem.write(0, source.bytes, 0, source.bytes.size)
|
println("Source ${source.fileName} pushed")
|
||||||
val pushresult = bass.BASS_StreamPutData(streamhandle, mem, source.bytes.size)
|
} else {
|
||||||
if (pushresult == -1) {
|
|
||||||
Logger.error { "Failed to write data from ${source.fileName} to stream: ${bass.BASS_ErrorGetCode()}" }
|
|
||||||
allsuccess = false
|
allsuccess = false
|
||||||
|
println("Source ${source.fileName} push failed")
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
allsuccess = false
|
||||||
|
println("Source ${source.fileName} is not valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (withChime){
|
||||||
|
val chdn = commonAudio["chimedown"]
|
||||||
|
if (chdn!=null && chdn.isValid()){
|
||||||
|
if (pushData(chdn.bytes)){
|
||||||
|
println("Chime down pushed")
|
||||||
|
} else {
|
||||||
|
allsuccess = false
|
||||||
|
println("Chime down failed")
|
||||||
|
}
|
||||||
|
} else println("Chime Down not valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
// now we wait until the stream is finished
|
val readsize: Long = 1024 * 1024 // read 1 MB at a time
|
||||||
while(bassenc.BASS_Encode_IsActive(encodehandle) == BASS_ACTIVE_PLAYING) {
|
var totalread: Long = 0
|
||||||
Thread.sleep(100) // Sleep for a short time to avoid busy waiting
|
do{
|
||||||
}
|
val p = Memory(readsize)
|
||||||
|
val read = bass.BASS_ChannelGetData(streamhandle, p, 4096)
|
||||||
|
if (read > 0) {
|
||||||
|
totalread += read
|
||||||
|
}
|
||||||
|
} while (read > 0)
|
||||||
|
println("Finished reading stream data, total $totalread bytes read")
|
||||||
|
|
||||||
|
|
||||||
// close the encoding handle
|
// close the encoding handle
|
||||||
bassenc.BASS_Encode_Stop(encodehandle)
|
bassenc.BASS_Encode_Stop(encodehandle)
|
||||||
bass.BASS_ChannelFree(streamhandle)
|
bass.BASS_ChannelFree(streamhandle)
|
||||||
if (allsuccess){
|
if (allsuccess){
|
||||||
|
|
||||||
callback.accept(true, "WAV file written successfully: $target")
|
callback.accept(true, "WAV file written successfully: $target")
|
||||||
} else {
|
} else {
|
||||||
callback.accept(false, "Failed to write some data to WAV file: $target")
|
callback.accept(false, "Failed to write some data to WAV file: $target")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -716,6 +716,7 @@ public interface Bass extends Library {
|
|||||||
boolean BASS_SampleStop(int handle);
|
boolean BASS_SampleStop(int handle);
|
||||||
|
|
||||||
int BASS_StreamCreate(int freq, int chans, int flags, STREAMPROC proc, Pointer user);
|
int BASS_StreamCreate(int freq, int chans, int flags, STREAMPROC proc, Pointer user);
|
||||||
|
int BASS_StreamCreate(int freq, int chans, int flags, Pointer proc, Pointer user); // for STREAMPROC_DUMMY
|
||||||
int BASS_StreamCreateFile(boolean mem, String file, long offset, long length, int flags);
|
int BASS_StreamCreateFile(boolean mem, String file, long offset, long length, int flags);
|
||||||
int BASS_StreamCreateFile(Pointer file, long offset, long length, int flags);
|
int BASS_StreamCreateFile(Pointer file, long offset, long length, int flags);
|
||||||
int BASS_StreamCreateURL(String url, int offset, int flags, DOWNLOADPROC proc, Pointer user);
|
int BASS_StreamCreateURL(String url, int offset, int flags, DOWNLOADPROC proc, Pointer user);
|
||||||
@@ -785,8 +786,7 @@ public interface Bass extends Library {
|
|||||||
boolean BASS_FXGetParameters(int handle, Object params);
|
boolean BASS_FXGetParameters(int handle, Object params);
|
||||||
boolean BASS_FXSetPriority(int handle, int priority);
|
boolean BASS_FXSetPriority(int handle, int priority);
|
||||||
boolean BASS_FXReset(int handle);
|
boolean BASS_FXReset(int handle);
|
||||||
// gak bisa
|
|
||||||
int BASS_StreamCreate(int freq, int chans, int flags, int proc, Pointer user);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ class BarixConnection(val index: UInt, var channel: String, val ipaddress: Strin
|
|||||||
fun SendData(data: ByteArray, cbOK: Consumer<String>, cbFail: Consumer<String>) {
|
fun SendData(data: ByteArray, cbOK: Consumer<String>, cbFail: Consumer<String>) {
|
||||||
if (data.isNotEmpty()) {
|
if (data.isNotEmpty()) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
|
||||||
val bb = ByteBuffer.wrap(data)
|
val bb = ByteBuffer.wrap(data)
|
||||||
while(bb.hasRemaining()){
|
while(bb.hasRemaining()){
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -2,11 +2,13 @@ package codes
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode
|
import com.fasterxml.jackson.databind.JsonNode
|
||||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||||
|
import content.Language
|
||||||
import content.ScheduleDay
|
import content.ScheduleDay
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import org.tinylog.Logger
|
||||||
import oshi.SystemInfo
|
import oshi.SystemInfo
|
||||||
import oshi.hardware.CentralProcessor
|
import oshi.hardware.CentralProcessor
|
||||||
import oshi.hardware.GlobalMemory
|
import oshi.hardware.GlobalMemory
|
||||||
@@ -22,8 +24,18 @@ import kotlin.io.path.name
|
|||||||
class Somecodes {
|
class Somecodes {
|
||||||
companion object {
|
companion object {
|
||||||
val current_directory : String = System.getProperty("user.dir")
|
val current_directory : String = System.getProperty("user.dir")
|
||||||
|
val Soundbank_directory : Path = Path.of(current_directory,"Soundbank")
|
||||||
|
val Soundbank_Languages_directory : List<Path> = listOf(
|
||||||
|
Soundbank_directory.resolve(Language.INDONESIA.name),
|
||||||
|
Soundbank_directory.resolve(Language.LOCAL.name),
|
||||||
|
Soundbank_directory.resolve(Language.ENGLISH.name),
|
||||||
|
Soundbank_directory.resolve(Language.CHINESE.name),
|
||||||
|
Soundbank_directory.resolve(Language.JAPANESE.name),
|
||||||
|
Soundbank_directory.resolve(Language.ARABIC.name)
|
||||||
|
)
|
||||||
val SoundbankResult_directory : Path = Path.of(current_directory,"SoundbankResult")
|
val SoundbankResult_directory : Path = Path.of(current_directory,"SoundbankResult")
|
||||||
val PagingResult_directory : Path = Path.of(current_directory,"PagingResult")
|
val PagingResult_directory : Path = Path.of(current_directory,"PagingResult")
|
||||||
|
|
||||||
val si = SystemInfo()
|
val si = SystemInfo()
|
||||||
val processor: CentralProcessor = si.hardware.processor
|
val processor: CentralProcessor = si.hardware.processor
|
||||||
val memory : GlobalMemory = si.hardware.memory
|
val memory : GlobalMemory = si.hardware.memory
|
||||||
@@ -42,6 +54,39 @@ class Somecodes {
|
|||||||
// regex for getting ann_id from Message, which is the number inside []
|
// regex for getting ann_id from Message, which is the number inside []
|
||||||
private val ann_id_regex = Regex("\\[(\\d+)]")
|
private val ann_id_regex = Regex("\\[(\\d+)]")
|
||||||
|
|
||||||
|
fun ExtractFilesFromClassPath(resourcePath: String, outputDir: Path) {
|
||||||
|
try {
|
||||||
|
val resource = Somecodes::class.java.getResource(resourcePath)
|
||||||
|
if (resource != null) {
|
||||||
|
val uri = resource.toURI()
|
||||||
|
val path = if (uri.scheme == "jar") {
|
||||||
|
val fileSystem = java.nio.file.FileSystems.newFileSystem(uri, emptyMap<String, Any>())
|
||||||
|
fileSystem.getPath(resourcePath)
|
||||||
|
} else {
|
||||||
|
Path.of(uri)
|
||||||
|
}
|
||||||
|
|
||||||
|
Files.walk(path).use { stream ->
|
||||||
|
stream.forEach { sourcePath ->
|
||||||
|
if (Files.isRegularFile(sourcePath)) {
|
||||||
|
val fn = sourcePath.fileName
|
||||||
|
val targetPath = outputDir.resolve(fn)
|
||||||
|
if (Files.isRegularFile(targetPath) && Files.size(targetPath) > 0) {
|
||||||
|
Logger.info { "File $targetPath already exists, skipping extraction." }
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
Files.copy(sourcePath, targetPath)
|
||||||
|
Logger.info { "Extracted ${sourcePath.name} to $targetPath" }
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else Logger.error { "Resource $resource not found" }
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Logger.error { "Exception while extracting $resourcePath, Message = ${e.message}"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a string is a valid number.
|
* Check if a string is a valid number.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user