More configuration options

* Allow configuration of generated file path and database path.  Closes #33
* Added checkboxes to choose what gets generated for the generate task.  Closes #32
This commit is contained in:
Stash Dev
2019-03-24 10:04:31 -07:00
parent 06d88cbeb4
commit c1f1a6ccff
16 changed files with 418 additions and 74 deletions

File diff suppressed because one or more lines are too long

View File

@@ -6,13 +6,10 @@ import (
"github.com/stashapp/stash/pkg/manager/config"
"github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/utils"
"path/filepath"
)
func (r *mutationResolver) ConfigureGeneral(ctx context.Context, input *models.ConfigGeneralInput) (models.ConfigGeneralResult, error) {
if input == nil {
return makeConfigGeneralResult(), fmt.Errorf("nil input")
}
func (r *mutationResolver) ConfigureGeneral(ctx context.Context, input models.ConfigGeneralInput) (models.ConfigGeneralResult, error) {
if len(input.Stashes) > 0 {
for _, stashPath := range input.Stashes {
exists, err := utils.DirExists(stashPath)
@@ -23,6 +20,21 @@ func (r *mutationResolver) ConfigureGeneral(ctx context.Context, input *models.C
config.Set(config.Stash, input.Stashes)
}
if input.DatabasePath != nil {
ext := filepath.Ext(*input.DatabasePath)
if ext != ".db" && ext != ".sqlite" && ext != ".sqlite3" {
return makeConfigGeneralResult(), fmt.Errorf("invalid database path, use extension db, sqlite, or sqlite3")
}
config.Set(config.Database, input.DatabasePath)
}
if input.GeneratedPath != nil {
if err := utils.EnsureDir(*input.GeneratedPath); err != nil {
return makeConfigGeneralResult(), err
}
config.Set(config.Generated, input.GeneratedPath)
}
if err := config.Write(); err != nil {
return makeConfigGeneralResult(), err
}

View File

@@ -27,6 +27,8 @@ func makeConfigResult() models.ConfigResult {
func makeConfigGeneralResult() models.ConfigGeneralResult {
return models.ConfigGeneralResult{
Stashes: config.GetStashPaths(),
Stashes: config.GetStashPaths(),
DatabasePath: config.GetDatabasePath(),
GeneratedPath: config.GetGeneratedPath(),
}
}
}

View File

@@ -3,6 +3,7 @@ package api
import (
"context"
"github.com/stashapp/stash/pkg/manager"
"github.com/stashapp/stash/pkg/models"
)
func (r *queryResolver) MetadataScan(ctx context.Context) (string, error) {
@@ -20,8 +21,8 @@ func (r *queryResolver) MetadataExport(ctx context.Context) (string, error) {
return "todo", nil
}
func (r *queryResolver) MetadataGenerate(ctx context.Context) (string, error) {
manager.GetInstance().Generate(true, true, true, true)
func (r *queryResolver) MetadataGenerate(ctx context.Context, input models.GenerateMetadataInput) (string, error) {
manager.GetInstance().Generate(input.Sprites, input.Previews, input.Markers, input.Transcodes)
return "todo", nil
}

View File

@@ -48,7 +48,9 @@ type DirectiveRoot struct {
type ComplexityRoot struct {
ConfigGeneralResult struct {
Stashes func(childComplexity int) int
Stashes func(childComplexity int) int
DatabasePath func(childComplexity int) int
GeneratedPath func(childComplexity int) int
}
ConfigResult struct {
@@ -112,7 +114,7 @@ type ComplexityRoot struct {
TagCreate func(childComplexity int, input TagCreateInput) int
TagUpdate func(childComplexity int, input TagUpdateInput) int
TagDestroy func(childComplexity int, input TagDestroyInput) int
ConfigureGeneral func(childComplexity int, input *ConfigGeneralInput) int
ConfigureGeneral func(childComplexity int, input ConfigGeneralInput) int
}
Performer struct {
@@ -163,7 +165,7 @@ type ComplexityRoot struct {
MetadataImport func(childComplexity int) int
MetadataExport func(childComplexity int) int
MetadataScan func(childComplexity int) int
MetadataGenerate func(childComplexity int) int
MetadataGenerate func(childComplexity int, input GenerateMetadataInput) int
MetadataClean func(childComplexity int) int
AllPerformers func(childComplexity int) int
AllStudios func(childComplexity int) int
@@ -290,7 +292,7 @@ type MutationResolver interface {
TagCreate(ctx context.Context, input TagCreateInput) (*Tag, error)
TagUpdate(ctx context.Context, input TagUpdateInput) (*Tag, error)
TagDestroy(ctx context.Context, input TagDestroyInput) (bool, error)
ConfigureGeneral(ctx context.Context, input *ConfigGeneralInput) (ConfigGeneralResult, error)
ConfigureGeneral(ctx context.Context, input ConfigGeneralInput) (ConfigGeneralResult, error)
}
type PerformerResolver interface {
ID(ctx context.Context, obj *Performer) (string, error)
@@ -339,7 +341,7 @@ type QueryResolver interface {
MetadataImport(ctx context.Context) (string, error)
MetadataExport(ctx context.Context) (string, error)
MetadataScan(ctx context.Context) (string, error)
MetadataGenerate(ctx context.Context) (string, error)
MetadataGenerate(ctx context.Context, input GenerateMetadataInput) (string, error)
MetadataClean(ctx context.Context) (string, error)
AllPerformers(ctx context.Context) ([]Performer, error)
AllStudios(ctx context.Context) ([]Studio, error)
@@ -617,26 +619,19 @@ func (e *executableSchema) field_Mutation_tagDestroy_args(ctx context.Context, r
func (e *executableSchema) field_Mutation_configureGeneral_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
args := map[string]interface{}{}
var arg0 *ConfigGeneralInput
var arg0 ConfigGeneralInput
if tmp, ok := rawArgs["input"]; ok {
var err error
var ptr1 ConfigGeneralInput
if tmp != nil {
ptr1, err = UnmarshalConfigGeneralInput(tmp)
arg0 = &ptr1
}
arg0, err = UnmarshalConfigGeneralInput(tmp)
if err != nil {
return nil, err
}
if arg0 != nil {
var err error
arg0, err = e.ConfigGeneralInputMiddleware(ctx, arg0)
if err != nil {
return nil, err
}
mConfigGeneralInput1, err := e.ConfigGeneralInputMiddleware(ctx, &arg0)
if err != nil {
return nil, err
}
arg0 = *mConfigGeneralInput1
}
args["input"] = arg0
return args, nil
@@ -1122,6 +1117,27 @@ func (e *executableSchema) field_Query_directories_args(ctx context.Context, raw
}
func (e *executableSchema) field_Query_metadataGenerate_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
args := map[string]interface{}{}
var arg0 GenerateMetadataInput
if tmp, ok := rawArgs["input"]; ok {
var err error
arg0, err = UnmarshalGenerateMetadataInput(tmp)
if err != nil {
return nil, err
}
mGenerateMetadataInput1, err := e.GenerateMetadataInputMiddleware(ctx, &arg0)
if err != nil {
return nil, err
}
arg0 = *mGenerateMetadataInput1
}
args["input"] = arg0
return args, nil
}
func (e *executableSchema) field_Query___type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
args := map[string]interface{}{}
var arg0 string
@@ -1187,6 +1203,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.ConfigGeneralResult.Stashes(childComplexity), true
case "ConfigGeneralResult.databasePath":
if e.complexity.ConfigGeneralResult.DatabasePath == nil {
break
}
return e.complexity.ConfigGeneralResult.DatabasePath(childComplexity), true
case "ConfigGeneralResult.generatedPath":
if e.complexity.ConfigGeneralResult.GeneratedPath == nil {
break
}
return e.complexity.ConfigGeneralResult.GeneratedPath(childComplexity), true
case "ConfigResult.general":
if e.complexity.ConfigResult.General == nil {
break
@@ -1483,7 +1513,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return 0, false
}
return e.complexity.Mutation.ConfigureGeneral(childComplexity, args["input"].(*ConfigGeneralInput)), true
return e.complexity.Mutation.ConfigureGeneral(childComplexity, args["input"].(ConfigGeneralInput)), true
case "Performer.id":
if e.complexity.Performer.Id == nil {
@@ -1888,7 +1918,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
return e.complexity.Query.MetadataGenerate(childComplexity), true
args, err := e.field_Query_metadataGenerate_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Query.MetadataGenerate(childComplexity, args["input"].(GenerateMetadataInput)), true
case "Query.metadataClean":
if e.complexity.Query.MetadataClean == nil {
@@ -2504,6 +2539,19 @@ func (ec *executionContext) _ConfigGeneralResult(ctx context.Context, sel ast.Se
out.Values[i] = graphql.MarshalString("ConfigGeneralResult")
case "stashes":
out.Values[i] = ec._ConfigGeneralResult_stashes(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalid = true
}
case "databasePath":
out.Values[i] = ec._ConfigGeneralResult_databasePath(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalid = true
}
case "generatedPath":
out.Values[i] = ec._ConfigGeneralResult_generatedPath(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalid = true
}
default:
panic("unknown field " + strconv.Quote(field.Name))
}
@@ -2531,6 +2579,9 @@ func (ec *executionContext) _ConfigGeneralResult_stashes(ctx context.Context, fi
return obj.Stashes, nil
})
if resTmp == nil {
if !ec.HasError(rctx) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.([]string)
@@ -2548,6 +2599,60 @@ func (ec *executionContext) _ConfigGeneralResult_stashes(ctx context.Context, fi
return arr1
}
// nolint: vetshadow
func (ec *executionContext) _ConfigGeneralResult_databasePath(ctx context.Context, field graphql.CollectedField, obj *ConfigGeneralResult) graphql.Marshaler {
ctx = ec.Tracer.StartFieldExecution(ctx, field)
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
rctx := &graphql.ResolverContext{
Object: "ConfigGeneralResult",
Field: field,
Args: nil,
}
ctx = graphql.WithResolverContext(ctx, rctx)
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
resTmp := ec.FieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.DatabasePath, nil
})
if resTmp == nil {
if !ec.HasError(rctx) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
rctx.Result = res
ctx = ec.Tracer.StartFieldChildExecution(ctx)
return graphql.MarshalString(res)
}
// nolint: vetshadow
func (ec *executionContext) _ConfigGeneralResult_generatedPath(ctx context.Context, field graphql.CollectedField, obj *ConfigGeneralResult) graphql.Marshaler {
ctx = ec.Tracer.StartFieldExecution(ctx, field)
defer func() { ec.Tracer.EndFieldExecution(ctx) }()
rctx := &graphql.ResolverContext{
Object: "ConfigGeneralResult",
Field: field,
Args: nil,
}
ctx = graphql.WithResolverContext(ctx, rctx)
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
resTmp := ec.FieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.GeneratedPath, nil
})
if resTmp == nil {
if !ec.HasError(rctx) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
rctx.Result = res
ctx = ec.Tracer.StartFieldChildExecution(ctx)
return graphql.MarshalString(res)
}
var configResultImplementors = []string{"ConfigResult"}
// nolint: gocyclo, errcheck, gas, goconst
@@ -4136,7 +4241,7 @@ func (ec *executionContext) _Mutation_configureGeneral(ctx context.Context, fiel
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
resTmp := ec.FieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().ConfigureGeneral(rctx, args["input"].(*ConfigGeneralInput))
return ec.resolvers.Mutation().ConfigureGeneral(rctx, args["input"].(ConfigGeneralInput))
})
if resTmp == nil {
if !ec.HasError(rctx) {
@@ -6153,10 +6258,17 @@ func (ec *executionContext) _Query_metadataGenerate(ctx context.Context, field g
Args: nil,
}
ctx = graphql.WithResolverContext(ctx, rctx)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Query_metadataGenerate_args(ctx, rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
rctx.Args = args
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
resTmp := ec.FieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().MetadataGenerate(rctx)
return ec.resolvers.Query().MetadataGenerate(rctx, args["input"].(GenerateMetadataInput))
})
if resTmp == nil {
if !ec.HasError(rctx) {
@@ -10597,6 +10709,28 @@ func UnmarshalConfigGeneralInput(v interface{}) (ConfigGeneralInput, error) {
for idx1 := range rawIf1 {
it.Stashes[idx1], err = graphql.UnmarshalString(rawIf1[idx1])
}
if err != nil {
return it, err
}
case "databasePath":
var err error
var ptr1 string
if v != nil {
ptr1, err = graphql.UnmarshalString(v)
it.DatabasePath = &ptr1
}
if err != nil {
return it, err
}
case "generatedPath":
var err error
var ptr1 string
if v != nil {
ptr1, err = graphql.UnmarshalString(v)
it.GeneratedPath = &ptr1
}
if err != nil {
return it, err
}
@@ -10683,6 +10817,47 @@ func (e *executableSchema) FindFilterTypeMiddleware(ctx context.Context, obj *Fi
return obj, nil
}
func UnmarshalGenerateMetadataInput(v interface{}) (GenerateMetadataInput, error) {
var it GenerateMetadataInput
var asMap = v.(map[string]interface{})
for k, v := range asMap {
switch k {
case "sprites":
var err error
it.Sprites, err = graphql.UnmarshalBoolean(v)
if err != nil {
return it, err
}
case "previews":
var err error
it.Previews, err = graphql.UnmarshalBoolean(v)
if err != nil {
return it, err
}
case "markers":
var err error
it.Markers, err = graphql.UnmarshalBoolean(v)
if err != nil {
return it, err
}
case "transcodes":
var err error
it.Transcodes, err = graphql.UnmarshalBoolean(v)
if err != nil {
return it, err
}
}
}
return it, nil
}
func (e *executableSchema) GenerateMetadataInputMiddleware(ctx context.Context, obj *GenerateMetadataInput) (*GenerateMetadataInput, error) {
return obj, nil
}
func UnmarshalPerformerCreateInput(v interface{}) (PerformerCreateInput, error) {
var it PerformerCreateInput
var asMap = v.(map[string]interface{})
@@ -12148,11 +12323,19 @@ input SceneFilterType {
input ConfigGeneralInput {
"""Array of file paths to content"""
stashes: [String!]
"""Path to the SQLite database"""
databasePath: String
"""Path to generated files"""
generatedPath: String
}
type ConfigGeneralResult {
"""Array of file paths to content"""
stashes: [String!]
stashes: [String!]!
"""Path to the SQLite database"""
databasePath: String!
"""Path to generated files"""
generatedPath: String!
}
"""All configuration settings"""
@@ -12160,6 +12343,17 @@ type ConfigResult {
general: ConfigGeneralResult!
}
#######################################
# Metadata
#######################################
input GenerateMetadataInput {
sprites: Boolean!
previews: Boolean!
markers: Boolean!
transcodes: Boolean!
}
#############
# Root Schema
#############
@@ -12225,7 +12419,7 @@ type Query {
"""Start a scan. Returns the job ID"""
metadataScan: String!
"""Start generating content. Returns the job ID"""
metadataGenerate: String!
metadataGenerate(input: GenerateMetadataInput!): String!
"""Clean metadata. Returns the job ID"""
metadataClean: String!
@@ -12254,7 +12448,7 @@ type Mutation {
tagDestroy(input: TagDestroyInput!): Boolean!
"""Change general configuration options"""
configureGeneral(input: ConfigGeneralInput): ConfigGeneralResult!
configureGeneral(input: ConfigGeneralInput!): ConfigGeneralResult!
}
type Subscription {

View File

@@ -11,11 +11,19 @@ import (
type ConfigGeneralInput struct {
// Array of file paths to content
Stashes []string `json:"stashes"`
// Path to the SQLite database
DatabasePath *string `json:"databasePath"`
// Path to generated files
GeneratedPath *string `json:"generatedPath"`
}
type ConfigGeneralResult struct {
// Array of file paths to content
Stashes []string `json:"stashes"`
// Path to the SQLite database
DatabasePath string `json:"databasePath"`
// Path to generated files
GeneratedPath string `json:"generatedPath"`
}
// All configuration settings
@@ -62,6 +70,13 @@ type GalleryFilesType struct {
Path *string `json:"path"`
}
type GenerateMetadataInput struct {
Sprites bool `json:"sprites"`
Previews bool `json:"previews"`
Markers bool `json:"markers"`
Transcodes bool `json:"transcodes"`
}
type MarkerStringsResultType struct {
Count int `json:"count"`
ID string `json:"id"`

View File

@@ -1,5 +1,7 @@
fragment ConfigGeneralData on ConfigGeneralResult {
stashes
databasePath
generatedPath
}
fragment ConfigData on ConfigResult {

View File

@@ -10,8 +10,8 @@ query MetadataScan {
metadataScan
}
query MetadataGenerate {
metadataGenerate
query MetadataGenerate($input: GenerateMetadataInput!) {
metadataGenerate(input: $input)
}
query MetadataClean {

View File

@@ -379,11 +379,19 @@ input SceneFilterType {
input ConfigGeneralInput {
"""Array of file paths to content"""
stashes: [String!]
"""Path to the SQLite database"""
databasePath: String
"""Path to generated files"""
generatedPath: String
}
type ConfigGeneralResult {
"""Array of file paths to content"""
stashes: [String!]
stashes: [String!]!
"""Path to the SQLite database"""
databasePath: String!
"""Path to generated files"""
generatedPath: String!
}
"""All configuration settings"""
@@ -391,6 +399,17 @@ type ConfigResult {
general: ConfigGeneralResult!
}
#######################################
# Metadata
#######################################
input GenerateMetadataInput {
sprites: Boolean!
previews: Boolean!
markers: Boolean!
transcodes: Boolean!
}
#############
# Root Schema
#############
@@ -456,7 +475,7 @@ type Query {
"""Start a scan. Returns the job ID"""
metadataScan: String!
"""Start generating content. Returns the job ID"""
metadataGenerate: String!
metadataGenerate(input: GenerateMetadataInput!): String!
"""Clean metadata. Returns the job ID"""
metadataClean: String!
@@ -485,7 +504,7 @@ type Mutation {
tagDestroy(input: TagDestroyInput!): Boolean!
"""Change general configuration options"""
configureGeneral(input: ConfigGeneralInput): ConfigGeneralResult!
configureGeneral(input: ConfigGeneralInput!): ConfigGeneralResult!
}
type Subscription {

View File

@@ -9,7 +9,7 @@ import { IBaseProps } from "../../models";
import { SettingsAboutPanel } from "./SettingsAboutPanel";
import { SettingsConfigurationPanel } from "./SettingsConfigurationPanel";
import { SettingsLogsPanel } from "./SettingsLogsPanel";
import { SettingsTasksPanel } from "./SettingsTasksPanel";
import { SettingsTasksPanel } from "./SettingsTasksPanel/SettingsTasksPanel";
interface IProps extends IBaseProps {}

View File

@@ -7,6 +7,7 @@ import {
H6,
Spinner,
Tag,
InputGroup,
} from "@blueprintjs/core";
import React, { FunctionComponent, useEffect, useState } from "react";
import * as GQL from "../../core/generated-graphql";
@@ -21,12 +22,15 @@ interface IProps {}
export const SettingsConfigurationPanel: FunctionComponent<IProps> = (props: IProps) => {
// Editing config state
const [stashes, setStashes] = useState<string[]>([]);
const [databasePath, setDatabasePath] = useState<string | undefined>(undefined);
const [generatedPath, setGeneratedPath] = useState<string | undefined>(undefined);
// const [config, setConfig] = useState<Partial<GQL.ConfigDataFragment>>({});
const { data, error, loading } = StashService.useConfiguration();
const updateGeneralConfig = StashService.useConfigureGeneral({
stashes,
databasePath,
generatedPath,
});
useEffect(() => {
@@ -34,8 +38,9 @@ export const SettingsConfigurationPanel: FunctionComponent<IProps> = (props: IPr
const conf = StashService.nullToUndefined(data.configuration) as GQL.ConfigDataFragment;
if (!!conf.general) {
setStashes(conf.general.stashes || []);
setDatabasePath(conf.general.databasePath);
setGeneratedPath(conf.general.generatedPath);
}
// setConfig(conf);
}, [data]);
function onStashesChanged(directories: string[]) {
@@ -54,7 +59,7 @@ export const SettingsConfigurationPanel: FunctionComponent<IProps> = (props: IPr
return (
<>
{!!error ? error : undefined}
{!!error ? <h1>{error.message}</h1> : undefined}
{(!data || !data.configuration || loading) ? <Spinner size={Spinner.SIZE_LARGE} /> : undefined}
<H4>Library</H4>
<FormGroup
@@ -66,6 +71,18 @@ export const SettingsConfigurationPanel: FunctionComponent<IProps> = (props: IPr
onDirectoriesChanged={onStashesChanged}
/>
</FormGroup>
<FormGroup
label="Database Path"
helperText="File location for the SQLite database (requires restart)"
>
<InputGroup defaultValue={databasePath} onChange={(e: any) => setDatabasePath(e.target.value)} />
</FormGroup>
<FormGroup
label="Generated Path"
helperText="Directory location for the generated files (scene markers, scene previews, sprites, etc)"
>
<InputGroup defaultValue={generatedPath} onChange={(e: any) => setGeneratedPath(e.target.value)} />
</FormGroup>
<Divider />
<Button intent="primary" onClick={() => onSave()}>Save</Button>
</>

View File

@@ -0,0 +1,53 @@
import {
Button,
Checkbox,
FormGroup,
} from "@blueprintjs/core";
import React, { FunctionComponent, useState } from "react";
import { StashService } from "../../../core/StashService";
import { ErrorUtils } from "../../../utils/errors";
import { ToastUtils } from "../../../utils/toasts";
interface IProps {}
export const GenerateButton: FunctionComponent<IProps> = () => {
const [sprites, setSprites] = useState<boolean>(true);
const [previews, setPreviews] = useState<boolean>(true);
const [markers, setMarkers] = useState<boolean>(true);
const [transcodes, setTranscodes] = useState<boolean>(true);
async function onGenerate() {
try {
await StashService.queryMetadataGenerate({sprites, previews, markers, transcodes});
ToastUtils.success("Started generating");
} catch (e) {
ErrorUtils.handle(e);
}
}
return (
<FormGroup
helperText="Generate supporting image, sprite, video, vtt and other files."
labelFor="generate"
inline={true}
>
<Checkbox checked={sprites} label="Sprites (for the scene scrubber)" onChange={() => setSprites(!sprites)} />
<Checkbox
checked={previews}
label="Previews (video previews which play when hovering over a scene)"
onChange={() => setPreviews(!previews)}
/>
<Checkbox
checked={markers}
label="Markers (20 second videos which begin at the given timecode)"
onChange={() => setMarkers(!markers)}
/>
<Checkbox
checked={transcodes}
label="Transcodes (MP4 conversions of unsupported video formats)"
onChange={() => setTranscodes(!transcodes)}
/>
<Button id="generate" text="Generate" onClick={() => onGenerate()} />
</FormGroup>
);
};

View File

@@ -10,9 +10,12 @@ import {
Tag,
} from "@blueprintjs/core";
import React, { FunctionComponent, useState } from "react";
import * as GQL from "../../core/generated-graphql";
import { StashService } from "../../core/StashService";
import { TextUtils } from "../../utils/text";
import * as GQL from "../../../core/generated-graphql";
import { StashService } from "../../../core/StashService";
import { TextUtils } from "../../../utils/text";
import { GenerateButton } from "./GenerateButton";
import { ToastUtils } from "../../../utils/toasts";
import { ErrorUtils } from "../../../utils/errors";
interface IProps {}
@@ -43,6 +46,15 @@ export const SettingsTasksPanel: FunctionComponent<IProps> = (props: IProps) =>
);
}
async function onScan() {
try {
await StashService.queryMetadataScan();
ToastUtils.success("Started scan");
} catch (e) {
ErrorUtils.handle(e);
}
}
return (
<>
{renderImportAlert()}
@@ -53,18 +65,12 @@ export const SettingsTasksPanel: FunctionComponent<IProps> = (props: IProps) =>
labelFor="scan"
inline={true}
>
<Button id="scan" text="Scan" onClick={() => StashService.queryMetadataScan()} />
<Button id="scan" text="Scan" onClick={() => onScan()} />
</FormGroup>
<Divider />
<H4>Generated Content</H4>
<FormGroup
helperText="Generate supporting image, sprite, video, vtt and other files."
labelFor="generate"
inline={true}
>
<Button id="generate" text="Generate" onClick={() => StashService.queryMetadataGenerate()} />
</FormGroup>
<GenerateButton />
<FormGroup
helperText="TODO"
labelFor="clean"

View File

@@ -74,7 +74,7 @@ export const FolderSelect: FunctionComponent<IProps> = (props: IProps) => {
return (
<>
{!!error ? error : undefined}
{!!error ? <h1>{error.message}</h1> : undefined}
{renderDialog()}
{selectedDirectories.map((path) => {
return <div key={path}>{path} <a onClick={() => onRemoveDirectory(path)}>Remove</a></div>;

View File

@@ -166,9 +166,10 @@ export class StashService {
});
}
public static queryMetadataGenerate() {
public static queryMetadataGenerate(input: GQL.GenerateMetadataInput) {
return StashService.client.query<GQL.MetadataGenerateQuery>({
query: GQL.MetadataGenerateDocument,
variables: { input },
fetchPolicy: "network-only",
});
}

View File

@@ -1,5 +1,5 @@
/* tslint:disable */
// Generated in 2019-03-23T12:23:40-07:00
// Generated in 2019-03-24T09:16:39-07:00
export type Maybe<T> = T | undefined;
export interface SceneFilterType {
@@ -47,6 +47,16 @@ export interface PerformerFilterType {
filter_favorites?: Maybe<boolean>;
}
export interface GenerateMetadataInput {
sprites: boolean;
previews: boolean;
markers: boolean;
transcodes: boolean;
}
export interface SceneUpdateInput {
clientMutationId?: Maybe<string>;
@@ -206,6 +216,10 @@ export interface TagDestroyInput {
export interface ConfigGeneralInput {
/** Array of file paths to content */
stashes?: Maybe<string[]>;
/** Path to the SQLite database */
databasePath?: Maybe<string>;
/** Path to generated files */
generatedPath?: Maybe<string>;
}
export enum ResolutionEnum {
@@ -804,7 +818,9 @@ export type MetadataScanQuery = {
metadataScan: string;
};
export type MetadataGenerateVariables = {};
export type MetadataGenerateVariables = {
input: GenerateMetadataInput;
};
export type MetadataGenerateQuery = {
__typename?: "Query";
@@ -863,7 +879,11 @@ export type MetadataUpdateSubscription = {
export type ConfigGeneralDataFragment = {
__typename?: "ConfigGeneralResult";
stashes: Maybe<string[]>;
stashes: string[];
databasePath: string;
generatedPath: string;
};
export type ConfigDataFragment = {
@@ -1244,6 +1264,8 @@ import * as ReactApolloHooks from "react-apollo-hooks";
export const ConfigGeneralDataFragmentDoc = gql`
fragment ConfigGeneralData on ConfigGeneralResult {
stashes
databasePath
generatedPath
}
`;
@@ -2276,8 +2298,8 @@ export function useMetadataScan(
);
}
export const MetadataGenerateDocument = gql`
query MetadataGenerate {
metadataGenerate
query MetadataGenerate($input: GenerateMetadataInput!) {
metadataGenerate(input: $input)
}
`;
export function useMetadataGenerate(