Made user queue only able to be added by logged in users, added added_by user ID in the queue, added fetching best/top/firsts scores, check for replay similarity
This commit is contained in:
parent
c7aa44ebed
commit
248c16b44f
@ -18,7 +18,7 @@ import org.jooq.Identity
|
|||||||
import org.jooq.Name
|
import org.jooq.Name
|
||||||
import org.jooq.Record
|
import org.jooq.Record
|
||||||
import org.jooq.Records
|
import org.jooq.Records
|
||||||
import org.jooq.Row7
|
import org.jooq.Row8
|
||||||
import org.jooq.Schema
|
import org.jooq.Schema
|
||||||
import org.jooq.SelectField
|
import org.jooq.SelectField
|
||||||
import org.jooq.Table
|
import org.jooq.Table
|
||||||
@ -99,6 +99,11 @@ open class UpdateUserQueue(
|
|||||||
*/
|
*/
|
||||||
val PROGRESS_TOTAL: TableField<UpdateUserQueueRecord, Int?> = createField(DSL.name("progress_total"), SQLDataType.INTEGER, this, "")
|
val PROGRESS_TOTAL: TableField<UpdateUserQueueRecord, Int?> = createField(DSL.name("progress_total"), SQLDataType.INTEGER, this, "")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The column <code>public.update_user_queue.added_by_user_id</code>.
|
||||||
|
*/
|
||||||
|
val ADDED_BY_USER_ID: TableField<UpdateUserQueueRecord, Long?> = createField(DSL.name("added_by_user_id"), SQLDataType.BIGINT, this, "")
|
||||||
|
|
||||||
private constructor(alias: Name, aliased: Table<UpdateUserQueueRecord>?): this(alias, null, null, aliased, null)
|
private constructor(alias: Name, aliased: Table<UpdateUserQueueRecord>?): this(alias, null, null, aliased, null)
|
||||||
private constructor(alias: Name, aliased: Table<UpdateUserQueueRecord>?, parameters: Array<Field<*>?>?): this(alias, null, null, aliased, parameters)
|
private constructor(alias: Name, aliased: Table<UpdateUserQueueRecord>?, parameters: Array<Field<*>?>?): this(alias, null, null, aliased, parameters)
|
||||||
|
|
||||||
@ -141,18 +146,18 @@ open class UpdateUserQueue(
|
|||||||
override fun rename(name: Table<*>): UpdateUserQueue = UpdateUserQueue(name.getQualifiedName(), null)
|
override fun rename(name: Table<*>): UpdateUserQueue = UpdateUserQueue(name.getQualifiedName(), null)
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Row7 type methods
|
// Row8 type methods
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
override fun fieldsRow(): Row7<Int?, Long?, Boolean?, LocalDateTime?, OffsetDateTime?, Int?, Int?> = super.fieldsRow() as Row7<Int?, Long?, Boolean?, LocalDateTime?, OffsetDateTime?, Int?, Int?>
|
override fun fieldsRow(): Row8<Int?, Long?, Boolean?, LocalDateTime?, OffsetDateTime?, Int?, Int?, Long?> = super.fieldsRow() as Row8<Int?, Long?, Boolean?, LocalDateTime?, OffsetDateTime?, Int?, Int?, Long?>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience mapping calling {@link SelectField#convertFrom(Function)}.
|
* Convenience mapping calling {@link SelectField#convertFrom(Function)}.
|
||||||
*/
|
*/
|
||||||
fun <U> mapping(from: (Int?, Long?, Boolean?, LocalDateTime?, OffsetDateTime?, Int?, Int?) -> U): SelectField<U> = convertFrom(Records.mapping(from))
|
fun <U> mapping(from: (Int?, Long?, Boolean?, LocalDateTime?, OffsetDateTime?, Int?, Int?, Long?) -> U): SelectField<U> = convertFrom(Records.mapping(from))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience mapping calling {@link SelectField#convertFrom(Class,
|
* Convenience mapping calling {@link SelectField#convertFrom(Class,
|
||||||
* Function)}.
|
* Function)}.
|
||||||
*/
|
*/
|
||||||
fun <U> mapping(toType: Class<U>, from: (Int?, Long?, Boolean?, LocalDateTime?, OffsetDateTime?, Int?, Int?) -> U): SelectField<U> = convertFrom(toType, Records.mapping(from))
|
fun <U> mapping(toType: Class<U>, from: (Int?, Long?, Boolean?, LocalDateTime?, OffsetDateTime?, Int?, Int?, Long?) -> U): SelectField<U> = convertFrom(toType, Records.mapping(from))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,8 +11,8 @@ import java.time.OffsetDateTime
|
|||||||
|
|
||||||
import org.jooq.Field
|
import org.jooq.Field
|
||||||
import org.jooq.Record1
|
import org.jooq.Record1
|
||||||
import org.jooq.Record7
|
import org.jooq.Record8
|
||||||
import org.jooq.Row7
|
import org.jooq.Row8
|
||||||
import org.jooq.impl.UpdatableRecordImpl
|
import org.jooq.impl.UpdatableRecordImpl
|
||||||
|
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ import org.jooq.impl.UpdatableRecordImpl
|
|||||||
* This class is generated by jOOQ.
|
* This class is generated by jOOQ.
|
||||||
*/
|
*/
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
open class UpdateUserQueueRecord private constructor() : UpdatableRecordImpl<UpdateUserQueueRecord>(UpdateUserQueue.UPDATE_USER_QUEUE), Record7<Int?, Long?, Boolean?, LocalDateTime?, OffsetDateTime?, Int?, Int?> {
|
open class UpdateUserQueueRecord private constructor() : UpdatableRecordImpl<UpdateUserQueueRecord>(UpdateUserQueue.UPDATE_USER_QUEUE), Record8<Int?, Long?, Boolean?, LocalDateTime?, OffsetDateTime?, Int?, Int?, Long?> {
|
||||||
|
|
||||||
open var id: Int?
|
open var id: Int?
|
||||||
set(value): Unit = set(0, value)
|
set(value): Unit = set(0, value)
|
||||||
@ -50,6 +50,10 @@ open class UpdateUserQueueRecord private constructor() : UpdatableRecordImpl<Upd
|
|||||||
set(value): Unit = set(6, value)
|
set(value): Unit = set(6, value)
|
||||||
get(): Int? = get(6) as Int?
|
get(): Int? = get(6) as Int?
|
||||||
|
|
||||||
|
open var addedByUserId: Long?
|
||||||
|
set(value): Unit = set(7, value)
|
||||||
|
get(): Long? = get(7) as Long?
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Primary key information
|
// Primary key information
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
@ -57,11 +61,11 @@ open class UpdateUserQueueRecord private constructor() : UpdatableRecordImpl<Upd
|
|||||||
override fun key(): Record1<Int?> = super.key() as Record1<Int?>
|
override fun key(): Record1<Int?> = super.key() as Record1<Int?>
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Record7 type implementation
|
// Record8 type implementation
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
override fun fieldsRow(): Row7<Int?, Long?, Boolean?, LocalDateTime?, OffsetDateTime?, Int?, Int?> = super.fieldsRow() as Row7<Int?, Long?, Boolean?, LocalDateTime?, OffsetDateTime?, Int?, Int?>
|
override fun fieldsRow(): Row8<Int?, Long?, Boolean?, LocalDateTime?, OffsetDateTime?, Int?, Int?, Long?> = super.fieldsRow() as Row8<Int?, Long?, Boolean?, LocalDateTime?, OffsetDateTime?, Int?, Int?, Long?>
|
||||||
override fun valuesRow(): Row7<Int?, Long?, Boolean?, LocalDateTime?, OffsetDateTime?, Int?, Int?> = super.valuesRow() as Row7<Int?, Long?, Boolean?, LocalDateTime?, OffsetDateTime?, Int?, Int?>
|
override fun valuesRow(): Row8<Int?, Long?, Boolean?, LocalDateTime?, OffsetDateTime?, Int?, Int?, Long?> = super.valuesRow() as Row8<Int?, Long?, Boolean?, LocalDateTime?, OffsetDateTime?, Int?, Int?, Long?>
|
||||||
override fun field1(): Field<Int?> = UpdateUserQueue.UPDATE_USER_QUEUE.ID
|
override fun field1(): Field<Int?> = UpdateUserQueue.UPDATE_USER_QUEUE.ID
|
||||||
override fun field2(): Field<Long?> = UpdateUserQueue.UPDATE_USER_QUEUE.USER_ID
|
override fun field2(): Field<Long?> = UpdateUserQueue.UPDATE_USER_QUEUE.USER_ID
|
||||||
override fun field3(): Field<Boolean?> = UpdateUserQueue.UPDATE_USER_QUEUE.PROCESSED
|
override fun field3(): Field<Boolean?> = UpdateUserQueue.UPDATE_USER_QUEUE.PROCESSED
|
||||||
@ -69,6 +73,7 @@ open class UpdateUserQueueRecord private constructor() : UpdatableRecordImpl<Upd
|
|||||||
override fun field5(): Field<OffsetDateTime?> = UpdateUserQueue.UPDATE_USER_QUEUE.PROCESSED_AT
|
override fun field5(): Field<OffsetDateTime?> = UpdateUserQueue.UPDATE_USER_QUEUE.PROCESSED_AT
|
||||||
override fun field6(): Field<Int?> = UpdateUserQueue.UPDATE_USER_QUEUE.PROGRESS_CURRENT
|
override fun field6(): Field<Int?> = UpdateUserQueue.UPDATE_USER_QUEUE.PROGRESS_CURRENT
|
||||||
override fun field7(): Field<Int?> = UpdateUserQueue.UPDATE_USER_QUEUE.PROGRESS_TOTAL
|
override fun field7(): Field<Int?> = UpdateUserQueue.UPDATE_USER_QUEUE.PROGRESS_TOTAL
|
||||||
|
override fun field8(): Field<Long?> = UpdateUserQueue.UPDATE_USER_QUEUE.ADDED_BY_USER_ID
|
||||||
override fun component1(): Int? = id
|
override fun component1(): Int? = id
|
||||||
override fun component2(): Long = userId
|
override fun component2(): Long = userId
|
||||||
override fun component3(): Boolean? = processed
|
override fun component3(): Boolean? = processed
|
||||||
@ -76,6 +81,7 @@ open class UpdateUserQueueRecord private constructor() : UpdatableRecordImpl<Upd
|
|||||||
override fun component5(): OffsetDateTime? = processedAt
|
override fun component5(): OffsetDateTime? = processedAt
|
||||||
override fun component6(): Int? = progressCurrent
|
override fun component6(): Int? = progressCurrent
|
||||||
override fun component7(): Int? = progressTotal
|
override fun component7(): Int? = progressTotal
|
||||||
|
override fun component8(): Long? = addedByUserId
|
||||||
override fun value1(): Int? = id
|
override fun value1(): Int? = id
|
||||||
override fun value2(): Long = userId
|
override fun value2(): Long = userId
|
||||||
override fun value3(): Boolean? = processed
|
override fun value3(): Boolean? = processed
|
||||||
@ -83,6 +89,7 @@ open class UpdateUserQueueRecord private constructor() : UpdatableRecordImpl<Upd
|
|||||||
override fun value5(): OffsetDateTime? = processedAt
|
override fun value5(): OffsetDateTime? = processedAt
|
||||||
override fun value6(): Int? = progressCurrent
|
override fun value6(): Int? = progressCurrent
|
||||||
override fun value7(): Int? = progressTotal
|
override fun value7(): Int? = progressTotal
|
||||||
|
override fun value8(): Long? = addedByUserId
|
||||||
|
|
||||||
override fun value1(value: Int?): UpdateUserQueueRecord {
|
override fun value1(value: Int?): UpdateUserQueueRecord {
|
||||||
set(0, value)
|
set(0, value)
|
||||||
@ -119,7 +126,12 @@ open class UpdateUserQueueRecord private constructor() : UpdatableRecordImpl<Upd
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun values(value1: Int?, value2: Long?, value3: Boolean?, value4: LocalDateTime?, value5: OffsetDateTime?, value6: Int?, value7: Int?): UpdateUserQueueRecord {
|
override fun value8(value: Long?): UpdateUserQueueRecord {
|
||||||
|
set(7, value)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun values(value1: Int?, value2: Long?, value3: Boolean?, value4: LocalDateTime?, value5: OffsetDateTime?, value6: Int?, value7: Int?, value8: Long?): UpdateUserQueueRecord {
|
||||||
this.value1(value1)
|
this.value1(value1)
|
||||||
this.value2(value2)
|
this.value2(value2)
|
||||||
this.value3(value3)
|
this.value3(value3)
|
||||||
@ -127,13 +139,14 @@ open class UpdateUserQueueRecord private constructor() : UpdatableRecordImpl<Upd
|
|||||||
this.value5(value5)
|
this.value5(value5)
|
||||||
this.value6(value6)
|
this.value6(value6)
|
||||||
this.value7(value7)
|
this.value7(value7)
|
||||||
|
this.value8(value8)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a detached, initialised UpdateUserQueueRecord
|
* Create a detached, initialised UpdateUserQueueRecord
|
||||||
*/
|
*/
|
||||||
constructor(id: Int? = null, userId: Long, processed: Boolean? = null, createdAt: LocalDateTime? = null, processedAt: OffsetDateTime? = null, progressCurrent: Int? = null, progressTotal: Int? = null): this() {
|
constructor(id: Int? = null, userId: Long, processed: Boolean? = null, createdAt: LocalDateTime? = null, processedAt: OffsetDateTime? = null, progressCurrent: Int? = null, progressTotal: Int? = null, addedByUserId: Long? = null): this() {
|
||||||
this.id = id
|
this.id = id
|
||||||
this.userId = userId
|
this.userId = userId
|
||||||
this.processed = processed
|
this.processed = processed
|
||||||
@ -141,6 +154,7 @@ open class UpdateUserQueueRecord private constructor() : UpdatableRecordImpl<Upd
|
|||||||
this.processedAt = processedAt
|
this.processedAt = processedAt
|
||||||
this.progressCurrent = progressCurrent
|
this.progressCurrent = progressCurrent
|
||||||
this.progressTotal = progressTotal
|
this.progressTotal = progressTotal
|
||||||
|
this.addedByUserId = addedByUserId
|
||||||
resetChangedOnNotNull()
|
resetChangedOnNotNull()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import org.springframework.security.web.authentication.logout.LogoutSuccessHandl
|
|||||||
import org.springframework.session.web.http.CookieSerializer
|
import org.springframework.session.web.http.CookieSerializer
|
||||||
import org.springframework.session.web.http.DefaultCookieSerializer
|
import org.springframework.session.web.http.DefaultCookieSerializer
|
||||||
import org.springframework.stereotype.Component
|
import org.springframework.stereotype.Component
|
||||||
|
import org.springframework.web.cors.CorsUtils
|
||||||
import org.springframework.web.filter.CorsFilter
|
import org.springframework.web.filter.CorsFilter
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
@ -69,6 +70,11 @@ class SecurityConfig {
|
|||||||
http
|
http
|
||||||
.csrf { csrf -> csrf.disable() }
|
.csrf { csrf -> csrf.disable() }
|
||||||
.addFilterBefore(customCorsFilter(), CorsFilter::class.java)
|
.addFilterBefore(customCorsFilter(), CorsFilter::class.java)
|
||||||
|
.authorizeHttpRequests { auth ->
|
||||||
|
auth
|
||||||
|
.requestMatchers("/user-queue").authenticated()
|
||||||
|
.anyRequest().permitAll()
|
||||||
|
}
|
||||||
.oauth2Login { oauthLogin ->
|
.oauth2Login { oauthLogin ->
|
||||||
oauthLogin.successHandler(CustomAuthenticationSuccessHandler())
|
oauthLogin.successHandler(CustomAuthenticationSuccessHandler())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import com.nisemoe.nise.SuspiciousScoreEntry
|
|||||||
import com.nisemoe.nise.UserDetails
|
import com.nisemoe.nise.UserDetails
|
||||||
import com.nisemoe.nise.UserQueueDetails
|
import com.nisemoe.nise.UserQueueDetails
|
||||||
import com.nisemoe.nise.database.UserService
|
import com.nisemoe.nise.database.UserService
|
||||||
|
import com.nisemoe.nise.service.AuthService
|
||||||
import com.nisemoe.nise.service.UpdateUserQueueService
|
import com.nisemoe.nise.service.UpdateUserQueueService
|
||||||
import org.springframework.http.ResponseEntity
|
import org.springframework.http.ResponseEntity
|
||||||
import org.springframework.web.bind.annotation.GetMapping
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
@ -21,6 +22,7 @@ import java.time.ZoneOffset
|
|||||||
@RestController
|
@RestController
|
||||||
class UserDetailsController(
|
class UserDetailsController(
|
||||||
private val scoreService: ScoreService,
|
private val scoreService: ScoreService,
|
||||||
|
private val authService: AuthService,
|
||||||
private val userService: UserService,
|
private val userService: UserService,
|
||||||
private val userQueueService: UpdateUserQueueService
|
private val userQueueService: UpdateUserQueueService
|
||||||
) {
|
) {
|
||||||
@ -43,7 +45,8 @@ class UserDetailsController(
|
|||||||
if(!userQueueDetails.canUpdate)
|
if(!userQueueDetails.canUpdate)
|
||||||
return ResponseEntity.badRequest().build()
|
return ResponseEntity.badRequest().build()
|
||||||
|
|
||||||
val inserted = this.userQueueService.insertUser(request.userId)
|
val inserted = this.userQueueService.insertUser(request.userId, addedByUserId = this.authService.getCurrentUser().userId)
|
||||||
|
|
||||||
return if(inserted)
|
return if(inserted)
|
||||||
ResponseEntity.ok().build()
|
ResponseEntity.ok().build()
|
||||||
else
|
else
|
||||||
|
|||||||
@ -154,12 +154,14 @@ class OsuApi(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getTopUserScores(userId: Long): List<OsuApiModels.Score>? {
|
fun getTopUserScores(userId: Long, type: String = "best"): List<OsuApiModels.Score>? {
|
||||||
val queryParams = mapOf(
|
val queryParams = mapOf(
|
||||||
"mode" to "osu",
|
"mode" to "osu",
|
||||||
"limit" to "100"
|
"limit" to "100",
|
||||||
|
"legacy_only" to "1"
|
||||||
)
|
)
|
||||||
val response = doRequest("https://osu.ppy.sh/api/v2/users/$userId/scores/best?", queryParams)
|
|
||||||
|
val response = doRequest("https://osu.ppy.sh/api/v2/users/$userId/scores/$type?", queryParams)
|
||||||
if(response == null) {
|
if(response == null) {
|
||||||
this.logger.info("Error loading top user scores")
|
this.logger.info("Error loading top user scores")
|
||||||
return null
|
return null
|
||||||
|
|||||||
@ -157,8 +157,26 @@ class ImportScores(
|
|||||||
|
|
||||||
for(userId in queue) {
|
for(userId in queue) {
|
||||||
val topUserScores = this.osuApi.getTopUserScores(userId = userId)
|
val topUserScores = this.osuApi.getTopUserScores(userId = userId)
|
||||||
|
val recentUserScores = this.osuApi.getTopUserScores(userId = userId, type = "recent")
|
||||||
|
val firstPlaceUserScores = this.osuApi.getTopUserScores(userId = userId, type = "firsts")
|
||||||
|
|
||||||
|
this.logger.info("Processing user with id = $userId")
|
||||||
|
this.logger.info("Top scores: ${topUserScores?.size}")
|
||||||
|
this.logger.info("Recent scores: ${recentUserScores?.size}")
|
||||||
|
this.logger.info("First place scores: ${firstPlaceUserScores?.size}")
|
||||||
|
|
||||||
Thread.sleep(this.sleepTimeInMs)
|
Thread.sleep(this.sleepTimeInMs)
|
||||||
if(topUserScores != null) {
|
|
||||||
|
if(topUserScores == null || recentUserScores == null || firstPlaceUserScores == null) {
|
||||||
|
this.logger.error("Failed to fetch top scores for user with id = $userId")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
val allUserScores = (topUserScores + recentUserScores + firstPlaceUserScores)
|
||||||
|
.filter { it.beatmap != null && it.beatmapset != null }
|
||||||
|
.distinctBy { it.best_id }
|
||||||
|
|
||||||
|
this.logger.info("Unique scores: ${allUserScores.size}")
|
||||||
|
|
||||||
val userExists = dslContext.fetchExists(USERS, USERS.USER_ID.eq(userId), USERS.SYS_LAST_UPDATE.greaterOrEqual(OffsetDateTime.now(ZoneOffset.UTC).minusDays(UPDATE_USER_EVERY_DAYS)))
|
val userExists = dslContext.fetchExists(USERS, USERS.USER_ID.eq(userId), USERS.SYS_LAST_UPDATE.greaterOrEqual(OffsetDateTime.now(ZoneOffset.UTC).minusDays(UPDATE_USER_EVERY_DAYS)))
|
||||||
if(!userExists) {
|
if(!userExists) {
|
||||||
@ -181,13 +199,12 @@ class ImportScores(
|
|||||||
.limit(1)
|
.limit(1)
|
||||||
.fetchOneInto(OffsetDateTime::class.java)
|
.fetchOneInto(OffsetDateTime::class.java)
|
||||||
|
|
||||||
for(topScore in topUserScores) {
|
for(topScore in allUserScores) {
|
||||||
if(topScore.beatmap != null && topScore.beatmapset != null) {
|
val beatmapExists = dslContext.fetchExists(BEATMAPS, BEATMAPS.BEATMAP_ID.eq(topScore.beatmap!!.id))
|
||||||
val beatmapExists = dslContext.fetchExists(BEATMAPS, BEATMAPS.BEATMAP_ID.eq(topScore.beatmap.id))
|
|
||||||
if (!beatmapExists) {
|
if (!beatmapExists) {
|
||||||
dslContext.insertInto(BEATMAPS)
|
dslContext.insertInto(BEATMAPS)
|
||||||
.set(BEATMAPS.BEATMAP_ID, topScore.beatmap.id)
|
.set(BEATMAPS.BEATMAP_ID, topScore.beatmap.id)
|
||||||
.set(BEATMAPS.BEATMAPSET_ID, topScore.beatmapset.id)
|
.set(BEATMAPS.BEATMAPSET_ID, topScore.beatmapset!!.id)
|
||||||
.set(BEATMAPS.STAR_RATING, topScore.beatmap.difficulty_rating)
|
.set(BEATMAPS.STAR_RATING, topScore.beatmap.difficulty_rating)
|
||||||
.set(BEATMAPS.VERSION, topScore.beatmap.version)
|
.set(BEATMAPS.VERSION, topScore.beatmap.version)
|
||||||
.set(BEATMAPS.ARTIST, topScore.beatmapset.artist)
|
.set(BEATMAPS.ARTIST, topScore.beatmapset.artist)
|
||||||
@ -202,7 +219,7 @@ class ImportScores(
|
|||||||
// Update the database
|
// Update the database
|
||||||
dslContext.update(UPDATE_USER_QUEUE)
|
dslContext.update(UPDATE_USER_QUEUE)
|
||||||
.set(UPDATE_USER_QUEUE.PROGRESS_CURRENT, current)
|
.set(UPDATE_USER_QUEUE.PROGRESS_CURRENT, current)
|
||||||
.set(UPDATE_USER_QUEUE.PROGRESS_TOTAL, topUserScores.size)
|
.set(UPDATE_USER_QUEUE.PROGRESS_TOTAL, allUserScores.size)
|
||||||
.where(UPDATE_USER_QUEUE.USER_ID.eq(userId))
|
.where(UPDATE_USER_QUEUE.USER_ID.eq(userId))
|
||||||
.and(UPDATE_USER_QUEUE.PROCESSED.isFalse)
|
.and(UPDATE_USER_QUEUE.PROCESSED.isFalse)
|
||||||
.execute()
|
.execute()
|
||||||
@ -212,7 +229,7 @@ class ImportScores(
|
|||||||
lastCompletedUpdate = lastCompletedUpdate,
|
lastCompletedUpdate = lastCompletedUpdate,
|
||||||
canUpdate = false,
|
canUpdate = false,
|
||||||
progressCurrent = current,
|
progressCurrent = current,
|
||||||
progressTotal = topUserScores.size
|
progressTotal = allUserScores.size
|
||||||
)
|
)
|
||||||
|
|
||||||
// Update the frontend
|
// Update the frontend
|
||||||
@ -222,10 +239,17 @@ class ImportScores(
|
|||||||
)
|
)
|
||||||
|
|
||||||
this.insertAndProcessNewScore(topScore.beatmap.id, topScore, isUserQueue = true)
|
this.insertAndProcessNewScore(topScore.beatmap.id, topScore, isUserQueue = true)
|
||||||
}
|
|
||||||
current += 1
|
current += 1
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Check for stolen replays.
|
||||||
|
val uniqueBeatmapIds = allUserScores
|
||||||
|
.groupBy { it.beatmap!!.id }
|
||||||
|
|
||||||
|
this.logger.info("Checking similarity for ${uniqueBeatmapIds.size} beatmaps.")
|
||||||
|
|
||||||
|
uniqueBeatmapIds.forEach { checkReplaySimilarity(it.key) }
|
||||||
|
|
||||||
// Update the backend
|
// Update the backend
|
||||||
this.updateUserQueueService.setUserAsProcessed(userId)
|
this.updateUserQueueService.setUserAsProcessed(userId)
|
||||||
@ -432,6 +456,11 @@ class ImportScores(
|
|||||||
.and(SCORES.IS_BANNED.isFalse)
|
.and(SCORES.IS_BANNED.isFalse)
|
||||||
.fetchInto(ReplayDto::class.java)
|
.fetchInto(ReplayDto::class.java)
|
||||||
|
|
||||||
|
if(allReplays.size < 2) {
|
||||||
|
this.logger.debug("Not enough replays to compare for beatmapId = $beatmapId.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
sw.start("konata")
|
sw.start("konata")
|
||||||
|
|
||||||
val konataResults: List<ReplaySetComparison> = try {
|
val konataResults: List<ReplaySetComparison> = try {
|
||||||
|
|||||||
@ -91,7 +91,7 @@ class UpdateUserQueueService(
|
|||||||
* Inserts a user into the update queue if they are not already in the queue.
|
* Inserts a user into the update queue if they are not already in the queue.
|
||||||
* @return true if the user was inserted, false if the user was already in the queue
|
* @return true if the user was inserted, false if the user was already in the queue
|
||||||
*/
|
*/
|
||||||
fun insertUser(userId: Long): Boolean {
|
fun insertUser(userId: Long, addedByUserId: Long? = null): Boolean {
|
||||||
val exists = dslContext.fetchExists(UPDATE_USER_QUEUE,
|
val exists = dslContext.fetchExists(UPDATE_USER_QUEUE,
|
||||||
UPDATE_USER_QUEUE.USER_ID.eq(userId),
|
UPDATE_USER_QUEUE.USER_ID.eq(userId),
|
||||||
UPDATE_USER_QUEUE.PROCESSED.isFalse
|
UPDATE_USER_QUEUE.PROCESSED.isFalse
|
||||||
@ -101,6 +101,7 @@ class UpdateUserQueueService(
|
|||||||
|
|
||||||
val insertedRows = dslContext.insertInto(UPDATE_USER_QUEUE)
|
val insertedRows = dslContext.insertInto(UPDATE_USER_QUEUE)
|
||||||
.set(UPDATE_USER_QUEUE.USER_ID, userId)
|
.set(UPDATE_USER_QUEUE.USER_ID, userId)
|
||||||
|
.set(UPDATE_USER_QUEUE.ADDED_BY_USER_ID, addedByUserId)
|
||||||
.execute()
|
.execute()
|
||||||
|
|
||||||
return insertedRows == 1
|
return insertedRows == 1
|
||||||
|
|||||||
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE public.update_user_queue
|
||||||
|
ADD COLUMN added_by_user_id bigint;
|
||||||
@ -40,6 +40,7 @@
|
|||||||
<li *ngIf="this.userInfo.user_details.playcount">Playcount: {{ this.userInfo.user_details.playcount | number: '1.0-1' }}</li>
|
<li *ngIf="this.userInfo.user_details.playcount">Playcount: {{ this.userInfo.user_details.playcount | number: '1.0-1' }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<ng-container *ngIf="this.userService.isUserLoggedIn()">
|
||||||
<ng-container *ngIf="!this.userInfo.queue_details.isProcessing; else updateProgress">
|
<ng-container *ngIf="!this.userInfo.queue_details.isProcessing; else updateProgress">
|
||||||
<ng-container *ngIf="this.userInfo.queue_details.canUpdate">
|
<ng-container *ngIf="this.userInfo.queue_details.canUpdate">
|
||||||
<a (click)="this.addUserToQueue()" class="btn btn-success pointer" target="_blank">
|
<a (click)="this.addUserToQueue()" class="btn btn-success pointer" target="_blank">
|
||||||
@ -63,6 +64,7 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container *ngIf="this.userInfo.suspicious_scores.length > 0">
|
<ng-container *ngIf="this.userInfo.suspicious_scores.length > 0">
|
||||||
<h4>Suspicious Scores ({{ this.userInfo.suspicious_scores.length }})</h4>
|
<h4>Suspicious Scores ({{ this.userInfo.suspicious_scores.length }})</h4>
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import {Message} from "@stomp/stompjs/esm6";
|
|||||||
import {CuteLoadingComponent} from "../../corelib/components/cute-loading/cute-loading.component";
|
import {CuteLoadingComponent} from "../../corelib/components/cute-loading/cute-loading.component";
|
||||||
import {differenceInDays, differenceInHours} from "date-fns/fp";
|
import {differenceInDays, differenceInHours} from "date-fns/fp";
|
||||||
import {FilterManagerService} from "../filter-manager.service";
|
import {FilterManagerService} from "../filter-manager.service";
|
||||||
|
import {UserService} from "../../corelib/service/user.service";
|
||||||
|
|
||||||
interface UserInfo {
|
interface UserInfo {
|
||||||
user_details: UserDetails;
|
user_details: UserDetails;
|
||||||
@ -63,6 +64,7 @@ export class ViewUserComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
private activatedRoute: ActivatedRoute,
|
private activatedRoute: ActivatedRoute,
|
||||||
private title: Title,
|
private title: Title,
|
||||||
private rxStompService: RxStompService,
|
private rxStompService: RxStompService,
|
||||||
|
public userService: UserService
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
getUserInfo(): Observable<UserInfo> {
|
getUserInfo(): Observable<UserInfo> {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user