diff --git a/app/commands/MigrateOldData.php b/app/commands/MigrateOldData.php index cfca2836..1ebde208 100644 --- a/app/commands/MigrateOldData.php +++ b/app/commands/MigrateOldData.php @@ -1,206 +1,210 @@ call('migrate:refresh'); + public function fire() { + $this->call('migrate:refresh'); - $oldDb = DB::connection('old'); - $oldUsers = $oldDb->table('users')->get(); + $oldDb = DB::connection('old'); + $oldUsers = $oldDb->table('users')->get(); - $this->info('Syncing Users'); - foreach ($oldUsers as $user) { - $displayName = $user->display_name; - if (!$displayName) - $displayName = $user->username; + $this->info('Syncing Users'); + foreach ($oldUsers as $user) { + $displayName = $user->display_name; + if (!$displayName) + $displayName = $user->username; - if (!$displayName) - $displayName = $user->mlpforums_name; + if (!$displayName) + $displayName = $user->mlpforums_name; - if (!$displayName) - continue; + if (!$displayName) + continue; - DB::table('users')->insert([ - 'id' => $user->id, - 'display_name' => $displayName, - 'email' => $user->email, - 'created_at' => $user->created_at, - 'updated_at' => $user->updated_at, - 'slug' => $user->slug, - 'password_hash' => $user->password_hash, - 'password_salt' => $user->password_salt, - 'bio' => $user->bio, - 'sync_names' => $user->sync_names, - 'can_see_explicit_content' => $user->can_see_explicit_content, - 'mlpforums_name' => $user->mlpforums_name, - 'uses_gravatar' => $user->uses_gravatar, - 'gravatar' => $user->gravatar, - 'avatar_id' => null - ]); + DB::table('users')->insert([ + 'id' => $user->id, + 'display_name' => $displayName, + 'email' => $user->email, + 'created_at' => $user->created_at, + 'updated_at' => $user->updated_at, + 'slug' => $user->slug, + 'password_hash' => $user->password_hash, + 'password_salt' => $user->password_salt, + 'bio' => $user->bio, + 'sync_names' => $user->sync_names, + 'can_see_explicit_content' => $user->can_see_explicit_content, + 'mlpforums_name' => $user->mlpforums_name, + 'uses_gravatar' => $user->uses_gravatar, + 'gravatar' => $user->gravatar, + 'avatar_id' => null + ]); - $coverId = null; - if (!$user->uses_gravatar) { - $coverFile = $this->getIdDirectory('users', $user->id) . '/' . $user->id . '_.png'; - $coverId = \Entities\Image::upload(new Symfony\Component\HttpFoundation\File\UploadedFile($coverFile, $user->id . '_.png'), $user->id)->id; - DB::table('users')->where('id', $user->id)->update(['avatar_id' => $coverId]); + $coverId = null; + if (!$user->uses_gravatar) { + $coverFile = $this->getIdDirectory('users', $user->id) . '/' . $user->id . '_.png'; + $coverId = \Entities\Image::upload(new Symfony\Component\HttpFoundation\File\UploadedFile($coverFile, $user->id . '_.png'), $user->id)->id; + DB::table('users')->where('id', $user->id)->update(['avatar_id' => $coverId]); + } + } + + $this->info('Syncing Genres'); + $oldGenres = $oldDb->table('genres')->get(); + foreach ($oldGenres as $genre) { + DB::table('genres')->insert([ + 'id' => $genre->id, + 'name' => $genre->title, + 'slug' => $genre->slug + ]); + } + + $this->info('Syncing Albums'); + $oldAlbums = $oldDb->table('albums')->get(); + foreach ($oldAlbums as $playlist) { + DB::table('albums')->insert([ + 'title' => $playlist->title, + 'description' => $playlist->description, + 'created_at' => $playlist->created_at, + 'updated_at' => $playlist->updated_at, + 'deleted_at' => $playlist->deleted_at, + 'slug' => $playlist->slug, + 'id' => $playlist->id, + 'user_id' => $playlist->user_id + ]); + } + + $this->info('Syncing Tracks'); + $oldTracks = $oldDb->table('tracks')->get(); + foreach ($oldTracks as $track) { + $coverId = null; + if ($track->cover) { + $coverFile = $this->getIdDirectory('tracks', $track->id) . '/' . $track->id . '_' . $track->cover . '.png'; + $coverId = \Entities\Image::upload(new Symfony\Component\HttpFoundation\File\UploadedFile($coverFile, $track->id . '_' . $track->cover . '.png'), $track->user_id)->id; + } + + DB::table('tracks')->insert([ + 'id' => $track->id, + 'title' => $track->title, + 'slug' => $track->slug, + 'description' => $track->description, + 'lyrics' => $track->lyrics, + 'created_at' => $track->created_at, + 'deleted_at' => $track->deleted_at, + 'updated_at' => $track->updated_at, + 'released_at' => $track->released_at, + 'published_at' => $track->published_at, + 'genre_id' => $track->genre_id, + 'is_explicit' => $track->explicit, + 'is_downloadable' => $track->downloadable, + 'is_vocal' => $track->is_vocal, + 'track_type_id' => $track->track_type_id, + 'track_number' => $track->track_number, + 'user_id' => $track->user_id, + 'album_id' => $track->album_id, + 'cover_id' => $coverId, + 'license_id' => $track->license_id, + 'duration' => $track->duration + ]); + } + + $oldShowSongs = $oldDb->table('song_track')->get(); + foreach ($oldShowSongs as $song) { + DB::table('show_song_track')->insert([ + 'id' => $song->id, + 'show_song_id' => $song->song_id, + 'track_id' => $song->track_id + ]); + } + + $this->info('Syncing Playlists'); + $oldPlaylists = $oldDb->table('playlists')->get(); + foreach ($oldPlaylists as $playlist) { + DB::table('playlists')->insert([ + 'title' => $playlist->title, + 'description' => $playlist->description, + 'created_at' => $playlist->created_at, + 'updated_at' => $playlist->updated_at, + 'deleted_at' => $playlist->deleted_at, + 'slug' => $playlist->slug, + 'id' => $playlist->id, + 'user_id' => $playlist->user_id, + 'is_public' => true + ]); + } + + $this->info('Syncing Playlist Tracks'); + $oldPlaylistTracks = $oldDb->table('playlist_track')->get(); + foreach ($oldPlaylistTracks as $playlistTrack) { + DB::table('playlist_track')->insert([ + 'id' => $playlistTrack->id, + 'created_at' => $playlistTrack->created_at, + 'updated_at' => $playlistTrack->updated_at, + 'position' => $playlistTrack->position, + 'playlist_id' => $playlistTrack->playlist_id, + 'track_id' => $playlistTrack->track_id + ]); + } + + $this->info('Syncing Comments'); + $oldComments = $oldDb->table('comments')->get(); + foreach ($oldComments as $comment) { + try { + DB::table('comments')->insert([ + 'id' => $comment->id, + 'user_id' => $comment->user_id, + 'created_at' => $comment->created_at, + 'deleted_at' => $comment->deleted_at, + 'updated_at' => $comment->updated_at, + 'content' => $comment->content, + 'track_id' => $comment->track_id, + 'album_id' => $comment->album_id, + 'playlist_id' => $comment->playlist_id, + 'profile_id' => $comment->profile_id + ]); + } catch (Exception $e) { + $this->error('Could not sync comment ' . $comment->id . ' because ' . $e->getMessage()); + } + } + + $this->info('Syncing Favourites'); + $oldFavs = $oldDb->table('favourites')->get(); + foreach ($oldFavs as $fav) { + try { + DB::table('favourites')->insert([ + 'id' => $fav->id, + 'user_id' => $fav->user_id, + 'created_at' => $fav->created_at, + 'updated_at' => $fav->updated_at, + 'track_id' => $fav->track_id, + 'album_id' => $fav->album_id, + 'playlist_id' => $fav->playlist_id, + ]); + } catch (Exception $e) { + $this->error('Could not sync favourite ' . $fav->id . ' because ' . $e->getMessage()); + } } } - $this->info('Syncing Genres'); - $oldGenres = $oldDb->table('genres')->get(); - foreach ($oldGenres as $genre) { - DB::table('genres')->insert([ - 'id' => $genre->id, - 'name' => $genre->title, - 'slug' => $genre->slug - ]); + private function getIdDirectory($type, $id) { + $dir = (string) ( floor( $id / 100 ) * 100 ); + return \Config::get('app.files_directory') . '/' . $type . '/' . $dir; } - $this->info('Syncing Albums'); - $oldAlbums = $oldDb->table('albums')->get(); - foreach ($oldAlbums as $playlist) { - DB::table('albums')->insert([ - 'title' => $playlist->title, - 'description' => $playlist->description, - 'created_at' => $playlist->created_at, - 'updated_at' => $playlist->updated_at, - 'deleted_at' => $playlist->deleted_at, - 'slug' => $playlist->slug, - 'id' => $playlist->id, - 'user_id' => $playlist->user_id - ]); + protected function getArguments() + { + return []; } - $this->info('Syncing Tracks'); - $oldTracks = $oldDb->table('tracks')->get(); - foreach ($oldTracks as $track) { - $coverId = null; - if ($track->cover) { - $coverFile = $this->getIdDirectory('tracks', $track->id) . '/' . $track->id . '_' . $track->cover . '.png'; - $coverId = \Entities\Image::upload(new Symfony\Component\HttpFoundation\File\UploadedFile($coverFile, $track->id . '_' . $track->cover . '.png'), $track->user_id)->id; - } - - DB::table('tracks')->insert([ - 'id' => $track->id, - 'title' => $track->title, - 'slug' => $track->slug, - 'description' => $track->description, - 'lyrics' => $track->lyrics, - 'created_at' => $track->created_at, - 'deleted_at' => $track->deleted_at, - 'updated_at' => $track->updated_at, - 'released_at' => $track->released_at, - 'published_at' => $track->published_at, - 'genre_id' => $track->genre_id, - 'is_explicit' => $track->explicit, - 'is_downloadable' => $track->downloadable, - 'is_vocal' => $track->is_vocal, - 'track_type_id' => $track->track_type_id, - 'track_number' => $track->track_number, - 'user_id' => $track->user_id, - 'album_id' => $track->album_id, - 'cover_id' => $coverId, - 'license_id' => $track->license_id - ]); + protected function getOptions() { + return []; } - - $oldShowSongs = $oldDb->table('song_track')->get(); - foreach ($oldShowSongs as $song) { - DB::table('show_song_track')->insert([ - 'id' => $song->id, - 'show_song_id' => $song->song_id, - 'track_id' => $song->track_id - ]); - } - - $this->info('Syncing Playlists'); - $oldPlaylists = $oldDb->table('playlists')->get(); - foreach ($oldPlaylists as $playlist) { - DB::table('playlists')->insert([ - 'title' => $playlist->title, - 'description' => $playlist->description, - 'created_at' => $playlist->created_at, - 'updated_at' => $playlist->updated_at, - 'deleted_at' => $playlist->deleted_at, - 'slug' => $playlist->slug, - 'id' => $playlist->id, - 'user_id' => $playlist->user_id, - 'is_pinned' => true, - 'is_public' => true - ]); - } - - $this->info('Syncing Playlist Tracks'); - $oldPlaylistTracks = $oldDb->table('playlist_tracks'); - foreach ($oldPlaylistTracks as $playlistTrack) { - DB::table('playlist_tracks')->insert([ - 'id' => $playlistTrack['id'], - 'created_at' => $playlistTrack['created_at'], - 'updated_at' => $playlistTrack['updated_at'], - 'position' => $playlistTrack['position'], - 'playlist_id' => $playlistTrack['playlist_id'], - 'track_id' => $playlistTrack['track_id'] - ]); - } - - $this->info('Syncing Comments'); - $oldComments = $oldDb->table('comments'); - foreach ($oldComments as $fav) { - DB::table('comments')->insert([ - 'id' => $fav->id, - 'user_id' => $fav->user_id, - 'created_at' => $fav->created_at, - 'deleted_at' => $fav->deleted_at, - 'updated_at' => $fav->updated_at, - 'content' => $fav->content, - 'track_id' => $fav->track_id, - 'album_id' => $fav->album_id, - 'playlist_id' => $fav->playlist_id, - 'profile_id' => $fav->profile_id - ]); - } - - $this->info('Syncing Favourites'); - $oldFavs = $oldDb->table('favourites'); - foreach ($oldFavs as $fav) { - DB::table('favourites')->insert([ - 'id' => $fav->id, - 'user_id' => $fav->user_id, - 'created_at' => $fav->created_at, - 'updated_at' => $fav->updated_at, - 'track_id' => $fav->track_id, - 'album_id' => $fav->album_id, - 'playlist_id' => $fav->playlist_id, - ]); - } - } - - private function getIdDirectory($type, $id) { - $dir = (string) ( floor( $id / 100 ) * 100 ); - return \Config::get('app.files_directory') . '/' . $type . '/' . $dir; - } - - protected function getArguments() - { - return [ - ['example', InputArgument::REQUIRED, 'An example argument.'], - ]; - } - - protected function getOptions() { - return [ - ['example', null, InputOption::VALUE_OPTIONAL, 'An example option.', null], - ]; - } -} \ No newline at end of file + } \ No newline at end of file diff --git a/app/controllers/Api/Web/AlbumsController.php b/app/controllers/Api/Web/AlbumsController.php index 55a844ad..3672d41c 100644 --- a/app/controllers/Api/Web/AlbumsController.php +++ b/app/controllers/Api/Web/AlbumsController.php @@ -31,52 +31,8 @@ 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) - ]; - } - - $comments = []; - foreach ($album->comments as $comment) { - $comments[] = Comment::mapPublic($comment); - } - 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' => count($comments), 'list' => $comments], - 'is_favourited' => $album->favourites->count() > 0 - ] + 'album' => Album::mapPublicAlbumShow($album) ], 200); } diff --git a/app/controllers/Api/Web/TracksController.php b/app/controllers/Api/Web/TracksController.php index 4887155d..05c10665 100644 --- a/app/controllers/Api/Web/TracksController.php +++ b/app/controllers/Api/Web/TracksController.php @@ -137,9 +137,10 @@ $query->whereIn('track_type_id', Input::get('types')); if (Input::has('songs')) { - $query->join('show_song_track', 'tracks.id', '=', 'show_song_track.track_id') - ->whereIn('show_song_track.show_song_id', Input::get('songs')); - + $query->join('show_song_track', function($join) { + $join->on('tracks.id', '=', 'show_song_track.track_id'); + }); + $query->whereIn('show_song_track.show_song_id', Input::get('songs')); $query->select('tracks.*'); } diff --git a/app/models/Entities/Album.php b/app/models/Entities/Album.php index cdc6709f..fc9072f7 100644 --- a/app/models/Entities/Album.php +++ b/app/models/Entities/Album.php @@ -3,7 +3,9 @@ namespace Entities; use Cover; + use Helpers; use Illuminate\Support\Facades\Auth; + use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\URL; use Whoops\Example\Exception; use Traits\SlugTrait; @@ -49,6 +51,39 @@ return $this->hasMany('Entities\Comment'); } + public static function mapPublicAlbumShow($album) { + $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), + 'size' => Helpers::formatBytes($album->getFilesize($name)) + ]; + } + + $comments = []; + foreach ($album->comments as $comment) { + $comments[] = Comment::mapPublic($comment); + } + + $data = self::mapPublicAlbumSummary($album); + $data['tracks'] = $tracks; + $data['comments'] = ['count' => count($comments), 'list' => $comments]; + $data['formats'] = $formats; + $data['stats'] = [ + 'views' => 0, + 'downloads' => 0 + ]; + + return $data; + } + public static function mapPublicAlbumSummary($album) { return [ 'id' => $album->id, @@ -82,6 +117,21 @@ return URL::to('a' . $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) { if (!$this->hasCover()) return $this->user->getAvatarUrl($type); @@ -176,5 +226,13 @@ foreach ($albumsToFix as $album) { $album->updateTrackNumbers(); } + + foreach (Track::$Formats as $name => $format) { + Cache::forget($this->getCacheKey('filesize' . $name)); + } + } + + private function getCacheKey($key) { + return 'album-' . $this->id . '-' . $key; } } \ No newline at end of file diff --git a/app/models/Entities/Track.php b/app/models/Entities/Track.php index 0a38ad30..8b2c5e3e 100644 --- a/app/models/Entities/Track.php +++ b/app/models/Entities/Track.php @@ -7,6 +7,7 @@ use getid3_writetags; use Helpers; use Illuminate\Support\Facades\Auth; + use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\URL; use Illuminate\Support\Str; @@ -72,14 +73,12 @@ $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)]; + $formats[] = [ + 'name' => $name, + 'extension' => $format['extension'], + 'url' => $track->getUrlFor($name), + 'size' => Helpers::formatBytes($track->getFilesize($name)) + ]; } $returnValue['formats'] = $formats; @@ -118,7 +117,10 @@ 'normal' => $track->getCoverUrl(Image::NORMAL) ], 'is_favourited' => $track->favourites->count() > 0, - 'duration' => $track->duration + 'duration' => $track->duration, + 'streams' => [ + 'mp3' => $track->getStreamUrl('MP3') + ] ]; } @@ -194,6 +196,18 @@ return date('Y', strtotime($this->release_date)); } + public function getFilesize($formatName) { + return Cache::remember($this->getCacheKey('filesize-' . $formatName), 1440, function () use ($formatName) { + $file = $this->getFileFor($formatName); + $size = 0; + + if (is_file($file)) + $size = filesize($file); + + return $size; + }); + } + public function canView($user) { if ($this->isPublished()) return true; @@ -241,6 +255,10 @@ return $this->cover->getUrl($type); } + public function getStreamUrl($format) { + return URL::to('/t' . $this->id . '/stream'); + } + public function getDirectory() { $dir = (string) ( floor( $this->id / 100 ) * 100 ); return \Config::get('app.files_directory') . '/tracks/' . $dir; @@ -356,4 +374,8 @@ Log::error('Failed to write tags!
' . implode('

