From ebf6bf13d2f4fca5cac36e9d4b9ba4542c2afe11 Mon Sep 17 00:00:00 2001 From: OldHawk Date: Wed, 30 May 2018 19:11:36 +0800 Subject: [PATCH] feat(torrents): new feature for upload torrent screenshots images --- config/env/torrents.js | 2 +- config/lib/multer.js | 45 +++++- modules/core/client/app/trans-string-en.js | 7 + .../mt-images-uploader.client.directive.js | 130 ++++++++++++++++++ .../mt-markdown-editor.client.directive.js | 4 +- .../forums-topic.client.controller.js | 2 +- .../view-message-tickets.client.controller.js | 2 +- .../controllers/uploads.client.controller.js | 42 +++++- modules/torrents/client/less/torrents.less | 88 ++++++++++++ .../views/uploads-torrents.client.view.html | 32 ++++- .../controllers/torrents.server.controller.js | 31 ++++- .../server/models/torrent.server.model.js | 2 + 12 files changed, 369 insertions(+), 18 deletions(-) create mode 100644 modules/core/client/directives/mt-images-uploader.client.directive.js diff --git a/config/env/torrents.js b/config/env/torrents.js index 62c87188..75233458 100644 --- a/config/env/torrents.js +++ b/config/env/torrents.js @@ -1284,7 +1284,7 @@ module.exports = { * @resourcesLanguage: settings for language of dropdown resource info */ tmdbConfig: { - key: 'this is access key from tmdb', + key: '7888f0042a366f63289ff571b68b7ce0', tmdbHome: 'https://www.themoviedb.org', tmdbMovieLinkUrl: 'https://www.themoviedb.org/movie/', tmdbTvserialLinkUrl: 'https://www.themoviedb.org/tv/', diff --git a/config/lib/multer.js b/config/lib/multer.js index 5358f37e..b70b9061 100644 --- a/config/lib/multer.js +++ b/config/lib/multer.js @@ -4,6 +4,13 @@ var path = require('path'), fs = require('fs'), config = require(path.resolve('./config/config')); +/** + * file filter + * @param req + * @param file + * @param callback + * @returns {*} + */ module.exports.imageFileFilter = function (req, file, callback) { if (file.mimetype !== 'image/png' && file.mimetype !== 'image/jpg' && file.mimetype !== 'image/jpeg' && file.mimetype !== 'image/gif' && file.mimetype !== 'image/bmp') { var err = new Error(); @@ -33,6 +40,12 @@ module.exports.subtitleFileFilter = function (req, file, callback) { callback(null, true); }; +/** + * createUploadFilename + * @param req + * @param file + * @param cb + */ module.exports.createUploadFilename = function (req, file, cb) { //var regex = new RegExp(',', 'g'); //var filename = file.originalname.replace(regex, ' '); @@ -76,6 +89,12 @@ module.exports.getUploadDestination = function (req, file, cb) { cb(null, config.uploads.torrent.file.temp); }; +/** + * createUploadAttachFilename + * @param req + * @param file + * @param cb + */ module.exports.createUploadAttachFilename = function (req, file, cb) { var RexStr = /\(|\)|\[|\]|\,/g; var filename = file.originalname.replace(RexStr, function (MatchStr) { @@ -119,6 +138,12 @@ module.exports.getUploadAttachDestination = function (req, file, cb) { cb(null, config.uploads.attach.file.temp); }; +/** + * createUploadSubtitleFilename + * @param req + * @param file + * @param cb + */ module.exports.createUploadSubtitleFilename = function (req, file, cb) { var regex = new RegExp(',', 'g'); var filename = file.originalname.replace(regex, ' '); @@ -136,7 +161,12 @@ module.exports.getUploadSubtitleDestination = function (req, file, cb) { cb(null, config.uploads.subtitle.file.dest); }; - +/** + * createUploadCoverImageFilename + * @param req + * @param file + * @param cb + */ module.exports.createUploadCoverImageFilename = function (req, file, cb) { var RexStr = /\(|\)|\[|\]|\,/g; var filename = file.originalname.replace(RexStr, function (MatchStr) { @@ -175,6 +205,12 @@ module.exports.getUploadCoverImageDestination = function (req, file, cb) { cb(null, config.uploads.torrent.cover.temp); }; +/** + * createUploadTorrentImageFilename + * @param req + * @param file + * @param cb + */ module.exports.createUploadTorrentImageFilename = function (req, file, cb) { var RexStr = /\(|\)|\[|\]|\,/g; var filename = file.originalname.replace(RexStr, function (MatchStr) { @@ -213,7 +249,12 @@ module.exports.getUploadTorrentImageDestination = function (req, file, cb) { cb(null, config.uploads.torrent.image.temp); }; - +/** + * createUploadTicketImageFilename + * @param req + * @param file + * @param cb + */ module.exports.createUploadTicketImageFilename = function (req, file, cb) { var RexStr = /\(|\)|\[|\]|\,/g; var filename = file.originalname.replace(RexStr, function (MatchStr) { diff --git a/modules/core/client/app/trans-string-en.js b/modules/core/client/app/trans-string-en.js index 09116cb8..2c5a47ba 100644 --- a/modules/core/client/app/trans-string-en.js +++ b/modules/core/client/app/trans-string-en.js @@ -558,6 +558,7 @@ TMDB_IS_LOADING: 'Loading the resource info, please wait...', SELECT_SE: '• Please select number of seasons and input number of episodes', SELECT_TAGS: '• Please select any tags for the resources', + SELECT_SCREEN_SHOTS: '• Please select any screenshots for the resources', ENTER_VIDEO_NFO: '• Please enter video and audio NFO', SELECT_MAKER_GROUP: '• Please select resources group upload from and anonymous option', MAKER_NULL: 'NULL', @@ -587,6 +588,12 @@ SELECT_RESOURCE_IMAGE: '• Please select resource cover image', ENTER_RESOURCE_DETAIL_INFO: '• Please enter the resource detail info', + IMAGES_UPLOAD_TOOLTIP1: 'Image files by dragging & dropping or ', + IMAGES_UPLOAD_TOOLTIP2: 'select them', + IMAGES_UPLOADING: 'Uploading', + UPLOAD_IMAGES_SUCCESSFULLY: 'Upload image file successfully', + UPLOAD_IMAGES_FAILED: 'Upload image file failed', + //ranking view PAGE_HEADER_RANKING_UPLOAD: 'Uploaded Ranking', PAGE_HEADER_RANKING_DOWNLOAD: 'Downloaded Ranking', diff --git a/modules/core/client/directives/mt-images-uploader.client.directive.js b/modules/core/client/directives/mt-images-uploader.client.directive.js new file mode 100644 index 00000000..c05855fb --- /dev/null +++ b/modules/core/client/directives/mt-images-uploader.client.directive.js @@ -0,0 +1,130 @@ +(function () { + 'use strict'; + + angular.module('core') + .directive('mtImagesUploader', mtImagesUploader); + + mtImagesUploader.$inject = ['localStorageService', '$compile', 'NotifycationService', '$translate', 'DebugConsoleService', '$timeout']; + + function mtImagesUploader(localStorageService, $compile, NotifycationService, $translate, mtDebug, $timeout) { + var directive = { + restrict: 'A', + require: 'ngModel', + scope: {ngModel: '='}, + replace: true, + link: link + }; + + return directive; + + function link(scope, element, attrs, ngModel) { + if (attrs.uploadMethod) { + initVariable(); + + var eleUploadList = angular.element('
'); + var eleUploadTip = angular.element('
{{\'IMAGES_UPLOAD_TOOLTIP1\' | translate}}{{\'IMAGES_UPLOAD_TOOLTIP2\' | translate}}
'); + var eleUploadBegin = angular.element('
{{\'IMAGES_UPLOADING\' | translate}}: {{uFile.name}}
'); + + element.append(eleUploadList); + element.append(eleUploadTip); + element.append(eleUploadBegin); + + scope.removeImage = function (idx) { + scope.ngModel.splice(idx, 1); + scope.uResourceImages.splice(idx, 1); + }; + + scope.onFileSelected = function (evt) { + doUpload(scope.selectedFile); + }; + + element.bind('dragenter', function (evt) { + evt.stopPropagation(); + evt.preventDefault(); + }); + element.bind('dragover', function (evt) { + evt.stopPropagation(); + evt.preventDefault(); + }); + + element.bind('drop', function (evt) { + evt.stopPropagation(); + evt.preventDefault(); + + doUpload(evt.originalEvent.dataTransfer.files[0]); + return false; + }); + + //define method called from parent scope + //init all variable + scope.$parent.clearResourceImages = function () { + initVariable(); + }; + scope.$parent.$parent.clearResourceImages = scope.$parent.clearResourceImages; + + $compile(element.contents())(scope); + } + + /** + * initVariable + */ + function initVariable() { + scope.ngModel = []; + scope.uFile = undefined; + scope.uProgress = 0; + scope.uResourceImages = []; + } + + /** + * doUpload + * @param sFile + */ + function doUpload(sFile) { + if (!sFile) { + return; + } + + if (sFile.type !== 'image/png' && sFile.type !== 'image/jpg' && sFile.type !== 'image/jpeg' && sFile.type !== 'image/gif' && sFile.type !== 'image/bmp') { + NotifycationService.showErrorNotify($translate.instant('ERROR_ONLY_IMAGE'), 'ERROR'); + console.error($translate.instant('ERROR_ONLY_IMAGE')); + return; + } + + if (attrs.uploadMethod) { + scope.uFile = sFile; + scope.uProgress = 0; + + if (!attrs.uploadDir) { + console.error('uploadMethod must has a uploadDir attr!'); + return; + } + + scope.$parent.$eval(attrs.uploadMethod, { + ufile: scope.uFile, + progressback: function (pr) { + scope.uProgress = pr; + }, + callback: function (fn) { + var uFile = { + name: fn, + size: scope.uFile.size + }; + + scope.ngModel.push(uFile.name); + scope.uResourceImages.push(attrs.uploadDir + uFile.name); + + scope.uFile = undefined; + scope.uProgress = 0; + NotifycationService.showSuccessNotify('UPLOAD_IMAGES_SUCCESSFULLY'); + }, + errback: function (err) { + scope.uFile = undefined; + scope.uProgress = 0; + NotifycationService.showErrorNotify(err.data, 'UPLOAD_IMAGES_FAILED'); + } + }); + } + } + } + } +}()); diff --git a/modules/core/client/directives/mt-markdown-editor.client.directive.js b/modules/core/client/directives/mt-markdown-editor.client.directive.js index e6023b84..41fcd6e7 100644 --- a/modules/core/client/directives/mt-markdown-editor.client.directive.js +++ b/modules/core/client/directives/mt-markdown-editor.client.directive.js @@ -104,10 +104,10 @@ //define method called from parent scope //init all variable - scope.$parent.clearnAttach = function () { + scope.$parent.clearAttach = function () { initVariable(); }; - scope.$parent.$parent.clearnAttach = scope.$parent.clearnAttach; + scope.$parent.$parent.clearAttach = scope.$parent.clearAttach; //hide preview scope.$parent.hidePreview = function () { diff --git a/modules/forums/client/controllers/forums-topic.client.controller.js b/modules/forums/client/controllers/forums-topic.client.controller.js index 6892b9be..adf10e05 100644 --- a/modules/forums/client/controllers/forums-topic.client.controller.js +++ b/modules/forums/client/controllers/forums-topic.client.controller.js @@ -592,7 +592,7 @@ vm.pageChanged(); $scope.$broadcast('show-errors-reset', 'vm.replyForm'); - $scope.clearnAttach(); + $scope.clearAttach(); $scope.hidePreview(); NotifycationService.showSuccessNotify('FORUMS.POST_REPLY_SUCCESSFULLY'); } diff --git a/modules/tickets/client/controllers/admin/view-message-tickets.client.controller.js b/modules/tickets/client/controllers/admin/view-message-tickets.client.controller.js index 44720595..6ecbc94b 100644 --- a/modules/tickets/client/controllers/admin/view-message-tickets.client.controller.js +++ b/modules/tickets/client/controllers/admin/view-message-tickets.client.controller.js @@ -157,7 +157,7 @@ vm.pageChanged(); $scope.$broadcast('show-errors-reset', 'vm.replyForm'); - $scope.clearnAttach(); + $scope.clearAttach(); $scope.hidePreview(); NotifycationService.showSuccessNotify('FORUMS.POST_REPLY_SUCCESSFULLY'); } diff --git a/modules/torrents/client/controllers/uploads.client.controller.js b/modules/torrents/client/controllers/uploads.client.controller.js index 2b64c01f..9d8d2331 100644 --- a/modules/torrents/client/controllers/uploads.client.controller.js +++ b/modules/torrents/client/controllers/uploads.client.controller.js @@ -47,6 +47,7 @@ vm.anonymous = false; vm.videoNfo = ''; vm.customTorrent = {}; + vm.resourceImagesList = []; $rootScope.uploadPopupNotShowNextTime = localStorageService.get('upload_popup_not_show_next_time'); $rootScope.announceConfig = vm.announceConfig; @@ -196,7 +197,7 @@ if (response.data.params) { response.data.message = $translate.instant(response.data.message, response.data.params); } - console.log(response.data.message); + mtDebug.info(response.data.message); NotifycationService.showErrorNotify(response.data.message, 'TORRENTS_UPLOAD_FAILED'); } @@ -274,6 +275,34 @@ }); }; + /** + * uploadTorrentScreenshotsImage + * @param ufile + * @param progressback + * @param callback + * @param errback + */ + vm.uploadTorrentScreenshotsImage = function (ufile, progressback, callback, errback) { + Upload.upload({ + url: '/api/torrents/uploadTorrentImage', + data: { + newTorrentImageFile: ufile + } + }).then(function (res) { + if (callback) { + callback(res.data.filename); + } + }, function (res) { + if (errback && res.status > 0) { + errback(res); + } + }, function (evt) { + if (progressback) { + progressback(parseInt(100.0 * evt.loaded / evt.total, 10)); + } + }); + }; + /** * onTMDBIDKeyDown * @param evt @@ -323,6 +352,7 @@ vm.inputedEpisodesError = undefined; vm.inputedEpisodesOK = false; vm.showResourceTitleInput = false; + vm.showResourceScreenShots = false; vm.showResourcesTag = false; vm.movieinfo = undefined; @@ -455,6 +485,7 @@ vm.tmdb_info_ok = true; vm.tmdb_isloading = false; vm.showResourceTitleInput = true; + vm.showResourceScreenShots = true; vm.showResourcesTag = true; vm.showVideoNfo = true; vm.showAgreeAndSubmit = true; @@ -533,6 +564,7 @@ } else { vm.inputedEpisodesError = false; vm.inputedEpisodesOK = true; + vm.showResourceScreenShots = true; vm.showResourcesTag = true; vm.showResourceTitleInput = true; vm.showVideoNfo = true; @@ -583,7 +615,8 @@ isAnonymous: vm.anonymous, reqId: $state.params.reqId || undefined, - resource_detail_info: vm.movieinfo + resource_detail_info: vm.movieinfo, + screenshots_image: vm.resourceImagesList }); torrent.$save(function (response) { @@ -593,6 +626,7 @@ }); function successCallback(res) { + mtDebug.info(res); vm.isCreating = false; vm.showUploadedPopup(res); } @@ -631,7 +665,8 @@ isAnonymous: vm.anonymous, reqId: $state.params.reqId || undefined, - resource_detail_info: vm.tvinfo + resource_detail_info: vm.tvinfo, + screenshots_image: vm.resourceImagesList }); torrent.$save(function (response) { @@ -641,6 +676,7 @@ }); function successCallback(res) { + mtDebug.info(res); vm.isCreating = false; vm.showUploadedPopup(res); } diff --git a/modules/torrents/client/less/torrents.less b/modules/torrents/client/less/torrents.less index 52e11b5f..d6cb6faa 100644 --- a/modules/torrents/client/less/torrents.less +++ b/modules/torrents/client/less/torrents.less @@ -121,6 +121,93 @@ } } +.resourceScreenshots { + .upload-image-info { + color: #666; + height: 40px; + background-color: #f5f5f5; + border-top: 1px dashed #ddd; + .upload-tooltip { + margin: 8px; + .manual-file-chooser { + position: absolute; + width: 200px; + padding: 5px; + margin-left: 150px; + margin-top: -23px; + cursor: pointer; + opacity: 0.00001; + } + .manual-file-chooser-text { + cursor: pointer; + &:hover { + color: @mt-base-color; + } + } + + } + } + .upload-image-list { + color: #666; + background-color: #f5f5f5; + border-top: 1px dashed #ddd; + overflow-x: scroll; + .image-item { + position: relative; + display: table-cell; + &:last-child { + padding-right: 5px !important; + .fa { + right: 10px; + } + } + img { + height: 150px; + width: auto; + margin-top: 5px; + margin-bottom: 5px; + margin-left: 5px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); + } + .fa { + cursor: pointer; + position: absolute; + right: 5px; + top: 5px; + text-shadow: 0 0 0.1em #fff,-0 -0 0.1em #fff; + &:hover { + color: @mt-base-color; + } + } + } + } +} + +.upload-info { + position: relative; + color: #666; + height: 40px; + background-color: #f5f5f5; + border-top: 1px dashed #ddd; + i { + color: @mt-base-color; + float: left; + margin: 11px 5px; + } + .upload-progress { + height: 30px; + margin: 4px 30px; + max-width: ~"calc(100% - 40px)"; + background-color: @brand-info; + } + .upload-filename { + position: absolute; + top: 8px; + margin-left: 35px; + background-color: transparent; + } +} + /* csslint ignore:start */ .film-strip { border-top: solid 26px; @@ -353,6 +440,7 @@ pre.prettyprint { word-break: break-all; } } + /* csslint ignore:end */ //popup overlay---------------------------------------------- diff --git a/modules/torrents/client/views/uploads-torrents.client.view.html b/modules/torrents/client/views/uploads-torrents.client.view.html index 01e1c4a0..1896434e 100644 --- a/modules/torrents/client/views/uploads-torrents.client.view.html +++ b/modules/torrents/client/views/uploads-torrents.client.view.html @@ -309,7 +309,17 @@ -
+
+
+ +
+
+
+ +
@@ -533,7 +543,17 @@
-
+
+
+ +
+
+
+ +
@@ -655,7 +675,7 @@
-
+
@@ -763,8 +783,8 @@
- @@ -773,7 +793,7 @@
-
+
diff --git a/modules/torrents/server/controllers/torrents.server.controller.js b/modules/torrents/server/controllers/torrents.server.controller.js index 3e5eb8f6..cd8bb0ba 100644 --- a/modules/torrents/server/controllers/torrents.server.controller.js +++ b/modules/torrents/server/controllers/torrents.server.controller.js @@ -374,7 +374,7 @@ exports.uploadTorrentImage = function (req, res) { var upload = multer({ storage: storage, fileFilter: fileFilter, - limits: config.uploads.torrent.cover.limits + limits: config.uploads.torrent.image.limits }).single('newTorrentImageFile'); if (user) { @@ -684,8 +684,10 @@ exports.create = function (req, res) { fs.unlinkSync(oc); } }); + } - //move temp torrent image file to dest directory + //move temp torrent image file to dest directory + if (req.body._uImage && req.body._uImage.length > 0) { req.body._uImage.forEach(function (f) { var oi = config.uploads.torrent.image.temp + f; var ni = config.uploads.torrent.image.dest + f; @@ -707,6 +709,31 @@ exports.create = function (req, res) { }); } + //move temp torrent resource screenshots image file to dest directory + if (req.body.screenshots_image && req.body.screenshots_image.length > 0) { + req.body.screenshots_image.forEach(function (f, key) { + var os = config.uploads.torrent.image.temp + f; + var ns = config.uploads.torrent.image.dest + f; + var cs = config.uploads.torrent.image.crop + f; + + torrent.screenshots_image[key] = dst + f; + + move(os, ns, function (err) { + if (err) { + mtDebug.debugRed(err); + } else { + sharp(ns) + .resize(200) + .toFile(cs, function (err) { + if (err) { + mtDebug.debugError(err); + } + }); + } + }); + }); + } + torrent.save(function (err) { if (err) { return res.status(422).send({ diff --git a/modules/torrents/server/models/torrent.server.model.js b/modules/torrents/server/models/torrent.server.model.js index 17f1f2ab..2cf01b17 100644 --- a/modules/torrents/server/models/torrent.server.model.js +++ b/modules/torrents/server/models/torrent.server.model.js @@ -141,6 +141,8 @@ var TorrentSchema = new Schema({ _ratings: [CommonSchema.RatingSchema], _other_torrents: [], _all_files: [], + + screenshots_image: [String], //resource info resource_detail_info: Object,