Backend: Add config parameters #99 #157 #180

This commit adds config parameters for thumbnail quality, max thumbnail size and geocoding api as well as a flag to to disable TensorFlow.

Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
Michael Mayer
2020-01-06 06:59:35 +01:00
parent 10b143f8ae
commit 5ec2d9e9a4
13 changed files with 112 additions and 15 deletions

View File

@@ -55,6 +55,11 @@ func StartIndexing(router *gin.RouterGroup, conf *config.Config) {
return
}
// Set thumbnails JPEG quality and size
photoprism.JpegQuality = conf.ThumbQuality()
photoprism.MaxThumbWidth = conf.ThumbSize()
photoprism.MaxThumbHeight = conf.ThumbSize()
path := conf.OriginalsPath()
event.Info(fmt.Sprintf("indexing photos in \"%s\"", filepath.Base(path)))

View File

@@ -60,6 +60,7 @@ func configAction(ctx *cli.Context) error {
fmt.Printf("resources-path %s\n", conf.ResourcesPath())
fmt.Printf("tf-version %s\n", conf.TensorFlowVersion())
fmt.Printf("tf-model-path %s\n", conf.TensorFlowModelPath())
fmt.Printf("tf-disabled %t\n", conf.TensorFlowDisabled())
fmt.Printf("templates-path %s\n", conf.HttpTemplatesPath())
fmt.Printf("favicons-path %s\n", conf.HttpFaviconsPath())
fmt.Printf("static-path %s\n", conf.HttpStaticPath())
@@ -72,6 +73,9 @@ func configAction(ctx *cli.Context) error {
fmt.Printf("hide-nsfw %t\n", conf.HideNSFW())
fmt.Printf("upload-nsfw %t\n", conf.UploadNSFW())
fmt.Printf("geocoding-api %s\n", conf.GeoCodingApi())
fmt.Printf("thumb-quality %d\n", conf.ThumbQuality())
fmt.Printf("thumb-size %d\n", conf.ThumbSize())
return nil
}

View File

@@ -32,6 +32,10 @@ func thumbnailsAction(ctx *cli.Context) error {
log.Infof("creating thumbnails in \"%s\"", conf.ThumbnailsPath())
photoprism.JpegQuality = conf.ThumbQuality()
photoprism.MaxThumbWidth = conf.ThumbSize()
photoprism.MaxThumbHeight = conf.ThumbSize()
if err := photoprism.CreateThumbnailsFromOriginals(conf.OriginalsPath(), conf.ThumbnailsPath(), ctx.Bool("force")); err != nil {
log.Error(err)
return err

View File

@@ -11,7 +11,6 @@ import (
gc "github.com/patrickmn/go-cache"
"github.com/photoprism/photoprism/internal/event"
"github.com/sirupsen/logrus"
tensorflow "github.com/tensorflow/tensorflow/tensorflow/go"
"github.com/urfave/cli"
)
@@ -96,11 +95,6 @@ func (c *Config) Version() string {
return c.config.Version
}
// TensorFlowVersion returns the TenorFlow framework version.
func (c *Config) TensorFlowVersion() string {
return tensorflow.Version()
}
// Copyright returns the application copyright.
func (c *Config) Copyright() string {
return c.config.Copyright
@@ -185,3 +179,25 @@ func (c *Config) Shutdown() {
func (c *Config) Workers() int {
return runtime.NumCPU()
}
// ThumbQuality returns the thumbnail jpeg quality setting (0-100).
func (c *Config) ThumbQuality() int {
return c.config.ThumbQuality
}
// ThumbSize returns the thumbnail size limit in pixels.
func (c *Config) ThumbSize() int {
return c.config.ThumbSize
}
// GeoCodingApi returns the preferred geo coding api (none, osm or places).
func (c *Config) GeoCodingApi() string {
switch c.config.GeoCodingApi {
case "places":
return "places"
case "osm":
return "osm"
}
return ""
}

View File

@@ -214,4 +214,27 @@ var GlobalFlags = []cli.Flag{
Usage: "allow uploads that may contain offensive content",
EnvVar: "PHOTOPRISM_UPLOAD_NSFW",
},
cli.BoolFlag{
Name: "tf-disabled, t",
Usage: "don't use TensorFlow for image classification",
EnvVar: "PHOTOPRISM_TF_DISABLED",
},
cli.StringFlag{
Name: "geocoding-api, g",
Usage: "geocoding api (none, osm or places)",
Value: "places",
EnvVar: "PHOTOPRISM_GEOCODING_API",
},
cli.IntFlag{
Name: "thumb-quality, q",
Usage: "jpeg quality of thumbnails (0-100)",
Value: 95,
EnvVar: "PHOTOPRISM_THUMB_QUALITY",
},
cli.IntFlag{
Name: "thumb-size",
Usage: "max thumbnail size in pixels",
Value: 8192,
EnvVar: "PHOTOPRISM_THUMB_SIZE",
},
}

View File

@@ -69,6 +69,10 @@ type Params struct {
DetachServer bool `yaml:"detach-server" flag:"detach-server"`
HideNSFW bool `yaml:"hide-nsfw" flag:"hide-nsfw"`
UploadNSFW bool `yaml:"upload-nsfw" flag:"upload-nsfw"`
DisableTensorFlow bool `yaml:"tf-disabled" flag:"tf-disabled"`
GeoCodingApi string `yaml:"geocoding-api" flag:"geocoding-api"`
ThumbQuality int `yaml:"thumb-quality" flag:"thumb-quality"`
ThumbSize int `yaml:"thumb-size" flag:"thumb-size"`
}
// NewParams() creates a new configuration entity by using two methods:

View File

@@ -0,0 +1,13 @@
package config
import tf "github.com/tensorflow/tensorflow/tensorflow/go"
// TensorFlowVersion returns the TenorFlow framework version.
func (c *Config) TensorFlowVersion() string {
return tf.Version()
}
// TensorFlowDisabled returns true if the use of TensorFlow is disabled for image classification.
func (c *Config) TensorFlowDisabled() bool {
return c.config.DisableTensorFlow
}

View File

@@ -44,7 +44,7 @@ func NewLocation(lat, lng float64) *Location {
return result
}
func (m *Location) Find(db *gorm.DB) error {
func (m *Location) Find(db *gorm.DB, api string) error {
writeMutex.Lock()
defer writeMutex.Unlock()
@@ -57,7 +57,7 @@ func (m *Location) Find(db *gorm.DB) error {
ID: m.ID,
}
if err := l.QueryPlaces(); err != nil {
if err := l.Query(api); err != nil {
return err
}

View File

@@ -54,6 +54,17 @@ func NewLocation(id string) *Location {
return result
}
func (l *Location) Query(api string) error {
switch api {
case "osm":
return l.QueryOSM()
case "places":
return l.QueryPlaces()
}
return errors.New("maps: reverse lookup disabled")
}
func (l *Location) QueryPlaces() error {
s, err := places.FindLocation(l.ID)

View File

@@ -87,7 +87,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions) IndexResult {
photo.PhotoName = fileBase
if file.FilePrimary {
if fileChanged || o.UpdateKeywords || o.UpdateLabels || o.UpdateTitle {
if !ind.conf.TensorFlowDisabled() && (fileChanged || o.UpdateKeywords || o.UpdateLabels || o.UpdateTitle) {
// Image classification labels
labels, isNSFW = ind.classifyImage(m)
photo.PhotoNSFW = isNSFW
@@ -368,10 +368,10 @@ func (ind *Index) indexLocation(mediaFile *MediaFile, photo *entity.Photo, label
location.Lock()
defer location.Unlock()
err := location.Find(ind.db)
err := location.Find(ind.db, ind.conf.GeoCodingApi())
if err != nil {
log.Error(err)
log.Warn(err)
return keywords, labels
}

View File

@@ -24,7 +24,7 @@ func TestMediaFile_Location(t *testing.T) {
t.Fatal(err)
}
if err = location.Find(conf.Db()); err != nil {
if err = location.Find(conf.Db(), "places"); err != nil {
t.Fatal(err)
}
@@ -39,7 +39,7 @@ func TestMediaFile_Location(t *testing.T) {
t.Fatal(err)
}
if err = location.Find(conf.Db()); err != nil {
if err = location.Find(conf.Db(), "places"); err != nil {
t.Fatal(err)
}
@@ -60,7 +60,7 @@ func TestMediaFile_Location(t *testing.T) {
t.Fatal(err)
}
if err = location.Find(conf.Db()); err != nil {
if err = location.Find(conf.Db(), "places"); err != nil {
t.Fatal(err)
}

View File

@@ -47,6 +47,10 @@ func NewTensorFlow(conf *config.Config) *TensorFlow {
}
func (t *TensorFlow) Init() (err error) {
if t.conf.TensorFlowDisabled() {
return nil
}
if err := t.loadModel(); err != nil {
return err
}
@@ -85,6 +89,10 @@ func (t *TensorFlow) loadLabelRules() (err error) {
// LabelsFromFile returns matching labels for a jpeg media file.
func (t *TensorFlow) LabelsFromFile(filename string) (result Labels, err error) {
if t.conf.TensorFlowDisabled() {
return result, nil
}
imageBuffer, err := ioutil.ReadFile(filename)
if err != nil {
@@ -96,6 +104,10 @@ func (t *TensorFlow) LabelsFromFile(filename string) (result Labels, err error)
// Labels returns matching labels for a jpeg media string.
func (t *TensorFlow) Labels(img []byte) (result Labels, err error) {
if t.conf.TensorFlowDisabled() {
return result, nil
}
if err := t.loadModel(); err != nil {
return nil, err
}

View File

@@ -17,7 +17,7 @@ import (
"github.com/photoprism/photoprism/internal/util"
)
const (
var (
MaxThumbWidth = 8192
MaxThumbHeight = 8192
JpegQuality = 95
@@ -317,6 +317,11 @@ func (m *MediaFile) CreateDefaultThumbnails(thumbPath string, force bool) (err e
for _, name := range DefaultThumbnails {
thumbType := ThumbnailTypes[name]
if thumbType.Height > MaxThumbHeight || thumbType.Width > MaxThumbWidth {
log.Debugf("thumbs: size exceeds limit (width %d, height %d)", thumbType.Width, thumbType.Height)
continue
}
if fileName, err := ThumbnailFilename(hash, thumbPath, thumbType.Width, thumbType.Height, thumbType.Options...); err != nil {
log.Errorf("could not create %s thumbnail: \"%s\"", name, err)