Пофиксил проблемы сборки

This commit is contained in:
skettiks
2026-05-21 14:57:41 +03:00
parent 00f53bc949
commit a615450896
2 changed files with 35 additions and 19 deletions
@@ -5,9 +5,9 @@ import com.project.movienight.adapters.web.dto.response.RecommendationResponse
import com.project.movienight.application.ports.input.AcceptRecommendationCommand import com.project.movienight.application.ports.input.AcceptRecommendationCommand
import com.project.movienight.application.ports.input.AcceptRecommendationUseCase import com.project.movienight.application.ports.input.AcceptRecommendationUseCase
import com.project.movienight.application.ports.input.GetRecommendationsUseCase import com.project.movienight.application.ports.input.GetRecommendationsUseCase
import com.project.movienight.application.ports.input.RecommendationQuery
import com.project.movienight.application.ports.input.RejectRecommendationCommand import com.project.movienight.application.ports.input.RejectRecommendationCommand
import com.project.movienight.application.ports.input.RejectRecommendationUseCase import com.project.movienight.application.ports.input.RejectRecommendationUseCase
import com.project.movienight.application.ports.input.RecommendationQuery
import com.project.movienight.config.JellyfinIntegrationProperties import com.project.movienight.config.JellyfinIntegrationProperties
import com.project.movienight.domain.model.ContentType import com.project.movienight.domain.model.ContentType
import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.GetMapping
@@ -36,20 +36,21 @@ class RecommendationController(
@RequestParam(required = false, defaultValue = "false") libraryOnly: Boolean, @RequestParam(required = false, defaultValue = "false") libraryOnly: Boolean,
@RequestParam(required = false, defaultValue = "10") limit: Int, @RequestParam(required = false, defaultValue = "10") limit: Int,
): List<RecommendationResponse> = ): List<RecommendationResponse> =
getRecommendationsUseCase.recommend( getRecommendationsUseCase
RecommendationQuery( .recommend(
userId = userId, RecommendationQuery(
contentType = contentType?.let { runCatching { ContentType.valueOf(it.uppercase()) }.getOrNull() }, userId = userId,
mood = mood, contentType = contentType?.let { runCatching { ContentType.valueOf(it.uppercase()) }.getOrNull() },
libraryOnly = libraryOnly, mood = mood,
limit = limit, libraryOnly = libraryOnly,
), limit = limit,
).map { recommendation -> ),
RecommendationResponse.fromDomain( ).map { recommendation ->
recommendation = recommendation, RecommendationResponse.fromDomain(
watchUrl = buildWatchUrl(recommendation.film.jellyfinItemId), recommendation = recommendation,
) watchUrl = buildWatchUrl(recommendation.film.jellyfinItemId),
} )
}
@PostMapping("/{filmId}/accept") @PostMapping("/{filmId}/accept")
fun accept( fun accept(
@@ -4,9 +4,9 @@ import com.project.movienight.adapters.metrics.BusinessMetricsService
import com.project.movienight.application.ports.input.AcceptRecommendationCommand import com.project.movienight.application.ports.input.AcceptRecommendationCommand
import com.project.movienight.application.ports.input.AcceptRecommendationUseCase import com.project.movienight.application.ports.input.AcceptRecommendationUseCase
import com.project.movienight.application.ports.input.GetRecommendationsUseCase import com.project.movienight.application.ports.input.GetRecommendationsUseCase
import com.project.movienight.application.ports.input.RecommendationQuery
import com.project.movienight.application.ports.input.RejectRecommendationCommand import com.project.movienight.application.ports.input.RejectRecommendationCommand
import com.project.movienight.application.ports.input.RejectRecommendationUseCase import com.project.movienight.application.ports.input.RejectRecommendationUseCase
import com.project.movienight.application.ports.input.RecommendationQuery
import com.project.movienight.application.ports.output.FilmLibraryRepositoryPort import com.project.movienight.application.ports.output.FilmLibraryRepositoryPort
import com.project.movienight.application.ports.output.FilmRatingRepositoryPort import com.project.movienight.application.ports.output.FilmRatingRepositoryPort
import com.project.movienight.application.ports.output.FilmRepositoryPort import com.project.movienight.application.ports.output.FilmRepositoryPort
@@ -179,7 +179,15 @@ class RecommendationService(
preferences?.eras.orEmpty().forEach { profile.add(feature("era", it), PREFERENCE_ERA_WEIGHT) } preferences?.eras.orEmpty().forEach { profile.add(feature("era", it), PREFERENCE_ERA_WEIGHT) }
preferences?.castAndDirectors.orEmpty().forEach { profile.add(feature("person", it), PREFERENCE_PERSON_WEIGHT) } preferences?.castAndDirectors.orEmpty().forEach { profile.add(feature("person", it), PREFERENCE_PERSON_WEIGHT) }
preferences?.moods.orEmpty().forEach { profile.add(feature("mood", it), PREFERENCE_MOOD_WEIGHT) } preferences?.moods.orEmpty().forEach { profile.add(feature("mood", it), PREFERENCE_MOOD_WEIGHT) }
preferences?.contentTypes.orEmpty().forEach { profile.add(feature("type", it.name), PREFERENCE_CONTENT_TYPE_WEIGHT) } preferences
?.contentTypes
.orEmpty()
.forEach {
profile.add(
feature("type", it.name),
PREFERENCE_CONTENT_TYPE_WEIGHT,
)
}
ratings.forEach { rating -> ratings.forEach { rating ->
val film = filmsById[rating.filmId] ?: return@forEach val film = filmsById[rating.filmId] ?: return@forEach
@@ -309,7 +317,13 @@ class RecommendationService(
film: Film, film: Film,
preferences: UserPreferences?, preferences: UserPreferences?,
): Double { ): Double {
val preferredGenres = preferences?.weightedGenres.orEmpty().keys.map(::normalize).toSet() val preferredGenres =
preferences
?.weightedGenres
.orEmpty()
.keys
.map(::normalize)
.toSet()
val filmGenres = film.genres.map(::normalize).toSet() val filmGenres = film.genres.map(::normalize).toSet()
return when { return when {
preferredGenres.isEmpty() -> BASE_DIVERSITY_SCORE preferredGenres.isEmpty() -> BASE_DIVERSITY_SCORE
@@ -423,7 +437,8 @@ class RecommendationService(
return dot / (leftNorm * rightNorm) return dot / (leftNorm * rightNorm)
} }
private fun roundScore(score: Double): Double = kotlin.math.round(score * SCORE_ROUNDING_FACTOR) / SCORE_ROUNDING_FACTOR private fun roundScore(score: Double): Double =
kotlin.math.round(score * SCORE_ROUNDING_FACTOR) / SCORE_ROUNDING_FACTOR
private fun Iterable<Double>.averageOrNull(): Double? { private fun Iterable<Double>.averageOrNull(): Double? {
val values = toList() val values = toList()