From 89859369f9cb8b2656d713c4dbbf8babdaf7ddd8 Mon Sep 17 00:00:00 2001 From: InfiniteStash <117855276+InfiniteStash@users.noreply.github.com> Date: Sun, 25 Feb 2024 22:56:44 +0000 Subject: [PATCH] Add phash duration cutoff option --- README.md | 1 + pkg/manager/config/config.go | 8 +++++++- pkg/scene/scene.go | 8 ++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 94e51d3a7..a0aeb9c8a 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,7 @@ There are two ways to authenticate a user in Stash-box: a session or an API key. | `s3.max_dimension` | (none) | If set, a resized copy will be created for any image whose dimensions exceed this number. This copy will be served in place of the original. | | `s3.upload_headers` | (none) | A map of headers to send with each upload request. For example, DigitalOcean requires the `x-amz-acl` header to be set to `public-read` or it does not make the uploaded images available. | | `phash_distance` | 0 | Determines what binary distance is considered a match when querying with a pHash fingeprint. Using more than 8 is not recommended and may lead to large amounts of false positives. **Note**: The [pg-spgist_hamming extension](#phash-distance-matching) must be installed to use distance matching, otherwise you will get errors. | +| `phash_duration_cutoff` | 0 | Optionally sets a minimum duration for pHash fingerprint submission, in seconds. Fingerprints below this cutoff will be quietly dropped. Set to 0 to disable cutoff. | | `favicon_path` | (none) | Location where favicons for linked sites should be stored. Leave empty to disable. | | `draft_time_limit` | (24h) | Time, in seconds, before a draft is deleted. | | `profiler_port` | 0 | Port on which to serve pprof output. Omit to disable entirely. | diff --git a/pkg/manager/config/config.go b/pkg/manager/config/config.go index 29bceb0b9..957a1bbc8 100644 --- a/pkg/manager/config/config.go +++ b/pkg/manager/config/config.go @@ -85,7 +85,8 @@ type config struct { PostgresConfig `mapstructure:",squash"` } - PHashDistance int `mapstructure:"phash_distance"` + PHashDistance int `mapstructure:"phash_distance"` + PHashDurationCutoff int `mapstructure:"phash_duration_cutoff"` Title string `mapstructure:"title"` @@ -112,6 +113,7 @@ var C = &config{ EmailPort: 25, ImageBackend: string(FileBackend), PHashDistance: 0, + PHashDurationCutoff: 0, VoteApplicationThreshold: 3, VotePromotionThreshold: 10, VoteCronInterval: "5m", @@ -280,6 +282,10 @@ func GetPHashDistance() int { return C.PHashDistance } +func GetPhashDurationCutoff() int { + return C.PHashDurationCutoff +} + func InitializeDefaults() error { // generate some api keys const apiKeyLength = 32 diff --git a/pkg/scene/scene.go b/pkg/scene/scene.go index 040dabe36..6a1ec9b21 100644 --- a/pkg/scene/scene.go +++ b/pkg/scene/scene.go @@ -7,6 +7,7 @@ import ( "github.com/gofrs/uuid" "github.com/pkg/errors" "github.com/stashapp/stash-box/pkg/image" + "github.com/stashapp/stash-box/pkg/manager/config" "github.com/stashapp/stash-box/pkg/models" "github.com/stashapp/stash-box/pkg/user" ) @@ -235,6 +236,13 @@ func Destroy(fac models.Repo, input models.SceneDestroyInput) (bool, error) { func SubmitFingerprint(ctx context.Context, fac models.Repo, input models.FingerprintSubmission) (bool, error) { qb := fac.Scene() + // Optionally filter out phashes below a certain duration. + // Phashes are inaccurate for short videos which can make them undesirable. + cutoff := config.GetPhashDurationCutoff() + if cutoff > 0 && input.Fingerprint.Algorithm == models.FingerprintAlgorithmPhash && cutoff >= input.Fingerprint.Duration { + return true, nil + } + // Find the scene scene, err := qb.Find(input.SceneID)