Skip to content

Commit bfde965

Browse files
committed
feat(lyrics): expose Get API as well as Search
1 parent 03e943b commit bfde965

File tree

5 files changed

+86
-7
lines changed

5 files changed

+86
-7
lines changed

lyrics/composer.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ var composers = []Composer{}
1313

1414
type Composer interface {
1515
search(*entity.Track, ...context.Context) ([]byte, error)
16+
get(string, ...context.Context) ([]byte, error)
1617
}
1718

1819
// not found entries return no error
@@ -60,3 +61,32 @@ func Search(track *entity.Track) (string, error) {
6061

6162
return string(result), os.WriteFile(track.Path().Lyrics(), result, 0o644)
6263
}
64+
65+
func Get(url string) (string, error) {
66+
var (
67+
workers []nursery.ConcurrentJob
68+
result []byte
69+
ctxBackground = context.Background()
70+
ctx, ctxCancel = context.WithCancel(ctxBackground)
71+
)
72+
defer ctxCancel()
73+
74+
for _, composer := range composers {
75+
workers = append(workers, func(c Composer) func(context.Context, chan error) {
76+
return func(ctx context.Context, ch chan error) {
77+
scopedLyrics, err := c.get(url, ctx)
78+
if err != nil {
79+
ch <- err
80+
return
81+
}
82+
83+
if len(scopedLyrics) > len(result) {
84+
result = scopedLyrics
85+
ctxCancel()
86+
}
87+
}
88+
}(composer))
89+
}
90+
91+
return string(result), nursery.RunConcurrentlyWithContext(ctx, workers...)
92+
}

lyrics/composer_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,38 @@ func TestSearchCannotCreateDir(t *testing.T) {
114114
// testing
115115
assert.EqualError(t, util.ErrOnly(Search(track)), "ko")
116116
}
117+
118+
func TestGet(t *testing.T) {
119+
// monkey patching
120+
ch := make(chan bool, 1)
121+
defer gomonkey.NewPatches().
122+
ApplyPrivateMethod(reflect.TypeOf(genius{}), "get", func() ([]byte, error) {
123+
close(ch)
124+
return []byte("glyrics"), nil
125+
}).
126+
ApplyPrivateMethod(reflect.TypeOf(lyricsOvh{}), "get", func() ([]byte, error) {
127+
<-ch
128+
return []byte("olyrics"), nil
129+
}).
130+
Reset()
131+
132+
// testing
133+
lyrics, err := Get("http://localhost")
134+
assert.Nil(t, err)
135+
assert.Equal(t, "glyrics", lyrics)
136+
}
137+
138+
func TestGetFailure(t *testing.T) {
139+
// monkey patching
140+
defer gomonkey.NewPatches().
141+
ApplyPrivateMethod(reflect.TypeOf(genius{}), "get", func() ([]byte, error) {
142+
return nil, errors.New("ko")
143+
}).
144+
ApplyPrivateMethod(reflect.TypeOf(lyricsOvh{}), "get", func() ([]byte, error) {
145+
return nil, errors.New("ko")
146+
}).
147+
Reset()
148+
149+
// testing
150+
assert.EqualError(t, util.ErrOnly(Get("http://localhost")), "ko")
151+
}

lyrics/genius.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,15 @@ func (composer genius) search(track *entity.Track, ctxs ...context.Context) ([]b
120120
track, context.WithValue(ctx, contextValueLabel(contextValueLabelMainArtist), true))
121121
}
122122

123-
return composer.fromGeniusURL(url, ctx)
123+
return composer.get(url, ctx)
124124
}
125125

126-
func (composer genius) fromGeniusURL(url string, ctx context.Context) ([]byte, error) {
126+
func (composer genius) get(url string, ctxs ...context.Context) ([]byte, error) {
127+
ctx := context.Background()
128+
if len(ctxs) > 0 {
129+
ctx = ctxs[0]
130+
}
131+
127132
request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
128133
if err != nil {
129134
return nil, err
@@ -139,7 +144,7 @@ func (composer genius) fromGeniusURL(url string, ctx context.Context) ([]byte, e
139144

140145
if response.StatusCode == 429 {
141146
util.SleepUntilRetry(response.Header)
142-
return composer.fromGeniusURL(url, ctx)
147+
return composer.get(url, ctx)
143148
} else if response.StatusCode != 200 {
144149
return nil, errors.New("cannot fetch lyrics on genius: " + response.Status)
145150
}

lyrics/genius_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ func TestGeniusLyricsNewRequestFailure(t *testing.T) {
220220
}).Reset()
221221

222222
// testing
223-
assert.EqualError(t, util.ErrOnly(genius{}.fromGeniusURL("http://genius.com/test", context.Background())), "ko")
223+
assert.EqualError(t, util.ErrOnly(genius{}.get("http://genius.com/test", context.Background())), "ko")
224224
}
225225

226226
func TestGeniusLyricsNewRequestContextCanceled(t *testing.T) {

lyrics/lyricsovh.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,18 @@ func (composer lyricsOvh) search(track *entity.Track, ctxs ...context.Context) (
3131
ctx = ctxs[0]
3232
}
3333

34-
request, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("https://api.lyrics.ovh/v1/%s/%s",
34+
return composer.get(fmt.Sprintf("https://api.lyrics.ovh/v1/%s/%s",
3535
url.QueryEscape(track.Artists[0]),
36-
url.QueryEscape(track.Title)), nil)
36+
url.QueryEscape(track.Title)), ctx)
37+
}
38+
39+
func (composer lyricsOvh) get(url string, ctxs ...context.Context) ([]byte, error) {
40+
ctx := context.Background()
41+
if len(ctxs) > 0 {
42+
ctx = ctxs[0]
43+
}
44+
45+
request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
3746
if err != nil {
3847
return nil, err
3948
}
@@ -50,7 +59,7 @@ func (composer lyricsOvh) search(track *entity.Track, ctxs ...context.Context) (
5059
return nil, nil
5160
} else if response.StatusCode == 429 {
5261
util.SleepUntilRetry(response.Header)
53-
return composer.search(track, ctx)
62+
return composer.get(url, ctx)
5463
} else if response.StatusCode != 200 {
5564
return nil, errors.New("cannot fetch results on lyrics.ovh: " + response.Status)
5665
}

0 commit comments

Comments
 (0)