Skip to content

Commit

Permalink
Merge pull request #454 from Shikkanime/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
Ziedelth committed May 13, 2024
2 parents c432b30 + dfc7a07 commit 01633af
Show file tree
Hide file tree
Showing 18 changed files with 278 additions and 47 deletions.
12 changes: 8 additions & 4 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@ name: "CodeQL"

on:
push:
branches: [ "master","dev" ]
branches:
- master
- dev
pull_request:
branches: [ "master","dev" ]
branches:
- master
- dev
schedule:
- cron: '33 14 * * 5'

Expand Down Expand Up @@ -44,8 +48,8 @@ jobs:
fail-fast: false
matrix:
include:
# - language: java-kotlin
# build-mode: autobuild
- language: java-kotlin
build-mode: autobuild
- language: javascript-typescript
build-mode: none
# CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/global_workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,11 @@ jobs:
- uses: actions/checkout@v4

- name: Clear build cache
uses: prantlf/delete-cache-action@v2
uses: prantlf/delete-cache-action@v3
with:
key: ${{ runner.os }}-build-${{ hashFiles('**/build.gradle.kts') }}-${{ github.sha }}

- name: Clear gradle cache
uses: prantlf/delete-cache-action@v2
uses: prantlf/delete-cache-action@v3
with:
key: ${{ runner.os }}-dev-dependencies-${{ hashFiles('**/build.gradle.kts') }}-${{ github.sha }}
18 changes: 11 additions & 7 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
val ktorVersion = "2.3.10"
val ktorVersion = "2.3.11"
val ktorSwaggerUiVersion = "2.9.0"
val hibernateCoreVersion = "6.5.0.Final"
val ehcacheVersion = "3.10.8"
Expand All @@ -19,20 +19,24 @@ val bcprovVersion = "1.78.1"
val javaImageScalingVersion = "0.8.6"
val firebaseVersion = "9.2.0"

val jdaVersion = "5.0.0-beta.23"
val jdaVersion = "5.0.0-beta.24"
val twitter4jVersion = "4.0.7"
val twitter4jV2Version = "1.4.3"

val junitVersion = "5.10.2"
val h2Version = "2.2.224"
val mockitoVersion = "5.11.0"
val mockitoVersion = "5.12.0"

plugins {
kotlin("jvm") version "2.0.0-RC2"
kotlin("kapt") version "1.9.23"
id("io.ktor.plugin") version "2.3.10"
jacoco
val kotlinVersion = "1.9.24"

kotlin("jvm") version kotlinVersion
kotlin("kapt") version kotlinVersion

id("io.ktor.plugin") version "2.3.11"
id("org.sonarqube") version "5.0.0.4638"

jacoco
}

group = "fr.shikkanime"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package fr.shikkanime.caches

import java.util.*

open class UUIDPaginationKeyCache(
open val uuid: UUID,
open val page: Int,
open val limit: Int,
)
36 changes: 32 additions & 4 deletions src/main/kotlin/fr/shikkanime/controllers/api/AnimeController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ package fr.shikkanime.controllers.api

import com.google.inject.Inject
import fr.shikkanime.converters.AbstractConverter
import fr.shikkanime.dtos.AnimeDto
import fr.shikkanime.dtos.MessageDto
import fr.shikkanime.dtos.PageableDto
import fr.shikkanime.dtos.WeeklyAnimesDto
import fr.shikkanime.dtos.*
import fr.shikkanime.dtos.enums.Status
import fr.shikkanime.entities.enums.CountryCode
import fr.shikkanime.services.AnimeService
import fr.shikkanime.services.caches.AnimeCacheService
import fr.shikkanime.services.caches.MemberFollowAnimeCacheService
import fr.shikkanime.utils.routes.*
import fr.shikkanime.utils.routes.method.Delete
import fr.shikkanime.utils.routes.method.Get
Expand All @@ -31,6 +29,9 @@ class AnimeController : HasPageableRoute() {
@Inject
private lateinit var animeService: AnimeService

@Inject
private lateinit var memberFollowAnimeCacheService: MemberFollowAnimeCacheService

@Path
@Get
@OpenAPI(
Expand Down Expand Up @@ -211,4 +212,31 @@ class AnimeController : HasPageableRoute() {
)
)
}

