diff --git a/.gitattributes b/.gitattributes index 795235ffb..2eb84e779 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ go.mod text eol=lf go.sum text eol=lf ui/v2.5/**/*.ts* text eol=lf +ui/v2.5/**/*.scss text eol=lf diff --git a/pkg/manager/filename_parser.go b/pkg/manager/filename_parser.go index 673f4bb31..63efb300a 100644 --- a/pkg/manager/filename_parser.go +++ b/pkg/manager/filename_parser.go @@ -87,6 +87,7 @@ func initParserFields() { //I = new ParserField("i", undefined, "Matches any ignored word", false); ret["d"] = newParserField("d", `(?:\.|-|_)`, false) + ret["rating"] = newParserField("rating", `\d`, true) ret["performer"] = newParserField("performer", ".*", true) ret["studio"] = newParserField("studio", ".*", true) ret["movie"] = newParserField("movie", ".*", true) @@ -224,6 +225,10 @@ func newSceneHolder(scene *models.Scene) *sceneHolder { return &ret } +func validateRating(rating int) bool { + return rating >= 1 && rating <= 5 +} + func validateDate(dateStr string) bool { splits := strings.Split(dateStr, "-") if len(splits) != 3 { @@ -304,6 +309,14 @@ func (h *sceneHolder) setField(field parserField, value interface{}) { Valid: true, } } + case "rating": + rating, _ := strconv.Atoi(value.(string)) + if validateRating(rating) { + h.result.Rating = sql.NullInt64{ + Int64: int64(rating), + Valid: true, + } + } case "performer": // add performer to list h.performers = append(h.performers, value.(string)) @@ -661,6 +674,11 @@ func (p *SceneFilenameParser) setParserResult(h sceneHolder, result *models.Scen result.Date = &h.result.Date.String } + if h.result.Rating.Valid { + rating := int(h.result.Rating.Int64) + result.Rating = &rating + } + if len(h.performers) > 0 { p.setPerformers(h, result) } diff --git a/ui/v2.5/src/components/SceneFilenameParser/ParserField.ts b/ui/v2.5/src/components/SceneFilenameParser/ParserField.ts index dc84f9bee..6fd2d2982 100644 --- a/ui/v2.5/src/components/SceneFilenameParser/ParserField.ts +++ b/ui/v2.5/src/components/SceneFilenameParser/ParserField.ts @@ -13,6 +13,7 @@ export class ParserField { static Title = new ParserField("title"); static Ext = new ParserField("ext", "File extension"); + static Rating = new ParserField("rating"); static I = new ParserField("i", "Matches any ignored word"); static D = new ParserField("d", "Matches any delimiter (.-_)"); @@ -39,6 +40,7 @@ export class ParserField { ParserField.Ext, ParserField.D, ParserField.I, + ParserField.Rating, ParserField.Performer, ParserField.Studio, ParserField.Tag, diff --git a/ui/v2.5/src/components/SceneFilenameParser/ParserInput.tsx b/ui/v2.5/src/components/SceneFilenameParser/ParserInput.tsx index c8f5c9ca8..1c4d078d3 100644 --- a/ui/v2.5/src/components/SceneFilenameParser/ParserInput.tsx +++ b/ui/v2.5/src/components/SceneFilenameParser/ParserInput.tsx @@ -131,6 +131,7 @@ export const ParserInput: React.FC = ( ) => setPattern(e.currentTarget.value) @@ -144,8 +145,8 @@ export const ParserInput: React.FC = ( key={item.field} onSelect={() => addParserField(item)} > - {item.field} - {item.helperText} + {item.field || "{}"} + {item.helperText} ))} @@ -160,6 +161,7 @@ export const ParserInput: React.FC = ( Ignored words ) => setIgnoreWords(e.currentTarget.value) } @@ -178,6 +180,7 @@ export const ParserInput: React.FC = ( ) => setWhitespaceCharacters(e.currentTarget.value) } @@ -206,6 +209,7 @@ export const ParserInput: React.FC = ( variant="secondary" id="recipe-select" title="Select Parser Recipe" + drop="up" > {builtInRecipes.map((item) => ( = ( onSelect={() => setParserRecipe(item)} > {item.pattern} - {item.description} + {item.description} ))} @@ -237,7 +241,7 @@ export const ParserInput: React.FC = ( props.onPageSizeChanged(parseInt(e.currentTarget.value, 10)) } defaultValue={props.input.pageSize} - className="col-1 filter-item" + className="col-1 input-control filter-item" > {PAGE_SIZE_OPTIONS.map((val) => (