nise/nise-backend/src/main/kotlin/com/nisemoe/nise/database/UserService.kt

129 lines
5.0 KiB
Kotlin
Raw Normal View History

2024-02-14 16:43:11 +00:00
package com.nisemoe.nise.database
import com.nisemoe.generated.tables.records.UsersRecord
import com.nisemoe.generated.tables.references.USERS
import com.nisemoe.nise.osu.OsuApi
import com.nisemoe.nise.osu.OsuApiModels
import com.nisemoe.nise.Format
import com.nisemoe.nise.UserDetails
import org.jooq.DSLContext
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import java.time.LocalDateTime
import java.time.OffsetDateTime
@Service
class UserService(
private val dslContext: DSLContext,
private val osuApi: OsuApi
) {
private val logger = LoggerFactory.getLogger(javaClass)
fun mapUserToDatabase(dto: OsuApiModels.UserExtended): UserDetails {
return UserDetails(
user_id = dto.id,
username = dto.username,
rank = dto.statistics?.global_rank,
pp_raw = dto.statistics?.pp,
join_date = if (dto.join_date != null) Format.formatLocalDateTime(OffsetDateTime.parse(dto.join_date).toLocalDateTime()) else null,
seconds_played = dto.statistics?.play_time,
country = dto.country?.code,
country_rank = dto.statistics?.country_rank,
playcount = dto.statistics?.play_count
)
}
fun getUserDetails(username: String): UserDetails? {
val user = dslContext.selectFrom(USERS)
.where(USERS.USERNAME.equalIgnoreCase(username.lowercase()))
.fetchOneInto(UsersRecord::class.java)
if (user != null) {
return UserDetails(
user.userId!!,
user.username!!,
user.rank,
user.ppRaw,
user.joinDate?.let { Format.formatLocalDateTime(it) },
user.secondsPlayed,
user.country,
user.countryRank,
user.playcount
)
}
// The database does NOT have the user; we will now use the osu!api
val apiUser = this.osuApi.getUserProfile(userId = username, mode = "osu", key = "username")
?: return null
// Persist to database
insertApiUser(apiUser)
return this.mapUserToDatabase(apiUser)
}
fun insertApiUser(apiUser: OsuApiModels.UserExtended) {
this.logger.debug("Saving user ${apiUser.username}")
if(dslContext.fetchExists(USERS, USERS.USER_ID.eq(apiUser.id))) {
dslContext.update(USERS)
.set(USERS.USERNAME, apiUser.username)
.set(USERS.RANK, apiUser.statistics?.global_rank)
.set(USERS.PP_RAW, apiUser.statistics?.pp)
.set(USERS.ACCURACY, apiUser.statistics?.hit_accuracy)
.set(USERS.TOTAL_SCORE, apiUser.statistics?.total_score)
.set(USERS.RANKED_SCORE, apiUser.statistics?.ranked_score)
.set(USERS.COUNT_300, apiUser.statistics?.count_300)
.set(USERS.COUNT_100, apiUser.statistics?.count_100)
.set(USERS.COUNT_50, apiUser.statistics?.count_50)
.apply {
if(apiUser.join_date != null) {
set(USERS.JOIN_DATE, OffsetDateTime.parse(apiUser.join_date).toLocalDateTime())
}
}
.set(USERS.SECONDS_PLAYED, apiUser.statistics?.play_time)
.set(USERS.COUNTRY, apiUser.country?.code)
.set(USERS.COUNTRY_RANK, apiUser.statistics?.country_rank)
.set(USERS.PLAYCOUNT, apiUser.statistics?.play_count)
.set(USERS.SYS_LAST_UPDATE, LocalDateTime.now())
.where(USERS.USER_ID.eq(apiUser.id))
.execute()
return
}
val affectedRows = dslContext.insertInto(USERS)
.set(USERS.USER_ID, apiUser.id)
.set(USERS.USERNAME, apiUser.username)
.set(USERS.RANK, apiUser.statistics?.global_rank)
.set(USERS.PP_RAW, apiUser.statistics?.pp)
.set(USERS.ACCURACY, apiUser.statistics?.hit_accuracy)
.set(USERS.TOTAL_SCORE, apiUser.statistics?.total_score)
.set(USERS.RANKED_SCORE, apiUser.statistics?.ranked_score)
.set(USERS.COUNT_300, apiUser.statistics?.count_300)
.set(USERS.COUNT_100, apiUser.statistics?.count_100)
.set(USERS.COUNT_50, apiUser.statistics?.count_50)
.apply {
if(apiUser.join_date != null) {
set(USERS.JOIN_DATE, OffsetDateTime.parse(apiUser.join_date).toLocalDateTime())
}
}
.set(USERS.SECONDS_PLAYED, apiUser.statistics?.play_time)
.set(USERS.COUNTRY, apiUser.country?.code)
.set(USERS.COUNTRY_RANK, apiUser.statistics?.country_rank)
.set(USERS.PLAYCOUNT, apiUser.statistics?.play_count)
.set(USERS.SYS_LAST_UPDATE, LocalDateTime.now())
.onDuplicateKeyIgnore()
.execute()
if (affectedRows == 0) {
this.logger.error("Tried to insert ${apiUser.username} but failed.")
this.logger.error(apiUser.toString())
}
}
}