diff --git a/modules/core/client/app/trans-string-en.js b/modules/core/client/app/trans-string-en.js index a50119de..b70b810f 100644 --- a/modules/core/client/app/trans-string-en.js +++ b/modules/core/client/app/trans-string-en.js @@ -133,6 +133,9 @@ ADMIN_USER_LIST: 'User List', ADMIN_USER_VIEW: 'View User', ADMIN_USER_EDIT: 'Edit User', + ADMIN_USER_SEEDING: 'User Seeding', + ADMIN_USER_LEECHING: 'User Leeching', + ADMIN_USER_WARNING: 'User Warning', USER_INFO: 'User Info', ADMIN_TORRENTS_LIST: 'Torrents List', ADMIN_ANNOUNCE_EDIT: 'Announce Edit', diff --git a/modules/core/client/app/trans-string-zh.js b/modules/core/client/app/trans-string-zh.js index 36ef935c..1686001d 100644 --- a/modules/core/client/app/trans-string-zh.js +++ b/modules/core/client/app/trans-string-zh.js @@ -133,6 +133,9 @@ ADMIN_USER_LIST: '用户管理', ADMIN_USER_VIEW: '查看用户', ADMIN_USER_EDIT: '编辑用户', + ADMIN_USER_SEEDING: '用户正在做种', + ADMIN_USER_LEECHING: '用户正在下载', + ADMIN_USER_WARNING: '用户正被警告', USER_INFO: '用户信息', ADMIN_ANNOUNCE_EDIT: '种子修改', ADMIN_TORRENTS_LIST: '种子管理', diff --git a/modules/torrents/client/services/peers.client.service.js b/modules/torrents/client/services/peers.client.service.js index 424b82eb..85663768 100644 --- a/modules/torrents/client/services/peers.client.service.js +++ b/modules/torrents/client/services/peers.client.service.js @@ -27,15 +27,15 @@ }, getUserSeedingList: { method: 'GET', - url: '/api/:userId/seeding', + url: '/api/users/:userId/seeding', isArray: true, params: { userId: '@userId' } }, - getUserDownloadingList: { + getUserLeechingList: { method: 'GET', - url: '/api/:userId/downloading', + url: '/api/users/:userId/leeching', isArray: true, params: { userId: '@userId' @@ -43,7 +43,7 @@ }, getUserWarningList: { method: 'GET', - url: '/api/:userId/warning', + url: '/api/users/:userId/warning', isArray: true, params: { userId: '@userId' diff --git a/modules/torrents/server/controllers/peers.server.controller.js b/modules/torrents/server/controllers/peers.server.controller.js index a070cbb1..da02c8b7 100644 --- a/modules/torrents/server/controllers/peers.server.controller.js +++ b/modules/torrents/server/controllers/peers.server.controller.js @@ -99,85 +99,3 @@ exports.getMyWarning = function (req, res) { } }); }; - -/** - * list user seeding torrents - * @param req - * @param res - */ -exports.getUserSeeding = function (req, res) { - Peer.find({ - user: req.model._id, - peer_status: PEERSTATE_SEEDER - }).sort('-peer_uploaded') - .populate({ - path: 'torrent', - populate: { - path: 'user', - select: 'displayName profileImageURL' - } - }) - .exec(function (err, torrents) { - if (err) { - return res.status(422).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.json(torrents); - } - }); -}; - -/** - * list user downloading torrents - * @param req - * @param res - */ -exports.getUserDownloading = function (req, res) { - Peer.find({ - user: req.model._id, - peer_status: PEERSTATE_LEECHER - }).sort('-peer_downloaded') - .populate({ - path: 'torrent', - populate: { - path: 'user', - select: 'displayName profileImageURL' - } - }) - .exec(function (err, torrents) { - if (err) { - return res.status(422).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.json(torrents); - } - }); -}; - -/** - * list user warning torrents - * @param req - * @param res - */ -exports.getUserWarning = function (req, res) { - Complete.find({ - user: req.model._id, - hnr_warning: true - }).populate({ - path: 'torrent', - populate: { - path: 'user', - select: 'displayName profileImageURL' - } - }).exec(function (err, complets) { - if (err) { - return res.status(422).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.json(complets); - } - }); -}; diff --git a/modules/torrents/server/policies/torrents.server.policy.js b/modules/torrents/server/policies/torrents.server.policy.js index 51ab068d..9259562b 100644 --- a/modules/torrents/server/policies/torrents.server.policy.js +++ b/modules/torrents/server/policies/torrents.server.policy.js @@ -41,9 +41,6 @@ exports.invokeRolesPolicies = function () { {resources: '/api/my/seeding', permissions: '*'}, {resources: '/api/my/downloading', permissions: '*'}, {resources: '/api/my/warning', permissions: '*'}, - {resources: '/api/:userId/seeding', permissions: '*'}, - {resources: '/api/:userId/downloading', permissions: '*'}, - {resources: '/api/:userId/warning', permissions: '*'}, {resources: '/api/torrents/siteInfo', permissions: ['get']} ] }, diff --git a/modules/torrents/server/routes/peers.server.routes.js b/modules/torrents/server/routes/peers.server.routes.js index c61ef78e..016fe531 100644 --- a/modules/torrents/server/routes/peers.server.routes.js +++ b/modules/torrents/server/routes/peers.server.routes.js @@ -18,13 +18,4 @@ module.exports = function (app) { app.route('/api/my/warning').all(torrentsPolicy.isAllowed) .get(peers.getMyWarning); - app.route('/api/:userId/seeding').all(torrentsPolicy.isAllowed) - .get(peers.getUserSeeding); - - app.route('/api/:userId/downloading').all(torrentsPolicy.isAllowed) - .get(peers.getUserDownloading); - - app.route('/api/:userId/warning').all(torrentsPolicy.isAllowed) - .get(peers.getUserWarning); - }; diff --git a/modules/users/client/config/users-admin.client.routes.js b/modules/users/client/config/users-admin.client.routes.js index cfdd0e55..746ae889 100644 --- a/modules/users/client/config/users-admin.client.routes.js +++ b/modules/users/client/config/users-admin.client.routes.js @@ -42,6 +42,42 @@ data: { pageTitle: 'PAGETITLE.ADMIN_USER_EDIT' } + }) + .state('admin.user-seeding', { + url: '/users/:userId/seeding', + templateUrl: '/modules/users/client/views/admin/user-seeding.client.view.html', + controller: 'UserController', + controllerAs: 'vm', + resolve: { + userResolve: getUser + }, + data: { + pageTitle: 'PAGETITLE.ADMIN_USER_SEEDING' + } + }) + .state('admin.user-leeching', { + url: '/users/:userId/leeching', + templateUrl: '/modules/users/client/views/admin/user-leeching.client.view.html', + controller: 'UserController', + controllerAs: 'vm', + resolve: { + userResolve: getUser + }, + data: { + pageTitle: 'PAGETITLE.ADMIN_USER_LEECHING' + } + }) + .state('admin.user-warning', { + url: '/users/:userId/warning', + templateUrl: '/modules/users/client/views/admin/user-warning.client.view.html', + controller: 'UserController', + controllerAs: 'vm', + resolve: { + userResolve: getUser + }, + data: { + pageTitle: 'PAGETITLE.ADMIN_USER_WARNING' + } }); getUser.$inject = ['$stateParams', 'AdminService']; diff --git a/modules/users/client/controllers/admin/user.client.controller.js b/modules/users/client/controllers/admin/user.client.controller.js index c87e37dc..74cf3a2c 100644 --- a/modules/users/client/controllers/admin/user.client.controller.js +++ b/modules/users/client/controllers/admin/user.client.controller.js @@ -6,16 +6,18 @@ .controller('UserController', UserController); UserController.$inject = ['$scope', '$state', '$window', 'Authentication', 'userResolve', 'Notification', 'NotifycationService', 'MeanTorrentConfig', - 'AdminService', 'ScoreLevelService']; + 'AdminService', 'ScoreLevelService', 'PeersService', 'DownloadService', '$translate']; function UserController($scope, $state, $window, Authentication, user, Notification, NotifycationService, MeanTorrentConfig, AdminService, - ScoreLevelService) { + ScoreLevelService, PeersService, DownloadService, $translate) { var vm = this; vm.authentication = Authentication; vm.user = user; vm.selectedRole = vm.user.roles[0]; vm.userRolesConfig = MeanTorrentConfig.meanTorrentConfig.userRoles; + vm.resourcesTags = MeanTorrentConfig.meanTorrentConfig.resourcesTags; + vm.tmdbConfig = MeanTorrentConfig.meanTorrentConfig.tmdbConfig; vm.announce = MeanTorrentConfig.meanTorrentConfig.announce; vm.remove = remove; vm.update = update; @@ -237,5 +239,125 @@ NotifycationService.showErrorNotify(response.data.message, 'SET_DOWNLOADED_FAILED'); } }; + + /** + * getUserSeedingTorrent + */ + vm.getUserSeedingTorrent = function () { + PeersService.getUserSeedingList({ + userId: vm.user._id + }, function (items) { + console.log(items); + vm.UserSeedingList = items; + for (var i = items.length - 1; i >= 0; i--) { + if (!items[i].torrent) { + items.splice(i, 1); + } + } + }, function (err) { + Notification.error({ + message: ' ' + $translate.instant('SEEDING_LIST_ERROR') + }); + }); + }; + + /** + * getUserLeechingTorrent + */ + vm.getUserLeechingTorrent = function () { + PeersService.getUserLeechingList({ + userId: vm.user._id + }, function (items) { + vm.leechingList = items; + for (var i = items.length - 1; i >= 0; i--) { + if (!items[i].torrent) { + items.splice(i, 1); + } + } + }, function (err) { + Notification.error({ + message: ' ' + $translate.instant('DOWNLOADING_LIST_ERROR') + }); + }); + }; + + /** + * getUserWarningTorrent + */ + vm.getUserWarningTorrent = function () { + PeersService.getUserWarningList({ + userId: vm.user._id + }, function (items) { + vm.UserWarningList = items; + for (var i = items.length - 1; i >= 0; i--) { + if (!items[i].torrent) { + items.splice(i, 1); + } + } + }, function (err) { + Notification.error({ + message: ' ' + $translate.instant('WARNING_LIST_ERROR') + }); + }); + }; + + /** + * getTagTitle + * @param tag: tag name + * @returns {*} + */ + vm.getTagTitle = function (tag, item) { + var tmp = tag; + var find = false; + + angular.forEach(vm.resourcesTags.radio, function (item) { + angular.forEach(item.value, function (sitem) { + if (sitem.name === tag) { + tmp = item.name; + find = true; + } + }); + }); + + if (!find) { + angular.forEach(vm.resourcesTags.checkbox, function (item) { + angular.forEach(item.value, function (sitem) { + if (sitem.name === tag) { + tmp = item.name; + } + }); + }); + } + return tmp; + }; + + /** + * downloadTorrent + * @param id + */ + vm.downloadTorrent = function (id) { + var url = '/api/torrents/download/' + id; + DownloadService.downloadFile(url, null, function (status) { + if (status === 200) { + Notification.success({ + message: ' ' + $translate.instant('TORRENTS_DOWNLOAD_SUCCESSFULLY') + }); + } + }, function (err) { + Notification.error({ + title: 'ERROR', + message: ' ' + $translate.instant('TORRENT_DOWNLOAD_ERROR') + }); + }); + }; + + /** + * openTorrentInfo + * @param id + */ + vm.openTorrentInfo = function (id) { + var url = $state.href('torrents.view', {torrentId: id}); + $window.open(url, '_blank'); + }; } }()); diff --git a/modules/users/client/views/admin/user-leeching.client.view.html b/modules/users/client/views/admin/user-leeching.client.view.html new file mode 100644 index 00000000..282f1bdc --- /dev/null +++ b/modules/users/client/views/admin/user-leeching.client.view.html @@ -0,0 +1,133 @@ +
+
+ +
+

