From 0e11d077d229e211416c7faf35369a1fec001af9 Mon Sep 17 00:00:00 2001 From: luevard Date: Mon, 27 May 2024 19:59:32 +0200 Subject: [PATCH 01/12] :sparkles: [no_ci] Test upload image --- .../main/kotlin/allin/routing/basicRouter.kt | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Sources/src/main/kotlin/allin/routing/basicRouter.kt b/Sources/src/main/kotlin/allin/routing/basicRouter.kt index f4a16e4..a9e61ef 100644 --- a/Sources/src/main/kotlin/allin/routing/basicRouter.kt +++ b/Sources/src/main/kotlin/allin/routing/basicRouter.kt @@ -4,9 +4,15 @@ import allin.model.ApiMessage import io.github.smiley4.ktorswaggerui.dsl.get import io.ktor.http.* import io.ktor.server.application.* +import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* +import kotlinx.serialization.Serializable +import java.io.File +import java.util.* +@Serializable +data class ImageResponse(val url: String) fun Application.basicRouter() { routing { @@ -23,5 +29,28 @@ fun Application.basicRouter() { }) { call.respond(ApiMessage.WELCOME) } + post("/image") { + val base64Image = call.receiveText() + val imageBytes = Base64.getDecoder().decode(base64Image) + val fileName = "${UUID.randomUUID()}.png" + val file = File("uploads/$fileName") + + file.parentFile.mkdirs() + file.writeBytes(imageBytes) + + val imageUrl = "https://codefirst.iut.uca.fr/containers/AllDev-api/images/$fileName" + call.respond(HttpStatusCode.OK, ImageResponse(imageUrl)) + } + + get("/images/{fileName}") { + val fileName = call.parameters["fileName"] + val file = File("uploads/$fileName") + + if (file.exists()) { + call.respondFile(file) + } else { + call.respond(HttpStatusCode.NotFound, "File not found") + } + } } } \ No newline at end of file From 3e198b760524c20762106d3f38c6476a625f6435 Mon Sep 17 00:00:00 2001 From: Lucas EVARD Date: Mon, 27 May 2024 19:59:54 +0200 Subject: [PATCH 02/12] =?UTF-8?q?Mise=20=C3=A0=20jour=20de=20'.drone.star'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .drone.star | 105 +++++++++++++++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 46 deletions(-) diff --git a/.drone.star b/.drone.star index 5910419..37e215c 100644 --- a/.drone.star +++ b/.drone.star @@ -59,54 +59,67 @@ def ci(ctx): return CI def cd(ctx): - CD = { - "kind": "pipeline", - "name": "CD", - "steps": [ - { - "name": "hadolint", - "image": "hadolint/hadolint:latest-alpine", - "commands": [ - "hadolint Sources/Dockerfile" - ] - }, - { - "name": "docker-image", - "image": "plugins/docker", - "settings": { - "dockerfile": "Sources/Dockerfile", - "context": "Sources", - "registry": "hub.codefirst.iut.uca.fr", - "repo": "hub.codefirst.iut.uca.fr/lucas.evard/api", - "username": {"from_secret": "SECRET_REGISTRY_USERNAME"}, - "password": {"from_secret": "SECRET_REGISTRY_PASSWORD"} - } - }, - { - "name": "deploy-container", - "image": "hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest", - "environment": { - "CODEFIRST_CLIENTDRONE_ENV_DATA_SOURCE": "postgres", - "CODEFIRST_CLIENTDRONE_ENV_CODEFIRST_CONTAINER": {"from_secret": "CODEFIRST_CONTAINER"}, - "CODEFIRST_CLIENTDRONE_ENV_POSTGRES_DB": {"from_secret": "db_database"}, - "CODEFIRST_CLIENTDRONE_ENV_POSTGRES_USER": {"from_secret": "db_user"}, - "CODEFIRST_CLIENTDRONE_ENV_POSTGRES_PASSWORD": {"from_secret": "db_password"}, - "CODEFIRST_CLIENTDRONE_ENV_POSTGRES_HOST": {"from_secret": "db_host"}, - "CODEFIRST_CLIENTDRONE_ENV_SALT": {"from_secret": "SALT"}, - "ADMINS": "lucasevard,emrekartal,arthurvalin,lucasdelanier", - "IMAGENAME": "hub.codefirst.iut.uca.fr/lucas.evard/api:latest", - "CONTAINERNAME": "api", - "COMMAND": "create", - "OVERWRITE": "true", - }, - "depends_on": [ - "docker-image" + CD = { + "kind": "pipeline", + "name": "CD", + "volumes": [ + { + "name": "images", + "temp": {} + } + ], + "steps": [ + { + "name": "hadolint", + "image": "hadolint/hadolint:latest-alpine", + "commands": [ + "hadolint Sources/Dockerfile" + ] + }, + { + "name": "docker-image", + "image": "plugins/docker", + "settings": { + "dockerfile": "Sources/Dockerfile", + "context": "Sources", + "registry": "hub.codefirst.iut.uca.fr", + "repo": "hub.codefirst.iut.uca.fr/lucas.evard/api", + "username": {"from_secret": "SECRET_REGISTRY_USERNAME"}, + "password": {"from_secret": "SECRET_REGISTRY_PASSWORD"} + } + }, + { + "name": "deploy-container", + "image": "hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest", + "environment": { + "CODEFIRST_CLIENTDRONE_ENV_DATA_SOURCE": "postgres", + "CODEFIRST_CLIENTDRONE_ENV_CODEFIRST_CONTAINER": {"from_secret": "CODEFIRST_CONTAINER"}, + "CODEFIRST_CLIENTDRONE_ENV_POSTGRES_DB": {"from_secret": "db_database"}, + "CODEFIRST_CLIENTDRONE_ENV_POSTGRES_USER": {"from_secret": "db_user"}, + "CODEFIRST_CLIENTDRONE_ENV_POSTGRES_PASSWORD": {"from_secret": "db_password"}, + "CODEFIRST_CLIENTDRONE_ENV_POSTGRES_HOST": {"from_secret": "db_host"}, + "CODEFIRST_CLIENTDRONE_ENV_SALT": {"from_secret": "SALT"}, + "ADMINS": "lucasevard,emrekartal,arthurvalin,lucasdelanier", + "IMAGENAME": "hub.codefirst.iut.uca.fr/lucas.evard/api:latest", + "CONTAINERNAME": "api", + "COMMAND": "create", + "OVERWRITE": "true", + }, + "depends_on": [ + "docker-image" + ], + "volumes": [ + { + "name": "images", + "path": "/uploads" + } + ] + } ] - } - ] - } + } + + return CD - return CD def db(ctx): DB = { From e291e0064bc1c857716add40dced8fb070f91aba Mon Sep 17 00:00:00 2001 From: luevard <99143550+saucepommefrite@users.noreply.github.com> Date: Thu, 30 May 2024 12:39:18 +0200 Subject: [PATCH 03/12] :sparkles: [no_ci] Add routes for inject,get and remove image of a user. Update pom.xml dependencies. --- Sources/pom.xml | 16 +++-- Sources/src/main/kotlin/allin/Application.kt | 4 +- .../main/kotlin/allin/data/UserDataSource.kt | 3 + .../allin/data/mock/MockUserDataSource.kt | 15 ++++- .../data/postgres/PostgresUserDataSource.kt | 18 +++++- .../data/postgres/entities/UserImageEntity.kt | 29 +++++++++ Sources/src/main/kotlin/allin/dto/UserDTO.kt | 2 +- Sources/src/main/kotlin/allin/model/User.kt | 6 ++ .../main/kotlin/allin/routing/basicRouter.kt | 31 +--------- .../main/kotlin/allin/routing/userRouter.kt | 62 +++++++++++++++++++ .../src/test/kotlin/allin/ApplicationTest.kt | 1 + 11 files changed, 145 insertions(+), 42 deletions(-) create mode 100644 Sources/src/main/kotlin/allin/data/postgres/entities/UserImageEntity.kt diff --git a/Sources/pom.xml b/Sources/pom.xml index 9536a23..897fde2 100644 --- a/Sources/pom.xml +++ b/Sources/pom.xml @@ -10,7 +10,7 @@ 1.9.10 1.5.0 - 2.3.4 + 2.3.11 official 1.4.14 2.0.9 @@ -34,7 +34,7 @@ org.postgresql postgresql - 42.7.1 + 42.7.3 io.ktor @@ -44,7 +44,7 @@ io.github.smiley4 ktor-swagger-ui - 2.7.4 + 2.10.0 io.ktor @@ -142,12 +142,12 @@ io.ktor ktor-server-auth-jwt-jvm - 2.3.4 + 2.3.11 io.swagger.codegen.v3 swagger-codegen-generators - 1.0.38 + 1.0.50 @@ -155,6 +155,12 @@ hamcrest-core 1.3 + + org.junit.jupiter + junit-jupiter + RELEASE + test + ${project.basedir}/src/main/kotlin diff --git a/Sources/src/main/kotlin/allin/Application.kt b/Sources/src/main/kotlin/allin/Application.kt index 7b5a97d..cbc89f6 100644 --- a/Sources/src/main/kotlin/allin/Application.kt +++ b/Sources/src/main/kotlin/allin/Application.kt @@ -27,6 +27,8 @@ val BET_VERIFY_DELAY = 1.minutes val data_source = System.getenv()["DATA_SOURCE"] val isCodeFirstContainer = System.getenv()["CODEFIRST_CONTAINER"].orEmpty() +val hostIP = "0.0.0.0" +val hostPort = 8080 private val allInDataSource: AllInDataSource = when (data_source) { "mock" -> MockDataSource() @@ -38,7 +40,7 @@ val Application.dataSource: AllInDataSource get() = allInDataSource fun main() { - embeddedServer(Netty, port = 8080, host = "0.0.0.0") { + embeddedServer(Netty, port = hostPort, host = hostIP) { extracted() }.start(wait = true) } diff --git a/Sources/src/main/kotlin/allin/data/UserDataSource.kt b/Sources/src/main/kotlin/allin/data/UserDataSource.kt index ba4d54a..273de87 100644 --- a/Sources/src/main/kotlin/allin/data/UserDataSource.kt +++ b/Sources/src/main/kotlin/allin/data/UserDataSource.kt @@ -12,4 +12,7 @@ interface UserDataSource { fun userExists(username: String): Boolean fun emailExists(email: String): Boolean fun canHaveDailyGift(username: String): Boolean + fun addImage(userid: String, image: ByteArray) + fun removeImage(userid: String) + fun getImage(userid: String): ByteArray? } \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/data/mock/MockUserDataSource.kt b/Sources/src/main/kotlin/allin/data/mock/MockUserDataSource.kt index 454357f..03a63b2 100644 --- a/Sources/src/main/kotlin/allin/data/mock/MockUserDataSource.kt +++ b/Sources/src/main/kotlin/allin/data/mock/MockUserDataSource.kt @@ -3,8 +3,6 @@ package allin.data.mock import allin.data.UserDataSource import allin.dto.UserDTO import allin.model.User -import org.ktorm.dsl.eq -import org.ktorm.dsl.or import java.time.ZonedDateTime class MockUserDataSource(private val mockData: MockDataSource.MockData) : UserDataSource { @@ -57,4 +55,17 @@ class MockUserDataSource(private val mockData: MockDataSource.MockData) : UserDa lastGifts[username] = ZonedDateTime.now() return value } + + override fun addImage(userid: String, image: ByteArray) { + TODO("Not yet implemented") + } + + override fun removeImage(userid: String) { + TODO("Not yet implemented") + } + + override fun getImage(userid: String): ByteArray? { + TODO("Not yet implemented") + } + } \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/data/postgres/PostgresUserDataSource.kt b/Sources/src/main/kotlin/allin/data/postgres/PostgresUserDataSource.kt index 31a51f8..c9e858f 100644 --- a/Sources/src/main/kotlin/allin/data/postgres/PostgresUserDataSource.kt +++ b/Sources/src/main/kotlin/allin/data/postgres/PostgresUserDataSource.kt @@ -1,9 +1,7 @@ package allin.data.postgres import allin.data.UserDataSource -import allin.data.postgres.entities.UserEntity -import allin.data.postgres.entities.UsersEntity -import allin.data.postgres.entities.users +import allin.data.postgres.entities.* import allin.dto.UserDTO import allin.ext.executeWithResult import allin.model.User @@ -83,4 +81,18 @@ class PostgresUserDataSource(private val database: Database) : UserDataSource { return false } + override fun addImage(userid: String, image: ByteArray) { + database.usersimage.add(UserImageEntity { + id = userid + this.image = image + }) + } + + override fun removeImage(userid: String) { + database.usersimage.removeIf { it.id eq userid } + } + + override fun getImage(userid: String): ByteArray? = + database.usersimage.find { it.id eq userid }?.image + } \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/data/postgres/entities/UserImageEntity.kt b/Sources/src/main/kotlin/allin/data/postgres/entities/UserImageEntity.kt new file mode 100644 index 0000000..64a47eb --- /dev/null +++ b/Sources/src/main/kotlin/allin/data/postgres/entities/UserImageEntity.kt @@ -0,0 +1,29 @@ +package allin.data.postgres.entities + +import allin.model.UserImage +import org.ktorm.database.Database +import org.ktorm.entity.Entity +import org.ktorm.entity.sequenceOf +import org.ktorm.schema.Table +import org.ktorm.schema.bytes +import org.ktorm.schema.varchar + +interface UserImageEntity : Entity { + companion object : Entity.Factory() + + var id: String + var image: ByteArray + + fun toUserImage() = + UserImage( + id = id, + image = image, + ) +} + +object UsersImageEntity : Table("userimage") { + val id = varchar("user_id").primaryKey().bindTo { it.id } + val image = bytes("image").bindTo { it.image } +} + +val Database.usersimage get() = this.sequenceOf(UsersImageEntity) diff --git a/Sources/src/main/kotlin/allin/dto/UserDTO.kt b/Sources/src/main/kotlin/allin/dto/UserDTO.kt index c34686f..b4cc2bf 100644 --- a/Sources/src/main/kotlin/allin/dto/UserDTO.kt +++ b/Sources/src/main/kotlin/allin/dto/UserDTO.kt @@ -9,4 +9,4 @@ data class UserDTO( val email: String, val nbCoins: Int, var token: String? -) +) \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/model/User.kt b/Sources/src/main/kotlin/allin/model/User.kt index 423986e..534add7 100644 --- a/Sources/src/main/kotlin/allin/model/User.kt +++ b/Sources/src/main/kotlin/allin/model/User.kt @@ -27,4 +27,10 @@ data class UserRequest( data class CheckUser( val login: String, val password: String +) + +@Serializable +data class UserImage( + val id: String, + val image: ByteArray, ) \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/routing/basicRouter.kt b/Sources/src/main/kotlin/allin/routing/basicRouter.kt index a9e61ef..92d4e2d 100644 --- a/Sources/src/main/kotlin/allin/routing/basicRouter.kt +++ b/Sources/src/main/kotlin/allin/routing/basicRouter.kt @@ -4,17 +4,11 @@ import allin.model.ApiMessage import io.github.smiley4.ktorswaggerui.dsl.get import io.ktor.http.* import io.ktor.server.application.* -import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* -import kotlinx.serialization.Serializable -import java.io.File -import java.util.* - -@Serializable -data class ImageResponse(val url: String) fun Application.basicRouter() { + routing { get("/", { description = "Hello World of Allin API" @@ -29,28 +23,5 @@ fun Application.basicRouter() { }) { call.respond(ApiMessage.WELCOME) } - post("/image") { - val base64Image = call.receiveText() - val imageBytes = Base64.getDecoder().decode(base64Image) - val fileName = "${UUID.randomUUID()}.png" - val file = File("uploads/$fileName") - - file.parentFile.mkdirs() - file.writeBytes(imageBytes) - - val imageUrl = "https://codefirst.iut.uca.fr/containers/AllDev-api/images/$fileName" - call.respond(HttpStatusCode.OK, ImageResponse(imageUrl)) - } - - get("/images/{fileName}") { - val fileName = call.parameters["fileName"] - val file = File("uploads/$fileName") - - if (file.exists()) { - call.respondFile(file) - } else { - call.respond(HttpStatusCode.NotFound, "File not found") - } - } } } \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/routing/userRouter.kt b/Sources/src/main/kotlin/allin/routing/userRouter.kt index ace7d8b..b81a378 100644 --- a/Sources/src/main/kotlin/allin/routing/userRouter.kt +++ b/Sources/src/main/kotlin/allin/routing/userRouter.kt @@ -4,6 +4,9 @@ import allin.dataSource import allin.dto.UserDTO import allin.ext.hasToken import allin.ext.verifyUserFromToken +import allin.hostIP +import allin.hostPort +import allin.isCodeFirstContainer import allin.model.* import allin.utils.AppConfig import io.github.smiley4.ktorswaggerui.dsl.get @@ -15,6 +18,7 @@ import io.ktor.server.auth.jwt.* import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* +import java.io.File import java.util.* val RegexCheckerUser = AppConfig.regexChecker @@ -107,6 +111,23 @@ fun Application.userRouter() { } } + get("/users/images/{fileName}") { + val fileName = call.parameters["fileName"] + val file = File("images/$fileName.png") + if (file.exists()) { + call.respondFile(file) + } else { + val imageBytes = userDataSource.getImage(fileName.toString()) + if (imageBytes != null) { + file.parentFile.mkdirs() + file.writeBytes(imageBytes) + call.respondFile(file) + } else { + call.respond(HttpStatusCode.NotFound, "File not found") + } + } + } + authenticate { post("/users/delete", { description = "Allow you to delete your account" @@ -198,6 +219,47 @@ fun Application.userRouter() { } } } + + post("/users/image", { + description = "Allow you to add a profil image" + + request { + headerParameter("JWT token of the logged user") + body { + description = "User information" + } + } + response { + HttpStatusCode.Accepted to { + description = "Image added" + } + HttpStatusCode.NotFound to { + description = "User not found" + body(ApiMessage.INCORRECT_LOGIN_PASSWORD) + } + } + + }) { + hasToken { principal -> + verifyUserFromToken(userDataSource, principal) { user , _ -> + + val base64Image = call.receiveText() + val imageBytes = Base64.getDecoder().decode(base64Image) + + val urlfile = "images/${user.id}" + val file = File("${urlfile}.png") + file.parentFile.mkdirs() + file.writeBytes(imageBytes) + userDataSource.removeImage(user.id) + userDataSource.addImage(user.id,imageBytes) + if(isCodeFirstContainer.isEmpty()){ + call.respond(HttpStatusCode.OK, "http://${hostIP}:${hostPort}/users/${urlfile}") + } + else call.respond(HttpStatusCode.OK, "${isCodeFirstContainer}/${urlfile}") + } + } + } + } } } diff --git a/Sources/src/test/kotlin/allin/ApplicationTest.kt b/Sources/src/test/kotlin/allin/ApplicationTest.kt index 055425d..9dd77ad 100644 --- a/Sources/src/test/kotlin/allin/ApplicationTest.kt +++ b/Sources/src/test/kotlin/allin/ApplicationTest.kt @@ -1,4 +1,5 @@ package allin class ApplicationTest { + } From 6de6f78fe2362dcde71d8f36a1bd0d39dcb2a361 Mon Sep 17 00:00:00 2001 From: luevard <99143550+saucepommefrite@users.noreply.github.com> Date: Thu, 30 May 2024 13:42:37 +0200 Subject: [PATCH 04/12] :sparkles: [no_ci] Add SQL table for user image --- .../kotlin/allin/data/postgres/PostgresDataSource.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Sources/src/main/kotlin/allin/data/postgres/PostgresDataSource.kt b/Sources/src/main/kotlin/allin/data/postgres/PostgresDataSource.kt index 41b075b..8df9ea3 100644 --- a/Sources/src/main/kotlin/allin/data/postgres/PostgresDataSource.kt +++ b/Sources/src/main/kotlin/allin/data/postgres/PostgresDataSource.kt @@ -125,6 +125,16 @@ class PostgresDataSource : AllInDataSource() { ) """.trimIndent() ) + + database.execute( + """ + CREATE TABLE IF NOT EXISTS public.userimage + ( + user_id VARCHAR(255) PRIMARY KEY, + image bytea + ) + """.trimIndent() + ) } override val userDataSource: UserDataSource by lazy { PostgresUserDataSource(database) } From f9ae6c399b1e5f0c4690c591cce9a125209b643f Mon Sep 17 00:00:00 2001 From: luevard Date: Thu, 30 May 2024 23:35:48 +0200 Subject: [PATCH 05/12] :sparkles: Test User image --- .../allin/data/mock/MockUserDataSource.kt | 3 +- .../allin/data/postgres/PostgresDataSource.kt | 2 +- .../data/postgres/PostgresUserDataSource.kt | 2 +- .../data/postgres/entities/UserEntity.kt | 18 ++++++++-- Sources/src/main/kotlin/allin/dto/UserDTO.kt | 3 +- Sources/src/main/kotlin/allin/model/User.kt | 2 +- .../main/kotlin/allin/routing/userRouter.kt | 34 +++++++++---------- .../src/main/kotlin/allin/utils/AppConfig.kt | 2 ++ .../main/kotlin/allin/utils/ImageManager.kt | 22 ++++++++++++ .../src/main/kotlin/allin/utils/URLManager.kt | 13 +++++++ 10 files changed, 77 insertions(+), 24 deletions(-) create mode 100644 Sources/src/main/kotlin/allin/utils/ImageManager.kt create mode 100644 Sources/src/main/kotlin/allin/utils/URLManager.kt diff --git a/Sources/src/main/kotlin/allin/data/mock/MockUserDataSource.kt b/Sources/src/main/kotlin/allin/data/mock/MockUserDataSource.kt index 03a63b2..369dcb9 100644 --- a/Sources/src/main/kotlin/allin/data/mock/MockUserDataSource.kt +++ b/Sources/src/main/kotlin/allin/data/mock/MockUserDataSource.kt @@ -17,7 +17,8 @@ class MockUserDataSource(private val mockData: MockDataSource.MockData) : UserDa username = it.username, email = it.email, nbCoins = it.nbCoins, - token = it.token + token = it.token, + image = null ), it.password ) diff --git a/Sources/src/main/kotlin/allin/data/postgres/PostgresDataSource.kt b/Sources/src/main/kotlin/allin/data/postgres/PostgresDataSource.kt index 8df9ea3..f20b047 100644 --- a/Sources/src/main/kotlin/allin/data/postgres/PostgresDataSource.kt +++ b/Sources/src/main/kotlin/allin/data/postgres/PostgresDataSource.kt @@ -128,7 +128,7 @@ class PostgresDataSource : AllInDataSource() { database.execute( """ - CREATE TABLE IF NOT EXISTS public.userimage + CREATE TABLE IF NOT EXISTS userimage ( user_id VARCHAR(255) PRIMARY KEY, image bytea diff --git a/Sources/src/main/kotlin/allin/data/postgres/PostgresUserDataSource.kt b/Sources/src/main/kotlin/allin/data/postgres/PostgresUserDataSource.kt index c9e858f..40329f5 100644 --- a/Sources/src/main/kotlin/allin/data/postgres/PostgresUserDataSource.kt +++ b/Sources/src/main/kotlin/allin/data/postgres/PostgresUserDataSource.kt @@ -18,7 +18,7 @@ class PostgresUserDataSource(private val database: Database) : UserDataSource { override fun getUserByUsername(username: String): Pair = database.users .find { (it.username eq username) or (it.email eq username) } - ?.let { it.toUserDTO() to it.password } + ?.let { it.toUserDTO(database) to it.password } ?: (null to null) override fun addUser(user: User) { diff --git a/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt b/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt index 463b91e..b90fb5d 100644 --- a/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt +++ b/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt @@ -1,8 +1,12 @@ package allin.data.postgres.entities import allin.dto.UserDTO +import allin.routing.imageManagerUser +import allin.utils.AppConfig import org.ktorm.database.Database +import org.ktorm.dsl.eq import org.ktorm.entity.Entity +import org.ktorm.entity.find import org.ktorm.entity.sequenceOf import org.ktorm.schema.Table import org.ktorm.schema.int @@ -20,14 +24,24 @@ interface UserEntity : Entity { var nbCoins: Int var lastGift: Instant - fun toUserDTO() = + fun toUserDTO(database: Database) = UserDTO( id = id, username = username, email = email, nbCoins = nbCoins, - token = null + token = null, + image = getImage(id, database) ) + + fun getImage(userId: String, database: Database): String? { + val imageByte = database.usersimage.find { it.id eq id }?.image ?: return null + val urlfile = "image/$userId" + if (!imageManagerUser.imageAvailable(urlfile)) { + imageManagerUser.saveImage(urlfile, imageByte) + } + return "${AppConfig.urlManager.getURL()}${urlfile}" + } } object UsersEntity : Table("users") { diff --git a/Sources/src/main/kotlin/allin/dto/UserDTO.kt b/Sources/src/main/kotlin/allin/dto/UserDTO.kt index b4cc2bf..83b5bd9 100644 --- a/Sources/src/main/kotlin/allin/dto/UserDTO.kt +++ b/Sources/src/main/kotlin/allin/dto/UserDTO.kt @@ -8,5 +8,6 @@ data class UserDTO( val username: String, val email: String, val nbCoins: Int, - var token: String? + var token: String?, + val image: String? ) \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/model/User.kt b/Sources/src/main/kotlin/allin/model/User.kt index 534add7..fec7d28 100644 --- a/Sources/src/main/kotlin/allin/model/User.kt +++ b/Sources/src/main/kotlin/allin/model/User.kt @@ -33,4 +33,4 @@ data class CheckUser( data class UserImage( val id: String, val image: ByteArray, -) \ No newline at end of file +) diff --git a/Sources/src/main/kotlin/allin/routing/userRouter.kt b/Sources/src/main/kotlin/allin/routing/userRouter.kt index b81a378..7a04fe9 100644 --- a/Sources/src/main/kotlin/allin/routing/userRouter.kt +++ b/Sources/src/main/kotlin/allin/routing/userRouter.kt @@ -24,6 +24,8 @@ import java.util.* val RegexCheckerUser = AppConfig.regexChecker val CryptManagerUser = AppConfig.cryptManager val tokenManagerUser = AppConfig.tokenManager +val imageManagerUser = AppConfig.imageManager + const val DEFAULT_COINS = 500 @@ -59,11 +61,9 @@ fun Application.userRouter() { val tempUser = call.receive() if (RegexCheckerUser.isEmailInvalid(tempUser.email)) { call.respond(HttpStatusCode.Forbidden, ApiMessage.INVALID_MAIL) - } - else if (userDataSource.userExists(tempUser.username)) { + } else if (userDataSource.userExists(tempUser.username)) { call.respond(HttpStatusCode.Conflict, ApiMessage.USER_ALREADY_EXISTS) - } - else if (userDataSource.emailExists(tempUser.email)) { + } else if (userDataSource.emailExists(tempUser.email)) { call.respond(HttpStatusCode.Conflict, ApiMessage.MAIL_ALREADY_EXISTS) } else { val user = User( @@ -113,14 +113,16 @@ fun Application.userRouter() { get("/users/images/{fileName}") { val fileName = call.parameters["fileName"] - val file = File("images/$fileName.png") + + val urlfile = "images/$fileName" + + val file = File("$urlfile.png") if (file.exists()) { call.respondFile(file) } else { val imageBytes = userDataSource.getImage(fileName.toString()) if (imageBytes != null) { - file.parentFile.mkdirs() - file.writeBytes(imageBytes) + imageManagerUser.saveImage(urlfile, imageBytes.toString()) call.respondFile(file) } else { call.respond(HttpStatusCode.NotFound, "File not found") @@ -241,21 +243,19 @@ fun Application.userRouter() { }) { hasToken { principal -> - verifyUserFromToken(userDataSource, principal) { user , _ -> + verifyUserFromToken(userDataSource, principal) { user, _ -> val base64Image = call.receiveText() - val imageBytes = Base64.getDecoder().decode(base64Image) val urlfile = "images/${user.id}" - val file = File("${urlfile}.png") - file.parentFile.mkdirs() - file.writeBytes(imageBytes) - userDataSource.removeImage(user.id) - userDataSource.addImage(user.id,imageBytes) - if(isCodeFirstContainer.isEmpty()){ - call.respond(HttpStatusCode.OK, "http://${hostIP}:${hostPort}/users/${urlfile}") + val imageByteArray = imageManagerUser.saveImage(urlfile, base64Image) + if (imageByteArray != null && imageByteArray.isNotEmpty()) { + userDataSource.removeImage(user.id) + userDataSource.addImage(user.id, imageByteArray) + if (isCodeFirstContainer.isEmpty()) { + call.respond(HttpStatusCode.OK, "http://${hostIP}:${hostPort}/users/${urlfile}") + } else call.respond(HttpStatusCode.OK, "${isCodeFirstContainer}/${urlfile}") } - else call.respond(HttpStatusCode.OK, "${isCodeFirstContainer}/${urlfile}") } } } diff --git a/Sources/src/main/kotlin/allin/utils/AppConfig.kt b/Sources/src/main/kotlin/allin/utils/AppConfig.kt index 554e138..7aaddc8 100644 --- a/Sources/src/main/kotlin/allin/utils/AppConfig.kt +++ b/Sources/src/main/kotlin/allin/utils/AppConfig.kt @@ -8,4 +8,6 @@ object AppConfig { val tokenManager = TokenManager.getInstance(config) val regexChecker = RegexChecker() val cryptManager = CryptManager() + val imageManager = ImageManager() + val urlManager = URLManager() } diff --git a/Sources/src/main/kotlin/allin/utils/ImageManager.kt b/Sources/src/main/kotlin/allin/utils/ImageManager.kt new file mode 100644 index 0000000..6429544 --- /dev/null +++ b/Sources/src/main/kotlin/allin/utils/ImageManager.kt @@ -0,0 +1,22 @@ +package allin.utils + +import java.io.File +import java.util.* + +class ImageManager { + fun saveImage(urlfile: String, base64Image: String): ByteArray? { + val imageBytes = Base64.getDecoder().decode(base64Image) + val file = File("${urlfile}.png") + file.parentFile.mkdirs() + file.writeBytes(imageBytes) + return imageBytes + } + + fun saveImage(urlfile: String, base64Image: ByteArray) { + val file = File("${urlfile}.png") + file.parentFile.mkdirs() + file.writeBytes(base64Image) + } + + fun imageAvailable(urlfile: String) = File(urlfile).exists() +} \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/utils/URLManager.kt b/Sources/src/main/kotlin/allin/utils/URLManager.kt new file mode 100644 index 0000000..8d4432f --- /dev/null +++ b/Sources/src/main/kotlin/allin/utils/URLManager.kt @@ -0,0 +1,13 @@ +package allin.utils + +import allin.hostIP +import allin.hostPort +import allin.isCodeFirstContainer + +class URLManager { + fun getURL(): String { + return if (isCodeFirstContainer.isEmpty()) { + "http://$hostIP:$hostPort/" + } else isCodeFirstContainer + } +} \ No newline at end of file From 19aa5620a62f7327a2b8bf5ba13305ff96a21c17 Mon Sep 17 00:00:00 2001 From: luevard Date: Thu, 30 May 2024 23:44:14 +0200 Subject: [PATCH 06/12] :sparkles: Change URI --- Sources/src/main/kotlin/allin/utils/URLManager.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/src/main/kotlin/allin/utils/URLManager.kt b/Sources/src/main/kotlin/allin/utils/URLManager.kt index 8d4432f..15e44ae 100644 --- a/Sources/src/main/kotlin/allin/utils/URLManager.kt +++ b/Sources/src/main/kotlin/allin/utils/URLManager.kt @@ -8,6 +8,6 @@ class URLManager { fun getURL(): String { return if (isCodeFirstContainer.isEmpty()) { "http://$hostIP:$hostPort/" - } else isCodeFirstContainer + } else "http://codefirst.iut.uca.fr${isCodeFirstContainer}" } } \ No newline at end of file From 7aff06a86df8e3552dbbd16646449e0496d8196f Mon Sep 17 00:00:00 2001 From: luevard Date: Thu, 30 May 2024 23:50:30 +0200 Subject: [PATCH 07/12] :sparkles: Change URI --- Sources/src/main/kotlin/allin/routing/userRouter.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Sources/src/main/kotlin/allin/routing/userRouter.kt b/Sources/src/main/kotlin/allin/routing/userRouter.kt index 7a04fe9..2417100 100644 --- a/Sources/src/main/kotlin/allin/routing/userRouter.kt +++ b/Sources/src/main/kotlin/allin/routing/userRouter.kt @@ -4,9 +4,6 @@ import allin.dataSource import allin.dto.UserDTO import allin.ext.hasToken import allin.ext.verifyUserFromToken -import allin.hostIP -import allin.hostPort -import allin.isCodeFirstContainer import allin.model.* import allin.utils.AppConfig import io.github.smiley4.ktorswaggerui.dsl.get @@ -25,6 +22,7 @@ val RegexCheckerUser = AppConfig.regexChecker val CryptManagerUser = AppConfig.cryptManager val tokenManagerUser = AppConfig.tokenManager val imageManagerUser = AppConfig.imageManager +val urlManager = AppConfig.urlManager const val DEFAULT_COINS = 500 @@ -252,10 +250,9 @@ fun Application.userRouter() { if (imageByteArray != null && imageByteArray.isNotEmpty()) { userDataSource.removeImage(user.id) userDataSource.addImage(user.id, imageByteArray) - if (isCodeFirstContainer.isEmpty()) { - call.respond(HttpStatusCode.OK, "http://${hostIP}:${hostPort}/users/${urlfile}") - } else call.respond(HttpStatusCode.OK, "${isCodeFirstContainer}/${urlfile}") + call.respond(HttpStatusCode.OK, "${urlManager.getURL()}/users/${urlfile}") } + call.respond(HttpStatusCode.Conflict) } } } From 8be915ac9cd16241589edb95574955c59b29b543 Mon Sep 17 00:00:00 2001 From: luevard Date: Thu, 30 May 2024 23:53:23 +0200 Subject: [PATCH 08/12] :sparkles: Change URI --- .../src/main/kotlin/allin/data/postgres/entities/UserEntity.kt | 2 +- Sources/src/main/kotlin/allin/routing/userRouter.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt b/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt index b90fb5d..a0895ec 100644 --- a/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt +++ b/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt @@ -40,7 +40,7 @@ interface UserEntity : Entity { if (!imageManagerUser.imageAvailable(urlfile)) { imageManagerUser.saveImage(urlfile, imageByte) } - return "${AppConfig.urlManager.getURL()}${urlfile}" + return "${AppConfig.urlManager.getURL()}/users/${urlfile}" } } diff --git a/Sources/src/main/kotlin/allin/routing/userRouter.kt b/Sources/src/main/kotlin/allin/routing/userRouter.kt index 2417100..da43808 100644 --- a/Sources/src/main/kotlin/allin/routing/userRouter.kt +++ b/Sources/src/main/kotlin/allin/routing/userRouter.kt @@ -250,7 +250,7 @@ fun Application.userRouter() { if (imageByteArray != null && imageByteArray.isNotEmpty()) { userDataSource.removeImage(user.id) userDataSource.addImage(user.id, imageByteArray) - call.respond(HttpStatusCode.OK, "${urlManager.getURL()}/users/${urlfile}") + call.respond(HttpStatusCode.OK, "${urlManager.getURL()}users/${urlfile}") } call.respond(HttpStatusCode.Conflict) } From 8af569d8c0e25ff7fdfbae01792041d2099d73bf Mon Sep 17 00:00:00 2001 From: luevard Date: Thu, 30 May 2024 23:56:45 +0200 Subject: [PATCH 09/12] :sparkles: Last change URI --- .../src/main/kotlin/allin/data/postgres/entities/UserEntity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt b/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt index a0895ec..1815a18 100644 --- a/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt +++ b/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt @@ -40,7 +40,7 @@ interface UserEntity : Entity { if (!imageManagerUser.imageAvailable(urlfile)) { imageManagerUser.saveImage(urlfile, imageByte) } - return "${AppConfig.urlManager.getURL()}/users/${urlfile}" + return "${AppConfig.urlManager.getURL()}users/${urlfile}" } } From 73d33cc5f09c8b211ca2c6d566a2d54ddeb1e5c3 Mon Sep 17 00:00:00 2001 From: luevard Date: Thu, 30 May 2024 23:59:52 +0200 Subject: [PATCH 10/12] :sparkles: Last change URI --- .../src/main/kotlin/allin/data/postgres/entities/UserEntity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt b/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt index 1815a18..c994589 100644 --- a/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt +++ b/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt @@ -36,7 +36,7 @@ interface UserEntity : Entity { fun getImage(userId: String, database: Database): String? { val imageByte = database.usersimage.find { it.id eq id }?.image ?: return null - val urlfile = "image/$userId" + val urlfile = "images/$userId" if (!imageManagerUser.imageAvailable(urlfile)) { imageManagerUser.saveImage(urlfile, imageByte) } From 90694322259720c0e90cc4567f1a4697c6fdcfc8 Mon Sep 17 00:00:00 2001 From: luevard <99143550+saucepommefrite@users.noreply.github.com> Date: Fri, 31 May 2024 11:07:44 +0200 Subject: [PATCH 11/12] :sparkles: Clean Base64 from database --- .../src/main/kotlin/allin/data/UserDataSource.kt | 2 +- .../kotlin/allin/data/mock/MockBetDataSource.kt | 1 - .../kotlin/allin/data/mock/MockUserDataSource.kt | 2 +- .../allin/data/postgres/PostgresUserDataSource.kt | 15 +++++++++++++-- .../src/main/kotlin/allin/routing/userRouter.kt | 4 +--- .../src/main/kotlin/allin/utils/ImageManager.kt | 6 +++++- 6 files changed, 21 insertions(+), 9 deletions(-) diff --git a/Sources/src/main/kotlin/allin/data/UserDataSource.kt b/Sources/src/main/kotlin/allin/data/UserDataSource.kt index 273de87..a116264 100644 --- a/Sources/src/main/kotlin/allin/data/UserDataSource.kt +++ b/Sources/src/main/kotlin/allin/data/UserDataSource.kt @@ -14,5 +14,5 @@ interface UserDataSource { fun canHaveDailyGift(username: String): Boolean fun addImage(userid: String, image: ByteArray) fun removeImage(userid: String) - fun getImage(userid: String): ByteArray? + fun getImage(userid: String): String? } \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/data/mock/MockBetDataSource.kt b/Sources/src/main/kotlin/allin/data/mock/MockBetDataSource.kt index 7c522ea..c53d894 100644 --- a/Sources/src/main/kotlin/allin/data/mock/MockBetDataSource.kt +++ b/Sources/src/main/kotlin/allin/data/mock/MockBetDataSource.kt @@ -55,7 +55,6 @@ class MockBetDataSource(private val mockData: MockDataSource.MockData) : BetData }.map { it } } } - } override fun getBetById(id: String): Bet? = diff --git a/Sources/src/main/kotlin/allin/data/mock/MockUserDataSource.kt b/Sources/src/main/kotlin/allin/data/mock/MockUserDataSource.kt index 369dcb9..46d0b04 100644 --- a/Sources/src/main/kotlin/allin/data/mock/MockUserDataSource.kt +++ b/Sources/src/main/kotlin/allin/data/mock/MockUserDataSource.kt @@ -65,7 +65,7 @@ class MockUserDataSource(private val mockData: MockDataSource.MockData) : UserDa TODO("Not yet implemented") } - override fun getImage(userid: String): ByteArray? { + override fun getImage(userid: String): String? { TODO("Not yet implemented") } diff --git a/Sources/src/main/kotlin/allin/data/postgres/PostgresUserDataSource.kt b/Sources/src/main/kotlin/allin/data/postgres/PostgresUserDataSource.kt index 40329f5..566b21d 100644 --- a/Sources/src/main/kotlin/allin/data/postgres/PostgresUserDataSource.kt +++ b/Sources/src/main/kotlin/allin/data/postgres/PostgresUserDataSource.kt @@ -92,7 +92,18 @@ class PostgresUserDataSource(private val database: Database) : UserDataSource { database.usersimage.removeIf { it.id eq userid } } - override fun getImage(userid: String): ByteArray? = - database.usersimage.find { it.id eq userid }?.image + /*override fun getImage(userid: String): ByteArray? = + database.usersimage.find { it.id eq userid }?.image*/ + override fun getImage(userid: String): String? { + val resultSet = database.executeWithResult("SELECT encode(image, 'base64') AS image FROM userimage WHERE user_id = '${userid}'")?: return null + + if (resultSet.next()) { + val base64Image: String? = resultSet.getString("image") + if (base64Image != null) { + return base64Image + } + } + return null + } } \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/routing/userRouter.kt b/Sources/src/main/kotlin/allin/routing/userRouter.kt index da43808..06ec225 100644 --- a/Sources/src/main/kotlin/allin/routing/userRouter.kt +++ b/Sources/src/main/kotlin/allin/routing/userRouter.kt @@ -111,16 +111,14 @@ fun Application.userRouter() { get("/users/images/{fileName}") { val fileName = call.parameters["fileName"] - val urlfile = "images/$fileName" - val file = File("$urlfile.png") if (file.exists()) { call.respondFile(file) } else { val imageBytes = userDataSource.getImage(fileName.toString()) if (imageBytes != null) { - imageManagerUser.saveImage(urlfile, imageBytes.toString()) + imageManagerUser.saveImage(urlfile, imageBytes) call.respondFile(file) } else { call.respond(HttpStatusCode.NotFound, "File not found") diff --git a/Sources/src/main/kotlin/allin/utils/ImageManager.kt b/Sources/src/main/kotlin/allin/utils/ImageManager.kt index 6429544..18b977b 100644 --- a/Sources/src/main/kotlin/allin/utils/ImageManager.kt +++ b/Sources/src/main/kotlin/allin/utils/ImageManager.kt @@ -4,8 +4,10 @@ import java.io.File import java.util.* class ImageManager { + fun saveImage(urlfile: String, base64Image: String): ByteArray? { - val imageBytes = Base64.getDecoder().decode(base64Image) + val cleanedBase64Image = cleanBase64(base64Image) + val imageBytes = Base64.getDecoder().decode(cleanedBase64Image) val file = File("${urlfile}.png") file.parentFile.mkdirs() file.writeBytes(imageBytes) @@ -19,4 +21,6 @@ class ImageManager { } fun imageAvailable(urlfile: String) = File(urlfile).exists() + + fun cleanBase64(base64Image: String) = base64Image.replace("\n", "").replace("\r", "") } \ No newline at end of file From 5229765d6b8b55bb6a567ac300308fb852e8cb45 Mon Sep 17 00:00:00 2001 From: luevard <99143550+saucepommefrite@users.noreply.github.com> Date: Fri, 31 May 2024 11:44:13 +0200 Subject: [PATCH 12/12] :sparkles: Add UserDTO information (number of friends, number of bets and the best win) --- .../allin/data/ParticipationDataSource.kt | 1 + .../data/mock/MockParticipationDataSource.kt | 4 ++++ .../allin/data/mock/MockUserDataSource.kt | 17 +++++++++++++---- .../postgres/PostgresParticipationDataSource.kt | 5 +++++ .../data/postgres/PostgresUserDataSource.kt | 4 ---- .../allin/data/postgres/entities/UserEntity.kt | 8 +++++++- Sources/src/main/kotlin/allin/dto/UserDTO.kt | 5 ++++- Sources/src/main/kotlin/allin/model/User.kt | 3 ++- 8 files changed, 36 insertions(+), 11 deletions(-) diff --git a/Sources/src/main/kotlin/allin/data/ParticipationDataSource.kt b/Sources/src/main/kotlin/allin/data/ParticipationDataSource.kt index 1e6b3d8..5490ff9 100644 --- a/Sources/src/main/kotlin/allin/data/ParticipationDataSource.kt +++ b/Sources/src/main/kotlin/allin/data/ParticipationDataSource.kt @@ -7,4 +7,5 @@ interface ParticipationDataSource { fun getParticipationFromBetId(betid: String): List fun getParticipationFromUserId(username: String, betid: String): List fun deleteParticipation(id: String): Boolean + fun getBestWinFromUserid(userId: String): Int? } \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/data/mock/MockParticipationDataSource.kt b/Sources/src/main/kotlin/allin/data/mock/MockParticipationDataSource.kt index 653191a..68701f3 100644 --- a/Sources/src/main/kotlin/allin/data/mock/MockParticipationDataSource.kt +++ b/Sources/src/main/kotlin/allin/data/mock/MockParticipationDataSource.kt @@ -81,4 +81,8 @@ class MockParticipationDataSource(private val mockData: MockDataSource.MockData) return result } + override fun getBestWinFromUserid(userId: String) = + mockData.participations.filter { it.id == userId }.maxBy { it.stake }.stake + + } \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/data/mock/MockUserDataSource.kt b/Sources/src/main/kotlin/allin/data/mock/MockUserDataSource.kt index 46d0b04..004bb28 100644 --- a/Sources/src/main/kotlin/allin/data/mock/MockUserDataSource.kt +++ b/Sources/src/main/kotlin/allin/data/mock/MockUserDataSource.kt @@ -18,7 +18,10 @@ class MockUserDataSource(private val mockData: MockDataSource.MockData) : UserDa email = it.email, nbCoins = it.nbCoins, token = it.token, - image = null + image = null, + nbBets = MockBetDataSource(mockData).getHistory(it.username).count(), + nbFriends = MockFriendDataSource(mockData).getFriendFromUserId(it.id).count(), + bestWin = MockParticipationDataSource(mockData).getBestWinFromUserid(it.id) ), it.password ) @@ -58,15 +61,21 @@ class MockUserDataSource(private val mockData: MockDataSource.MockData) : UserDa } override fun addImage(userid: String, image: ByteArray) { - TODO("Not yet implemented") + val user = users.find { it.id == userid } + if (user != null) { + user.image = image.toString() + } } override fun removeImage(userid: String) { - TODO("Not yet implemented") + val user = users.find { it.id == userid } + if (user != null) { + user.image = null + } } override fun getImage(userid: String): String? { - TODO("Not yet implemented") + return users.find { it.id == userid }?.image } } \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/data/postgres/PostgresParticipationDataSource.kt b/Sources/src/main/kotlin/allin/data/postgres/PostgresParticipationDataSource.kt index 4ba7fa8..f7d9a29 100644 --- a/Sources/src/main/kotlin/allin/data/postgres/PostgresParticipationDataSource.kt +++ b/Sources/src/main/kotlin/allin/data/postgres/PostgresParticipationDataSource.kt @@ -64,5 +64,10 @@ class PostgresParticipationDataSource(private val database: Database) : Particip } return participation.delete() > 0 } + + override fun getBestWinFromUserid(userId: String) = + database.participations.filter { it.id eq userId }.maxBy { it.stake } + + } diff --git a/Sources/src/main/kotlin/allin/data/postgres/PostgresUserDataSource.kt b/Sources/src/main/kotlin/allin/data/postgres/PostgresUserDataSource.kt index 566b21d..2413c49 100644 --- a/Sources/src/main/kotlin/allin/data/postgres/PostgresUserDataSource.kt +++ b/Sources/src/main/kotlin/allin/data/postgres/PostgresUserDataSource.kt @@ -92,12 +92,8 @@ class PostgresUserDataSource(private val database: Database) : UserDataSource { database.usersimage.removeIf { it.id eq userid } } - /*override fun getImage(userid: String): ByteArray? = - database.usersimage.find { it.id eq userid }?.image*/ - override fun getImage(userid: String): String? { val resultSet = database.executeWithResult("SELECT encode(image, 'base64') AS image FROM userimage WHERE user_id = '${userid}'")?: return null - if (resultSet.next()) { val base64Image: String? = resultSet.getString("image") if (base64Image != null) { diff --git a/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt b/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt index c994589..a86f6d2 100644 --- a/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt +++ b/Sources/src/main/kotlin/allin/data/postgres/entities/UserEntity.kt @@ -1,5 +1,8 @@ package allin.data.postgres.entities +import allin.data.postgres.PostgresBetDataSource +import allin.data.postgres.PostgresFriendDataSource +import allin.data.postgres.PostgresParticipationDataSource import allin.dto.UserDTO import allin.routing.imageManagerUser import allin.utils.AppConfig @@ -31,7 +34,10 @@ interface UserEntity : Entity { email = email, nbCoins = nbCoins, token = null, - image = getImage(id, database) + image = getImage(id, database), + nbBets = PostgresBetDataSource(database).getHistory(username).count(), + nbFriends = PostgresFriendDataSource(database).getFriendFromUserId(id).count(), + bestWin = PostgresParticipationDataSource(database).getBestWinFromUserid(id)?: 0, ) fun getImage(userId: String, database: Database): String? { diff --git a/Sources/src/main/kotlin/allin/dto/UserDTO.kt b/Sources/src/main/kotlin/allin/dto/UserDTO.kt index 83b5bd9..1e46a6a 100644 --- a/Sources/src/main/kotlin/allin/dto/UserDTO.kt +++ b/Sources/src/main/kotlin/allin/dto/UserDTO.kt @@ -9,5 +9,8 @@ data class UserDTO( val email: String, val nbCoins: Int, var token: String?, - val image: String? + val image: String?, + var nbBets: Int, + var nbFriends: Int, + var bestWin: Int ) \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/model/User.kt b/Sources/src/main/kotlin/allin/model/User.kt index fec7d28..a1f76d8 100644 --- a/Sources/src/main/kotlin/allin/model/User.kt +++ b/Sources/src/main/kotlin/allin/model/User.kt @@ -13,7 +13,8 @@ data class User( val email: String, var password: String, var nbCoins: Int = DEFAULT_COIN_AMOUNT, - var token: String? = null + var token: String? = null, + var image: String? = null, ) @Serializable