-
Notifications
You must be signed in to change notification settings - Fork 9
/
media_library.go
94 lines (82 loc) · 2.12 KB
/
media_library.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
91
92
93
94
package main
import (
"sort"
)
type MediaListing struct {
CurrentDirectory *StorageDirectory
Directories []*StorageDirectory
Files []*StorageFile
Cover *StorageFile
AudioTracks []*StorageFile
}
type MediaLibrary struct {
store *S3Storage
}
func NewMediaLibrary(store *S3Storage) *MediaLibrary {
return &MediaLibrary{
store: store,
}
}
func (ml *MediaLibrary) findCover(files []*StorageFile) *StorageFile {
candidates := ScoreCovers(files)
if len(candidates) == 0 {
return nil
}
sort.SliceStable(candidates, func(i, j int) bool {
return candidates[i].Score > candidates[j].Score
})
return candidates[0].StorageFile
}
func (ml *MediaLibrary) listArtworkFiles(dirs []*StorageDirectory) ([]*StorageFile, error) {
var candidates []*StorageFile
for _, dir := range dirs {
if !IsArtworkDir(dir) {
continue
}
_, files, err := ml.store.List(dir.Path())
if err != nil {
return nil, err
}
candidates = append(candidates, files...)
}
return candidates, nil
}
// List returns directory listing under the provided path.
func (ml *MediaLibrary) List(p string) (*MediaListing, error) {
dirs, files, err := ml.store.List(p)
if err != nil {
return nil, err
}
// Find album cover in the current directory.
cover := ml.findCover(files)
if cover == nil {
// Scan nested artwork directories for covers.
artworkFiles, err := ml.listArtworkFiles(dirs)
if err != nil {
return nil, err
}
cover = ml.findCover(artworkFiles)
}
// Find audio tracks and separate all other files.
var tracks []*StorageFile
var otherFiles []*StorageFile
for _, f := range files {
if IsAudioFile(f) {
tracks = append(tracks, f)
} else if cover == nil || f.Path() != cover.Path() {
otherFiles = append(otherFiles, f)
}
}
listing := &MediaListing{
CurrentDirectory: NewStorageDirectory(p),
Directories: dirs,
Files: otherFiles,
Cover: cover,
AudioTracks: tracks,
}
return listing, nil
}
// ContentURL returns a public URL to a file under the given path.
func (ml *MediaLibrary) ContentURL(p string) (string, error) {
return ml.store.FileContentURL(p)
}