1
Fork 0

Update periodic scanner value from UI

This commit is contained in:
viktorstrate 2020-09-21 11:50:39 +02:00
parent 28749c44ac
commit 167ff4b8c4
4 changed files with 187 additions and 22 deletions

View File

@ -124,6 +124,7 @@ type ComplexityRoot struct {
RegisterUser func(childComplexity int, username string, password string, rootPath string) int RegisterUser func(childComplexity int, username string, password string, rootPath string) int
ScanAll func(childComplexity int) int ScanAll func(childComplexity int) int
ScanUser func(childComplexity int, userID int) int ScanUser func(childComplexity int, userID int) int
SetPeriodicScanInterval func(childComplexity int, interval int) int
ShareAlbum func(childComplexity int, albumID int, expire *time.Time, password *string) int ShareAlbum func(childComplexity int, albumID int, expire *time.Time, password *string) int
ShareMedia func(childComplexity int, mediaID int, expire *time.Time, password *string) int ShareMedia func(childComplexity int, mediaID int, expire *time.Time, password *string) int
UpdateUser func(childComplexity int, id int, username *string, rootPath *string, password *string, admin *bool) int UpdateUser func(childComplexity int, id int, username *string, rootPath *string, password *string, admin *bool) int
@ -241,6 +242,7 @@ type MutationResolver interface {
UpdateUser(ctx context.Context, id int, username *string, rootPath *string, password *string, admin *bool) (*models.User, error) UpdateUser(ctx context.Context, id int, username *string, rootPath *string, password *string, admin *bool) (*models.User, error)
CreateUser(ctx context.Context, username string, rootPath string, password *string, admin bool) (*models.User, error) CreateUser(ctx context.Context, username string, rootPath string, password *string, admin bool) (*models.User, error)
DeleteUser(ctx context.Context, id int) (*models.User, error) DeleteUser(ctx context.Context, id int) (*models.User, error)
SetPeriodicScanInterval(ctx context.Context, interval int) (int, error)
} }
type QueryResolver interface { type QueryResolver interface {
SiteInfo(ctx context.Context) (*models.SiteInfo, error) SiteInfo(ctx context.Context) (*models.SiteInfo, error)
@ -713,6 +715,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Mutation.ScanUser(childComplexity, args["userId"].(int)), true return e.complexity.Mutation.ScanUser(childComplexity, args["userId"].(int)), true
case "Mutation.setPeriodicScanInterval":
if e.complexity.Mutation.SetPeriodicScanInterval == nil {
break
}
args, err := ec.field_Mutation_setPeriodicScanInterval_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Mutation.SetPeriodicScanInterval(childComplexity, args["interval"].(int)), true
case "Mutation.shareAlbum": case "Mutation.shareAlbum":
if e.complexity.Mutation.ShareAlbum == nil { if e.complexity.Mutation.ShareAlbum == nil {
break break
@ -1307,6 +1321,12 @@ type Mutation {
admin: Boolean! admin: Boolean!
): User @isAdmin ): User @isAdmin
deleteUser(id: Int!): User @isAdmin deleteUser(id: Int!): User @isAdmin
"""
Set how often, in seconds, the server should automatically scan for new media,
a value of 0 will disable periodic scans
"""
setPeriodicScanInterval(interval: Int!): Int!
} }
type Subscription { type Subscription {
@ -1748,6 +1768,21 @@ func (ec *executionContext) field_Mutation_scanUser_args(ctx context.Context, ra
return args, nil return args, nil
} }
func (ec *executionContext) field_Mutation_setPeriodicScanInterval_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 int
if tmp, ok := rawArgs["interval"]; ok {
ctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField("interval"))
arg0, err = ec.unmarshalNInt2int(ctx, tmp)
if err != nil {
return nil, err
}
}
args["interval"] = arg0
return args, nil
}
func (ec *executionContext) field_Mutation_shareAlbum_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { func (ec *executionContext) field_Mutation_shareAlbum_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error var err error
args := map[string]interface{}{} args := map[string]interface{}{}
@ -4127,6 +4162,47 @@ func (ec *executionContext) _Mutation_deleteUser(ctx context.Context, field grap
return ec.marshalOUser2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐUser(ctx, field.Selections, res) return ec.marshalOUser2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐUser(ctx, field.Selections, res)
} }
func (ec *executionContext) _Mutation_setPeriodicScanInterval(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Mutation",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Mutation_setPeriodicScanInterval_args(ctx, rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
fc.Args = args
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().SetPeriodicScanInterval(rctx, args["interval"].(int))
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(int)
fc.Result = res
return ec.marshalNInt2int(ctx, field.Selections, res)
}
func (ec *executionContext) _Notification_key(ctx context.Context, field graphql.CollectedField, obj *models.Notification) (ret graphql.Marshaler) { func (ec *executionContext) _Notification_key(ctx context.Context, field graphql.CollectedField, obj *models.Notification) (ret graphql.Marshaler) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
@ -7545,6 +7621,11 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
out.Values[i] = ec._Mutation_createUser(ctx, field) out.Values[i] = ec._Mutation_createUser(ctx, field)
case "deleteUser": case "deleteUser":
out.Values[i] = ec._Mutation_deleteUser(ctx, field) out.Values[i] = ec._Mutation_deleteUser(ctx, field)
case "setPeriodicScanInterval":
out.Values[i] = ec._Mutation_setPeriodicScanInterval(ctx, field)
if out.Values[i] == graphql.Null {
invalids++
}
default: default:
panic("unknown field " + strconv.Quote(field.Name)) panic("unknown field " + strconv.Quote(field.Name))
} }

