mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 20:34:37 +03:00
Accept random seed from UI for random sorting (#328)
This commit is contained in:
@@ -93,6 +93,8 @@ func getSort(sort string, direction string, tableName string) string {
|
||||
direction = "ASC"
|
||||
}
|
||||
|
||||
const randomSeedPrefix = "random_"
|
||||
|
||||
if strings.Contains(sort, "_count") {
|
||||
var relationTableName = strings.Split(sort, "_")[0] // TODO: pluralize?
|
||||
colName := getColumn(relationTableName, "id")
|
||||
@@ -100,12 +102,18 @@ func getSort(sort string, direction string, tableName string) string {
|
||||
} else if strings.Compare(sort, "filesize") == 0 {
|
||||
colName := getColumn(tableName, "size")
|
||||
return " ORDER BY cast(" + colName + " as integer) " + direction
|
||||
} else if strings.HasPrefix(sort, randomSeedPrefix) {
|
||||
// seed as a parameter from the UI
|
||||
// turn the provided seed into a float
|
||||
seedStr := "0." + sort[len(randomSeedPrefix):]
|
||||
seed, err := strconv.ParseFloat(seedStr, 32)
|
||||
if err != nil {
|
||||
// fallback to default seed
|
||||
seed = randomSortFloat
|
||||
}
|
||||
return getRandomSort(tableName, direction, seed)
|
||||
} else if strings.Compare(sort, "random") == 0 {
|
||||
// https://stackoverflow.com/a/24511461
|
||||
// TODO seed as a parameter from the UI
|
||||
colName := getColumn(tableName, "id")
|
||||
randomSortString := strconv.FormatFloat(randomSortFloat, 'f', 16, 32)
|
||||
return " ORDER BY " + "(substr(" + colName + " * " + randomSortString + ", length(" + colName + ") + 2))" + " " + direction
|
||||
return getRandomSort(tableName, direction, randomSortFloat)
|
||||
} else {
|
||||
colName := getColumn(tableName, sort)
|
||||
var additional string
|
||||
@@ -122,6 +130,13 @@ func getSort(sort string, direction string, tableName string) string {
|
||||
}
|
||||
}
|
||||
|
||||
func getRandomSort(tableName string, direction string, seed float64) string {
|
||||
// https://stackoverflow.com/a/24511461
|
||||
colName := getColumn(tableName, "id")
|
||||
randomSortString := strconv.FormatFloat(seed, 'f', 16, 32)
|
||||
return " ORDER BY " + "(substr(" + colName + " * " + randomSortString + ", length(" + colName + ") + 2))" + " " + direction
|
||||
}
|
||||
|
||||
func getSearch(columns []string, q string) string {
|
||||
// TODO - susceptible to SQL injection
|
||||
var likeClauses []string
|
||||
|
||||
@@ -46,6 +46,7 @@ export class ListFilterModel {
|
||||
public criterionOptions: ICriterionOption[] = [];
|
||||
public criteria: Array<Criterion<any, any>> = [];
|
||||
public totalCount: number = 0;
|
||||
public randomSeed: number = -1;
|
||||
|
||||
private static createCriterionOption(criterion: CriterionType) {
|
||||
return new CriterionOption(Criterion.getLabel(criterion), criterion);
|
||||
@@ -153,6 +154,19 @@ export class ListFilterModel {
|
||||
const params = rawParms as IQueryParameters;
|
||||
if (params.sortby !== undefined) {
|
||||
this.sortBy = params.sortby;
|
||||
|
||||
// parse the random seed if provided
|
||||
const randomPrefix = "random_";
|
||||
if (this.sortBy && this.sortBy.startsWith(randomPrefix)) {
|
||||
let seedStr = this.sortBy.substring(randomPrefix.length);
|
||||
|
||||
this.sortBy = "random";
|
||||
try {
|
||||
this.randomSeed = Number.parseInt(seedStr);
|
||||
} catch (err) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
if (params.sortdir === "asc" || params.sortdir === "desc") {
|
||||
this.sortDirection = params.sortdir;
|
||||
@@ -187,6 +201,28 @@ export class ListFilterModel {
|
||||
}
|
||||
}
|
||||
|
||||
private setRandomSeed() {
|
||||
if (this.sortBy == "random") {
|
||||
// #321 - set the random seed if it is not set
|
||||
if (this.randomSeed == -1) {
|
||||
// generate 8-digit seed
|
||||
this.randomSeed = Math.floor(Math.random() * Math.pow(10, 8));
|
||||
}
|
||||
} else {
|
||||
this.randomSeed = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private getSortBy(): string | undefined {
|
||||
this.setRandomSeed();
|
||||
|
||||
if (this.sortBy == "random") {
|
||||
return this.sortBy + "_" + this.randomSeed.toString();
|
||||
}
|
||||
|
||||
return this.sortBy;
|
||||
}
|
||||
|
||||
public makeQueryParameters(): string {
|
||||
const encodedCriteria: string[] = [];
|
||||
this.criteria.forEach((criterion) => {
|
||||
@@ -198,8 +234,9 @@ export class ListFilterModel {
|
||||
encodedCriteria.push(jsonCriterion);
|
||||
});
|
||||
|
||||
|
||||
const result = {
|
||||
sortby: this.sortBy,
|
||||
sortby: this.getSortBy(),
|
||||
sortdir: this.sortDirection,
|
||||
disp: this.displayMode,
|
||||
q: this.searchTerm,
|
||||
@@ -216,7 +253,7 @@ export class ListFilterModel {
|
||||
q: this.searchTerm,
|
||||
page: this.currentPage,
|
||||
per_page: this.itemsPerPage,
|
||||
sort: this.sortBy,
|
||||
sort: this.getSortBy(),
|
||||
direction: this.sortDirection === "asc" ? SortDirectionEnum.Asc : SortDirectionEnum.Desc,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user