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 @@
+
|