2020-01-09 01:21:09 +01:00
|
|
|
package classify
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sort"
|
|
|
|
|
2020-01-12 14:00:56 +01:00
|
|
|
"github.com/photoprism/photoprism/pkg/txt"
|
2020-01-09 01:21:09 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// Labels is list of MediaFile labels.
|
|
|
|
type Labels []Label
|
|
|
|
|
2020-02-21 01:14:45 +01:00
|
|
|
// Implements functions for the Sort Interface. Default Labels sort is by priority and uncertainty
|
2020-01-09 01:21:09 +01:00
|
|
|
func (l Labels) Len() int { return len(l) }
|
|
|
|
func (l Labels) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
|
|
|
|
func (l Labels) Less(i, j int) bool {
|
2020-04-17 21:20:38 +02:00
|
|
|
if l[i].Uncertainty >= 100 {
|
|
|
|
return false
|
|
|
|
} else if l[j].Uncertainty >= 100 {
|
|
|
|
return true
|
|
|
|
} else if l[i].Priority == l[j].Priority {
|
2020-01-09 01:21:09 +01:00
|
|
|
return l[i].Uncertainty < l[j].Uncertainty
|
|
|
|
} else {
|
|
|
|
return l[i].Priority > l[j].Priority
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-21 01:14:45 +01:00
|
|
|
// AppendLabel extends append func by not appending empty label
|
2020-01-09 01:21:09 +01:00
|
|
|
func (l Labels) AppendLabel(label Label) Labels {
|
|
|
|
if label.Name == "" {
|
|
|
|
return l
|
|
|
|
}
|
|
|
|
|
|
|
|
return append(l, label)
|
|
|
|
}
|
|
|
|
|
2020-04-16 20:57:00 +02:00
|
|
|
// Keywords returns all keywords contains in Labels and their categories
|
2020-01-09 01:21:09 +01:00
|
|
|
func (l Labels) Keywords() (result []string) {
|
|
|
|
for _, label := range l {
|
2020-04-17 21:20:38 +02:00
|
|
|
if label.Uncertainty >= 100 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2020-01-09 01:21:09 +01:00
|
|
|
result = append(result, txt.Keywords(label.Name)...)
|
|
|
|
|
|
|
|
for _, c := range label.Categories {
|
|
|
|
result = append(result, txt.Keywords(c)...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2020-04-17 21:20:38 +02:00
|
|
|
// Title gets the best label out a list of labels or fallback to compute a meaningful default title.
|
2020-01-09 01:21:09 +01:00
|
|
|
func (l Labels) Title(fallback string) string {
|
|
|
|
fallbackRunes := len([]rune(fallback))
|
|
|
|
|
2020-02-21 01:14:45 +01:00
|
|
|
// check if given fallback is valid
|
2020-01-09 01:21:09 +01:00
|
|
|
if fallbackRunes < 2 || fallbackRunes > 25 || txt.ContainsNumber(fallback) {
|
|
|
|
fallback = ""
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(l) == 0 {
|
|
|
|
return fallback
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sort by priority and uncertainty
|
|
|
|
sort.Sort(l)
|
|
|
|
|
|
|
|
// Get best label (at the top)
|
|
|
|
label := l[0]
|
|
|
|
|
|
|
|
// Get second best label in case the first has high uncertainty
|
|
|
|
if len(l) > 1 && l[0].Uncertainty > 60 && l[1].Uncertainty <= 60 {
|
|
|
|
label = l[1]
|
|
|
|
}
|
|
|
|
|
|
|
|
if fallback != "" && label.Priority < 0 {
|
|
|
|
return fallback
|
|
|
|
} else if fallback != "" && label.Priority == 0 && label.Uncertainty > 50 {
|
|
|
|
return fallback
|
|
|
|
} else if label.Priority >= -1 && label.Uncertainty <= 60 {
|
|
|
|
return label.Name
|
|
|
|
}
|
|
|
|
|
|
|
|
return fallback
|
|
|
|
}
|