GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 2dafa8...290d64 )
by Christian
02:38
created

TrackService::scrobble()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.7666
c 0
b 0
f 0
cc 3
nc 3
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * (c) Christian Gripp <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Core23\LastFm\Service;
13
14
use Core23\LastFm\Connection\SessionInterface;
15
use Core23\LastFm\Exception\ApiException;
16
use Core23\LastFm\Exception\NotFoundException;
17
use Core23\LastFm\Model\NowPlaying;
18
use Core23\LastFm\Model\Song;
19
use Core23\LastFm\Model\SongInfo;
20
use Core23\LastFm\Model\Tag;
21
22
final class TrackService extends AbstractService
23
{
24
    /**
25
     * Tag an track using a list of user supplied tags.
26
     *
27
     * @param SessionInterface $session
28
     * @param string           $artist
29
     * @param string           $track
30
     * @param array            $tags
31
     *
32
     * @throws ApiException
33
     * @throws NotFoundException
34
     */
35
    public function addTags(SessionInterface $session, string $artist, string $track, array $tags): void
36
    {
37
        $count = \count($tags);
38
39
        if (0 === $count) {
40
            return;
41
        }
42
        if ($count > 10) {
43
            throw new \InvalidArgumentException('A maximum of 10 tags is allowed');
44
        }
45
46
        $this->signedCall('track.addTags', [
47
            'artist' => $artist,
48
            'track'  => $track,
49
            'tags'   => implode(',', $tags),
50
        ], $session, 'POST');
51
    }
52
53
    /**
54
     * Check whether the supplied track has a correction to a canonical artist.
55
     *
56
     * @param string $artist
57
     * @param string $track
58
     *
59
     * @throws ApiException
60
     * @throws NotFoundException
61
     *
62
     * @return Song|null
63
     */
64
    public function getCorrection(string $artist, string $track): ?Song
65
    {
66
        $response = $this->unsignedCall('track.getCorrection', [
67
            'artist' => $artist,
68
            'track'  => $track,
69
        ]);
70
71
        if (!isset($response['corrections']['correction']['track'])) {
72
            return null;
73
        }
74
75
        return Song::fromApi($response['corrections']['correction']['track']);
76
    }
77
78
    /**
79
     * Get the metadata for a track on Last.fm using the artist/track name.
80
     *
81
     * @param string      $artist
82
     * @param string      $track
83
     * @param string|null $username
84
     * @param bool        $autocorrect
85
     *
86
     * @throws ApiException
87
     * @throws NotFoundException
88
     *
89
     * @return SongInfo|null
90
     */
91
    public function getInfo(string $artist, string $track, ?string $username = null, $autocorrect = false): ?SongInfo
92
    {
93
        $response = $this->unsignedCall('track.getInfo', [
94
            'artist'      => $artist,
95
            'track'       => $track,
96
            'autocorrect' => (int) $autocorrect,
97
            'username'    => $username,
98
        ]);
99
100
        if (!isset($response['track'])) {
101
            return null;
102
        }
103
104
        return SongInfo::fromApi($response['track']);
105
    }
106
107
    /**
108
     * Get the metadata for a track on Last.fm using the musicbrainz id.
109
     *
110
     * @param string      $mbid
111
     * @param string|null $username
112
     * @param bool        $autocorrect
113
     *
114
     * @throws ApiException
115
     * @throws NotFoundException
116
     *
117
     * @return SongInfo|null
118
     */
119
    public function getInfoByMBID(string $mbid, ?string $username = null, $autocorrect = false): ?SongInfo
120
    {
121
        $response = $this->unsignedCall('track.getInfo', [
122
            'mbid'        => $mbid,
123
            'autocorrect' => (int) $autocorrect,
124
            'username'    => $username,
125
        ]);
126
127
        if (!isset($response['track'])) {
128
            return null;
129
        }
130
131
        return SongInfo::fromApi($response['track']);
132
    }
133
134
    /**
135
     * Get the similar tracks for this track on Last.fm, based on listening data.
136
     *
137
     * @param string $artist
138
     * @param string $track
139
     * @param int    $limit
140
     * @param bool   $autocorrect
141
     *
142
     * @throws ApiException
143
     * @throws NotFoundException
144
     *
145
     * @return SongInfo[]
146
     */
147
    public function getSimilar(string $artist, string $track, int $limit = 10, bool $autocorrect = false): array
148
    {
149
        $response = $this->unsignedCall('track.getSimilar', [
150
            'artist'      => $artist,
151
            'track'       => $track,
152
            'limit'       => $limit,
153
            'autocorrect' => (int) $autocorrect,
154
        ]);
155
156
        if (!isset($response['similartracks']['track'])) {
157
            return [];
158
        }
159
160
        return array_map(function ($data) {
161
            return SongInfo::fromApi($data);
162
        }, $response['similartracks']['track']);
163
    }
164
165
    /**
166
     * Get the similar tracks for this track using the musicbrainz id on Last.fm, based on listening data.
167
     *
168
     * @param string $mbid
169
     * @param int    $limit
170
     * @param bool   $autocorrect
171
     *
172
     * @throws ApiException
173
     * @throws NotFoundException
174
     *
175
     * @return SongInfo[]
176
     */
177
    public function getSimilarByMBID(string $mbid, int $limit = 10, bool $autocorrect = false): array
178
    {
179
        $response = $this->unsignedCall('track.getSimilar', [
180
            'mbid'        => $mbid,
181
            'limit'       => $limit,
182
            'autocorrect' => (int) $autocorrect,
183
        ]);
184
185
        if (!isset($response['similartracks']['track'])) {
186
            return [];
187
        }
188
189
        return array_map(function ($data) {
190
            return SongInfo::fromApi($data);
191
        }, $response['similartracks']['track']);
192
    }
193
194
    /**
195
     * Get the tags applied by an individual user to a track on Last.fm.
196
     *
197
     * @param string $artist
198
     * @param string $track
199
     * @param string $username
200
     * @param bool   $autocorrect
201
     *
202
     * @throws ApiException
203
     * @throws NotFoundException
204
     *
205
     * @return Tag[]
206
     */
207
    public function getTags(string $artist, string $track, string $username, bool $autocorrect = false): array
208
    {
209
        $response = $this->unsignedCall('track.getTags', [
210
            'artist'      => $artist,
211
            'track'       => $track,
212
            'user'        => $username,
213
            'autocorrect' => (int) $autocorrect,
214
        ]);
215
216
        if (!isset($response['tags']['tag'])) {
217
            return [];
218
        }
219
220
        return array_map(function ($data) {
221
            return Tag::fromApi($data);
222
        }, $response['tags']['tag']);
223
    }
224
225
    /**
226
     * Get the tags applied by an individual user to a track using the musicbrainz id on Last.fm.
227
     *
228
     * @param string $mbid
229
     * @param string $username
230
     * @param bool   $autocorrect
231
     *
232
     * @throws ApiException
233
     * @throws NotFoundException
234
     *
235
     * @return Tag[]
236
     */
237
    public function getTagsByMBID(string $mbid, string $username, bool $autocorrect = false): array
238
    {
239
        $response = $this->unsignedCall('track.getTags', [
240
            'mbid'        => $mbid,
241
            'user'        => $username,
242
            'autocorrect' => (int) $autocorrect,
243
        ]);
244
245
        if (!isset($response['tags']['tag'])) {
246
            return [];
247
        }
248
249
        return array_map(function ($data) {
250
            return Tag::fromApi($data);
251
        }, $response['tags']['tag']);
252
    }
253
254
    /**
255
     * Get the top tags for this track on Last.fm, ordered by tag count.
256
     *
257
     * @param string $artist
258
     * @param string $track
259
     * @param bool   $autocorrect
260
     *
261
     * @throws ApiException
262
     * @throws NotFoundException
263
     *
264
     * @return Tag[]
265
     */
266
    public function getTopTags(string $artist, string $track, bool $autocorrect = false): array
267
    {
268
        $response = $this->unsignedCall('track.getTopTags', [
269
            'artist'      => $artist,
270
            'track'       => $track,
271
            'autocorrect' => (int) $autocorrect,
272
        ]);
273
274
        if (!isset($response['toptags']['tag'])) {
275
            return [];
276
        }
277
278
        return array_map(function ($data) {
279
            return Tag::fromApi($data);
280
        }, $response['toptags']['tag']);
281
    }
282
283
    /**
284
     * Get the top tags for this track using the musicbrainz id on Last.fm, ordered by tag count.
285
     *
286
     * @param string $bdid
287
     * @param bool   $autocorrect
288
     *
289
     * @throws ApiException
290
     * @throws NotFoundException
291
     *
292
     * @return Tag[]
293
     */
294
    public function getTopTagsByMBID(string $bdid, bool $autocorrect = false): array
295
    {
296
        $response = $this->unsignedCall('track.getTopTags', [
297
            'bdid'        => $bdid,
298
            'autocorrect' => (int) $autocorrect,
299
        ]);
300
301
        if (!isset($response['toptags']['tag'])) {
302
            return [];
303
        }
304
305
        return array_map(function ($data) {
306
            return Tag::fromApi($data);
307
        }, $response['toptags']['tag']);
308
    }
309
310
    /**
311
     * Love a track for a user profile.
312
     *
313
     * @param SessionInterface $session
314
     * @param string           $artist
315
     * @param string           $track
316
     *
317
     * @throws ApiException
318
     * @throws NotFoundException
319
     */
320
    public function love(SessionInterface $session, string $artist, string $track): void
321
    {
322
        $this->signedCall('track.love', [
323
            'artist' => $artist,
324
            'track'  => $track,
325
        ], $session, 'POST');
326
    }
327
328
    /**
329
     * Remove a user's tag from a track.
330
     *
331
     * @param SessionInterface $session
332
     * @param string           $artist
333
     * @param string           $track
334
     * @param string           $tag
335
     *
336
     * @throws ApiException
337
     * @throws NotFoundException
338
     */
339
    public function removeTag(SessionInterface $session, string $artist, string $track, string $tag): void
340
    {
341
        $this->signedCall('track.removeTag', [
342
            'artist' => $artist,
343
            'track'  => $track,
344
            'tag'    => $tag,
345
        ], $session, 'POST');
346
    }
347
348
    /**
349
     * Share a track twith one or more Last.fm users or other friends.
350
     *
351
     * @param SessionInterface $session
352
     * @param array            $tracks
353
     *
354
     * @throws ApiException
355
     * @throws NotFoundException
356
     */
357
    public function scrobble(SessionInterface $session, array $tracks): void
358
    {
359
        $count = \count($tracks);
360
361
        if (0 === $count) {
362
            return;
363
        }
364
        if ($count > 10) {
365
            throw new \InvalidArgumentException('A maximum of 50 tracks is allowed');
366
        }
367
368
        $data = self::buildTrackList($tracks);
369
370
        $this->signedCall('album.scrobble', $data, $session, 'POST');
371
    }
372
373
    /**
374
     * Search for a track by track name. Returns track matches sorted by relevance.
375
     *
376
     * @param string $track
377
     * @param int    $limit
378
     * @param int    $page
379
     *
380
     * @throws ApiException
381
     * @throws NotFoundException
382
     *
383
     * @return SongInfo[]
384
     */
385
    public function search(string $track, int $limit = 50, int $page = 1): array
386
    {
387
        $response = $this->unsignedCall('track.search', [
388
            'track' => $track,
389
            'limit' => $limit,
390
            'page'  => $page,
391
        ]);
392
393
        if (!isset($response['results']['trackmatches']['track'])) {
394
            return [];
395
        }
396
397
        return array_map(function ($data) {
398
            return SongInfo::fromApi($data);
399
        }, $response['results']['trackmatches']['track']);
400
    }
401
402
    /**
403
     * Unlove a track for a user profile.
404
     *
405
     * @param SessionInterface $session
406
     * @param string           $artist
407
     * @param string           $track
408
     *
409
     * @throws ApiException
410
     * @throws NotFoundException
411
     */
412
    public function unlove(SessionInterface $session, string $artist, string $track): void
413
    {
414
        $this->signedCall('track.love', [
415
            'artist' => $artist,
416
            'track'  => $track,
417
        ], $session, 'POST');
418
    }
419
420
    /**
421
     * Share a track twith one or more Last.fm users or other friends.
422
     *
423
     * @param SessionInterface $session
424
     * @param NowPlaying       $nowPlaying
425
     */
426
    public function updateNowPlaying(SessionInterface $session, NowPlaying $nowPlaying): void
427
    {
428
        $this->signedCall('track.updateNowPlaying', $nowPlaying->toArray(), $session, 'POST');
429
    }
430
431
    /**
432
     * @param array $tracks
433
     *
434
     * @return array
435
     */
436
    private static function buildTrackList(array $tracks): array
437
    {
438
        $data = [];
439
440
        $i = 0;
441
        foreach ($tracks as $track) {
442
            // Required fields
443
            foreach (['artist', 'track', 'timestamp'] as $field) {
444
                if (!\array_key_exists($field, $track)) {
445
                    throw new \InvalidArgumentException(sprintf('Field "%s" not set on entry %s', $field, $i));
446
                }
447
                $data[$field.'['.$i.']'] = $track[$field];
448
            }
449
450
            // Optional fields
451
            foreach (['album', 'context', 'streamId', 'chosenByUser', 'trackNumber', 'mbid', 'albumArtist', 'duration'] as $field) {
452
                if (\array_key_exists($field, $track)) {
453
                    $data[$field.'['.$i.']'] = $track[$field];
454
                }
455
            }
456
457
            ++$i;
458
        }
459
460
        return $data;
461
    }
462
}
463