View File

@ -39,3 +39,23 @@ func (r *mutationResolver) ScanUser(ctx context.Context, userID int) (*models.Sc
Message: &startMessage, Message: &startMessage,
}, nil }, nil
} }
func (r *mutationResolver) SetPeriodicScanInterval(ctx context.Context, interval int) (int, error) {
if interval < 0 {
return 0, errors.New("interval must be 0 or above")
}
_, err := r.Database.Exec("UPDATE site_info SET periodic_scan_interval = ?", interval)
if err != nil {
return 0, err
}
var dbInterval int
row := r.Database.QueryRow("SELECT periodic_scan_interval FROM site_info")
if err = row.Scan(&dbInterval); err != nil {
return 0, err
}
return dbInterval, nil
}

View File

@ -92,6 +92,12 @@ type Mutation {
admin: Boolean! admin: Boolean!
): User @isAdmin ): User @isAdmin
deleteUser(id: Int!): User @isAdmin deleteUser(id: Int!): User @isAdmin
"""
Set how often, in seconds, the server should automatically scan for new media,
a value of 0 will disable periodic scans
"""
setPeriodicScanInterval(interval: Int!): Int!
} }
type Subscription { type Subscription {

View File

@ -1,6 +1,13 @@
import React, { useState } from 'react' import React, { useState } from 'react'
import { Button, Checkbox, Dropdown, Icon, Input } from 'semantic-ui-react' import {
Button,
Checkbox,
Dropdown,
Icon,
Input,
Loader,
} from 'semantic-ui-react'
import { useMutation, useQuery } from 'react-apollo' import { useMutation, useQuery } from 'react-apollo'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import styled from 'styled-components' import styled from 'styled-components'
@ -23,6 +30,12 @@ const SCAN_INTERVAL_QUERY = gql`
} }
` `
const SCAN_INTERVAL_MUTATION = gql`
mutation changeScanIntervalMutation($interval: Int!) {
setPeriodicScanInterval(interval: $interval)
}
`
const timeUnits = [ const timeUnits = [
{ {
value: 'second', value: 'second',
@ -46,6 +59,10 @@ const timeUnits = [
}, },
] ]
const convertToSeconds = ({ value, unit }) => {
return parseInt(value * timeUnits.find(x => x.value == unit).multiplier)
}
const convertToAppropriateUnit = ({ value, unit }) => { const convertToAppropriateUnit = ({ value, unit }) => {
if (value == 0) { if (value == 0) {
return { return {
@ -54,7 +71,7 @@ const convertToAppropriateUnit = ({ value, unit }) => {
} }
} }
const seconds = value * timeUnits.find(x => x.value == unit).multiplier const seconds = convertToSeconds({ value, unit })
let resultingUnit = timeUnits.first let resultingUnit = timeUnits.first
for (const unit of timeUnits) { for (const unit of timeUnits) {
@ -113,6 +130,29 @@ const ScannerSection = () => {
}, },
}) })
const [
setScanIntervalMutation,
{ loading: scanIntervalMutationLoading },
] = useMutation(SCAN_INTERVAL_MUTATION)
const onScanIntervalCheckboxChange = checked => {
setEnablePeriodicScanner(checked)
setScanIntervalMutation({
variables: {
interval: checked ? convertToSeconds(scanInterval) : 0,
},
})
}
const onScanIntervalUpdate = scanInterval => {
setScanIntervalMutation({
variables: {
interval: convertToSeconds(scanInterval),
},
})
}
const scanIntervalUnits = [ const scanIntervalUnits = [
{ {
key: 'second', key: 'second',
@ -163,7 +203,7 @@ const ScannerSection = () => {
label="Enable periodic scanner" label="Enable periodic scanner"
disabled={scanIntervalQuery.loading} disabled={scanIntervalQuery.loading}
checked={enablePeriodicScanner} checked={enablePeriodicScanner}
onChange={(_, { checked }) => setEnablePeriodicScanner(checked)} onChange={(_, { checked }) => onScanIntervalCheckboxChange(checked)}
/> />
</div> </div>
@ -178,25 +218,43 @@ const ScannerSection = () => {
<Input <Input
label={ label={
<Dropdown <Dropdown
onChange={(_, { value }) => onChange={(_, { value }) => {
setScanInterval(x => ({ const newScanInterval = {
...x, ...scanInterval,
unit: value, unit: value,
}))
} }
setScanInterval(newScanInterval)
onScanIntervalUpdate(newScanInterval)
}}
value={scanInterval.unit} value={scanInterval.unit}
options={scanIntervalUnits} options={scanIntervalUnits}
/> />
} }
onBlur={() => onScanIntervalUpdate(scanInterval)}
onKeyDown={({ key }) =>
key == 'Enter' && onScanIntervalUpdate(scanInterval)
}
loading={scanIntervalQuery.loading} loading={scanIntervalQuery.loading}
labelPosition="right" labelPosition="right"
style={{ maxWidth: 300 }} style={{ maxWidth: 300 }}
id="periodic_scan_field" id="periodic_scan_field"
value={scanInterval.value} value={scanInterval.value}
onChange={e => setScanInterval(e.target.value)} onChange={(_, { value }) => {
setScanInterval(x => ({
...x,
value,
}))
}}
/> />
</> </>
)} )}
<Loader
active={scanIntervalQuery.loading || scanIntervalMutationLoading}
inline
size="small"
style={{ marginLeft: 16 }}
/>
</div> </div>
) )
} }