Refactor feature flags and settings

Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
Michael Mayer 2020-05-04 18:28:23 +02:00
parent 5388b785bf
commit f9b2ff326b
24 changed files with 199 additions and 184 deletions

View file

@ -4,19 +4,22 @@ maps:
animate: 0
style: streets
features:
archive: true
private: true
review: true
upload: true
import: true
labels: true
places: true
archive: true
download: true
edit: true
share: true
library:
raw: false
thumbs: false
rescan: false
logs: true
import:
path: ""
move: false
private: true
review: true
library:
convert: true
resample: true
rescan: false
group: true

View file

@ -79,7 +79,7 @@
</v-list-tile-content>
</v-list-tile>
<v-list-tile to="/review" @click="" v-if="config.settings.library.review">
<v-list-tile to="/review" @click="" v-if="$config.feature('review')">
<v-list-tile-content>
<v-list-tile-title>
<translate>Review</translate>
@ -109,8 +109,7 @@
</v-list-tile-content>
</v-list-tile>
<v-list-tile v-if="config.settings.library.private" to="/private" @click=""
class="p-navigation-private">
<v-list-tile to="/private" @click="" class="p-navigation-private" v-if="$config.feature('private')" >
<v-list-tile-action>
<v-icon>lock</v-icon>
</v-list-tile-action>

View file

