Created JDownloaderClient.

This commit is contained in:
moonstar-x 2021-06-12 00:19:25 -05:00
parent bc604960fd
commit ee159c081a
4 changed files with 141 additions and 1 deletions

View File

@ -0,0 +1,107 @@
const { JdownloaderClient: Client, JdownloaderClient } = require('jdownloader-client-yaac');
const Logger = require('../utils/Logger');
const Utils = require('../utils/Utils');
const { FatalError, JDownloaderError } = require('../../errors');
const Show = require('../media/Show');
const Movie = require('../media/Movie');
const Media = require('../media/Media');
class JDownloaderClient {
constructor(credentials) {
this.client = new Client(credentials.email, credentials.password);
this.device = null;
}
async load() {
await this.client.core.connect();
this.device = (await this.client.core.listDevices())[0];
}
async addLinks(media) {
if (!(media instanceof Media)) {
throw new FatalError('Invalid Media instance passed to downloader!');
}
await this.client.linkgrabberV2.addLinks(this.device.id, {
destinationFolder: media.getDownloadDestinationFolder(),
packageName: media.getDownloadPackageName(),
links: media.downloadURLs
});
Logger.info(`Added links for ${media.name}`);
}
async getCrawledLinks(mediaDownloadURLs) {
let crawledLinks = await this.client.linkgrabberV2.queryLinks(this.device.id, {
url: true
});
let retries = 0;
while (crawledLinks.length !== mediaDownloadURLs.length && retries < JDownloaderClient.DEFAULTS.MAX_QUERY_RETRIES) {
retries++;
Logger.warn(`Querying links from LinkGrabber, retry ${retries} of ${JDownloaderClient.DEFAULTS.MAX_QUERY_RETRIES}...`);
crawledLinks = await this.client.linkgrabberV2.queryLinks(this.device.id, {
url: true
});
await Utils.wait(JDownloaderClient.DEFAULTS.RETRY_TIMEOUT);
}
if (crawledLinks.length < 1) {
throw new JDownloaderError('Could not fetch crawled links from JDownloader!');
}
return crawledLinks;
}
getRenamedCrawledLinks(crawledLinks, media) {
if (!(media instanceof Media)) {
throw new FatalError('Invalid Media instance passed to downloader!');
}
return crawledLinks.map((link) => {
const ext = link.name.substring(link.name.lastIndexOf('.') + 1);
return {
linkId: link.uuid,
newName: media.getDownloadFilename(ext, link.url)
};
}, []);
}
async renameCrawledLinks(renamedCrawledLinks) {
Logger.info('Renaming crawled links...');
await Utils.mapSeries(renamedCrawledLinks, (renamedLink) => {
return this.client.linkgrabberV2.renameLink(this.device.id, renamedLink)
.then(() => {
Logger.info(`Renamed ${renamedLink.newName}`);
});
});
Logger.success('Renaming complete.');
}
async startDownload(crawledLinks = []) {
if (!crawledLinks.packageUUID) {
throw new JDownloaderError('Cannot start download without packageUUID!');
}
const linkIDs = crawledLinks.map((link) => link.uuid);
if (linkIDs.length < 1) {
throw new JDownloaderError('No links to download!');
}
await this.client.core.callAction('/linkgrabberv2/moveToDownloadlist', this.device.id, [linkIDs, [crawledLinks.packageUUID]]);
Logger.success('Download started.');
}
}
JDownloaderClient.DEFAULTS = {
MAX_QUERY_RETRIES: 6,
RETRY_TIMEOUT: 3000
};
module.exports = JDownloaderClient;

View File

@ -0,0 +1,22 @@
class Utils {
static async mapSeries(iterable, action) {
for (const x of iterable) {
await action(x);
}
return Promise.resolve();
}
static wait(duration) {
return new Promise((resolve) => {
setTimeout(resolve, duration);
});
}
static parseTemplate(template, data) {
return Object.keys(data).reduce((str, key) => {
return str.replace(new RegExp(`{${key}}`, 'gi'), data[key]);
}, template);
}
}
module.exports = Utils;

View File

@ -0,0 +1,9 @@
class JDownloaderError extends Error {
constructor(message) {
super(message);
this.name = 'JDownloaderError';
}
}
module.exports = JDownloaderError;

View File

@ -1,7 +1,9 @@
const FatalError = require('./FatalError');
const ScraperError = require('./ScraperError');
const JDownloaderError = require('./JDownloaderError');
module.exports = {
FatalError,
ScraperError
ScraperError,
JDownloaderError
};