Created JDownloaderClient.
This commit is contained in:
		
							
								
								
									
										107
									
								
								src/classes/download/JDownloaderClient.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/classes/download/JDownloaderClient.js
									
									
									
									
									
										Normal 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; | ||||
							
								
								
									
										22
									
								
								src/classes/utils/Utils.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/classes/utils/Utils.js
									
									
									
									
									
										Normal 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; | ||||
							
								
								
									
										9
									
								
								src/errors/JDownloaderError.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/errors/JDownloaderError.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| class JDownloaderError extends Error { | ||||
|   constructor(message) { | ||||
|     super(message); | ||||
|      | ||||
|     this.name = 'JDownloaderError'; | ||||
|   } | ||||
| } | ||||
|  | ||||
| module.exports = JDownloaderError; | ||||
| @@ -1,7 +1,9 @@ | ||||
| const FatalError = require('./FatalError'); | ||||
| const ScraperError = require('./ScraperError'); | ||||
| const JDownloaderError = require('./JDownloaderError'); | ||||
|  | ||||
| module.exports = { | ||||
|   FatalError, | ||||
|   ScraperError | ||||
|   ScraperError, | ||||
|   JDownloaderError | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user