mirror of
https://github.com/zoriya/flood.git
synced 2025-12-22 23:25:27 +00:00
246 lines
6.5 KiB
JavaScript
246 lines
6.5 KiB
JavaScript
'use strict';
|
|
|
|
let _ = require('lodash');
|
|
|
|
let regEx = require('../../shared/util/regEx');
|
|
let stringUtil = require('../../shared/util/stringUtil');
|
|
|
|
const CALCULATED_DATA = [
|
|
'eta',
|
|
'percentComplete',
|
|
'status',
|
|
'trackers',
|
|
'totalPeers',
|
|
'totalSeeds'
|
|
];
|
|
|
|
const REQUESTED_DATA = [
|
|
// Torrent List data
|
|
'hash',
|
|
'added',
|
|
'bytesDone',
|
|
'downloadRate',
|
|
'downloadTotal',
|
|
'eta',
|
|
'name',
|
|
'percentComplete',
|
|
'ratio',
|
|
'sizeBytes',
|
|
'status',
|
|
'totalPeers',
|
|
'totalSeeds',
|
|
'uploadTotal',
|
|
'uploadRate',
|
|
'priority',
|
|
'trackers',
|
|
|
|
// Torrent Details data
|
|
'creationDate',
|
|
'freeDiskSpace',
|
|
'connectedPeers',
|
|
'connectedSeeds',
|
|
'message',
|
|
'basePath',
|
|
'ignoreScheduler',
|
|
'comment',
|
|
'isPrivate',
|
|
'directory',
|
|
'filename',
|
|
'isMultiFile'
|
|
];
|
|
|
|
class Torrent {
|
|
constructor(clientData, opts) {
|
|
if (!clientData) {
|
|
return;
|
|
}
|
|
|
|
opts = opts || {};
|
|
this._lastUpdated = opts.currentTime || Date.now();
|
|
this._torrentData = this.getCalculatedClientData(clientData, opts);
|
|
}
|
|
|
|
get data() {
|
|
// TODO: Only return the properties that are different than the last time
|
|
// get was called. Perhaps identify the last time it was called by ID so
|
|
// different consumers can use it. And/or allow users to get everything.
|
|
return Object.assign({}, this._torrentData);
|
|
}
|
|
|
|
get status() {
|
|
return this._torrentData.status || [];
|
|
}
|
|
|
|
get trackers() {
|
|
return this._torrentData.trackers || [];
|
|
}
|
|
|
|
getCalculatedClientData(clientData, opts) {
|
|
let keysToProcess = CALCULATED_DATA;
|
|
let requestedData = REQUESTED_DATA;
|
|
|
|
let torrentData = {};
|
|
|
|
if (opts.requestedData && _.isArray(opts.requestedData)) {
|
|
keysToProcess = opts.requestedData;
|
|
} else if (opts.requestedData) {
|
|
console.warn('Torrent: requestedData mut be an array, using defaults.');
|
|
}
|
|
|
|
keysToProcess = keysToProcess.concat(requestedData);
|
|
|
|
keysToProcess.forEach((key) => {
|
|
let getCalculatedFnName = `getCalculated${stringUtil.capitalize(key)}`;
|
|
|
|
if (typeof this[getCalculatedFnName] === 'function') {
|
|
torrentData[key] = this[getCalculatedFnName](clientData);
|
|
} else {
|
|
torrentData[key] = clientData[key];
|
|
}
|
|
});
|
|
|
|
return torrentData;
|
|
}
|
|
|
|
getPeerCount(string) {
|
|
var markerPosition = string.indexOf('@!@');
|
|
return string.substr(0, markerPosition);
|
|
}
|
|
|
|
getCalculatedEta(clientData) {
|
|
let rate = clientData.downloadRate;
|
|
let completed = clientData.bytesDone;
|
|
let total = clientData.sizeBytes;
|
|
|
|
if (rate > 0) {
|
|
let cumSeconds = (total - completed) / rate;
|
|
|
|
let years = Math.floor(cumSeconds / 31536000);
|
|
let weeks = Math.floor((cumSeconds % 31536000) / 604800);
|
|
let days = Math.floor(((cumSeconds % 31536000) % 604800) / 86400);
|
|
let hours = Math.floor((((cumSeconds % 31536000) % 604800) % 86400) / 3600);
|
|
let minutes = Math.floor(((((cumSeconds % 31536000) % 604800) % 86400) % 3600) / 60);
|
|
let seconds = Math.floor(cumSeconds - (minutes * 60));
|
|
|
|
let timeRemaining = {};
|
|
|
|
if (years > 0) {
|
|
timeRemaining = {years, weeks, cumSeconds};
|
|
} else if (weeks > 0) {
|
|
timeRemaining = {weeks, days, cumSeconds};
|
|
} else if (days > 0) {
|
|
timeRemaining = {days, hours, cumSeconds};
|
|
} else if (hours > 0) {
|
|
timeRemaining = {hours, minutes, cumSeconds};
|
|
} else if (minutes > 0) {
|
|
timeRemaining = {minutes, seconds, cumSeconds};
|
|
} else {
|
|
timeRemaining = {cumSeconds};
|
|
}
|
|
|
|
return timeRemaining;
|
|
} else {
|
|
return 'Infinity';
|
|
}
|
|
}
|
|
|
|
getCalculatedPercentComplete(clientData) {
|
|
let percentComplete = clientData.bytesDone / clientData.sizeBytes * 100;
|
|
|
|
if (percentComplete > 0 && percentComplete < 10) {
|
|
return percentComplete.toFixed(2);
|
|
} else if (percentComplete > 10 && percentComplete < 100) {
|
|
return percentComplete.toFixed(1);
|
|
} else {
|
|
return percentComplete;
|
|
}
|
|
}
|
|
|
|
getCalculatedStatus(clientData) {
|
|
let isHashChecking = clientData.isHashChecking;
|
|
let isComplete = clientData.isComplete;
|
|
let isOpen = clientData.isOpen;
|
|
let uploadRate = clientData.uploadRate;
|
|
let downloadRate = clientData.downloadRate;
|
|
let state = clientData.state;
|
|
let message = clientData.message;
|
|
|
|
let torrentStatus = [];
|
|
|
|
if (isHashChecking === '1') {
|
|
torrentStatus.push('ch'); // checking
|
|
} else if (isComplete === '1' && isOpen === '1' && state === '1') {
|
|
torrentStatus.push('sd'); // seeding
|
|
} else if (isComplete === '1' && isOpen === '1' && state === '0') {
|
|
torrentStatus.push('p'); // paused
|
|
} else if (isComplete === '1' && isOpen === '0') {
|
|
torrentStatus.push('s'); // stopped
|
|
torrentStatus.push('c'); // complete
|
|
} else if (isComplete === '0' && isOpen === '1' && state === '1') {
|
|
torrentStatus.push('d'); // downloading
|
|
} else if (isComplete === '0' && isOpen === '1' && state === '0') {
|
|
torrentStatus.push('p'); // paused
|
|
} else if (isComplete === '0' && isOpen === '0') {
|
|
torrentStatus.push('s'); // stopped
|
|
}
|
|
|
|
if (message.length) {
|
|
torrentStatus.push('e'); // error
|
|
}
|
|
|
|
if (uploadRate === '0' && downloadRate === '0') {
|
|
torrentStatus.push('i');
|
|
} else {
|
|
torrentStatus.push('a');
|
|
}
|
|
|
|
return torrentStatus;
|
|
}
|
|
|
|
getCalculatedTotalPeers(clientData) {
|
|
return this.getPeerCount(clientData.totalPeers);
|
|
}
|
|
|
|
getCalculatedTotalSeeds(clientData) {
|
|
return this.getPeerCount(clientData.totalSeeds);
|
|
}
|
|
|
|
getCalculatedTrackers(clientData) {
|
|
let trackers = clientData.trackers.split('@!@');
|
|
let trackerDomains = [];
|
|
|
|
trackers.forEach((tracker) => {
|
|
let domain = regEx.domainName.exec(tracker);
|
|
|
|
if (domain && domain[1]) {
|
|
domain = domain[1];
|
|
|
|
let domainSubsets = domain.split('.');
|
|
let desiredSubsets = 2;
|
|
let subsetMinLength = 3;
|
|
|
|
if (domainSubsets.length > desiredSubsets) {
|
|
let lastDesiredSubset = domainSubsets[domainSubsets.length - desiredSubsets];
|
|
if (lastDesiredSubset.length <= 3) {
|
|
desiredSubsets++;
|
|
}
|
|
}
|
|
|
|
domain = domainSubsets.slice(desiredSubsets * -1).join('.');
|
|
|
|
trackerDomains.push(domain);
|
|
}
|
|
});
|
|
|
|
return trackerDomains;
|
|
}
|
|
|
|
updateData(clientData, opts) {
|
|
// TODO somehow communicate that only some props were updated
|
|
this._lastUpdated = opts.currentTime || Date.now();
|
|
this._torrentData = this.getCalculatedClientData(clientData, opts);
|
|
}
|
|
}
|
|
|
|
module.exports = Torrent;
|