@ -130,7 +130,7 @@
data() {
return {
showLocation: this.$config.settings().features.places,
hidePrivate: this.$config.settings().library.private,
hidePrivate: this.$config.settings().features.private,
debug: this.$config.get('debug'),
mouseDown: {
index: -1,

View file

@ -56,7 +56,7 @@
color="private"
:disabled="selection.length === 0"
@click.stop="batchPrivate"
v-if="context !== 'archive' && config.settings.library.private"
v-if="context !== 'archive' && config.settings.features.private"
class="p-photo-clipboard-private"
>
<v-icon>lock</v-icon>

View file

@ -94,7 +94,7 @@
{text: '', value: '', sortable: false, align: 'center'},
],
showLocation: this.$config.settings().features.places,
hidePrivate: this.$config.settings().library.private,
hidePrivate: this.$config.settings().features.private,
mouseDown: {
index: -1,
timeStamp: -1,

View file

@ -91,7 +91,7 @@
},
data() {
return {
hidePrivate: this.$config.settings().library.private,
hidePrivate: this.$config.settings().features.private,
mouseDown: {
index: -1,
timeStamp: -1,

View file

@ -87,7 +87,7 @@
this.$gettext("Edit Photo");
},
isPrivate: function () {
if (this.model && this.model.PhotoPrivate && this.$config.settings().library.private) {
if (this.model && this.model.PhotoPrivate && this.$config.settings().features.private) {
return this.model.PhotoPrivate
}

View file

@ -73,7 +73,7 @@
total: 0,
completed: 0,
started: 0,
review: this.$config.settings().library.review,
review: this.$config.settings().features.review,
safe: !this.$config.get("uploadNSFW"),
}
},
@ -176,7 +176,7 @@
this.total = 0;
this.completed = 0;
this.started = 0;
this.review = this.$config.settings().library.review;
this.review = this.$config.feature("review");
this.safe = !this.$config.get("uploadNSFW");
}
},

View file

@ -361,7 +361,7 @@
</v-btn>
<v-btn color="secondary-dark" depressed dark @click.stop="save(false)"
class="p-photo-dialog-confirm">
<span v-if="config.settings.library.review && model.PhotoQuality < 3">Approve</span>
<span v-if="config.settings.feature.review && model.PhotoQuality < 3">Approve</span>
<span v-else>Apply</span>
</v-btn>
<v-btn color="secondary-dark" depressed dark @click.stop="save(true)"

View file

@ -16,7 +16,7 @@
<translate>Import</translate>
</v-tab>
<v-tab id="tab-logs" ripple @click="changePath('/library/logs')">
<v-tab id="tab-logs" ripple @click="changePath('/library/logs')" v-if="$config.feature('logs')">
<translate>Logs</translate>
</v-tab>
@ -29,7 +29,7 @@
<p-tab-import></p-tab-import>
</v-tab-item>
<v-tab-item>
<v-tab-item v-if="$config.feature('logs')">
<p-tab-logs></p-tab-logs>
</v-tab-item>
</v-tabs-items>

View file

@ -17,9 +17,10 @@
<v-layout wrap align-top class="pb-2">
<v-flex xs12 class="px-2 pb-2 pt-2">
<v-checkbox
@change="onChange"
:disabled="busy"
class="ma-0 pa-0"
v-model="options.move"
v-model="settings.import.move"
color="secondary-dark"
:label="labels.move"
:hint="hints.move"
@ -80,6 +81,7 @@
import Axios from "axios";
import Notify from "common/notify";
import Event from "pubsub-js";
import Settings from "model/settings";
export default {
name: 'p-tab-import',
@ -87,15 +89,13 @@
let settings = this.$config.settings();
return {
settings: new Settings(this.$config.settings()),
started: false,
busy: false,
completed: 0,
subscriptionId: '',
fileName: '',
source: null,
options: {
move: settings.library.move,
},
labels: {
move: this.$gettext("Remove imported files"),
},
@ -105,6 +105,9 @@
}
},
methods: {
onChange() {
this.settings.save();
},
showUpload() {
Event.publish("dialog.upload");
},
@ -124,7 +127,7 @@
const ctx = this;
Notify.blockUI();
Api.post('import', this.options, {cancelToken: this.source.token}).then(function () {
Api.post('import', this.settings.import, {cancelToken: this.source.token}).then(function () {
Notify.unblockUI();
ctx.busy = false;
ctx.completed = 100;

View file

@ -20,10 +20,10 @@
@change="onChange"
:disabled="busy"
class="ma-0 pa-0"
v-model="settings.library.raw"
v-model="settings.library.convert"
color="secondary-dark"
:label="labels.raw"
:hint="hints.raw"
:label="labels.convert"
:hint="hints.convert"
prepend-icon="photo_camera"
persistent-hint
>
@ -35,10 +35,10 @@
@change="onChange"
:disabled="busy"
class="ma-0 pa-0"
v-model="settings.library.thumbs"
v-model="settings.library.resample"
color="secondary-dark"
:label="labels.thumbs"
:hint="hints.thumbs"
:label="labels.resample"
:hint="hints.resample"
prepend-icon="photo_size_select_large"
persistent-hint
>
@ -91,7 +91,7 @@
import Axios from "axios";
import Notify from "common/notify";
import Event from "pubsub-js";
import Settings from "../../model/settings";
import Settings from "model/settings";
export default {
name: 'p-tab-index',
@ -108,13 +108,13 @@
source: null,
labels: {
rescan: this.$gettext("Complete rescan"),
thumbs: this.$gettext("Create thumbnails"),
raw: this.$gettext("Convert RAW files"),
resample: this.$gettext("Create thumbnails"),
convert: this.$gettext("Convert RAW files"),
},
hints: {
rescan: this.$gettext("Re-index all originals, including already indexed and unchanged files."),
thumbs: this.$gettext("Pre-render thumbnails if not done already. On-demand rendering saves storage but requires a powerful CPU."),
raw: this.$gettext("RAWs need to be converted to JPEG so that they can be displayed in a browser. You can also do this manually."),
resample: this.$gettext("Pre-render thumbnails if not done already. On-demand rendering saves storage but requires a powerful CPU."),
convert: this.$gettext("RAWs need to be converted to JPEG so that they can be displayed in a browser. You can also do this manually."),
}
}
},

View file

@ -87,11 +87,11 @@
const settings = this.$config.settings();
if (settings.library.private) {
if (settings.features.private) {
filter.public = true;
}
if (settings.library.review) {
if (settings.features.review) {
filter.quality = 3;
}

View file

@ -15,7 +15,22 @@
@change="onChange"
:disabled="busy"
class="ma-0 pa-0"
v-model="settings.library.private"
v-model="settings.features.archive"
color="secondary-dark"
:label="labels.archive"
:hint="hints.archive"
prepend-icon="archive"
persistent-hint
>
</v-checkbox>
</v-flex>
<v-flex xs12 sm6 lg3 class="px-2 pb-2 pt-2">
<v-checkbox
@change="onChange"
:disabled="busy"
class="ma-0 pa-0"
v-model="settings.features.private"
color="secondary-dark"
:label="labels.private"
:hint="hints.private"
@ -30,7 +45,7 @@
@change="onChange"
:disabled="busy"
class="ma-0 pa-0"
v-model="settings.library.review"
v-model="settings.features.review"
color="secondary-dark"
:label="labels.review"
:hint="hints.review"
@ -54,92 +69,49 @@
>
</v-checkbox>
</v-flex>
</v-layout>
</v-card-actions>
</v-card>
<v-flex xs12 sm6 lg3 class="px-2 pb-2 pt-2">
<v-checkbox
<v-card flat tile class="mt-0 px-1 application">
<v-card-title primary-title class="pb-2">
<h3 class="body-2 mb-0"><translate>User Interface</translate></h3>
</v-card-title>
<v-card-actions>
<v-layout wrap align-top>
<v-flex xs12 sm6 class="px-2 pb-2">
<v-select
@change="onChange"
:disabled="busy"
class="ma-0 pa-0"
v-model="settings.library.move"
:items="options.themes"
:label="labels.theme"
color="secondary-dark"
:label="labels.move"
:hint="hints.move"
prepend-icon="delete"
persistent-hint
>
</v-checkbox>
background-color="secondary-light"
v-model="settings.theme"
hide-details box
></v-select>
</v-flex>
<v-flex xs12 sm6 class="px-2 pb-2">
<v-select
@change="onChange"
:disabled="busy"
:items="options.languages"
:label="labels.language"
color="secondary-dark"
background-color="secondary-light"
v-model="settings.language"
hide-details box
></v-select>
</v-flex>
</v-layout>
</v-card-actions>
</v-card>
<v-card flat tile class="mt-0 px-1 application">
<v-card-title primary-title class="pb-0">
<h3 class="body-2 mb-0"><translate>Features</translate></h3>
</v-card-title>
<v-card-actions>
<v-layout wrap align-top>
<v-flex xs12 sm6 lg3 class="px-2 pb-2 pt-2">
<v-checkbox
@change="onChange"
:disabled="busy"
class="ma-0 pa-0"
v-model="settings.features.places"
color="secondary-dark"
:label="labels.places"
:hint="hints.places"
prepend-icon="place"
persistent-hint
>
</v-checkbox>
</v-flex>
<v-flex xs12 sm6 lg3 class="px-2 pb-2 pt-2">
<v-checkbox
@change="onChange"
:disabled="busy"
class="ma-0 pa-0"
v-model="settings.features.labels"
color="secondary-dark"
:label="labels.labels"
:hint="hints.labels"
prepend-icon="label"
persistent-hint
>
</v-checkbox>
</v-flex>
<v-flex xs12 sm6 lg3 class="px-2 pb-2 pt-2">
<v-checkbox
@change="onChange"
:disabled="busy"
class="ma-0 pa-0"
v-model="settings.features.import"
color="secondary-dark"
:label="labels.import"
:hint="hints.import"
prepend-icon="create_new_folder"
persistent-hint
>
</v-checkbox>
</v-flex>
<v-flex xs12 sm6 lg3 class="px-2 pb-2 pt-2">
<v-checkbox
@change="onChange"
:disabled="busy"
class="ma-0 pa-0"
v-model="settings.features.archive"
color="secondary-dark"
:label="labels.archive"
:hint="hints.archive"
prepend-icon="archive"
persistent-hint
>
</v-checkbox>
</v-flex>
<v-flex xs12 sm6 lg3 class="px-2 pb-2 pt-2">
<v-checkbox
@change="onChange"
@ -170,6 +142,21 @@
</v-checkbox>
</v-flex>
<v-flex xs12 sm6 lg3 class="px-2 pb-2 pt-2">
<v-checkbox
@change="onChange"
:disabled="busy"
class="ma-0 pa-0"
v-model="settings.features.import"
color="secondary-dark"
:label="labels.import"
:hint="hints.import"
prepend-icon="create_new_folder"
persistent-hint
>
</v-checkbox>
</v-flex>
<v-flex xs12 sm6 lg3 class="px-2 pb-2 pt-2">
<v-checkbox
@change="onChange"
@ -199,41 +186,50 @@
>
</v-checkbox>
</v-flex>
</v-layout>
</v-card-actions>
</v-card>
<v-card flat tile class="px-1 application">
<v-card-title primary-title class="pb-2">
<h3 class="body-2 mb-0"><translate>User Interface</translate></h3>
</v-card-title>
<v-card-actions>
<v-layout wrap align-top>
<v-flex xs12 sm6 class="px-2 pb-2">
<v-select
<v-flex xs12 sm6 lg3 class="px-2 pb-2 pt-2">
<v-checkbox
@change="onChange"
:disabled="busy"
:items="options.themes"
:label="labels.theme"
class="ma-0 pa-0"
v-model="settings.features.labels"
color="secondary-dark"
background-color="secondary-light"
v-model="settings.theme"
hide-details box
></v-select>
:label="labels.labels"
:hint="hints.labels"
prepend-icon="label"
persistent-hint
>
</v-checkbox>
</v-flex>
<v-flex xs12 sm6 class="px-2 pb-2">
<v-select
<v-flex xs12 sm6 lg3 class="px-2 pb-2 pt-2">
<v-checkbox
@change="onChange"
:disabled="busy"
:items="options.languages"
:label="labels.language"
class="ma-0 pa-0"
v-model="settings.features.logs"
color="secondary-dark"
background-color="secondary-light"
v-model="settings.language"
hide-details box
></v-select>
:label="labels.logs"
:hint="hints.logs"
prepend-icon="notes"
persistent-hint
>
</v-checkbox>
</v-flex>
<v-flex xs12 sm6 lg3 class="px-2 pb-2 pt-2">
<v-checkbox
@change="onChange"
:disabled="busy"
class="ma-0 pa-0"
v-model="settings.features.places"
color="secondary-dark"
:label="labels.places"
:hint="hints.places"
prepend-icon="place"
persistent-hint
>
</v-checkbox>
</v-flex>
</v-layout>
</v-card-actions>
@ -318,17 +314,18 @@
thumbs: this.$gettext("Create thumbnails"),
raw: this.$gettext("Convert RAW files"),
move: this.$gettext("Remove imported files"),
group: this.$gettext("Group related files"),
private: this.$gettext("Hide private content"),
review: this.$gettext("Apply quality filter"),
group: this.$gettext("Group Sequential"),
archive: this.$gettext("Photo Archive"),
private: this.$gettext("Hide Private"),
review: this.$gettext("Quality Filter"),
places: this.$gettext("Places"),
labels: this.$gettext("Labels"),
import: this.$gettext("Import"),
archive: this.$gettext("Archive"),
upload: this.$gettext("Upload"),
download: this.$gettext("Download"),
edit: this.$gettext("Edit"),
share: this.$gettext("Share"),
logs: this.$gettext("Logs"),
},
hints: {
private: this.$gettext("Exclude photos marked as private from search results by default."),
@ -343,7 +340,7 @@
download: this.$gettext("Download single files and zip archives."),
edit: this.$gettext("Change photo titles, locations and other metadata."),
share: this.$gettext("Upload to WebDAV and other remote services."),
logs: this.$gettext("Show logs tab on library page."),
},
busy: false,
};

View file

@ -42,7 +42,7 @@ func StartIndexing(router *gin.RouterGroup, conf *config.Config) {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
}
if f.ConvertRaw && !conf.ReadOnly() {
if f.Convert && !conf.ReadOnly() {
convert := service.Convert()
if err := convert.Start(conf.OriginalsPath()); err != nil {
@ -51,7 +51,7 @@ func StartIndexing(router *gin.RouterGroup, conf *config.Config) {
}
}
if f.CreateThumbs {
if f.Resample {
rs := service.Resample()
if err := rs.Start(false); err != nil {
@ -62,7 +62,7 @@ func StartIndexing(router *gin.RouterGroup, conf *config.Config) {
ind := service.Index()
if f.CompleteRescan {
if f.Rescan {
ind.Start(photoprism.IndexOptionsAll())
} else {
ind.Start(photoprism.IndexOptionsNone())

View file

@ -21,24 +21,29 @@ type MapsSettings struct {
}
type LibrarySettings struct {
ConvertRaw bool `json:"raw" yaml:"raw"`
CreateThumbs bool `json:"thumbs" yaml:"thumbs"`
CompleteRescan bool `json:"rescan" yaml:"rescan"`
MoveImported bool `json:"move" yaml:"move"`
HidePrivate bool `json:"private" yaml:"private"`
RequireReview bool `json:"review" yaml:"review"`
GroupRelated bool `json:"group" yaml:"group"`
Convert bool `json:"convert" yaml:"convert"`
Resample bool `json:"resample" yaml:"resample"`
Rescan bool `json:"rescan" yaml:"rescan"`
Group bool `json:"group" yaml:"group"`
}
type ImportSettings struct {
Path string `json:"path" yaml:"path"`
Move bool `json:"move" yaml:"move"`
}
type FeatureSettings struct {
Archive bool `json:"archive" yaml:"archive"`
Private bool `json:"private" yaml:"private"`
Review bool `json:"review" yaml:"review"`
Upload bool `json:"upload" yaml:"upload"`
Import bool `json:"import" yaml:"import"`
Labels bool `json:"labels" yaml:"labels"`
Places bool `json:"places" yaml:"places"`
Archive bool `json:"archive" yaml:"archive"`
Download bool `json:"download" yaml:"download"`
Edit bool `json:"edit" yaml:"edit"`
Share bool `json:"share" yaml:"share"`
Logs bool `json:"logs" yaml:"logs"`
}
// Settings contains Web UI settings
@ -47,6 +52,7 @@ type Settings struct {
Language string `json:"language" yaml:"language"`
Maps MapsSettings `json:"maps" yaml:"maps"`
Features FeatureSettings `json:"features" yaml:"features"`
Import ImportSettings `json:"import" yaml:"import"`
Library LibrarySettings `json:"library" yaml:"library"`
}
@ -60,23 +66,27 @@ func NewSettings() *Settings {
Style: "streets",
},
Features: FeatureSettings{
Archive: true,
Review: true,
Private: true,
Upload: true,
Import: true,
Labels: true,
Places: true,
Archive: true,
Download: true,
Edit: true,
Share: true,
Logs: true,
},
Import: ImportSettings{
Path: "",
Move: false,
},
Library: LibrarySettings{
CompleteRescan: false,
ConvertRaw: false,
CreateThumbs: false,
MoveImported: false,
GroupRelated: true,
RequireReview: true,
HidePrivate: true,
Rescan: false,
Convert: true,
Resample: true,
Group: true,
},
}
}

View file

@ -4,19 +4,22 @@ maps:
animate: 0
style: streets
features:
archive: true
private: true
review: true
upload: true
import: true
labels: true
places: true
archive: true
download: true
edit: true
share: true
library:
raw: false
thumbs: false
rescan: false
logs: true
import:
path: ""
move: false
private: true
review: true
library:
convert: true
resample: true
rescan: false
group: true

View file

@ -1,7 +1,7 @@
package form
type IndexOptions struct {
CompleteRescan bool `json:"rescan"`
CreateThumbs bool `json:"thumbs"`
ConvertRaw bool `json:"raw"`
Convert bool `json:"convert"`
Resample bool `json:"resample"`
Rescan bool `json:"rescan"`
}

View file

@ -119,7 +119,7 @@ func (c *Convert) ConvertCommand(image *MediaFile, jpegName string, xmpName stri
result = exec.Command(c.conf.DarktableBin(), image.fileName, jpegName)
}
} else {
return nil, useMutex, fmt.Errorf("convert: no raw to jpeg converter installed (%s)", image.Base(c.conf.Settings().Library.GroupRelated))
return nil, useMutex, fmt.Errorf("convert: no raw to jpeg converter installed (%s)", image.Base(c.conf.Settings().Library.Group))
}
} else if image.IsHEIF() {
result = exec.Command(c.conf.HeifConvertBin(), image.fileName, jpegName)
@ -140,7 +140,7 @@ func (c *Convert) ToJpeg(image *MediaFile) (*MediaFile, error) {
return image, nil
}
jpegName := fs.TypeJpeg.Find(image.FileName(), c.conf.Settings().Library.GroupRelated)
jpegName := fs.TypeJpeg.Find(image.FileName(), c.conf.Settings().Library.Group)
mediaFile, err := NewMediaFile(jpegName)
@ -148,7 +148,7 @@ func (c *Convert) ToJpeg(image *MediaFile) (*MediaFile, error) {
return mediaFile, nil
}
jpegName = image.AbsBase(c.conf.Settings().Library.GroupRelated) + ".jpg"
jpegName = image.AbsBase(c.conf.Settings().Library.Group) + ".jpg"
if c.conf.ReadOnly() {
return nil, fmt.Errorf("convert: disabled in read only mode (%s)", image.RelativeName(c.conf.OriginalsPath()))
@ -158,7 +158,7 @@ func (c *Convert) ToJpeg(image *MediaFile) (*MediaFile, error) {
log.Infof("convert: %s -> %s", fileName, fs.RelativeName(jpegName, c.conf.OriginalsPath()))
xmpName := fs.TypeXMP.Find(image.FileName(), c.conf.Settings().Library.GroupRelated)
xmpName := fs.TypeXMP.Find(image.FileName(), c.conf.Settings().Library.Group)
event.Publish("index.converting", event.Data{
"fileType": image.FileType(),

View file

@ -119,7 +119,7 @@ func (imp *Import) Start(opt ImportOptions) {
return nil
}
related, err := mf.RelatedFiles(imp.conf.Settings().Library.GroupRelated)
related, err := mf.RelatedFiles(imp.conf.Settings().Library.Group)
if err != nil {
event.Error(fmt.Sprintf("import: %s", err.Error()))

View file

@ -95,7 +95,7 @@ func ImportWorker(jobs <-chan ImportJob) {
}
}
related, err := importedMainFile.RelatedFiles(imp.conf.Settings().Library.GroupRelated)
related, err := importedMainFile.RelatedFiles(imp.conf.Settings().Library.Group)
if err != nil {
log.Errorf("import: could not index %s (%s)", txt.Quote(fs.RelativeName(destinationMainFilename, imp.originalsPath())), err.Error())

View file

@ -122,7 +122,7 @@ func (ind *Index) Start(options IndexOptions) map[string]bool {
return nil
}
related, err := mf.RelatedFiles(ind.conf.Settings().Library.GroupRelated)
related, err := mf.RelatedFiles(ind.conf.Settings().Library.Group)
if err != nil {
log.Warnf("index: %s", err.Error())

View file

@ -64,7 +64,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
var locKeywords []string
labels := classify.Labels{}
fileBase := m.Base(ind.conf.Settings().Library.GroupRelated)
fileBase := m.Base(ind.conf.Settings().Library.Group)
filePath := m.RelativePath(ind.originalsPath())
fileName := m.RelativeName(ind.originalsPath())
fileHash := ""

View file

@ -33,7 +33,7 @@ func (s *Sync) relatedDownloads(a entity.Account) (result Downloads, err error)
// Group results by directory and base name
for i, file := range files {
k := fs.AbsBase(file.RemoteName, s.conf.Settings().Library.GroupRelated)
k := fs.AbsBase(file.RemoteName, s.conf.Settings().Library.Group)
result[k] = append(result[k], file)
@ -136,7 +136,7 @@ func (s *Sync) download(a entity.Account) (complete bool, err error) {
continue
}
related, err := mf.RelatedFiles(s.conf.Settings().Library.GroupRelated)
related, err := mf.RelatedFiles(s.conf.Settings().Library.Group)
if err != nil {
log.Warnf("sync: %s", err.Error())