feat(torrents): admin or oper can edit torrent tags in admin panel

This commit is contained in:
OldHawk
2017-10-14 15:27:22 +08:00
parent 6e57b3883d
commit 23d3ff96a0
11 changed files with 201 additions and 4 deletions

View File

@@ -292,6 +292,7 @@
ADMIN_BASIC_SET_HNR: 'SetHnR',
ADMIN_BASIC_UNSET_HNR: 'UnsetHnR',
ADMIN_BASIC_SET_VIP: 'SetVIP',
ADMIN_BASIC_EDIT_TAGS: 'Edit Tags',
ADMIN_BASIC_UNSET_VIP: 'UnsetVIP',
ADMIN_BASIC_TYPE_SET: 'Sale Type',
ADMIN_SALE_TYPE_SET: 'Sale Type Set',
@@ -320,6 +321,8 @@
TORRENT_TOGGLE_HNR_FAILED: 'Torrent toggle HnR tag failed',
TORRENT_TOGGLE_VIP_SUCCESSFULLY: 'Torrent toggle VIP tag successfully',
TORRENT_TOGGLE_VIP_FAILED: 'Torrent toggle VIP tag failed',
TORRENT_SETTAGS_SUCCESSFULLY: 'Torrent tags set successfully',
TORRENT_SETTAGS_ERROR: 'Torrent tags set failed',
//page text
PAGE_TEXT_FIRST: 'First',
@@ -446,6 +449,7 @@
BUTTON_SELECT_PICTURE: 'Select Picture',
BUTTON_USE_THIS_PICTURE: 'Use This Picture',
BUTTON_CANCEL: 'Cancel',
BUTTON_SAVE: 'Save',
BUTTON_SET: 'Set',
BUTTON_COMPLETE: 'Complete',
BUTTON_SAVE_PASSWORD: 'Save Password',

View File

@@ -292,6 +292,7 @@
ADMIN_BASIC_SET_HNR: '设置HnR',
ADMIN_BASIC_UNSET_HNR: '取消HnR',
ADMIN_BASIC_SET_VIP: '设置VIP',
ADMIN_BASIC_EDIT_TAGS: '编辑标签',
ADMIN_BASIC_UNSET_VIP: '取消VIP',
ADMIN_BASIC_TYPE_SET: '设置促销',
ADMIN_SALE_TYPE_SET: '种子促销类型',
@@ -320,6 +321,8 @@
TORRENT_TOGGLE_HNR_FAILED: '改变种子HnR标签失败',
TORRENT_TOGGLE_VIP_SUCCESSFULLY: '改变种子VIP标签成功',
TORRENT_TOGGLE_VIP_FAILED: '改变种子VIP标签失败',
TORRENT_SETTAGS_SUCCESSFULLY: '种子属性标签设置成功',
TORRENT_SETTAGS_ERROR: '种子属性标签设置失败',
//page text
PAGE_TEXT_FIRST: '首页',
@@ -416,6 +419,8 @@
SET_ROLE_FAILED: '用户角色权限设置失败',
SET_STATUS_SUCCESSFULLY: '用户帐号状态设置成功',
SET_STATUS_FAILED: '用户帐号状态设置失败',
SET_IMAGE_SUCCESSFULLY: '用户帐号图片修改成功',
SET_IMAGE_FAILED: '用户帐号图片修改失败',
SCORE_NUMBER: '积分数',
SCORE_TITLE: '修改积分',
@@ -444,6 +449,7 @@
BUTTON_SELECT_PICTURE: '选择图片',
BUTTON_USE_THIS_PICTURE: '应用图片',
BUTTON_CANCEL: '取消',
BUTTON_SAVE: '保存',
BUTTON_SET: '设置',
BUTTON_COMPLETE: '完成',
BUTTON_SAVE_PASSWORD: '保存密码',

View File

