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.core.JsonParser
|
||||||
import com.fasterxml.jackson.databind.DeserializationContext
|
import com.fasterxml.jackson.databind.DeserializationContext
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||||
import com.fasterxml.jackson.databind.JsonDeserializer
|
import com.fasterxml.jackson.databind.JsonDeserializer
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import com.fasterxml.jackson.databind.module.SimpleModule
|
import com.fasterxml.jackson.databind.module.SimpleModule
|
||||||
|
@ -19,6 +20,7 @@ import org.apache.tika.Tika
|
||||||
import org.apache.tika.mime.MimeTypes
|
import org.apache.tika.mime.MimeTypes
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.http.HttpStatus
|
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.RequestBody
|
||||||
import org.springframework.web.bind.annotation.RequestHeader
|
import org.springframework.web.bind.annotation.RequestHeader
|
||||||
import org.springframework.web.bind.annotation.RequestMapping
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
@ -37,6 +39,7 @@ import kotlin.reflect.jvm.jvmErasure
|
||||||
typealias RP = RequestParam
|
typealias RP = RequestParam
|
||||||
typealias RB = RequestBody
|
typealias RB = RequestBody
|
||||||
typealias RH = RequestHeader
|
typealias RH = RequestHeader
|
||||||
|
typealias PV = PathVariable
|
||||||
typealias API = RequestMapping
|
typealias API = RequestMapping
|
||||||
typealias Str = String
|
typealias Str = String
|
||||||
typealias Bool = Boolean
|
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_FALSE = setOf("0", "false", "no", "off", "False", "None", "null")
|
||||||
val ACCEPTABLE_TRUE = setOf("1", "true", "yes", "on", "True")
|
val ACCEPTABLE_TRUE = setOf("1", "true", "yes", "on", "True")
|
||||||
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
|
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
|
||||||
val jackson = ObjectMapper().apply {
|
val JACKSON = ObjectMapper().apply {
|
||||||
findAndRegisterModules()
|
findAndRegisterModules()
|
||||||
registerModule(SimpleModule().addDeserializer(Boolean::class.java, object : JsonDeserializer<Boolean>() {
|
registerModule(SimpleModule().addDeserializer(Boolean::class.java, object : JsonDeserializer<Boolean>() {
|
||||||
override fun deserialize(parser: JsonParser, context: DeserializationContext) = when(parser.text) {
|
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) =
|
override fun deserialize(parser: JsonParser, context: DeserializationContext) =
|
||||||
parser.text.asDateTime() ?: (400 - "Invalid date time value ${parser.text}")
|
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)
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
val JSON = Json {
|
val JSON = Json {
|
||||||
ignoreUnknownKeys = true
|
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 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" }
|
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>) =
|
operator fun <K, V> Map<K, V>.plus(map: Map<K, V>) =
|
||||||
(if (this is MutableMap) this else toMutableMap()).apply { putAll(map) }
|
(if (this is MutableMap) this else toMutableMap()).apply { putAll(map) }
|
||||||
operator fun <K, V> MutableMap<K, V>.plusAssign(map: Map<K, V>) { 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
|
// Strings
|
||||||
operator fun Str.get(range: IntRange) = substring(range.first, (range.last + 1).coerceAtMost(length))
|
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 })
|
userRepo.save(u.apply { gameOptions = it })
|
||||||
}
|
}
|
||||||
// Check field type
|
// 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)
|
field.setCast(options, value)
|
||||||
goRepo.save(options)
|
goRepo.save(options)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package icu.samnyan.aqua.net.games
|
package icu.samnyan.aqua.net.games
|
||||||
|
|
||||||
import ext.jackson
|
import ext.JACKSON
|
||||||
import ext.splitLines
|
import ext.splitLines
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
@ -54,7 +54,7 @@ abstract class ImportController<T: Any>(
|
||||||
lists[tb.name]?.add(obj) ?: field.set(data, obj)
|
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
|
companion object
|
||||||
|
@ -69,7 +69,7 @@ abstract class ImportController<T: Any>(
|
||||||
// Process Nones
|
// Process Nones
|
||||||
dict = dict.filterValues { it != "None" }
|
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
|
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.api.model.resp.sega.chuni.v2.external.Chu3DataExport
|
||||||
import icu.samnyan.aqua.net.games.ImportClass
|
import icu.samnyan.aqua.net.games.ImportClass
|
||||||
import icu.samnyan.aqua.net.games.ImportController
|
import icu.samnyan.aqua.net.games.ImportController
|
||||||
import icu.samnyan.aqua.sega.chusan.model.userdata.*
|
import icu.samnyan.aqua.sega.chusan.model.userdata.*
|
||||||
import kotlin.io.path.Path
|
import org.springframework.web.bind.annotation.RestController
|
||||||
import kotlin.io.path.readText
|
|
||||||
|
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@API("api/v2/game/chu3")
|
||||||
class Chu3Import : ImportController<Chu3DataExport>(
|
class Chu3Import : ImportController<Chu3DataExport>(
|
||||||
exportFields = Chu3DataExport::class.java.declaredFields.associateBy {
|
exportFields = Chu3DataExport::class.java.declaredFields.associateBy {
|
||||||
var name = it.name
|
var name = it.name
|
||||||
|
@ -35,7 +36,3 @@ class Chu3Import : ImportController<Chu3DataExport>(
|
||||||
override fun createEmpty() = Chu3DataExport("SDEZ", UserData(), UserGameOption(), ArrayList(), ArrayList(),
|
override fun createEmpty() = Chu3DataExport("SDEZ", UserData(), UserGameOption(), ArrayList(), ArrayList(),
|
||||||
ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), ArrayList(), 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
|
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.api.model.resp.sega.maimai2.external.Maimai2DataExport
|
||||||
import icu.samnyan.aqua.net.games.ImportClass
|
import icu.samnyan.aqua.net.games.ImportClass
|
||||||
import icu.samnyan.aqua.net.games.ImportController
|
import icu.samnyan.aqua.net.games.ImportController
|
||||||
import icu.samnyan.aqua.sega.maimai2.model.userdata.*
|
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>(
|
class Mai2Import : ImportController<Maimai2DataExport>(
|
||||||
exportFields = Maimai2DataExport::class.java.declaredFields.associateBy {
|
exportFields = Maimai2DataExport::class.java.declaredFields.associateBy {
|
||||||
it.name.replace("List", "").lowercase()
|
it.name.replace("List", "").lowercase()
|
||||||
|
|
|
@ -2,6 +2,7 @@ package icu.samnyan.aqua.net.games.mai2
|
||||||
|
|
||||||
import ext.*
|
import ext.*
|
||||||
import icu.samnyan.aqua.api.model.resp.sega.maimai2.external.Maimai2DataExport
|
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.db.AquaUserServices
|
||||||
import icu.samnyan.aqua.net.games.*
|
import icu.samnyan.aqua.net.games.*
|
||||||
import icu.samnyan.aqua.net.utils.*
|
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 icu.samnyan.aqua.sega.maimai2.model.userdata.UserDetail
|
||||||
import org.springframework.web.bind.annotation.RestController
|
import org.springframework.web.bind.annotation.RestController
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
|
import java.time.LocalDateTime
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import kotlin.io.path.Path
|
||||||
|
import kotlin.io.path.writeText
|
||||||
import kotlin.reflect.full.declaredMembers
|
import kotlin.reflect.full.declaredMembers
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
|
@ -19,7 +23,8 @@ class Maimai2(
|
||||||
override val playlogRepo: Mai2UserPlaylogRepo,
|
override val playlogRepo: Mai2UserPlaylogRepo,
|
||||||
override val userDataRepo: Mai2UserDataRepo,
|
override val userDataRepo: Mai2UserDataRepo,
|
||||||
val userGeneralDataRepository: Mai2UserGeneralDataRepo,
|
val userGeneralDataRepository: Mai2UserGeneralDataRepo,
|
||||||
val repos: Mai2Repos
|
val repos: Mai2Repos,
|
||||||
|
val netProps: AquaNetProps
|
||||||
): GameApiController<UserDetail>("mai2", UserDetail::class) {
|
): GameApiController<UserDetail>("mai2", UserDetail::class) {
|
||||||
override suspend fun trend(@RP username: Str): List<TrendOut> = us.cardByName(username) { card ->
|
override suspend fun trend(@RP username: Str): List<TrendOut> = us.cardByName(username) { card ->
|
||||||
findTrend(playlogRepo.findByUserCardExtId(card.extId)
|
findTrend(playlogRepo.findByUserCardExtId(card.extId)
|
||||||
|
@ -49,15 +54,13 @@ class Maimai2(
|
||||||
// Use reflection to get all properties in Mai2Repos with matching names in Maimai2DataExport
|
// 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<Field, UserLinked<*>> = listOf(*Maimai2DataExport::class.java.declaredFields)
|
||||||
.associateWith { Mai2Repos::class.declaredMembers
|
.associateWith { Mai2Repos::class.declaredMembers
|
||||||
|
.filter { f -> f.name !in setOf("gameId", "userData") }
|
||||||
.filter { f -> f returns UserLinked::class }
|
.filter { f -> f returns UserLinked::class }
|
||||||
.firstOrNull { f -> f.name == it.name || f.name == it.name.replace("List", "") }
|
.firstOrNull { f -> f.name == it.name || f.name == it.name.replace("List", "") }
|
||||||
?.call(repos) as UserLinked<*>? ?: error("No matching field found for ${it.name}")
|
?.call(repos) as UserLinked<*>? ?: error("No matching field found for ${it.name}")
|
||||||
}
|
}
|
||||||
|
|
||||||
@API("export")
|
fun export(u: AquaNetUser) = Maimai2DataExport().apply {
|
||||||
fun exportAllUserData(@RP token: Str) = us.jwt.auth(token) { u ->
|
|
||||||
try {
|
|
||||||
Maimai2DataExport().apply {
|
|
||||||
gameId = "SDEZ"
|
gameId = "SDEZ"
|
||||||
userData = repos.userData.findByCard(u.ghostCard) ?: (404 - "User not found")
|
userData = repos.userData.findByCard(u.ghostCard) ?: (404 - "User not found")
|
||||||
exportFields.forEach { (f, u) ->
|
exportFields.forEach { (f, u) ->
|
||||||
|
@ -66,6 +69,25 @@ class Maimai2(
|
||||||
else u.findSingleByUser(userData).orElse(null))
|
else u.findSingleByUser(userData).orElse(null))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) { 500 - "Error during data export. Reason: ${e.message}" }
|
|
||||||
|
@API("export")
|
||||||
|
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")
|
@ConfigurationProperties(prefix = "aqua-net")
|
||||||
class AquaNetProps {
|
class AquaNetProps {
|
||||||
var linkCardLimit: Int = 10
|
var linkCardLimit: Int = 10
|
||||||
|
var importBackupPath = "data/import-backups"
|
||||||
}
|
}
|
Loading…
Reference in New Issue