Config: Add options to disable specific image / video converters #1245

This commit is contained in:
Michael Mayer
2021-04-30 14:24:01 +02:00
parent 11503beb00
commit f87c9c01da
10 changed files with 289 additions and 114 deletions

View File

@@ -46,6 +46,11 @@ export class ConfigOptions extends Model {
DisableSettings: config.values.disable.settings,
DisablePlaces: config.values.disable.places,
DisableExifTool: config.values.disable.exiftool,
DisableDarktable: config.values.disable.darktable,
DisableRawtherapee: config.values.disable.rawtherapee,
DisableSips: config.values.disable.sips,
DisableHeifConvert: config.values.disable.heifconvert,
DisableFFmpeg: config.values.disable.ffmpeg,
DisableTensorFlow: config.values.disable.tensorflow,
DetectNSFW: false,
UploadNSFW: config.values.uploadNSFW,

View File

@@ -19,7 +19,7 @@
class="ma-0 pa-0 input-private"
color="secondary-dark"
:label="$gettext('Debug Logs')"
:hint="$gettext('Shows more detailed log messages.')"
:hint="$gettext('Shows more detailed log messages. Requires a restart.')"
prepend-icon="pest_control"
persistent-hint
@change="onChange"
@@ -227,7 +227,7 @@
<v-card-actions>
<v-layout wrap align-top>
<v-flex xs12 sm8 class="px-2 pb-2">
<v-flex xs12 sm4 class="px-2 pb-2">
<v-subheader class="pa-0">
{{ $gettextInterpolate($gettext('JPEG Size Limit: %{n}px'), {n: settings.JpegSize}) }}
</v-subheader>
@@ -244,6 +244,21 @@
</v-flex>
</v-flex>
<v-flex xs12 sm4 class="px-2 pb-2 pt-2">
<v-checkbox
v-model="settings.DisableDarktable"
:disabled="busy"
class="ma-0 pa-0 input-private"
color="secondary-dark"
:label="$gettext('Disable Darktable')"
:hint="$gettext('Don\'t use Darktable to convert RAW files.')"
prepend-icon="image_not_supported"
persistent-hint
@change="onChange"
>
</v-checkbox>
</v-flex>
<v-flex xs12 sm4 class="px-2 pb-2 pt-2">
<v-checkbox
v-model="settings.DarktablePresets"
@@ -258,6 +273,52 @@
>
</v-checkbox>
</v-flex>
<v-flex xs12 sm4 class="px-2 pb-2 pt-2">
<v-checkbox
v-model="settings.DisableSips"
:disabled="busy"
class="ma-0 pa-0 input-private"
color="secondary-dark"
:label="$gettext('Disable SIPS')"
:hint="$gettext('Don\'t use SIPS to convert RAW files on macOS.')"
prepend-icon="image_not_supported"
persistent-hint
@change="onChange"
>
</v-checkbox>
</v-flex>
<v-flex xs12 sm4 class="px-2 pb-2 pt-2">
<v-checkbox
v-model="settings.DisableRawtherapee"
:disabled="busy"
class="ma-0 pa-0 input-private"
color="secondary-dark"
:label="$gettext('Disable RawTherapee')"
:hint="$gettext('Don\'t use RawTherapee to convert RAW files.')"
prepend-icon="image_not_supported"
persistent-hint
@change="onChange"
>
</v-checkbox>
</v-flex>
<v-flex xs12 sm4 class="px-2 pb-2 pt-2">
<v-checkbox
v-model="settings.DisableFFmpeg"
:disabled="busy"
class="ma-0 pa-0 input-private"
color="secondary-dark"
:label="$gettext('Disable FFmpeg')"
:hint="$gettext('Don\'t transcode videos with FFmpeg.')"
prepend-icon="videocam_off"
persistent-hint
@change="onChange"
>
</v-checkbox>
</v-flex>
</v-layout>
</v-card-actions>

View File

@@ -65,9 +65,14 @@ func configAction(ctx *cli.Context) error {
fmt.Printf("%-25s %t\n", "disable-settings", conf.DisableSettings())
fmt.Printf("%-25s %t\n", "disable-places", conf.DisablePlaces())
fmt.Printf("%-25s %t\n", "disable-exiftool", conf.DisableExifTool())
fmt.Printf("%-25s %t\n", "disable-tensorflow", conf.DisableTensorFlow())
fmt.Printf("%-25s %t\n", "disable-darktable", conf.DisableDarktable())
fmt.Printf("%-25s %t\n", "disable-rawtherapee", conf.DisableRawtherapee())
fmt.Printf("%-25s %t\n", "disable-sips", conf.DisableSips())
fmt.Printf("%-25s %t\n", "disable-heifconvert", conf.DisableHeifConvert())
fmt.Printf("%-25s %t\n", "disable-ffmpeg", conf.DisableFFmpeg())
// Everything related to TensorFlow.
fmt.Printf("%-25s %t\n", "disable-tensorflow", conf.DisableTensorFlow())
fmt.Printf("%-25s %s\n", "tensorflow-version", conf.TensorFlowVersion())
fmt.Printf("%-25s %s\n", "tensorflow-model-path", conf.TensorFlowModelPath())
fmt.Printf("%-25s %t\n", "detect-nsfw", conf.DetectNSFW())

View File

@@ -62,6 +62,11 @@ type ClientDisable struct {
Settings bool `json:"settings"`
Places bool `json:"places"`
ExifTool bool `json:"exiftool"`
Darktable bool `json:"darktable"`
Rawtherapee bool `json:"rawtherapee"`
Sips bool `json:"sips"`
HeifConvert bool `json:"heifconvert"`
FFmpeg bool `json:"ffmpeg"`
TensorFlow bool `json:"tensorflow"`
}
@@ -154,6 +159,11 @@ func (c *Config) PublicConfig() ClientConfig {
Places: c.DisablePlaces(),
ExifTool: true,
TensorFlow: true,
Darktable: true,
Rawtherapee: true,
Sips: true,
HeifConvert: true,
FFmpeg: true,
},
Flags: strings.Join(c.Flags(), " "),
Mode: "public",
@@ -206,6 +216,11 @@ func (c *Config) GuestConfig() ClientConfig {
Places: c.DisablePlaces(),
ExifTool: true,
TensorFlow: true,
Darktable: true,
Rawtherapee: true,
Sips: true,
HeifConvert: true,
FFmpeg: true,
},
Flags: "readonly public shared",
Mode: "guest",
@@ -252,6 +267,11 @@ func (c *Config) UserConfig() ClientConfig {
Places: c.DisablePlaces(),
ExifTool: c.DisableExifTool(),
TensorFlow: c.DisableTensorFlow(),
Darktable: c.DisableDarktable(),
Rawtherapee: c.DisableRawtherapee(),
Sips: c.DisableSips(),
HeifConvert: c.DisableHeifConvert(),
FFmpeg: c.DisableFFmpeg(),
},
Flags: strings.Join(c.Flags(), " "),
Mode: "user",

View File

@@ -41,3 +41,28 @@ func (c *Config) DisableExifTool() bool {
func (c *Config) DisableTensorFlow() bool {
return c.options.DisableTensorFlow
}
// DisableDarktable tests if Darktable is disabled for RAW conversion.
func (c *Config) DisableDarktable() bool {
return c.options.DisableDarktable || c.DarktableBin() == ""
}
// DisableRawtherapee tests if Rawtherapee is disabled for RAW conversion.
func (c *Config) DisableRawtherapee() bool {
return c.options.DisableRawtherapee || c.RawtherapeeBin() == ""
}
// DisableSips tests if SIPS is disabled for RAW conversion.
func (c *Config) DisableSips() bool {
return c.options.DisableSips || c.SipsBin() == ""
}
// DisableHeifConvert tests if heif-convert is disabled for HEIF conversion.
func (c *Config) DisableHeifConvert() bool {
return c.options.DisableHeifConvert || c.HeifConvertBin() == ""
}
// DisableFFmpeg tests if FFmpeg is disabled for video transcoding.
func (c *Config) DisableFFmpeg() bool {
return c.options.DisableFFmpeg || c.FFmpegBin() == ""
}

View File

@@ -5,6 +5,11 @@ func (c *Config) FFmpegBin() string {
return findExecutable(c.options.FFmpegBin, "ffmpeg")
}
// FFmpegEnabled tests if FFmpeg is enabled for video transcoding.
func (c *Config) FFmpegEnabled() bool {
return !c.DisableFFmpeg()
}
// FFmpegEncoder returns the ffmpeg AVC encoder name.
func (c *Config) FFmpegEncoder() string {
if c.options.FFmpegEncoder == "" {

View File

@@ -133,7 +133,7 @@ var GlobalFlags = []cli.Flag{
},
cli.BoolFlag{
Name: "disable-webdav",
Usage: "disable built-in WebDAV server",
Usage: "disables built-in WebDAV server",
EnvVar: "PHOTOPRISM_DISABLE_WEBDAV",
},
cli.BoolFlag{
@@ -148,7 +148,7 @@ var GlobalFlags = []cli.Flag{
},
cli.BoolFlag{
Name: "disable-exiftool",
Usage: "don't create ExifTool JSON files for enhanced metadata extraction",
Usage: "don't use ExifTool to extract metadata from image and video files",
EnvVar: "PHOTOPRISM_DISABLE_EXIFTOOL",
},
cli.BoolFlag{
@@ -156,6 +156,31 @@ var GlobalFlags = []cli.Flag{
Usage: "don't use TensorFlow for image classification",
EnvVar: "PHOTOPRISM_DISABLE_TENSORFLOW",
},
cli.BoolFlag{
Name: "disable-darktable",
Usage: "don't use Darktable to convert RAW files",
EnvVar: "PHOTOPRISM_DISABLE_DARKTABLE",
},
cli.BoolFlag{
Name: "disable-rawtherapee",
Usage: "don't use RawTherapee to convert RAW files",
EnvVar: "PHOTOPRISM_DISABLE_RAWTHERAPEE",
},
cli.BoolFlag{
Name: "disable-sips",
Usage: "don't use SIPS to convert RAW files on macOS",
EnvVar: "PHOTOPRISM_DISABLE_SIPS",
},
cli.BoolFlag{
Name: "disable-heifconvert",
Usage: "don't convert HEIC/HEIF files",
EnvVar: "PHOTOPRISM_DISABLE_HEIFCONVERT",
},
cli.BoolFlag{
Name: "disable-ffmpeg",
Usage: "don't transcode videos with FFmpeg",
EnvVar: "PHOTOPRISM_DISABLE_FFMPEG",
},
cli.BoolFlag{
Name: "detect-nsfw",
Usage: "flag photos as private that may be offensive (requires TensorFlow)",
@@ -282,13 +307,13 @@ var GlobalFlags = []cli.Flag{
},
cli.StringFlag{
Name: "rawtherapee-bin",
Usage: "RawTherapee CLI `COMMAND` for raw image conversion",
Usage: "RawTherapee CLI `COMMAND` for RAW conversion",
Value: "rawtherapee-cli",
EnvVar: "PHOTOPRISM_RAWTHERAPEE_BIN",
},
cli.StringFlag{
Name: "darktable-bin",
Usage: "Darktable CLI `COMMAND` for raw image conversion",
Usage: "Darktable CLI `COMMAND` for RAW conversion",
Value: "darktable-cli",
EnvVar: "PHOTOPRISM_DARKTABLE_BIN",
},
@@ -299,7 +324,7 @@ var GlobalFlags = []cli.Flag{
},
cli.StringFlag{
Name: "sips-bin",
Usage: "Scriptable Image Processing System `COMMAND`",
Usage: "SIPS (Scriptable Image Processing System) `COMMAND` for RAW conversion",
Value: "sips",
EnvVar: "PHOTOPRISM_SIPS_BIN",
},

View File

@@ -62,6 +62,11 @@ type Options struct {
DisablePlaces bool `yaml:"DisablePlaces" json:"DisablePlaces" flag:"disable-places"`
DisableExifTool bool `yaml:"DisableExifTool" json:"DisableExifTool" flag:"disable-exiftool"`
DisableTensorFlow bool `yaml:"DisableTensorFlow" json:"DisableTensorFlow" flag:"disable-tensorflow"`
DisableDarktable bool `yaml:"DisableDarktable" json:"DisableDarktable" flag:"disable-darktable"`
DisableRawtherapee bool `yaml:"DisableRawtherapee" json:"DisableRawtherapee" flag:"disable-rawtherapee"`
DisableSips bool `yaml:"DisableSips" json:"DisableSips" flag:"disable-sips"`
DisableHeifConvert bool `yaml:"DisableHeifConvert" json:"DisableHeifConvert" flag:"disable-heifconvert"`
DisableFFmpeg bool `yaml:"DisableFFmpeg" json:"DisableFFmpeg" flag:"disable-ffmpeg"`
DetectNSFW bool `yaml:"DetectNSFW" json:"DetectNSFW" flag:"detect-nsfw"`
UploadNSFW bool `yaml:"UploadNSFW" json:"-" flag:"upload-nsfw"`
LogLevel string `yaml:"LogLevel" json:"-" flag:"log-level"`

View File

@@ -5,17 +5,32 @@ func (c *Config) RawtherapeeBin() string {
return findExecutable(c.options.RawtherapeeBin, "rawtherapee-cli")
}
// RawtherapeeEnabled tests if Rawtherapee is enabled for RAW conversion.
func (c *Config) RawtherapeeEnabled() bool {
return !c.DisableRawtherapee()
}
// DarktableBin returns the darktable-cli executable file name.
func (c *Config) DarktableBin() string {
return findExecutable(c.options.DarktableBin, "darktable-cli")
}
// DarktablePresets checks if presets should be enabled (disables concurrent raw to jpeg conversion).
// DarktableEnabled tests if Darktable is enabled for RAW conversion.
func (c *Config) DarktableEnabled() bool {
return !c.DisableDarktable()
}
// DarktablePresets checks if Darktable presets are enabled (disables concurrent RAW conversion).
func (c *Config) DarktablePresets() bool {
return c.options.DarktablePresets
}
// SipsBin returns the sips executable file name.
// SipsEnabled tests if SIPS is enabled for RAW conversion.
func (c *Config) SipsEnabled() bool {
return !c.DisableSips()
}
// SipsBin returns the SIPS executable file name.
func (c *Config) SipsBin() string {
return findExecutable(c.options.SipsBin, "sips")
}
@@ -24,3 +39,8 @@ func (c *Config) SipsBin() string {
func (c *Config) HeifConvertBin() string {
return findExecutable(c.options.HeifConvertBin, "heif-convert")
}
// HeifConvertEnabled tests if heif-convert is enabled for HEIF conversion.
func (c *Config) HeifConvertEnabled() bool {
return !c.DisableHeifConvert()
}

View File

@@ -179,9 +179,9 @@ func (c *Convert) JpegConvertCommand(f *MediaFile, jpegName string, xmpName stri
size := strconv.Itoa(c.conf.JpegSize())
if f.IsRaw() {
if c.conf.SipsBin() != "" {
if c.conf.SipsEnabled() {
result = exec.Command(c.conf.SipsBin(), "-Z", size, "-s", "format", "jpeg", "--out", jpegName, f.FileName())
} else if c.conf.DarktableBin() != "" && f.Extension() != ".cr3" {
} else if c.conf.DarktableEnabled() && f.Extension() != ".cr3" {
var args []string
// Only one instance of darktable-cli allowed due to locking if presets are loaded.
@@ -200,7 +200,7 @@ func (c *Convert) JpegConvertCommand(f *MediaFile, jpegName string, xmpName stri
}
result = exec.Command(c.conf.DarktableBin(), args...)
} else if c.conf.RawtherapeeBin() != "" {
} else if c.conf.RawtherapeeEnabled() {
jpegQuality := fmt.Sprintf("-j%d", c.conf.JpegQuality())
profile := filepath.Join(conf.AssetsPath(), "profiles", "raw.pp3")
@@ -210,9 +210,9 @@ func (c *Convert) JpegConvertCommand(f *MediaFile, jpegName string, xmpName stri
} else {
return nil, useMutex, fmt.Errorf("convert: no converter found for %s", txt.Quote(f.BaseName()))
}
} else if f.IsVideo() {
} else if f.IsVideo() && c.conf.FFmpegEnabled() {
result = exec.Command(c.conf.FFmpegBin(), "-y", "-i", f.FileName(), "-ss", "00:00:00.001", "-vframes", "1", jpegName)
} else if f.IsHEIF() {
} else if f.IsHEIF() && c.conf.HeifConvertEnabled() {
result = exec.Command(c.conf.HeifConvertBin(), f.FileName(), jpegName)
} else {
return nil, useMutex, fmt.Errorf("convert: file type %s not supported in %s", f.FileType(), txt.Quote(f.BaseName()))
@@ -382,7 +382,11 @@ func (c *Convert) ToAvc(f *MediaFile, encoderName string) (file *MediaFile, err
}
if !c.conf.SidecarWritable() {
return nil, fmt.Errorf("convert: disabled in read only mode (%s)", f.RelName(c.conf.OriginalsPath()))
return nil, fmt.Errorf("convert: transcoding disabled in read only mode (%s)", f.RelName(c.conf.OriginalsPath()))
}
if c.conf.DisableFFmpeg() {
return nil, fmt.Errorf("convert: ffmpeg is disabled for transcoding %s", f.RelName(c.conf.OriginalsPath()))
}
avcName = fs.FileName(f.FileName(), c.conf.SidecarPath(), c.conf.OriginalsPath(), fs.AvcExt)