{{vm.user.displayName}} - {{'PAGETITLE.STATUS_DOWNLOADING' | translate}}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
{{ 'TABLE_FIELDS.INFO' | translate}}{{ 'TABLE_FIELDS.VOTES' | translate}}{{ 'TABLE_FIELDS.LIFETIME' | translate}}{{ 'TABLE_FIELDS.SIZE' | translate}} + + {{ 'TABLE_FIELDS.DOWNLOADED_SPEED' | translate}} + + + + {{ 'TABLE_FIELDS.UPLOADED_RATIO_PERCENT' | translate}} + +
+
+
+ ... +
+
+
+ {{item.torrent.resource_detail_info.original_title || item.torrent.resource_detail_info.original_name}} + + / {{item.torrent.resource_detail_info.title}} + + + / {{item.torrent.resource_detail_info.name}} + + + {{ 'CA_DOWNLOAD' | translate}} + +
+ +
+ {{t.name}} +
+ +
{{item.torrent.torrent_filename | filename}}
+ +
+ + + {{'TORRENT_TYPE_LABEL.' + item.torrent.torrent_type.toUpperCase() | translate}} + + + {{'TORRENT_STATUS_LABEL.' + item.torrent.torrent_status.toUpperCase() | translate}} + + + {{ item.torrent.resource_detail_info.release_date}} + + + {{ 'TORRENT_RECOMMEND_LEVEL_ITEM.' + item.torrent.torrent_recommended.toUpperCase() | translate}} + + + {{item.torrent.torrent_sale_status}} {{item.torrent.torrent_sale_expires | unlife}} + + S{{item.torrent_seasons}}E{{item.torrent_episodes}} + + H&R + + + + {{ 'RESOURCESTAGS.' + vm.getTagTitle(t, item.torrent) + '.' + t | translate}} + + +
+
+
+
+ IMDB {{item.torrent.resource_detail_info.vote_average | number : 1}} + {{item.torrent.createdat | life}}{{item.torrent.torrent_size | bytes:2}} +

+ {{item.peer_uploaded | bytes:2}} +

+ +

+ {{item.peer_ratio | ratio}} +

+ +

+ {{item.peer_percent}}% +

+
+
+ +
+
+
diff --git a/modules/users/client/views/admin/user-seeding.client.view.html b/modules/users/client/views/admin/user-seeding.client.view.html new file mode 100644 index 00000000..3aa44028 --- /dev/null +++ b/modules/users/client/views/admin/user-seeding.client.view.html @@ -0,0 +1,128 @@ +
+
+
+

{{vm.user.displayName}} - {{'PAGETITLE.STATUS_SEEDING' | translate}}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
{{ 'TABLE_FIELDS.INFO' | translate}}{{ 'TABLE_FIELDS.VOTES' | translate}}{{ 'TABLE_FIELDS.LIFETIME' | translate}}{{ 'TABLE_FIELDS.SIZE' | translate}} + + {{ 'TABLE_FIELDS.UPLOADED_SPEED' | translate}} + + + + {{ 'TABLE_FIELDS.DOWNLOADED_RATIO' | translate}} + +
+
+
+ ... +
+
+
+ {{item.torrent.resource_detail_info.original_title || item.torrent.resource_detail_info.original_name}} + + / {{item.torrent.resource_detail_info.title}} + + + / {{item.torrent.resource_detail_info.name}} + + + {{ 'CA_DOWNLOAD' | translate}} + +
+ +
+ {{t.name}} +
+ +
{{item.torrent.torrent_filename | filename}}
+ +
+ + + {{'TORRENT_TYPE_LABEL.' + item.torrent.torrent_type.toUpperCase() | translate}} + + + {{'TORRENT_STATUS_LABEL.' + item.torrent.torrent_status.toUpperCase() | translate}} + + + {{ item.torrent.resource_detail_info.release_date}} + + + {{ 'TORRENT_RECOMMEND_LEVEL_ITEM.' + item.torrent.torrent_recommended.toUpperCase() | translate}} + + + {{item.torrent.torrent_sale_status}} {{item.torrent.torrent_sale_expires | unlife}} + + S{{item.torrent_seasons}}E{{item.torrent_episodes}} + + H&R + + + + {{ 'RESOURCESTAGS.' + vm.getTagTitle(t, item.torrent) + '.' + t | translate}} + + +
+
+
+
+ IMDB {{item.torrent.resource_detail_info.vote_average | number : 1}} + {{item.torrent.createdat | life}}{{item.torrent.torrent_size | bytes:2}} +

