v3 41 - Adjusting collection and title extract

This commit is contained in:
bskjon 2024-07-21 02:57:42 +02:00
parent d67e40180d
commit 015052b97c
4 changed files with 57 additions and 30 deletions

View File

@ -4,7 +4,6 @@ import com.google.gson.JsonObject
import no.iktdev.eventi.core.ConsumableEvent import no.iktdev.eventi.core.ConsumableEvent
import no.iktdev.eventi.core.WGson import no.iktdev.eventi.core.WGson
import no.iktdev.eventi.data.EventStatus import no.iktdev.eventi.data.EventStatus
import no.iktdev.eventi.implementations.EventCoordinator
import no.iktdev.exfl.using import no.iktdev.exfl.using
import no.iktdev.mediaprocessing.coordinator.Coordinator import no.iktdev.mediaprocessing.coordinator.Coordinator
import no.iktdev.mediaprocessing.coordinator.CoordinatorEventListener import no.iktdev.mediaprocessing.coordinator.CoordinatorEventListener
@ -13,9 +12,8 @@ import no.iktdev.mediaprocessing.shared.common.SharedConfig
import no.iktdev.mediaprocessing.shared.common.parsing.FileNameDeterminate import no.iktdev.mediaprocessing.shared.common.parsing.FileNameDeterminate
import no.iktdev.mediaprocessing.shared.common.parsing.NameHelper import no.iktdev.mediaprocessing.shared.common.parsing.NameHelper
import no.iktdev.mediaprocessing.shared.common.parsing.Regexes import no.iktdev.mediaprocessing.shared.common.parsing.Regexes
import no.iktdev.mediaprocessing.shared.common.parsing.isCharOnlyUpperCase
import no.iktdev.mediaprocessing.shared.contract.Events import no.iktdev.mediaprocessing.shared.contract.Events
import no.iktdev.mediaprocessing.shared.contract.EventsListenerContract
import no.iktdev.mediaprocessing.shared.contract.EventsManagerContract
import no.iktdev.mediaprocessing.shared.contract.data.* import no.iktdev.mediaprocessing.shared.contract.data.*
import no.iktdev.mediaprocessing.shared.contract.data.EpisodeInfo import no.iktdev.mediaprocessing.shared.contract.data.EpisodeInfo
import no.iktdev.mediaprocessing.shared.contract.data.MovieInfo import no.iktdev.mediaprocessing.shared.contract.data.MovieInfo
@ -23,6 +21,7 @@ import no.iktdev.mediaprocessing.shared.contract.data.pyMetadata
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.FileFilter import java.io.FileFilter
import javax.naming.Name
@Service @Service
@ -96,45 +95,61 @@ class MediaOutInformationTaskListener: CoordinatorEventListener() {
metadata?.altTitle?.let { titles.addAll(it) } metadata?.altTitle?.let { titles.addAll(it) }
return titles return titles
} }
fun getExistingCollections() = fun getExistingCollections() = SharedConfig.outgoingContent.listFiles(FileFilter { it.isDirectory })?.map { it.name } ?: emptyList()
SharedConfig.outgoingContent.listFiles(FileFilter { it.isDirectory })?.map { it.name } ?: emptyList()
fun getAlreadyUsedForCollectionOrTitle(): String { fun getUsedCollectionForTitleOrNull(): String? {
val exisiting = getExistingCollections() val exisiting = getExistingCollections()
if (exisiting.isEmpty()) {
return null
}
val existingMatch = exisiting.find { it.lowercase().contains(baseInfo.title.lowercase()) } val existingMatch = exisiting.find { it.lowercase().contains(baseInfo.title.lowercase()) }
if (existingMatch != null) {
return existingMatch return existingMatch
} }
val metaTitles = getTitlesFromMetadata() fun getCollection(): String {
val existingMatchOnMeta = metaTitles.find { it.lowercase().contains(baseInfo.title.lowercase()) } val usedCollection = getUsedCollectionForTitleOrNull()
if (usedCollection != null) {
return usedCollection
return existingMatchOnMeta
?: (getTitlesFromMetadata().firstOrNull { it in exisiting } ?: getTitlesFromMetadata().firstOrNull()
?: baseInfo.title)
} }
fun getCollection(): String { val metaTitles = getTitlesFromMetadata()
val title = getAlreadyUsedForCollectionOrTitle()?: metadata?.title ?: baseInfo.title val existingCollection = getExistingCollections()
var cleaned = Regexes.illegalCharacters.replace(title, " - ") val ecList = existingCollection.filter { ec -> metaTitles.any { it.lowercase().contains(ec.lowercase() )} }
cleaned = Regexes.trimWhiteSpaces.replace(cleaned, " ") if (ecList.isNotEmpty()) {
return cleaned return ecList.first()
}
val existingMatchOnMeta = metaTitles.find { it.lowercase().contains(baseInfo.title.lowercase()) && !it.isCharOnlyUpperCase() }
return NameHelper.cleanup((existingMatchOnMeta ?: baseInfo.title))
} }
fun getTitle(): String { fun getTitle(): String {
val metaTitles = getTitlesFromMetadata() val metaTitles = getTitlesFromMetadata()
val metaTitle = metaTitles.filter { it.contains(baseInfo.title) || NameHelper.normalize(it).contains(baseInfo.title) } val collection = getCollection()
val title = metaTitle.firstOrNull() ?: metaTitles.firstOrNull() ?: baseInfo.title
var cleaned = Regexes.illegalCharacters.replace(title, " - ") val filteredMetaTitles = metaTitles.filter { it.lowercase().contains(baseInfo.title.lowercase()) || NameHelper.normalize(it).lowercase().contains(baseInfo.title.lowercase()) }
cleaned = Regexes.trimWhiteSpaces.replace(cleaned, " ")
return cleaned //val viableFileTitles = filteredMetaTitles.filter { !it.isCharOnlyUpperCase() }
return if (collection == baseInfo.title) {
collection
} else {
NameHelper.cleanup (filteredMetaTitles.firstOrNull() ?: baseInfo.title)
}
} }
fun getVideoPayload(): JsonObject? { fun getVideoPayload(): JsonObject? {
val defaultFnd = FileNameDeterminate(getTitle(), baseInfo.sanitizedName, FileNameDeterminate.ContentType.UNDEFINED) val defaultFnd = FileNameDeterminate(getTitle(), baseInfo.sanitizedName, FileNameDeterminate.ContentType.UNDEFINED)
val determinedContentType = defaultFnd.getDeterminedVideoInfo().let { if (it is EpisodeInfo) FileNameDeterminate.ContentType.SERIE else if (it is MovieInfo) FileNameDeterminate.ContentType.MOVIE else FileNameDeterminate.ContentType.UNDEFINED } val determinedContentType = defaultFnd.getDeterminedVideoInfo()
.let {
when (it) {
is EpisodeInfo -> FileNameDeterminate.ContentType.SERIE
is MovieInfo -> FileNameDeterminate.ContentType.MOVIE
else -> FileNameDeterminate.ContentType.UNDEFINED
}
}
return if (determinedContentType == metadataDeterminedContentType && determinedContentType == FileNameDeterminate.ContentType.MOVIE) { return if (determinedContentType == metadataDeterminedContentType && determinedContentType == FileNameDeterminate.ContentType.MOVIE) {
FileNameDeterminate(getTitle(), getTitle(), FileNameDeterminate.ContentType.MOVIE).getDeterminedVideoInfo()?.toJsonObject() FileNameDeterminate(getTitle(), getTitle(), FileNameDeterminate.ContentType.MOVIE).getDeterminedVideoInfo()?.toJsonObject()
} else { } else {

View File

@ -5,7 +5,7 @@ import no.iktdev.mediaprocessing.shared.contract.data.MediaInfo
import no.iktdev.mediaprocessing.shared.contract.data.MovieInfo import no.iktdev.mediaprocessing.shared.contract.data.MovieInfo
class FileNameDeterminate(val title: String, val sanitizedName: String, val ctype: ContentType = ContentType.UNDEFINED, val metaTitle: String? = null) { class FileNameDeterminate(val title: String, val sanitizedName: String, val ctype: ContentType = ContentType.UNDEFINED) {
enum class ContentType { enum class ContentType {
MOVIE, MOVIE,
@ -29,7 +29,7 @@ class FileNameDeterminate(val title: String, val sanitizedName: String, val ctyp
else -> sanitizedName else -> sanitizedName
} }
val nonResolutioned = movieEx.removeResolutionAndBeyond(stripped) ?: stripped val nonResolutioned = movieEx.removeResolutionAndBeyond(stripped) ?: stripped
return MovieInfo(title = metaTitle ?: cleanup(nonResolutioned), fullName = cleanup(nonResolutioned)) return MovieInfo(title = cleanup(nonResolutioned), fullName = cleanup(nonResolutioned))
} }
private fun determineSerieFileName(): EpisodeInfo? { private fun determineSerieFileName(): EpisodeInfo? {
@ -58,7 +58,7 @@ class FileNameDeterminate(val title: String, val sanitizedName: String, val ctyp
} }
} else title } else title
val fullName = "${useTitle.trim()} - $seasonEpisodeCombined ${if (episodeTitle.isNullOrEmpty()) "" else " - $episodeTitle"}".trim() val fullName = "${useTitle.trim()} - $seasonEpisodeCombined ${if (episodeTitle.isNullOrEmpty()) "" else " - $episodeTitle"}".trim()
return EpisodeInfo(title = metaTitle ?: title, episode = episodeNumber.toInt(), season = seasonNumber.toInt(), episodeTitle = episodeTitle, fullName = cleanup(fullName)) return EpisodeInfo(title = title, episode = episodeNumber.toInt(), season = seasonNumber.toInt(), episodeTitle = episodeTitle, fullName = cleanup(fullName))
} }
private fun determineUndefinedFileName(): MediaInfo? { private fun determineUndefinedFileName(): MediaInfo? {

View File

@ -10,4 +10,15 @@ object NameHelper {
val cleaned = "[^A-Za-z0-9 -]".toRegex().replace(result, "") val cleaned = "[^A-Za-z0-9 -]".toRegex().replace(result, "")
return StringUtils.stripAccents(cleaned) return StringUtils.stripAccents(cleaned)
} }
fun cleanup(input: String): String {
var cleaned = Regex("(?<=\\w)[_.](?=\\w)").replace(input, " ")
cleaned = Regexes.illegalCharacters.replace(cleaned, " - ")
cleaned = Regexes.trimWhiteSpaces.replace(cleaned, " ")
return NameHelper.normalize(cleaned)
}
}
fun String.isCharOnlyUpperCase(): Boolean {
return "[^A-Za-z]".toRegex().replace(this, "").all { it.isUpperCase() }
} }

View File

@ -12,6 +12,7 @@ enum class Events(val event: String) {
EventMediaParameterEncodeCreated ("event:media-encode-parameter:created"), EventMediaParameterEncodeCreated ("event:media-encode-parameter:created"),
EventMediaParameterExtractCreated ("event:media-extract-parameter:created"), EventMediaParameterExtractCreated ("event:media-extract-parameter:created"),
EventMediaParameterDownloadCoverCreated ("event:media-download-cover-parameter:created"), EventMediaParameterDownloadCoverCreated ("event:media-download-cover-parameter:created"),
EventMediaWorkProceedPermitted ("event:media-work-proceed:permitted"), EventMediaWorkProceedPermitted ("event:media-work-proceed:permitted"),