mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2024-11-22 04:58:01 +01:00
#58: Implemented a more stable and useful track details endpoint.
This commit is contained in:
parent
29cd3de86e
commit
dba9ae1b15
5 changed files with 177 additions and 42 deletions
|
@ -2,7 +2,7 @@
|
|||
|
||||
/**
|
||||
* Pony.fm - A community for pony fan music.
|
||||
* Copyright (C) 2015 Peter Deltchev
|
||||
* Copyright (C) 2015-2017 Peter Deltchev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
|
@ -75,38 +75,59 @@ class TracksController extends ApiControllerBase
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stable representation of a track for the API. This is very
|
||||
* similar to the radio representation below but finds tracks by ID and is
|
||||
* expected to be more stable.
|
||||
*
|
||||
* @param int $id track ID
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function getTrackDetails($id) {
|
||||
/** @var Track|null $track */
|
||||
$track = Track
|
||||
::with('user', 'album', 'user.avatar', 'cover', 'genre')
|
||||
->published()
|
||||
->where('id', $id)->first();
|
||||
|
||||
if (!$track) {
|
||||
return Response::json(['message' => 'Track not found.'], 404);
|
||||
}
|
||||
|
||||
return Response::json(static::trackToJson($track, false, true), 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a serialized version of a track for use by radios.
|
||||
*
|
||||
* @deprecated in favour of getTrackDetails
|
||||
* @param $hash
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function getTrackRadioDetails($hash)
|
||||
{
|
||||
/** @var Track|null $track */
|
||||
$track = Track
|
||||
::with('user', 'album', 'user.avatar', 'cover', 'comments', 'genre')
|
||||
->published()
|
||||
->whereHash($hash)->first();
|
||||
->where('hash', $hash)->first();
|
||||
|
||||
if (!$track) {
|
||||
return Response::json(['message' => 'Track not found.'], 403);
|
||||
}
|
||||
|
||||
$comments = [];
|
||||
foreach ($track->comments as $comment) {
|
||||
$comments[] = [
|
||||
'id' => $comment->id,
|
||||
'created_at' => $comment->created_at,
|
||||
'content' => $comment->content,
|
||||
'user' => [
|
||||
'name' => $comment->user->display_name,
|
||||
'id' => $comment->user->id,
|
||||
'url' => $comment->user->url,
|
||||
'avatars' => [
|
||||
'normal' => $comment->user->getAvatarUrl(Image::NORMAL),
|
||||
'thumbnail' => $comment->user->getAvatarUrl(Image::THUMBNAIL),
|
||||
'small' => $comment->user->getAvatarUrl(Image::SMALL),
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
return Response::json(static::trackToJson($track, true, false), 200);
|
||||
}
|
||||
|
||||
return Response::json([
|
||||
/**
|
||||
* Helper method to form the serialized version of a track for the V1 API.
|
||||
*
|
||||
* @param Track $track
|
||||
* @param bool $includeComments if true, includes the track's comments in the serialization
|
||||
* @return array serialized track
|
||||
*/
|
||||
private static function trackToJson(Track $track, bool $includeComments, bool $includeStreamUrl) {
|
||||
$trackResponse = [
|
||||
'id' => $track->id,
|
||||
'title' => $track->title,
|
||||
'description' => $track->description,
|
||||
|
@ -141,19 +162,52 @@ class TracksController extends ApiControllerBase
|
|||
'name' => $track->genre->name
|
||||
] : null,
|
||||
'type' => [
|
||||
'id' => $track->track_type->id,
|
||||
'name' => $track->track_type->title
|
||||
'id' => $track->trackType->id,
|
||||
'name' => $track->trackType->title
|
||||
],
|
||||
'covers' => [
|
||||
'thumbnail' => $track->getCoverUrl(Image::THUMBNAIL),
|
||||
'small' => $track->getCoverUrl(Image::SMALL),
|
||||
'normal' => $track->getCoverUrl(Image::NORMAL)
|
||||
],
|
||||
'comments' => $comments,
|
||||
|
||||
// As of 2015-10-28, this should be expected to produce either
|
||||
// "direct_upload" or "mlpma" for all tracks.
|
||||
// As of 2017-10-28, this should be expected to produce
|
||||
// "direct_upload", "mlpma", or "eqbeats" for all tracks.
|
||||
'source' => $track->source
|
||||
], 200);
|
||||
];
|
||||
|
||||
if ($includeComments) {
|
||||
$comments = [];
|
||||
foreach ($track->comments as $comment) {
|
||||
$comments[] = [
|
||||
'id' => $comment->id,
|
||||
'created_at' => $comment->created_at,
|
||||
'content' => $comment->content,
|
||||
'user' => [
|
||||
'name' => $comment->user->display_name,
|
||||
'id' => $comment->user->id,
|
||||
'url' => $comment->user->url,
|
||||
'avatars' => [
|
||||
'normal' => $comment->user->getAvatarUrl(Image::NORMAL),
|
||||
'thumbnail' => $comment->user->getAvatarUrl(Image::THUMBNAIL),
|
||||
'small' => $comment->user->getAvatarUrl(Image::SMALL),
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
$trackResponse['comments'] = $comments;
|
||||
}
|
||||
|
||||
if ($includeStreamUrl) {
|
||||
$trackResponse['streams'] = [
|
||||
'mp3' => [
|
||||
'url' => $track->getStreamUrl('MP3', session('api_client_id')),
|
||||
'mime_type' => Track::$Formats['MP3']['mime_type'],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
return $trackResponse;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
/**
|
||||
* Pony.fm - A community for pony fan music.
|
||||
* Copyright (C) 2015 Peter Deltchev
|
||||
* Copyright (C) 2015-2017 Peter Deltchev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
|
@ -890,11 +890,19 @@ class Track extends Model implements Searchable, Commentable, Favouritable
|
|||
* be used by the on-site player.
|
||||
*
|
||||
* @param string $format one of the format keys from the `$Formats` array
|
||||
* @param string $apiClientId if a URL is being requested for the third-party
|
||||
* API, this should be set to the requesting app's
|
||||
* client ID.
|
||||
* @return string
|
||||
*/
|
||||
public function getStreamUrl($format = 'MP3')
|
||||
public function getStreamUrl(string $format = 'MP3', string $apiClientId = null)
|
||||
{
|
||||
return action('TracksController@getStream', ['id' => $this->id, 'extension' => self::$Formats[$format]['extension']]);
|
||||
return action('TracksController@getStream',
|
||||
[
|
||||
'id' => $this->id,
|
||||
'extension' => self::$Formats[$format]['extension']
|
||||
] + ($apiClientId !== null ? ['api_client_id' => $apiClientId] : [])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
/**
|
||||
* Pony.fm - A community for pony fan music.
|
||||
* Copyright (C) 2015 Peter Deltchev
|
||||
* Copyright (C) 2015-2017 Peter Deltchev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
|
@ -52,9 +52,8 @@ $factory->define(\Poniverse\Ponyfm\Models\Track::class, function(\Faker\Generato
|
|||
'user_id' => $user->id,
|
||||
'hash' => $faker->md5,
|
||||
'title' => $faker->sentence(5),
|
||||
'slug' => $faker->slug,
|
||||
'track_type_id' => \Poniverse\Ponyfm\Models\TrackType::UNCLASSIFIED_TRACK,
|
||||
'genre' => $faker->word,
|
||||
'album' => $faker->sentence(5),
|
||||
'track_number' => null,
|
||||
'description' => $faker->paragraph(5),
|
||||
'lyrics' => $faker->paragraph(5),
|
||||
|
@ -62,6 +61,39 @@ $factory->define(\Poniverse\Ponyfm\Models\Track::class, function(\Faker\Generato
|
|||
'is_explicit' => false,
|
||||
'is_downloadable' => true,
|
||||
'is_listed' => true,
|
||||
'metadata' => '{"this":{"is":["very","random","metadata"]}}'
|
||||
'metadata' => '{"this":{"is":["very","random","metadata"]}}',
|
||||
'duration' => $faker->randomFloat(null, 30, 600)
|
||||
];
|
||||
});
|
||||
|
||||
$factory->define(\Poniverse\Ponyfm\Models\Genre::class, function(\Faker\Generator $faker) {
|
||||
return [
|
||||
'name' => $faker->word,
|
||||
'slug' => $faker->slug,
|
||||
];
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
* @property integer $id
|
||||
* @property integer $user_id
|
||||
* @property string $title
|
||||
* @property string $slug
|
||||
* @property string $description
|
||||
* @property integer $cover_id
|
||||
* @property integer $track_count
|
||||
* @property integer $view_count
|
||||
* @property integer $download_count
|
||||
* @property integer $favourite_count
|
||||
* @property integer $comment_count
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property string $updated_at
|
||||
* @property \Carbon\Carbon $deleted_at
|
||||
*/
|
||||
$factory->define(\Poniverse\Ponyfm\Models\Album::class, function(\Faker\Generator $faker) {
|
||||
return [
|
||||
'title' => $faker->sentence(5),
|
||||
'slug' => $faker->slug,
|
||||
'description' => $faker->paragraph(5),
|
||||
];
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
/**
|
||||
* Pony.fm - A community for pony fan music.
|
||||
* Copyright (C) 2015 Peter Deltchev
|
||||
* Copyright (C) 2015-2017 Peter Deltchev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
|
@ -89,12 +89,13 @@ Route::group(['prefix' => 'notifications/email'], function() {
|
|||
Route::get('oembed', 'TracksController@getOembed');
|
||||
|
||||
Route::group(['prefix' => 'api/v1', 'middleware' => 'json-exceptions'], function () {
|
||||
Route::get('/tracks/radio-details/{hash}', 'Api\V1\TracksController@getTrackRadioDetails');
|
||||
Route::get( '/tracks/radio-details/{hash}', 'Api\V1\TracksController@getTrackRadioDetails');
|
||||
Route::post('/tracks/radio-details/{hash}', 'Api\V1\TracksController@getTrackRadioDetails');
|
||||
Route::get( '/tracks/{id}', 'Api\V1\TracksController@getTrackDetails')->where('id', '\d+');
|
||||
|
||||
Route::group(['middleware' => 'auth.oauth:ponyfm:tracks:upload'], function () {
|
||||
Route::post('tracks', 'Api\V1\TracksController@postUploadTrack');
|
||||
Route::get('/tracks/{id}/upload-status', 'Api\V1\TracksController@getUploadStatus');
|
||||
Route::get( '/tracks/{id}/upload-status', 'Api\V1\TracksController@getUploadStatus');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
/**
|
||||
* Pony.fm - A community for pony fan music.
|
||||
* Copyright (C) 2015 Peter Deltchev
|
||||
* Copyright (C) 2015-2017 Peter Deltchev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
|
@ -18,8 +18,11 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Foundation\Testing\WithoutMiddleware;
|
||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||
use Poniverse\Ponyfm\Models\Album;
|
||||
use Poniverse\Ponyfm\Models\Genre;
|
||||
use Poniverse\Ponyfm\Models\Track;
|
||||
use Poniverse\Ponyfm\Models\User;
|
||||
|
||||
|
@ -74,13 +77,18 @@ class ApiTest extends TestCase
|
|||
|
||||
public function testUploadWithOptionalData()
|
||||
{
|
||||
/** @var Track $track */
|
||||
$track = factory(Track::class)->make();
|
||||
/** @var Genre $genre */
|
||||
$genre = factory(Genre::class)->make();
|
||||
/** @var Album $album */
|
||||
$album = factory(Album::class)->make();
|
||||
|
||||
$this->callUploadWithParameters([
|
||||
'title' => $track->title,
|
||||
'track_type_id' => $track->track_type_id,
|
||||
'genre' => $track->genre,
|
||||
'album' => $track->album,
|
||||
'genre' => $genre->name,
|
||||
'album' => $album->title,
|
||||
'released_at' => \Carbon\Carbon::create(2015, 1, 1, 1, 1, 1)->toIso8601String(),
|
||||
'description' => $track->description,
|
||||
'lyrics' => $track->lyrics,
|
||||
|
@ -94,11 +102,11 @@ class ApiTest extends TestCase
|
|||
]);
|
||||
|
||||
$this->seeInDatabase('genres', [
|
||||
'name' => $track->genre
|
||||
'name' => $genre->name
|
||||
]);
|
||||
|
||||
$this->seeInDatabase('albums', [
|
||||
'title' => $track->album
|
||||
'title' => $album->title
|
||||
]);
|
||||
|
||||
$this->seeInDatabase('images', [
|
||||
|
@ -121,4 +129,36 @@ class ApiTest extends TestCase
|
|||
'metadata' => $track->metadata
|
||||
]);
|
||||
}
|
||||
|
||||
public function testGetTrackDetails()
|
||||
{
|
||||
/** @var Track $track */
|
||||
$track = factory(Track::class)->create();
|
||||
/** @var Genre $genre */
|
||||
$genre = factory(Genre::class)->create();
|
||||
|
||||
$track->genre()->associate($genre);
|
||||
$this->seeInDatabase('tracks', ['id' => $track->id]);
|
||||
|
||||
$track->published_at = Carbon::now();
|
||||
$track->save();
|
||||
|
||||
|
||||
$response = $this
|
||||
->withSession(['api_client_id' => 'ponyponyponyponypony'])
|
||||
->get("/api/v1/tracks/{$track->id}");
|
||||
|
||||
$response
|
||||
->assertResponseStatus(200)
|
||||
->seeJsonSubset([
|
||||
'title' => $track->title,
|
||||
'description' => $track->description,
|
||||
'streams' => [
|
||||
'mp3' => [
|
||||
'url' => $track->getStreamUrl('MP3', 'ponyponyponyponypony'),
|
||||
'mime_type' => Track::$Formats['MP3']['mime_type']
|
||||
]
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue