mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2025-01-31 03:16:42 +01:00
Finished basic stats for tracks, playlists and albums
Finished downloading for albums and playlists
This commit is contained in:
parent
2046b8e98d
commit
1c4bc006b7
9 changed files with 201 additions and 58 deletions
|
@ -10,6 +10,7 @@
|
||||||
use Entities\Comment;
|
use Entities\Comment;
|
||||||
use Entities\Image;
|
use Entities\Image;
|
||||||
use Entities\Playlist;
|
use Entities\Playlist;
|
||||||
|
use Entities\ResourceLogItem;
|
||||||
use Entities\Track;
|
use Entities\Track;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Input;
|
use Illuminate\Support\Facades\Input;
|
||||||
|
@ -33,64 +34,38 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getShow($id) {
|
public function getShow($id) {
|
||||||
$playlist = Playlist::with(['tracks' => function($query) { $query->details(); }, 'comments' => function($query) { $query->with('user'); }])->find($id);
|
$playlist = Playlist::with(['tracks.user', 'tracks' => function($query) { $query->details(); }, 'comments', 'comments.user'])->details()->find($id);
|
||||||
if (!$playlist || !$playlist->canView(Auth::user()))
|
if (!$playlist || !$playlist->canView(Auth::user()))
|
||||||
App::abort('404');
|
App::abort('404');
|
||||||
|
|
||||||
$tracks = [];
|
if (Input::get('log')) {
|
||||||
foreach ($playlist->tracks as $track) {
|
ResourceLogItem::logItem('playlist', $id, ResourceLogItem::VIEW);
|
||||||
$tracks[] = Track::mapPublicTrackSummary($track);
|
$playlist->view_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
$comments = [];
|
return Response::json(Playlist::mapPublicPlaylistShow($playlist), 200);
|
||||||
foreach ($playlist->comments as $comment) {
|
|
||||||
$comments[] = Comment::mapPublic($comment);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Response::json([
|
|
||||||
'id' => $playlist->id,
|
|
||||||
'title' => $playlist->title,
|
|
||||||
'description' => $playlist->description,
|
|
||||||
'slug' => $playlist->slug,
|
|
||||||
'created_at' => $playlist->created_at,
|
|
||||||
'url' => $playlist->url,
|
|
||||||
'covers' => [
|
|
||||||
'small' => $playlist->getCoverUrl(Image::SMALL),
|
|
||||||
'normal' => $playlist->getCoverUrl(Image::NORMAL)
|
|
||||||
],
|
|
||||||
'is_pinned' => true,
|
|
||||||
'is_public' => $playlist->is_public == 1,
|
|
||||||
'tracks' => $tracks,
|
|
||||||
'comments' => ['count' => count($comments), 'list' => $comments],
|
|
||||||
], 200);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPinned() {
|
public function getPinned() {
|
||||||
$query = Playlist::join('pinned_playlists', function($join) {
|
$query = Playlist
|
||||||
|
::with(['tracks.user', 'tracks' => function($query) {}, 'comments', 'comments.user'])
|
||||||
|
->details()
|
||||||
|
->join('pinned_playlists', function($join) {
|
||||||
$join->on('playlist_id', '=', 'playlists.id');
|
$join->on('playlist_id', '=', 'playlists.id');
|
||||||
})
|
})
|
||||||
->where('pinned_playlists.user_id', '=', Auth::user()->id)
|
->where('pinned_playlists.user_id', '=', Auth::user()->id)
|
||||||
->orderBy('title', 'asc')
|
->orderBy('title', 'asc')
|
||||||
->select('playlists.id', 'playlists.title', 'playlists.slug', 'playlists.created_at', 'playlists.user_id', 'playlists.is_public', 'playlists.description')
|
->select('playlists.*')
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
$playlists = [];
|
$playlists = [];
|
||||||
foreach ($query as $playlist) {
|
foreach ($query as $playlist) {
|
||||||
$playlists[] = [
|
$mapped = Playlist::mapPublicPlaylistSummary($playlist);
|
||||||
'id' => $playlist->id,
|
$mapped['description'] = $playlist->description;
|
||||||
'title' => $playlist->title,
|
$mapped['is_pinned'] = true;
|
||||||
'description' => $playlist->description,
|
$playlists[] = $mapped;
|
||||||
'slug' => $playlist->slug,
|
|
||||||
'created_at' => $playlist->created_at,
|
|
||||||
'url' => $playlist->url,
|
|
||||||
'covers' => [
|
|
||||||
'small' => $playlist->getCoverUrl(Image::SMALL),
|
|
||||||
'normal' => $playlist->getCoverUrl(Image::NORMAL)
|
|
||||||
],
|
|
||||||
'is_pinned' => true,
|
|
||||||
'is_public' => $playlist->is_public == 1
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response::json($playlists, 200);
|
return Response::json($playlists, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Entities\Playlist;
|
use Entities\Playlist;
|
||||||
|
use Entities\ResourceLogItem;
|
||||||
|
use Entities\Track;
|
||||||
use Illuminate\Support\Facades\Redirect;
|
use Illuminate\Support\Facades\Redirect;
|
||||||
|
|
||||||
class PlaylistsController extends Controller {
|
class PlaylistsController extends Controller {
|
||||||
|
@ -26,4 +28,28 @@
|
||||||
|
|
||||||
return Redirect::action('PlaylistsController@getPlaylist', [$id, $playlist->slug]);
|
return Redirect::action('PlaylistsController@getPlaylist', [$id, $playlist->slug]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getDownload($id, $extension) {
|
||||||
|
$playlist = Playlist::with('tracks', 'user', 'tracks.album')->find($id);
|
||||||
|
if (!$playlist || !$playlist->is_public)
|
||||||
|
App::abort(404);
|
||||||
|
|
||||||
|
$format = null;
|
||||||
|
$formatName = null;
|
||||||
|
|
||||||
|
foreach (Track::$Formats as $name => $item) {
|
||||||
|
if ($item['extension'] == $extension) {
|
||||||
|
$format = $item;
|
||||||
|
$formatName = $name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($format == null)
|
||||||
|
App::abort(404);
|
||||||
|
|
||||||
|
ResourceLogItem::logItem('playlist', $id, ResourceLogItem::DOWNLOAD, $format['index']);
|
||||||
|
$downloader = new PlaylistDownloader($playlist, $formatName);
|
||||||
|
$downloader->download();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -106,7 +106,7 @@
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => $album->id,
|
'id' => $album->id,
|
||||||
'track_count' => $album->tracks->count(),
|
'track_count' => $album->tracks()->count(),
|
||||||
'title' => $album->title,
|
'title' => $album->title,
|
||||||
'slug' => $album->slug,
|
'slug' => $album->slug,
|
||||||
'created_at' => $album->created_at,
|
'created_at' => $album->created_at,
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Entities;
|
namespace Entities;
|
||||||
|
use Helpers;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Support\Facades\URL;
|
||||||
use Traits\SlugTrait;
|
use Traits\SlugTrait;
|
||||||
|
|
||||||
class Playlist extends \Eloquent {
|
class Playlist extends \Eloquent {
|
||||||
|
@ -10,7 +14,93 @@
|
||||||
use SlugTrait;
|
use SlugTrait;
|
||||||
|
|
||||||
public static function summary() {
|
public static function summary() {
|
||||||
return self::select('id', 'title', 'user_id', 'slug', 'created_at', 'is_public', 'description');
|
return self::select('id', 'title', 'user_id', 'slug', 'created_at', 'is_public', 'description', 'comment_count', 'download_count', 'view_count', 'favourite_count');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scopeDetails($query) {
|
||||||
|
if (Auth::check()) {
|
||||||
|
$query->with(['users' => function($query) {
|
||||||
|
$query->whereUserId(Auth::user()->id);
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !$query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function mapPublicPlaylistShow($playlist) {
|
||||||
|
$tracks = [];
|
||||||
|
foreach ($playlist->tracks as $track) {
|
||||||
|
$tracks[] = Track::mapPublicTrackSummary($track);
|
||||||
|
}
|
||||||
|
|
||||||
|
$formats = [];
|
||||||
|
foreach (Track::$Formats as $name => $format) {
|
||||||
|
$formats[] = [
|
||||||
|
'name' => $name,
|
||||||
|
'extension' => $format['extension'],
|
||||||
|
'url' => $playlist->getDownloadUrl($name),
|
||||||
|
'size' => Helpers::formatBytes($playlist->getFilesize($name))
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$comments = [];
|
||||||
|
foreach ($playlist->comments as $comment) {
|
||||||
|
$comments[] = Comment::mapPublic($comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = self::mapPublicPlaylistSummary($playlist);
|
||||||
|
$data['tracks'] = $tracks;
|
||||||
|
$data['comments'] = $comments;
|
||||||
|
$data['formats'] = $formats;
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function mapPublicPlaylistSummary($playlist) {
|
||||||
|
$userData = [
|
||||||
|
'stats' => [
|
||||||
|
'views' => 0,
|
||||||
|
'downloads' => 0
|
||||||
|
],
|
||||||
|
'is_favourited' => false
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($playlist->users->count()) {
|
||||||
|
$userRow = $playlist->users[0];
|
||||||
|
$userData = [
|
||||||
|
'stats' => [
|
||||||
|
'views' => $userRow->view_count,
|
||||||
|
'downloads' => $userRow->download_count,
|
||||||
|
],
|
||||||
|
'is_favourited' => $userRow->is_favourited
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'id' => $playlist->id,
|
||||||
|
'track_count' => $playlist->tracks->count(),
|
||||||
|
'title' => $playlist->title,
|
||||||
|
'slug' => $playlist->slug,
|
||||||
|
'created_at' => $playlist->created_at,
|
||||||
|
'is_public' => $playlist->is_public,
|
||||||
|
'stats' => [
|
||||||
|
'views' => $playlist->view_count,
|
||||||
|
'downloads' => $playlist->download_count,
|
||||||
|
'comments' => $playlist->comment_count,
|
||||||
|
'favourites' => $playlist->favourite_count
|
||||||
|
],
|
||||||
|
'covers' => [
|
||||||
|
'small' => $playlist->getCoverUrl(Image::SMALL),
|
||||||
|
'normal' => $playlist->getCoverUrl(Image::NORMAL)
|
||||||
|
],
|
||||||
|
'url' => $playlist->url,
|
||||||
|
'user' => [
|
||||||
|
'id' => $playlist->user->id,
|
||||||
|
'name' => $playlist->user->display_name,
|
||||||
|
'url' => $playlist->user->url,
|
||||||
|
],
|
||||||
|
'user_data' => $userData
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tracks() {
|
public function tracks() {
|
||||||
|
@ -21,6 +111,10 @@
|
||||||
->orderBy('position', 'asc');
|
->orderBy('position', 'asc');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function users() {
|
||||||
|
return $this->hasMany('Entities\ResourceUser');
|
||||||
|
}
|
||||||
|
|
||||||
public function comments(){
|
public function comments(){
|
||||||
return $this->hasMany('Entities\Comment');
|
return $this->hasMany('Entities\Comment');
|
||||||
}
|
}
|
||||||
|
@ -47,7 +141,26 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUrlAttribute() {
|
public function getUrlAttribute() {
|
||||||
return '/playlist/' . $this->id . '-' . $this->slug;
|
return URL::to('/playlist/' . $this->id . '-' . $this->slug);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDownloadUrl($format) {
|
||||||
|
return URL::to('p' . $this->id . '/dl.' . Track::$Formats[$format]['extension']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFilesize($format) {
|
||||||
|
$tracks = $this->tracks()->get();
|
||||||
|
if (!count($tracks))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return Cache::remember($this->getCacheKey('filesize-' . $format), 1440, function() use ($tracks, $format) {
|
||||||
|
$size = 0;
|
||||||
|
foreach ($tracks as $track) {
|
||||||
|
$size += $track->getFilesize($format);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $size;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCoverUrl($type = Image::NORMAL) {
|
public function getCoverUrl($type = Image::NORMAL) {
|
||||||
|
@ -63,4 +176,8 @@
|
||||||
$pin->user_id = $userId;
|
$pin->user_id = $userId;
|
||||||
$pin->save();
|
$pin->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getCacheKey($key) {
|
||||||
|
return 'album-' . $this->id . '-' . $key;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -245,6 +245,14 @@
|
||||||
return URL::to('/tracks/' . $this->id . '-' . $this->slug);
|
return URL::to('/tracks/' . $this->id . '-' . $this->slug);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getDownloadDirectoryAttribute() {
|
||||||
|
if ($this->album) {
|
||||||
|
return $this->user->display_name . '/' . $this->album->title;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->user->display_name;
|
||||||
|
}
|
||||||
|
|
||||||
public function getReleaseDate() {
|
public function getReleaseDate() {
|
||||||
if($this->attributes['released_at'] !== NULL)
|
if($this->attributes['released_at'] !== NULL)
|
||||||
return $this->attributes['released_at'];
|
return $this->attributes['released_at'];
|
||||||
|
@ -281,7 +289,7 @@
|
||||||
return $this->cover->getUrl($type);
|
return $this->cover->getUrl($type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getStreamUrl($format) {
|
public function getStreamUrl() {
|
||||||
return URL::to('/t' . $this->id . '/stream');
|
return URL::to('/t' . $this->id . '/stream');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,17 +12,15 @@
|
||||||
function download() {
|
function download() {
|
||||||
$zip = new ZipStream($this->_playlist->user->display_name . ' - ' . $this->_playlist->title . '.zip');
|
$zip = new ZipStream($this->_playlist->user->display_name . ' - ' . $this->_playlist->title . '.zip');
|
||||||
$zip->setComment(
|
$zip->setComment(
|
||||||
'Album: ' . $this->_playlist->title ."\r\n".
|
'Playlist: '. $this->_playlist->title ."\r\n".
|
||||||
'Artist: ' . $this->_playlist->user->display_name ."\r\n".
|
'Curator: ' . $this->_playlist->user->display_name ."\r\n".
|
||||||
'URL: ' . $this->_playlist->url ."\r\n"."\r\n".
|
'URL: ' . $this->_playlist->url ."\r\n"."\r\n".
|
||||||
'Downloaded on '. date('l, F jS, Y, \a\t h:i:s A') . '.'
|
'Downloaded on '. date('l, F jS, Y, \a\t h:i:s A') . '.'
|
||||||
);
|
);
|
||||||
|
|
||||||
$directory = $this->_playlist->user->display_name . '/' . $this->_playlist->title . '/';
|
|
||||||
|
|
||||||
$notes =
|
$notes =
|
||||||
'Album: ' . $this->_playlist->title ."\r\n".
|
'Playlist: '. $this->_playlist->title ."\r\n".
|
||||||
'Artist: ' . $this->_playlist->user->display_name ."\r\n".
|
'Curator: ' . $this->_playlist->user->display_name ."\r\n".
|
||||||
'URL: ' . $this->_playlist->url ."\r\n".
|
'URL: ' . $this->_playlist->url ."\r\n".
|
||||||
"\r\n".
|
"\r\n".
|
||||||
$this->_playlist->description ."\r\n".
|
$this->_playlist->description ."\r\n".
|
||||||
|
@ -31,18 +29,28 @@
|
||||||
'Tracks' ."\r\n".
|
'Tracks' ."\r\n".
|
||||||
"\r\n";
|
"\r\n";
|
||||||
|
|
||||||
|
$m3u = '';
|
||||||
|
$index = 1;
|
||||||
foreach ($this->_playlist->tracks as $track) {
|
foreach ($this->_playlist->tracks as $track) {
|
||||||
if (!$track->is_downloadable)
|
if (!$track->is_downloadable)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
$zip->addLargeFile($track->getFileFor($this->_format), $directory . $track->getDownloadFilenameFor($this->_format));
|
$trackTarget = $track->downloadDirectory . '/' . $track->getDownloadFilenameFor($this->_format);
|
||||||
|
$zip->addLargeFile($track->getFileFor($this->_format), $trackTarget);
|
||||||
$notes .=
|
$notes .=
|
||||||
$track->track_number . '. ' . $track->title ."\r\n".
|
$index . '. ' . $track->title ."\r\n".
|
||||||
$track->description ."\r\n".
|
$track->description ."\r\n".
|
||||||
"\r\n";
|
"\r\n";
|
||||||
|
|
||||||
|
$m3u .= '#EXTINF:' . $track->duration . ',' . $track->title . "\r\n";
|
||||||
|
$m3u .= '../' . $trackTarget . "\r\n";
|
||||||
|
|
||||||
|
$index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
$zip->addFile($notes, $directory . 'Album Notes.txt');
|
$playlistDir = 'Pony.fm Playlists/';
|
||||||
|
$zip->addFile($notes, $playlistDir . $this->_playlist->title . '.txt');
|
||||||
|
$zip->addFile($m3u, $playlistDir . $this->_playlist->title . '.m3u');
|
||||||
$zip->finalize();
|
$zip->finalize();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -41,6 +41,7 @@
|
||||||
|
|
||||||
Route::get('playlist/{id}-{slug}', 'PlaylistsController@getPlaylist');
|
Route::get('playlist/{id}-{slug}', 'PlaylistsController@getPlaylist');
|
||||||
Route::get('p{id}', 'PlaylistsController@getShortlink')->where('id', '\d+');
|
Route::get('p{id}', 'PlaylistsController@getShortlink')->where('id', '\d+');
|
||||||
|
Route::get('p{id}/dl.{extension}', 'PlaylistsController@getDownload' );
|
||||||
|
|
||||||
Route::group(['prefix' => 'api/web'], function() {
|
Route::group(['prefix' => 'api/web'], function() {
|
||||||
Route::get('/taxonomies/all', 'Api\Web\TaxonomiesController@getAll');
|
Route::get('/taxonomies/all', 'Api\Web\TaxonomiesController@getAll');
|
||||||
|
|
|
@ -11,7 +11,7 @@ angular.module('ponyfm').factory('playlists', [
|
||||||
force = force || false
|
force = force || false
|
||||||
return playlists[id] if !force && playlists[id]
|
return playlists[id] if !force && playlists[id]
|
||||||
def = new $.Deferred()
|
def = new $.Deferred()
|
||||||
$http.get('/api/web/playlists/' + id).success (playlist) ->
|
$http.get('/api/web/playlists/' + id + '?log=true').success (playlist) ->
|
||||||
def.resolve playlist
|
def.resolve playlist
|
||||||
|
|
||||||
playlists[id] = def.promise()
|
playlists[id] = def.promise()
|
||||||
|
|
|
@ -5,12 +5,13 @@
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="track-toolbar btn-group pull-right">
|
<div class="track-toolbar btn-group pull-right">
|
||||||
|
<pfm-favourite-button resource="playlist" type="playlist"></pfm-favourite-button>
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<a href="#" class="btn btn-small btn-info dropdown-toggle">
|
<a href="#" class="btn btn-small btn-info dropdown-toggle">
|
||||||
Downloads <i class="caret"></i>
|
Downloads <i class="caret"></i>
|
||||||
</a>
|
</a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li ng-repeat="format in playlist.formats"><a href="{{format.url}}">{{format.name}}</a></li>
|
<li ng-repeat="format in playlist.formats"><a target="_blank" href="{{format.url}}">{{format.name}} <small>({{format.size}})</small></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -38,6 +39,13 @@
|
||||||
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
|
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
|
||||||
|
|
||||||
<a href="#" class="btn btn-info">Share or Embed</a>
|
<a href="#" class="btn btn-info">Share or Embed</a>
|
||||||
|
|
||||||
|
<h2>Stats</h2>
|
||||||
|
<ul class="stats">
|
||||||
|
<li>Views: <strong>{{playlist.stats.views}}</strong></li>
|
||||||
|
<li>Downloads: <strong>{{playlist.stats.downloads}}</strong></li>
|
||||||
|
<li>Favourites: <strong>{{playlist.stats.favourites}}</strong></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue