From 19328c205cdcc5d847b107666eec29d1892af895 Mon Sep 17 00:00:00 2001 From: OldHawk Date: Tue, 12 Sep 2017 17:07:12 +0800 Subject: [PATCH] feat(H&R): user can remove warning with score number, admin and oper can remove warning too. --- config/env/torrents.js | 2 + modules/core/client/app/trans-string-en.js | 11 ++ modules/core/client/app/trans-string-zh.js | 11 ++ .../controllers/header.client.controller.js | 7 + .../services/completes.client.service.js | 22 +++ .../completes.server.controller.js | 129 ++++++++++++++++++ .../server/models/complete.server.model.js | 8 +- .../server/policies/torrents.server.policy.js | 8 +- .../server/routes/completes.server.routes.js | 15 ++ .../controllers/traces.server.controller.js | 8 ++ .../admin/user.client.controller.js | 44 +++++- .../status/warning.client.controller.js | 49 ++++++- .../views/admin/user-warning.client.view.html | 1 + .../views/status/warning.client.view.html | 1 + 14 files changed, 306 insertions(+), 10 deletions(-) create mode 100644 modules/torrents/client/services/completes.client.service.js create mode 100644 modules/torrents/server/controllers/completes.server.controller.js create mode 100644 modules/torrents/server/routes/completes.server.routes.js diff --git a/config/env/torrents.js b/config/env/torrents.js index 617835e3..90be7fcd 100644 --- a/config/env/torrents.js +++ b/config/env/torrents.js @@ -209,6 +209,8 @@ module.exports = { AdminTorrentSetReviewedStatus: {name: 'AdminTorrentSetReviewedStatus', enable: true}, userInvitationExchange: {name: 'userInvitationExchange', enable: true}, + adminRemoveHnrWarning: {name: 'adminRemoveHnrWarning', enable: true}, + userRemoveHnrWarning: {name: 'userRemoveHnrWarning', enable: true}, userAnnounceData: {name: 'userAnnounceData', enable: true}, userScoreChange: {name: 'userScoreChange', enable: true}, diff --git a/modules/core/client/app/trans-string-en.js b/modules/core/client/app/trans-string-en.js index a498e6ed..067599f2 100644 --- a/modules/core/client/app/trans-string-en.js +++ b/modules/core/client/app/trans-string-en.js @@ -426,6 +426,7 @@ STATUS_SEEDING: 'Seeding torrents', STATUS_DOWNLOADING: 'Downloading torrents', STATUS_WARNING: 'Warning torrents', + BTN_REMOVE_WARNING: 'Remove', UPLOADED_LIST_ERROR: 'Get uploaded list info failed', SEEDING_LIST_ERROR: 'Get seeding list info failed', WARNING_LIST_ERROR: 'Get warning list info failed', @@ -475,6 +476,16 @@ REVIEWED: 'Reviewed' }, + //user status warning list + REMOVE_WARNING_CONFIRM_OK: 'Remove Warning', + REMOVE_WARNING_CONFIRM_CANCEL: 'Cancel', + REMOVE_WARNING_CONFIRM_HEADER_TEXT: 'Remove Confirm', + REMOVE_WARNING_CONFIRM_BODY_TEXT: 'Are you sure want to remove this H&R warning with {{score}} scores?', + REMOVE_WARNING_CONFIRM_BODY_TEXT_ADMIN: 'Are you sure want to remove this H&R warning?', + REMOVE_WARNING_SUCCESSFULLY: 'Remove warning successfully', + REMOVE_WARNING_ERROR: 'Remove warning failed', + REMOVE_WARNING_NO_ENOUGH_SCORE: 'ERROR: no enough score!', + //user score SCORE: { CURRENT_SCORE: 'Current score:', diff --git a/modules/core/client/app/trans-string-zh.js b/modules/core/client/app/trans-string-zh.js index 199b0ad7..88c4fb13 100644 --- a/modules/core/client/app/trans-string-zh.js +++ b/modules/core/client/app/trans-string-zh.js @@ -426,6 +426,7 @@ STATUS_SEEDING: '正在做种的种子', STATUS_DOWNLOADING: '正在下载的种子', STATUS_WARNING: '正被警告的种子', + BTN_REMOVE_WARNING: '移除警告', UPLOADED_LIST_ERROR: '获取我上传的种子列表失败', SEEDING_LIST_ERROR: '获取我正做种的列表失败', WARNING_LIST_ERROR: '获取正被警告种子列表失败', @@ -475,6 +476,16 @@ REVIEWED: '已审核' }, + //user status warning list + REMOVE_WARNING_CONFIRM_OK: '移除警告', + REMOVE_WARNING_CONFIRM_CANCEL: '取消', + REMOVE_WARNING_CONFIRM_HEADER_TEXT: '移除确认', + REMOVE_WARNING_CONFIRM_BODY_TEXT: '您确定愿意使用 {{score}} 积分来移除这个 H&R 警告?', + REMOVE_WARNING_CONFIRM_BODY_TEXT_ADMIN: '您确定要移除这个 H&R 警告?', + REMOVE_WARNING_SUCCESSFULLY: '警告移除成功', + REMOVE_WARNING_ERROR: '警告移除失败', + REMOVE_WARNING_NO_ENOUGH_SCORE: '错误: 积分不足!', + //user score SCORE: { CURRENT_SCORE: '当前积分:', diff --git a/modules/core/client/controllers/header.client.controller.js b/modules/core/client/controllers/header.client.controller.js index bfb38cba..8abf7db9 100644 --- a/modules/core/client/controllers/header.client.controller.js +++ b/modules/core/client/controllers/header.client.controller.js @@ -42,6 +42,13 @@ vm.getInvitationsCount(); }); + /** + * user-hnr-warnings-changed + */ + $scope.$on('user-hnr-warnings-changed', function (event, args) { + vm.getWarning(); + }); + /** * user-unread-count-changed */ diff --git a/modules/torrents/client/services/completes.client.service.js b/modules/torrents/client/services/completes.client.service.js new file mode 100644 index 00000000..418ffd22 --- /dev/null +++ b/modules/torrents/client/services/completes.client.service.js @@ -0,0 +1,22 @@ +(function () { + 'use strict'; + + // Users service used for communicating with the users REST endpoint + angular + .module('torrents.services') + .factory('CompleteService', CompleteService); + + CompleteService.$inject = ['$resource']; + + function CompleteService($resource) { + var completes = $resource('/api/completes/:completeId', { + completeId: '@completeId' + }, { + update: { + method: 'PUT' + } + }); + + return completes; + } +}()); diff --git a/modules/torrents/server/controllers/completes.server.controller.js b/modules/torrents/server/controllers/completes.server.controller.js new file mode 100644 index 00000000..8315d6cb --- /dev/null +++ b/modules/torrents/server/controllers/completes.server.controller.js @@ -0,0 +1,129 @@ +'use strict'; + +/** + * Module dependencies + */ +var path = require('path'), + config = require(path.resolve('./config/config')), + mongoose = require('mongoose'), + errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')), + User = mongoose.model('User'), + Complete = mongoose.model('Complete'), + Torrent = mongoose.model('Torrent'), + async = require('async'), + validator = require('validator'), + traceLogCreate = require(path.resolve('./config/lib/tracelog')).create; + +var hnrConfig = config.meanTorrentConfig.hitAndRun; +var traceConfig = config.meanTorrentConfig.trace; + +/** + * removeWarning + * @param req + * @param res + */ +exports.removeWarning = function (req, res) { + var comp = req.complate; + var user = req.user ? req.user.toJSON() : {}; //fill isVip, isAdmin, isOper in toJSON() + + //console.log(user); + + if (user.isOper) { + comp.hnr_warning = false; + comp.remove_warning_at = Date.now(); + comp.remove_by = req.user; + + comp.save(function (err) { + if (err) { + return res.status(422).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + res.json(comp); + + //update warning number of user + comp.user.update({ + $inc: {hnr_warning: -1} + }).exec(); + + //create trace log + traceLogCreate(req, traceConfig.action.adminRemoveHnrWarning, { + user: comp.user._id, + complete: comp._id + }); + } + }); + } else { + if (!comp.user._id.equals(req.user._id)) { + return res.status(403).json({ + message: 'Only owner or oper can remove warning' + }); + } else { + if (req.user.score < hnrConfig.scoreToRemoveWarning) { + return res.status(422).send({ + message: 'NO_ENOUGH_SCORE_TO_REMOVE_WARNING' + }); + } else { + //update score + req.user.update({ + $set: {score: req.user.score - hnrConfig.scoreToRemoveWarning} + }).exec(); + + comp.hnr_warning = false; + comp.remove_warning_at = Date.now(); + comp.remove_warning_score = hnrConfig.scoreToRemoveWarning; + comp.remove_by = req.user; + + comp.save(function (err) { + if (err) { + return res.status(422).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + res.json(comp); + + //update warning number of user + comp.user.update({ + $inc: {hnr_warning: -1} + }).exec(); + + //create trace log + traceLogCreate(req, traceConfig.action.userRemoveHnrWarning, { + complete: comp._id, + score: hnrConfig.scoreToRemoveWarning + }); + } + }); + } + } + } +}; + + +/** + * complete middleware + */ +exports.completeByID = function (req, res, next, id) { + + if (!mongoose.Types.ObjectId.isValid(id)) { + return res.status(400).send({ + message: 'COMPLETE_ID_INVALID' + }); + } + + Complete.findById(id) + .populate('user', 'username displayName profileImageURL') + .populate('remove_by', 'username displayName profileImageURL') + .exec(function (err, complete) { + if (err) { + return next(err); + } else if (!complete) { + return res.status(404).send({ + message: 'No complete with that identifier has been found' + }); + } + req.complate = complete; + next(); + }); +}; + diff --git a/modules/torrents/server/models/complete.server.model.js b/modules/torrents/server/models/complete.server.model.js index 3257869e..7727155a 100644 --- a/modules/torrents/server/models/complete.server.model.js +++ b/modules/torrents/server/models/complete.server.model.js @@ -57,6 +57,10 @@ var CompleteSchema = new Schema({ type: Date, default: '' }, + remove_by: { + type: Schema.Types.ObjectId, + ref: 'User' + }, createdAt: { type: Date, default: Date.now @@ -109,7 +113,7 @@ function countSeedDay(t) { */ CompleteSchema.methods.countHnRWarning = function (u) { if (this.complete) { - if (this.total_seed_time >= hnrConfig.condition.seedTime || this.total_downloaded === 0 || this.total_ratio >= hnrConfig.condition.ratio) { + if (u.isVip || this.total_seed_time >= hnrConfig.condition.seedTime || this.total_downloaded === 0 || this.total_ratio >= hnrConfig.condition.ratio) { if (this.hnr_warning) { this.update({ $set: {hnr_warning: false} @@ -121,7 +125,7 @@ CompleteSchema.methods.countHnRWarning = function (u) { }).exec(); } } else { - if (!this.hnr_warning) { + if (!this.hnr_warning && !this.remove_by) { this.update({ $set: {hnr_warning: true} }).exec(); diff --git a/modules/torrents/server/policies/torrents.server.policy.js b/modules/torrents/server/policies/torrents.server.policy.js index 9259562b..18763c6e 100644 --- a/modules/torrents/server/policies/torrents.server.policy.js +++ b/modules/torrents/server/policies/torrents.server.policy.js @@ -41,7 +41,9 @@ exports.invokeRolesPolicies = function () { {resources: '/api/my/seeding', permissions: '*'}, {resources: '/api/my/downloading', permissions: '*'}, {resources: '/api/my/warning', permissions: '*'}, - {resources: '/api/torrents/siteInfo', permissions: ['get']} + {resources: '/api/torrents/siteInfo', permissions: ['get']}, + + {resources: '/api/completes/:completeId', permissions: ['put']} ] }, { @@ -66,7 +68,9 @@ exports.invokeRolesPolicies = function () { {resources: '/api/my/seeding', permissions: ['get']}, {resources: '/api/my/downloading', permissions: ['get']}, {resources: '/api/my/warning', permissions: ['get']}, - {resources: '/api/torrents/siteInfo', permissions: ['get']} + {resources: '/api/torrents/siteInfo', permissions: ['get']}, + + {resources: '/api/completes/:completeId', permissions: ['put']} ] }, { diff --git a/modules/torrents/server/routes/completes.server.routes.js b/modules/torrents/server/routes/completes.server.routes.js new file mode 100644 index 00000000..a0ef0e06 --- /dev/null +++ b/modules/torrents/server/routes/completes.server.routes.js @@ -0,0 +1,15 @@ +'use strict'; + +/** + * Module dependencies + */ +var completes = require('../controllers/completes.server.controller'), + torrentsPolicy = require('../policies/torrents.server.policy'); + + +module.exports = function (app) { + app.route('/api/completes/:completeId').all(torrentsPolicy.isAllowed) + .put(completes.removeWarning); + + app.param('completeId', completes.completeByID); +}; diff --git a/modules/traces/server/controllers/traces.server.controller.js b/modules/traces/server/controllers/traces.server.controller.js index 68e1bd10..07154f25 100644 --- a/modules/traces/server/controllers/traces.server.controller.js +++ b/modules/traces/server/controllers/traces.server.controller.js @@ -50,6 +50,14 @@ exports.list = function (req, res) { path: 'content.forum', model: 'Forum' }) + .populate({ + path: 'content.torrent', + model: 'Torrent' + }) + .populate({ + path: 'content.complete', + model: 'Complete' + }) .skip(skip) .limit(limit) .exec(function (err, traces) { diff --git a/modules/users/client/controllers/admin/user.client.controller.js b/modules/users/client/controllers/admin/user.client.controller.js index f16cb091..cdfb082f 100644 --- a/modules/users/client/controllers/admin/user.client.controller.js +++ b/modules/users/client/controllers/admin/user.client.controller.js @@ -6,10 +6,10 @@ .controller('UserController', UserController); UserController.$inject = ['$scope', '$state', '$window', 'Authentication', 'userResolve', 'Notification', 'NotifycationService', 'MeanTorrentConfig', - 'AdminService', 'ScoreLevelService', 'PeersService', 'DownloadService', '$translate', 'TorrentsService']; + 'AdminService', 'ScoreLevelService', 'PeersService', 'DownloadService', '$translate', 'TorrentsService', 'ModalConfirmService', 'CompleteService']; function UserController($scope, $state, $window, Authentication, user, Notification, NotifycationService, MeanTorrentConfig, AdminService, - ScoreLevelService, PeersService, DownloadService, $translate, TorrentsService) { + ScoreLevelService, PeersService, DownloadService, $translate, TorrentsService, ModalConfirmService, CompleteService) { var vm = this; vm.authentication = Authentication; @@ -18,6 +18,7 @@ vm.userRolesConfig = MeanTorrentConfig.meanTorrentConfig.userRoles; vm.resourcesTags = MeanTorrentConfig.meanTorrentConfig.resourcesTags; vm.tmdbConfig = MeanTorrentConfig.meanTorrentConfig.tmdbConfig; + vm.hnrConfig = MeanTorrentConfig.meanTorrentConfig.hitAndRun; vm.announce = MeanTorrentConfig.meanTorrentConfig.announce; vm.remove = remove; vm.update = update; @@ -379,5 +380,44 @@ var url = $state.href('torrents.view', {torrentId: id}); $window.open(url, '_blank'); }; + + /** + * removeWarning + * @param comp + */ + vm.removeWarning = function (comp) { + var modalOptions = { + closeButtonText: $translate.instant('REMOVE_WARNING_CONFIRM_CANCEL'), + actionButtonText: $translate.instant('REMOVE_WARNING_CONFIRM_OK'), + headerText: $translate.instant('REMOVE_WARNING_CONFIRM_HEADER_TEXT'), + bodyText: $translate.instant('REMOVE_WARNING_CONFIRM_BODY_TEXT_ADMIN') + }; + + ModalConfirmService.showModal({}, modalOptions) + .then(function (result) { + if (vm.user.score >= vm.hnrConfig.scoreToRemoveWarning) { + CompleteService.update({ + completeId: comp._id + }, function (response) { + successCallback(response); + }, function (errorResponse) { + errorCallback(errorResponse); + }); + + } else { + NotifycationService.showErrorNotify($translate.instant('REMOVE_WARNING_NO_ENOUGH_SCORE'), 'REMOVE_WARNING_ERROR'); + } + + function successCallback(res) { + vm.UserWarningList.splice(vm.UserWarningList.indexOf(comp), 1); + NotifycationService.showSuccessNotify('REMOVE_WARNING_SUCCESSFULLY'); + } + + function errorCallback(res) { + NotifycationService.showErrorNotify(res.data.message, 'REMOVE_WARNING_ERROR'); + } + }); + + }; } }()); diff --git a/modules/users/client/controllers/status/warning.client.controller.js b/modules/users/client/controllers/status/warning.client.controller.js index c043c7e4..d5242569 100644 --- a/modules/users/client/controllers/status/warning.client.controller.js +++ b/modules/users/client/controllers/status/warning.client.controller.js @@ -5,16 +5,17 @@ .module('users') .controller('WarningController', WarningController); - WarningController.$inject = ['$scope', '$state', '$translate', '$timeout', 'Authentication', 'Notification', 'PeersService', - 'MeanTorrentConfig', '$window', '$filter', 'DownloadService']; + WarningController.$inject = ['$rootScope', '$state', '$translate', '$timeout', 'Authentication', 'Notification', 'PeersService', 'CompleteService', + 'MeanTorrentConfig', '$window', '$filter', 'DownloadService', 'NotifycationService', 'ModalConfirmService']; - function WarningController($scope, $state, $translate, $timeout, Authentication, Notification, PeersService, MeanTorrentConfig, - $window, $filter, DownloadService) { + function WarningController($rootScope, $state, $translate, $timeout, Authentication, Notification, PeersService, CompleteService, MeanTorrentConfig, + $window, $filter, DownloadService, NotifycationService, ModalConfirmService) { var vm = this; vm.user = Authentication.user; vm.tmdbConfig = MeanTorrentConfig.meanTorrentConfig.tmdbConfig; vm.resourcesTags = MeanTorrentConfig.meanTorrentConfig.resourcesTags; vm.torrentSalesType = MeanTorrentConfig.meanTorrentConfig.torrentSalesType; + vm.hnrConfig = MeanTorrentConfig.meanTorrentConfig.hitAndRun; vm.searchTags = []; @@ -102,5 +103,45 @@ var url = $state.href('torrents.view', {torrentId: id}); $window.open(url, '_blank'); }; + + /** + * removeWarning + * @param comp + */ + vm.removeWarning = function (comp) { + var modalOptions = { + closeButtonText: $translate.instant('REMOVE_WARNING_CONFIRM_CANCEL'), + actionButtonText: $translate.instant('REMOVE_WARNING_CONFIRM_OK'), + headerText: $translate.instant('REMOVE_WARNING_CONFIRM_HEADER_TEXT'), + bodyText: $translate.instant('REMOVE_WARNING_CONFIRM_BODY_TEXT', {score: vm.hnrConfig.scoreToRemoveWarning}) + }; + + ModalConfirmService.showModal({}, modalOptions) + .then(function (result) { + if (vm.user.score >= vm.hnrConfig.scoreToRemoveWarning) { + CompleteService.update({ + completeId: comp._id + }, function (response) { + successCallback(response); + }, function (errorResponse) { + errorCallback(errorResponse); + }); + + } else { + NotifycationService.showErrorNotify($translate.instant('REMOVE_WARNING_NO_ENOUGH_SCORE'), 'REMOVE_WARNING_ERROR'); + } + + function successCallback(res) { + vm.warningList.splice(vm.warningList.indexOf(comp), 1); + $rootScope.$broadcast('user-hnr-warnings-changed'); + NotifycationService.showSuccessNotify('REMOVE_WARNING_SUCCESSFULLY'); + } + + function errorCallback(res) { + NotifycationService.showErrorNotify(res.data.message, 'REMOVE_WARNING_ERROR'); + } + }); + + }; } }()); diff --git a/modules/users/client/views/admin/user-warning.client.view.html b/modules/users/client/views/admin/user-warning.client.view.html index 6f585326..86ab88c3 100644 --- a/modules/users/client/views/admin/user-warning.client.view.html +++ b/modules/users/client/views/admin/user-warning.client.view.html @@ -121,6 +121,7 @@

+ diff --git a/modules/users/client/views/status/warning.client.view.html b/modules/users/client/views/status/warning.client.view.html index 6e2c2124..b049dc88 100644 --- a/modules/users/client/views/status/warning.client.view.html +++ b/modules/users/client/views/status/warning.client.view.html @@ -115,6 +115,7 @@

+