Add config option to enable/disable Transcoding configuration

This commit is contained in:
Deluan 2020-04-27 21:23:15 -04:00 committed by Deluan Quintão
parent eb7d2dcaa1
commit c816ca4525
12 changed files with 134 additions and 49 deletions

View File

@ -27,9 +27,10 @@ type nd struct {
IgnoredArticles string `default:"The El La Los Las Le Les Os As O A"`
IndexGroups string `default:"A B C D E F G H I J K L M N O P Q R S T U V W X-Z(XYZ) [Unknown]([)"`
TranscodingCacheSize string `default:"100MB"` // in MB
ImageCacheSize string `default:"100MB"` // in MB
ProbeCommand string `default:"ffmpeg %s -f ffmetadata"`
EnableTranscodingConfig bool `default:"false"`
TranscodingCacheSize string `default:"100MB"` // in MB
ImageCacheSize string `default:"100MB"` // in MB
ProbeCommand string `default:"ffmpeg %s -f ffmetadata"`
// DevFlags. These are used to enable/disable debugging and incomplete features
DevLogSourceLine bool `default:"false"`

View File

@ -7,6 +7,7 @@ import (
"strings"
"github.com/deluan/navidrome/assets"
"github.com/deluan/navidrome/conf"
"github.com/deluan/navidrome/engine/auth"
"github.com/deluan/navidrome/model"
"github.com/deluan/rest"
@ -41,12 +42,12 @@ func (app *Router) routes(path string) http.Handler {
r.Use(mapAuthHeader())
r.Use(jwtauth.Verifier(auth.TokenAuth))
r.Use(authenticator(app.ds))
app.R(r, "/user", model.User{})
app.R(r, "/song", model.MediaFile{})
app.R(r, "/album", model.Album{})
app.R(r, "/artist", model.Artist{})
app.R(r, "/transcoding", model.Transcoding{})
app.R(r, "/player", model.Player{})
app.R(r, "/user", model.User{}, true)
app.R(r, "/song", model.MediaFile{}, true)
app.R(r, "/album", model.Album{}, true)
app.R(r, "/artist", model.Artist{}, true)
app.R(r, "/player", model.Player{}, true)
app.R(r, "/transcoding", model.Transcoding{}, conf.Server.EnableTranscodingConfig)
// Keepalive endpoint to be used to keep the session valid (ex: while playing songs)
r.Get("/keepalive/*", func(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte(`{"response":"ok"}`)) })
@ -59,18 +60,22 @@ func (app *Router) routes(path string) http.Handler {
return r
}
func (app *Router) R(r chi.Router, pathPrefix string, model interface{}) {
func (app *Router) R(r chi.Router, pathPrefix string, model interface{}, persistable bool) {
constructor := func(ctx context.Context) rest.Repository {
return app.ds.Resource(ctx, model)
}
r.Route(pathPrefix, func(r chi.Router) {
r.Get("/", rest.GetAll(constructor))
r.Post("/", rest.Post(constructor))
if persistable {
r.Post("/", rest.Post(constructor))
}
r.Route("/{id:[0-9a-f\\-]+}", func(r chi.Router) {
r.Use(UrlParams)
r.Get("/", rest.Get(constructor))
r.Put("/", rest.Put(constructor))
r.Delete("/", rest.Delete(constructor))
if persistable {
r.Put("/", rest.Put(constructor))
r.Delete("/", rest.Delete(constructor))
}
})
})
}

View File

@ -22,10 +22,11 @@ func ServeIndex(ds model.DataStore, fs http.FileSystem) http.HandlerFunc {
t := getIndexTemplate(r, fs)
appConfig := map[string]interface{}{
"version": consts.Version(),
"firstTime": firstTime,
"baseURL": strings.TrimSuffix(conf.Server.BaseURL, "/"),
"loginBackgroundURL": conf.Server.UILoginBackgroundURL,
"version": consts.Version(),
"firstTime": firstTime,
"baseURL": strings.TrimSuffix(conf.Server.BaseURL, "/"),
"loginBackgroundURL": conf.Server.UILoginBackgroundURL,
"enableTranscodingConfig": conf.Server.EnableTranscodingConfig,
}
j, _ := json.Marshal(appConfig)

10
ui/src/common/DocLink.js Normal file
View File

@ -0,0 +1,10 @@
import React from 'react'
import { docsUrl } from '../utils/docsUrl'
const DocLink = ({ path, children }) => (
<a href={docsUrl(path)} target={'_blank'} rel="noopener noreferrer">
{children}
</a>
)
export default DocLink

View File

@ -7,6 +7,7 @@ import SimpleList from './SimpleList'
import RangeField, { formatRange } from './RangeField'
import SongDetails from './SongDetails'
import SizeField from './SizeField'
import DocLink from './DocLink'
export {
Title,
@ -18,5 +19,6 @@ export {
SimpleList,
RangeField,
SongDetails,
DocLink,
formatRange,
}

View File

@ -1,8 +1,12 @@
// These defaults are only used in development mode. When bundled in the app,
// the __APP_CONFIG__ object is dynamically filled by the ServeIndex function,
// in the /server/app/serve_index.go
const defaultConfig = {
version: 'dev',
firstTime: false,
baseURL: '',
loginBackgroundURL: 'https://source.unsplash.com/random/1600x900?music',
enableTranscodingConfig: true,
}
let config

View File

@ -14,6 +14,7 @@ import HelpOutlineIcon from '@material-ui/icons/HelpOutline'
import { changeTheme } from './actions'
import themes from '../themes'
import i18n from '../i18n'
import { docsUrl } from '../utils/docsUrl'
const useStyles = makeStyles({
root: { marginTop: '1em' },
@ -53,9 +54,7 @@ const SelectLanguage = (props) => {
choices={langChoices}
onChange={(event) => {
if (event.target.value === helpKey) {
openInNewTab(
'https://www.navidrome.org/docs/developers/translations/'
)
openInNewTab(docsUrl('/docs/developers/translations/'))
return
}
setLocale(event.target.value)
@ -85,9 +84,7 @@ const SelectTheme = (props) => {
choices={themeChoices}
onChange={(event) => {
if (event.target.value === helpKey) {
openInNewTab(
'https://www.navidrome.org/docs/developers/creating-themes/'
)
openInNewTab(docsUrl('/docs/developers/creating-themes/'))
return
}
dispatch(changeTheme(event.target.value))

View File

@ -7,6 +7,7 @@ import {
SimpleForm,
useTranslate,
} from 'react-admin'
import { Card, CardContent, Typography, Box } from '@material-ui/core'
import { Title } from '../common'
const TranscodingTitle = ({ record }) => {
@ -18,29 +19,48 @@ const TranscodingTitle = ({ record }) => {
}
const TranscodingEdit = (props) => (
<Edit title={<TranscodingTitle />} {...props}>
<SimpleForm>
<TextInput source="name" validate={[required()]} />
<TextInput source="targetFormat" validate={[required()]} />
<SelectInput
source="defaultBitRate"
choices={[
{ id: 32, name: '32' },
{ id: 48, name: '48' },
{ id: 64, name: '64' },
{ id: 80, name: '80' },
{ id: 96, name: '96' },
{ id: 112, name: '112' },
{ id: 128, name: '128' },
{ id: 160, name: '160' },
{ id: 192, name: '192' },
{ id: 256, name: '256' },
{ id: 320, name: '320' },
]}
/>
<TextInput source="command" fullWidth validate={[required()]} />
</SimpleForm>
</Edit>
<>
<Card>
<CardContent>
<Typography>
<Box fontWeight="fontWeightBold" component={'span'}>
NOTE:
</Box>{' '}
Navidrome is currently running with the{' '}
<Box fontFamily="Monospace" component={'span'}>
ND_ENABLETRANSCODINGCONFIG=true
</Box>
, making it possible to run system commands from the transcoding
settings using the web interface. We recommend to disable it for
security reasons and only enable it when configuring Transcoding
options.
</Typography>
</CardContent>
</Card>
<Edit title={<TranscodingTitle />} {...props}>
<SimpleForm>
<TextInput source="name" validate={[required()]} />
<TextInput source="targetFormat" validate={[required()]} />
<SelectInput
source="defaultBitRate"
choices={[
{ id: 32, name: '32' },
{ id: 48, name: '48' },
{ id: 64, name: '64' },
{ id: 80, name: '80' },
{ id: 96, name: '96' },
{ id: 112, name: '112' },
{ id: 128, name: '128' },
{ id: 160, name: '160' },
{ id: 192, name: '192' },
{ id: 256, name: '256' },
{ id: 320, name: '320' },
]}
/>
<TextInput source="command" fullWidth validate={[required()]} />
</SimpleForm>
</Edit>
</>
)
export default TranscodingEdit

View File

@ -2,6 +2,7 @@ import React from 'react'
import { Datagrid, List, TextField } from 'react-admin'
import { useMediaQuery } from '@material-ui/core'
import { SimpleList, Title } from '../common'
import config from '../config'
const TranscodingList = (props) => {
const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))
@ -23,7 +24,7 @@ const TranscodingList = (props) => {
tertiaryText={(r) => r.defaultBitRate}
/>
) : (
<Datagrid rowClick="edit">
<Datagrid rowClick={config.enableTranscodingConfig ? 'edit' : 'show'}>
<TextField source="name" />
<TextField source="targetFormat" />
<TextField source="defaultBitRate" />

View File

@ -0,0 +1,40 @@
import React from 'react'
import { TextField, Show, SimpleShowLayout } from 'react-admin'
import { Card, CardContent, Typography, Box } from '@material-ui/core'
import { Title } from '../common'
const TranscodingTitle = ({ record }) => {
return <Title subTitle={`Transcoding ${record ? record.name : ''}`} />
}
const TranscodingShow = (props) => (
<>
<Card>
<CardContent>
<Typography>
<Box fontWeight="fontWeightBold" component={'span'}>
NOTE:
</Box>{' '}
Changing the transcoding configuration through the web interface is
disabled for security reasons. If you would like to change (edit or
add) transcoding options, restart the server with the{' '}
<Box fontFamily="Monospace" component={'span'}>
ND_ENABLETRANSCODINGCONFIG=true
</Box>{' '}
configuration option.
</Typography>
</CardContent>
</Card>
<Show title={<TranscodingTitle />} {...props}>
<SimpleShowLayout>
<TextField source="name" />
<TextField source="targetFormat" />
<TextField source="defaultBitRate" />
<TextField source="command" />
</SimpleShowLayout>
</Show>
</>
)
export default TranscodingShow

View File

@ -2,10 +2,13 @@ import TransformIcon from '@material-ui/icons/Transform'
import TranscodingList from './TranscodingList'
import TranscodingEdit from './TranscodingEdit'
import TranscodingCreate from './TranscodingCreate'
import TranscodingShow from './TranscodingShow'
import config from '../config'
export default {
list: TranscodingList,
edit: TranscodingEdit,
create: TranscodingCreate,
edit: config.enableTranscodingConfig && TranscodingEdit,
create: config.enableTranscodingConfig && TranscodingCreate,
show: !config.enableTranscodingConfig && TranscodingShow,
icon: TransformIcon,
}

1
ui/src/utils/docsUrl.js Normal file
View File

@ -0,0 +1 @@
export const docsUrl = (path) => `https://www.navidrome.org${path}`