@@ -1268,6 +1268,11 @@ body {
}
}
.tags-side-overlay {
top: 50px !important;
max-height: ~"calc(100% - 100px)";
}
.imgCropArea {
background: #E4E4E4;
overflow: hidden;
@@ -1276,7 +1281,7 @@ body {
}
.page-header {
padding-bottom: 0;
padding-bottom: 5px;
}
.ranking-user-img {

View File

@@ -165,7 +165,8 @@
};
/**
* viewMessage
* showMessage
* @param evt
* @param msg
*/
vm.showMessage = function (evt, msg) {

View File

@@ -8,12 +8,12 @@
TorrentsInfoController.$inject = ['$scope', '$state', '$stateParams', '$translate', 'Authentication', 'Notification', 'TorrentsService',
'MeanTorrentConfig', 'DownloadService', '$sce', '$filter', 'CommentsService', 'ModalConfirmService', 'marked', 'Upload', '$timeout',
'SubtitlesService', 'getStorageLangService', 'ScrapeService', 'NotifycationService', 'DebugConsoleService', 'TorrentGetInfoServices',
'localStorageService', '$compile'];
'localStorageService', '$compile', 'SideOverlay'];
function TorrentsInfoController($scope, $state, $stateParams, $translate, Authentication, Notification, TorrentsService, MeanTorrentConfig,
DownloadService, $sce, $filter, CommentsService, ModalConfirmService, marked, Upload, $timeout, SubtitlesService,
getStorageLangService, ScrapeService, NotifycationService, mtDebug, TGI,
localStorageService, $compile) {
localStorageService, $compile, SideOverlay) {
var vm = this;
vm.TGI = TGI;
vm.user = Authentication.user;
@@ -28,6 +28,7 @@
vm.scoreConfig = MeanTorrentConfig.meanTorrentConfig.score;
vm.torrentTabs = [];
vm.searchTags = [];
vm.progress = 0;
/**
@@ -166,6 +167,86 @@
});
};
/**
* editTags
* @param evt
*/
vm.editTags = function (evt) {
vm.searchTags = vm.torrentLocalInfo.torrent_tags;
SideOverlay.open(evt, 'tagsPopupSlide');
};
/**
* hideTagsPopup
*/
vm.hideTagsPopup = function () {
SideOverlay.close(null, 'tagsPopupSlide');
};
/**
* setTorrentTags
*/
vm.setTorrentTags = function () {
mtDebug.info(vm.searchTags);
SideOverlay.close(null, 'tagsPopupSlide');
TorrentsService.setTorrentTags({
_torrentId: vm.torrentLocalInfo._id,
tags: vm.searchTags
}, function (res) {
Notification.success({
message: '<i class="glyphicon glyphicon-ok"></i> ' + $translate.instant('TORRENT_SETTAGS_SUCCESSFULLY')
});
vm.torrentLocalInfo = res;
mtDebug.info(res);
}, function (res) {
Notification.error({
message: res.data.message,
title: '<i class="glyphicon glyphicon-remove"></i> ' + $translate.instant('TORRENT_SETTAGS_ERROR')
});
});
};
/**
* onRadioTagClicked
* @param event
* @param n: tag name
*/
vm.onRadioTagClicked = function (event, n) {
var e = angular.element(event.currentTarget);
if (e.hasClass('btn-success')) {
e.removeClass('btn-success').addClass('btn-default');
vm.searchTags.splice(vm.searchTags.indexOf(n), 1);
} else {
e.addClass('btn-success').removeClass('btn-default').siblings().removeClass('btn-success').addClass('btn-default');
vm.searchTags.push(n);
angular.forEach(e.siblings(), function (se) {
if (vm.searchTags.indexOf(se.value) !== -1) {
vm.searchTags.splice(vm.searchTags.indexOf(se.value), 1);
}
});
}
e.blur();
};
/**
* onCheckboxTagClicked
* @param event
* @param n: tag name
*/
vm.onCheckboxTagClicked = function (event, n) {
var e = angular.element(event.currentTarget);
if (e.hasClass('btn-success')) {
vm.searchTags.push(n);
} else {
vm.searchTags.splice(vm.searchTags.indexOf(n), 1);
}
};
/**
* doScrape
*/

View File

@@ -47,6 +47,13 @@
rlevel: '@_rlevel'
}
},
setTorrentTags: {
method: 'PUT',
url: '/api/torrents/:torrentId/set/tags',
params: {
torrentId: '@_torrentId'
}
},
setReviewedStatus: {
method: 'PUT',
url: '/api/torrents/:torrentId/set/reviewed',

View File

@@ -111,6 +111,8 @@
</dd>
</div>
<div style="margin-top: 20px;"></div>
<div ng-repeat="item in vm.resourcesTags.checkbox | filter:vm.torrentType">
<dt class="h-line">{{ 'RESOURCESTAGS.'+item.name+'.SELF' | translate}}:</dt>
<dd class="h-line">

View File

@@ -371,6 +371,63 @@
</div>
</div>
<!-- =================================================================
side-overlay
================================================================== -->
<div id="tagsPopupSlide" side-overlay="top" side-class="tags-side-overlay" side-modal side-close-on-esc>
<div class="container">
<div class="row">
<div class="col-sm-12 col-md-10 col-md-offset-1">
<div class="page-header"><h3>{{ 'ATTRIBUTE_TAGS' | translate}}</h3></div>
<dl class="dl-horizontal">
<div ng-repeat="item in vm.resourcesTags.radio | filter:vm.torrentLocalInfo.torrent_type">
<dt class="h-line">{{ 'RESOURCESTAGS.'+item.name+'.SELF' | translate}}:</dt>
<dd class="h-line">
<div class="btn-group btn-group-xs" role="group">
<button ng-repeat="sitem in item.value" id="tag_{{sitem.name}}"
class="btn btn-xs btn-tag" value="{{sitem.name}}"
ng-class="vm.searchTags.indexOf(sitem.name) !== -1 ? 'btn-success' : 'btn-default'"
ng-click="vm.onRadioTagClicked($event, sitem.name)">
{{ 'RESOURCESTAGS.' + item.name + '.' + sitem.name.toUpperCase() | translate}}
</button>
</span>
</div>
</dd>
</div>
<div style="margin-top: 20px;"></div>
<div ng-repeat="item in vm.resourcesTags.checkbox | filter:vm.torrentLocalInfo.torrent_type">
<dt class="h-line">{{ 'RESOURCESTAGS.'+item.name+'.SELF' | translate}}:</dt>
<dd class="h-line">
<div class="btn-group btn-group-xs" role="group">
<button ng-repeat="sitem in item.value" id="tag_{{sitem.name}}"
class="btn btn-xs btn-tag" value="{{sitem.name}}"
ng-class="vm.searchTags.indexOf(sitem.name) !== -1 ? 'btn-success' : 'btn-default'"
ng-click="vm.onCheckboxTagClicked($event, sitem.name)"
toggle-class="btn-success" base-class="btn-default" onclick="this.blur();">
{{ 'RESOURCESTAGS.' + item.name + '.' + sitem.name.toUpperCase() | translate}}
</button>
</div>
</dd>
</div>
<div style="margin-top: 20px;">
<dt class="h-line"></dt>
<dd class="h-line">
<button class="btn btn-success btn-width-100" ng-click="vm.setTorrentTags();">
{{ 'BUTTON_SAVE' | translate }}
</button>
<button class="btn btn-default btn-width-100" ng-click="vm.hideTagsPopup();">
{{ 'BUTTON_CANCEL' | translate }}
</button>
</dd>
</div>
</dl>
</div>
</div>
</div>
</div>
<!-- =================================================================
torrentInfo.html
================================================================== -->
@@ -815,6 +872,9 @@
<button class="btn btn-default btn-sm"
ng-click="vm.toggleVIP();">{{ (vm.torrentLocalInfo.torrent_vip ? 'ADMIN_BASIC_UNSET_VIP' : 'ADMIN_BASIC_SET_VIP') | translate}}
</button>
<button class="btn btn-default btn-sm"
ng-click="vm.editTags($event);">{{ 'ADMIN_BASIC_EDIT_TAGS' | translate}}
</button>
<button class="btn btn-default btn-sm" ng-click="vm.doScrape();"
ng-if="!vm.announce.privateTorrentCmsMode">{{ 'ADMIN_BASIC_SCRAPE' | translate}}
</button>

View File

@@ -917,6 +917,33 @@ exports.setRecommendLevel = function (req, res) {
}
};
/**
* setTorrentTags
* @param req
* @param res
*/
exports.setTorrentTags = function (req, res) {
var torrent = req.torrent;
if (req.body.tags) {
torrent.torrent_tags = req.body.tags;
torrent.save(function (err) {
if (err) {
return res.status(422).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.json(torrent);
}
});
} else {
return res.status(422).send({
message: 'params tags error'
});
}
};
/**
* setReviewedStatus
* @param req

View File

@@ -34,6 +34,7 @@ exports.invokeRolesPolicies = function () {
{resources: '/api/torrents/:torrentId/set/saletype/:saleType', permissions: '*'},
{resources: '/api/torrents/:torrentId/set/recommendlevel/:rlevel', permissions: '*'},
{resources: '/api/torrents/:torrentId/set/reviewed', permissions: '*'},
{resources: '/api/torrents/:torrentId/set/tags', permissions: '*'},
{resources: '/api/subtitles/:torrentId', permissions: '*'},
{resources: '/api/subtitles/:torrentId/:subtitleId', permissions: '*'},

View File

@@ -65,5 +65,8 @@ module.exports = function (app) {
app.route('/api/torrents/:torrentId/set/reviewed').all(torrentsPolicy.isAllowed)
.put(torrents.setReviewedStatus);
app.route('/api/torrents/:torrentId/set/tags').all(torrentsPolicy.isAllowed)
.put(torrents.setTorrentTags);
app.param('torrentId', torrents.torrentByID);
};