[F] Fix mai2 import

This commit is contained in:
Azalea
2024-03-21 03:59:35 -04:00
parent cc8c125934
commit 95a06d572b
6 changed files with 69 additions and 54 deletions

View File

@@ -1,6 +1,11 @@
package icu.samnyan.aqua.net.games
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.module.SimpleModule
import ext.JACKSON
import ext.minus
import ext.splitLines
import java.lang.reflect.Field
import kotlin.reflect.KClass
@@ -54,7 +59,7 @@ abstract class ImportController<T: Any>(
lists[tb.name]?.add(obj) ?: field.set(data, obj)
}
return ImportResult(errors, warnings, JACKSON.writeValueAsString(data))
return ImportResult(errors, warnings, JACKSON_ARTEMIS.writeValueAsString(data))
}
companion object
@@ -69,7 +74,7 @@ abstract class ImportController<T: Any>(
// Process Nones
dict = dict.filterValues { it != "None" }
return JACKSON.convertValue(dict, type.java)
return JACKSON_ARTEMIS.convertValue(dict, type.java)
}
}
}
@@ -96,3 +101,18 @@ fun String.asSqlInsert(): SqlInsert {
assert(cols.size == vals.size) { "Column and value count mismatch" }
return SqlInsert(table, cols.zip(vals).toMap())
}
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
val JSON_INT_LIST_STR = SimpleModule().addDeserializer(List::class.java, object : JsonDeserializer<List<Integer>>() {
override fun deserialize(parser: JsonParser, context: DeserializationContext) =
try {
val text = parser.text.trim('[', ']')
if (text.isEmpty()) emptyList()
else text.split(',').map { it.trim().toInt() } as List<Integer>
} catch (e: Exception) {
400 - "Invalid list value ${parser.text}: $e" }
})
val JACKSON_ARTEMIS = JACKSON.copy().apply {
registerModule(JSON_INT_LIST_STR)
}

View File

@@ -1,6 +1,7 @@
package icu.samnyan.aqua.net.games
import com.fasterxml.jackson.annotation.JsonIgnore
import ext.JACKSON
import ext.JavaSerializable
import icu.samnyan.aqua.sega.general.model.Card
import jakarta.persistence.*
@@ -11,6 +12,8 @@ import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.NoRepositoryBean
import java.util.*
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.isAccessible
data class TrendOut(val date: String, val rating: Int, val plays: Int)
@@ -99,13 +102,16 @@ interface IGenericGamePlaylog {
val isAllPerfect: Boolean
}
@Serializable
@MappedSuperclass
open class BaseEntity(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@JsonIgnore
var id: Long = 0
) : JavaSerializable
) : JavaSerializable {
override fun toString() = JACKSON.writeValueAsString(this)
}
@NoRepositoryBean
interface GenericUserDataRepo<T : IGenericUserData> : JpaRepository<T, Long> {

View File

@@ -34,8 +34,5 @@ class Mai2Import : ImportController<Maimai2DataExport>(
// "mai2_profile_region" to ImportClass(UserRegion::class),
)
) {
override fun createEmpty() = Maimai2DataExport("SDEZ", Mai2UserDetail(), Mai2UserExtend(), Mai2UserOption(),
ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(),
ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(),
ArrayList(), Mai2UserUdemae())
override fun createEmpty() = Maimai2DataExport()
}

View File

@@ -12,11 +12,11 @@ import icu.samnyan.aqua.sega.maimai2.model.userdata.Mai2UserEntity
import org.springframework.transaction.PlatformTransactionManager
import org.springframework.transaction.support.TransactionTemplate
import org.springframework.web.bind.annotation.RestController
import java.lang.reflect.Field
import java.time.LocalDateTime
import java.util.*
import kotlin.io.path.Path
import kotlin.io.path.writeText
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.full.declaredMembers
@RestController
@@ -58,7 +58,7 @@ class Maimai2(
}
// Use reflection to get all properties in Mai2Repos with matching names in Maimai2DataExport
val exportFields: Map<Field, UserLinked<*>> = listOf(*Maimai2DataExport::class.java.declaredFields)
val exportFields: Map<KMutableProperty1<Maimai2DataExport, Any>, UserLinked<*>> = Maimai2DataExport::class.vars()
.filter { f -> f.name !in setOf("gameId", "userData") }
.associateWith { Mai2Repos::class.declaredMembers
.filter { f -> f returns UserLinked::class }
@@ -66,15 +66,15 @@ class Maimai2(
?.call(repos) as UserLinked<*>? ?: error("No matching field found for ${it.name}")
}
val listFields = exportFields.filter { it.key.type == List::class.java }
val singleFields = exportFields.filter { it.key.type != List::class.java }
val listFields = exportFields.filter { it.key returns List::class }
val singleFields = exportFields.filter { !(it.key returns List::class) }
fun export(u: AquaNetUser) = Maimai2DataExport().apply {
gameId = "SDEZ"
userData = repos.userData.findByCard(u.ghostCard) ?: (404 - "User not found")
exportFields.forEach { (f, u) ->
f.set(this, if (f.type == List::class.java) u.findByUser(userData)
else u.findSingleByUser(userData).orElse(null))
if (f returns List::class) f.set(this, u.findByUser(userData))
else u.findSingleByUser(userData)()?.let { f.set(this, it) }
}
}
@@ -84,13 +84,11 @@ class Maimai2(
@Suppress("UNCHECKED_CAST")
@API("import")
fun importUserData(@RP token: Str, @RB json: Str) = us.jwt.auth(token) { u ->
val export = json.parseJson<Maimai2DataExport>()
val export = json.parseJackson<Maimai2DataExport>()
if (!export.gameId.equals("SDEZ", true)) 400 - "Invalid game ID"
val lists = listFields.toList().associate { (f, r) -> r to f.gets<List<Mai2UserEntity>>(export) }.vNotNull()
val singles = singleFields.toList().associate { (f, r) -> r to f.gets<Mai2UserEntity>(export) }.vNotNull()
if (export.userData == null) 400 - "Invalid user data"
val lists = listFields.toList().associate { (f, r) -> r to f.get(export) as List<Mai2UserEntity> }.vNotNull()
val singles = singleFields.toList().associate { (f, r) -> r to f.get(export) as Mai2UserEntity }.vNotNull()
// Validate new user data
// Check that all ids are 0 (this should be true since all ids are @JsonIgnore)
@@ -120,8 +118,8 @@ class Maimai2(
lists.values.flatten().forEach { it.user = nu }
singles.values.forEach { it.user = nu }
// Save new data
lists.forEach { (repo, list) -> (repo as UserLinked<Any>).saveAll(list) }
singles.forEach { (repo, single) -> (repo as UserLinked<Any>).save(single) }
lists.forEach { (repo, list) -> (repo as UserLinked<Any>).saveAll(list) }
}
SUCCESS