Updated version + Naming parsing
This commit is contained in:
parent
b1061b3c9e
commit
35d4299e74
1
.idea/gradle.xml
generated
1
.idea/gradle.xml
generated
@ -5,6 +5,7 @@
|
|||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<GradleProjectSettings>
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="gradleJvm" value="17" />
|
||||||
<option name="modules">
|
<option name="modules">
|
||||||
<set>
|
<set>
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
|
|||||||
2
.idea/kotlinc.xml
generated
2
.idea/kotlinc.xml
generated
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="KotlinJpsPluginSettings">
|
<component name="KotlinJpsPluginSettings">
|
||||||
<option name="version" value="1.9.20" />
|
<option name="version" value="2.1.0" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
26
.idea/runConfigurations/UIApplicationKt.xml
generated
Normal file
26
.idea/runConfigurations/UIApplicationKt.xml
generated
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="UIApplicationKt" type="JetRunConfigurationType" nameIsGenerated="true">
|
||||||
|
<envs>
|
||||||
|
<env name="DATABASE_ADDRESS" value="192.168.2.250" />
|
||||||
|
<env name="DATABASE_NAME_E" value="eventsV4" />
|
||||||
|
<env name="DATABASE_NAME_S" value="streamitv3" />
|
||||||
|
<env name="DATABASE_PASSWORD" value="shFZ27eL2x2NoxyEDBMfDWkvFO" />
|
||||||
|
<env name="DATABASE_PORT" value="3306" />
|
||||||
|
<env name="DATABASE_USERNAME" value="root" />
|
||||||
|
<env name="DIRECTORY_CONTENT_INCOMING" value="G:\MediaProcessingPlayground\input" />
|
||||||
|
<env name="DIRECTORY_CONTENT_OUTGOING" value="G:\MediaProcessingPlayground\output" />
|
||||||
|
<env name="DISABLE_COMPLETE" value="true" />
|
||||||
|
<env name="DISABLE_PRODUCE" value="true" />
|
||||||
|
<env name="EncoderWs" value="ws://192.168.2.250:6081/ws" />
|
||||||
|
<env name="METADATA_TIMEOUT" value="0" />
|
||||||
|
<env name="SUPPORTING_EXECUTABLE_FFMPEG" value="G:\MediaProcessingPlayground\ffmpeg.exe" />
|
||||||
|
<env name="SUPPORTING_EXECUTABLE_FFPROBE" value="G:\MediaProcessingPlayground\ffprobe.exe" />
|
||||||
|
</envs>
|
||||||
|
<option name="MAIN_CLASS_NAME" value="no.iktdev.mediaprocessing.ui.UIApplicationKt" />
|
||||||
|
<module name="MediaProcessing.apps.ui.main" />
|
||||||
|
<shortenClasspath name="NONE" />
|
||||||
|
<method v="2">
|
||||||
|
<option name="Make" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
1198
.idea/workspace.xml
generated
1198
.idea/workspace.xml
generated
File diff suppressed because it is too large
Load Diff
@ -2,8 +2,8 @@ plugins {
|
|||||||
id("java")
|
id("java")
|
||||||
kotlin("jvm")
|
kotlin("jvm")
|
||||||
kotlin("plugin.spring") version "1.5.31"
|
kotlin("plugin.spring") version "1.5.31"
|
||||||
id("org.springframework.boot") version "2.5.5"
|
id("org.springframework.boot") version "3.2.0"
|
||||||
id("io.spring.dependency-management") version "1.0.11.RELEASE"
|
id("io.spring.dependency-management") version "1.1.4"
|
||||||
id("org.jetbrains.kotlin.plugin.serialization") version "1.5.0" // Legg til Kotlin Serialization-plugin
|
id("org.jetbrains.kotlin.plugin.serialization") version "1.5.0" // Legg til Kotlin Serialization-plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,18 +26,19 @@ val exposedVersion = "0.44.0"
|
|||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
/*Spring boot*/
|
/*Spring boot*/
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter")
|
||||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||||
implementation("org.springframework.boot:spring-boot-starter:3.2.0")
|
implementation("org.springframework.boot:spring-boot-starter-actuator")
|
||||||
// implementation("org.springframework.kafka:spring-kafka:3.0.1")
|
implementation("org.springframework.boot:spring-boot-starter-websocket")
|
||||||
implementation("org.springframework.kafka:spring-kafka:2.8.5")
|
implementation("org.springframework:spring-tx")
|
||||||
implementation("org.springframework.boot:spring-boot-starter-websocket:2.6.3")
|
|
||||||
|
|
||||||
implementation("io.github.microutils:kotlin-logging-jvm:2.0.11")
|
implementation("io.github.microutils:kotlin-logging-jvm:2.0.11")
|
||||||
implementation("com.google.code.gson:gson:2.8.9")
|
implementation("com.google.code.gson:gson:2.8.9")
|
||||||
implementation("org.json:json:20210307")
|
implementation("org.json:json:20210307")
|
||||||
|
|
||||||
implementation("no.iktdev:exfl:0.0.16-SNAPSHOT")
|
implementation("no.iktdev:exfl:0.0.16-SNAPSHOT")
|
||||||
implementation("no.iktdev.streamit.library:streamit-library-db:1.0.0-alpha14")
|
implementation("no.iktdev.streamit.library:streamit-library-db:1.0-rc1")
|
||||||
|
|
||||||
|
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1")
|
||||||
@ -71,16 +72,6 @@ dependencies {
|
|||||||
testImplementation("org.mockito:mockito-core:3.+")
|
testImplementation("org.mockito:mockito-core:3.+")
|
||||||
testImplementation("org.assertj:assertj-core:3.4.1")
|
testImplementation("org.assertj:assertj-core:3.4.1")
|
||||||
|
|
||||||
/*testImplementation("org.junit.vintage:junit-vintage-engine")
|
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter:5.10.1")
|
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter-params:5.8.1")
|
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.1")
|
|
||||||
testRuntimeOnly ("org.junit.jupiter:junit-jupiter-engine:5.10.1")
|
|
||||||
testImplementation("org.mockito:mockito-core:5.8.0") // Oppdater versjonen hvis det er nyere tilgjengelig
|
|
||||||
testImplementation("org.mockito:mockito-junit-jupiter:5.8.0")
|
|
||||||
testImplementation(platform("org.junit:junit-bom:5.10.1"))
|
|
||||||
testImplementation("org.junit.platform:junit-platform-runner:1.10.1")*/
|
|
||||||
|
|
||||||
testImplementation(platform("org.junit:junit-bom:5.9.1"))
|
testImplementation(platform("org.junit:junit-bom:5.9.1"))
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter")
|
testImplementation("org.junit.jupiter:junit-jupiter")
|
||||||
testImplementation("junit:junit:4.13.2")
|
testImplementation("junit:junit:4.13.2")
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package no.iktdev.mediaprocessing.coordinator
|
package no.iktdev.mediaprocessing.coordinator
|
||||||
|
|
||||||
|
|
||||||
|
import jakarta.annotation.PreDestroy
|
||||||
import mu.KotlinLogging
|
import mu.KotlinLogging
|
||||||
import no.iktdev.exfl.coroutines.CoroutinesDefault
|
import no.iktdev.exfl.coroutines.CoroutinesDefault
|
||||||
import no.iktdev.exfl.coroutines.CoroutinesIO
|
import no.iktdev.exfl.coroutines.CoroutinesIO
|
||||||
@ -10,15 +11,22 @@ import no.iktdev.eventi.database.MySqlDataSource
|
|||||||
import no.iktdev.mediaprocessing.shared.common.database.cal.EventsManager
|
import no.iktdev.mediaprocessing.shared.common.database.cal.EventsManager
|
||||||
import no.iktdev.mediaprocessing.shared.common.database.cal.RunnerManager
|
import no.iktdev.mediaprocessing.shared.common.database.cal.RunnerManager
|
||||||
import no.iktdev.mediaprocessing.shared.common.database.cal.TasksManager
|
import no.iktdev.mediaprocessing.shared.common.database.cal.TasksManager
|
||||||
import no.iktdev.streamit.library.db.tables.*
|
import no.iktdev.streamit.library.db.tables.content.CatalogTable
|
||||||
import no.iktdev.streamit.library.db.tables.helper.cast_errors
|
import no.iktdev.streamit.library.db.tables.content.GenreTable
|
||||||
import no.iktdev.streamit.library.db.tables.helper.data_audio
|
import no.iktdev.streamit.library.db.tables.content.MovieTable
|
||||||
import no.iktdev.streamit.library.db.tables.helper.data_video
|
import no.iktdev.streamit.library.db.tables.content.ProgressTable
|
||||||
|
import no.iktdev.streamit.library.db.tables.content.SerieTable
|
||||||
|
import no.iktdev.streamit.library.db.tables.content.SubtitleTable
|
||||||
|
import no.iktdev.streamit.library.db.tables.content.SummaryTable
|
||||||
|
import no.iktdev.streamit.library.db.tables.content.TitleTable
|
||||||
|
import no.iktdev.streamit.library.db.tables.other.CastErrorTable
|
||||||
|
import no.iktdev.streamit.library.db.tables.other.DataAudioTable
|
||||||
|
import no.iktdev.streamit.library.db.tables.other.DataVideoTable
|
||||||
|
import no.iktdev.streamit.library.db.tables.user.UserTable
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||||
import org.springframework.boot.runApplication
|
import org.springframework.boot.runApplication
|
||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.transaction.annotation.Transactional
|
import org.springframework.transaction.annotation.Transactional
|
||||||
import javax.annotation.PreDestroy
|
|
||||||
|
|
||||||
val log = KotlinLogging.logger {}
|
val log = KotlinLogging.logger {}
|
||||||
lateinit var eventDatabase: EventsDatabase
|
lateinit var eventDatabase: EventsDatabase
|
||||||
@ -101,18 +109,18 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
|
|
||||||
val tables = arrayOf(
|
val tables = arrayOf(
|
||||||
catalog,
|
CatalogTable,
|
||||||
genre,
|
GenreTable,
|
||||||
movie,
|
MovieTable,
|
||||||
serie,
|
SerieTable,
|
||||||
subtitle,
|
SubtitleTable,
|
||||||
summary,
|
SummaryTable,
|
||||||
users,
|
UserTable,
|
||||||
progress,
|
ProgressTable,
|
||||||
data_audio,
|
DataAudioTable,
|
||||||
data_video,
|
DataVideoTable,
|
||||||
cast_errors,
|
CastErrorTable,
|
||||||
titles
|
TitleTable
|
||||||
)
|
)
|
||||||
storeDatabase.createTables(*tables)
|
storeDatabase.createTables(*tables)
|
||||||
|
|
||||||
|
|||||||
@ -7,16 +7,10 @@ import no.iktdev.mediaprocessing.shared.common.SharedConfig
|
|||||||
import no.iktdev.mediaprocessing.shared.common.database.tables.files
|
import no.iktdev.mediaprocessing.shared.common.database.tables.files
|
||||||
import no.iktdev.mediaprocessing.shared.common.extended.isSupportedVideoFile
|
import no.iktdev.mediaprocessing.shared.common.extended.isSupportedVideoFile
|
||||||
import no.iktdev.mediaprocessing.shared.common.md5
|
import no.iktdev.mediaprocessing.shared.common.md5
|
||||||
import no.iktdev.streamit.library.db.withTransaction
|
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
|
||||||
import org.jetbrains.exposed.sql.deleteWhere
|
|
||||||
import org.jetbrains.exposed.sql.insertIgnore
|
import org.jetbrains.exposed.sql.insertIgnore
|
||||||
import org.jetbrains.exposed.sql.select
|
|
||||||
import org.jetbrains.exposed.sql.selectAll
|
|
||||||
import org.springframework.scheduling.annotation.EnableScheduling
|
import org.springframework.scheduling.annotation.EnableScheduling
|
||||||
import org.springframework.scheduling.annotation.Scheduled
|
import org.springframework.scheduling.annotation.Scheduled
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@EnableScheduling
|
@EnableScheduling
|
||||||
|
|||||||
@ -6,9 +6,9 @@ import no.iktdev.mediaprocessing.coordinator.getStoreDatabase
|
|||||||
import no.iktdev.mediaprocessing.shared.common.contract.reader.VideoDetails
|
import no.iktdev.mediaprocessing.shared.common.contract.reader.VideoDetails
|
||||||
import no.iktdev.streamit.library.db.executeWithStatus
|
import no.iktdev.streamit.library.db.executeWithStatus
|
||||||
import no.iktdev.streamit.library.db.insertWithSuccess
|
import no.iktdev.streamit.library.db.insertWithSuccess
|
||||||
import no.iktdev.streamit.library.db.query.MovieQuery
|
import no.iktdev.streamit.library.db.tables.content.CatalogTable
|
||||||
import no.iktdev.streamit.library.db.tables.catalog
|
import no.iktdev.streamit.library.db.tables.content.MovieTable
|
||||||
import no.iktdev.streamit.library.db.tables.serie
|
import no.iktdev.streamit.library.db.tables.content.SerieTable
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
|
|
||||||
object ContentCatalogStore {
|
object ContentCatalogStore {
|
||||||
@ -20,56 +20,56 @@ object ContentCatalogStore {
|
|||||||
*/
|
*/
|
||||||
fun getCollectionByTitleAndType(type: String, titles: List<String>): String? {
|
fun getCollectionByTitleAndType(type: String, titles: List<String>): String? {
|
||||||
return withTransaction(getStoreDatabase()) {
|
return withTransaction(getStoreDatabase()) {
|
||||||
catalog.select {
|
CatalogTable.select {
|
||||||
(catalog.type eq type) and
|
(CatalogTable.type eq type) and
|
||||||
((catalog.title inList titles) or
|
((CatalogTable.title inList titles) or
|
||||||
(catalog.collection inList titles))
|
(CatalogTable.collection inList titles))
|
||||||
}.map {
|
}.map {
|
||||||
it[catalog.collection]
|
it[CatalogTable.collection]
|
||||||
}.firstOrNull()
|
}.firstOrNull()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getCover(collection: String, type: String): String? {
|
private fun getCover(collection: String, type: String): String? {
|
||||||
return withTransaction(getStoreDatabase()) {
|
return withTransaction(getStoreDatabase()) {
|
||||||
catalog.select {
|
CatalogTable.select {
|
||||||
(catalog.collection eq collection) and
|
(CatalogTable.collection eq collection) and
|
||||||
(catalog.type eq type)
|
(CatalogTable.type eq type)
|
||||||
}.map { it[catalog.cover] }.firstOrNull()
|
}.map { it[CatalogTable.cover] }.firstOrNull()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun storeCatalog(title: String, titles: List<String>, collection: String, type: String, cover: String?, genres: String?): Int? {
|
fun storeCatalog(title: String, titles: List<String>, collection: String, type: String, cover: String?, genres: String?): Int? {
|
||||||
val status = executeWithStatus(getStoreDatabase().database, block = {
|
val status = executeWithStatus(getStoreDatabase().database, run = {
|
||||||
val existingRow = catalog.select {
|
val existingRow = CatalogTable.select {
|
||||||
(catalog.collection eq collection) and
|
(CatalogTable.collection eq collection) and
|
||||||
(catalog.type eq type)
|
(CatalogTable.type eq type)
|
||||||
}.firstOrNull()
|
}.firstOrNull()
|
||||||
|
|
||||||
if (existingRow == null) {
|
if (existingRow == null) {
|
||||||
log.info { "$collection does not exist, and will be created" }
|
log.info { "$collection does not exist, and will be created" }
|
||||||
catalog.insert {
|
CatalogTable.insert {
|
||||||
it[catalog.title] = title
|
it[CatalogTable.title] = title
|
||||||
it[catalog.cover] = cover
|
it[CatalogTable.cover] = cover
|
||||||
it[catalog.type] = type
|
it[CatalogTable.type] = type
|
||||||
it[catalog.collection] = collection
|
it[CatalogTable.collection] = collection
|
||||||
it[catalog.genres] = genres
|
it[CatalogTable.genres] = genres
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val id = existingRow[catalog.id]
|
val id = existingRow[CatalogTable.id]
|
||||||
val storedTitle = existingRow[catalog.title]
|
val storedTitle = existingRow[CatalogTable.title]
|
||||||
val useCover = existingRow[catalog.cover] ?: cover
|
val useCover = existingRow[CatalogTable.cover] ?: cover
|
||||||
val useGenres = existingRow[catalog.genres] ?: genres
|
val useGenres = existingRow[CatalogTable.genres] ?: genres
|
||||||
|
|
||||||
catalog.update({
|
CatalogTable.update({
|
||||||
(catalog.id eq id) and
|
(CatalogTable.id eq id) and
|
||||||
(catalog.collection eq collection)
|
(CatalogTable.collection eq collection)
|
||||||
}) {
|
}) {
|
||||||
it[catalog.cover] = useCover
|
it[CatalogTable.cover] = useCover
|
||||||
it[catalog.genres] = useGenres
|
it[CatalogTable.genres] = useGenres
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
}, onError = {
|
||||||
log.error { "Failed to store catalog $collection: ${it.message}" }
|
log.error { "Failed to store catalog $collection: ${it.message}" }
|
||||||
})
|
})
|
||||||
if (status) {
|
if (status) {
|
||||||
@ -81,17 +81,17 @@ object ContentCatalogStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun storeMovie(catalogId: Int, videoDetails: VideoDetails) {
|
private fun storeMovie(catalogId: Int, videoDetails: VideoDetails) {
|
||||||
val iid = MovieQuery(videoDetails.fileName).insertAndGetId() ?: run {
|
val iid = MovieTable.insertAndGetId(videoDetails.fileName)?.value ?: run {
|
||||||
log.error { "Movie id was not returned!" }
|
log.error { "Movie id was not returned!" }
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val status = executeWithStatus(getStoreDatabase().database, block = {
|
val status = executeWithStatus(getStoreDatabase().database, run = {
|
||||||
catalog.update({
|
CatalogTable.update({
|
||||||
(catalog.id eq catalogId)
|
(CatalogTable.id eq catalogId)
|
||||||
}) {
|
}) {
|
||||||
it[catalog.iid] = iid
|
it[CatalogTable.iid] = iid
|
||||||
}
|
}
|
||||||
}, {
|
}, onError = {
|
||||||
log.error { "Failed to store movie ${videoDetails.fileName}: ${it.message}" }
|
log.error { "Failed to store movie ${videoDetails.fileName}: ${it.message}" }
|
||||||
})
|
})
|
||||||
if (status) {
|
if (status) {
|
||||||
@ -107,28 +107,28 @@ object ContentCatalogStore {
|
|||||||
log.error { "serieInfo in videoDetails is null!" }
|
log.error { "serieInfo in videoDetails is null!" }
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val status = insertWithSuccess(getStoreDatabase().database, block = {
|
val status = insertWithSuccess(getStoreDatabase().database, run = {
|
||||||
serie.insert {
|
SerieTable.insert {
|
||||||
it[title] = serieInfo.episodeTitle
|
it[title] = serieInfo.episodeTitle
|
||||||
it[episode] = serieInfo.episodeNumber
|
it[episode] = serieInfo.episodeNumber
|
||||||
it[season] = serieInfo.seasonNumber
|
it[season] = serieInfo.seasonNumber
|
||||||
it[video] = videoDetails.fileName
|
it[video] = videoDetails.fileName
|
||||||
it[serie.collection] = collection
|
it[SerieTable.collection] = collection
|
||||||
}
|
}
|
||||||
}, onError = {
|
}, onError = {
|
||||||
log.error { "Failed to store serie ${videoDetails.fileName}: ${it.message}" }
|
log.error { "Failed to store serie ${videoDetails.fileName}: ${it.message}" }
|
||||||
})
|
})
|
||||||
if (!status) {
|
if (!status) {
|
||||||
log.error { "Failed to insert ${videoDetails.fileName} with episode: ${serieInfo.episodeNumber} and season ${serieInfo.seasonNumber}" }
|
log.error { "Failed to insert ${videoDetails.fileName} with episode: ${serieInfo.episodeNumber} and season ${serieInfo.seasonNumber}" }
|
||||||
val finalStatus = insertWithSuccess(getStoreDatabase().database, block = {
|
val finalStatus = insertWithSuccess(getStoreDatabase().database, run = {
|
||||||
serie.insert {
|
SerieTable.insert {
|
||||||
it[title] = serieInfo.episodeTitle
|
it[title] = serieInfo.episodeTitle
|
||||||
it[episode] = serieInfo.episodeNumber
|
it[episode] = serieInfo.episodeNumber
|
||||||
it[season] = 0
|
it[season] = 0
|
||||||
it[video] = videoDetails.fileName
|
it[video] = videoDetails.fileName
|
||||||
it[serie.collection] = collection
|
it[SerieTable.collection] = collection
|
||||||
}
|
}
|
||||||
}, { log.error { "Failed to store serie: ${it.message}" } })
|
}, onError = { log.error { "Failed to store serie: ${it.message}" } })
|
||||||
if (!finalStatus) {
|
if (!finalStatus) {
|
||||||
log.error { "Failed to insert ${videoDetails.fileName} with fallback season 0" }
|
log.error { "Failed to insert ${videoDetails.fileName} with fallback season 0" }
|
||||||
} else {
|
} else {
|
||||||
@ -157,12 +157,12 @@ object ContentCatalogStore {
|
|||||||
|
|
||||||
private fun getId(title: String, titles: List<String>, collection: String, type: String): Int? {
|
private fun getId(title: String, titles: List<String>, collection: String, type: String): Int? {
|
||||||
val ids = withTransaction(getStoreDatabase().database) {
|
val ids = withTransaction(getStoreDatabase().database) {
|
||||||
catalog.select {
|
CatalogTable.select {
|
||||||
((catalog.title eq title)
|
((CatalogTable.title eq title)
|
||||||
or (catalog.collection eq collection)
|
or (CatalogTable.collection eq collection)
|
||||||
or (catalog.title inList titles)) and
|
or (CatalogTable.title inList titles)) and
|
||||||
(catalog.type eq type)
|
(CatalogTable.type eq type)
|
||||||
}.map { it[catalog.id].value }
|
}.map { it[CatalogTable.id].value }
|
||||||
} ?: run {
|
} ?: run {
|
||||||
log.warn { "No values found on $title with type $type" }
|
log.warn { "No values found on $title with type $type" }
|
||||||
return null
|
return null
|
||||||
|
|||||||
@ -2,15 +2,18 @@ package no.iktdev.mediaprocessing.coordinator.tasksV2.mapping.store
|
|||||||
|
|
||||||
import no.iktdev.eventi.database.withTransaction
|
import no.iktdev.eventi.database.withTransaction
|
||||||
import no.iktdev.mediaprocessing.coordinator.getStoreDatabase
|
import no.iktdev.mediaprocessing.coordinator.getStoreDatabase
|
||||||
import no.iktdev.streamit.library.db.query.GenreQuery
|
import no.iktdev.streamit.library.db.tables.content.GenreTable
|
||||||
|
import org.jetbrains.exposed.sql.insertIgnoreAndGetId
|
||||||
|
|
||||||
object ContentGenresStore {
|
object ContentGenresStore {
|
||||||
fun storeAndGetIds(genres: List<String>): String? {
|
fun storeAndGetIds(genres: List<String>): String? {
|
||||||
return try {
|
return try {
|
||||||
withTransaction(getStoreDatabase()) {
|
withTransaction(getStoreDatabase()) {
|
||||||
val gq = GenreQuery( *genres.toTypedArray() )
|
val receivedGenreIdMap = genres.associateWith { genreName ->
|
||||||
gq.insertAndGetIds()
|
GenreTable.insertIgnoreAndGetId { it[GenreTable.genre] = genreName }?.value
|
||||||
gq.getIds().joinToString(",")
|
}
|
||||||
|
receivedGenreIdMap.values.filterNotNull()
|
||||||
|
.joinToString(",")
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
|||||||
@ -3,17 +3,17 @@ package no.iktdev.mediaprocessing.coordinator.tasksV2.mapping.store
|
|||||||
import no.iktdev.mediaprocessing.coordinator.getStoreDatabase
|
import no.iktdev.mediaprocessing.coordinator.getStoreDatabase
|
||||||
import no.iktdev.mediaprocessing.shared.common.contract.reader.SummaryInfo
|
import no.iktdev.mediaprocessing.shared.common.contract.reader.SummaryInfo
|
||||||
import no.iktdev.streamit.library.db.executeOrException
|
import no.iktdev.streamit.library.db.executeOrException
|
||||||
import no.iktdev.streamit.library.db.query.SummaryQuery
|
import no.iktdev.streamit.library.db.tables.content.SummaryTable
|
||||||
|
|
||||||
object ContentMetadataStore {
|
object ContentMetadataStore {
|
||||||
|
|
||||||
fun storeSummary(catalogId: Int, summaryInfo: SummaryInfo) {
|
fun storeSummary(catalogId: Int, summaryInfo: SummaryInfo) {
|
||||||
val result = executeOrException(getStoreDatabase().database, block = {
|
val result = executeOrException(getStoreDatabase().database, run = {
|
||||||
SummaryQuery(
|
SummaryTable.insertIgnore(
|
||||||
cid = catalogId,
|
catalogId = catalogId,
|
||||||
language = summaryInfo.language,
|
language = summaryInfo.language,
|
||||||
description = summaryInfo.summary
|
content = summaryInfo.summary
|
||||||
).insert()
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3,8 +3,7 @@ package no.iktdev.mediaprocessing.coordinator.tasksV2.mapping.store
|
|||||||
import mu.KotlinLogging
|
import mu.KotlinLogging
|
||||||
import no.iktdev.mediaprocessing.coordinator.getStoreDatabase
|
import no.iktdev.mediaprocessing.coordinator.getStoreDatabase
|
||||||
import no.iktdev.streamit.library.db.executeWithStatus
|
import no.iktdev.streamit.library.db.executeWithStatus
|
||||||
import no.iktdev.streamit.library.db.query.SubtitleQuery
|
import no.iktdev.streamit.library.db.tables.content.SubtitleTable
|
||||||
import no.iktdev.streamit.library.db.tables.subtitle
|
|
||||||
import org.jetbrains.exposed.sql.insert
|
import org.jetbrains.exposed.sql.insert
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@ -12,8 +11,8 @@ object ContentSubtitleStore {
|
|||||||
val log = KotlinLogging.logger {}
|
val log = KotlinLogging.logger {}
|
||||||
|
|
||||||
fun storeSubtitles(collection: String, destinationFile: File): Boolean {
|
fun storeSubtitles(collection: String, destinationFile: File): Boolean {
|
||||||
return executeWithStatus (getStoreDatabase().database, block = {
|
return executeWithStatus (getStoreDatabase().database, run = {
|
||||||
subtitle.insert {
|
SubtitleTable.insert {
|
||||||
it[this.associatedWithVideo] = destinationFile.nameWithoutExtension
|
it[this.associatedWithVideo] = destinationFile.nameWithoutExtension
|
||||||
it[this.language] = destinationFile.parentFile.nameWithoutExtension
|
it[this.language] = destinationFile.parentFile.nameWithoutExtension
|
||||||
it[this.collection] = collection
|
it[this.collection] = collection
|
||||||
|
|||||||
@ -2,7 +2,7 @@ package no.iktdev.mediaprocessing.coordinator.tasksV2.mapping.store
|
|||||||
|
|
||||||
import no.iktdev.mediaprocessing.coordinator.getStoreDatabase
|
import no.iktdev.mediaprocessing.coordinator.getStoreDatabase
|
||||||
import no.iktdev.mediaprocessing.shared.common.parsing.NameHelper
|
import no.iktdev.mediaprocessing.shared.common.parsing.NameHelper
|
||||||
import no.iktdev.streamit.library.db.tables.titles
|
import no.iktdev.streamit.library.db.tables.content.TitleTable
|
||||||
import no.iktdev.streamit.library.db.withTransaction
|
import no.iktdev.streamit.library.db.withTransaction
|
||||||
import org.jetbrains.exposed.sql.insertIgnore
|
import org.jetbrains.exposed.sql.insertIgnore
|
||||||
import org.jetbrains.exposed.sql.or
|
import org.jetbrains.exposed.sql.or
|
||||||
@ -12,19 +12,17 @@ object ContentTitleStore {
|
|||||||
|
|
||||||
fun store(mainTitle: String, otherTitles: List<String>) {
|
fun store(mainTitle: String, otherTitles: List<String>) {
|
||||||
try {
|
try {
|
||||||
withTransaction(getStoreDatabase().database, block = {
|
withTransaction(getStoreDatabase().database, run = {
|
||||||
val titlesToUse = otherTitles + listOf(
|
val titlesToUse = otherTitles + listOf(
|
||||||
NameHelper.normalize(mainTitle)
|
NameHelper.normalize(mainTitle)
|
||||||
).filter { it != mainTitle }
|
).filter { it != mainTitle }
|
||||||
|
|
||||||
titlesToUse.forEach { t ->
|
titlesToUse.forEach { t ->
|
||||||
titles.insertIgnore {
|
TitleTable.insertIgnore {
|
||||||
it[masterTitle] = mainTitle
|
it[masterTitle] = mainTitle
|
||||||
it[alternativeTitle] = t
|
it[alternativeTitle] = t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
|
||||||
|
|
||||||
})
|
})
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
@ -32,15 +30,13 @@ object ContentTitleStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun findMasterTitles(titleList: List<String>): List<String> {
|
fun findMasterTitles(titleList: List<String>): List<String> {
|
||||||
return withTransaction(getStoreDatabase().database, block = {
|
return withTransaction(getStoreDatabase().database, run = {
|
||||||
titles.select {
|
TitleTable.select {
|
||||||
(titles.alternativeTitle inList titleList) or
|
(TitleTable.alternativeTitle inList titleList) or
|
||||||
(titles.masterTitle inList titleList)
|
(TitleTable.masterTitle inList titleList)
|
||||||
}.map {
|
}.map {
|
||||||
it[titles.masterTitle]
|
it[TitleTable.masterTitle]
|
||||||
}.distinctBy { it }
|
}.distinctBy { it }
|
||||||
}, {
|
|
||||||
|
|
||||||
}) ?: emptyList()
|
}) ?: emptyList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -18,16 +18,15 @@ object ProcessedFileStore {
|
|||||||
val checksum = getChecksum(inputFilePath)
|
val checksum = getChecksum(inputFilePath)
|
||||||
|
|
||||||
|
|
||||||
withTransaction(eventDatabase.database.database, block = {
|
withTransaction(eventDatabase.database.database, run = {
|
||||||
filesProcessed.insert {
|
filesProcessed.insert {
|
||||||
it[this.title] = title
|
it[this.title] = title
|
||||||
it[this.inputFile] = inputFilePath
|
it[this.inputFile] = inputFilePath
|
||||||
it[this.data] = Gson().toJson(summary)
|
it[this.data] = Gson().toJson(summary)
|
||||||
it[this.checksum] = checksum
|
it[this.checksum] = checksum
|
||||||
}
|
}
|
||||||
}) {
|
}, onError = {
|
||||||
it.printStackTrace()
|
it.printStackTrace()
|
||||||
}
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3,6 +3,7 @@ package no.iktdev.mediaprocessing.coordinator.watcher
|
|||||||
import dev.vishna.watchservice.KWatchEvent.Kind.Deleted
|
import dev.vishna.watchservice.KWatchEvent.Kind.Deleted
|
||||||
import dev.vishna.watchservice.KWatchEvent.Kind.Initialized
|
import dev.vishna.watchservice.KWatchEvent.Kind.Initialized
|
||||||
import dev.vishna.watchservice.asWatchChannel
|
import dev.vishna.watchservice.asWatchChannel
|
||||||
|
import jakarta.annotation.PreDestroy
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.channels.consumeEach
|
import kotlinx.coroutines.channels.consumeEach
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
@ -22,7 +23,6 @@ import org.jetbrains.exposed.sql.insertIgnore
|
|||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.annotation.PreDestroy
|
|
||||||
|
|
||||||
|
|
||||||
interface FileWatcherEvents {
|
interface FileWatcherEvents {
|
||||||
|
|||||||
@ -3,3 +3,6 @@ logging.level.org.apache.kafka=INFO
|
|||||||
logging.level.root=INFO
|
logging.level.root=INFO
|
||||||
logging.level.Exposed=OFF
|
logging.level.Exposed=OFF
|
||||||
logging.level.org.springframework.web.socket.config.WebSocketMessageBrokerStats = WARN
|
logging.level.org.springframework.web.socket.config.WebSocketMessageBrokerStats = WARN
|
||||||
|
management.endpoints.web.exposure.include=*
|
||||||
|
management.endpoint.health.show-details=always
|
||||||
|
management.endpoints.web.base-path=/actuator
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("java")
|
id("java")
|
||||||
kotlin("plugin.spring") version "1.5.31"
|
kotlin("plugin.spring") version "1.5.31"
|
||||||
kotlin("jvm") version "1.9.20"
|
kotlin("jvm") version "2.1.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "no.iktdev.mediaprocessing"
|
group = "no.iktdev.mediaprocessing"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("java")
|
id("java")
|
||||||
kotlin("jvm") version "1.9.20"
|
kotlin("jvm") version "2.1.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "no.iktdev.mediaprocessing"
|
group = "no.iktdev.mediaprocessing"
|
||||||
|
|||||||
@ -40,6 +40,7 @@ class FileNameParser(val fileName: String) {
|
|||||||
|
|
||||||
else -> cleanedFileName
|
else -> cleanedFileName
|
||||||
}.trim()
|
}.trim()
|
||||||
|
.replace(Regex("[-\\s]+$"), "") // fjern trailing "-" og whitespace
|
||||||
}
|
}
|
||||||
|
|
||||||
fun guessDesiredTitle(): String {
|
fun guessDesiredTitle(): String {
|
||||||
@ -52,6 +53,7 @@ class FileNameParser(val fileName: String) {
|
|||||||
} else desiredFileName
|
} else desiredFileName
|
||||||
result.trim()
|
result.trim()
|
||||||
}.trim('.', '-').trim()
|
}.trim('.', '-').trim()
|
||||||
|
.replace(Regex("[-\\s]+$"), "") // fjern trailing "-" og whitespace
|
||||||
}
|
}
|
||||||
|
|
||||||
fun guessSearchableTitle(): MutableList<String> {
|
fun guessSearchableTitle(): MutableList<String> {
|
||||||
|
|||||||
@ -77,8 +77,11 @@ abstract class EventCoordinator<T : EventImpl, E : EventsManagerImpl<T>> {
|
|||||||
|
|
||||||
private suspend fun onEventsReceived(events: List<T>): Boolean = coroutineScope {
|
private suspend fun onEventsReceived(events: List<T>): Boolean = coroutineScope {
|
||||||
val listeners = getListeners()
|
val listeners = getListeners()
|
||||||
|
log.debug("onEventsReceived called with ${events.size} events for referenceId: ${events.firstOrNull()?.referenceId() ?: "unknown"}")
|
||||||
events.forEach { event ->
|
events.forEach { event ->
|
||||||
|
log.debug { "Processing event: ${event.eventType} with referenceId: ${event.referenceId()}" }
|
||||||
listeners.forEach { listener ->
|
listeners.forEach { listener ->
|
||||||
|
log.debug { "Checking listener: ${listener::class.java.simpleName} for event: ${event.eventType}" }
|
||||||
if (listener.shouldIProcessAndHandleEvent(event, events)) {
|
if (listener.shouldIProcessAndHandleEvent(event, events)) {
|
||||||
val consumableEvent = ConsumableEvent(event)
|
val consumableEvent = ConsumableEvent(event)
|
||||||
listener.onEventsReceived(consumableEvent, events)
|
listener.onEventsReceived(consumableEvent, events)
|
||||||
@ -218,12 +221,13 @@ abstract class EventCoordinator<T : EventImpl, E : EventsManagerImpl<T>> {
|
|||||||
|
|
||||||
suspend fun waitForConditionOrTimeout(timeout: Long, condition: () -> Boolean) {
|
suspend fun waitForConditionOrTimeout(timeout: Long, condition: () -> Boolean) {
|
||||||
val startTime = System.currentTimeMillis()
|
val startTime = System.currentTimeMillis()
|
||||||
|
log.debug("Waiting for condition with timeout: $timeout ms")
|
||||||
try {
|
try {
|
||||||
withTimeout(timeout) {
|
withTimeout(timeout) {
|
||||||
while (!condition()) {
|
while (!condition()) {
|
||||||
delay(100)
|
delay(100)
|
||||||
if (System.currentTimeMillis() - startTime >= timeout) {
|
if (System.currentTimeMillis() - startTime >= timeout) {
|
||||||
|
log.debug("Condition not met within timeout: $timeout ms")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user