diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php new file mode 100644 index 00000000..0c97a3d5 --- /dev/null +++ b/app/Http/Controllers/AccountController.php @@ -0,0 +1,18 @@ +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]); + } + + public function getDownload($id, $extension) + { + $album = Album::with('tracks', 'user')->find($id); + if (!$album) { + 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('album', $id, ResourceLogItem::DOWNLOAD, $format['index']); + $downloader = new AlbumDownloader($album, $formatName); + $downloader->download(); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Api/Mobile/TracksController.php b/app/Http/Controllers/Api/Mobile/TracksController.php new file mode 100644 index 00000000..687a348f --- /dev/null +++ b/app/Http/Controllers/Api/Mobile/TracksController.php @@ -0,0 +1,44 @@ +userDetails() + ->listed() + ->explicitFilter() + ->published() + ->with('user', 'genre', 'cover', 'album', 'album.user')->take(10); + + $json = [ + 'total_tracks' => $tracks->count(), + 'tracks' => $tracks->toArray() + ]; + + return Response::json($json, 200); + } + + public function popular() + { + $tracks = Track::popular(10) + ->userDetails() + ->listed() + ->explicitFilter() + ->published() + ->with('user', 'genre', 'cover', 'album', 'album.user')->take(10); + + $json = [ + 'total_tracks' => $tracks->count(), + 'tracks' => $tracks->toArray() + ]; + + return Response::json($json, 200); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Api/V1/TracksController.php b/app/Http/Controllers/Api/V1/TracksController.php new file mode 100644 index 00000000..9b15b9f3 --- /dev/null +++ b/app/Http/Controllers/Api/V1/TracksController.php @@ -0,0 +1,88 @@ +published() + ->whereHash($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([ + 'id' => $track->id, + 'title' => $track->title, + 'description' => $track->description, + 'lyrics' => $track->lyrics, + 'user' => [ + 'id' => $track->user->id, + 'name' => $track->user->display_name, + 'url' => $track->user->url, + 'avatars' => [ + 'thumbnail' => $track->user->getAvatarUrl(Image::THUMBNAIL), + 'small' => $track->user->getAvatarUrl(Image::SMALL), + 'normal' => $track->user->getAvatarUrl(Image::NORMAL) + ] + ], + 'stats' => [ + 'views' => $track->view_count, + 'plays' => $track->play_count, + 'downloads' => $track->download_count, + 'comments' => $track->comment_count, + 'favourites' => $track->favourite_count + ], + 'url' => $track->url, + 'is_vocal' => !!$track->is_vocal, + 'is_explicit' => !!$track->is_explicit, + 'is_downloadable' => !!$track->is_downloadable, + 'published_at' => $track->published_at, + 'duration' => $track->duration, + 'genre' => $track->genre != null + ? + [ + 'id' => $track->genre->id, + 'name' => $track->genre->name + ] : null, + 'type' => [ + 'id' => $track->track_type->id, + 'name' => $track->track_type->title + ], + 'covers' => [ + 'thumbnail' => $track->getCoverUrl(Image::THUMBNAIL), + 'small' => $track->getCoverUrl(Image::SMALL), + 'normal' => $track->getCoverUrl(Image::NORMAL) + ], + 'comments' => $comments + ], 200); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Api/Web/AccountController.php b/app/Http/Controllers/Api/Web/AccountController.php new file mode 100644 index 00000000..579e03c0 --- /dev/null +++ b/app/Http/Controllers/Api/Web/AccountController.php @@ -0,0 +1,33 @@ + $user->bio, + 'can_see_explicit_content' => $user->can_see_explicit_content == 1, + 'display_name' => $user->display_name, + 'sync_names' => $user->sync_names == 1, + 'mlpforums_name' => $user->mlpforums_name, + 'gravatar' => $user->gravatar ? $user->gravatar : $user->email, + 'avatar_url' => !$user->uses_gravatar ? $user->getAvatarUrl() : null, + 'uses_gravatar' => $user->uses_gravatar == 1 + ], 200); + } + + public function postSave() + { + return $this->execute(new SaveAccountSettingsCommand(Input::all())); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Api/Web/AlbumsController.php b/app/Http/Controllers/Api/Web/AlbumsController.php new file mode 100644 index 00000000..e86279cd --- /dev/null +++ b/app/Http/Controllers/Api/Web/AlbumsController.php @@ -0,0 +1,146 @@ +execute(new CreateAlbumCommand(Input::all())); + } + + public function postEdit($id) + { + return $this->execute(new EditAlbumCommand($id, Input::all())); + } + + public function postDelete($id) + { + return $this->execute(new DeleteAlbumCommand($id)); + } + + public function getShow($id) + { + $album = Album::with([ + 'tracks' => function ($query) { + $query->userDetails(); + }, + 'tracks.cover', + 'tracks.genre', + 'tracks.user', + 'user', + 'comments', + 'comments.user' + ]) + ->userDetails() + ->find($id); + + if (!$album) { + App::abort(404); + } + + if (Input::get('log')) { + ResourceLogItem::logItem('album', $id, ResourceLogItem::VIEW); + $album->view_count++; + } + + $returned_album = Album::mapPublicAlbumShow($album); + if ($returned_album['is_downloadable'] == 0) { + unset($returned_album['formats']); + } + + return Response::json([ + 'album' => $returned_album + ], 200); + } + + public function getIndex() + { + $page = 1; + if (Input::has('page')) { + $page = Input::get('page'); + } + + $query = Album::summary() + ->with('user', 'user.avatar', 'cover') + ->userDetails() + ->orderBy('created_at', 'desc') + ->where('track_count', '>', 0); + + $count = $query->count(); + $perPage = 40; + + $query->skip(($page - 1) * $perPage)->take($perPage); + $albums = []; + + foreach ($query->get() as $album) { + $albums[] = Album::mapPublicAlbumSummary($album); + } + + 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 = []; + foreach ($query as $album) { + $albums[] = [ + 'id' => $album->id, + 'title' => $album->title, + 'slug' => $album->slug, + 'created_at' => $album->created_at, + 'covers' => [ + 'small' => $album->getCoverUrl(Image::SMALL), + 'normal' => $album->getCoverUrl(Image::NORMAL) + ] + ]; + } + + return Response::json($albums, 200); + } + + public function getEdit($id) + { + $album = Album::with('tracks')->find($id); + if (!$album) { + return $this->notFound('Album ' . $id . ' not found!'); + } + + if ($album->user_id != Auth::user()->id) { + return $this->notAuthorized(); + } + + $tracks = []; + foreach ($album->tracks as $track) { + $tracks[] = [ + 'id' => $track->id, + 'title' => $track->title + ]; + } + + return Response::json([ + 'id' => $album->id, + 'title' => $album->title, + 'user_id' => $album->user_id, + 'slug' => $album->slug, + 'created_at' => $album->created_at, + 'published_at' => $album->published_at, + 'description' => $album->description, + 'cover_url' => $album->hasCover() ? $album->getCoverUrl(Image::NORMAL) : null, + 'real_cover_url' => $album->getCoverUrl(Image::NORMAL), + 'tracks' => $tracks + ], 200); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Api/Web/ArtistsController.php b/app/Http/Controllers/Api/Web/ArtistsController.php new file mode 100644 index 00000000..8908cc0d --- /dev/null +++ b/app/Http/Controllers/Api/Web/ArtistsController.php @@ -0,0 +1,196 @@ +first(); + if (!$user) { + App::abort(404); + } + + $favs = Favourite::whereUserId($user->id)->with([ + 'track.genre', + 'track.cover', + 'track.user', + 'album.cover', + 'album.user', + 'track' => function ($query) { + $query->userDetails(); + }, + 'album' => function ($query) { + $query->userDetails(); + } + ])->get(); + + $tracks = []; + $albums = []; + + foreach ($favs as $fav) { + if ($fav->type == 'App\Track') { + $tracks[] = Track::mapPublicTrackSummary($fav->track); + } else { + if ($fav->type == 'App\Album') { + $albums[] = Album::mapPublicAlbumSummary($fav->album); + } + } + } + + return Response::json([ + 'tracks' => $tracks, + 'albums' => $albums + ], 200); + } + + public function getContent($slug) + { + $user = User::whereSlug($slug)->first(); + if (!$user) { + App::abort(404); + } + + $query = Track::summary()->published()->listed()->explicitFilter()->with('genre', 'cover', + 'user')->userDetails()->whereUserId($user->id)->whereNotNull('published_at'); + $tracks = []; + $singles = []; + + foreach ($query->get() as $track) { + if ($track->album_id != null) { + $tracks[] = Track::mapPublicTrackSummary($track); + } else { + $singles[] = Track::mapPublicTrackSummary($track); + } + } + + $query = Album::summary() + ->with('user') + ->orderBy('created_at', 'desc') + ->where('track_count', '>', 0) + ->whereUserId($user->id); + + $albums = []; + + foreach ($query->get() as $album) { + $albums[] = Album::mapPublicAlbumSummary($album); + } + + return Response::json(['singles' => $singles, 'albumTracks' => $tracks, 'albums' => $albums], 200); + } + + public function getShow($slug) + { + $user = User::whereSlug($slug) + ->userDetails() + ->with([ + 'comments' => function ($query) { + $query->with('user'); + } + ]) + ->first(); + if (!$user) { + App::abort(404); + } + + $trackQuery = Track::summary() + ->published() + ->explicitFilter() + ->listed() + ->with('genre', 'cover', 'user') + ->userDetails() + ->whereUserId($user->id) + ->whereNotNull('published_at') + ->orderBy('created_at', 'desc') + ->take(20); + + $latestTracks = []; + foreach ($trackQuery->get() as $track) { + $latestTracks[] = Track::mapPublicTrackSummary($track); + } + + $comments = []; + foreach ($user->comments as $comment) { + $comments[] = Comment::mapPublic($comment); + } + + $userData = [ + 'is_following' => false + ]; + + if ($user->users->count()) { + $userRow = $user->users[0]; + $userData = [ + 'is_following' => $userRow->is_followed + ]; + } + + return Response::json([ + 'artist' => [ + 'id' => $user->id, + 'name' => $user->display_name, + 'slug' => $user->slug, + 'is_archived' => $user->is_archived, + 'avatars' => [ + 'small' => $user->getAvatarUrl(Image::SMALL), + 'normal' => $user->getAvatarUrl(Image::NORMAL) + ], + 'created_at' => $user->created_at, + 'followers' => [], + 'following' => [], + 'latest_tracks' => $latestTracks, + 'comments' => $comments, + 'bio' => $user->bio, + 'mlpforums_username' => $user->mlpforums_name, + 'message_url' => $user->message_url, + 'user_data' => $userData + ] + ], 200); + } + + public function getIndex() + { + $page = 1; + if (Input::has('page')) { + $page = Input::get('page'); + } + + $query = User::orderBy('created_at', 'desc') + ->where('track_count', '>', 0); + + $count = $query->count(); + $perPage = 40; + + $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, + 'is_archived' => $user->is_archived, + '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/Http/Controllers/Api/Web/AuthController.php b/app/Http/Controllers/Api/Web/AuthController.php new file mode 100644 index 00000000..c4242377 --- /dev/null +++ b/app/Http/Controllers/Api/Web/AuthController.php @@ -0,0 +1,13 @@ +execute(new CreateCommentCommand($type, $id, Input::all())); + } + + public function getIndex($type, $id) + { + $column = ''; + + if ($type == 'track') { + $column = 'track_id'; + } else { + if ($type == 'user') { + $column = 'profile_id'; + } else { + if ($type == 'album') { + $column = 'album_id'; + } else { + if ($type == 'playlist') { + $column = 'playlist_id'; + } else { + App::abort(500); + } + } + } + } + + $query = Comment::where($column, '=', $id)->orderBy('created_at', 'desc')->with('user'); + $comments = []; + + foreach ($query->get() as $comment) { + $comments[] = Comment::mapPublic($comment); + } + + return Response::json(['list' => $comments, 'count' => count($comments)]); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Api/Web/DashboardController.php b/app/Http/Controllers/Api/Web/DashboardController.php new file mode 100644 index 00000000..3dc57d65 --- /dev/null +++ b/app/Http/Controllers/Api/Web/DashboardController.php @@ -0,0 +1,46 @@ +with(['genre', 'user', 'cover', 'user.avatar']) + ->whereIsLatest(true) + ->listed() + ->userDetails() + ->explicitFilter() + ->published() + ->orderBy('published_at', 'desc') + ->take(30); + + $recentTracks = []; + + foreach ($recentQuery->get() as $track) { + $recentTracks[] = Track::mapPublicTrackSummary($track); + } + + return Response::json([ + 'recent_tracks' => $recentTracks, + 'popular_tracks' => Track::popular(30, Auth::check() && Auth::user()->can_see_explicit_content), + 'news' => News::getNews(0, 10) + ], 200); + } + + public function postReadNews() + { + News::markPostAsRead(Input::get('url')); + + return Response::json([ + ]); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Api/Web/FavouritesController.php b/app/Http/Controllers/Api/Web/FavouritesController.php new file mode 100644 index 00000000..e855c3a4 --- /dev/null +++ b/app/Http/Controllers/Api/Web/FavouritesController.php @@ -0,0 +1,109 @@ +execute(new ToggleFavouriteCommand(Input::get('type'), Input::get('id'))); + } + + public function getTracks() + { + $query = Favourite + ::whereUserId(Auth::user()->id) + ->whereNotNull('track_id') + ->with([ + 'track' => function ($query) { + $query + ->userDetails() + ->published(); + }, + 'track.user', + 'track.genre', + 'track.cover', + 'track.album', + 'track.album.user' + ]); + + $tracks = []; + + foreach ($query->get() as $fav) { + if ($fav->track == null) // deleted track + { + continue; + } + + $tracks[] = Track::mapPublicTrackSummary($fav->track); + } + + return Response::json(["tracks" => $tracks], 200); + } + + public function getAlbums() + { + $query = Favourite + ::whereUserId(Auth::user()->id) + ->whereNotNull('album_id') + ->with([ + 'album' => function ($query) { + $query->userDetails(); + }, + 'album.user', + 'album.user.avatar', + 'album.cover' + ]); + + $albums = []; + + foreach ($query->get() as $fav) { + if ($fav->album == null) // deleted album + { + continue; + } + + $albums[] = Album::mapPublicAlbumSummary($fav->album); + } + + return Response::json(["albums" => $albums], 200); + } + + public function getPlaylists() + { + $query = Favourite + ::whereUserId(Auth::user()->id) + ->whereNotNull('playlist_id') + ->with([ + 'playlist' => function ($query) { + $query->userDetails(); + }, + 'playlist.user', + 'playlist.user.avatar', + 'playlist.tracks', + 'playlist.tracks.cover' + ]); + + $playlists = []; + + foreach ($query->get() as $fav) { + if ($fav->playlist == null) // deleted playlist + { + continue; + } + + $playlists[] = Playlist::mapPublicPlaylistSummary($fav->playlist); + } + + return Response::json(["playlists" => $playlists], 200); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Api/Web/FollowController.php b/app/Http/Controllers/Api/Web/FollowController.php new file mode 100644 index 00000000..133b2122 --- /dev/null +++ b/app/Http/Controllers/Api/Web/FollowController.php @@ -0,0 +1,14 @@ +execute(new ToggleFollowingCommand(Input::get('type'), Input::get('id'))); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Api/Web/ImagesController.php b/app/Http/Controllers/Api/Web/ImagesController.php new file mode 100644 index 00000000..8bdb5050 --- /dev/null +++ b/app/Http/Controllers/Api/Web/ImagesController.php @@ -0,0 +1,30 @@ +id); + $images = []; + foreach ($query->get() as $image) { + $images[] = [ + 'id' => $image->id, + 'urls' => [ + 'small' => $image->getUrl(Image::SMALL), + 'normal' => $image->getUrl(Image::NORMAL), + 'thumbnail' => $image->getUrl(Image::THUMBNAIL), + 'original' => $image->getUrl(Image::ORIGINAL) + ], + 'filename' => $image->filename + ]; + } + + return Response::json($images, 200); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Api/Web/PlaylistsController.php b/app/Http/Controllers/Api/Web/PlaylistsController.php new file mode 100644 index 00000000..9c47d62c --- /dev/null +++ b/app/Http/Controllers/Api/Web/PlaylistsController.php @@ -0,0 +1,142 @@ +execute(new CreatePlaylistCommand(Input::all())); + } + + public function postEdit($id) + { + return $this->execute(new EditPlaylistCommand($id, Input::all())); + } + + public function postDelete($id) + { + return $this->execute(new DeletePlaylistCommand($id, Input::all())); + } + + public function postAddTrack($id) + { + return $this->execute(new AddTrackToPlaylistCommand($id, Input::get('track_id'))); + } + + public function getIndex() + { + $page = 1; + if (Input::has('page')) { + $page = Input::get('page'); + } + + $query = Playlist::summary() + ->with('user', 'user.avatar', 'tracks', 'tracks.cover', 'tracks.user', 'tracks.album', 'tracks.album.user') + ->userDetails() + ->orderBy('created_at', 'desc') + ->where('track_count', '>', 0) + ->whereIsPublic(true); + + $count = $query->count(); + $perPage = 40; + + $query->skip(($page - 1) * $perPage)->take($perPage); + $playlists = []; + + foreach ($query->get() as $playlist) { + $playlists[] = Playlist::mapPublicPlaylistSummary($playlist); + } + + return Response::json([ + "playlists" => $playlists, + "current_page" => $page, + "total_pages" => ceil($count / $perPage) + ], 200); + } + + public function getShow($id) + { + $playlist = Playlist::with([ + 'tracks.user', + 'tracks.genre', + 'tracks.cover', + 'tracks.album', + 'tracks' => function ($query) { + $query->userDetails(); + }, + 'comments', + 'comments.user' + ])->userDetails()->find($id); + if (!$playlist || !$playlist->canView(Auth::user())) { + App::abort('404'); + } + + if (Input::get('log')) { + ResourceLogItem::logItem('playlist', $id, ResourceLogItem::VIEW); + $playlist->view_count++; + } + + return Response::json(Playlist::mapPublicPlaylistShow($playlist), 200); + } + + public function getPinned() + { + $query = Playlist + ::userDetails() + ->with('tracks', 'tracks.cover', 'tracks.user', 'user') + ->join('pinned_playlists', function ($join) { + $join->on('playlist_id', '=', 'playlists.id'); + }) + ->where('pinned_playlists.user_id', '=', Auth::user()->id) + ->orderBy('title', 'asc') + ->select('playlists.*') + ->get(); + + $playlists = []; + foreach ($query as $playlist) { + $mapped = Playlist::mapPublicPlaylistSummary($playlist); + $mapped['description'] = $playlist->description; + $mapped['is_pinned'] = true; + $playlists[] = $mapped; + } + + return Response::json($playlists, 200); + } + + public function getOwned() + { + $query = Playlist::summary()->with('pins', 'tracks', 'tracks.cover')->where('user_id', + \Auth::user()->id)->orderBy('title', 'asc')->get(); + $playlists = []; + foreach ($query as $playlist) { + $playlists[] = [ + 'id' => $playlist->id, + 'title' => $playlist->title, + 'slug' => $playlist->slug, + 'created_at' => $playlist->created_at, + 'description' => $playlist->description, + 'url' => $playlist->url, + 'covers' => [ + 'small' => $playlist->getCoverUrl(Image::SMALL), + 'normal' => $playlist->getCoverUrl(Image::NORMAL) + ], + 'is_pinned' => $playlist->hasPinFor(Auth::user()->id), + 'is_public' => $playlist->is_public == 1 + ]; + } + + return Response::json($playlists, 200); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Api/Web/ProfilerController.php b/app/Http/Controllers/Api/Web/ProfilerController.php new file mode 100644 index 00000000..4fa87ef1 --- /dev/null +++ b/app/Http/Controllers/Api/Web/ProfilerController.php @@ -0,0 +1,29 @@ + ProfileRequest::load($request)->toArray()], 200); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Api/Web/TaxonomiesController.php b/app/Http/Controllers/Api/Web/TaxonomiesController.php new file mode 100644 index 00000000..23f3bcf4 --- /dev/null +++ b/app/Http/Controllers/Api/Web/TaxonomiesController.php @@ -0,0 +1,25 @@ + License::all()->toArray(), + 'genres' => Genre::select('genres.*', + DB::raw('(SELECT COUNT(id) FROM tracks WHERE tracks.genre_id = genres.id AND tracks.published_at IS NOT NULL) AS track_count'))->orderBy('name')->get()->toArray(), + 'track_types' => TrackType::select('track_types.*', + DB::raw('(SELECT COUNT(id) FROM tracks WHERE tracks.track_type_id = track_types.id AND tracks.published_at IS NOT NULL) AS track_count'))->get()->toArray(), + 'show_songs' => ShowSong::select('title', 'id', 'slug', + DB::raw('(SELECT COUNT(tracks.id) FROM show_song_track INNER JOIN tracks ON tracks.id = show_song_track.track_id WHERE show_song_track.show_song_id = show_songs.id AND tracks.published_at IS NOT NULL) AS track_count'))->get()->toArray() + ], 200); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Api/Web/TracksController.php b/app/Http/Controllers/Api/Web/TracksController.php new file mode 100644 index 00000000..8c1e8a0a --- /dev/null +++ b/app/Http/Controllers/Api/Web/TracksController.php @@ -0,0 +1,158 @@ +execute(new UploadTrackCommand()); + } + + public function postDelete($id) + { + return $this->execute(new DeleteTrackCommand($id)); + } + + public function postEdit($id) + { + return $this->execute(new EditTrackCommand($id, Input::all())); + } + + public function getShow($id) + { + $track = Track::userDetails()->withComments()->find($id); + if (!$track || !$track->canView(Auth::user())) { + return $this->notFound('Track not found!'); + } + + if (Input::get('log')) { + ResourceLogItem::logItem('track', $id, ResourceLogItem::VIEW); + $track->view_count++; + } + + $returned_track = Track::mapPublicTrackShow($track); + if ($returned_track['is_downloadable'] != 1) { + unset($returned_track['formats']); + } + + return Response::json(['track' => $returned_track], 200); + } + + public function getIndex() + { + $page = 1; + $perPage = 45; + + if (Input::has('page')) { + $page = Input::get('page'); + } + + $query = Track::summary() + ->userDetails() + ->listed() + ->explicitFilter() + ->published() + ->with('user', 'genre', 'cover', 'album', 'album.user'); + + $this->applyFilters($query); + + $totalCount = $query->count(); + $query->take($perPage)->skip($perPage * ($page - 1)); + + $tracks = []; + $ids = []; + + foreach ($query->get(['tracks.*']) as $track) { + $tracks[] = Track::mapPublicTrackSummary($track); + $ids[] = $track->id; + } + + return Response::json([ + "tracks" => $tracks, + "current_page" => $page, + "total_pages" => ceil($totalCount / $perPage) + ], 200); + } + + public function getOwned() + { + $query = Track::summary()->where('user_id', \Auth::user()->id)->orderBy('created_at', 'desc'); + + $tracks = []; + foreach ($query->get() as $track) { + $tracks[] = Track::mapPrivateTrackSummary($track); + } + + return Response::json($tracks, 200); + } + + public function getEdit($id) + { + $track = Track::with('showSongs')->find($id); + if (!$track) { + return $this->notFound('Track ' . $id . ' not found!'); + } + + if ($track->user_id != Auth::user()->id) { + return $this->notAuthorized(); + } + + return Response::json(Track::mapPrivateTrackShow($track), 200); + } + + private function applyFilters($query) + { + if (Input::has('order')) { + $order = \Input::get('order'); + $parts = explode(',', $order); + $query->orderBy($parts[0], $parts[1]); + } + + if (Input::has('is_vocal')) { + $isVocal = \Input::get('is_vocal'); + if ($isVocal == 'true') { + $query->whereIsVocal(true); + } else { + $query->whereIsVocal(false); + } + } + + if (Input::has('in_album')) { + if (Input::get('in_album') == 'true') { + $query->whereNotNull('album_id'); + } else { + $query->whereNull('album_id'); + } + } + + if (Input::has('genres')) { + $query->whereIn('genre_id', Input::get('genres')); + } + + if (Input::has('types')) { + $query->whereIn('track_type_id', Input::get('types')); + } + + if (Input::has('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')); + } + + return $query; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/ApiControllerBase.php b/app/Http/Controllers/ApiControllerBase.php new file mode 100644 index 00000000..a62ead0b --- /dev/null +++ b/app/Http/Controllers/ApiControllerBase.php @@ -0,0 +1,33 @@ +authorize()) { + return $this->notAuthorized(); + } + + $result = $command->execute(); + if ($result->didFail()) { + return Response::json([ + 'message' => 'Validation failed', + 'errors' => $result->getValidator()->messages()->getMessages() + ], 400); + } + + return Response::json($result->getResponse(), 200); + } + + public function notAuthorized() + { + return Response::json(['message' => 'You may not do this!'], 403); + } + + public function notFound($message) + { + return Response::json(['message' => $message], 403); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/ArtistsController.php b/app/Http/Controllers/ArtistsController.php new file mode 100644 index 00000000..5d8da45d --- /dev/null +++ b/app/Http/Controllers/ArtistsController.php @@ -0,0 +1,32 @@ +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/Http/Controllers/Auth/AuthController.php b/app/Http/Controllers/Auth/AuthController.php deleted file mode 100644 index c0ad3b8e..00000000 --- a/app/Http/Controllers/Auth/AuthController.php +++ /dev/null @@ -1,65 +0,0 @@ -middleware('guest', ['except' => 'getLogout']); - } - - /** - * Get a validator for an incoming registration request. - * - * @param array $data - * @return \Illuminate\Contracts\Validation\Validator - */ - protected function validator(array $data) - { - return Validator::make($data, [ - 'name' => 'required|max:255', - 'email' => 'required|email|max:255|unique:users', - 'password' => 'required|confirmed|min:6', - ]); - } - - /** - * Create a new user instance after a valid registration. - * - * @param array $data - * @return User - */ - protected function create(array $data) - { - return User::create([ - 'name' => $data['name'], - 'email' => $data['email'], - 'password' => bcrypt($data['password']), - ]); - } -} diff --git a/app/Http/Controllers/Auth/PasswordController.php b/app/Http/Controllers/Auth/PasswordController.php deleted file mode 100644 index 1ceed97b..00000000 --- a/app/Http/Controllers/Auth/PasswordController.php +++ /dev/null @@ -1,32 +0,0 @@ -middleware('guest'); - } -} diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php new file mode 100644 index 00000000..d120e2ff --- /dev/null +++ b/app/Http/Controllers/AuthController.php @@ -0,0 +1,107 @@ +poniverse = new Poniverse(Config::get('poniverse.client_id'), Config::get('poniverse.secret')); + $this->poniverse->setRedirectUri(URL::to('/auth/oauth')); + } + + public function getLogin() + { + if (Auth::guest()) { + return Redirect::to($this->poniverse->getAuthenticationUrl('login')); + } + + return Redirect::to('/'); + } + + public function postLogout() + { + Auth::logout(); + + return Redirect::to('/'); + } + + public function getOAuth() + { + $code = $this->poniverse->getClient()->getAccessToken( + Config::get('poniverse.urls')['token'], + 'authorization_code', + [ + 'code' => Input::query('code'), + 'redirect_uri' => URL::to('/auth/oauth') + ]); + + if ($code['code'] != 200) { + if ($code['code'] == 400 && $code['result']['error_description'] == 'The authorization code has expired' && !isset($this->request['login_attempt'])) { + return Redirect::to($this->poniverse->getAuthenticationUrl('login_attempt')); + } + + return Redirect::to('/')->with('message', + 'Unfortunately we are having problems attempting to log you in at the moment. Please try again at a later time.'); + } + + $this->poniverse->setAccessToken($code['result']['access_token']); + $poniverseUser = $this->poniverse->getUser(); + $token = DB::table('oauth2_tokens')->where('external_user_id', '=', $poniverseUser['id'])->where('service', '=', + 'poniverse')->first(); + + $setData = [ + 'access_token' => $code['result']['access_token'], + 'expires' => date('Y-m-d H:i:s', strtotime("+" . $code['result']['expires_in'] . " Seconds", time())), + 'type' => $code['result']['token_type'], + ]; + + if (isset($code['result']['refresh_token']) && !empty($code['result']['refresh_token'])) { + $setData['refresh_token'] = $code['result']['refresh_token']; + } + + if ($token) { + //User already exists, update access token and refresh token if provided. + DB::table('oauth2_tokens')->where('id', '=', $token->id)->update($setData); + + return $this->loginRedirect(User::find($token->user_id)); + } + + //Check by email to see if they already have an account + $localMember = User::where('email', '=', $poniverseUser['email'])->first(); + + if ($localMember) { + return $this->loginRedirect($localMember); + } + + $user = new User; + + $user->mlpforums_name = $poniverseUser['username']; + $user->display_name = $poniverseUser['display_name']; + $user->email = $poniverseUser['email']; + $user->created_at = gmdate("Y-m-d H:i:s", time()); + $user->uses_gravatar = 1; + + $user->save(); + + //We need to insert a new token row :O + + $setData['user_id'] = $user->id; + $setData['external_user_id'] = $poniverseUser['id']; + $setData['service'] = 'poniverse'; + + DB::table('oauth2_tokens')->insert($setData); + + return $this->loginRedirect($user); + } + + protected function loginRedirect($user, $rememberMe = true) + { + Auth::login($user, $rememberMe); + + return Redirect::to('/'); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/ContentController.php b/app/Http/Controllers/ContentController.php new file mode 100644 index 00000000..51fa4370 --- /dev/null +++ b/app/Http/Controllers/ContentController.php @@ -0,0 +1,21 @@ +getFile($coverType['id']); + + if (!is_file($filename)) { + $redirect = URL::to('/images/icons/profile_' . Image::$ImageTypes[$coverType['id']]['name'] . '.png'); + + return Redirect::to($redirect); + } + + if (Config::get('app.sendfile')) { + $response->header('X-Sendfile', $filename); + } else { + $response->header('X-Accel-Redirect', $filename); + } + + $response->header('Content-Disposition', 'filename="' . $filename . '"'); + $response->header('Content-Type', 'image/png'); + + $lastModified = filemtime($filename); + + $response->header('Last-Modified', $lastModified); + $response->header('Cache-Control', 'max-age=' . (60 * 60 * 24 * 7)); + + return $response; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/PlaylistsController.php b/app/Http/Controllers/PlaylistsController.php new file mode 100644 index 00000000..58314b16 --- /dev/null +++ b/app/Http/Controllers/PlaylistsController.php @@ -0,0 +1,66 @@ +canView(Auth::user())) { + App::abort(404); + } + + if ($playlist->slug != $slug) { + return Redirect::action('PlaylistsController@getPlaylist', [$id, $playlist->slug]); + } + + return View::make('playlists.show'); + } + + public function getShortlink($id) + { + $playlist = Playlist::find($id); + if (!$playlist || !$playlist->canView(Auth::user())) { + App::abort(404); + } + + 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(); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/TracksController.php b/app/Http/Controllers/TracksController.php new file mode 100644 index 00000000..50c71455 --- /dev/null +++ b/app/Http/Controllers/TracksController.php @@ -0,0 +1,147 @@ +published() + ->userDetails() + ->with( + 'user', + 'user.avatar', + 'genre' + )->first(); + + if (!$track || !$track->canView(Auth::user())) { + App::abort(404); + } + + $userData = [ + 'stats' => [ + 'views' => 0, + 'plays' => 0, + 'downloads' => 0 + ], + 'is_favourited' => false + ]; + + if ($track->users->count()) { + $userRow = $track->users[0]; + $userData = [ + 'stats' => [ + 'views' => $userRow->view_count, + 'plays' => $userRow->play_count, + 'downloads' => $userRow->download_count, + ], + 'is_favourited' => $userRow->is_favourited + ]; + } + + return View::make('tracks.embed', ['track' => $track, 'user' => $userData]); + } + + public function getTrack($id, $slug) + { + $track = Track::find($id); + if (!$track || !$track->canView(Auth::user())) { + App::abort(404); + } + + if ($track->slug != $slug) { + return Redirect::action('TracksController@getTrack', [$id, $track->slug]); + } + + return View::make('tracks.show'); + } + + public function getShortlink($id) + { + $track = Track::find($id); + if (!$track || !$track->canView(Auth::user())) { + App::abort(404); + } + + return Redirect::action('TracksController@getTrack', [$id, $track->slug]); + } + + public function getStream($id, $extension) + { + $track = Track::find($id); + if (!$track || !$track->canView(Auth::user())) { + App::abort(404); + } + + $trackFile = TrackFile::findOrFailByExtension($track->id, $extension); + ResourceLogItem::logItem('track', $id, ResourceLogItem::PLAY, $trackFile->getFormat()['index']); + + $response = Response::make('', 200); + $filename = $trackFile->getFile(); + + if (Config::get('app.sendfile')) { + $response->header('X-Sendfile', $filename); + } else { + $response->header('X-Accel-Redirect', $filename); + } + + $time = gmdate(filemtime($filename)); + + if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $time == $_SERVER['HTTP_IF_MODIFIED_SINCE']) { + header('HTTP/1.0 304 Not Modified'); + exit(); + } + + $response->header('Last-Modified', $time); + $response->header('Content-Type', $trackFile->getFormat()['mime_type']); + + return $response; + } + + public function getDownload($id, $extension) + { + $track = Track::find($id); + if (!$track || !$track->canView(Auth::user())) { + App::abort(404); + } + + $trackFile = TrackFile::findOrFailByExtension($track->id, $extension); + ResourceLogItem::logItem('track', $id, ResourceLogItem::DOWNLOAD, $trackFile->getFormat()['index']); + + $response = Response::make('', 200); + $filename = $trackFile->getFile(); + + if (Config::get('app.sendfile')) { + $response->header('X-Sendfile', $filename); + $response->header('Content-Disposition', + 'attachment; filename="' . $trackFile->getDownloadFilename() . '"'); + } else { + $response->header('X-Accel-Redirect', $filename); + $response->header('Content-Disposition', + 'attachment; filename="' . $trackFile->getDownloadFilename() . '"'); + } + + $time = gmdate(filemtime($filename)); + + if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $time == $_SERVER['HTTP_IF_MODIFIED_SINCE']) { + header('HTTP/1.0 304 Not Modified'); + exit(); + } + + $response->header('Last-Modified', $time); + $response->header('Content-Type', $trackFile->getFormat()['mime_type']); + + return $response; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/UploaderController.php b/app/Http/Controllers/UploaderController.php new file mode 100644 index 00000000..0d4e9a9b --- /dev/null +++ b/app/Http/Controllers/UploaderController.php @@ -0,0 +1,11 @@ +getAvatarFile($coverType['id']), 'image/png', 'cover.png'); + } +} \ No newline at end of file