Add updateNowPlaying for Last.fm

This commit is contained in:
An Phan 2015-12-23 14:26:16 +08:00
parent 5e79a2737e
commit a083696289
8 changed files with 151 additions and 3 deletions

View file

@ -0,0 +1,45 @@
<?php
namespace App\Events;
use App\Models\Song;
use App\Models\User;
use Illuminate\Queue\SerializesModels;
class SongStartedPlaying extends Event
{
use SerializesModels;
/**
* The now playing song.
*
* @var Song
*/
public $song;
/**
* The user listening.
*
* @var User
*/
public $user;
/**
* Create a new event instance.
*/
public function __construct(Song $song, User $user)
{
$this->song = $song;
$this->user = $user;
}
/**
* Get the channels the event should be broadcast on.
*
* @return array
*/
public function broadcastOn()
{
return [];
}
}

View file

@ -2,6 +2,7 @@
namespace App\Http\Controllers\API;
use App\Events\SongStartedPlaying;
use App\Http\Requests\API\BatchInteractionRequest;
use App\Models\Interaction;
use Illuminate\Http\Request;
@ -17,7 +18,11 @@ class InteractionController extends Controller
*/
public function play(Request $request)
{
return response()->json(Interaction::increasePlayCount($request->input('id'), $request->user()));
if ($interaction = Interaction::increasePlayCount($request->input('id'), $request->user())) {
event(new SongStartedPlaying($interaction->song, $interaction->user));
}
return response()->json($interaction);
}
/**

View file

@ -0,0 +1,48 @@
<?php
namespace App\Listeners;
use App\Events\SongStartedPlaying;
use App\Models\Album;
use App\Services\Lastfm;
class UpdateLastfmNowPlaying
{
/**
* The Last.fm service instance.
*
* @var Lastfm
*/
protected $lastfm;
/**
* Create the event listener.
*/
public function __construct(Lastfm $lastfm)
{
$this->lastfm = $lastfm;
}
/**
* Handle the event.
*
* @param SongStartedPlaying $event
*/
public function handle(SongStartedPlaying $event)
{
if (!$this->lastfm->enabled() ||
!($sessionKey = $event->user->getLastfmSessionKey()) ||
$event->song->album->artist->isUnknown()
) {
return;
}
$this->lastfm->updateNowPlaying(
$event->song->album->artist->name,
$event->song->title,
$event->song->album->name === Album::UNKNOWN_NAME ? null : $event->song->album->name,
$event->song->length,
$sessionKey
);
}
}

View file

@ -19,6 +19,9 @@ class EventServiceProvider extends ServiceProvider
'App\Events\SongLikeToggled' => [
'App\Listeners\LoveTrackOnLastfm',
],
'App\Events\SongStartedPlaying' => [
'App\Listeners\UpdateLastfmNowPlaying',
],
];
/**

View file

@ -233,6 +233,35 @@ class Lastfm extends RESTfulService
}
}
/**
* Update a track's "now playing" on Last.fm.
*
* @param string $artist Name of the artist
* @param string $track Name of the track
* @param string $album Name of the album
* @param int|float $duration Duration of the track, in seconds
* @param string $sk The session key
*
* @return bool
*/
public function updateNowPlaying($artist, $track, $album, $duration, $sk)
{
$params = compact('artist', 'track', 'duration', 'sk');
$params['method'] = 'track.updateNowPlaying';
if ($album) {
$params['album'] = $album;
}
try {
return (bool) $this->post('/', $this->buildAuthCallParams($params), false);
} catch (\Exception $e) {
Log::error($e);
return false;
}
}
/**
* Build the parameters to use for _authenticated_ Last.fm API calls.
* Such calls require:

View file

@ -93,7 +93,7 @@ export default {
this.player.source(`/api/${song.id}/play`);
this.player.play();
// Register the play count to the server
// Register the play to the server
songStore.registerPlay(song);
// Show the notification if we're allowed to

View file

@ -20,6 +20,7 @@ class InteractionTest extends TestCase
public function testPlayCountRegister()
{
$this->withoutEvents();
$user = factory(User::class)->create();
$song = Song::orderBy('id')->first();

View file

@ -1,8 +1,10 @@
<?php
use App\Events\SongLikeToggled;
use App\Events\SongStartedPlaying;
use App\Http\Controllers\API\LastfmController;
use App\Listeners\LoveTrackOnLastfm;
use App\Listeners\UpdateLastfmNowPlaying;
use App\Models\Interaction;
use App\Models\Song;
use App\Models\User;
@ -170,8 +172,23 @@ class LastfmTest extends TestCase
$lastfm = m::mock(Lastfm::class, ['enabled' => true]);
$lastfm->shouldReceive('toggleLoveTrack')
->withArgs([$interaction->song->title, $interaction->song->album->artist->name, 'bar', false]);
->with($interaction->song->title, $interaction->song->album->artist->name, 'bar', false);
(new LoveTrackOnLastfm($lastfm))->handle(new SongLikeToggled($interaction, $user));
}
public function testUpdateNowPlaying()
{
$this->withoutEvents();
$this->createSampleMediaSet();
$user = factory(User::class)->create(['preferences' => ['lastfm_session_key' => 'bar']]);
$song = Song::first();
$lastfm = m::mock(Lastfm::class, ['enabled' => true]);
$lastfm->shouldReceive('updateNowPlaying')
->with($song->album->artist->name, $song->title, $song->album->name, $song->length, 'bar');
(new UpdateLastfmNowPlaying($lastfm))->handle(new SongStartedPlaying($song, $user));
}
}