mirror of https://github.com/hykilpikonna/AquaDX
[+] Import (TODO)
parent
aaf7e1e3e5
commit
313dd681de
|
@ -2,6 +2,7 @@ package ext
|
|||
|
||||
import com.fasterxml.jackson.core.JsonParser
|
||||
import com.fasterxml.jackson.databind.DeserializationContext
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule
|
||||
|
@ -19,6 +20,7 @@ import org.apache.tika.Tika
|
|||
import org.apache.tika.mime.MimeTypes
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.RequestBody
|
||||
import org.springframework.web.bind.annotation.RequestHeader
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
|
@ -37,6 +39,7 @@ import kotlin.reflect.jvm.jvmErasure
|
|||
typealias RP = RequestParam
|
||||
typealias RB = RequestBody
|
||||
typealias RH = RequestHeader
|
||||
typealias PV = PathVariable
|
||||
typealias API = RequestMapping
|
||||
typealias Str = String
|
||||
typealias Bool = Boolean
|
||||
|
@ -83,7 +86,7 @@ fun Str.isValidEmail(): Bool = emailRegex.matches(this)
|
|||
val ACCEPTABLE_FALSE = setOf("0", "false", "no", "off", "False", "None", "null")
|
||||
val ACCEPTABLE_TRUE = setOf("1", "true", "yes", "on", "True")
|
||||
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
|
||||
val jackson = ObjectMapper().apply {
|
||||
val JACKSON = ObjectMapper().apply {
|
||||
findAndRegisterModules()
|
||||
registerModule(SimpleModule().addDeserializer(Boolean::class.java, object : JsonDeserializer<Boolean>() {
|
||||
override fun deserialize(parser: JsonParser, context: DeserializationContext) = when(parser.text) {
|
||||
|
@ -103,7 +106,10 @@ val jackson = ObjectMapper().apply {
|
|||
override fun deserialize(parser: JsonParser, context: DeserializationContext) =
|
||||
parser.text.asDateTime() ?: (400 - "Invalid date time value ${parser.text}")
|
||||
}))
|
||||
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
}
|
||||
inline fun <reified T> Str.parseJson() = JACKSON.readValue(this, T::class.java)
|
||||
fun <T> T.toJson() = JACKSON.writeValueAsString(this)
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
val JSON = Json {
|
||||
ignoreUnknownKeys = true
|
||||
|
@ -144,10 +150,12 @@ catch (e: Exception) { null } }
|
|||
fun Long.toHex(len: Int = 16): Str = "0x${this.toString(len).padStart(len, '0').uppercase()}"
|
||||
fun Map<String, Any>.toUrl() = entries.joinToString("&") { (k, v) -> "$k=$v" }
|
||||
|
||||
// Map
|
||||
// Collections
|
||||
operator fun <K, V> Map<K, V>.plus(map: Map<K, V>) =
|
||||
(if (this is MutableMap) this else toMutableMap()).apply { putAll(map) }
|
||||
operator fun <K, V> MutableMap<K, V>.plusAssign(map: Map<K, V>) { putAll(map) }
|
||||
fun <T> MutableList<T>.popAll(list: List<T>) = list.also { removeAll(it) }
|
||||
fun <T> MutableList<T>.popAll(vararg items: T) = popAll(items.toList())
|
||||
|
||||
// Strings
|
||||
operator fun Str.get(range: IntRange) = substring(range.first, (range.last + 1).coerceAtMost(length))
|
||||
|
|
|
@ -40,14 +40,6 @@ class SettingsApi(
|
|||
userRepo.save(u.apply { gameOptions = it })
|
||||
}
|
||||
// Check field type
|
||||
// val type = field.returnType
|
||||
// val newValue = when (type.classifier) {
|
||||
// String::class -> value
|
||||
// Int::class -> value.toInt()
|
||||
// Boolean::class -> value.toBoolean()
|
||||
// else -> (400 - "Invalid field type $type")
|
||||
// }
|
||||
// field.set(options, newValue)
|
||||
field.setCast(options, value)
|
||||
goRepo.save(options)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package icu.samnyan.aqua.net.games
|
||||
|
||||
import ext.jackson
|
||||
import ext.JACKSON
|
||||
import ext.splitLines
|
||||
import java.lang.reflect.Field
|
||||
import kotlin.reflect.KClass
|
||||
|
@ -54,7 +54,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.writeValueAsString(data))
|
||||
}
|
||||
|
||||
companion object
|
||||
|
@ -69,7 +69,7 @@ abstract class ImportController<T: Any>(
|
|||
// Process Nones
|
||||
dict = dict.filterValues { it != "None" }
|
||||
|
||||
return jackson.convertValue(dict, type.java)
|
||||
return JACKSON.convertValue(dict, type.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
package icu.samnyan.aqua.net.games.chu3
|
||||
|
||||
import ext.API
|
||||
import icu.samnyan.aqua.api.model.resp.sega.chuni.v2.external.Chu3DataExport
|
||||
import icu.samnyan.aqua.net.games.ImportClass
|
||||
import icu.samnyan.aqua.net.games.ImportController
|
||||
import icu.samnyan.aqua.sega.chusan.model.userdata.*
|
||||
import kotlin.io.path.Path
|
||||
import kotlin.io.path.readText
|
||||
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RestController
|
||||
@API("api/v2/game/chu3")
|
||||
class Chu3Import : ImportController<Chu3DataExport>(
|
||||
exportFields = Chu3DataExport::class.java.declaredFields.associateBy {
|
||||
var name = it.name
|
||||
|
@ -35,7 +36,3 @@ class Chu3Import : ImportController<Chu3DataExport>(
|
|||
override fun createEmpty() = Chu3DataExport("SDEZ", UserData(), UserGameOption(), ArrayList(), ArrayList(),
|
||||
ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList())
|
||||
}
|
||||
|
||||
fun main() {
|
||||
Chu3Import().importArtemisSql(Path("C:\\Users\\Azalea\\Downloads\\all_inserts (2).sql").readText())
|
||||
}
|
|
@ -1,10 +1,14 @@
|
|||
package icu.samnyan.aqua.net.games.mai2
|
||||
|
||||
import ext.API
|
||||
import icu.samnyan.aqua.api.model.resp.sega.maimai2.external.Maimai2DataExport
|
||||
import icu.samnyan.aqua.net.games.ImportClass
|
||||
import icu.samnyan.aqua.net.games.ImportController
|
||||
import icu.samnyan.aqua.sega.maimai2.model.userdata.*
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RestController
|
||||
@API("api/v2/game/mai2")
|
||||
class Mai2Import : ImportController<Maimai2DataExport>(
|
||||
exportFields = Maimai2DataExport::class.java.declaredFields.associateBy {
|
||||
it.name.replace("List", "").lowercase()
|
||||
|
|
|
@ -2,6 +2,7 @@ package icu.samnyan.aqua.net.games.mai2
|
|||
|
||||
import ext.*
|
||||
import icu.samnyan.aqua.api.model.resp.sega.maimai2.external.Maimai2DataExport
|
||||
import icu.samnyan.aqua.net.db.AquaNetUser
|
||||
import icu.samnyan.aqua.net.db.AquaUserServices
|
||||
import icu.samnyan.aqua.net.games.*
|
||||
import icu.samnyan.aqua.net.utils.*
|
||||
|
@ -9,7 +10,10 @@ import icu.samnyan.aqua.sega.maimai2.model.*
|
|||
import icu.samnyan.aqua.sega.maimai2.model.userdata.UserDetail
|
||||
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.full.declaredMembers
|
||||
|
||||
@RestController
|
||||
|
@ -19,7 +23,8 @@ class Maimai2(
|
|||
override val playlogRepo: Mai2UserPlaylogRepo,
|
||||
override val userDataRepo: Mai2UserDataRepo,
|
||||
val userGeneralDataRepository: Mai2UserGeneralDataRepo,
|
||||
val repos: Mai2Repos
|
||||
val repos: Mai2Repos,
|
||||
val netProps: AquaNetProps
|
||||
): GameApiController<UserDetail>("mai2", UserDetail::class) {
|
||||
override suspend fun trend(@RP username: Str): List<TrendOut> = us.cardByName(username) { card ->
|
||||
findTrend(playlogRepo.findByUserCardExtId(card.extId)
|
||||
|
@ -49,23 +54,40 @@ 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)
|
||||
.associateWith { Mai2Repos::class.declaredMembers
|
||||
.filter { f -> f.name !in setOf("gameId", "userData") }
|
||||
.filter { f -> f returns UserLinked::class }
|
||||
.firstOrNull { f -> f.name == it.name || f.name == it.name.replace("List", "") }
|
||||
?.call(repos) as UserLinked<*>? ?: error("No matching field found for ${it.name}")
|
||||
}
|
||||
|
||||
fun export(u: AquaNetUser) = Maimai2DataExport().apply {
|
||||
gameId = "SDEZ"
|
||||
userData = repos.userData.findByCard(u.ghostCard) ?: (404 - "User not found")
|
||||
exportFields.forEach { (f, u) ->
|
||||
if (f.name == "gameId" || f.name == "userData") return@forEach
|
||||
f.set(this, if (f.type == List::class.java) u.findByUser(userData)
|
||||
else u.findSingleByUser(userData).orElse(null))
|
||||
}
|
||||
}
|
||||
|
||||
@API("export")
|
||||
fun exportAllUserData(@RP token: Str) = us.jwt.auth(token) { u ->
|
||||
try {
|
||||
Maimai2DataExport().apply {
|
||||
gameId = "SDEZ"
|
||||
userData = repos.userData.findByCard(u.ghostCard) ?: (404 - "User not found")
|
||||
exportFields.forEach { (f, u) ->
|
||||
if (f.name == "gameId" || f.name == "userData") return@forEach
|
||||
f.set(this, if (f.type == List::class.java) u.findByUser(userData)
|
||||
else u.findSingleByUser(userData).orElse(null))
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) { 500 - "Error during data export. Reason: ${e.message}" }
|
||||
fun exportAllUserData(@RP token: Str) = us.jwt.auth(token) { u -> export(u) }
|
||||
|
||||
@API("import")
|
||||
fun importUserData(@RP token: Str, @RP json: Str) = us.jwt.auth(token) { u ->
|
||||
val export = json.parseJson<Maimai2DataExport>()
|
||||
if (!export.gameId.equals("SDEZ", true)) 400 - "Invalid game ID"
|
||||
|
||||
// Check existing data
|
||||
if (repos.userData.findByCard(u.ghostCard) != null) {
|
||||
// Store a backup of the old data
|
||||
val fl = "mai2-backup-${u.auId}-${LocalDateTime.now().isoDateTime()}.json"
|
||||
(Path(netProps.importBackupPath) / fl).writeText(export(u).toJson())
|
||||
|
||||
// Delete the old data
|
||||
TODO()
|
||||
}
|
||||
|
||||
TODO()
|
||||
}
|
||||
}
|
|
@ -7,4 +7,5 @@ import org.springframework.context.annotation.Configuration
|
|||
@ConfigurationProperties(prefix = "aqua-net")
|
||||
class AquaNetProps {
|
||||
var linkCardLimit: Int = 10
|
||||
var importBackupPath = "data/import-backups"
|
||||
}
|
Loading…
Reference in New Issue