', $tagWriter->errors)); } } + + private function getCacheKey($key) { + return 'track-' . $this->id . '-' . $key; + } } \ No newline at end of file diff --git a/public/scripts/app/directives/comments.coffee b/public/scripts/app/directives/comments.coffee index 393945ea..691b9013 100644 --- a/public/scripts/app/directives/comments.coffee +++ b/public/scripts/app/directives/comments.coffee @@ -6,7 +6,7 @@ angular.module('ponyfm').directive 'pfmComments', () -> type: '@type' controller: [ - '$scope', 'comments' + '$scope', 'comments', 'auth' ($scope, comments, auth) -> $scope.isWorking = false diff --git a/public/scripts/app/services/player.coffee b/public/scripts/app/services/player.coffee index 2335cd26..18a5f22d 100644 --- a/public/scripts/app/services/player.coffee +++ b/public/scripts/app/services/player.coffee @@ -7,7 +7,7 @@ angular.module('ponyfm').factory('player', [ self.currentTrack = track $rootScope.$broadcast 'player-starting-track', track self.currentSound = soundManager.createSound - url: '/t' + track.id + '/stream', + url: track.streams.mp3, volume: self.volume whileloading: () -> $rootScope.safeApply -> diff --git a/public/styles/app.less b/public/styles/app.less index bcbb0f21..beb0374a 100644 --- a/public/styles/app.less +++ b/public/styles/app.less @@ -1,11 +1,11 @@ -@import-once 'base/bootstrap/bootstrap'; -@import-once 'base/font-awesome/font-awesome'; -@import-once 'mixins'; -@import-once 'layout'; -@import-once 'home'; -@import-once 'account-content'; -@import-once 'components'; -@import-once 'forms'; -@import-once 'tracks'; -@import-once 'albums'; -@import-once 'animations'; \ No newline at end of file +@import 'base/bootstrap/bootstrap'; +@import 'base/font-awesome/font-awesome'; +@import 'mixins'; +@import 'layout'; +@import 'home'; +@import 'account-content'; +@import 'components'; +@import 'forms'; +@import 'tracks'; +@import 'albums'; +@import 'animations'; diff --git a/public/styles/tracks.less b/public/styles/tracks.less index cde76aa0..84e1f7d9 100644 --- a/public/styles/tracks.less +++ b/public/styles/tracks.less @@ -36,25 +36,6 @@ } } -.dashboard { - section { - /* - .box-sizing(border-box); - - width: 50%; - float: left; - - &:first-child { - padding-right: 10px; - } - - &:last-child { - padding-left: 10px; - } - */ - } -} - .tracks-listing { overflow-y: auto; margin: 0px; @@ -71,6 +52,13 @@ } } + &.condensed { + li { + margin: 0px; + border-bottom: 1px solid #ddd; + } + } + &.two-column { li { .box-sizing(border-box); @@ -114,7 +102,27 @@ } } - &:hover, &.is-playing { + &.is-playing, &:hover.is-playing { + background: #444; + + .icons { + span, a { + color: #fff; + } + } + + .info { + .title { + color: rgba(255, 255, 255, .9); + } + + .metadata { + color: #ddd; + } + } + } + + &:hover { background: #eee; .image { @@ -180,6 +188,7 @@ float: right; font-size: 14px; margin-right: 2px; + margin-top: 4px; a { text-decoration: none; diff --git a/public/templates/albums/show.html b/public/templates/albums/show.html index 958f75ed..258c1f7f 100644 --- a/public/templates/albums/show.html +++ b/public/templates/albums/show.html @@ -11,7 +11,7 @@ Downloads @@ -31,7 +31,7 @@

Tracks

- +

Comments

diff --git a/public/templates/directives/player.html b/public/templates/directives/player.html index fcd7f09b..edeeeea4 100644 --- a/public/templates/directives/player.html +++ b/public/templates/directives/player.html @@ -7,6 +7,9 @@