From 70dccafa9c6a6e7bb68b87b5c9cddbcc8b189ea2 Mon Sep 17 00:00:00 2001 From: nelsonlaquet Date: Wed, 31 Jul 2013 21:01:41 -0500 Subject: [PATCH] Albums and artists --- app/controllers/AlbumsController.php | 21 ++++ app/controllers/Api/Web/AlbumsController.php | 87 +++++++++++++++++ app/controllers/Api/Web/ArtistsController.php | 69 +++++++++++++ app/controllers/ArtistsController.php | 18 ++++ app/library/Helpers.php | 15 +++ app/models/Entities/Album.php | 9 ++ app/models/Entities/Track.php | 38 ++++++++ app/routes.php | 26 +++-- app/views/albums/show.blade.php | 6 ++ app/views/artists/profile.blade.php | 6 ++ app/views/shared/_app_layout.blade.php | 15 ++- public/scripts/app/app.coffee | 25 +++++ public/scripts/app/controllers/album.coffee | 18 ++++ .../app/controllers/albums-list.coffee | 12 +++ public/scripts/app/controllers/albums.coffee | 21 ++++ public/scripts/app/controllers/artist.coffee | 12 +++ .../app/controllers/artists-list.coffee | 12 +++ public/scripts/app/controllers/artists.coffee | 21 ++++ public/scripts/app/controllers/track.coffee | 16 ++- public/scripts/app/services/albums.coffee | 32 ++++++ public/scripts/app/services/artists.coffee | 32 ++++++ public/scripts/shared/layout.coffee | 6 ++ public/styles/albums.less | 97 +++++++++++++++++++ public/styles/app.less | 1 + public/styles/tracks.less | 68 ++++++++++++- public/templates/albums/index.html | 12 +++ public/templates/albums/list.html | 14 +++ public/templates/albums/show.html | 88 +++++++++++++++++ public/templates/artists/index.html | 14 ++- public/templates/artists/list.html | 14 +++ public/templates/artists/show.html | 8 ++ public/templates/tracks/show.html | 55 +++++++++-- 32 files changed, 860 insertions(+), 28 deletions(-) create mode 100644 app/controllers/Api/Web/ArtistsController.php create mode 100644 app/views/albums/show.blade.php create mode 100644 app/views/artists/profile.blade.php create mode 100644 public/scripts/app/controllers/album.coffee create mode 100644 public/scripts/app/controllers/albums-list.coffee create mode 100644 public/scripts/app/controllers/albums.coffee create mode 100644 public/scripts/app/controllers/artist.coffee create mode 100644 public/scripts/app/controllers/artists-list.coffee create mode 100644 public/scripts/app/controllers/artists.coffee create mode 100644 public/scripts/app/services/albums.coffee create mode 100644 public/scripts/app/services/artists.coffee create mode 100644 public/styles/albums.less create mode 100644 public/templates/albums/list.html create mode 100644 public/templates/albums/show.html create mode 100644 public/templates/artists/list.html create mode 100644 public/templates/artists/show.html diff --git a/app/controllers/AlbumsController.php b/app/controllers/AlbumsController.php index 0ad3ac01..7538288c 100644 --- a/app/controllers/AlbumsController.php +++ b/app/controllers/AlbumsController.php @@ -1,7 +1,28 @@ slug != $slug) + return Redirect::action('AlbumsController@getAlbum', [$id, $album->slug]); + + return View::make('albums.show'); + } + + public function getShortlink($id) { + $album = Album::find($id); + if (!$album) + App::abort(404); + + return Redirect::action('AlbumsController@getTrack', [$id, $album->slug]); + } } \ No newline at end of file diff --git a/app/controllers/Api/Web/AlbumsController.php b/app/controllers/Api/Web/AlbumsController.php index c1b56fab..1ec18c06 100644 --- a/app/controllers/Api/Web/AlbumsController.php +++ b/app/controllers/Api/Web/AlbumsController.php @@ -28,6 +28,93 @@ return $this->execute(new DeleteAlbumCommand($id)); } + public function getShow($id) { + $album = Album::with('tracks', 'user')->find($id); + if (!$album) + App::abort(404); + + $tracks = []; + foreach ($album->tracks as $track) { + $tracks[] = Track::mapPublicTrackSummary($track); + } + + $formats = []; + foreach (Track::$Formats as $name => $format) { + $formats[] = [ + 'name' => $name, + 'extension' => $format['extension'], + 'url' => $album->getDownloadUrl($name) + ]; + } + + return Response::json([ + 'album' => [ + 'id' => $album->id, + 'formats' => $formats, + 'track_count' => $album->tracks->count(), + 'title' => $album->title, + 'description' => $album->description, + 'slug' => $album->slug, + 'created_at' => $album->created_at, + 'covers' => [ + 'small' => $album->getCoverUrl(Image::SMALL), + 'normal' => $album->getCoverUrl(Image::NORMAL) + ], + 'url' => $album->url, + 'user' => [ + 'id' => $album->user->id, + 'name' => $album->user->display_name, + 'url' => $album->user->url, + ], + 'tracks' => $tracks, + 'stats' => [ + 'views' => 0, + 'downloads' => 0 + ], + 'comments' => ['count' => 0, 'list' => []] + ] + ], 200); + } + + public function getIndex() { + $page = 1; + if (Input::has('page')) + $page = Input::get('page'); + + $query = Album::summary() + ->with('tracks', 'user') + ->orderBy('created_at', 'desc') + ->whereRaw('(SELECT COUNT(id) FROM tracks WHERE tracks.album_id = albums.id) > 0'); + + $count = $query->count(); + $perPage = 15; + + $query->skip(($page - 1) * $perPage)->take($perPage); + $albums = []; + + foreach ($query->get() as $album) { + $albums[] = [ + 'id' => $album->id, + 'track_count' => $album->tracks->count(), + 'title' => $album->title, + 'slug' => $album->slug, + 'created_at' => $album->created_at, + 'covers' => [ + 'small' => $album->getCoverUrl(Image::SMALL), + 'normal' => $album->getCoverUrl(Image::NORMAL) + ], + 'url' => $album->url, + 'user' => [ + 'id' => $album->user->id, + 'name' => $album->user->display_name, + 'url' => $album->user->url, + ] + ]; + } + + return Response::json(["albums" => $albums, "current_page" => $page, "total_pages" => ceil($count / $perPage)], 200); + } + public function getOwned() { $query = Album::summary()->where('user_id', \Auth::user()->id)->orderBy('created_at', 'desc')->get(); $albums = []; diff --git a/app/controllers/Api/Web/ArtistsController.php b/app/controllers/Api/Web/ArtistsController.php new file mode 100644 index 00000000..a71def8a --- /dev/null +++ b/app/controllers/Api/Web/ArtistsController.php @@ -0,0 +1,69 @@ +first(); + if (!$user) + App::abort(404); + + return Response::json([ + 'artist' => [ + 'id' => $user->id, + 'name' => $user->display_name, + 'slug' => $user->slug, + 'avatars' => [ + 'small' => $user->getAvatarUrl(Image::SMALL), + 'normal' => $user->getAvatarUrl(Image::NORMAL) + ], + 'created_at' => $user->created_at + ] + ], 200); + } + + public function getIndex() { + $page = 1; + if (Input::has('page')) + $page = Input::get('page'); + + $query = User::orderBy('created_at', 'desc') + ->whereRaw('(SELECT COUNT(id) FROM tracks WHERE tracks.user_id = users.id) > 0'); + + $count = $query->count(); + $perPage = 15; + + $query->skip(($page - 1) * $perPage)->take($perPage); + $users = []; + + foreach ($query->get() as $user) { + $users[] = [ + 'id' => $user->id, + 'name' => $user->display_name, + 'slug' => $user->slug, + 'url' => $user->url, + 'avatars' => [ + 'small' => $user->getAvatarUrl(Image::SMALL), + 'normal' => $user->getAvatarUrl(Image::NORMAL) + ], + 'created_at' => $user->created_at + ]; + } + + return Response::json(["artists" => $users, "current_page" => $page, "total_pages" => ceil($count / $perPage)], 200); + } + } \ No newline at end of file diff --git a/app/controllers/ArtistsController.php b/app/controllers/ArtistsController.php index e0bc496c..c5e1dde8 100644 --- a/app/controllers/ArtistsController.php +++ b/app/controllers/ArtistsController.php @@ -1,7 +1,25 @@ first(); + if (!$user) + App::abort('404'); + + return View::make('artists.profile'); + } + + public function getShortlink($id) { + $user = User::find($id); + if (!$user) + App::abort('404'); + + return Redirect::action('ArtistsController@getProfile', [$id]); + } } \ No newline at end of file diff --git a/app/library/Helpers.php b/app/library/Helpers.php index af326431..ec6caaac 100644 --- a/app/library/Helpers.php +++ b/app/library/Helpers.php @@ -8,4 +8,19 @@ public static function angular($expression) { return '{{' . $expression . '}}'; } + + public static function formatBytes($bytes, $precision = 2) { + if ($bytes == 0) + return '0 MB'; + + $units = array('B', 'KB', 'MB', 'GB', 'TB'); + + $bytes = max($bytes, 0); + $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); + $pow = min($pow, count($units) - 1); + + $bytes /= pow(1024, $pow); + + return round($bytes, $precision) . ' ' . $units[$pow]; + } } \ No newline at end of file diff --git a/app/models/Entities/Album.php b/app/models/Entities/Album.php index ad2e5982..a43801a9 100644 --- a/app/models/Entities/Album.php +++ b/app/models/Entities/Album.php @@ -3,6 +3,7 @@ namespace Entities; use Cover; + use Illuminate\Support\Facades\URL; use Whoops\Example\Exception; use Traits\SlugTrait; @@ -33,6 +34,14 @@ return $this->cover_id != null; } + public function getUrlAttribute() { + return URL::to('albums/' . $this->id . '-' . $this->slug); + } + + public function getDownloadUrl($format) { + return URL::to('a' . $this->id . '/dl.' . Track::$Formats[$format]['extension']); + } + public function getCoverUrl($type = Image::NORMAL) { if (!$this->hasCover()) return $this->user->getAvatarUrl($type); diff --git a/app/models/Entities/Track.php b/app/models/Entities/Track.php index d3406071..d805686c 100644 --- a/app/models/Entities/Track.php +++ b/app/models/Entities/Track.php @@ -5,6 +5,7 @@ use Cover; use External; use getid3_writetags; + use Helpers; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\URL; use Illuminate\Support\Str; @@ -32,6 +33,35 @@ $returnValue = self::mapPublicTrackSummary($track); $returnValue['description'] = $track->description; $returnValue['lyrics'] = $track->lyrics; + $returnValue['stats'] = [ + 'views' => 0, + 'plays' => 0, + 'downloads' => 0 + ]; + $returnValue['comments'] = ['count' => 0, 'list' => []]; + + if ($track->album_id != null) { + $returnValue['album'] = [ + 'title' => $track->album->title, + 'url' => $track->album->url, + ]; + } + + $formats = []; + + foreach (self::$Formats as $name => $format) { + $file = $track->getFileFor($name); + $url = $track->getUrlFor($name); + $size = 0; + + if (is_file($file)) + $size = filesize($file); + + $formats[] = ['name' => $name, 'extension' => $format['extension'], 'url' => $url, 'size' => Helpers::formatBytes($size)]; + } + + $returnValue['formats'] = $formats; + return $returnValue; } @@ -204,6 +234,14 @@ return "{$this->getDirectory()}/{$this->id}.{$format['extension']}"; } + public function getUrlFor($format) { + if (!isset(self::$Formats[$format])) + throw new Exception("$format is not a valid format!"); + + $format = self::$Formats[$format]; + return URL::to('/t' . $this->id . '/dl.' . $format['extension']); + } + public function updateTags() { foreach (self::$Formats as $format => $data) { $this->{$data['tag_method']}($format); diff --git a/app/routes.php b/app/routes.php index 2ca6efc8..ab32f4f6 100644 --- a/app/routes.php +++ b/app/routes.php @@ -18,10 +18,14 @@ Route::get('tracks/{id}-{slug}', 'TracksController@getTrack'); Route::get('t{id}', 'TracksController@getShortlink' ); + Route::get('t{id}/dl.{extension}', 'TracksController@getDownload' ); - Route::get('/albums', 'AlbumsController@getIndex'); - Route::get('/artists', 'ArtistsController@getIndex'); - Route::get('/playlists', 'PlaylistsController@getIndex'); + Route::get('albums', 'AlbumsController@getIndex'); + Route::get('albums/{id}-{slug}', 'AlbumsController@getShow'); + Route::get('a{id}', 'AlbumsController@getShortlink')->where('id', '\d+'); + + Route::get('artists', 'ArtistsController@getIndex'); + Route::get('playlists', 'PlaylistsController@getIndex'); Route::get('/login', function() { return View::make('auth.login'); }); Route::get('/register', function() { return View::make('auth.register'); }); @@ -29,12 +33,12 @@ Route::get('/about', function() { return View::make('pages.about'); }); Route::get('/faq', function() { return View::make('pages.faq'); }); - Route::get('i{id}/{type}.png', 'ImagesController@getImage'); + Route::get('i{id}/{type}.png', 'ImagesController@getImage')->where('id', '\d+'); - Route::get('u{id}/avatar_{type}.png', 'UsersController@getAvatar'); + Route::get('u{id}/avatar_{type}.png', 'UsersController@getAvatar')->where('id', '\d+'); Route::get('playlist/{id}-{slug}', 'PlaylistsController@getPlaylist'); - Route::get('p{id}', 'PlaylistsController@getShortlink'); + Route::get('p{id}', 'PlaylistsController@getShortlink')->where('id', '\d+'); Route::group(['prefix' => 'api/web'], function() { Route::get('/taxonomies/all', 'Api\Web\TaxonomiesController@getAll'); @@ -45,6 +49,12 @@ Route::get('/tracks', 'Api\Web\TracksController@getIndex'); Route::get('/tracks/{id}', 'Api\Web\TracksController@getShow')->where('id', '\d+'); + Route::get('/albums', 'Api\Web\AlbumsController@getIndex'); + Route::get('/albums/{id}', 'Api\Web\AlbumsController@getShow')->where('id', '\d+'); + + Route::get('/artists', 'Api\Web\ArtistsController@getIndex'); + Route::get('/artists/{slug}', 'Api\Web\ArtistsController@getShow')->where('id', '[-\w]'); + Route::get('/dashboard', 'Api\Web\DashboardController@getIndex'); Route::group(['before' => 'auth|csrf'], function() { @@ -101,4 +111,8 @@ }); }); + Route::get('u{id}', 'ArtistsController@getShortlink')->where('id', '\d+'); + Route::get('users/{id}-{slug}', 'ArtistsController@getShortlink')->where('id', '\d+'); + Route::get('{slug}', 'ArtistsController@getProfile')->where('id', '[-\w]'); + Route::get('/', 'HomeController@getIndex'); \ No newline at end of file diff --git a/app/views/albums/show.blade.php b/app/views/albums/show.blade.php new file mode 100644 index 00000000..ff1c68da --- /dev/null +++ b/app/views/albums/show.blade.php @@ -0,0 +1,6 @@ +@extends('shared._app_layout') + +@section('app_content') +

Album!

+

This page should be what search engines see

+@endsection \ No newline at end of file diff --git a/app/views/artists/profile.blade.php b/app/views/artists/profile.blade.php new file mode 100644 index 00000000..ec68134b --- /dev/null +++ b/app/views/artists/profile.blade.php @@ -0,0 +1,6 @@ +@extends('shared._app_layout') + +@section('app_content') +

Artist Profile!

+

This page should be what search engines see

+@endsection \ No newline at end of file diff --git a/app/views/shared/_app_layout.blade.php b/app/views/shared/_app_layout.blade.php index 5d00acd9..f896d5d0 100644 --- a/app/views/shared/_app_layout.blade.php +++ b/app/views/shared/_app_layout.blade.php @@ -36,9 +36,8 @@ @endif
  • Discover

  • Music
  • -
  • Albums
  • -
  • Playlists
  • -
  • Artists
  • +
  • Albums
  • +
  • Artists
  • @if (Auth::check())
  • @@ -102,7 +101,17 @@ @section('scripts') +
    + + + Share or Embed + +

    Stats

    + + + + + \ No newline at end of file diff --git a/public/templates/artists/index.html b/public/templates/artists/index.html index 07eab233..7904a910 100644 --- a/public/templates/artists/index.html +++ b/public/templates/artists/index.html @@ -1,3 +1,15 @@
    -

    Artists

    +

    Artist Directory

    + + + +
    \ No newline at end of file diff --git a/public/templates/artists/list.html b/public/templates/artists/list.html new file mode 100644 index 00000000..ad9d0ddc --- /dev/null +++ b/public/templates/artists/list.html @@ -0,0 +1,14 @@ + diff --git a/public/templates/artists/show.html b/public/templates/artists/show.html new file mode 100644 index 00000000..4b66220f --- /dev/null +++ b/public/templates/artists/show.html @@ -0,0 +1,8 @@ +
    + + +

    {{artist.name}}

    +
    \ No newline at end of file diff --git a/public/templates/tracks/show.html b/public/templates/tracks/show.html index 9f73e263..d208c727 100644 --- a/public/templates/tracks/show.html +++ b/public/templates/tracks/show.html @@ -1,4 +1,4 @@ -
    + @@ -26,13 +32,17 @@

    {{track.title}} + + from: {{track.album.title}} + + by: {{track.user.name}}

    -
    +
    -
    +

    @@ -46,12 +56,37 @@

    + +

    Comments

    +
    +
    + There are no comments yet! +
    +
    +
    + +
    + +
    +
    -
    +
    + +
    + + + + Share or Embed + +

    Stats

    +
      +
    • Published: {{track.published_at | pfmdate:"short"}}
    • +
    • Views: {{track.stats.views}}
    • +
    • Plays: {{track.stats.plays}}
    • +
    • Downloads: {{track.stats.downloads}}
    • +
    - -

    Comments

    \ No newline at end of file