server: isolate rTorrent specific functions

This commit is contained in:
Jesse Chan
2020-10-08 23:49:11 +08:00
parent 95cf01f598
commit a75498b110
17 changed files with 119 additions and 117 deletions

View File

@@ -1,7 +1,7 @@
import type {UserInDatabase} from '@shared/schema/Auth';
import ClientGatewayService from './clientGatewayService';
import ClientRequestManager from './clientRequestManager';
import ClientGatewayService from './rTorrent/clientGatewayService';
import ClientRequestManager from './rTorrent/clientRequestManager';
import FeedService from './feedService';
import HistoryService from './historyService';
import NotificationService from './notificationService';

View File

@@ -22,26 +22,26 @@ import type {
StopTorrentsOptions,
} from '@shared/types/api/torrents';
import {accessDeniedError, createDirectory, isAllowedPath, sanitizePath} from '../util/fileUtil';
import BaseService from './BaseService';
import {getFileTreeFromPathsArr} from '../util/fileTreeUtil';
import scgiUtil from '../util/scgiUtil';
import {getMethodCalls, processMethodCallResponse} from '../util/rTorrentMethodCallUtil';
import {accessDeniedError, createDirectory, isAllowedPath, sanitizePath} from '../../util/fileUtil';
import BaseService from '../BaseService';
import {getFileTreeFromPathsArr} from './util/fileTreeUtil';
import scgiUtil from './util/scgiUtil';
import {getMethodCalls, processMethodCallResponse} from './util/rTorrentMethodCallUtil';
import {
encodeTags,
getTorrentETAFromProperties,
getTorrentPercentCompleteFromProperties,
getTorrentStatusFromProperties,
} from '../util/torrentPropertiesUtil';
} from './util/torrentPropertiesUtil';
import {
torrentContentMethodCallConfigs,
torrentListMethodCallConfigs,
torrentPeerMethodCallConfigs,
torrentTrackerMethodCallConfigs,
transferSummaryMethodCallConfigs,
} from '../constants/rTorrentMethodCallConfigs';
} from './constants/methodCallConfigs';
import type {MultiMethodCalls} from '../util/rTorrentMethodCallUtil';
import type {MultiMethodCalls} from './util/rTorrentMethodCallUtil';
const filePathMethodCalls = getMethodCalls({pathComponents: torrentContentMethodCallConfigs.pathComponents});

View File

@@ -1,7 +1,7 @@
import BaseService from './BaseService';
import scgiUtil from '../util/scgiUtil';
import BaseService from '../BaseService';
import scgiUtil from './util/scgiUtil';
import type {MultiMethodCalls} from '../util/rTorrentMethodCallUtil';
import type {MultiMethodCalls} from './util/rTorrentMethodCallUtil';
type MethodCallParameters = Array<string | Buffer | MultiMethodCalls>;

View File

