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\Image;
|
||||
use Entities\Playlist;
|
||||
use Entities\ResourceLogItem;
|
||||
use Entities\Track;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
|
@ -33,64 +34,38 @@
|
|||
}
|
||||
|
||||
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()))
|
||||
App::abort('404');
|
||||
|
||||
$tracks = [];
|
||||
foreach ($playlist->tracks as $track) {
|
||||
$tracks[] = Track::mapPublicTrackSummary($track);
|
||||
if (Input::get('log')) {
|
||||
ResourceLogItem::logItem('playlist', $id, ResourceLogItem::VIEW);
|
||||
$playlist->view_count++;
|
||||
}
|
||||
|
||||
$comments = [];
|
||||
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);
|
||||
return Response::json(Playlist::mapPublicPlaylistShow($playlist), 200);
|
||||
}
|
||||
|
||||
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');
|
||||
})
|
||||
->where('pinned_playlists.user_id', '=', Auth::user()->id)
|
||||
->orderBy('title', 'asc')
|
||||
->select('playlists.id', 'playlists.title', 'playlists.slug', 'playlists.created_at', 'playlists.user_id', 'playlists.is_public', 'playlists.description')
|
||||
->select('playlists.*')
|
||||
->get();
|
||||
|
||||
$playlists = [];
|
||||
foreach ($query as $playlist) {
|
||||
$playlists[] = [
|
||||
'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
|
||||
];
|
||||
$mapped = Playlist::mapPublicPlaylistSummary($playlist);
|
||||
$mapped['description'] = $playlist->description;
|
||||
$mapped['is_pinned'] = true;
|
||||
$playlists[] = $mapped;
|
||||
}
|
||||
|
||||
return Response::json($playlists, 200);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
|
||||
use Entities\Playlist;
|
||||
use Entities\ResourceLogItem;
|
||||
use Entities\Track;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
|
||||
class PlaylistsController extends Controller {
|
||||
|
@ -26,4 +28,28 @@
|
|||
|
||||
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 [
|
||||
'id' => $album->id,
|
||||
'track_count' => $album->tracks->count(),
|
||||
'track_count' => $album->tracks()->count(),
|
||||
'title' => $album->title,
|
||||
'slug' => $album->slug,
|
||||
'created_at' => $album->created_at,
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Entities;
|
||||
use Helpers;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Traits\SlugTrait;
|
||||
|
||||
class Playlist extends \Eloquent {
|
||||
|
@ -10,7 +14,93 @@
|
|||
use SlugTrait;
|
||||
|
||||
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() {
|
||||
|
@ -21,6 +111,10 @@
|
|||
->orderBy('position', 'asc');
|
||||
}
|
||||
|
||||
public function users() {
|
||||
return $this->hasMany('Entities\ResourceUser');
|
||||
}
|
||||
|
||||
public function comments(){
|
||||
return $this->hasMany('Entities\Comment');
|
||||
}
|
||||
|
@ -47,7 +141,26 @@
|
|||
}
|
||||
|
||||
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) {
|
||||
|
@ -63,4 +176,8 @@
|
|||
$pin->user_id = $userId;
|
||||
$pin->save();
|
||||
}
|
||||
|
||||
private function getCacheKey($key) {
|
||||
return 'album-' . $this->id . '-' . $key;
|
||||
}
|
||||
}
|
|
@ -245,6 +245,14 @@
|
|||
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() {
|
||||
if($this->attributes['released_at'] !== NULL)
|
||||
return $this->attributes['released_at'];
|
||||
|
@ -281,7 +289,7 @@
|
|||
return $this->cover->getUrl($type);
|
||||
}
|
||||
|
||||
public function getStreamUrl($format) {
|
||||
public function getStreamUrl() {
|
||||
return URL::to('/t' . $this->id . '/stream');
|
||||
}
|
||||
|
||||
|
|
|
@ -12,17 +12,15 @@
|
|||
function download() {
|
||||
$zip = new ZipStream($this->_playlist->user->display_name . ' - ' . $this->_playlist->title . '.zip');
|
||||
$zip->setComment(
|
||||
'Album: ' . $this->_playlist->title ."\r\n".
|
||||
'Artist: ' . $this->_playlist->user->display_name ."\r\n".
|
||||
'Playlist: '. $this->_playlist->title ."\r\n".
|
||||
'Curator: ' . $this->_playlist->user->display_name ."\r\n".
|
||||
'URL: ' . $this->_playlist->url ."\r\n"."\r\n".
|
||||
'Downloaded on '. date('l, F jS, Y, \a\t h:i:s A') . '.'
|
||||
);
|
||||
|
||||
$directory = $this->_playlist->user->display_name . '/' . $this->_playlist->title . '/';
|
||||
|
||||
$notes =
|
||||
'Album: ' . $this->_playlist->title ."\r\n".
|
||||
'Artist: ' . $this->_playlist->user->display_name ."\r\n".
|
||||
'Playlist: '. $this->_playlist->title ."\r\n".
|
||||
'Curator: ' . $this->_playlist->user->display_name ."\r\n".
|
||||
'URL: ' . $this->_playlist->url ."\r\n".
|
||||
"\r\n".
|
||||
$this->_playlist->description ."\r\n".
|
||||
|
@ -31,18 +29,28 @@
|
|||
'Tracks' ."\r\n".
|
||||
"\r\n";
|
||||
|
||||
$m3u = '';
|
||||
$index = 1;
|
||||
foreach ($this->_playlist->tracks as $track) {
|
||||
if (!$track->is_downloadable)
|
||||
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 .=
|
||||
$track->track_number . '. ' . $track->title ."\r\n".
|
||||
$index . '. ' . $track->title ."\r\n".
|
||||
$track->description ."\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();
|
||||
}
|
||||
}
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
Route::get('playlist/{id}-{slug}', 'PlaylistsController@getPlaylist');
|
||||
Route::get('p{id}', 'PlaylistsController@getShortlink')->where('id', '\d+');
|
||||
Route::get('p{id}/dl.{extension}', 'PlaylistsController@getDownload' );
|
||||
|
||||
Route::group(['prefix' => 'api/web'], function() {
|
||||
Route::get('/taxonomies/all', 'Api\Web\TaxonomiesController@getAll');
|
||||
|
|
|
@ -11,7 +11,7 @@ angular.module('ponyfm').factory('playlists', [
|
|||
force = force || false
|
||||
return playlists[id] if !force && playlists[id]
|
||||
def = new $.Deferred()
|
||||
$http.get('/api/web/playlists/' + id).success (playlist) ->
|
||||
$http.get('/api/web/playlists/' + id + '?log=true').success (playlist) ->
|
||||
def.resolve playlist
|
||||
|
||||
playlists[id] = def.promise()
|
||||
|
|
|
@ -5,12 +5,13 @@
|
|||
</ul>
|
||||
|
||||
<div class="track-toolbar btn-group pull-right">
|
||||
<pfm-favourite-button resource="playlist" type="playlist"></pfm-favourite-button>
|
||||
<div class="dropdown">
|
||||
<a href="#" class="btn btn-small btn-info dropdown-toggle">
|
||||
Downloads <i class="caret"></i>
|
||||
</a>
|
||||
<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>
|
||||
</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>
|
||||
|
||||
<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>
|
||||
|
|
Loading…
Reference in a new issue