Skip to content

Commit

Permalink
Merge pull request #128 from Shikkanime/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
Ziedelth authored Feb 2, 2024
2 parents 458c18c + 386e1dc commit 109ba82
Show file tree
Hide file tree
Showing 16 changed files with 270 additions and 260 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM mcr.microsoft.com/playwright:v1.41.1-jammy
FROM mcr.microsoft.com/playwright:v1.41.2-jammy
ARG version=21.0.2.13-1
ENV LANG C.UTF-8
ENV JAVA_HOME /usr/lib/jvm/java-21-amazon-corretto
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ dependencies {
implementation("org.quartz-scheduler:quartz:2.5.0-rc1")
implementation("com.google.guava:guava:33.0.0-jre")
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.16.1")
implementation("com.microsoft.playwright:playwright:1.41.1")
implementation("com.microsoft.playwright:playwright:1.41.2")
implementation("org.jsoup:jsoup:1.17.2")
implementation("com.google.code.gson:gson:2.10.1")
implementation("org.openpnp:opencv:4.9.0-0")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package fr.shikkanime.caches

import fr.shikkanime.entities.enums.CountryCode

data class CountryCodeNamePaginationKeyCache(
override val countryCode: CountryCode?,
val name: String,
override val page: Int,
override val limit: Int,
) : CountryCodePaginationKeyCache(countryCode, page, limit) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
if (!super.equals(other)) return false

other as CountryCodeNamePaginationKeyCache

if (countryCode != other.countryCode) return false
if (name != other.name) return false
if (page != other.page) return false
if (limit != other.limit) return false

return true
}

override fun hashCode(): Int {
var result = super.hashCode()
result = 31 * result + (countryCode?.hashCode() ?: 0)
result = 31 * result + name.hashCode()
result = 31 * result + page
result = 31 * result + limit
return result
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package fr.shikkanime.caches

import fr.shikkanime.entities.enums.CountryCode

open class CountryCodePaginationKeyCache(
open val countryCode: CountryCode?,
open val page: Int,
open val limit: Int,
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

other as CountryCodePaginationKeyCache

if (countryCode != other.countryCode) return false
if (page != other.page) return false
if (limit != other.limit) return false

return true
}

override fun hashCode(): Int {
var result = countryCode?.hashCode() ?: 0
result = 31 * result + page
result = 31 * result + limit
return result
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ import fr.shikkanime.entities.enums.CountryCode
import java.util.*

data class CountryCodeUUIDSortPaginationKeyCache(
val countryCode: CountryCode?,
override val countryCode: CountryCode?,
val uuid: UUID?,
val sort: List<SortParameter>,
val page: Int,
val limit: Int,
) {
override val page: Int,
override val limit: Int,
) : CountryCodePaginationKeyCache(countryCode, page, limit) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
if (!super.equals(other)) return false

other as CountryCodeUUIDSortPaginationKeyCache

Expand All @@ -27,7 +28,8 @@ data class CountryCodeUUIDSortPaginationKeyCache(
}

override fun hashCode(): Int {
var result = countryCode?.hashCode() ?: 0
var result = super.hashCode()
result = 31 * result + (countryCode?.hashCode() ?: 0)
result = 31 * result + (uuid?.hashCode() ?: 0)
result = 31 * result + sort.hashCode()
result = 31 * result + page
Expand Down
11 changes: 5 additions & 6 deletions src/main/kotlin/fr/shikkanime/controllers/api/AnimeController.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package fr.shikkanime.controllers.api

import com.google.inject.Inject
import fr.shikkanime.dtos.AnimeDto
import fr.shikkanime.dtos.MessageDto
import fr.shikkanime.dtos.PageableDto
import fr.shikkanime.entities.SortParameter
import fr.shikkanime.entities.enums.CountryCode
import fr.shikkanime.services.AnimeService
import fr.shikkanime.services.caches.AnimeCacheService
import fr.shikkanime.utils.routes.Controller
import fr.shikkanime.utils.routes.Path
import fr.shikkanime.utils.routes.Response
Expand All @@ -19,7 +18,7 @@ import java.util.*
@Controller("/api/v1/animes")
class AnimeController {
@Inject
private lateinit var animeService: AnimeService
private lateinit var animeCacheService: AnimeCacheService

@Path
@Get
Expand Down Expand Up @@ -74,11 +73,11 @@ class AnimeController {
} ?: mutableListOf()

val pageable = if (!name.isNullOrBlank()) {
animeService.findAllByName(name, countryParam, page, limit)
animeCacheService.findAllByName(name, countryParam, page, limit)
} else {
animeService.findAllBy(countryParam, simulcastParam, sortParameters, page, limit)
animeCacheService.findAllBy(countryParam, simulcastParam, sortParameters, page, limit)
}

return Response.ok(PageableDto.fromPageable(pageable, AnimeDto::class.java))
return Response.ok(pageable)
}
}
93 changes: 43 additions & 50 deletions src/main/kotlin/fr/shikkanime/plugins/Routing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import java.util.*
import java.util.logging.Level
import kotlin.collections.set
import kotlin.reflect.KFunction
import kotlin.reflect.KParameter
import kotlin.reflect.full.*
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.jvm.javaType
Expand Down Expand Up @@ -263,7 +264,10 @@ private suspend fun handleRequest(
}
}
} catch (e: Exception) {
logger.log(Level.SEVERE, "Error while calling method $method", e)
if (e.message?.contains("Broken pipe") != true && e.message?.contains("Relais brisé (pipe)") != true) {
logger.log(Level.SEVERE, "Error while calling method $method", e)
}

call.respond(HttpStatusCode.BadRequest)
}
}
Expand All @@ -281,63 +285,52 @@ private suspend fun callMethodWithParameters(
): Response {
val methodParams = method.parameters.associateWith { kParameter ->
when {
kParameter.name.isNullOrBlank() -> {
controller
}
kParameter.name.isNullOrBlank() -> controller
method.hasAnnotation<JWTAuthenticated>() && kParameter.hasAnnotation<JWTUser>() ->
UUID.fromString(call.principal<JWTPrincipal>()!!.payload.getClaim("uuid").asString())

method.hasAnnotation<JWTAuthenticated>() && kParameter.hasAnnotation<JWTUser>() -> {
val jwtPrincipal = call.principal<JWTPrincipal>()
UUID.fromString(jwtPrincipal!!.payload.getClaim("uuid").asString())
}

method.hasAnnotation<AdminSessionAuthenticated>() && kParameter.hasAnnotation<AdminSessionUser>() -> {
method.hasAnnotation<AdminSessionAuthenticated>() && kParameter.hasAnnotation<AdminSessionUser>() ->
call.principal<TokenDto>()
}

kParameter.hasAnnotation<BodyParam>() -> {
when (kParameter.type.javaType) {
Array<UUID>::class.java -> call.receive<Array<UUID>>()
Parameters::class.java -> call.receiveParameters()
else -> call.receive<String>()
}
}

kParameter.hasAnnotation<QueryParam>() -> {
val name = kParameter.findAnnotation<QueryParam>()!!.name.ifBlank { kParameter.name!! }
val queryParamValue = call.request.queryParameters[name]
kParameter.hasAnnotation<BodyParam>() -> handleBodyParam(kParameter, call)
kParameter.hasAnnotation<QueryParam>() -> handleQueryParam(kParameter, call)
kParameter.hasAnnotation<PathParam>() -> handlePathParam(kParameter, parameters)
else -> throw Exception("Unknown parameter ${kParameter.name}")
}
}

when (kParameter.type) {
Int::class.starProjectedType.withNullability(true) -> queryParamValue?.toIntOrNull()
String::class.starProjectedType.withNullability(true) -> queryParamValue
CountryCode::class.starProjectedType.withNullability(true) -> CountryCode.fromNullable(
queryParamValue
)
method.isAccessible = true
return method.callBy(methodParams) as Response
}

UUID::class.starProjectedType.withNullability(true) -> if (queryParamValue.isNullOrBlank()) null else UUID.fromString(
queryParamValue
)
private suspend fun handleBodyParam(kParameter: KParameter, call: ApplicationCall): Any {
return when (kParameter.type.javaType) {
Array<UUID>::class.java -> call.receive<Array<UUID>>()
Parameters::class.java -> call.receiveParameters()
else -> call.receive<String>()
}
}

else -> throw Exception("Unknown type ${kParameter.type}")
}
}
private fun handleQueryParam(kParameter: KParameter, call: ApplicationCall): Any? {
val name = kParameter.findAnnotation<QueryParam>()!!.name.ifBlank { kParameter.name!! }
val queryParamValue = call.request.queryParameters[name]

kParameter.hasAnnotation<PathParam>() -> {
val name = kParameter.findAnnotation<PathParam>()!!.name.ifBlank { kParameter.name!! }
val pathParamValue = parameters[name]?.firstOrNull()
return when (kParameter.type) {
Int::class.starProjectedType.withNullability(true) -> queryParamValue?.toIntOrNull()
String::class.starProjectedType.withNullability(true) -> queryParamValue
CountryCode::class.starProjectedType.withNullability(true) -> CountryCode.fromNullable(queryParamValue)
UUID::class.starProjectedType.withNullability(true) -> if (queryParamValue.isNullOrBlank()) null else UUID.fromString(queryParamValue)
else -> throw Exception("Unknown type ${kParameter.type}")
}
}

when (kParameter.type.javaType) {
UUID::class.java -> UUID.fromString(pathParamValue)
Platform::class.java -> Platform.valueOf(pathParamValue!!)
else -> throw Exception("Unknown type ${kParameter.type}")
}
}
private fun handlePathParam(kParameter: KParameter, parameters: Map<String, List<String>>): Any? {
val name = kParameter.findAnnotation<PathParam>()!!.name.ifBlank { kParameter.name!! }
val pathParamValue = parameters[name]?.firstOrNull()

else -> {
throw Exception("Unknown parameter ${kParameter.name}")
}
}
return when (kParameter.type.javaType) {
UUID::class.java -> UUID.fromString(pathParamValue)
Platform::class.java -> Platform.valueOf(pathParamValue!!)
else -> throw Exception("Unknown type ${kParameter.type}")
}

method.isAccessible = true
return method.callBy(methodParams) as Response
}
58 changes: 36 additions & 22 deletions src/main/kotlin/fr/shikkanime/repositories/AbstractRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import fr.shikkanime.entities.ShikkEntity
import fr.shikkanime.utils.Database
import jakarta.persistence.EntityManager
import jakarta.persistence.TypedQuery
import org.hibernate.ScrollMode
import org.hibernate.jpa.AvailableHints
import org.hibernate.query.Query
import java.lang.reflect.ParameterizedType
Expand All @@ -21,9 +22,9 @@ abstract class AbstractRepository<E : ShikkEntity> {
}

protected fun <T> inTransaction(block: (EntityManager) -> T): T {
val entityManager = database.getEntityManager()
val entityManager = database.entityManager
val transaction = entityManager.transaction
transaction.begin()
if (!transaction.isActive) transaction.begin()
val result: T

try {
Expand All @@ -32,43 +33,56 @@ abstract class AbstractRepository<E : ShikkEntity> {
} catch (e: Exception) {
transaction.rollback()
throw e
} finally {
entityManager.close()
}

return result
}

fun <T> createQuery(query: String, clazz: Class<T>): TypedQuery<T> {
return database.entityManager.createQuery(query, clazz)
.setHint(AvailableHints.HINT_READ_ONLY, true)
}

fun buildPageableQuery(
query: TypedQuery<E>,
page: Int,
limit: Int
): Pageable<E> {
val scrollableResults = (query as Query).scroll()
scrollableResults.last()
val total = scrollableResults.rowNumber + 1
scrollableResults.close()
val scrollableResults = query.unwrap(Query::class.java)
.setReadOnly(true)
.setFetchSize(limit)
.scroll(ScrollMode.SCROLL_SENSITIVE)

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

query.setFirstResult((limit * page) - limit).setMaxResults(limit)
return Pageable(query.resultList, page, limit, total.toLong())
scrollableResults.use {
if (!it.first()) {
return@use
}

while (it.scroll((limit * page) - limit) && list.size < limit) {
@Suppress("UNCHECKED_CAST")
list.add(it.get() as E)
it.next()
}

total = if (it.last()) it.rowNumber + 1L else 0
}

return Pageable(list, page, limit, total)
}

open fun findAll(): List<E> {
return inTransaction {
it.createQuery("FROM ${getEntityClass().simpleName}", getEntityClass())
.setHint(AvailableHints.HINT_READ_ONLY, true)
.resultList
}
return createQuery("FROM ${getEntityClass().simpleName}", getEntityClass())
.resultList
}

open fun find(uuid: UUID): E? {
return inTransaction {
it.createQuery("FROM ${getEntityClass().simpleName} WHERE uuid = :uuid", getEntityClass())
.setParameter("uuid", uuid)
.setHint(AvailableHints.HINT_READ_ONLY, true)
.resultList
.firstOrNull()
}
return createQuery("FROM ${getEntityClass().simpleName} WHERE uuid = :uuid", getEntityClass())
.setParameter("uuid", uuid)
.resultList
.firstOrNull()
}

fun save(entity: E): E {
Expand Down
Loading

0 comments on commit 109ba82

Please sign in to comment.