diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php
index 450da761..821cfef4 100644
--- a/app/Http/Controllers/AdminController.php
+++ b/app/Http/Controllers/AdminController.php
@@ -48,4 +48,9 @@ class AdminController extends Controller
{
return View::make('shared.null');
}
+
+ public function getClassifierQueue()
+ {
+ return View::make('shared.null');
+ }
}
diff --git a/app/Http/Controllers/Api/Web/TracksController.php b/app/Http/Controllers/Api/Web/TracksController.php
index d0bfdb5e..ee24c2bb 100644
--- a/app/Http/Controllers/Api/Web/TracksController.php
+++ b/app/Http/Controllers/Api/Web/TracksController.php
@@ -27,9 +27,12 @@ use Poniverse\Ponyfm\Commands\EditTrackCommand;
use Poniverse\Ponyfm\Commands\UploadTrackCommand;
use Poniverse\Ponyfm\Http\Controllers\ApiControllerBase;
use Poniverse\Ponyfm\Jobs\EncodeTrackFile;
+use Poniverse\Ponyfm\Models\Genre;
use Poniverse\Ponyfm\Models\ResourceLogItem;
use Poniverse\Ponyfm\Models\TrackFile;
use Poniverse\Ponyfm\Models\Track;
+use Poniverse\Ponyfm\Models\TrackType;
+use Poniverse\Ponyfm\Models\TrackTypes;
use Auth;
use Input;
use Poniverse\Ponyfm\Models\User;
@@ -131,7 +134,7 @@ class TracksController extends ApiControllerBase
return Response::json(['url' => $url], 200);
}
- public function getIndex($all = false)
+ public function getIndex($all = false, $unknown = false)
{
$page = 1;
$perPage = 45;
@@ -155,7 +158,7 @@ class TracksController extends ApiControllerBase
->with('user', 'genre', 'cover', 'album', 'album.user');
}
- $this->applyFilters($query);
+ $this->applyFilters($query, $unknown);
$totalCount = $query->count();
$this->applyOrdering($query);
@@ -182,6 +185,12 @@ class TracksController extends ApiControllerBase
return $this->getIndex(true);
}
+ public function getClassifierQueue()
+ {
+ $this->authorize('access-admin-area');
+ return $this->getIndex(true, true);
+ }
+
public function getOwned(User $user)
{
$query = Track::summary()->where('user_id', $user->id)->orderBy('created_at', 'desc');
@@ -231,7 +240,7 @@ class TracksController extends ApiControllerBase
* @param $query
* @return mixed
*/
- private function applyFilters($query)
+ private function applyFilters($query, $unknown = false)
{
if (Input::has('is_vocal')) {
$isVocal = \Input::get('is_vocal');
@@ -254,10 +263,23 @@ class TracksController extends ApiControllerBase
$query->whereIn('genre_id', Input::get('genres'));
}
- if (Input::has('types')) {
+ if (Input::has('types') && !$unknown) {
$query->whereIn('track_type_id', Input::get('types'));
}
+ if ($unknown) {
+ $query->where(function($q) {
+ $unknownGenre = Genre::where('name', 'Unknown')->first();
+
+ $q->where('track_type_id', TrackType::UNCLASSIFIED_TRACK);
+
+ if ($unknownGenre) {
+ $q->orWhere('genre_id', $unknownGenre->id);
+ }
+ });
+
+ }
+
if (Input::has('songs')) {
// DISTINCT is needed here to avoid duplicate results
// when a track is associated with multiple show songs.
diff --git a/app/Http/routes.php b/app/Http/routes.php
index 88fa844e..4539cae2 100644
--- a/app/Http/routes.php
+++ b/app/Http/routes.php
@@ -177,6 +177,7 @@ Route::group(['prefix' => 'api/web'], function() {
Route::delete('/showsongs/{id}', 'Api\Web\ShowSongsController@deleteSong')->where('id', '\d+');
Route::get('/tracks', 'Api\Web\TracksController@getAllTracks');
+ Route::get('/tracks/unclassified', 'Api\Web\TracksController@getClassifierQueue');
});
Route::post('/auth/logout', 'Api\Web\AuthController@postLogout');
@@ -186,6 +187,7 @@ Route::group(['prefix' => 'api/web'], function() {
Route::group(['prefix' => 'admin', 'middleware' => ['auth', 'can:access-admin-area']], function() {
Route::get('/genres', 'AdminController@getGenres');
Route::get('/tracks', 'AdminController@getTracks');
+ Route::get('/tracks/unclassified', 'AdminController@getClassifierQueue');
Route::get('/show-songs', 'AdminController@getShowSongs');
Route::get('/users', 'AdminController@getUsers');
Route::get('/', 'AdminController@getIndex');
diff --git a/public/templates/admin/_layout.html b/public/templates/admin/_layout.html
index 5d1a4700..f94c5b84 100644
--- a/public/templates/admin/_layout.html
+++ b/public/templates/admin/_layout.html
@@ -1,5 +1,6 @@
- All Tracks
+ - Unclassified Tracks
- Genres
- Show Songs
- Users
diff --git a/public/templates/admin/classifier.html b/public/templates/admin/classifier.html
new file mode 100644
index 00000000..90db7aaf
--- /dev/null
+++ b/public/templates/admin/classifier.html
@@ -0,0 +1 @@
+
diff --git a/public/templates/admin/tracks.html b/public/templates/admin/tracks.html
index 72a5f353..54bf6aa7 100644
--- a/public/templates/admin/tracks.html
+++ b/public/templates/admin/tracks.html
@@ -1,20 +1 @@
-
-
-
+
diff --git a/public/templates/directives/paged-tracks-list.html b/public/templates/directives/paged-tracks-list.html
new file mode 100644
index 00000000..80f74694
--- /dev/null
+++ b/public/templates/directives/paged-tracks-list.html
@@ -0,0 +1,22 @@
+
diff --git a/resources/assets/scripts/app/app.coffee b/resources/assets/scripts/app/app.coffee
index 851c1c3e..7d768c42 100644
--- a/resources/assets/scripts/app/app.coffee
+++ b/resources/assets/scripts/app/app.coffee
@@ -283,6 +283,11 @@ ponyfm.config [
controller: 'admin-tracks'
templateUrl: '/templates/admin/tracks.html'
+ state.state 'admin.classifier',
+ url: '/tracks/unclassified'
+ controller: 'admin-classifier'
+ templateUrl: '/templates/admin/classifier.html'
+
state.state 'admin.users',
url: '/users'
controller: 'admin-users'
diff --git a/resources/assets/scripts/app/controllers/admin-classifier.coffee b/resources/assets/scripts/app/controllers/admin-classifier.coffee
new file mode 100644
index 00000000..cf795510
--- /dev/null
+++ b/resources/assets/scripts/app/controllers/admin-classifier.coffee
@@ -0,0 +1,32 @@
+# Pony.fm - A community for pony fan music.
+# Copyright (C) 2016 Josef Citrine
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+window.pfm.preloaders['admin-classifier'] = [
+ 'tracks', '$state'
+ (tracks, $state) ->
+ tracks.loadFilters().then(->
+ tracks.mainQuery.fromFilterString($state.params.filter)
+ tracks.mainQuery.setPage $state.params.page || 1
+ tracks.mainQuery.setAdmin true
+ )
+]
+
+module.exports = angular.module('ponyfm').controller "admin-classifier", [
+ '$scope', 'tracks', '$state',
+ ($scope, tracks, $state) ->
+
+
+]
diff --git a/resources/assets/scripts/app/controllers/admin-tracks.coffee b/resources/assets/scripts/app/controllers/admin-tracks.coffee
index 140ec3cb..9d66f888 100644
--- a/resources/assets/scripts/app/controllers/admin-tracks.coffee
+++ b/resources/assets/scripts/app/controllers/admin-tracks.coffee
@@ -21,56 +21,12 @@ window.pfm.preloaders['admin-tracks'] = [
tracks.mainQuery.fromFilterString($state.params.filter)
tracks.mainQuery.setPage $state.params.page || 1
tracks.mainQuery.setAdmin true
-
- tracks.mainQuery.fetch()
)
]
module.exports = angular.module('ponyfm').controller "admin-tracks", [
'$scope', 'tracks', '$state',
($scope, tracks, $state) ->
- tracks.mainQuery.fetch().done (searchResults) ->
- $scope.tracks = searchResults.tracks
- $scope.currentPage = parseInt(searchResults.current_page)
- $scope.totalPages = parseInt(searchResults.total_pages)
- delete $scope.nextPage
- delete $scope.prevPage
-
- $scope.nextPage = $scope.currentPage + 1 if $scope.currentPage < $scope.totalPages
- $scope.prevPage = $scope.currentPage - 1 if $scope.currentPage > 1
- $scope.allPages = [1..$scope.totalPages]
-
- # TODO: turn this into a directive
- # The actual first page will always be in the paginator.
- $scope.pages = [1]
-
- # This logic determines how many pages to add prior to the current page, if any.
- firstPage = Math.max(2, $scope.currentPage-3)
- $scope.pages = $scope.pages.concat [firstPage..$scope.currentPage] unless $scope.currentPage == 1
-
- pagesLeftToAdd = 8-$scope.pages.length
-
- lastPage = Math.min($scope.totalPages - 1, $scope.currentPage+1+pagesLeftToAdd)
- $scope.pages = $scope.pages.concat([$scope.currentPage+1..lastPage]) unless $scope.currentPage >= lastPage
-
- # The actual last page will always be in the paginator.
- $scope.pages.push($scope.totalPages) unless $scope.totalPages in $scope.pages
-
- $scope.pageSelectorShown = false
-
- $scope.gotoPage = (page) ->
- $state.transitionTo 'content.tracks.list', {filter: $state.params.filter, page: page}
-
- $scope.showPageSelector = () ->
- $scope.pageSelectorShown = true
- focus('#pagination-jump-destination')
-
- $scope.hidePageSelector = () ->
- $scope.pageSelectorShown = false
-
-
- $scope.jumpToPage = (inputPageNumber) ->
- $scope.gotoPage(inputPageNumber)
]
diff --git a/resources/assets/scripts/app/directives/paged-tracks-list.coffee b/resources/assets/scripts/app/directives/paged-tracks-list.coffee
new file mode 100644
index 00000000..ef956b42
--- /dev/null
+++ b/resources/assets/scripts/app/directives/paged-tracks-list.coffee
@@ -0,0 +1,76 @@
+# Pony.fm - A community for pony fan music.
+# Copyright (C) 2016 Josef Citrine
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+module.exports = angular.module('ponyfm').directive 'pfmPagedTracksList', () ->
+ restrict: 'E'
+ templateUrl: '/templates/directives/paged-tracks-list.html'
+ replace: true
+ scope:
+ type: '@'
+ class: '@class'
+
+ controller: [
+ '$scope', 'tracks', '$state',
+ ($scope, tracks, $state) ->
+ typeEnum = switch
+ when $scope.type == 'normal' then tracks.FetchType.NORMAL
+ when $scope.type == 'all' then tracks.FetchType.ALL
+ when $scope.type == 'unclassified' then tracks.FetchType.UNCLASSIFIED
+ else tracks.FetchType.NORMAL
+
+ tracks.mainQuery.fetch(typeEnum).done (searchResults) ->
+ $scope.tracks = searchResults.tracks
+
+ $scope.currentPage = parseInt(searchResults.current_page)
+ $scope.totalPages = parseInt(searchResults.total_pages)
+ delete $scope.nextPage
+ delete $scope.prevPage
+
+ $scope.nextPage = $scope.currentPage + 1 if $scope.currentPage < $scope.totalPages
+ $scope.prevPage = $scope.currentPage - 1 if $scope.currentPage > 1
+ $scope.allPages = [1..$scope.totalPages]
+
+ # The actual first page will always be in the paginator.
+ $scope.pages = [1]
+
+ # This logic determines how many pages to add prior to the current page, if any.
+ firstPage = Math.max(2, $scope.currentPage-3)
+ $scope.pages = $scope.pages.concat [firstPage..$scope.currentPage] unless $scope.currentPage == 1
+
+ pagesLeftToAdd = 8-$scope.pages.length
+
+ lastPage = Math.min($scope.totalPages - 1, $scope.currentPage+1+pagesLeftToAdd)
+ $scope.pages = $scope.pages.concat([$scope.currentPage+1..lastPage]) unless $scope.currentPage >= lastPage
+
+ # The actual last page will always be in the paginator.
+ $scope.pages.push($scope.totalPages) unless $scope.totalPages in $scope.pages
+
+ $scope.pageSelectorShown = false
+
+ $scope.gotoPage = (page) ->
+ $state.transitionTo 'content.tracks.list', {filter: $state.params.filter, page: page}
+
+ $scope.showPageSelector = () ->
+ $scope.pageSelectorShown = true
+ focus('#pagination-jump-destination')
+
+ $scope.hidePageSelector = () ->
+ $scope.pageSelectorShown = false
+
+
+ $scope.jumpToPage = (inputPageNumber) ->
+ $scope.gotoPage(inputPageNumber)
+ ]
diff --git a/resources/assets/scripts/app/services/tracks.coffee b/resources/assets/scripts/app/services/tracks.coffee
index 286c0ca2..9b9f05a7 100644
--- a/resources/assets/scripts/app/services/tracks.coffee
+++ b/resources/assets/scripts/app/services/tracks.coffee
@@ -144,16 +144,19 @@ module.exports = angular.module('ponyfm').factory('tracks', [
else
@toggleListFilter filterName, id for id in _.rest parts, 1
- fetch: () ->
+ fetch: (type) ->
return @cachedDef if @cachedDef
@cachedDef = new $.Deferred()
trackDef = @cachedDef
query = '/api/web/tracks?'
- if @admin
+ if type == self.FetchType.ALL && @admin
query = '/api/web/admin/tracks?'
+ if type == self.FetchType.UNCLASSIFIED && @admin
+ query = '/api/web/admin/tracks/unclassified?'
+
parts = ['page=' + @page]
_.each @availableFilters, (filter, name) =>
@@ -178,6 +181,11 @@ module.exports = angular.module('ponyfm').factory('tracks', [
self =
filters: {}
+ FetchType:
+ NORMAL: 0
+ ALL: 1
+ UNCLASSIFIED: 2
+
fetch: (id, force) ->
force = force || false
return trackCache[id] if !force && trackCache[id]