Skip to content

Commit

Permalink
Merge pull request #487 from Shikkanime/dev
Browse files Browse the repository at this point in the history
Add filter on seasons
  • Loading branch information
Ziedelth committed May 23, 2024
2 parents 519f0a6 + bb73bbb commit 77faa5f
Show file tree
Hide file tree
Showing 23 changed files with 137 additions and 42 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package fr.shikkanime.caches

import fr.shikkanime.dtos.enums.Status
import fr.shikkanime.entities.SortParameter
import fr.shikkanime.entities.enums.CountryCode
import java.util.*

data class CountryCodeUUIDSeasonSortPaginationKeyCache(
override val countryCode: CountryCode?,
val uuid: UUID?,
val season: Int?,
val sort: List<SortParameter>,
override val page: Int,
override val limit: Int,
val status: Status? = null,
) : CountryCodePaginationKeyCache(countryCode, page, limit)
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class EpisodeMappingController : HasPageableRoute() {
private fun getAll(
@QueryParam("country", description = "By default: FR", type = CountryCode::class) countryParam: String?,
@QueryParam("anime") animeParam: UUID?,
@QueryParam("season") seasonParam: Int?,
@QueryParam("page") pageParam: Int?,
@QueryParam("limit") limitParam: Int?,
@QueryParam("sort") sortParam: String?,
Expand All @@ -63,6 +64,7 @@ class EpisodeMappingController : HasPageableRoute() {
episodeMappingCacheService.findAllBy(
CountryCode.fromNullable(countryParam) ?: CountryCode.FR,
animeParam,
seasonParam,
sortParameters,
page,
limit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ class SEOController {
val episodeMapping = episodeMappingCacheService.findAllBy(
CountryCode.FR,
null,
listOf(SortParameter("releaseDateTime", SortParameter.Order.DESC)),
null,
listOf(SortParameter("lastReleaseDateTime", SortParameter.Order.DESC)),
1,
1
)!!.data.firstOrNull()
Expand Down
20 changes: 16 additions & 4 deletions src/main/kotlin/fr/shikkanime/controllers/site/SiteController.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package fr.shikkanime.controllers.site

import com.google.inject.Inject
import fr.shikkanime.converters.AbstractConverter
import fr.shikkanime.dtos.AnimeDto
import fr.shikkanime.entities.SortParameter
import fr.shikkanime.entities.enums.ConfigPropertyKey
Expand Down Expand Up @@ -83,6 +82,7 @@ class SiteController {
"episodeMappings" to episodeMappingCacheService.findAllBy(
CountryCode.FR,
null,
null,
listOf(
SortParameter("lastReleaseDateTime", SortParameter.Order.DESC),
SortParameter("animeName", SortParameter.Order.DESC),
Expand Down Expand Up @@ -123,18 +123,30 @@ class SiteController {
@Path("animes/{slug}")
@Get
private fun animeDetail(@PathParam("slug") slug: String): Response {
val anime = animeCacheService.findBySlug(CountryCode.FR, slug) ?: return Response.redirect("/404")
val dto = AbstractConverter.convert(anime, AnimeDto::class.java)
val dto = animeCacheService.findBySlug(CountryCode.FR, slug) ?: return Response.redirect("/404")
return Response.redirect("/animes/${dto.slug}/season-${dto.seasons.first().number}")
}

@Path("animes/{slug}/season-{season}")
@Get
private fun animeDetailBySeason(
@PathParam("slug") slug: String,
@PathParam("season") season: Int
): Response {
val dto = animeCacheService.findBySlug(CountryCode.FR, slug) ?: return Response.redirect("/404")
val seasonDto = dto.seasons.firstOrNull { it.number == season } ?: return Response.redirect("/404")

return Response.template(
"/site/anime.ftl",
dto.shortName,
mutableMapOf(
"description" to dto.description?.let { StringUtils.sanitizeXSS(it) },
"anime" to dto,
"season" to seasonDto,
"episodeMappings" to episodeMappingCacheService.findAllBy(
CountryCode.FR,
anime.uuid,
dto.uuid,
season,
listOf(
SortParameter("releaseDateTime", SortParameter.Order.ASC),
SortParameter("season", SortParameter.Order.ASC),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,24 @@ package fr.shikkanime.converters.anime
import com.google.inject.Inject
import fr.shikkanime.converters.AbstractConverter
import fr.shikkanime.dtos.AnimeDto
import fr.shikkanime.dtos.SeasonDto
import fr.shikkanime.dtos.SimulcastDto
import fr.shikkanime.entities.Anime
import fr.shikkanime.entities.enums.LangType
import fr.shikkanime.services.EpisodeMappingService
import fr.shikkanime.services.SimulcastService.Companion.sortBySeasonAndYear
import fr.shikkanime.services.caches.EpisodeVariantCacheService
import fr.shikkanime.utils.StringUtils
import fr.shikkanime.utils.withUTCString
import java.time.ZonedDateTime

class AnimeToAnimeDtoConverter : AbstractConverter<Anime, AnimeDto>() {
@Inject
private lateinit var episodeVariantCacheService: EpisodeVariantCacheService

@Inject
private lateinit var episodeMappingService: EpisodeMappingService

override fun convert(from: Anime): AnimeDto {
val audioLocales = episodeVariantCacheService.findAllAudioLocalesByAnime(from)!!

Expand All @@ -35,6 +41,8 @@ class AnimeToAnimeDtoConverter : AbstractConverter<Anime, AnimeDto>() {
)?.toList(),
audioLocales = audioLocales,
langTypes = audioLocales.map { LangType.fromAudioLocale(from.countryCode, it) }.distinct().sorted(),
seasons = episodeMappingService.findAllSeasonsByAnime(from)
.map { SeasonDto(it[0] as Int, (it[1] as ZonedDateTime).withUTCString()) },
status = from.status,
)
}
Expand Down
1 change: 1 addition & 0 deletions src/main/kotlin/fr/shikkanime/dtos/AnimeDto.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ data class AnimeDto(
val simulcasts: List<SimulcastDto>?,
val audioLocales: List<String>? = null,
val langTypes: List<LangType>? = null,
val seasons: List<SeasonDto> = emptyList(),
val status: Status? = null,
)
6 changes: 6 additions & 0 deletions src/main/kotlin/fr/shikkanime/dtos/SeasonDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package fr.shikkanime.dtos

data class SeasonDto(
val number: Int,
val lastReleaseDateTime: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class CustomLuceneAnalysisDefinitionProvider : LuceneAnalysisConfigurer {
.tokenFilter("lowercase")
.tokenFilter("asciifolding")
.tokenFilter("ngram")
.param("minGramSize", "2")
.param("maxGramSize", "4")
.param("minGramSize", "3")
.param("maxGramSize", "6")
}
}
1 change: 1 addition & 0 deletions src/main/kotlin/fr/shikkanime/modules/Routing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ private fun handlePathParam(kParameter: KParameter, parameters: Map<String, List
UUID::class.java -> pathParamValue?.let { UUID.fromString(it) }
Platform::class.java -> pathParamValue?.let { Platform.valueOf(it) }
String::class.java -> pathParamValue
Int::class.java -> pathParamValue?.toIntOrNull()
else -> throw Exception("Unknown type ${kParameter.type}")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class EpisodeMappingRepository : AbstractRepository<EpisodeMapping>() {
fun findAllBy(
countryCode: CountryCode?,
anime: Anime?,
season: Int?,
sort: List<SortParameter>,
page: Int,
limit: Int,
Expand All @@ -26,6 +27,7 @@ class EpisodeMappingRepository : AbstractRepository<EpisodeMapping>() {

val predicates = mutableListOf<Predicate>()
anime?.let { predicates.add(cb.equal(root[EpisodeMapping_.anime], it)) }
season?.let { predicates.add(cb.equal(root[EpisodeMapping_.season], it)) }
countryCode?.let { predicates.add(cb.equal(root[EpisodeMapping_.anime][Anime_.countryCode], it)) }
status?.let { predicates.add(cb.equal(root[EpisodeMapping_.status], it)) }
query.where(*predicates.toTypedArray())
Expand All @@ -52,12 +54,13 @@ class EpisodeMappingRepository : AbstractRepository<EpisodeMapping>() {
}

fun findAllUuidAndImage(): List<Tuple> {
return inTransaction { entityManager ->
val cb = entityManager.criteriaBuilder
return inTransaction {
val cb = it.criteriaBuilder
val query = cb.createTupleQuery()
val root = query.from(getEntityClass())
query.multiselect(root[EpisodeMapping_.uuid], root[EpisodeMapping_.image])
entityManager.createQuery(query).resultList
createReadOnlyQuery(it, query)
.resultList
}
}

Expand All @@ -69,7 +72,24 @@ class EpisodeMappingRepository : AbstractRepository<EpisodeMapping>() {

query.where(cb.equal(root[EpisodeMapping_.anime], anime))

it.createQuery(query)
createReadOnlyQuery(it, query)
.resultList
}
}

fun findAllSeasonsByAnime(anime: Anime): List<Tuple> {
return inTransaction {
val cb = it.criteriaBuilder
val query = cb.createTupleQuery()
val root = query.from(getEntityClass())

query.multiselect(root[EpisodeMapping_.season], cb.greatest(root[EpisodeMapping_.lastReleaseDateTime]))
query.groupBy(root[EpisodeMapping_.season])
query.where(cb.equal(root[EpisodeMapping_.anime], anime))
query.orderBy(cb.asc(root[EpisodeMapping_.season]))
query.distinct(true)

createReadOnlyQuery(it, query)
.resultList
}
}
Expand All @@ -94,7 +114,7 @@ class EpisodeMappingRepository : AbstractRepository<EpisodeMapping>() {
)
)

it.createQuery(query)
createReadOnlyQuery(it, query)
.resultList
.firstOrNull()
}
Expand Down Expand Up @@ -125,7 +145,7 @@ class EpisodeMappingRepository : AbstractRepository<EpisodeMapping>() {
)

query.orderBy(cb.desc(root[EpisodeVariant_.mapping][EpisodeMapping_.number]))
it.createQuery(query)
createReadOnlyQuery(it, query)
.resultList
.firstOrNull() ?: 0
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class EpisodeVariantRepository : AbstractRepository<EpisodeVariant>() {
}
}

fun findAllSimulcasted(countryCode: CountryCode): List<EpisodeMapping> {
fun findAllSimulcastedByAnime(anime: Anime): List<EpisodeMapping> {
return inTransaction { entityManager ->
val cb = entityManager.criteriaBuilder
val query = cb.createQuery(EpisodeMapping::class.java)
Expand All @@ -135,12 +135,18 @@ class EpisodeVariantRepository : AbstractRepository<EpisodeVariant>() {
.select(root[EpisodeVariant_.mapping])
.where(
cb.and(
cb.notEqual(root[EpisodeVariant_.audioLocale], countryCode.locale),
cb.notEqual(root[EpisodeVariant_.audioLocale], anime.countryCode!!.locale),
cb.notEqual(root[EpisodeVariant_.mapping][EpisodeMapping_.episodeType], EpisodeType.FILM),
cb.notEqual(root[EpisodeVariant_.mapping][EpisodeMapping_.episodeType], EpisodeType.SUMMARY),
cb.equal(root[EpisodeVariant_.mapping][EpisodeMapping_.anime], anime)
)
)
.orderBy(cb.asc(root[EpisodeVariant_.mapping][EpisodeMapping_.releaseDateTime]))
.orderBy(
cb.asc(root[EpisodeVariant_.mapping][EpisodeMapping_.releaseDateTime]),
cb.asc(root[EpisodeVariant_.mapping][EpisodeMapping_.season]),
cb.asc(root[EpisodeVariant_.mapping][EpisodeMapping_.episodeType]),
cb.asc(root[EpisodeVariant_.mapping][EpisodeMapping_.number]),
)

createReadOnlyQuery(entityManager, query)
.resultList
Expand Down
13 changes: 4 additions & 9 deletions src/main/kotlin/fr/shikkanime/services/AnimeService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -133,18 +133,13 @@ class AnimeService : AbstractService<Anime, AnimeRepository>() {
fun recalculateSimulcasts() {
findAll().forEach { anime ->
anime.simulcasts.clear()
update(anime)
}

episodeVariantService.findAllSimulcasted(CountryCode.FR)
.forEach { episodeMapping ->
val anime = find(episodeMapping.anime!!.uuid!!)!!
episodeVariantService.findAllSimulcastedByAnime(anime).forEach { episodeMapping ->
addSimulcastToAnime(anime, episodeVariantService.getSimulcast(anime, episodeMapping))

if (episodeMapping.anime != anime) {
update(anime)
}
}

update(anime)
}
}

override fun save(entity: Anime): Anime {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,19 @@ class EpisodeMappingService : AbstractService<EpisodeMapping, EpisodeMappingRepo
fun findAllBy(
countryCode: CountryCode?,
anime: Anime?,
season: Int?,
sort: List<SortParameter>,
page: Int,
limit: Int,
status: Status? = null
) = episodeMappingRepository.findAllBy(countryCode, anime, sort, page, limit, status)
) = episodeMappingRepository.findAllBy(countryCode, anime, season, sort, page, limit, status)

fun findAllUuidAndImage() = episodeMappingRepository.findAllUuidAndImage()

fun findAllByAnime(anime: Anime) = episodeMappingRepository.findAllByAnime(anime)

fun findAllSeasonsByAnime(anime: Anime) = episodeMappingRepository.findAllSeasonsByAnime(anime)

fun findLastNumber(anime: Anime, episodeType: EpisodeType, season: Int, platform: Platform, audioLocale: String) =
episodeMappingRepository.findLastNumber(anime, episodeType, season, platform, audioLocale)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ import fr.shikkanime.platforms.AbstractPlatform
import fr.shikkanime.repositories.EpisodeVariantRepository
import fr.shikkanime.services.caches.ConfigCacheService
import fr.shikkanime.utils.Constant
import fr.shikkanime.utils.LoggerFactory
import fr.shikkanime.utils.MapCache
import fr.shikkanime.utils.StringUtils
import java.time.ZonedDateTime
import java.time.temporal.ChronoUnit

class EpisodeVariantService : AbstractService<EpisodeVariant, EpisodeVariantRepository>() {
private val logger = LoggerFactory.getLogger(javaClass)

@Inject
private lateinit var episodeVariantRepository: EpisodeVariantRepository

Expand Down Expand Up @@ -50,7 +53,7 @@ class EpisodeVariantService : AbstractService<EpisodeVariant, EpisodeVariantRepo

fun findAllByMapping(mapping: EpisodeMapping) = episodeVariantRepository.findAllByMapping(mapping)

fun findAllSimulcasted(countryCode: CountryCode) = episodeVariantRepository.findAllSimulcasted(countryCode)
fun findAllSimulcastedByAnime(anime: Anime) = episodeVariantRepository.findAllSimulcastedByAnime(anime)

fun findByIdentifier(identifier: String) = episodeVariantRepository.findByIdentifier(identifier)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import fr.shikkanime.caches.CountryCodeIdKeyCache
import fr.shikkanime.caches.CountryCodeLocalDateKeyCache
import fr.shikkanime.caches.CountryCodeNamePaginationKeyCache
import fr.shikkanime.caches.CountryCodeUUIDSortPaginationKeyCache
import fr.shikkanime.converters.AbstractConverter
import fr.shikkanime.dtos.AnimeDto
import fr.shikkanime.dtos.PageableDto
import fr.shikkanime.dtos.WeeklyAnimesDto
Expand Down Expand Up @@ -51,8 +52,9 @@ class AnimeCacheService : AbstractCacheService {
)
}

private val findBySlugCache = MapCache<CountryCodeIdKeyCache, Anime?>(classes = listOf(Anime::class.java)) {
private val findBySlugCache = MapCache<CountryCodeIdKeyCache, AnimeDto?>(classes = listOf(Anime::class.java)) {
animeService.findBySlug(it.countryCode, it.id)
.let { anime -> AbstractConverter.convert(anime, AnimeDto::class.java) }
}

private val weeklyMemberCache =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package fr.shikkanime.services.caches

import com.google.inject.Inject
import fr.shikkanime.caches.CountryCodeUUIDSortPaginationKeyCache
import fr.shikkanime.caches.CountryCodeUUIDSeasonSortPaginationKeyCache
import fr.shikkanime.dtos.EpisodeMappingDto
import fr.shikkanime.dtos.PageableDto
import fr.shikkanime.dtos.enums.Status
Expand All @@ -22,7 +22,7 @@ class EpisodeMappingCacheService : AbstractCacheService {
private lateinit var animeService: AnimeService

private val findAllByCache =
MapCache<CountryCodeUUIDSortPaginationKeyCache, PageableDto<EpisodeMappingDto>>(
MapCache<CountryCodeUUIDSeasonSortPaginationKeyCache, PageableDto<EpisodeMappingDto>>(
classes = listOf(
EpisodeMapping::class.java,
EpisodeVariant::class.java
Expand All @@ -32,6 +32,7 @@ class EpisodeMappingCacheService : AbstractCacheService {
episodeMappingService.findAllBy(
it.countryCode,
animeService.find(it.uuid),
it.season,
it.sort,
it.page,
it.limit,
Expand All @@ -44,9 +45,10 @@ class EpisodeMappingCacheService : AbstractCacheService {
fun findAllBy(
countryCode: CountryCode?,
anime: UUID?,
season: Int?,
sort: List<SortParameter>,
page: Int,
limit: Int,
status: Status? = null
) = findAllByCache[CountryCodeUUIDSortPaginationKeyCache(countryCode, anime, sort, page, limit, status)]
) = findAllByCache[CountryCodeUUIDSeasonSortPaginationKeyCache(countryCode, anime, season, sort, page, limit, status)]
}
Loading

0 comments on commit 77faa5f

Please sign in to comment.