@@ -1,4 +1,4 @@
import regEx from '../../../shared/util/regEx';
import regEx from '../../../../../shared/util/regEx';
import {stringTransformer, booleanTransformer, numberTransformer} from '../../util/rTorrentMethodCallUtil';
const torrentListMethodCallConfigs = {

View File

@@ -0,0 +1,102 @@
import formatUtil from '../../../../shared/util/formatUtil';
import truncateTo from './numberUtils';
import type {TorrentProperties} from '../../../../shared/types/Torrent';
import type {TorrentStatus} from '../../../../shared/constants/torrentStatusMap';
export const getTorrentETAFromProperties = (
processingTorrentProperties: Record<string, unknown>,
): TorrentProperties['eta'] => {
const {downRate, bytesDone, sizeBytes} = processingTorrentProperties;
if (typeof downRate !== 'number' || typeof bytesDone !== 'number' || typeof sizeBytes !== 'number') {
return -1;
}
if (downRate > 0) {
return formatUtil.secondsToDuration((sizeBytes - bytesDone) / downRate);
}
return -1;
};
export const getTorrentPercentCompleteFromProperties = (
processingTorrentProperties: Record<string, unknown>,
): TorrentProperties['percentComplete'] => {
const {bytesDone, sizeBytes} = processingTorrentProperties;
if (typeof bytesDone !== 'number' || typeof sizeBytes !== 'number') {
return 0;
}
const percentComplete = (bytesDone / sizeBytes) * 100;
if (percentComplete > 0 && percentComplete < 10) {
return Number(truncateTo(percentComplete, 2));
}
if (percentComplete > 10 && percentComplete < 100) {
return Number(truncateTo(percentComplete, 1));
}
return percentComplete;
};
export const getTorrentStatusFromProperties = (
processingTorrentProperties: Record<string, unknown>,
): TorrentProperties['status'] => {
const {isHashing, isComplete, isOpen, upRate, downRate, state, message} = processingTorrentProperties;
const torrentStatus: Array<TorrentStatus> = [];
if (isHashing) {
torrentStatus.push('checking');
} else if (isComplete && isOpen && state === '1') {
torrentStatus.push('complete');
torrentStatus.push('seeding');
} else if (isComplete && isOpen && state === '0') {
torrentStatus.push('stopped');
} else if (isComplete && !isOpen) {
torrentStatus.push('stopped');
torrentStatus.push('complete');
} else if (!isComplete && isOpen && state === '1') {
torrentStatus.push('downloading');
} else if (!isComplete && isOpen && state === '0') {
torrentStatus.push('stopped');
} else if (!isComplete && !isOpen) {
torrentStatus.push('stopped');
}
if (typeof message === 'string' && message.length) {
torrentStatus.push('error');
}
if (upRate !== 0) {
torrentStatus.push('activelyUploading');
}
if (downRate !== 0) {
torrentStatus.push('activelyDownloading');
}
if (upRate !== 0 || downRate !== 0) {
torrentStatus.push('active');
} else {
torrentStatus.push('inactive');
}
return torrentStatus;
};
export const encodeTags = (tags: TorrentProperties['tags']): string => {
return tags
.reduce((accumulator: Array<string>, currentTag) => {
const tag = encodeURIComponent(currentTag.trim());
if (tag !== '' && accumulator.indexOf(tag) === -1) {
accumulator.push(tag);
}
return accumulator;
}, [])
.join(',');
};

View File

@@ -4,8 +4,7 @@ import type {TorrentProperties, TorrentListDiff, TorrentListSummary} from '@shar
import BaseService from './BaseService';
import config from '../../config';
import {hasTorrentFinished} from '../util/torrentPropertiesUtil';
import hasTorrentFinished from '../util/torrentPropertiesUtil';
interface TorrentServiceEvents {
FETCH_TORRENT_LIST_SUCCESS: () => void;

View File

@@ -1,93 +1,6 @@
import formatUtil from '../../shared/util/formatUtil';
import truncateTo from './numberUtils';
import type {TorrentProperties} from '../../shared/types/Torrent';
import type {TorrentStatus} from '../../shared/constants/torrentStatusMap';
export const getTorrentETAFromProperties = (
processingTorrentProperties: Record<string, unknown>,
): TorrentProperties['eta'] => {
const {downRate, bytesDone, sizeBytes} = processingTorrentProperties;
if (typeof downRate !== 'number' || typeof bytesDone !== 'number' || typeof sizeBytes !== 'number') {
return -1;
}
if (downRate > 0) {
return formatUtil.secondsToDuration((sizeBytes - bytesDone) / downRate);
}
return -1;
};
export const getTorrentPercentCompleteFromProperties = (
processingTorrentProperties: Record<string, unknown>,
): TorrentProperties['percentComplete'] => {
const {bytesDone, sizeBytes} = processingTorrentProperties;
if (typeof bytesDone !== 'number' || typeof sizeBytes !== 'number') {
return 0;
}
const percentComplete = (bytesDone / sizeBytes) * 100;
if (percentComplete > 0 && percentComplete < 10) {
return Number(truncateTo(percentComplete, 2));
}
if (percentComplete > 10 && percentComplete < 100) {
return Number(truncateTo(percentComplete, 1));
}
return percentComplete;
};
export const getTorrentStatusFromProperties = (
processingTorrentProperties: Record<string, unknown>,
): TorrentProperties['status'] => {
const {isHashing, isComplete, isOpen, upRate, downRate, state, message} = processingTorrentProperties;
const torrentStatus: Array<TorrentStatus> = [];
if (isHashing) {
torrentStatus.push('checking');
} else if (isComplete && isOpen && state === '1') {
torrentStatus.push('complete');
torrentStatus.push('seeding');
} else if (isComplete && isOpen && state === '0') {
torrentStatus.push('stopped');
} else if (isComplete && !isOpen) {
torrentStatus.push('stopped');
torrentStatus.push('complete');
} else if (!isComplete && isOpen && state === '1') {
torrentStatus.push('downloading');
} else if (!isComplete && isOpen && state === '0') {
torrentStatus.push('stopped');
} else if (!isComplete && !isOpen) {
torrentStatus.push('stopped');
}
if (typeof message === 'string' && message.length) {
torrentStatus.push('error');
}
if (upRate !== 0) {
torrentStatus.push('activelyUploading');
}
if (downRate !== 0) {
torrentStatus.push('activelyDownloading');
}
if (upRate !== 0 || downRate !== 0) {
torrentStatus.push('active');
} else {
torrentStatus.push('inactive');
}
return torrentStatus;
};
export const hasTorrentFinished = (
const hasTorrentFinished = (
prevData: Partial<TorrentProperties> = {},
nextData: Partial<TorrentProperties> = {},
): boolean => {
@@ -106,16 +19,4 @@ export const hasTorrentFinished = (
return false;
};
export const encodeTags = (tags: TorrentProperties['tags']): string => {
return tags
.reduce((accumulator: Array<string>, currentTag) => {
const tag = encodeURIComponent(currentTag.trim());
if (tag !== '' && accumulator.indexOf(tag) === -1) {
accumulator.push(tag);
}
return accumulator;
}, [])
.join(',');
};
export default hasTorrentFinished;