+ {{item.peer_downloaded | bytes:2}} +

+ +

+ {{item.peer_ratio | ratio}} +

+
+
+ +
+
+
diff --git a/modules/users/client/views/admin/user-warning.client.view.html b/modules/users/client/views/admin/user-warning.client.view.html new file mode 100644 index 00000000..c78d4d89 --- /dev/null +++ b/modules/users/client/views/admin/user-warning.client.view.html @@ -0,0 +1,126 @@ +
+
+
+

{{vm.user.displayName}} - {{'PAGETITLE.STATUS_WARNING' | translate}}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
{{ 'TABLE_FIELDS.INFO' | translate}}{{ 'TABLE_FIELDS.VOTES' | translate}}{{ 'TABLE_FIELDS.LIFETIME' | translate}}{{ 'TABLE_FIELDS.SIZE' | translate}} + + {{ 'TABLE_FIELDS.UP_DOWN_RATIO_TIME' | translate}} + + + CMD +
+
+
+ ... +
+
+
+ {{item.torrent.resource_detail_info.original_title || item.torrent.resource_detail_info.original_name}} + + / {{item.torrent.resource_detail_info.title}} + + + / {{item.torrent.resource_detail_info.name}} + + + {{ 'CA_DOWNLOAD' | translate}} + +
+ +
+ {{t.name}} +
+ +
{{item.torrent.torrent_filename | filename}}
+ +
+ + + {{'TORRENT_TYPE_LABEL.' + item.torrent.torrent_type.toUpperCase() | translate}} + + + {{'TORRENT_STATUS_LABEL.' + item.torrent.torrent_status.toUpperCase() | translate}} + + + {{ item.torrent.resource_detail_info.release_date}} + + + {{ 'TORRENT_RECOMMEND_LEVEL_ITEM.' + item.torrent.torrent_recommended.toUpperCase() | translate}} + + + {{item.torrent.torrent_sale_status}} {{item.torrent.torrent_sale_expires | unlife}} + + S{{item.torrent_seasons}}E{{item.torrent_episodes}} + + H&R + + + + {{ 'RESOURCESTAGS.' + vm.getTagTitle(t, item.torrent) + '.' + t | translate}} + + +
+
+
+
+ IMDB {{item.torrent.resource_detail_info.vote_average | number : 1}} + {{item.torrent.createdat | life}}{{item.torrent.torrent_size | bytes:2}} +
+
+
+
+
diff --git a/modules/users/client/views/admin/view-user.client.view.html b/modules/users/client/views/admin/view-user.client.view.html index 9300d80c..dbc6a12c 100644 --- a/modules/users/client/views/admin/view-user.client.view.html +++ b/modules/users/client/views/admin/view-user.client.view.html @@ -178,18 +178,19 @@
{{ 'STATUS_FIELD.SEEDED' | translate}}:
-
{{ vm.user.seeded }}
+
{{ vm.user.seeded }} {{ 'STATUS_FIELD.DETAIL' | translate }}
{{ 'STATUS_FIELD.LEECHED' | translate}}:
-
{{ vm.user.leeched }}
+
{{ vm.user.leeched }} {{ 'STATUS_FIELD.DETAIL' | translate }}
{{ 'STATUS_FIELD.FINISHED' | translate}}:
-
{{ vm.user.finished }}
+
{{ vm.user.finished }}
{{ 'STATUS_FIELD.HNY_WARNING' | translate}}:
{{vm.user.hnr_warning}} + {{ 'STATUS_FIELD.DETAIL' | translate }}
diff --git a/modules/users/server/controllers/admin.server.controller.js b/modules/users/server/controllers/admin.server.controller.js index bb59e317..41696ea1 100644 --- a/modules/users/server/controllers/admin.server.controller.js +++ b/modules/users/server/controllers/admin.server.controller.js @@ -7,9 +7,14 @@ var path = require('path'), config = require(path.resolve('./config/config')), mongoose = require('mongoose'), User = mongoose.model('User'), + Peer = mongoose.model('Peer'), + Complete = mongoose.model('Complete'), errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')), traceLogCreate = require(path.resolve('./config/lib/tracelog')).create; +const PEERSTATE_SEEDER = 'seeder'; +const PEERSTATE_LEECHER = 'leecher'; + var traceConfig = config.meanTorrentConfig.trace; /** * Show the current user @@ -229,6 +234,89 @@ exports.updateUserDownloaded = function (req, res) { }); }; + +/** + * list user seeding torrents + * @param req + * @param res + */ +exports.getUserSeeding = function (req, res) { + Peer.find({ + user: req.model._id, + peer_status: PEERSTATE_SEEDER + }).sort('-peer_uploaded') + .populate({ + path: 'torrent', + populate: { + path: 'user', + select: 'displayName profileImageURL' + } + }) + .exec(function (err, torrents) { + if (err) { + return res.status(422).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + res.json(torrents); + } + }); +}; + +/** + * list user getUserLeeching torrents + * @param req + * @param res + */ +exports.getUserLeeching = function (req, res) { + Peer.find({ + user: req.model._id, + peer_status: PEERSTATE_LEECHER + }).sort('-peer_downloaded') + .populate({ + path: 'torrent', + populate: { + path: 'user', + select: 'displayName profileImageURL' + } + }) + .exec(function (err, torrents) { + if (err) { + return res.status(422).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + res.json(torrents); + } + }); +}; + +/** + * list user warning torrents + * @param req + * @param res + */ +exports.getUserWarning = function (req, res) { + Complete.find({ + user: req.model._id, + hnr_warning: true + }).populate({ + path: 'torrent', + populate: { + path: 'user', + select: 'displayName profileImageURL' + } + }).exec(function (err, complets) { + if (err) { + return res.status(422).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + res.json(complets); + } + }); +}; + /** * User middleware */ diff --git a/modules/users/server/policies/admin.server.policy.js b/modules/users/server/policies/admin.server.policy.js index ef7af64a..d6acdef5 100644 --- a/modules/users/server/policies/admin.server.policy.js +++ b/modules/users/server/policies/admin.server.policy.js @@ -28,7 +28,10 @@ exports.invokeRolesPolicies = function () { {resources: '/api/users/:userId/status', permissions: '*'}, {resources: '/api/users/:userId/score', permissions: '*'}, {resources: '/api/users/:userId/uploaded', permissions: '*'}, - {resources: '/api/users/:userId/downloaded', permissions: '*'} + {resources: '/api/users/:userId/downloaded', permissions: '*'}, + {resources: '/api/users/:userId/seeding', permissions: '*'}, + {resources: '/api/users/:userId/leeching', permissions: '*'}, + {resources: '/api/users/:userId/warning', permissions: '*'} ] }, { diff --git a/modules/users/server/routes/admin.server.routes.js b/modules/users/server/routes/admin.server.routes.js index 05574062..32cbcedf 100644 --- a/modules/users/server/routes/admin.server.routes.js +++ b/modules/users/server/routes/admin.server.routes.js @@ -32,6 +32,13 @@ module.exports = function (app) { app.route('/api/users/:userId/downloaded') .post(adminPolicy.isAllowed, admin.updateUserDownloaded); + app.route('/api/users/:userId/seeding').all(adminPolicy.isAllowed) + .get(admin.getUserSeeding); + app.route('/api/users/:userId/leeching').all(adminPolicy.isAllowed) + .get(admin.getUserLeeching); + app.route('/api/users/:userId/warning').all(adminPolicy.isAllowed) + .get(admin.getUserWarning); + // Finish by binding the user middleware app.param('userId', admin.userByID); };