@Path("/missed")
@Get
@JWTAuthenticated
@OpenAPI(
"Get missed animes",
[
OpenAPIResponse(
200,
"Get missed animes",
PageableDto::class,
),
OpenAPIResponse(401, "Unauthorized")
],
security = true
)
private fun getMissedAnimes(
@JWTUser uuid: UUID,
@QueryParam("page") pageParam: Int?,
@QueryParam("limit") limitParam: Int?,
): Response {
val (page, limit, _) = pageableRoute(pageParam, limitParam, null, null)

return Response.ok(
memberFollowAnimeCacheService.getMissedAnimes(uuid, page, limit) ?: return Response.notFound()
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class MemberToMemberDtoConverter : AbstractConverter<Member, MemberDto>() {
creationDateTime = from.creationDateTime.withUTCString(),
lastUpdateDateTime = from.lastUpdateDateTime.withUTCString(),
isPrivate = from.isPrivate,
followedAnimes = memberFollowAnimeService.getAllFollowedAnimesUUID(from),
followedEpisodes = memberFollowEpisodeService.getAllFollowedEpisodesUUID(from),
followedAnimes = memberFollowAnimeService.findAllFollowedAnimesUUID(from),
followedEpisodes = memberFollowEpisodeService.findAllFollowedEpisodesUUID(from),
totalDuration = memberFollowEpisodeService.getTotalDuration(from),
)
}
Expand Down
6 changes: 6 additions & 0 deletions src/main/kotlin/fr/shikkanime/dtos/MissedAnimeDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package fr.shikkanime.dtos

data class MissedAnimeDto(
val anime: AnimeDto,
val episodeMissed: Long,
)
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,18 @@ abstract class AbstractRepository<E : ShikkEntity> {
.setHint(AvailableHints.HINT_READ_ONLY, true)
}

fun buildPageableQuery(query: TypedQuery<E>, page: Int, limit: Int): Pageable<E> {
fun <C> buildPageableQuery(query: TypedQuery<C>, page: Int, limit: Int): Pageable<C> {
val scrollableResults = query.unwrap(Query::class.java)
.setReadOnly(true)
.setFetchSize(limit)
.scroll(ScrollMode.SCROLL_SENSITIVE)

val list = mutableListOf<E>()
val list = mutableListOf<C>()
var total = 0L

if (scrollableResults.first() && scrollableResults.scroll((limit * page) - limit)) {
for (i in 0 until limit) {
list.add(scrollableResults.get() as E) // NOSONAR
list.add(scrollableResults.get() as C) // NOSONAR
if (!scrollableResults.next()) break
}
total = if (scrollableResults.last()) scrollableResults.rowNumber + 1L else 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class AnimeRepository : AbstractRepository<Anime>() {
}

query.orderBy(orders)
buildPageableQuery(entityManager.createQuery(query), page, limit)
buildPageableQuery(createReadOnlyQuery(entityManager, query), page, limit)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class EpisodeMappingRepository : AbstractRepository<EpisodeMapping>() {
}

query.orderBy(orders)
buildPageableQuery(entityManager.createQuery(query), page, limit)
buildPageableQuery(createReadOnlyQuery(entityManager, query), page, limit)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class EpisodeVariantRepository : AbstractRepository<EpisodeVariant>() {

member?.let {
val animePredicate = root[EpisodeVariant_.mapping][EpisodeMapping_.anime].get<UUID>(Anime_.UUID).`in`(
memberFollowAnimeService.getAllFollowedAnimesUUID(it)
memberFollowAnimeService.findAllFollowedAnimesUUID(it)
)
predicates.add(animePredicate)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fr.shikkanime.repositories

import fr.shikkanime.entities.*
import jakarta.persistence.Tuple
import java.util.*

class MemberFollowAnimeRepository : AbstractRepository<MemberFollowAnime>() {
Expand All @@ -23,7 +24,7 @@ class MemberFollowAnimeRepository : AbstractRepository<MemberFollowAnime>() {
}
}

fun getAllFollowedAnimesUUID(member: Member): List<UUID> {
fun findAllFollowedAnimesUUID(member: Member): List<UUID> {
return inTransaction {
val cb = it.criteriaBuilder
val query = cb.createQuery(UUID::class.java)
Expand All @@ -38,4 +39,34 @@ class MemberFollowAnimeRepository : AbstractRepository<MemberFollowAnime>() {
.resultList
}
}

fun findAllMissedAnimes(
member: Member,
watchedEpisodes: List<EpisodeMapping>,
page: Int,
limit: Int,
): Pageable<Tuple> {
return inTransaction { entityManager ->
val cb = entityManager.criteriaBuilder
val query = cb.createQuery(Tuple::class.java)
val root = query.from(getEntityClass())

val subQuery = query.subquery(Long::class.java)
val subRoot = subQuery.from(EpisodeMapping::class.java)
subQuery.select(cb.count(subRoot))
subQuery.where(
cb.equal(subRoot[EpisodeMapping_.anime], root[MemberFollowAnime_.anime]),
cb.not(subRoot.get<UUID>(EpisodeMapping_.UUID).`in`(watchedEpisodes.map { it.uuid }))
)

query.select(cb.tuple(root[MemberFollowAnime_.anime], subQuery))
query.where(
cb.equal(root[MemberFollowAnime_.member], member),
cb.greaterThan(subQuery, 0)
)

query.orderBy(cb.desc(root[MemberFollowAnime_.anime][Anime_.lastReleaseDateTime]))
buildPageableQuery(createReadOnlyQuery(entityManager, query), page, limit)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,28 @@ import java.util.*
class MemberFollowEpisodeRepository : AbstractRepository<MemberFollowEpisode>() {
override fun getEntityClass() = MemberFollowEpisode::class.java

fun findByMemberAndEpisode(member: Member, episode: EpisodeMapping): MemberFollowEpisode? {
fun findAllFollowedEpisodesUUID(member: Member): List<UUID> {
return inTransaction {
val cb = it.criteriaBuilder
val query = cb.createQuery(getEntityClass())
val query = cb.createQuery(UUID::class.java)
val root = query.from(getEntityClass())
query.select(root[MemberFollowEpisode_.episode][EpisodeMapping_.UUID])

query.where(
cb.equal(root[MemberFollowEpisode_.member], member),
cb.equal(root[MemberFollowEpisode_.episode], episode)
cb.equal(root[MemberFollowEpisode_.member], member)
)

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

fun getAllFollowedEpisodesUUID(member: Member): List<UUID> {
fun findAllFollowedEpisodes(member: Member): List<EpisodeMapping> {
return inTransaction {
val cb = it.criteriaBuilder
val query = cb.createQuery(UUID::class.java)
val query = cb.createQuery(EpisodeMapping::class.java)
val root = query.from(getEntityClass())
query.select(root[MemberFollowEpisode_.episode][EpisodeMapping_.UUID])
query.select(root[MemberFollowEpisode_.episode])

query.where(
cb.equal(root[MemberFollowEpisode_.member], member)
Expand All @@ -39,6 +38,23 @@ class MemberFollowEpisodeRepository : AbstractRepository<MemberFollowEpisode>()
}
}

fun findByMemberAndEpisode(member: Member, episode: EpisodeMapping): MemberFollowEpisode? {
return inTransaction {
val cb = it.criteriaBuilder
val query = cb.createQuery(getEntityClass())
val root = query.from(getEntityClass())

query.where(
cb.equal(root[MemberFollowEpisode_.member], member),
cb.equal(root[MemberFollowEpisode_.episode], episode)
)

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

fun getTotalDuration(member: Member): Long {
return inTransaction {
val cb = it.criteriaBuilder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package fr.shikkanime.services

import com.google.inject.Inject
import fr.shikkanime.dtos.GenericDto
import fr.shikkanime.entities.EpisodeMapping
import fr.shikkanime.entities.Member
import fr.shikkanime.entities.MemberFollowAnime
import fr.shikkanime.repositories.MemberFollowAnimeRepository
Expand All @@ -22,7 +23,10 @@ class MemberFollowAnimeService : AbstractService<MemberFollowAnime, MemberFollow

override fun getRepository() = memberFollowAnimeRepository

fun getAllFollowedAnimesUUID(member: Member) = memberFollowAnimeRepository.getAllFollowedAnimesUUID(member)
fun findAllFollowedAnimesUUID(member: Member) = memberFollowAnimeRepository.findAllFollowedAnimesUUID(member)

fun findAllMissedAnimes(member: Member, watchedEpisodes: List<EpisodeMapping>, page: Int, limit: Int) =
memberFollowAnimeRepository.findAllMissedAnimes(member, watchedEpisodes, page, limit)

fun follow(uuidUser: UUID, anime: GenericDto): Response {
val member = memberService.find(uuidUser) ?: return Response.notFound()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ class MemberFollowEpisodeService : AbstractService<MemberFollowEpisode, MemberFo

override fun getRepository() = memberFollowEpisodeRepository

fun getAllFollowedEpisodesUUID(member: Member) = memberFollowEpisodeRepository.getAllFollowedEpisodesUUID(member)
fun findAllFollowedEpisodesUUID(member: Member) = memberFollowEpisodeRepository.findAllFollowedEpisodesUUID(member)

fun findAllFollowedEpisodes(member: Member) = memberFollowEpisodeRepository.findAllFollowedEpisodes(member)

fun getTotalDuration(member: Member) = memberFollowEpisodeRepository.getTotalDuration(member)

Expand Down
Loading

0 comments on commit 01633af

Please sign in to comment.