Skip to content

Commit

Permalink
chess-service
Browse files Browse the repository at this point in the history
  • Loading branch information
MichiBaum committed Oct 8, 2024
1 parent f26e2cd commit 78c0b32
Show file tree
Hide file tree
Showing 40 changed files with 17,788 additions and 159 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ data class Error<T>(val error: String): ApiResult<T>(), Loggable{
}
}

data class Exception<T>(val throwable: Throwable): ApiResult<T>(), Loggable{
data class Exception<T>(val message: String, val throwable: Throwable): ApiResult<T>(), Loggable{
private val logger = LoggerFactory.getLogger(Exception::class.java)
override fun log(){
logger.error(throwable.message, throwable)
logger.error(message + " " + throwable.message, throwable)
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
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.doIfIsInstance
import com.michibaum.chess.domain.Account
import com.michibaum.chess.domain.ChessPlatform
import org.springframework.stereotype.Service
Expand All @@ -28,5 +30,42 @@ class ApiService(

}

fun getGames(account: Account): List<GameDto> {
val result = when(account.platform) {
ChessPlatform.CHESSCOM -> chesscomApiService.getGames(account)
ChessPlatform.LICHESS -> lichessApiService.getGames(account)
}

if(result is Success){
return result.result
}
return emptyList()
}

fun getTopAccounts(): List<AccountDto> {
val chesscomTopAccounts = chesscomApiService.findTopAccounts()
val chesscomAccounts = when(chesscomTopAccounts){
is Success -> Success(chesscomTopAccounts.result.map { chesscomApiService.findUser(it.username) })
else -> Error("")
}

val lichessTopAccounts = lichessApiService.findTopAccounts()
val lichessAccounts = when(lichessTopAccounts){
is Success -> Success(lichessTopAccounts.result.map { lichessApiService.findUser(it.username) })
else -> Error("")
}

val allResults = listOf(chesscomAccounts, lichessAccounts)

return allResults
.doIfIsInstance<ApiResult<List<ApiResult<AccountDto>>>, Loggable> { it.log() }
.filterIsInstance<Success<List<ApiResult<AccountDto>>>>()
.map { it.result }
.flatten()
.doIfIsInstance<ApiResult<AccountDto>, Loggable> { it.log() }
.filterIsInstance<Success<AccountDto>>()
.map { it.result }
}


}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ 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.apis.dtos.TopAccountDto
import com.michibaum.chess.domain.Account

interface IApiService {
Expand All @@ -12,5 +13,6 @@ interface IApiService {
fun getStats(account: Account): ApiResult<StatsDto>

fun getGames(account: Account): ApiResult<List<GameDto>>
fun findTopAccounts(): ApiResult<List<TopAccountDto>>

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ 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.apis.dtos.TopAccountDto
import com.michibaum.chess.domain.Account
import com.michibaum.chess.domain.ChessPlatform
import org.springframework.http.MediaType
Expand Down Expand Up @@ -32,7 +33,7 @@ class ApiServiceImpl(
.bodyToMono(ChesscomAccountDto::class.java) // TODO onError
.block()
} catch (throwable: Throwable){
return Exception(throwable)
return Exception("Exception chesscom findUser with username=$username", throwable)
}

if(result == null)
Expand All @@ -51,7 +52,7 @@ class ApiServiceImpl(
.bodyToMono(ChesscomStatsDto::class.java) // TODO onError
.block()
} catch (throwable: Throwable){
return Exception(throwable)
return Exception("Exception chesscom getStats with username=${account.username}", throwable)
}

if(result == null)
Expand Down Expand Up @@ -90,7 +91,7 @@ class ApiServiceImpl(
.mapNotNull { it.games }
.block()
} catch (throwable: Throwable){
return Exception(throwable)
return Exception("Exception chesscom getGames with username=${account.username} and year=$currentYear and month=$currentMonth", throwable)
}
results.add(result)
}
Expand All @@ -107,6 +108,25 @@ class ApiServiceImpl(
return Success(gameDtos)
}

override fun findTopAccounts(): ApiResult<List<TopAccountDto>> {
val result = try {
client.get()
.uri("/pub/leaderboards")
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(ChesscomLeaderboards::class.java) // TODO onError
.block()
} catch (throwable: Throwable){
return Exception("Exception chesscom findTopAccounts", throwable)
}

if(result == null)
return Error("Error happend while fetching chesscom top accounts")

val topAccountDto = result.let { converter.convert(it) }
return Success(topAccountDto)
}

private fun getMonth(month: Int): String =
if (month.toString().length == 1) {
"0$month"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.michibaum.chess.apis.chesscom

import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonProperty

@JsonIgnoreProperties(ignoreUnknown = true)
data class ChesscomAccountDto(
val avatar: String,
@JsonProperty("player_id")
Expand All @@ -11,16 +13,12 @@ data class ChesscomAccountDto(
val url: String,
val name: String,
val username: String,
val followers: Long,
@JsonProperty("title", defaultValue = "")
val title: String?,
val country: String,
@JsonProperty("last_online")
val lastOnline: Long,
val joined: Long,
val status: String,
@JsonProperty("is_streamer")
val isStreamer: Boolean,
val verified: Boolean,
val league: String,
@JsonProperty("streaming_platforms")
val streamingPlatforms: List<Any?>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.michibaum.chess.apis.chesscom

import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonProperty

@JsonIgnoreProperties(ignoreUnknown = true)
data class ChesscomLeaderboards(
@JsonProperty("live_rapid")
val liveRapid: List<LiveRapid>,
@JsonProperty("live_blitz")
val liveBlitz: List<LiveBlitz>,
@JsonProperty("live_bullet")
val liveBullet: List<LiveBullet>
)

@JsonIgnoreProperties(ignoreUnknown = true)
data class LiveRapid(
@JsonProperty("player_id")
val playerId: Long,
@JsonProperty("@id")
val id: String,
val url: String,
val username: String,
val score: Long,
val rank: Long,
val country: String,
val title: String?,
val name: String?,
val status: String,
)

@JsonIgnoreProperties(ignoreUnknown = true)
data class LiveBlitz(
@JsonProperty("player_id")
val playerId: Long,
@JsonProperty("@id")
val id: String,
val url: String,
val username: String,
val score: Long,
val rank: Long,
val country: String,
val title: String,
val name: String,
val status: String,
)

@JsonIgnoreProperties(ignoreUnknown = true)
data class LiveBullet(
@JsonProperty("player_id")
val playerId: Long,
@JsonProperty("@id")
val id: String,
val url: String,
val username: String,
val score: Long,
val rank: Long,
val country: String,
val name: String,
val status: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.michibaum.chess.apis.chesscom
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonProperty

@JsonIgnoreProperties(value = ["puzzle_rush"])
@JsonIgnoreProperties(ignoreUnknown = true)
data class ChesscomStatsDto(
@JsonProperty("chess_rapid")
val chessRapid: Rapid?,
Expand All @@ -12,7 +12,6 @@ data class ChesscomStatsDto(
@JsonProperty("chess_blitz")
val chessBlitz: Blitz?,
val fide: Double?,
val tactics: Tactics,
)

data class Rapid(
Expand Down Expand Up @@ -51,11 +50,6 @@ data class Blitz(
val record: Record,
)

data class Tactics(
val highest: Highest,
val lowest: Lowest,
)

data class Highest(
val rating: Double,
val date: Long,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.michibaum.chess.apis.chesscom

import com.michibaum.chess.apis.dtos.*
import com.michibaum.chess.apis.dtos.Player
import com.michibaum.chess.apis.dtos.PlayerDto
import com.michibaum.chess.domain.ChessPlatform
import com.michibaum.chess.domain.GameType
import org.springframework.stereotype.Component
Expand All @@ -22,11 +22,11 @@ class Converter {

fun convert(gameDto: ChesscomGameDto): GameDto {
val player1 = gameDto.white?.let {
Player(id = it.uuid, username = it.username, rating = it.rating, pieceColor = PieceColor.WHITE)
PlayerDto(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)
PlayerDto(id = it.uuid, username = it.username, rating = it.rating, pieceColor = PieceColor.BLACK)
}

val gametype = when(gameDto.timeClass){
Expand Down Expand Up @@ -64,4 +64,13 @@ class Converter {
),
)

fun convert(leaderboards: ChesscomLeaderboards): List<TopAccountDto> {
val topBullet = leaderboards.liveBullet.map { TopAccountDto(it.username.lowercase()) } // TODO BUG example: usernames are MagnusCarlsen. Player endpoint accepts magnuscarlsen
val topBlitz = leaderboards.liveBlitz.map { TopAccountDto(it.username.lowercase()) } // TODO BUG example: usernames are MagnusCarlsen. Player endpoint accepts magnuscarlsen
val topRapid = leaderboards.liveRapid.map { TopAccountDto(it.username.lowercase()) } // TODO BUG example: usernames are MagnusCarlsen. Player endpoint accepts magnuscarlsen

return topBullet + topBlitz + topRapid

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ data class ApisConfigProperties(

val webClient: WebClient = WebClient.builder()
.baseUrl(baseUrl)
.defaultHeader("User-Agent", "chess-statistic-application/0.1; +http://www.michibaum.ch")
.codecs { configurer ->
configurer.defaultCodecs()
.maxInMemorySize(10000000)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import com.michibaum.chess.domain.GameType

data class GameDto(
val chessPlatform: ChessPlatform,
val id: String?,
val players: List<Player>,
val id: String,
val players: List<PlayerDto>,
val pgn: String,
val gameType: GameType
)

data class Player(
data class PlayerDto(
val id: String,
val username: String,
val rating: Long,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.michibaum.chess.apis.dtos

data class TopAccountDto(
val username: String
)
Loading

0 comments on commit 78c0b32

Please sign in to comment.