-
Notifications
You must be signed in to change notification settings - Fork 9
/
media_detector.go
90 lines (76 loc) · 1.98 KB
/
media_detector.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package main
import "strings"
type StringSet map[string]struct{}
func NewStringSet(vs ...string) StringSet {
ss := make(StringSet, len(vs))
for _, v := range vs {
ss.Add(v)
}
return ss
}
func (ss StringSet) Add(v string) {
ss[v] = struct{}{}
}
func (ss StringSet) Contains(v string) bool {
_, ok := ss[v]
return ok
}
// TODO: this should probably live in the config.
var audioExtensions = NewStringSet("mp3", "m4a", "aac", "ogg", "oga", "flac")
// IsAudioFile returns whether the given file is an audio file.
func IsAudioFile(f *StorageFile) bool {
_, ext := splitNameExt(strings.ToLower(f.Name()))
return audioExtensions.Contains(ext)
}
var artworkDirNames = NewStringSet("scans", "covers", "artwork", "media")
// IsArtworkDir returns whether the given directory may contain cover images.
func IsArtworkDir(d *StorageDirectory) bool {
return artworkDirNames.Contains(strings.ToLower(d.Name()))
}
type ScoredFile struct {
*StorageFile
Score int
}
var imageExtensions = NewStringSet("jpg", "jpeg", "png", "gif")
var coverNames = NewStringSet("cover", "front", "folder")
func splitNameExt(fullName string) (string, string) {
idx := strings.LastIndexByte(fullName, '.')
if idx == -1 {
return fullName, ""
}
return fullName[:idx], fullName[idx+1:]
}
func scoreCover(f *StorageFile) int {
name, ext := splitNameExt(strings.ToLower(f.Name()))
if !imageExtensions.Contains(ext) {
return -1
}
// Exact match.
if coverNames.Contains(name) {
return 2
}
// Partial match.
for pattern := range coverNames {
if strings.Contains(name, pattern) {
return 1
}
}
// Any image.
return 0
}
// ScoreCovers returns a slice of image files scored as album covers.
// The highest score is more likely to be a cover image.
func ScoreCovers(files []*StorageFile) []ScoredFile {
var scored []ScoredFile
for _, f := range files {
score := scoreCover(f)
if score == -1 {
continue
}
scored = append(scored, ScoredFile{
StorageFile: f,
Score: score,
})
}
return scored
}