diff --git a/config/env/torrents.js b/config/env/torrents.js index 00c9fa7f..722bcde7 100644 --- a/config/env/torrents.js +++ b/config/env/torrents.js @@ -274,7 +274,7 @@ module.exports = { requests: { scoreForAddRequest: 100, rewardsFormDefaultValue: 1000, - requestExpires: 60 * 60 * 1000 * 24 * 7 + requestExpires: 60 * 60 * 1000 * 24 * 1 }, /** @@ -300,7 +300,8 @@ module.exports = { uploadTorrentBeRecommend: {name: 'uploadTorrentBeRecommend', value: 10, enable: true}, uploadSubtitle: {name: 'uploadSubtitle', value: 20, enable: true}, uploadSubtitleBeDeleted: {name: 'uploadSubtitleBeDeleted', value: -20, enable: true}, - postRequest: {name: 'postRequest', value: -100, enable: true}, + + postRequest: {name: 'postRequest', value: -100, enable: true}, //value used requests.scoreForAddRequest, default -100 seedAnnounce: { name: 'seedAnnounce', @@ -424,7 +425,9 @@ module.exports = { torrentDeleted: {title: 'TITLE_TORRENT_DELETED', content: 'CONTENT_TORRENT_DELETED', enable: true}, torrentSubtitleNew: {title: 'TITLE_TORRENT_SUBTITLE_NEW', content: 'CONTENT_TORRENT_SUBTITLE_NEW', enable: true}, torrentSubtitleDeleted: {title: 'TITLE_TORRENT_SUBTITLE_DELETED', content: 'CONTENT_TORRENT_SUBTITLE_DELETED', enable: true}, - torrentUploadRequest: {title: 'TITLE_TORRENT_UPLOAD_REQUEST', content: 'CONTENT_TORRENT_UPLOAD_REQUEST', enable: true} + + RequestTorrentUpload: {title: 'TITLE_REQUEST_TORRENT_UPLOAD', content: 'CONTENT_REQUEST_TORRENT_UPLOAD', enable: true}, + RequestTorrentRespond: {title: 'TITLE_REQUEST_TORRENT_RESPOND', content: 'CONTENT_REQUEST_TORRENT_RESPOND', enable: true} } }, diff --git a/modules/about/server/controllers/makers.server.controller.js b/modules/about/server/controllers/makers.server.controller.js index cae7aa97..ca666574 100644 --- a/modules/about/server/controllers/makers.server.controller.js +++ b/modules/about/server/controllers/makers.server.controller.js @@ -316,10 +316,9 @@ exports.removeMember = function (req, res) { * Maker middleware */ exports.makerByID = function (req, res, next, id) { - if (!mongoose.Types.ObjectId.isValid(id)) { return res.status(400).send({ - message: 'Maker is invalid' + message: 'SERVER.INVALID_OBJECTID' }); } diff --git a/modules/articles/server/controllers/articles.server.controller.js b/modules/articles/server/controllers/articles.server.controller.js index ddba5fe1..d8f1bec4 100644 --- a/modules/articles/server/controllers/articles.server.controller.js +++ b/modules/articles/server/controllers/articles.server.controller.js @@ -96,7 +96,6 @@ exports.list = function (req, res) { * Article middleware */ exports.articleByID = function (req, res, next, id) { - if (!mongoose.Types.ObjectId.isValid(id)) { return res.status(400).send({ message: 'Article is invalid' diff --git a/modules/collections/server/controllers/collections.server.controller.js b/modules/collections/server/controllers/collections.server.controller.js index 8095056d..3497785f 100644 --- a/modules/collections/server/controllers/collections.server.controller.js +++ b/modules/collections/server/controllers/collections.server.controller.js @@ -304,10 +304,9 @@ exports.list = function (req, res) { * Collection middleware */ exports.collectionByID = function (req, res, next, id) { - if (!mongoose.Types.ObjectId.isValid(id)) { return res.status(400).send({ - message: 'COLLECTION_ID_INVALID' + message: 'SERVER.INVALID_OBJECTID' }); } diff --git a/modules/core/client/app/trans-string-en.js b/modules/core/client/app/trans-string-en.js index a1361a13..103baf88 100644 --- a/modules/core/client/app/trans-string-en.js +++ b/modules/core/client/app/trans-string-en.js @@ -733,6 +733,7 @@ FIELD_RESPONSES: 'responses', FIELD_USER: 'User', BTN_EDIT_DESC: 'Edit Desc', + BTN_ACCEPT: 'Accept', EDIT_SUCCESSFULLY: 'Edit request successfully', EDIT_FAILED: 'Edit request failed', DELETE_CONFIRM_OK: 'Delete', @@ -741,6 +742,12 @@ DELETE_CONFIRM_BODY_TEXT: 'Are you sure want to delete this request?', DELETE_SUCCESSFULLY: 'Request deleted successfully', DELETE_FAILED: 'Request deleted failed', + ACCEPT_CONFIRM_OK: 'Accept', + ACCEPT_CONFIRM_CANCEL: 'Cancel', + ACCEPT_CONFIRM_HEADER_TEXT: 'Accept Response Confirm', + ACCEPT_CONFIRM_BODY_TEXT: 'The acceptance of the result can not be changed, Are you sure want to accept this response?', + ACCEPT_SUCCESSFULLY: 'Accept response successfully', + ACCEPT_FAILED: 'Accept response failed', RESPONSE_TITLE: 'Response torrent list:', DESC_LIST: '### NOTE: \n - The list contains only the last `{{days}}` days of the requests. \n - If your response is accepted, the requestor\'s reward score will be automatically transferred to your account. \n - Only the torrents reviewed by the administrator can be accepted by the requestor. \n - The requester can only accept one of the responses. \n - If your response is complains, your account may be punished, Please respond to the user\'s request carefully.', DESC_MY: '### NOTE: \n - If you accept a response, your reward score will be transferred to the respondent\'s account that you accept. \n - Only the torrents reviewed by the administrator can be accepted by you. \n - You can only accept one of the responses. \n - The request over `{{days}}` days has expired and cannot accept the response, you can only post the request again. \n - If your score is maliciously damaged, please mail to the [administrator](mailto:{{admin}})', @@ -1381,7 +1388,10 @@ ONLY_VIP_CAN_DOWNLOAD: 'This torrent is only for Vip users', CAN_NOT_DOWNLOAD_BANNED: 'Download failed, you are banned from server', CAN_NOT_DOWNLOAD_IDLE: 'Download failed, you are idle for long time, before download any things, you should active you account again in profile menu "account status"!', - ALREADY_FOLLOWING: 'You have already following {{name}}' + ALREADY_FOLLOWING: 'You have already following {{name}}', + INVALID_OBJECTID: 'Invalid object id', + REQUEST_STATUS_FINISHED: 'Status error! Request already finished.', + REQUEST_STATUS_EXPIRED: 'Status error! Request already expired.' }, //server message string, content string support markdown and emoji @@ -1463,8 +1473,11 @@ TITLE_TORRENT_SUBTITLE_DELETED: 'Torrent subtitle file was deleted', CONTENT_TORRENT_SUBTITLE_DELETED: ':warning: You uploaded subtitle file **{{subtitle_file_name}}** of torrent [{{torrent_file_name}}](/torrents/{{torrent_id}}) was deleted by user [{{by_name}}](/userinfo/{{by_id}}).', - TITLE_TORRENT_UPLOAD_REQUEST: 'Request has new response uploaded', - CONTENT_TORRENT_UPLOAD_REQUEST: '### New response! \n :new: You posted request [{{request_title}}](/requests/{{request_id}}) has a new response [{{torrent_file_name}}](/torrents/{{torrent_id}}) upload by user [{{by_name}}](/userinfo/{{by_id}}).' + TITLE_REQUEST_TORRENT_UPLOAD: 'Request has new response uploaded', + CONTENT_REQUEST_TORRENT_UPLOAD: '### New response! \n :new: You posted request [{{request_title}}](/requests/{{request_id}}) has a new response torrent [{{torrent_file_name}}](/torrents/{{torrent_id}}) upload by user [{{by_name}}](/userinfo/{{by_id}}).', + + TITLE_REQUEST_TORRENT_RESPOND: 'Response of request was accepted', + CONTENT_REQUEST_TORRENT_RESPOND: '### Response was accepted! \n :clap: Yor uploaded response torrent [{{torrent_file_name}}](/torrents/{{torrent_id}}) of request [{{request_title}}](/requests/{{request_id}}) was accepted by user [{{by_name}}](/userinfo/{{by_id}}), and the rewards score `{{rewards}}` already be automatically transferred to your account.' } }; diff --git a/modules/core/client/app/trans-string-zh.js b/modules/core/client/app/trans-string-zh.js index 35eab57e..7d9dddc4 100644 --- a/modules/core/client/app/trans-string-zh.js +++ b/modules/core/client/app/trans-string-zh.js @@ -733,6 +733,7 @@ FIELD_RESPONSES: '响应', FIELD_USER: '求种用户', BTN_EDIT_DESC: '编辑描述', + BTN_ACCEPT: '接受', EDIT_SUCCESSFULLY: '请求编辑成功', EDIT_FAILED: '请求编辑失败', DELETE_CONFIRM_OK: '删除', @@ -741,7 +742,12 @@ DELETE_CONFIRM_BODY_TEXT: '您确定要删除该条求种请求吗?', DELETE_SUCCESSFULLY: '请求删除成功', DELETE_FAILED: '请求删除失败', - DETAIL_TITLE: '求种详情', + ACCEPT_CONFIRM_OK: '接受', + ACCEPT_CONFIRM_CANCEL: '取消', + ACCEPT_CONFIRM_HEADER_TEXT: '接受响应确认', + ACCEPT_CONFIRM_BODY_TEXT: '接受结果不可更改, 您确定要接受此响应吗?', + ACCEPT_SUCCESSFULLY: '接受响应成功', + ACCEPT_FAILED: '接受响应失败', RESPONSE_TITLE: '响应列表', DESC_LIST: '### 提示: \n - 此列表只包含最近 `{{days}}` 天内发布的求种请求. \n - 如果你的回应被采纳, 请求者悬赏的积分将自动转入你的帐户. \n - 只有被管理员审核通过的种子才能被请求者接受. \n - 请求者只能接受多个响应中的一个. \n - 如果你的响应被请求者投诉,你的帐号就可能会受到惩罚, 请认真响应用户的请求.', DESC_MY: '### 提示: \n - 如果您接受一个响应, 你的悬赏积分就会转入你接受的响应者的帐户. \n - 只有被管理员审核通过的种子才能被您接受. \n - 您只能接受多个响应中的一个. \n - 超过 `{{days}}` 天的请求已经过期且不能接受响应, 如果需要你只能再次发起请求. \n - 如果您的积分受到恶意损害, 请向管理员[投诉](mailto:{{admin}}).', @@ -1382,7 +1388,10 @@ ONLY_VIP_CAN_DOWNLOAD: '该种子只有VIP用户才可以下载', CAN_NOT_DOWNLOAD_BANNED: '下载失败, 您被服务器禁止(banned)', CAN_NOT_DOWNLOAD_IDLE: '下载失败,您闲置了太长时间,在您下载任何种子前, 您必须进入帐户状态页再次激活您的帐户!', - ALREADY_FOLLOWING: '您已经关注过 {{name}} 了' + ALREADY_FOLLOWING: '您已经关注过 {{name}} 了', + INVALID_OBJECTID: '无效的数据记录ID', + REQUEST_STATUS_FINISHED: '状态错误! 求种请求已完成.', + REQUEST_STATUS_EXPIRED: '状态错误! 求种请求已过期.' }, //server message string, content string support markdown and emoji @@ -1464,8 +1473,11 @@ TITLE_TORRENT_SUBTITLE_DELETED: '上传的种子字幕文件被删除', CONTENT_TORRENT_SUBTITLE_DELETED: ':warning: 您为种子 [{{torrent_file_name}}](/torrents/{{torrent_id}}) 上传的字幕文件 {{subtitle_file_name}} 被管理员用户 [{{by_name}}](/userinfo/{{by_id}}) 删除.', - TITLE_TORRENT_UPLOAD_REQUEST: '求种请求有新的响应', - CONTENT_TORRENT_UPLOAD_REQUEST: '### 新的求种响应! \n :new: 您发布的求种请求 [{{request_title}}](/requests/{{request_id}}) 有一个新的上传响应 [{{torrent_file_name}}](/torrents/{{torrent_id}}) 来自用户 [{{by_name}}](/userinfo/{{by_id}}).' + TITLE_REQUEST_TORRENT_UPLOAD: '求种请求有新的响应', + CONTENT_REQUEST_TORRENT_UPLOAD: '### 新的求种响应! \n :new: 您发布的求种请求 [{{request_title}}](/requests/{{request_id}}) 有一个新的上传响应 [{{torrent_file_name}}](/torrents/{{torrent_id}}) 来自用户 [{{by_name}}](/userinfo/{{by_id}}).', + + TITLE_REQUEST_TORRENT_RESPOND: '求种响应被接受', + CONTENT_REQUEST_TORRENT_RESPOND: '### 响应被接受! \n :clap: 您对求种请求 [{{request_title}}](/requests/{{request_id}}) 响应的上传种子 [{{torrent_file_name}}](/torrents/{{torrent_id}}) 已经被用户 [{{by_name}}](/userinfo/{{by_id}}) 接受, 悬赏的 `{{rewards}}` 积分已经转入您的帐户.' } }; diff --git a/modules/core/client/less/btn-size.less b/modules/core/client/less/btn-size.less index 9cb3db02..165d4018 100644 --- a/modules/core/client/less/btn-size.less +++ b/modules/core/client/less/btn-size.less @@ -104,6 +104,10 @@ min-width: 400px !important; } +.width-500 { + min-width: 500px !important; +} + .btn-mt-o { background-image: none; background-repeat: no-repeat; diff --git a/modules/core/client/less/margin.less b/modules/core/client/less/margin.less index 16989263..985f1d37 100644 --- a/modules/core/client/less/margin.less +++ b/modules/core/client/less/margin.less @@ -98,6 +98,10 @@ margin-left: 50px; } +.margin-left-80 { + margin-left: 80px; +} + .padding-top-10 { padding-top: 10px; } diff --git a/modules/core/client/less/mt.less b/modules/core/client/less/mt.less index b6f1f854..a468a01e 100644 --- a/modules/core/client/less/mt.less +++ b/modules/core/client/less/mt.less @@ -848,7 +848,7 @@ body { max-width: 570px; min-width: 560px; } - @media (max-width: @screen-lg-min) { + @media (max-width: @screen-md-max) { max-width: 420px; min-width: 410px; } @@ -863,7 +863,7 @@ body { max-width: 540px; min-width: 530px; } - @media (max-width: @screen-lg-min) { + @media (max-width: @screen-md-max) { max-width: 370px; min-width: 360px; } @@ -1028,7 +1028,7 @@ body { max-width: 700px !important; min-width: 690px !important; } - @media (max-width: @screen-lg-min) { + @media (max-width: @screen-md-max) { max-width: 530px !important; min-width: 520px !important; } diff --git a/modules/forums/server/controllers/forums.admin.server.controller.js b/modules/forums/server/controllers/forums.admin.server.controller.js index ae5ff1f5..2a930d40 100644 --- a/modules/forums/server/controllers/forums.admin.server.controller.js +++ b/modules/forums/server/controllers/forums.admin.server.controller.js @@ -174,10 +174,9 @@ exports.delete = function (req, res) { * Invitation middleware */ exports.forumByID = function (req, res, next, id) { - if (!mongoose.Types.ObjectId.isValid(id)) { return res.status(400).send({ - message: 'Forum is invalid' + message: 'SERVER.INVALID_OBJECTID' }); } diff --git a/modules/forums/server/controllers/forums.server.controller.js b/modules/forums/server/controllers/forums.server.controller.js index 5ec59cdb..5cffc350 100644 --- a/modules/forums/server/controllers/forums.server.controller.js +++ b/modules/forums/server/controllers/forums.server.controller.js @@ -1047,10 +1047,9 @@ exports.attachDownload = function (req, res) { * Invitation middleware */ exports.topicById = function (req, res, next, id) { - if (!mongoose.Types.ObjectId.isValid(id)) { return res.status(400).send({ - message: 'Topic is invalid' + message: 'SERVER.INVALID_OBJECTID' }); } diff --git a/modules/invitations/server/controllers/invitations.server.controller.js b/modules/invitations/server/controllers/invitations.server.controller.js index 088ecda0..0eaacfae 100644 --- a/modules/invitations/server/controllers/invitations.server.controller.js +++ b/modules/invitations/server/controllers/invitations.server.controller.js @@ -452,10 +452,9 @@ exports.countInvitations = function (req, res) { * Invitation middleware */ exports.invitationByID = function (req, res, next, id) { - if (!mongoose.Types.ObjectId.isValid(id)) { return res.status(400).send({ - message: 'Invitation is invalid' + message: 'SERVER.INVALID_OBJECTID' }); } diff --git a/modules/messages/server/controllers/admin-messages.server.controller.js b/modules/messages/server/controllers/admin-messages.server.controller.js index 2155e02c..a69d776c 100644 --- a/modules/messages/server/controllers/admin-messages.server.controller.js +++ b/modules/messages/server/controllers/admin-messages.server.controller.js @@ -95,10 +95,9 @@ exports.setReaded = function (req, res) { * Invitation middleware */ exports.adminMessageByID = function (req, res, next, id) { - if (!mongoose.Types.ObjectId.isValid(id)) { return res.status(400).send({ - message: 'Message is invalid' + message: 'SERVER.INVALID_OBJECTID' }); } diff --git a/modules/messages/server/controllers/messages.server.controller.js b/modules/messages/server/controllers/messages.server.controller.js index c7b92374..cfb4ee03 100644 --- a/modules/messages/server/controllers/messages.server.controller.js +++ b/modules/messages/server/controllers/messages.server.controller.js @@ -334,10 +334,9 @@ exports.countUnread = function (req, res) { * Invitation middleware */ exports.messageByID = function (req, res, next, id) { - if (!mongoose.Types.ObjectId.isValid(id)) { return res.status(400).send({ - message: 'Message is invalid' + message: 'SERVER.INVALID_OBJECTID' }); } diff --git a/modules/requests/client/controllers/requests-list.client.controller.js b/modules/requests/client/controllers/requests-list.client.controller.js index 80e91351..1a4a6a64 100644 --- a/modules/requests/client/controllers/requests-list.client.controller.js +++ b/modules/requests/client/controllers/requests-list.client.controller.js @@ -81,5 +81,18 @@ }); }; + /** + * isExpired + * @returns {boolean} + */ + vm.isExpired = function (r) { + var exp = false; + if (r) { + exp = (r.createdAt + vm.requestsConfig.requestExpires) > Date.now() ? false : true; + } + + return exp; + } + } }()); diff --git a/modules/requests/client/controllers/requests-my.client.controller.js b/modules/requests/client/controllers/requests-my.client.controller.js index 2ee94946..76c2fe6a 100644 --- a/modules/requests/client/controllers/requests-my.client.controller.js +++ b/modules/requests/client/controllers/requests-my.client.controller.js @@ -84,5 +84,18 @@ }); }; + /** + * isExpired + * @returns {boolean} + */ + vm.isExpired = function (r) { + var exp = false; + if (r) { + exp = (r.createdAt + vm.requestsConfig.requestExpires) > Date.now() ? false : true; + } + + return exp; + } + } }()); diff --git a/modules/requests/client/controllers/requests-res.client.controller.js b/modules/requests/client/controllers/requests-res.client.controller.js index 1945591a..79645a48 100644 --- a/modules/requests/client/controllers/requests-res.client.controller.js +++ b/modules/requests/client/controllers/requests-res.client.controller.js @@ -84,5 +84,18 @@ }); }; + /** + * isExpired + * @returns {boolean} + */ + vm.isExpired = function (r) { + var exp = false; + if (r) { + exp = (r.createdAt + vm.requestsConfig.requestExpires) > Date.now() ? false : true; + } + + return exp; + } + } }()); diff --git a/modules/requests/client/controllers/requests-view.client.controller.js b/modules/requests/client/controllers/requests-view.client.controller.js index 24731593..79338789 100644 --- a/modules/requests/client/controllers/requests-view.client.controller.js +++ b/modules/requests/client/controllers/requests-view.client.controller.js @@ -230,5 +230,41 @@ } }; + /** + * acceptResponse + */ + vm.acceptResponse = function (t) { + var modalOptions = { + closeButtonText: $translate.instant('REQUESTS.ACCEPT_CONFIRM_CANCEL'), + actionButtonText: $translate.instant('REQUESTS.ACCEPT_CONFIRM_OK'), + headerText: $translate.instant('REQUESTS.ACCEPT_CONFIRM_HEADER_TEXT'), + bodyText: $translate.instant('REQUESTS.ACCEPT_CONFIRM_BODY_TEXT') + }; + + ModalConfirmService.showModal({}, modalOptions) + .then(function (result) { + vm.request.$accept({ + torrentId: t._id + }, function (res) { + vm.request = res; + NotifycationService.showSuccessNotify('REQUESTS.ACCEPT_SUCCESSFULLY'); + }, function (res) { + NotifycationService.showErrorNotify(res.data.message, 'REQUESTS.ACCEPT_FAILED'); + }); + }); + }; + + /** + * isExpired + * @returns {boolean} + */ + vm.isExpired = function (r) { + var exp = false; + if (r) { + exp = (r.createdAt + vm.requestsConfig.requestExpires) > Date.now() ? false : true; + } + + return exp; + } } }()); diff --git a/modules/requests/client/less/requests.less b/modules/requests/client/less/requests.less index 7ad604de..244ef892 100644 --- a/modules/requests/client/less/requests.less +++ b/modules/requests/client/less/requests.less @@ -53,40 +53,44 @@ } } -.request-list { +.response-list { table { margin-bottom: 0; tbody { tr { - cursor: auto !important; .td-text-overflow { .text-long { @media (min-width: @screen-lg-min) { - max-width: 500px; - min-width: 500px; + max-width: 480px; + min-width: 470px; } - @media (max-width: @screen-lg-min) { - max-width: 420px; - min-width: 420px; + @media (max-width: @screen-md-max) { + max-width: 370px; + min-width: 360px; } - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + } + } + &:hover { + .btn-response-accept { + display: block; } } } } } +} + +.request-list { h4, .h4 { margin: 5px 0; font-size: 16px; } .request-item { .item-desc { - color: #999; + color: #888; } .item-marked-desc { - color: #999; + color: #888; margin-top: 10px; } } @@ -101,30 +105,102 @@ border-radius: 3px; height: 60px; width: 60px; - @media (max-width: @screen-xs-max) { - height: 40px; - width: 40px; - } } } .request-list { margin-left: 80px; - @media (max-width: @screen-xs-max) { - margin-left: 60px; + table { + margin-bottom: 0; + tbody { + tr { + cursor: auto !important; + .td-text-overflow { + .text-long { + @media (min-width: @screen-lg-min) { + max-width: 510px; + min-width: 500px; + } + @media (max-width: @screen-md-max) { + max-width: 410px; + min-width: 400px; + } + } + } + } + } } } + fieldset { + float: left; + margin-right: 5px; + } } .response-wrapper { + margin-bottom: 30px; .response-list { - margin-left: 80px; - @media (max-width: @screen-xs-max) { - margin-left: 60px; + .div-accept { + width: 80px !important; + padding: 0 5px; + } + .btn-response-accept { + display: none; + } + .accepted-item { + td:not(:first-child) { + background-color: lighten(@brand-success, 30%); + } + } + .tb-v-middle { + tbody { + tr { + td:first-child { + padding: 0; + } + } + } + @media (min-width: @screen-sm-min) { + thead { + tr { + th { + &:first-child { + border-top: none !important; + border-bottom: none !important; + } + } + } + } + + tbody { + tr { + td { + &:first-child { + border-top: none; + } + } + &:hover { + td { + &:first-child { + background-color: #fff; + } + } + } + } + &:last-child { + td { + &:first-child { + border-bottom: none !important; + } + } + } + } + } + ; } } .response-title { - margin: 20px 0 5px 0; - font-size: 18px; + margin: 20px 0 5px 88px; + font-size: 16px; font-weight: 500; } } diff --git a/modules/requests/client/services/requests.client.service.js b/modules/requests/client/services/requests.client.service.js index 5baba487..929b90e1 100644 --- a/modules/requests/client/services/requests.client.service.js +++ b/modules/requests/client/services/requests.client.service.js @@ -13,6 +13,14 @@ }, { update: { method: 'PUT' + }, + accept: { + method: 'PUT', + url: '/api/requests/:requestId/accept/:torrentId', + params: { + requestId: '@_id', + torrentId: 'torrentId' + } } }); } diff --git a/modules/requests/client/views/requests-list.client.view.html b/modules/requests/client/views/requests-list.client.view.html index ab466009..23507c2d 100644 --- a/modules/requests/client/views/requests-list.client.view.html +++ b/modules/requests/client/views/requests-list.client.view.html @@ -69,7 +69,7 @@ - +

{{item.title}} @@ -78,7 +78,13 @@
{{item.desc}}
{{'MENU_TORRENTS_SUB.'+item.type.toUpperCase() | translate}} - {{item.createdAt | life }} + + {{item.createdAt | life }} +
+ Expired + Finished +
+ {{item.rewards}} {{item.torrents.length}} {{item.comments.length}} diff --git a/modules/requests/client/views/requests-my.client.view.html b/modules/requests/client/views/requests-my.client.view.html index 56441b0e..3c6d37af 100644 --- a/modules/requests/client/views/requests-my.client.view.html +++ b/modules/requests/client/views/requests-my.client.view.html @@ -69,7 +69,7 @@ - +

{{item.title}} @@ -78,7 +78,13 @@
{{item.desc}}
{{'MENU_TORRENTS_SUB.'+item.type.toUpperCase() | translate}} - {{item.createdAt | life }} + + {{item.createdAt | life }} +
+ Expired + Finished +
+ {{item.rewards}} {{item.torrents.length}} {{item.comments.length}} diff --git a/modules/requests/client/views/requests-res.client.view.html b/modules/requests/client/views/requests-res.client.view.html index d7d7179c..046f96d4 100644 --- a/modules/requests/client/views/requests-res.client.view.html +++ b/modules/requests/client/views/requests-res.client.view.html @@ -69,7 +69,7 @@ - +

{{item.title}} @@ -78,7 +78,13 @@
{{item.desc}}
{{'MENU_TORRENTS_SUB.'+item.type.toUpperCase() | translate}} - {{item.createdAt | life }} + + {{item.createdAt | life }} +
+ Expired + Finished +
+ {{item.rewards}} {{item.torrents.length}} {{item.comments.length}} diff --git a/modules/requests/client/views/requests-view.client.view.html b/modules/requests/client/views/requests-view.client.view.html index 02e463c6..db9e972a 100644 --- a/modules/requests/client/views/requests-view.client.view.html +++ b/modules/requests/client/views/requests-view.client.view.html @@ -32,7 +32,7 @@ - +

{{'MENU_TORRENTS_SUB.'+vm.request.type.toUpperCase() | translate}} - {{vm.request.createdAt | life }} + + {{vm.request.createdAt | life }} +
+ Expired + Finished +
+ {{vm.request.rewards}} {{vm.request.torrents.length}} {{vm.request.comments.length}} @@ -61,27 +67,31 @@ -
- {{ 'DO_UPLOAD' | translate}} - - - +
+
+ + {{ 'DO_UPLOAD' | translate}} + + +
+ +
-

@@ -91,7 +101,7 @@
-
+

{{'REQUESTS.NO_RESPONSES' | translate}}

@@ -99,9 +109,10 @@
{{ 'REQUESTS.RESPONSE_TITLE' | translate}}
- +
+ @@ -116,8 +127,18 @@ - +
{{ 'TABLE_FIELDS.INFO' | translate}} {{ 'TABLE_FIELDS.VOTES' | translate}} {{ 'TABLE_FIELDS.LIFETIME' | translate}}
+ ng-click="vm.TGI.openTorrentDetailInfo(item._id);" + ng-class="{'accepted-item': vm.request.accept == item._id}"> + +
+ +
+
= Date.now()) { + if (!request.accept) { + request.title = req.body.title; + request.desc = req.body.desc; + request.rewards = req.body.rewards; + request.type = req.body.type; - request.save(function (err) { - if (err) { - return res.status(422).send({ - message: errorHandler.getErrorMessage(err) + request.save(function (err) { + if (err) { + return res.status(422).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + res.json(request); + } }); } else { - res.json(request); + return res.status(422).send({ + message: 'SERVER.REQUEST_STATUS_FINISHED' + }); } - }); + } else { + return res.status(422).send({ + message: 'SERVER.REQUEST_STATUS_EXPIRED' + }); + } } else { return res.status(403).json({ message: 'SERVER.USER_IS_NOT_AUTHORIZED' @@ -96,16 +108,102 @@ exports.update = function (req, res) { exports.delete = function (req, res) { var request = req.request; - if (request.user._id === req.user._id || req.user.isOper) { - request.remove(function (err) { - if (err) { - return res.status(422).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.json(request); - } + if (request.user._id.equals(req.user._id) || req.user.isOper) { + if (!request.accept) { + request.remove(function (err) { + if (err) { + return res.status(422).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + res.json(request); + } + }); + } else { + return res.status(422).send({ + message: 'SERVER.REQUEST_STATUS_FINISHED' + }); + } + } else { + return res.status(403).json({ + message: 'SERVER.USER_IS_NOT_AUTHORIZED' }); + } +}; + +/** + * accept + * @param req + * @param res + */ +exports.accept = function (req, res) { + var request = req.request; + var torrent = req.torrent; + + if (request.user._id.equals(req.user._id)) { + if ((request.createdAt + requestsConfig.requestExpires) >= Date.now()) { + if (!request.accept) { + var exist = false; + request.torrents.forEach(function (r) { + if (r._id.equals(torrent._id)) { + exist = true; + } + }); + if (exist) { + if (request.user.score >= request.rewards) { + request.acceptedAt = Date.now(); + request.accept = torrent._id; + + request.save(function (err) { + if (err) { + return res.status(422).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + res.json(request); + + //transfer reward score + request.user.update({ + $inc: {score: -request.rewards} + }).exec(); + torrent.user.update({ + $inc: {score: request.rewards} + }).exec(); + + //add server message + if (serverNoticeConfig.action.RequestTorrentRespond.enable) { + serverMessage.addMessage(torrent.user._id, serverNoticeConfig.action.RequestTorrentRespond.title, serverNoticeConfig.action.RequestTorrentRespond.content, { + request_title: request.title, + request_id: request._id, + torrent_file_name: torrent.torrent_filename, + torrent_id: torrent._id, + by_name: request.user.displayName, + by_id: request.user._id, + rewards: request.rewards + }); + } + } + }); + } else { + return res.status(422).send({ + message: 'SERVER.SCORE_NOT_ENOUGH' + }); + } + } else { + return res.status(403).json({ + message: 'SERVER.INVALID_OBJECTID' + }); + } + } else { + return res.status(422).send({ + message: 'SERVER.REQUEST_STATUS_FINISHED' + }); + } + } else { + return res.status(422).send({ + message: 'SERVER.REQUEST_STATUS_EXPIRED' + }); + } } else { return res.status(403).json({ message: 'SERVER.USER_IS_NOT_AUTHORIZED' @@ -136,6 +234,12 @@ exports.list = function (req, res) { } var condition = {}; + + if (!user_id && !res_id) { + condition.createdAt = { + $gt: Date.now() - requestsConfig.requestExpires + }; + } if (user_id !== undefined) { condition.user = user_id; } @@ -184,7 +288,6 @@ exports.list = function (req, res) { * Maker middleware */ exports.requestByID = function (req, res, next, id) { - if (!mongoose.Types.ObjectId.isValid(id)) { return res.status(400).send({ message: 'SERVER.INVALID_OBJECTID' @@ -192,7 +295,7 @@ exports.requestByID = function (req, res, next, id) { } Request.findById(id) - .populate('user', 'username displayName profileImageURL isVip') + .populate('user', 'username displayName profileImageURL isVip score') .populate({ path: 'torrents', populate: { diff --git a/modules/requests/server/policies/requests.server.policy.js b/modules/requests/server/policies/requests.server.policy.js index 836b6cdb..4d6bcd38 100644 --- a/modules/requests/server/policies/requests.server.policy.js +++ b/modules/requests/server/policies/requests.server.policy.js @@ -16,7 +16,8 @@ exports.invokeRolesPolicies = function () { roles: ['user', 'oper', 'admin'], allows: [ {resources: '/api/requests', permissions: '*'}, - {resources: '/api/requests/:requestId', permissions: '*'} + {resources: '/api/requests/:requestId', permissions: '*'}, + {resources: '/api/requests/:requestId/accept/:torrentId', permissions: '*'} ] }]); }; diff --git a/modules/requests/server/routes/requests.server.routes.js b/modules/requests/server/routes/requests.server.routes.js index b7f64ee4..c4107344 100644 --- a/modules/requests/server/routes/requests.server.routes.js +++ b/modules/requests/server/routes/requests.server.routes.js @@ -16,5 +16,8 @@ module.exports = function (app) { .put(requests.update) .delete(requests.delete); + app.route('/api/requests/:requestId/accept/:torrentId').all(requestsPolicy.isAllowed) + .put(requests.accept); + app.param('requestId', requests.requestByID); }; diff --git a/modules/torrents/server/controllers/completes.server.controller.js b/modules/torrents/server/controllers/completes.server.controller.js index 7acd4097..2acacfde 100644 --- a/modules/torrents/server/controllers/completes.server.controller.js +++ b/modules/torrents/server/controllers/completes.server.controller.js @@ -102,10 +102,9 @@ exports.removeWarning = function (req, res) { * complete middleware */ exports.completeByID = function (req, res, next, id) { - if (!mongoose.Types.ObjectId.isValid(id)) { return res.status(400).send({ - message: 'COMPLETE_ID_INVALID' + message: 'SERVER.INVALID_OBJECTID' }); } diff --git a/modules/torrents/server/controllers/torrents.server.controller.js b/modules/torrents/server/controllers/torrents.server.controller.js index b4d98272..7ccd1614 100644 --- a/modules/torrents/server/controllers/torrents.server.controller.js +++ b/modules/torrents/server/controllers/torrents.server.controller.js @@ -667,8 +667,8 @@ exports.create = function (req, res) { mtDebug.debugError(err); } else { //add server message - if (serverNoticeConfig.action.torrentUploadRequest.enable) { - serverMessage.addMessage(doc.user, serverNoticeConfig.action.torrentUploadRequest.title, serverNoticeConfig.action.torrentUploadRequest.content, { + if (serverNoticeConfig.action.RequestTorrentUpload.enable) { + serverMessage.addMessage(doc.user, serverNoticeConfig.action.RequestTorrentUpload.title, serverNoticeConfig.action.RequestTorrentUpload.content, { request_title: doc.title, request_id: doc._id, torrent_file_name: torrent.torrent_filename, @@ -2048,10 +2048,9 @@ exports.getLeecherUsers = function (req, res) { * Torrent middleware */ exports.torrentByID = function (req, res, next, id) { - if (!mongoose.Types.ObjectId.isValid(id)) { return res.status(400).send({ - message: 'TORRENT_ID_INVALID' + message: 'SERVER.INVALID_OBJECTID' }); } diff --git a/modules/traces/server/controllers/traces.server.controller.js b/modules/traces/server/controllers/traces.server.controller.js index bac13f7c..88a53aa8 100644 --- a/modules/traces/server/controllers/traces.server.controller.js +++ b/modules/traces/server/controllers/traces.server.controller.js @@ -122,10 +122,9 @@ exports.delete = function (req, res) { * Invitation middleware */ exports.traceByID = function (req, res, next, id) { - if (!mongoose.Types.ObjectId.isValid(id)) { return res.status(400).send({ - message: 'Trace is invalid' + message: 'SERVER.INVALID_OBJECTID' }); } diff --git a/modules/users/server/controllers/admin.server.controller.js b/modules/users/server/controllers/admin.server.controller.js index d887b5bf..8190a066 100644 --- a/modules/users/server/controllers/admin.server.controller.js +++ b/modules/users/server/controllers/admin.server.controller.js @@ -644,7 +644,7 @@ exports.resetUserProfileImage = function (req, res) { exports.userByID = function (req, res, next, id) { if (!mongoose.Types.ObjectId.isValid(id)) { return res.status(400).send({ - message: 'User is invalid' + message: 'SERVER.INVALID_OBJECTID' }); } diff --git a/modules/users/server/controllers/users/users.authorization.server.controller.js b/modules/users/server/controllers/users/users.authorization.server.controller.js index 2a1c54c9..665e0adf 100644 --- a/modules/users/server/controllers/users/users.authorization.server.controller.js +++ b/modules/users/server/controllers/users/users.authorization.server.controller.js @@ -13,7 +13,7 @@ var _ = require('lodash'), exports.userByID = function (req, res, next, id) { if (!mongoose.Types.ObjectId.isValid(id)) { return res.status(400).send({ - message: 'User is invalid' + message: 'SERVER.INVALID_OBJECTID' }); }