mirror of
https://github.com/stashapp/stash.git
synced 2025-12-06 16:34:02 +01:00
Feature: Filter by Total Scene Duration (#6172)
This commit is contained in:
parent
289b698598
commit
53655e51c4
7 changed files with 62 additions and 2 deletions
|
|
@ -726,6 +726,28 @@ func (qb *PerformerStore) sortByLastPlayedAt(direction string) string {
|
||||||
return " ORDER BY (" + selectPerformerLastPlayedAtSQL + ") " + direction
|
return " ORDER BY (" + selectPerformerLastPlayedAtSQL + ") " + direction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// used for sorting by total scene duration
|
||||||
|
var selectPerformerScenesDurationSQL = utils.StrFormat(
|
||||||
|
"SELECT COALESCE(SUM(video_files.duration), 0) FROM {performers_scenes} s "+
|
||||||
|
"LEFT JOIN {scenes} ON {scenes}.id = s.{scene_id} "+
|
||||||
|
"LEFT JOIN {scenes_files} ON {scenes_files}.{scene_id} = {scenes}.id "+
|
||||||
|
"LEFT JOIN video_files ON video_files.file_id = {scenes_files}.file_id "+
|
||||||
|
"WHERE s.{performer_id} = {performers}.id",
|
||||||
|
map[string]interface{}{
|
||||||
|
"performer_id": performerIDColumn,
|
||||||
|
"performers": performerTable,
|
||||||
|
"performers_scenes": performersScenesTable,
|
||||||
|
"scenes": sceneTable,
|
||||||
|
"scene_id": sceneIDColumn,
|
||||||
|
"scenes_files": scenesFilesTable,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
func (qb *PerformerStore) sortByScenesDuration(direction string) string {
|
||||||
|
// need to sum duration from all scenes for this performer
|
||||||
|
return " ORDER BY (" + selectPerformerScenesDurationSQL + ") " + direction
|
||||||
|
}
|
||||||
|
|
||||||
var performerSortOptions = sortOptions{
|
var performerSortOptions = sortOptions{
|
||||||
"birthdate",
|
"birthdate",
|
||||||
"career_length",
|
"career_length",
|
||||||
|
|
@ -744,6 +766,7 @@ var performerSortOptions = sortOptions{
|
||||||
"random",
|
"random",
|
||||||
"rating",
|
"rating",
|
||||||
"scenes_count",
|
"scenes_count",
|
||||||
|
"scenes_duration",
|
||||||
"tag_count",
|
"tag_count",
|
||||||
"updated_at",
|
"updated_at",
|
||||||
"weight",
|
"weight",
|
||||||
|
|
@ -771,6 +794,8 @@ func (qb *PerformerStore) getPerformerSort(findFilter *models.FindFilterType) (s
|
||||||
sortQuery += getCountSort(performerTable, performersTagsTable, performerIDColumn, direction)
|
sortQuery += getCountSort(performerTable, performersTagsTable, performerIDColumn, direction)
|
||||||
case "scenes_count":
|
case "scenes_count":
|
||||||
sortQuery += getCountSort(performerTable, performersScenesTable, performerIDColumn, direction)
|
sortQuery += getCountSort(performerTable, performersScenesTable, performerIDColumn, direction)
|
||||||
|
case "scenes_duration":
|
||||||
|
sortQuery += qb.sortByScenesDuration(direction)
|
||||||
case "images_count":
|
case "images_count":
|
||||||
sortQuery += getCountSort(performerTable, performersImagesTable, performerIDColumn, direction)
|
sortQuery += getCountSort(performerTable, performersImagesTable, performerIDColumn, direction)
|
||||||
case "galleries_count":
|
case "galleries_count":
|
||||||
|
|
|
||||||
|
|
@ -576,6 +576,16 @@ func (qb *StudioStore) QueryCount(ctx context.Context, studioFilter *models.Stud
|
||||||
return query.executeCount(ctx)
|
return query.executeCount(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (qb *StudioStore) sortByScenesDuration(direction string) string {
|
||||||
|
return fmt.Sprintf(` ORDER BY (
|
||||||
|
SELECT COALESCE(SUM(video_files.duration), 0)
|
||||||
|
FROM %s
|
||||||
|
LEFT JOIN %s ON %s.%s = %s.id
|
||||||
|
LEFT JOIN video_files ON video_files.file_id = %s.file_id
|
||||||
|
WHERE %s.%s = %s.id
|
||||||
|
) %s`, sceneTable, scenesFilesTable, scenesFilesTable, sceneIDColumn, sceneTable, scenesFilesTable, sceneTable, studioIDColumn, studioTable, getSortDirection(direction))
|
||||||
|
}
|
||||||
|
|
||||||
var studioSortOptions = sortOptions{
|
var studioSortOptions = sortOptions{
|
||||||
"child_count",
|
"child_count",
|
||||||
"created_at",
|
"created_at",
|
||||||
|
|
@ -584,6 +594,7 @@ var studioSortOptions = sortOptions{
|
||||||
"images_count",
|
"images_count",
|
||||||
"name",
|
"name",
|
||||||
"scenes_count",
|
"scenes_count",
|
||||||
|
"scenes_duration",
|
||||||
"random",
|
"random",
|
||||||
"rating",
|
"rating",
|
||||||
"tag_count",
|
"tag_count",
|
||||||
|
|
@ -612,6 +623,8 @@ func (qb *StudioStore) getStudioSort(findFilter *models.FindFilterType) (string,
|
||||||
sortQuery += getCountSort(studioTable, studiosTagsTable, studioIDColumn, direction)
|
sortQuery += getCountSort(studioTable, studiosTagsTable, studioIDColumn, direction)
|
||||||
case "scenes_count":
|
case "scenes_count":
|
||||||
sortQuery += getCountSort(studioTable, sceneTable, studioIDColumn, direction)
|
sortQuery += getCountSort(studioTable, sceneTable, studioIDColumn, direction)
|
||||||
|
case "scenes_duration":
|
||||||
|
sortQuery += qb.sortByScenesDuration(direction)
|
||||||
case "images_count":
|
case "images_count":
|
||||||
sortQuery += getCountSort(studioTable, imageTable, studioIDColumn, direction)
|
sortQuery += getCountSort(studioTable, imageTable, studioIDColumn, direction)
|
||||||
case "galleries_count":
|
case "galleries_count":
|
||||||
|
|
|
||||||
|
|
@ -651,9 +651,21 @@ var tagSortOptions = sortOptions{
|
||||||
"random",
|
"random",
|
||||||
"scene_markers_count",
|
"scene_markers_count",
|
||||||
"scenes_count",
|
"scenes_count",
|
||||||
|
"scenes_duration",
|
||||||
"updated_at",
|
"updated_at",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (qb *TagStore) sortByScenesDuration(direction string) string {
|
||||||
|
return fmt.Sprintf(` ORDER BY (
|
||||||
|
SELECT COALESCE(SUM(video_files.duration), 0)
|
||||||
|
FROM %s
|
||||||
|
LEFT JOIN %s ON %s.id = %s.%s
|
||||||
|
LEFT JOIN %s ON %s.%s = %s.id
|
||||||
|
LEFT JOIN video_files ON video_files.file_id = %s.file_id
|
||||||
|
WHERE %s.%s = %s.id
|
||||||
|
) %s`, scenesTagsTable, sceneTable, sceneTable, scenesTagsTable, sceneIDColumn, scenesFilesTable, scenesFilesTable, sceneIDColumn, sceneTable, scenesFilesTable, scenesTagsTable, tagIDColumn, tagTable, getSortDirection(direction))
|
||||||
|
}
|
||||||
|
|
||||||
func (qb *TagStore) getDefaultTagSort() string {
|
func (qb *TagStore) getDefaultTagSort() string {
|
||||||
return getSort("name", "ASC", "tags")
|
return getSort("name", "ASC", "tags")
|
||||||
}
|
}
|
||||||
|
|
@ -680,6 +692,8 @@ func (qb *TagStore) getTagSort(query *queryBuilder, findFilter *models.FindFilte
|
||||||
sortQuery += fmt.Sprintf(" ORDER BY COALESCE(tags.sort_name, tags.name) COLLATE NATURAL_CI %s", getSortDirection(direction))
|
sortQuery += fmt.Sprintf(" ORDER BY COALESCE(tags.sort_name, tags.name) COLLATE NATURAL_CI %s", getSortDirection(direction))
|
||||||
case "scenes_count":
|
case "scenes_count":
|
||||||
sortQuery += getCountSort(tagTable, scenesTagsTable, tagIDColumn, direction)
|
sortQuery += getCountSort(tagTable, scenesTagsTable, tagIDColumn, direction)
|
||||||
|
case "scenes_duration":
|
||||||
|
sortQuery += qb.sortByScenesDuration(direction)
|
||||||
case "scene_markers_count":
|
case "scene_markers_count":
|
||||||
sortQuery += fmt.Sprintf(" ORDER BY (SELECT COUNT(*) FROM scene_markers_tags WHERE tags.id = scene_markers_tags.tag_id)+(SELECT COUNT(*) FROM scene_markers WHERE tags.id = scene_markers.primary_tag_id) %s", getSortDirection(direction))
|
sortQuery += fmt.Sprintf(" ORDER BY (SELECT COUNT(*) FROM scene_markers_tags WHERE tags.id = scene_markers_tags.tag_id)+(SELECT COUNT(*) FROM scene_markers WHERE tags.id = scene_markers.primary_tag_id) %s", getSortDirection(direction))
|
||||||
case "images_count":
|
case "images_count":
|
||||||
|
|
|
||||||
|
|
@ -1308,6 +1308,7 @@
|
||||||
"sceneTagger": "Scene Tagger",
|
"sceneTagger": "Scene Tagger",
|
||||||
"scene_code": "Studio Code",
|
"scene_code": "Studio Code",
|
||||||
"scene_count": "Scene Count",
|
"scene_count": "Scene Count",
|
||||||
|
"scenes_duration": "Scene Duration",
|
||||||
"scene_created_at": "Scene Created At",
|
"scene_created_at": "Scene Created At",
|
||||||
"scene_date": "Date of Scene",
|
"scene_date": "Date of Scene",
|
||||||
"scene_id": "Scene ID",
|
"scene_id": "Scene ID",
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ const sortByOptions = [
|
||||||
"career_length",
|
"career_length",
|
||||||
"weight",
|
"weight",
|
||||||
"measurements",
|
"measurements",
|
||||||
|
"scenes_duration",
|
||||||
]
|
]
|
||||||
.map(ListFilterOptions.createSortBy)
|
.map(ListFilterOptions.createSortBy)
|
||||||
.concat([
|
.concat([
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,13 @@ import { ListFilterOptions } from "./filter-options";
|
||||||
import { DisplayMode } from "./types";
|
import { DisplayMode } from "./types";
|
||||||
|
|
||||||
const defaultSortBy = "name";
|
const defaultSortBy = "name";
|
||||||
const sortByOptions = ["name", "tag_count", "random", "rating"]
|
const sortByOptions = [
|
||||||
|
"name",
|
||||||
|
"tag_count",
|
||||||
|
"random",
|
||||||
|
"rating",
|
||||||
|
"scenes_duration",
|
||||||
|
]
|
||||||
.map(ListFilterOptions.createSortBy)
|
.map(ListFilterOptions.createSortBy)
|
||||||
.concat([
|
.concat([
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import {
|
||||||
import { FavoriteTagCriterionOption } from "./criteria/favorite";
|
import { FavoriteTagCriterionOption } from "./criteria/favorite";
|
||||||
|
|
||||||
const defaultSortBy = "name";
|
const defaultSortBy = "name";
|
||||||
const sortByOptions = ["name", "random"]
|
const sortByOptions = ["name", "random", "scenes_duration"]
|
||||||
.map(ListFilterOptions.createSortBy)
|
.map(ListFilterOptions.createSortBy)
|
||||||
.concat([
|
.concat([
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue