Skip to content

Commit

Permalink
added support for image orientation filter
Browse files Browse the repository at this point in the history
  • Loading branch information
keenbed committed Dec 30, 2023
1 parent bd7d4ac commit 35ea86c
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 0 deletions.
15 changes: 15 additions & 0 deletions graphql/schema/types/filters.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@ input ResolutionCriterionInput {
modifier: CriterionModifier!
}

enum OrientationEnum {
"Landscape"
LANDSCAPE
"Portrait"
PORTRAIT
"Square"
SQUARE
}

input OrientationCriterionInput {
value: OrientationEnum!
}

input PHashDuplicationCriterionInput {
duplicated: Boolean
"Currently unimplemented"
Expand Down Expand Up @@ -465,6 +478,8 @@ input ImageFilterType {
o_counter: IntCriterionInput
"Filter by resolution"
resolution: ResolutionCriterionInput
"Filter by orientation"
orientation: OrientationEnum
"Filter to only include images missing this property"
is_missing: String
"Filter to only include images with this studio"
Expand Down
2 changes: 2 additions & 0 deletions pkg/models/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ type ImageFilterType struct {
OCounter *IntCriterionInput `json:"o_counter"`
// Filter by resolution
Resolution *ResolutionCriterionInput `json:"resolution"`
// Filter by landscape/portrait
Orientation *OrientationEnum `json:"orientation"`
// Filter to only include images missing this property
IsMissing *string `json:"is_missing"`
// Filter to only include images with this studio
Expand Down
17 changes: 17 additions & 0 deletions pkg/models/orientation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package models

type OrientationEnum string

const (
OrientationLandscape OrientationEnum = "Landscape"
OrientationPortrait OrientationEnum = "Portrait"
OrientationSquare OrientationEnum = "Square"
)

func (e OrientationEnum) IsValid() bool {
switch e {
case OrientationLandscape, OrientationPortrait, OrientationSquare:
return true
}
return false
}
19 changes: 19 additions & 0 deletions pkg/sqlite/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,24 @@ func (qb *ImageStore) All(ctx context.Context) ([]*models.Image, error) {
return qb.getMany(ctx, qb.selectDataset())
}

func orientationCriterionHandler(orientation *models.OrientationEnum, heightColumn string, widthColumn string, addJoinFn func(f *filterBuilder)) criterionHandlerFunc {
return func(ctx context.Context, f *filterBuilder) {
if orientation != nil && orientation.IsValid() {
if addJoinFn != nil {
addJoinFn(f)
}
switch *orientation {
case models.OrientationPortrait:
f.addWhere(fmt.Sprintf("ROUND(%s*1.0/%s, 3) < 1.0", widthColumn, heightColumn))
case models.OrientationLandscape:
f.addWhere(fmt.Sprintf("ROUND(%s*1.0/%s, 3) > 1.0", widthColumn, heightColumn))
case models.OrientationSquare:
f.addWhere(fmt.Sprintf("ROUND(%s*1.0/%s, 3) = 1.0", widthColumn, heightColumn))
}
}
}
}

func (qb *ImageStore) validateFilter(imageFilter *models.ImageFilterType) error {
const and = "AND"
const or = "OR"
Expand Down Expand Up @@ -709,6 +727,7 @@ func (qb *ImageStore) makeFilter(ctx context.Context, imageFilter *models.ImageF
query.handleCriterion(ctx, imageURLsCriterionHandler(imageFilter.URL))

query.handleCriterion(ctx, resolutionCriterionHandler(imageFilter.Resolution, "image_files.height", "image_files.width", qb.addImageFilesTable))
query.handleCriterion(ctx, orientationCriterionHandler(imageFilter.Orientation, "image_files.height", "image_files.width", qb.addImageFilesTable))
query.handleCriterion(ctx, imageIsMissingCriterionHandler(qb, imageFilter.IsMissing))

query.handleCriterion(ctx, imageTagsCriterionHandler(qb, imageFilter.Tags))
Expand Down
1 change: 1 addition & 0 deletions ui/v2.5/src/locales/en-GB.json
Original file line number Diff line number Diff line change
Expand Up @@ -1076,6 +1076,7 @@
"none": "None",
"o_counter": "O-Counter",
"operations": "Operations",
"orientation": "Orientation",
"organized": "Organised",
"package_manager": {
"add_source": "Add Source",
Expand Down
27 changes: 27 additions & 0 deletions ui/v2.5/src/models/list-filter/criteria/orientation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { orientationStrings } from "src/utils/orientation";
import { CriterionType } from "../types";
import { CriterionOption, StringCriterion } from "./criterion";
import { CriterionModifier } from "../../../core/generated-graphql";

export class OrientationCriterion extends StringCriterion {
protected toCriterionInput(): string {
return this.value;
}
}

class BaseOrientationCriterionOption extends CriterionOption {
constructor(value: CriterionType) {
super({
messageID: value,
type: value,
modifierOptions: [],
options: orientationStrings,
defaultModifier: CriterionModifier.Equals,
makeCriterion: () => new OrientationCriterion(this),
});
}
}

export const OrientationCriterionOption = new BaseOrientationCriterionOption(
"orientation"
);
2 changes: 2 additions & 0 deletions ui/v2.5/src/models/list-filter/images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { PathCriterionOption } from "./criteria/path";
import { PerformersCriterionOption } from "./criteria/performers";
import { RatingCriterionOption } from "./criteria/rating";
import { ResolutionCriterionOption } from "./criteria/resolution";
import { OrientationCriterionOption } from "./criteria/orientation";
import { StudiosCriterionOption } from "./criteria/studios";
import {
PerformerTagsCriterionOption,
Expand Down Expand Up @@ -41,6 +42,7 @@ const criterionOptions = [
OrganizedCriterionOption,
createMandatoryNumberCriterionOption("o_counter"),
ResolutionCriterionOption,
OrientationCriterionOption,
ImageIsMissingCriterionOption,
TagsCriterionOption,
RatingCriterionOption,
Expand Down
1 change: 1 addition & 0 deletions ui/v2.5/src/models/list-filter/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ export type CriterionType =
| "details"
| "title"
| "oshash"
| "orientation"
| "checksum"
| "phash_distance"
| "director"
Expand Down
32 changes: 32 additions & 0 deletions ui/v2.5/src/utils/orientation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { OrientationEnum } from "src/core/generated-graphql";

const stringOrientationMap = new Map<string, OrientationEnum>([
["Landscape", OrientationEnum.Landscape],
["Portrait", OrientationEnum.Portrait],
["Square", OrientationEnum.Square],
]);

export const stringToOrientation = (
value?: string | null,
caseInsensitive?: boolean
) => {
if (!value) {
return undefined;
}

const ret = stringOrientationMap.get(value);
if (ret || !caseInsensitive) {
return ret;
}

const asUpper = value.toUpperCase();
const foundEntry = Array.from(stringOrientationMap.entries()).find((e) => {
return e[0].toUpperCase() === asUpper;
});

if (foundEntry) {
return foundEntry[1];
}
};

export const orientationStrings = Array.from(stringOrientationMap.keys());

0 comments on commit 35ea86c

Please sign in to comment.