Skip to content

Commit

Permalink
chess-service
Browse files Browse the repository at this point in the history
  • Loading branch information
MichiBaum committed Oct 7, 2024
1 parent 1130a3d commit 3cf5b92
Show file tree
Hide file tree
Showing 47 changed files with 147,620 additions and 131 deletions.
5 changes: 5 additions & 0 deletions chess-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.wiremock</groupId>
<artifactId>wiremock-standalone</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.michibaum.chess.apis
import com.michibaum.chess.apis.dtos.AccountDto
import com.michibaum.chess.apis.dtos.StatsDto
import com.michibaum.chess.domain.Account
import com.michibaum.chess.domain.ChessPlatforms
import com.michibaum.chess.domain.ChessPlatform
import org.springframework.stereotype.Service

@Service
Expand All @@ -22,8 +22,8 @@ class ApiService(

fun getStats(account: Account): ApiResult<StatsDto> {
return when (account.platform) {
ChessPlatforms.CHESSCOM -> chesscomApiService.getStats(account.username)
ChessPlatforms.LICHESS -> lichessApiService.getStats(account.username)
ChessPlatform.CHESSCOM -> chesscomApiService.getStats(account)
ChessPlatform.LICHESS -> lichessApiService.getStats(account)
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package com.michibaum.chess.apis
import com.michibaum.chess.apis.dtos.AccountDto
import com.michibaum.chess.apis.dtos.GameDto
import com.michibaum.chess.apis.dtos.StatsDto
import com.michibaum.chess.domain.Account

interface IApiService {

fun findUser(username: String): ApiResult<AccountDto>

fun getStats(username: String): ApiResult<StatsDto>
fun getStats(account: Account): ApiResult<StatsDto>

fun getGames(username: String): ApiResult<List<GameDto>>
fun getGames(account: Account): ApiResult<List<GameDto>>

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@ import com.michibaum.chess.apis.config.ChessConfigProperties
import com.michibaum.chess.apis.dtos.AccountDto
import com.michibaum.chess.apis.dtos.GameDto
import com.michibaum.chess.apis.dtos.StatsDto
import com.michibaum.chess.domain.ChessPlatforms
import com.michibaum.chess.domain.Account
import com.michibaum.chess.domain.ChessPlatform
import org.springframework.http.MediaType
import org.springframework.stereotype.Service
import java.time.LocalDate
import java.time.Year
import java.time.format.DateTimeFormatter
import java.util.*


@Service(value = "chesscomApiService")
class ApiServiceImpl(
chessConfigProperties: ChessConfigProperties,
val converter: Converter
): IApiService {

val client = chessConfigProperties.getWebClient(ChessPlatforms.CHESSCOM)
val client = chessConfigProperties.getWebClient(ChessPlatform.CHESSCOM)

override fun findUser(username: String): ApiResult<AccountDto> {
val result = try {
Expand All @@ -36,10 +42,10 @@ class ApiServiceImpl(
return Success(accountDto)
}

override fun getStats(username: String): ApiResult<StatsDto> {
override fun getStats(account: Account): ApiResult<StatsDto> {
val result = try {
client.get()
.uri("/pub/player/{0}/stats", username)
.uri("/pub/player/{0}/stats", account.username)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(ChesscomStatsDto::class.java) // TODO onError
Expand All @@ -55,27 +61,57 @@ class ApiServiceImpl(
return Success(statsDto)
}

override fun getGames(username: String): ApiResult<List<GameDto>> { // TODO Year and month
val currentYear = "2024"
val currentMonth = "09"
override fun getGames(account: Account): ApiResult<List<GameDto>> { // TODO Year and month
val creationYear = run {
val calendar = Calendar.getInstance()
calendar.time = account.createdAt
calendar.get(Calendar.YEAR);
}

val result = try {
client.get()
.uri("/pub/player/{0}/games/{1}/{2}", username, currentYear, currentMonth)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(Gamesresult::class.java)
.mapNotNull { it.games }
.block()
} catch (throwable: Throwable){
return Exception(throwable)
val years = IntRange(creationYear, Year.now().value)
val months = IntRange(1, 12)

val results = mutableListOf<MutableList<ChesscomGameDto?>?>()
for (year in years){
for (month in months){
val currentMonth = getMonth(month)
val currentYear = year.toString()

val dateIsInTheFuture = LocalDate.now().isBefore(LocalDate.parse("$currentYear-$currentMonth-01", DateTimeFormatter.ofPattern( "yyyy-MM-dd" )))
if(dateIsInTheFuture)
continue

val result = try {
client.get()
.uri("/pub/player/{0}/games/{1}/{2}", account.username, currentYear, currentMonth)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(Gamesresult::class.java)
.mapNotNull { it.games }
.block()
} catch (throwable: Throwable){
return Exception(throwable)
}
results.add(result)
}
}

if(result == null)
val allResults = results.filterNotNull()
.flatten()
.filterNotNull()

if(allResults.isEmpty())
return Error("")

val gameDtos = result.mapNotNull { it?.let { converter.convert(it) } }
val gameDtos = allResults.map { it.let { converter.convert(it) } }
return Success(gameDtos)
}

private fun getMonth(month: Int): String =
if (month.toString().length == 1) {
"0$month"
} else {
month.toString()
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package com.michibaum.chess.apis.chesscom
import com.fasterxml.jackson.annotation.JsonProperty

data class Gamesresult(
val games: MutableList<ChesscomGamesDto?> = mutableListOf()
val games: MutableList<ChesscomGameDto?> = mutableListOf()
)

data class ChesscomGamesDto(
data class ChesscomGameDto(
val url: String?, // Can be null, don't know why
val pgn: String?, // Can be null, don't know why
@JsonProperty("time_control")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,52 @@
package com.michibaum.chess.apis.chesscom

import com.michibaum.chess.apis.dtos.AccountDto
import com.michibaum.chess.domain.ChessPlatforms
import com.michibaum.chess.apis.dtos.GameDto
import com.michibaum.chess.apis.dtos.Rating
import com.michibaum.chess.apis.dtos.StatsDto
import com.michibaum.chess.apis.dtos.*
import com.michibaum.chess.apis.dtos.Player
import com.michibaum.chess.domain.ChessPlatform
import com.michibaum.chess.domain.GameType
import org.springframework.stereotype.Component
import java.util.*

@Component(value = "chesscomConverter")
class Converter {

fun convert(accountDto: ChesscomAccountDto): AccountDto {
return AccountDto(
fun convert(accountDto: ChesscomAccountDto): AccountDto =
AccountDto(
id = accountDto.playerId.toString(),
url = accountDto.url,
username = accountDto.username,
name = accountDto.name,
platform = ChessPlatforms.CHESSCOM
platform = ChessPlatform.CHESSCOM,
createdAt = Date(accountDto.joined * 1000)
)
}

fun convert(gamesDto: ChesscomGamesDto): GameDto {
TODO("Not yet implemented")
val player1 = null
val player2 = null
return GameDto(
id = gamesDto.uuid ?: "",
players = listOf()
)
fun convert(gameDto: ChesscomGameDto): GameDto {
val player1 = gameDto.white?.let {
Player(id = it.uuid, username = it.username, rating = it.rating, pieceColor = PieceColor.WHITE)
}

val player2 = gameDto.black?.let {
Player(id = it.uuid, username = it.username, rating = it.rating, pieceColor = PieceColor.BLACK)
}

val gametype = when(gameDto.timeClass){
"bullet" -> GameType.BULLET
"blitz" -> GameType.BLITZ
"rapid" -> GameType.RAPID
else -> GameType.UNKNOWN
}

return GameDto(
chessPlatform = ChessPlatform.CHESSCOM,
id = gameDto.uuid ?: "",
players = listOfNotNull(player1, player2),
pgn = gameDto.pgn ?: "",
gameType = gametype
)
}

fun convert(stats: ChesscomStatsDto): StatsDto {
return StatsDto(
fun convert(stats: ChesscomStatsDto): StatsDto =
StatsDto(
bullet = Rating(
current = stats.chessBullet?.last?.rating,
lowest = null,
Expand All @@ -48,6 +63,5 @@ class Converter {
highest = stats.chessRapid?.best?.rating
),
)
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.michibaum.chess.apis.config

import com.michibaum.chess.domain.ChessPlatforms
import com.michibaum.chess.domain.ChessPlatform
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.web.reactive.function.client.WebClient

Expand All @@ -11,15 +11,19 @@ data class ApisConfigProperties(

val webClient: WebClient = WebClient.builder()
.baseUrl(baseUrl)
.codecs { configurer ->
configurer.defaultCodecs()
.maxInMemorySize(10000000)
}
.build()

}

@ConfigurationProperties(value = "chess-apis")
data class ChessConfigProperties(
var properties: Map<ChessPlatforms, ApisConfigProperties> = emptyMap()
var properties: Map<ChessPlatform, ApisConfigProperties> = emptyMap()
) {
fun getWebClient(apis: ChessPlatforms): WebClient {
fun getWebClient(apis: ChessPlatform): WebClient {
return properties[apis]!!.webClient
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package com.michibaum.chess.apis.dtos

import com.michibaum.chess.domain.Account
import com.michibaum.chess.domain.ChessPlatforms
import com.michibaum.chess.domain.ChessPlatform
import java.util.*

class AccountDto(
val id: String,
val url: String,
val username: String,
val name: String, // Realname
val platform: ChessPlatforms
val platform: ChessPlatform,
val createdAt: Date
) {
fun toAccount(): Account {
return Account(accId = id, username = username, platform = platform, url = url, name = name, player = null)
return Account(accId = id, username = username, platform = platform, url = url, name = name, person = null, createdAt = createdAt)
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package com.michibaum.chess.apis.dtos

import com.michibaum.chess.domain.ChessPlatform
import com.michibaum.chess.domain.GameType


data class GameDto(
val chessPlatform: ChessPlatform,
val id: String?,
val players: List<Player>

val players: List<Player>,
val pgn: String,
val gameType: GameType
)

data class Player(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,27 @@ import com.michibaum.chess.apis.config.ChessConfigProperties
import com.michibaum.chess.apis.dtos.AccountDto
import com.michibaum.chess.apis.dtos.GameDto
import com.michibaum.chess.apis.dtos.StatsDto
import com.michibaum.chess.domain.ChessPlatforms
import com.michibaum.chess.domain.Account
import com.michibaum.chess.domain.ChessPlatform
import org.springframework.http.MediaType
import org.springframework.stereotype.Service
import java.util.stream.Stream

@Service("lichessApiService")
class ApiServiceImpl(
chessConfigProperties: ChessConfigProperties,
val converter: Converter
): IApiService {

val client = chessConfigProperties.getWebClient(ChessPlatforms.LICHESS)
val client = chessConfigProperties.getWebClient(ChessPlatform.LICHESS)

override fun findUser(username: String): ApiResult<AccountDto> {
val result = try {
client.get()
.uri("/api/user/{0}", username)
.accept(MediaType.APPLICATION_JSON)
.attributes {
it["pgnInJson"] = true
}
.accept(MediaType.APPLICATION_NDJSON)
.retrieve()
.bodyToMono(LichessAccountDto::class.java)
.block()
Expand All @@ -37,10 +40,10 @@ class ApiServiceImpl(
return Success(accountDto)
}

override fun getStats(username: String): ApiResult<StatsDto> {
override fun getStats(account: Account): ApiResult<StatsDto> {
val statsRequest: (String) -> LichessStatsDto? = { perf: String ->
client.get()
.uri("/api/user/{0}/perf/{1}", username, perf)
.uri("/api/user/{0}/perf/{1}", account.username, perf)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(LichessStatsDto::class.java)
Expand Down Expand Up @@ -75,14 +78,14 @@ class ApiServiceImpl(

}

override fun getGames(username: String): ApiResult<List<GameDto>> {
override fun getGames(account: Account): ApiResult<List<GameDto>> {

val result = try {
client.get()
.uri("/api/games/user/{0}", username)
.uri("/api/games/user/{0}", account.username)
.accept(MediaType.APPLICATION_NDJSON)
.retrieve()
.bodyToFlux(LichessGamesDto::class.java)
.bodyToFlux(LichessGameDto::class.java)
.collectList()
.block()
} catch (throwable: Throwable) {
Expand Down
Loading

0 comments on commit 3cf5b92

Please sign in to comment.