-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathalbumpact.go
124 lines (117 loc) · 3.08 KB
/
albumpact.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package albumpact
import (
"github.com/pkg/errors"
_ "github.com/varyoo/albumpact/flac"
"github.com/varyoo/albumpact/meta"
"github.com/varyoo/albumpact/release"
"github.com/varyoo/albumpact/source"
_ "github.com/varyoo/albumpact/source/7digital"
_ "github.com/varyoo/albumpact/source/discogs"
_ "github.com/varyoo/albumpact/source/itunes"
_ "github.com/varyoo/albumpact/source/qobuz"
"github.com/varyoo/albumpact/stats"
)
type Release struct {
release.Release
stats stats.AlbumStats
trackStats map[uint16]stats.TrackStats
}
func NewRelease(paths ...string) (*Release, error) {
eng, err := release.NewRelease(paths...)
if err != nil {
return nil, err
}
r := &Release{Release: eng, stats: stats.NewAlbumStats()}
r.stats.Add(r)
r.trackStats = make(map[uint16]stats.TrackStats)
for _, t := range eng.Tracks() {
ts := stats.NewTrackStats()
ts.Add(t)
r.trackStats[t.TrackNumber()] = ts
}
return r, nil
}
func (r *Release) Source(sources ...string) error {
for _, s := range sources {
a, l, err := source.Get(s)
if err != nil {
return errors.Wrap(err, "source")
}
r.stats.Add(a)
for _, t := range l {
r.trackStats[t.TrackNumber()].Add(t)
}
}
return nil
}
func mergeTags(tag meta.Tag, tags stats.StringTags,
ask func(meta.Tag, []*stats.StringTag) (string, error),
set func(string)) error {
values := tags.Slice()
count := len(values)
if count == 1 {
set(values[0].Val())
} else if count > 1 {
if val, err := ask(tag, values); err != nil {
return errors.Wrap(err, "manual tag fix")
} else {
set(val)
}
}
return nil
}
func (r *Release) FixAlbum(ask func(meta.Tag, []*stats.StringTag) (string, error)) error {
t := &meta.AlbumTags{
AlbumTag: r.AlbumTitle(),
AlbumArtistTag: r.AlbumArtist(),
DateTag: r.Date(),
}
if err := mergeTags(meta.AlbumTag, r.stats.Albums, ask, func(v string) {
t.AlbumTag = v
}); err != nil {
return errors.Wrap(err, "album")
}
if err := mergeTags(meta.AlbumArtistTag, r.stats.AlbumArtists, ask, func(v string) {
t.AlbumArtistTag = v
}); err != nil {
return errors.Wrap(err, "album artist")
}
if err := mergeTags(meta.DateTag, r.stats.Dates, ask, func(v string) {
t.DateTag = v
}); err != nil {
return errors.Wrap(err, "date")
}
r.Tags(t)
return nil
}
type fixStringTag func(meta.Tag, []*stats.StringTag) (string, error)
func (r *Release) FixTrack(track release.Track, ask fixStringTag) error {
tn := track.TrackNumber()
t := &meta.TrackTags{
Album: r,
TrackNumberTag: tn,
TitleTag: track.Title(),
ArtistTag: track.Artist(),
}
ts := r.trackStats[tn]
if err := mergeTags(meta.TitleTag, ts.Titles, ask, func(v string) {
t.TitleTag = v
}); err != nil {
return errors.Wrap(err, "title")
}
if err := mergeTags(meta.ArtistTag, ts.Artists, ask, func(v string) {
t.ArtistTag = v
}); err != nil {
return errors.Wrap(err, "artist")
}
track.Tags(t)
return nil
}
func (r *Release) FixTracks(ask fixStringTag) error {
for _, t := range r.Tracks() {
if err := r.FixTrack(t, ask); err != nil {
return errors.Wrapf(err, "track %d", t.TrackNumber())
}
}
return nil
}