Cleaning up advanced search
This commit is contained in:
parent
f182284f60
commit
79557b170a
@ -5,19 +5,10 @@ import com.nisemoe.generated.tables.references.SCORES
|
|||||||
import com.nisemoe.generated.tables.references.USERS
|
import com.nisemoe.generated.tables.references.USERS
|
||||||
import com.nisemoe.nise.Format
|
import com.nisemoe.nise.Format
|
||||||
import com.nisemoe.nise.service.AuthService
|
import com.nisemoe.nise.service.AuthService
|
||||||
import org.jooq.Condition
|
import org.jooq.*
|
||||||
import org.jooq.DSLContext
|
|
||||||
import org.jooq.Field
|
|
||||||
import org.jooq.OrderField
|
|
||||||
import org.jooq.Record
|
|
||||||
import org.jooq.Result
|
|
||||||
import org.jooq.impl.DSL
|
import org.jooq.impl.DSL
|
||||||
import org.springframework.http.ResponseEntity
|
import org.springframework.http.ResponseEntity
|
||||||
import org.springframework.web.bind.annotation.GetMapping
|
import org.springframework.web.bind.annotation.*
|
||||||
import org.springframework.web.bind.annotation.PostMapping
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody
|
|
||||||
import org.springframework.web.bind.annotation.RequestHeader
|
|
||||||
import org.springframework.web.bind.annotation.RestController
|
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@ -144,6 +135,18 @@ class SearchController(
|
|||||||
val type: String
|
val type: String
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data class InternalSchemaField(
|
||||||
|
val name: String,
|
||||||
|
val shortName: String,
|
||||||
|
val category: Category,
|
||||||
|
val type: Type,
|
||||||
|
val active: Boolean,
|
||||||
|
val description: String,
|
||||||
|
|
||||||
|
val isPrivileged: Boolean = false,
|
||||||
|
val databaseField: Field<*>? = null
|
||||||
|
)
|
||||||
|
|
||||||
data class SchemaField(
|
data class SchemaField(
|
||||||
val name: String,
|
val name: String,
|
||||||
val shortName: String,
|
val shortName: String,
|
||||||
@ -169,68 +172,89 @@ class SearchController(
|
|||||||
|
|
||||||
@GetMapping("search")
|
@GetMapping("search")
|
||||||
fun getSearchSchema(): ResponseEntity<SearchSchema> {
|
fun getSearchSchema(): ResponseEntity<SearchSchema> {
|
||||||
val fields = listOf(
|
val internalFields = listOf(
|
||||||
// User fields
|
// User fields
|
||||||
SchemaField("user_id", "ID", Category.user, Type.number, false, "unique identifier for a user"),
|
InternalSchemaField("user_id", "ID", Category.user, Type.number, false, "unique identifier for a user"),
|
||||||
SchemaField("user_username", "Username", Category.user, Type.string, true, "user's name"),
|
InternalSchemaField("user_username", "Username", Category.user, Type.string, true, "user's name"),
|
||||||
SchemaField("user_join_date", "Join Date", Category.user, Type.string, false, "when the user joined"),
|
InternalSchemaField("user_join_date", "Join Date", Category.user, Type.string, false, "when the user joined"),
|
||||||
SchemaField("user_country", "Country", Category.user, Type.flag, true, "user's country flag"),
|
InternalSchemaField("user_country", "Country", Category.user, Type.flag, true, "user's country flag"),
|
||||||
SchemaField("user_country_rank", "Country Rank", Category.user, Type.number, false, "ranking within user's country"),
|
InternalSchemaField("user_country_rank", "Country Rank", Category.user, Type.number, false, "ranking within user's country"),
|
||||||
SchemaField("user_rank", "Rank", Category.user, Type.number, false, "global ranking"),
|
InternalSchemaField("user_rank", "Rank", Category.user, Type.number, false, "global ranking"),
|
||||||
SchemaField("user_pp_raw", "User PP", Category.user, Type.number, false, "performance points"),
|
InternalSchemaField("user_pp_raw", "User PP", Category.user, Type.number, false, "performance points"),
|
||||||
SchemaField("user_accuracy", "User Accuracy", Category.user, Type.number, false, "hit accuracy percentage"),
|
InternalSchemaField("user_accuracy", "User Accuracy", Category.user, Type.number, false, "hit accuracy percentage"),
|
||||||
SchemaField("user_playcount", "Playcount", Category.user, Type.number, false, "total plays"),
|
InternalSchemaField("user_playcount", "Playcount", Category.user, Type.number, false, "total plays"),
|
||||||
SchemaField("user_total_score", "Total Score", Category.user, Type.number, false, "cumulative score"),
|
InternalSchemaField("user_total_score", "Total Score", Category.user, Type.number, false, "cumulative score"),
|
||||||
SchemaField("user_ranked_score", "Ranked Score", Category.user, Type.number, false, "score from ranked maps"),
|
InternalSchemaField("user_ranked_score", "Ranked Score", Category.user, Type.number, false, "score from ranked maps"),
|
||||||
SchemaField("user_seconds_played", "Play Time", Category.user, Type.number, false, "total play time in seconds"),
|
InternalSchemaField("user_seconds_played", "Play Time", Category.user, Type.number, false, "total play time in seconds"),
|
||||||
SchemaField("user_count_300", "300s", Category.user, Type.number, false, "number of 300 hits"),
|
InternalSchemaField("user_count_300", "300s", Category.user, Type.number, false, "number of 300 hits"),
|
||||||
SchemaField("user_count_100", "100s", Category.user, Type.number, false, "number of 100 hits"),
|
InternalSchemaField("user_count_100", "100s", Category.user, Type.number, false, "number of 100 hits"),
|
||||||
SchemaField("user_count_50", "50s", Category.user, Type.number, false, "number of 50 hits"),
|
InternalSchemaField("user_count_50", "50s", Category.user, Type.number, false, "number of 50 hits"),
|
||||||
SchemaField("user_count_miss", "Misses", Category.user, Type.number, false, "missed hits"),
|
InternalSchemaField("user_count_miss", "Misses", Category.user, Type.number, false, "missed hits"),
|
||||||
|
|
||||||
// Score fields
|
// Score fields
|
||||||
SchemaField("id", "ID", Category.score, Type.number, false, "unique identifier for a score"),
|
InternalSchemaField("id", "ID", Category.score, Type.number, false, "unique identifier for a score"),
|
||||||
SchemaField("beatmap_id", "Beatmap ID", Category.score, Type.number, false, "identifies the beatmap"),
|
InternalSchemaField("beatmap_id", "Beatmap ID", Category.score, Type.number, false, "identifies the beatmap"),
|
||||||
SchemaField("count_300", "300s", Category.score, Type.number, false, "number of 300 hits in score"),
|
InternalSchemaField("count_300", "300s", Category.score, Type.number, false, "number of 300 hits in score"),
|
||||||
SchemaField("count_100", "100s", Category.score, Type.number, false, "number of 100 hits in score"),
|
InternalSchemaField("count_100", "100s", Category.score, Type.number, false, "number of 100 hits in score"),
|
||||||
SchemaField("count_50", "50s", Category.score, Type.number, false, "number of 50 hits in score"),
|
InternalSchemaField("count_50", "50s", Category.score, Type.number, false, "number of 50 hits in score"),
|
||||||
SchemaField("count_miss", "Misses", Category.score, Type.number, false, "missed hits in score"),
|
InternalSchemaField("count_miss", "Misses", Category.score, Type.number, false, "missed hits in score"),
|
||||||
SchemaField("date", "Date", Category.score, Type.string, true, "when score was achieved"),
|
InternalSchemaField("date", "Date", Category.score, Type.string, true, "when score was achieved"),
|
||||||
SchemaField("max_combo", "Max Combo", Category.score, Type.number, false, "highest combo in score"),
|
InternalSchemaField("max_combo", "Max Combo", Category.score, Type.number, false, "highest combo in score"),
|
||||||
SchemaField("mods", "Mods", Category.score, Type.number, false, "game modifiers used"),
|
InternalSchemaField("mods", "Mods", Category.score, Type.number, false, "game modifiers used"),
|
||||||
SchemaField("perfect", "Perfect", Category.score, Type.boolean, false, "if score is a full combo"),
|
InternalSchemaField("perfect", "Perfect", Category.score, Type.boolean, false, "if score is a full combo"),
|
||||||
SchemaField("pp", "Score PP", Category.score, Type.number, true, "performance points for score"),
|
InternalSchemaField("pp", "Score PP", Category.score, Type.number, true, "performance points for score"),
|
||||||
SchemaField("rank", "Rank", Category.score, Type.grade, false, "score grade"),
|
InternalSchemaField("rank", "Rank", Category.score, Type.grade, false, "score grade"),
|
||||||
SchemaField("replay_id", "Replay ID", Category.score, Type.number, false, "identifier for replay"),
|
InternalSchemaField("replay_id", "Replay ID", Category.score, Type.number, false, "identifier for replay"),
|
||||||
SchemaField("score", "Score", Category.score, Type.number, false, "score value"),
|
InternalSchemaField("score", "Score", Category.score, Type.number, false, "score value"),
|
||||||
SchemaField("ur", "UR", Category.score, Type.number, false, "unstable rate"),
|
InternalSchemaField("ur", "UR", Category.score, Type.number, false, "unstable rate"),
|
||||||
SchemaField("frametime", "Frame Time", Category.score, Type.number, false, "average frame time during play"),
|
InternalSchemaField("frametime", "Frame Time", Category.score, Type.number, false, "average frame time during play"),
|
||||||
SchemaField("edge_hits", "Edge Hits", Category.score, Type.number, false, "hits at the edge of hit window"),
|
InternalSchemaField("edge_hits", "Edge Hits", Category.score, Type.number, false, "hits at the edge of hit window"),
|
||||||
SchemaField("snaps", "Snaps", Category.score, Type.number, false, "rapid cursor movements"),
|
InternalSchemaField("snaps", "Snaps", Category.score, Type.number, false, "rapid cursor movements"),
|
||||||
SchemaField("adjusted_ur", "Adj. UR", Category.score, Type.number, true, "adjusted unstable rate"),
|
InternalSchemaField("adjusted_ur", "Adj. UR", Category.score, Type.number, true, "adjusted unstable rate"),
|
||||||
SchemaField("mean_error", "Mean Error", Category.score, Type.number, false, "average timing error"),
|
InternalSchemaField("mean_error", "Mean Error", Category.score, Type.number, false, "average timing error"),
|
||||||
SchemaField("error_variance", "Error Var.", Category.score, Type.number, false, "variability of error in scores"),
|
InternalSchemaField("error_variance", "Error Var.", Category.score, Type.number, false, "variability of error in scores"),
|
||||||
SchemaField("error_standard_deviation", "Error SD", Category.score, Type.number, false, "standard deviation of error"),
|
InternalSchemaField("error_standard_deviation", "Error SD", Category.score, Type.number, false, "standard deviation of error"),
|
||||||
SchemaField("minimum_error", "Min Error", Category.score, Type.number, false, "smallest error recorded"),
|
InternalSchemaField("minimum_error", "Min Error", Category.score, Type.number, false, "smallest error recorded"),
|
||||||
SchemaField("maximum_error", "Max Error", Category.score, Type.number, false, "largest error recorded"),
|
InternalSchemaField("maximum_error", "Max Error", Category.score, Type.number, false, "largest error recorded"),
|
||||||
SchemaField("error_range", "Error Range", Category.score, Type.number, false, "range between min and max error"),
|
InternalSchemaField("error_range", "Error Range", Category.score, Type.number, false, "range between min and max error"),
|
||||||
SchemaField("error_coefficient_of_variation", "Error CV", Category.score, Type.number, false, "relative variability of error"),
|
InternalSchemaField("error_coefficient_of_variation", "Error CV", Category.score, Type.number, false, "relative variability of error"),
|
||||||
SchemaField("error_kurtosis", "Kurtosis", Category.score, Type.number, false, "peakedness of error distribution"),
|
InternalSchemaField("error_kurtosis", "Kurtosis", Category.score, Type.number, false, "peakedness of error distribution"),
|
||||||
SchemaField("error_skewness", "Skewness", Category.score, Type.number, false, "asymmetry of error distribution"),
|
InternalSchemaField("error_skewness", "Skewness", Category.score, Type.number, false, "asymmetry of error distribution"),
|
||||||
SchemaField("keypresses_median_adjusted", "KP Median Adj.", Category.score, Type.number, false, "median of adjusted keypresses"),
|
InternalSchemaField("keypresses_median_adjusted", "KP Median Adj.", Category.score, Type.number, false, "median of adjusted keypresses", isPrivileged = true),
|
||||||
SchemaField("keypresses_standard_deviation_adjusted", "KP std. Adj.", Category.score, Type.number, false, "std. dev of adjusted keypresses"),
|
InternalSchemaField("keypresses_standard_deviation_adjusted", "KP std. Adj.", Category.score, Type.number, false, "std. dev of adjusted keypresses", isPrivileged = true),
|
||||||
SchemaField("sliderend_release_median_adjusted", "Sliderend Median Adj.", Category.score, Type.number, false, "median of adjusted sliderend releases"),
|
InternalSchemaField("sliderend_release_median_adjusted", "Sliderend Median Adj.", Category.score, Type.number, false, "median of adjusted sliderend releases", isPrivileged = true),
|
||||||
SchemaField("sliderend_release_standard_deviation_adjusted", "Sliderend std. Adj.", Category.score, Type.number, false, "std. dev of adjusted sliderend releases"),
|
InternalSchemaField("sliderend_release_standard_deviation_adjusted", "Sliderend std. Adj.", Category.score, Type.number, false, "std. dev of adjusted sliderend releases", isPrivileged = true),
|
||||||
|
|
||||||
// Beatmap fields
|
// Beatmap fields
|
||||||
SchemaField("beatmap_artist", "Artist", Category.beatmap, Type.string, false, "artist of the beatmap"),
|
InternalSchemaField("beatmap_artist", "Artist", Category.beatmap, Type.string, false, "artist of the beatmap"),
|
||||||
SchemaField("beatmap_beatmapset_id", "Set ID", Category.beatmap, Type.number, false, "id of the beatmap set"),
|
InternalSchemaField("beatmap_beatmapset_id", "Set ID", Category.beatmap, Type.number, false, "id of the beatmap set"),
|
||||||
SchemaField("beatmap_creator", "Creator", Category.beatmap, Type.string, false, "creator of the beatmap"),
|
InternalSchemaField("beatmap_creator", "Creator", Category.beatmap, Type.string, false, "creator of the beatmap"),
|
||||||
SchemaField("beatmap_source", "Source", Category.beatmap, Type.string, false, "source of the beatmap music"),
|
InternalSchemaField("beatmap_source", "Source", Category.beatmap, Type.string, false, "source of the beatmap music"),
|
||||||
SchemaField("beatmap_star_rating", "Stars", Category.beatmap, Type.number, false, "(★) difficulty rating of the beatmap"),
|
InternalSchemaField("beatmap_star_rating", "Stars", Category.beatmap, Type.number, false, "(★) difficulty rating of the beatmap"),
|
||||||
SchemaField("beatmap_title", "Title", Category.beatmap, Type.string, false, "title of the beatmap"),
|
InternalSchemaField("beatmap_title", "Title", Category.beatmap, Type.string, false, "title of the beatmap"),
|
||||||
SchemaField("beatmap_version", "Version", Category.beatmap, Type.string, false, "version or difficulty name of the beatmap")
|
InternalSchemaField("beatmap_version", "Version", Category.beatmap, Type.string, false, "version or difficulty name of the beatmap")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Map to SchemaField
|
||||||
|
val isUserAdmin = authService.isAdmin()
|
||||||
|
val fields = internalFields
|
||||||
|
.filter {
|
||||||
|
return@filter !(it.isPrivileged && !isUserAdmin)
|
||||||
|
}
|
||||||
|
.map {
|
||||||
|
SchemaField(
|
||||||
|
name = it.name,
|
||||||
|
shortName = it.shortName,
|
||||||
|
category = it.category,
|
||||||
|
type = it.type,
|
||||||
|
active = it.active,
|
||||||
|
description = it.description
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter privileged fields
|
||||||
|
|
||||||
|
|
||||||
val schema = SearchSchema(fields)
|
val schema = SearchSchema(fields)
|
||||||
return ResponseEntity.ok(schema)
|
return ResponseEntity.ok(schema)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -112,12 +112,7 @@ export class SearchComponent implements OnInit {
|
|||||||
queries: Query[] | null = null;
|
queries: Query[] | null = null;
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
this.httpClient.get<SchemaResponse>(`${environment.apiUrl}/search`,).subscribe({
|
||||||
this.localCacheService.fetchData<SchemaResponse>(
|
|
||||||
"search-schema",
|
|
||||||
`${environment.apiUrl}/search`,
|
|
||||||
60
|
|
||||||
).subscribe({
|
|
||||||
next: (response) => {
|
next: (response) => {
|
||||||
this.fields = response.fields;
|
this.fields = response.fields;
|
||||||
this.loadPreviousFromLocalStorage();
|
this.loadPreviousFromLocalStorage();
|
||||||
|
|||||||
@ -15,7 +15,6 @@ export class UserService {
|
|||||||
currentUser: UserInfo | null = null;
|
currentUser: UserInfo | null = null;
|
||||||
|
|
||||||
loginCallback: () => void = () => {};
|
loginCallback: () => void = () => {};
|
||||||
logoutCallback: () => void = () => {};
|
|
||||||
|
|
||||||
constructor(private httpClient: HttpClient) {
|
constructor(private httpClient: HttpClient) {
|
||||||
this.currentUser = this.loadCurrentUserFromLocalStorage();
|
this.currentUser = this.loadCurrentUserFromLocalStorage();
|
||||||
@ -23,14 +22,6 @@ export class UserService {
|
|||||||
.catch(reason => console.debug(reason));
|
.catch(reason => console.debug(reason));
|
||||||
}
|
}
|
||||||
|
|
||||||
public doLogout(): void {
|
|
||||||
this.currentUser = null;
|
|
||||||
this.clearCurrentUserFromLocalStorage();
|
|
||||||
this.updateUser().then(
|
|
||||||
() => this.logoutCallback()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
isUserLoggedIn(): boolean {
|
isUserLoggedIn(): boolean {
|
||||||
return this.currentUser !== null;
|
return this.currentUser !== null;
|
||||||
}
|
}
|
||||||
@ -74,7 +65,7 @@ export class UserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
clearCurrentUserFromLocalStorage() {
|
clearCurrentUserFromLocalStorage() {
|
||||||
localStorage.setItem('currentUser', '');
|
localStorage.removeItem('currentUser');
|
||||||
document.cookie = 'SESSION=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
|
document.cookie = 'SESSION=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user