From 7a687fb1be217a2666e538a710591371ca34384d Mon Sep 17 00:00:00 2001 From: Jesse Chan Date: Thu, 8 Oct 2020 21:13:05 +0800 Subject: [PATCH] server: migrate setTorrentsTags and setTorrentContentsPriority to clientGatewayService --- .../src/javascript/actions/TorrentActions.ts | 17 +++--- .../general/filesystem/DirectoryFileList.tsx | 2 +- .../modals/set-tags-modal/SetTagsModal.tsx | 4 +- .../torrent-details-modal/TorrentFiles.tsx | 5 +- server/models/ClientRequest.js | 32 ----------- server/models/client.js | 24 --------- server/routes/api/torrents.ts | 38 ++++++++++--- server/services/clientGatewayService.ts | 54 +++++++++++++++++++ shared/types/Action.ts | 21 +++++++- 9 files changed, 120 insertions(+), 77 deletions(-) diff --git a/client/src/javascript/actions/TorrentActions.ts b/client/src/javascript/actions/TorrentActions.ts index c9b3353a..665d057a 100644 --- a/client/src/javascript/actions/TorrentActions.ts +++ b/client/src/javascript/actions/TorrentActions.ts @@ -6,7 +6,9 @@ import type { CheckTorrentsOptions, DeleteTorrentsOptions, MoveTorrentsOptions, + SetTorrentContentsPropertiesOptions, SetTorrentsPriorityOptions, + SetTorrentsTagsOptions, StartTorrentsOptions, StopTorrentsOptions, } from '@shared/types/Action'; @@ -240,12 +242,9 @@ const TorrentActions = { }, ), - setFilePriority: (hash: TorrentProperties['hash'], indices: Array, priority: number) => + setFilePriority: (hash: TorrentProperties['hash'], options: SetTorrentContentsPropertiesOptions) => axios - .patch(`${baseURI}api/torrents/${hash}/contents`, { - indices, - priority, - }) + .patch(`${baseURI}api/torrents/${hash}/contents`, options) .then((json) => json.data) .then( () => { @@ -264,13 +263,9 @@ const TorrentActions = { }, ), - setTaxonomy: (hashes: Array, tags: Array, options = {}) => + setTags: (options: SetTorrentsTagsOptions) => axios - .patch(`${baseURI}api/torrents/taxonomy`, { - hashes, - tags, - options, - }) + .patch(`${baseURI}api/torrents/tags`, options) .then((json) => json.data) .then( (data) => { diff --git a/client/src/javascript/components/general/filesystem/DirectoryFileList.tsx b/client/src/javascript/components/general/filesystem/DirectoryFileList.tsx index d53cb372..65ead123 100644 --- a/client/src/javascript/components/general/filesystem/DirectoryFileList.tsx +++ b/client/src/javascript/components/general/filesystem/DirectoryFileList.tsx @@ -82,7 +82,7 @@ class DirectoryFiles extends React.Component { handlePriorityChange(fileIndex: React.ReactText, priorityLevel: number) { this.props.onPriorityChange(); - TorrentActions.setFilePriority(this.props.hash, [Number(fileIndex)], priorityLevel); + TorrentActions.setFilePriority(this.props.hash, {indices: [Number(fileIndex)], priority: priorityLevel}); } render() { diff --git a/client/src/javascript/components/modals/set-tags-modal/SetTagsModal.tsx b/client/src/javascript/components/modals/set-tags-modal/SetTagsModal.tsx index e1ac072e..08863ea3 100644 --- a/client/src/javascript/components/modals/set-tags-modal/SetTagsModal.tsx +++ b/client/src/javascript/components/modals/set-tags-modal/SetTagsModal.tsx @@ -29,7 +29,9 @@ class SetTagsModal extends React.Component TorrentActions.setTaxonomy(TorrentStore.getSelectedTorrents(), tags)); + this.setState({isSettingTags: true}, () => + TorrentActions.setTags({hashes: TorrentStore.getSelectedTorrents(), tags}), + ); }; getActions(): Modal['props']['actions'] { diff --git a/client/src/javascript/components/modals/torrent-details-modal/TorrentFiles.tsx b/client/src/javascript/components/modals/torrent-details-modal/TorrentFiles.tsx index 758a412f..f4436f88 100644 --- a/client/src/javascript/components/modals/torrent-details-modal/TorrentFiles.tsx +++ b/client/src/javascript/components/modals/torrent-details-modal/TorrentFiles.tsx @@ -120,7 +120,10 @@ class TorrentFiles extends React.Component { - indices.forEach((index) => { - this.requests.push(getMethodCall('f.priority.set', [`${hash}:f${index}`, options.priority])); - }); - this.requests.push(getMethodCall('d.update_priorities', [hash])); - }); - } - setSettings(options) { const settings = getEnsuredArray(options.settings); @@ -138,26 +126,6 @@ class ClientRequest { }); } - setTaxonomy(options) { - const methodName = 'd.custom1.set'; - - const tags = options.tags - .reduce((memo, currentTag) => { - const tag = encodeURIComponent(currentTag.trim()); - - if (tag !== '' && memo.indexOf(tag) === -1) { - memo.push(tag); - } - - return memo; - }, []) - .join(','); - - getEnsuredArray(options.hashes).forEach((hash) => { - this.requests.push(getMethodCall(methodName, [hash, tags])); - }); - } - setTracker(options) { const existingTrackerIndex = 0; const {tracker} = options; diff --git a/server/models/client.js b/server/models/client.js index 44abba64..f15000d0 100644 --- a/server/models/client.js +++ b/server/models/client.js @@ -147,18 +147,6 @@ const client = { request.send(); }, - setFilePriority(user, services, hashes, data, callback) { - const {indices, priority} = data; - const request = new ClientRequest(user, services); - - request.setFilePriority({hashes, indices, priority}); - request.onComplete((response, error) => { - services.torrentService.fetchTorrentList(); - callback(response, error); - }); - request.send(); - }, - setSettings(user, services, payloads, callback) { const request = new ClientRequest(user, services); if (payloads.length === 0) return callback({}); @@ -203,18 +191,6 @@ const client = { request.send(); }, - setTaxonomy(user, services, data, callback) { - const request = new ClientRequest(user, services); - - request.setTaxonomy(data); - request.onComplete((response, error) => { - // Fetch the latest torrent list to re-index the taxonomy. - services.torrentService.fetchTorrentList(); - callback(response, error); - }); - request.send(); - }, - setTracker(user, services, data, callback) { const request = new ClientRequest(user, services); diff --git a/server/routes/api/torrents.ts b/server/routes/api/torrents.ts index 041d5fb3..88617fd0 100644 --- a/server/routes/api/torrents.ts +++ b/server/routes/api/torrents.ts @@ -6,7 +6,9 @@ import { CheckTorrentsOptions, DeleteTorrentsOptions, MoveTorrentsOptions, + SetTorrentContentsPropertiesOptions, SetTorrentsPriorityOptions, + SetTorrentsTagsOptions, StartTorrentsOptions, StopTorrentsOptions, } from '@shared/types/Action'; @@ -217,13 +219,27 @@ router.patch('/priority', (req, re }); /** - * PATCH /api/torrents/taxonomy + * PATCH /api/torrents/tags * @summary Sets tags of torrents. * @tags Torrents * @security AuthenticatedUser + * @param {SetTorrentsTagsOptions} request.body.required - options - application/json + * @return {object} 200 - success response - application/json + * @return {Error} 500 - failure response - application/json */ -router.patch('/taxonomy', (req, res) => { - client.setTaxonomy(req.user, req.services, req.body, ajaxUtil.getResponseFn(res)); +router.patch('/tags', (req, res) => { + const callback = ajaxUtil.getResponseFn(res); + + req.services?.clientGatewayService + .setTorrentsTags(req.body) + .then((response) => { + req.services?.torrentService.fetchTorrentList(); + return response; + }) + .then(callback) + .catch((err) => { + callback(null, err); + }); }); /** @@ -262,13 +278,23 @@ router.patch('/tracker', (req, res) => { /** * PATCH /api/torrents/{hash}/contents - * @summary Sets properties of contents of a torrent. Only priority can be set. + * @summary Sets properties of contents of a torrent. Only priority can be set for now. * @tags Torrent * @security AuthenticatedUser * @param {string} hash.path + * @param {SetTorrentContentsPropertiesOptions} request.body.required - options - application/json + * @return {object} 200 - success response - application/json + * @return {Error} 500 - failure response - application/json */ -router.patch('/:hash/contents', (req, res) => { - client.setFilePriority(req.user, req.services, req.params.hash, req.body, ajaxUtil.getResponseFn(res)); +router.patch<{hash: string}, unknown, SetTorrentContentsPropertiesOptions>('/:hash/contents', (req, res) => { + const callback = ajaxUtil.getResponseFn(res); + + req.services?.clientGatewayService + .setTorrentContentsPriority(req.params.hash, req.body) + .then(callback) + .catch((err) => { + callback(null, err); + }); }); /** diff --git a/server/services/clientGatewayService.ts b/server/services/clientGatewayService.ts index 5b7ee1fe..27366171 100644 --- a/server/services/clientGatewayService.ts +++ b/server/services/clientGatewayService.ts @@ -11,7 +11,9 @@ import type { CheckTorrentsOptions, DeleteTorrentsOptions, MoveTorrentsOptions, + SetTorrentContentsPropertiesOptions, SetTorrentsPriorityOptions, + SetTorrentsTagsOptions, StartTorrentsOptions, StopTorrentsOptions, } from '@shared/types/Action'; @@ -356,6 +358,58 @@ class ClientGatewayService extends BaseService { ); } + /** + * Sets tags of torrents + * + * @param {SetTorrentsTagsOptions} options - An object of options... + * @return {Promise} - Resolves with RPC call response or rejects with error. + */ + async setTorrentsTags({hashes, tags}: SetTorrentsTagsOptions) { + const methodCalls = hashes.reduce((accumulator: MultiMethodCalls, hash) => { + accumulator.push({ + methodName: 'd.custom1.set', + params: [hash, encodeTags(tags)], + }); + + return accumulator; + }, []); + + return ( + this.services?.clientRequestManager + .methodCall('system.multicall', [methodCalls]) + .then(this.processClientRequestSuccess, this.processClientRequestError) || Promise.reject() + ); + } + + /** + * Sets priority of contents of a torrent + * @param {string} hash - Hash of the torrent. + * @param {Array} indices - Indices of contents to be altered. + * @param {number} priority - Target priority. + * @return {Promise} - Resolves with RPC call response or rejects with error. + */ + async setTorrentContentsPriority(hash: string, {indices, priority}: SetTorrentContentsPropertiesOptions) { + const methodCalls = indices.reduce((accumulator: MultiMethodCalls, index) => { + accumulator.push({ + methodName: 'f.priority.set', + params: [`${hash}:f${index}`, `${priority}`], + }); + + return accumulator; + }, []); + + methodCalls.push({ + methodName: 'd.update_priorities', + params: [hash], + }); + + return ( + this.services?.clientRequestManager + .methodCall('system.multicall', [methodCalls]) + .then(this.processClientRequestSuccess, this.processClientRequestError) || Promise.reject() + ); + } + /** * Starts torrents * diff --git a/shared/types/Action.ts b/shared/types/Action.ts index c87263b9..5b0e6304 100644 --- a/shared/types/Action.ts +++ b/shared/types/Action.ts @@ -70,7 +70,7 @@ export interface StopTorrentsOptions { // PATCH /api/torrents/priority export interface SetTorrentsPriorityOptions { - // An array of string representing hashes of torrents to operated on + // An array of string representing hashes of torrents to operate on hashes: Array; // Number representing priority: // 0 - DON'T_DOWNLOAD @@ -79,3 +79,22 @@ export interface SetTorrentsPriorityOptions { // 3 - HIGH priority: number; } + +// PATCH /api/torrents/tags +export interface SetTorrentsTagsOptions { + // An array of string representing hashes of torrents to operate on + hashes: Array; + // An array of string representing tags + tags: TorrentProperties['tags']; +} + +// PATCH /api/torrents/{hash}/contents +export interface SetTorrentContentsPropertiesOptions { + // An array of number representing indices of contents of a torrent + indices: Array; + // Number representing priority: + // 0 - DON'T_DOWNLOAD + // 1 - NORMAL + // 2 - HIGH + priority: number; +}