Added custom file names, fixed bugs

This commit is contained in:
nise.moe 2024-02-24 18:38:37 +01:00
parent b1635fd79c
commit f182284f60
4 changed files with 78 additions and 64 deletions

View File

@ -171,64 +171,65 @@ class SearchController(
fun getSearchSchema(): ResponseEntity<SearchSchema> { fun getSearchSchema(): ResponseEntity<SearchSchema> {
val fields = listOf( val fields = listOf(
// User fields // User fields
SchemaField("user_id", "ID", Category.user, Type.number, true, "unique identifier for a user"), SchemaField("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"), SchemaField("user_username", "Username", Category.user, Type.string, true, "user's name"),
SchemaField("user_join_date", "Join Date", Category.user, Type.string, true, "when the user joined"), SchemaField("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"), SchemaField("user_country", "Country", Category.user, Type.flag, true, "user's country flag"),
SchemaField("user_country_rank", "Country Rank", Category.user, Type.number, true, "ranking within user's country"), SchemaField("user_country_rank", "Country Rank", Category.user, Type.number, false, "ranking within user's country"),
SchemaField("user_rank", "Rank", Category.user, Type.number, true, "global ranking"), SchemaField("user_rank", "Rank", Category.user, Type.number, false, "global ranking"),
SchemaField("user_pp_raw", "User PP", Category.user, Type.number, true, "performance points"), SchemaField("user_pp_raw", "User PP", Category.user, Type.number, false, "performance points"),
SchemaField("user_accuracy", "User Accuracy", Category.user, Type.number, true, "hit accuracy percentage"), SchemaField("user_accuracy", "User Accuracy", Category.user, Type.number, false, "hit accuracy percentage"),
SchemaField("user_playcount", "Playcount", Category.user, Type.number, true, "total plays"), SchemaField("user_playcount", "Playcount", Category.user, Type.number, false, "total plays"),
SchemaField("user_total_score", "Total Score", Category.user, Type.number, true, "cumulative score"), SchemaField("user_total_score", "Total Score", Category.user, Type.number, false, "cumulative score"),
SchemaField("user_ranked_score", "Ranked Score", Category.user, Type.number, true, "score from ranked maps"), SchemaField("user_ranked_score", "Ranked Score", Category.user, Type.number, false, "score from ranked maps"),
SchemaField("user_seconds_played", "Play Time", Category.user, Type.number, true, "total play time in seconds"), SchemaField("user_seconds_played", "Play Time", Category.user, Type.number, false, "total play time in seconds"),
SchemaField("user_count_300", "300s", Category.user, Type.number, true, "number of 300 hits"), SchemaField("user_count_300", "300s", Category.user, Type.number, false, "number of 300 hits"),
SchemaField("user_count_100", "100s", Category.user, Type.number, true, "number of 100 hits"), SchemaField("user_count_100", "100s", Category.user, Type.number, false, "number of 100 hits"),
SchemaField("user_count_50", "50s", Category.user, Type.number, true, "number of 50 hits"), SchemaField("user_count_50", "50s", Category.user, Type.number, false, "number of 50 hits"),
SchemaField("user_count_miss", "Misses", Category.user, Type.number, true, "missed hits"), SchemaField("user_count_miss", "Misses", Category.user, Type.number, false, "missed hits"),
// Score fields // Score fields
SchemaField("beatmap_id", "Beatmap ID", Category.score, Type.number, true, "identifies the beatmap"), SchemaField("id", "ID", Category.score, Type.number, false, "unique identifier for a score"),
SchemaField("count_300", "300s", Category.score, Type.number, true, "number of 300 hits in score"), SchemaField("beatmap_id", "Beatmap ID", Category.score, Type.number, false, "identifies the beatmap"),
SchemaField("count_100", "100s", Category.score, Type.number, true, "number of 100 hits in score"), SchemaField("count_300", "300s", Category.score, Type.number, false, "number of 300 hits in score"),
SchemaField("count_50", "50s", Category.score, Type.number, true, "number of 50 hits in score"), SchemaField("count_100", "100s", Category.score, Type.number, false, "number of 100 hits in score"),
SchemaField("count_miss", "Misses", Category.score, Type.number, true, "missed hits in score"), SchemaField("count_50", "50s", Category.score, Type.number, false, "number of 50 hits in score"),
SchemaField("date", "Date", Category.score, Type.number, true, "when score was achieved"), SchemaField("count_miss", "Misses", Category.score, Type.number, false, "missed hits in score"),
SchemaField("max_combo", "Max Combo", Category.score, Type.number, true, "highest combo in score"), SchemaField("date", "Date", Category.score, Type.string, true, "when score was achieved"),
SchemaField("mods", "Mods", Category.score, Type.number, true, "game modifiers used"), SchemaField("max_combo", "Max Combo", Category.score, Type.number, false, "highest combo in score"),
SchemaField("perfect", "Perfect", Category.score, Type.boolean, true, "if score is a full combo"), SchemaField("mods", "Mods", Category.score, Type.number, false, "game modifiers used"),
SchemaField("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"), SchemaField("pp", "Score PP", Category.score, Type.number, true, "performance points for score"),
SchemaField("rank", "Rank", Category.score, Type.grade, true, "score grade"), SchemaField("rank", "Rank", Category.score, Type.grade, false, "score grade"),
SchemaField("replay_id", "Replay ID", Category.score, Type.number, true, "identifier for replay"), SchemaField("replay_id", "Replay ID", Category.score, Type.number, false, "identifier for replay"),
SchemaField("score", "Score", Category.score, Type.number, true, "score value"), SchemaField("score", "Score", Category.score, Type.number, false, "score value"),
SchemaField("ur", "UR", Category.score, Type.number, true, "unstable rate"), SchemaField("ur", "UR", Category.score, Type.number, false, "unstable rate"),
SchemaField("frametime", "Frame Time", Category.score, Type.number, true, "average frame time during play"), SchemaField("frametime", "Frame Time", Category.score, Type.number, false, "average frame time during play"),
SchemaField("edge_hits", "Edge Hits", Category.score, Type.number, true, "hits at the edge of hit window"), SchemaField("edge_hits", "Edge Hits", Category.score, Type.number, false, "hits at the edge of hit window"),
SchemaField("snaps", "Snaps", Category.score, Type.number, true, "rapid cursor movements"), SchemaField("snaps", "Snaps", Category.score, Type.number, false, "rapid cursor movements"),
SchemaField("adjusted_ur", "Adj. UR", Category.score, Type.number, true, "adjusted unstable rate"), SchemaField("adjusted_ur", "Adj. UR", Category.score, Type.number, true, "adjusted unstable rate"),
SchemaField("mean_error", "Mean Error", Category.score, Type.number, true, "average timing error"), SchemaField("mean_error", "Mean Error", Category.score, Type.number, false, "average timing error"),
SchemaField("error_variance", "Error Var.", Category.score, Type.number, true, "variability of error in scores"), SchemaField("error_variance", "Error Var.", Category.score, Type.number, false, "variability of error in scores"),
SchemaField("error_standard_deviation", "Error SD", Category.score, Type.number, true, "standard deviation of error"), SchemaField("error_standard_deviation", "Error SD", Category.score, Type.number, false, "standard deviation of error"),
SchemaField("minimum_error", "Min Error", Category.score, Type.number, true, "smallest error recorded"), SchemaField("minimum_error", "Min Error", Category.score, Type.number, false, "smallest error recorded"),
SchemaField("maximum_error", "Max Error", Category.score, Type.number, true, "largest error recorded"), SchemaField("maximum_error", "Max Error", Category.score, Type.number, false, "largest error recorded"),
SchemaField("error_range", "Error Range", Category.score, Type.number, true, "range between min and max error"), SchemaField("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, true, "relative variability of error"), SchemaField("error_coefficient_of_variation", "Error CV", Category.score, Type.number, false, "relative variability of error"),
SchemaField("error_kurtosis", "Kurtosis", Category.score, Type.number, true, "peakedness of error distribution"), SchemaField("error_kurtosis", "Kurtosis", Category.score, Type.number, false, "peakedness of error distribution"),
SchemaField("error_skewness", "Skewness", Category.score, Type.number, true, "asymmetry of error distribution"), SchemaField("error_skewness", "Skewness", Category.score, Type.number, false, "asymmetry of error distribution"),
SchemaField("keypresses_median_adjusted", "KP Median Adj.", Category.score, Type.number, true, "median of adjusted keypresses"), SchemaField("keypresses_median_adjusted", "KP Median Adj.", Category.score, Type.number, false, "median of adjusted keypresses"),
SchemaField("keypresses_standard_deviation_adjusted", "KP std. Adj.", Category.score, Type.number, true, "std. dev of adjusted keypresses"), SchemaField("keypresses_standard_deviation_adjusted", "KP std. Adj.", Category.score, Type.number, false, "std. dev of adjusted keypresses"),
SchemaField("sliderend_release_median_adjusted", "Sliderend Median Adj.", Category.score, Type.number, true, "median of adjusted sliderend releases"), SchemaField("sliderend_release_median_adjusted", "Sliderend Median Adj.", Category.score, Type.number, false, "median of adjusted sliderend releases"),
SchemaField("sliderend_release_standard_deviation_adjusted", "Sliderend std. Adj.", Category.score, Type.number, true, "std. dev of adjusted sliderend releases"), SchemaField("sliderend_release_standard_deviation_adjusted", "Sliderend std. Adj.", Category.score, Type.number, false, "std. dev of adjusted sliderend releases"),
// Beatmap fields // Beatmap fields
SchemaField("beatmap_artist", "Artist", Category.beatmap, Type.string, true, "artist of the beatmap"), SchemaField("beatmap_artist", "Artist", Category.beatmap, Type.string, false, "artist of the beatmap"),
SchemaField("beatmap_beatmapset_id", "Set ID", Category.beatmap, Type.number, true, "id of the beatmap set"), SchemaField("beatmap_beatmapset_id", "Set ID", Category.beatmap, Type.number, false, "id of the beatmap set"),
SchemaField("beatmap_creator", "Creator", Category.beatmap, Type.string, true, "creator of the beatmap"), SchemaField("beatmap_creator", "Creator", Category.beatmap, Type.string, false, "creator of the beatmap"),
SchemaField("beatmap_source", "Source", Category.beatmap, Type.string, true, "source of the beatmap music"), SchemaField("beatmap_source", "Source", Category.beatmap, Type.string, false, "source of the beatmap music"),
SchemaField("beatmap_star_rating", "Stars", Category.beatmap, Type.number, true, "(★) difficulty rating of the beatmap"), SchemaField("beatmap_star_rating", "Stars", Category.beatmap, Type.number, false, "(★) difficulty rating of the beatmap"),
SchemaField("beatmap_title", "Title", Category.beatmap, Type.string, true, "title of the beatmap"), SchemaField("beatmap_title", "Title", Category.beatmap, Type.string, false, "title of the beatmap"),
SchemaField("beatmap_version", "Version", Category.beatmap, Type.string, true, "version or difficulty name of the beatmap") SchemaField("beatmap_version", "Version", Category.beatmap, Type.string, false, "version or difficulty name of the beatmap")
) )
val schema = SearchSchema(fields) val schema = SearchSchema(fields)
return ResponseEntity.ok(schema) return ResponseEntity.ok(schema)

View File

@ -74,9 +74,9 @@
<fieldset class="mb-2"> <fieldset class="mb-2">
<legend>tools</legend> <legend>tools</legend>
<div class="text-center"> <div class="text-center">
<button (click)="this.downloadFilesService.downloadCSV(response.scores)">Download .csv</button> <button (click)="this.downloadFilesService.downloadCSV(response.scores, getColumns(), 'nise-search')">Download .csv</button>
<button (click)="this.downloadFilesService.downloadJSON(response.scores)">Download .json</button> <button (click)="this.downloadFilesService.downloadJSON(response.scores, 'nise-search')">Download .json</button>
<button (click)="this.downloadFilesService.downloadXLSX(response.scores)">Download .xlsx</button> <button (click)="this.downloadFilesService.downloadXLSX(response.scores, 'nise-search')">Download .xlsx</button>
</div> </div>
</fieldset> </fieldset>
<div class="scrollable-table"> <div class="scrollable-table">
@ -84,7 +84,7 @@
<thead> <thead>
<tr> <tr>
<th *ngFor="let column of fields" [hidden]="!column.active" class="text-center"> <th *ngFor="let column of fields" [hidden]="!column.active" class="text-center">
{{ column.short_name }} {{ column.shortName }}
</th> </th>
</tr> </tr>
</thead> </thead>

View File

@ -13,7 +13,7 @@ import {LocalCacheService} from "../../corelib/service/local-cache.service";
interface SchemaField { interface SchemaField {
name: string; name: string;
short_name: string; shortName: string;
category: 'user' | 'score' | 'beatmap'; category: 'user' | 'score' | 'beatmap';
type: 'number' | 'string' | 'flag' | 'grade' | 'boolean'; type: 'number' | 'string' | 'flag' | 'grade' | 'boolean';
active: boolean; active: boolean;
@ -190,7 +190,11 @@ export class SearchComponent implements OnInit {
queries: this.queries, queries: this.queries,
sorting: this.sortingOrder sorting: this.sortingOrder
} as any; } as any;
this.downloadFilesService.downloadJSON(settings); this.downloadFilesService.downloadJSON(settings, 'nise-settings');
}
getColumns(): string[] {
return this.fields.map(field => field.name);
} }
importSettings(event: any): void { importSettings(event: any): void {

View File

@ -6,31 +6,40 @@ import * as XLSX from "xlsx";
}) })
export class DownloadFilesService { export class DownloadFilesService {
downloadJSON(input: Object[]) { downloadJSON(input: Object[], fileName: string = 'data') {
const dataStr = JSON.stringify(input); const dataStr = JSON.stringify(input);
const blob = new Blob([dataStr], { type: 'application/json' }); const blob = new Blob([dataStr], { type: 'application/json' });
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
const link = document.createElement('a'); const link = document.createElement('a');
link.href = url; link.href = url;
link.download = 'data.json'; link.download = fileName + '.json';
link.click(); link.click();
} }
downloadCSV(input: Object[]) { downloadCSV(input: Object[], columns: string[], fileName: string = 'data') {
let csvData = input.map(row => Object.values(row).join(',')).join('\n'); const header = columns.join(',') + '\n';
let csvData = input.map(row =>
input.map(row => Object.values(row).join(',')).join('\n')
).join('\n');
csvData = header + csvData;
const blob = new Blob([csvData], { type: 'text/csv' }); const blob = new Blob([csvData], { type: 'text/csv' });
const url = window.URL.createObjectURL(blob); const url = window.URL.createObjectURL(blob);
const link = document.createElement('a'); const link = document.createElement('a');
link.href = url; link.href = url;
link.download = 'data.csv'; link.download = fileName + '.csv';
link.click(); link.click();
} }
downloadXLSX(input: Object[]) { downloadXLSX(input: Object[], fileName: string = 'data') {
const ws: XLSX.WorkSheet = XLSX.utils.json_to_sheet(input); const ws: XLSX.WorkSheet = XLSX.utils.json_to_sheet(input);
const wb: XLSX.WorkBook = XLSX.utils.book_new(); const wb: XLSX.WorkBook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, 'Data');
XLSX.writeFile(wb, 'data.xlsx'); XLSX.utils.book_append_sheet(wb, ws, 'Main Sheet');
XLSX.writeFile(wb, fileName + '.xlsx');
} }
} }