mirror of
https://github.com/TheBeastLT/torrentio-scraper.git
synced 2026-04-21 23:31:55 +00:00
add easy debrid moch, closes #320
This commit is contained in:
parent
5bf7fb8230
commit
bf13251928
6 changed files with 120 additions and 2 deletions
|
|
@ -205,6 +205,7 @@ export default function landingTemplate(manifest, config = {}) {
|
||||||
const premiumizeApiKey = config[MochOptions.premiumize.key] || '';
|
const premiumizeApiKey = config[MochOptions.premiumize.key] || '';
|
||||||
const allDebridApiKey = config[MochOptions.alldebrid.key] || '';
|
const allDebridApiKey = config[MochOptions.alldebrid.key] || '';
|
||||||
const debridLinkApiKey = config[MochOptions.debridlink.key] || '';
|
const debridLinkApiKey = config[MochOptions.debridlink.key] || '';
|
||||||
|
const easyDebridApiKey = config[MochOptions.easydebrid.key] || '';
|
||||||
const offcloudApiKey = config[MochOptions.offcloud.key] || '';
|
const offcloudApiKey = config[MochOptions.offcloud.key] || '';
|
||||||
const torboxApiKey = config[MochOptions.torbox.key] || '';
|
const torboxApiKey = config[MochOptions.torbox.key] || '';
|
||||||
const putioKey = config[MochOptions.putio.key] || '';
|
const putioKey = config[MochOptions.putio.key] || '';
|
||||||
|
|
@ -326,6 +327,11 @@ export default function landingTemplate(manifest, config = {}) {
|
||||||
<input type="text" id="iDebridLink" onchange="generateInstallLink()" class="input">
|
<input type="text" id="iDebridLink" onchange="generateInstallLink()" class="input">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="dEasyDebrid">
|
||||||
|
<label class="label" for="iEasyDebrid">EasyDebrid API Key:</label>
|
||||||
|
<input type="text" id="iEasyDebrid" onchange="generateInstallLink()" class="input">
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="dOffcloud">
|
<div id="dOffcloud">
|
||||||
<label class="label" for="iOffcloud">Offcloud API Key (Find it <a href='https://offcloud.com/#/account' target="_blank">here</a>):</label>
|
<label class="label" for="iOffcloud">Offcloud API Key (Find it <a href='https://offcloud.com/#/account' target="_blank">here</a>):</label>
|
||||||
<input type="text" id="iOffcloud" onchange="generateInstallLink()" class="input">
|
<input type="text" id="iOffcloud" onchange="generateInstallLink()" class="input">
|
||||||
|
|
@ -401,6 +407,7 @@ export default function landingTemplate(manifest, config = {}) {
|
||||||
$('#iPremiumize').val("${premiumizeApiKey}");
|
$('#iPremiumize').val("${premiumizeApiKey}");
|
||||||
$('#iAllDebrid').val("${allDebridApiKey}");
|
$('#iAllDebrid').val("${allDebridApiKey}");
|
||||||
$('#iDebridLink').val("${debridLinkApiKey}");
|
$('#iDebridLink').val("${debridLinkApiKey}");
|
||||||
|
$('#iEasyDebrid').val("${easyDebridApiKey}");
|
||||||
$('#iOffcloud').val("${offcloudApiKey}");
|
$('#iOffcloud').val("${offcloudApiKey}");
|
||||||
$('#iTorbox').val("${torboxApiKey}");
|
$('#iTorbox').val("${torboxApiKey}");
|
||||||
$('#iPutioClientId').val("${putioClientId}");
|
$('#iPutioClientId').val("${putioClientId}");
|
||||||
|
|
@ -428,6 +435,7 @@ export default function landingTemplate(manifest, config = {}) {
|
||||||
$('#dPremiumize').toggle(provider === '${MochOptions.premiumize.key}');
|
$('#dPremiumize').toggle(provider === '${MochOptions.premiumize.key}');
|
||||||
$('#dAllDebrid').toggle(provider === '${MochOptions.alldebrid.key}');
|
$('#dAllDebrid').toggle(provider === '${MochOptions.alldebrid.key}');
|
||||||
$('#dDebridLink').toggle(provider === '${MochOptions.debridlink.key}');
|
$('#dDebridLink').toggle(provider === '${MochOptions.debridlink.key}');
|
||||||
|
$('#dEasyDebrid').toggle(provider === '${MochOptions.easydebrid.key}');
|
||||||
$('#dOffcloud').toggle(provider === '${MochOptions.offcloud.key}');
|
$('#dOffcloud').toggle(provider === '${MochOptions.offcloud.key}');
|
||||||
$('#dTorbox').toggle(provider === '${MochOptions.torbox.key}');
|
$('#dTorbox').toggle(provider === '${MochOptions.torbox.key}');
|
||||||
$('#dPutio').toggle(provider === '${MochOptions.putio.key}');
|
$('#dPutio').toggle(provider === '${MochOptions.putio.key}');
|
||||||
|
|
@ -447,6 +455,7 @@ export default function landingTemplate(manifest, config = {}) {
|
||||||
const allDebridValue = $('#iAllDebrid').val() || '';
|
const allDebridValue = $('#iAllDebrid').val() || '';
|
||||||
const debridLinkValue = $('#iDebridLink').val() || ''
|
const debridLinkValue = $('#iDebridLink').val() || ''
|
||||||
const premiumizeValue = $('#iPremiumize').val() || '';
|
const premiumizeValue = $('#iPremiumize').val() || '';
|
||||||
|
const easyDebridValue = $('#iEasyDebrid').val() || '';
|
||||||
const offcloudValue = $('#iOffcloud').val() || '';
|
const offcloudValue = $('#iOffcloud').val() || '';
|
||||||
const torboxValue = $('#iTorbox').val() || '';
|
const torboxValue = $('#iTorbox').val() || '';
|
||||||
const putioClientIdValue = $('#iPutioClientId').val() || '';
|
const putioClientIdValue = $('#iPutioClientId').val() || '';
|
||||||
|
|
@ -465,6 +474,7 @@ export default function landingTemplate(manifest, config = {}) {
|
||||||
const premiumize = premiumizeValue.length && premiumizeValue.trim();
|
const premiumize = premiumizeValue.length && premiumizeValue.trim();
|
||||||
const allDebrid = allDebridValue.length && allDebridValue.trim();
|
const allDebrid = allDebridValue.length && allDebridValue.trim();
|
||||||
const debridLink = debridLinkValue.length && debridLinkValue.trim();
|
const debridLink = debridLinkValue.length && debridLinkValue.trim();
|
||||||
|
const easyDebrid = easyDebridValue.length && easyDebridValue.trim();
|
||||||
const offcloud = offcloudValue.length && offcloudValue.trim();
|
const offcloud = offcloudValue.length && offcloudValue.trim();
|
||||||
const torbox = torboxValue.length && torboxValue.trim();
|
const torbox = torboxValue.length && torboxValue.trim();
|
||||||
const putio = putioClientIdValue.length && putioTokenValue.length && putioClientIdValue.trim() + '@' + putioTokenValue.trim();
|
const putio = putioClientIdValue.length && putioTokenValue.length && putioClientIdValue.trim() + '@' + putioTokenValue.trim();
|
||||||
|
|
@ -484,6 +494,7 @@ export default function landingTemplate(manifest, config = {}) {
|
||||||
['${MochOptions.premiumize.key}', premiumize],
|
['${MochOptions.premiumize.key}', premiumize],
|
||||||
['${MochOptions.alldebrid.key}', allDebrid],
|
['${MochOptions.alldebrid.key}', allDebrid],
|
||||||
['${MochOptions.debridlink.key}', debridLink],
|
['${MochOptions.debridlink.key}', debridLink],
|
||||||
|
['${MochOptions.easydebrid.key}', easyDebrid],
|
||||||
['${MochOptions.offcloud.key}', offcloud],
|
['${MochOptions.offcloud.key}', offcloud],
|
||||||
['${MochOptions.torbox.key}', torbox],
|
['${MochOptions.torbox.key}', torbox],
|
||||||
['${MochOptions.putio.key}', putio]
|
['${MochOptions.putio.key}', putio]
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ function getCatalogs(config) {
|
||||||
function getResources(config) {
|
function getResources(config) {
|
||||||
const streamResource = {
|
const streamResource = {
|
||||||
name: 'stream',
|
name: 'stream',
|
||||||
types: [Type.MOVIE, Type.SERIES],
|
types: [Type.MOVIE, Type.SERIES, Type.ANIME],
|
||||||
idPrefixes: ['tt', 'kitsu']
|
idPrefixes: ['tt', 'kitsu']
|
||||||
};
|
};
|
||||||
const metaResource = {
|
const metaResource = {
|
||||||
|
|
|
||||||
83
addon/moch/easydebrid.js
Normal file
83
addon/moch/easydebrid.js
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
import { EasyDebridClient } from '@paradise-cloud/easy-debrid';
|
||||||
|
import { isVideo, isArchive } from '../lib/extension.js';
|
||||||
|
import StaticResponse from './static.js';
|
||||||
|
import { BadTokenError, sameFilename, streamFilename } from './mochHelper.js';
|
||||||
|
import magnet from "magnet-uri";
|
||||||
|
|
||||||
|
const KEY = 'easydebrid';
|
||||||
|
|
||||||
|
export async function getCachedStreams(streams, apiKey) {
|
||||||
|
const options = await getDefaultOptions(apiKey);
|
||||||
|
const ED = new EasyDebridClient(options);
|
||||||
|
const hashes = streams.map(stream => stream.infoHash);
|
||||||
|
return ED.linkLookup(hashes)
|
||||||
|
.catch(error => {
|
||||||
|
if (toCommonError(error)) {
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
console.warn('Failed EasyDebrid cached torrent availability request:', error);
|
||||||
|
return undefined;
|
||||||
|
})
|
||||||
|
.then(response => streams
|
||||||
|
.reduce((mochStreams, stream, index) => {
|
||||||
|
const filename = streamFilename(stream);
|
||||||
|
mochStreams[`${stream.infoHash}@${stream.fileIdx}`] = {
|
||||||
|
url: `${apiKey}/${stream.infoHash}/${filename}/${stream.fileIdx}`,
|
||||||
|
cached: response?.cached?.[index]
|
||||||
|
};
|
||||||
|
return mochStreams;
|
||||||
|
}, {}));
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function resolve({ ip, isBrowser, apiKey, infoHash, cachedEntryInfo, fileIndex }) {
|
||||||
|
console.log(`Unrestricting EasyDebrid ${infoHash} [${fileIndex}]`);
|
||||||
|
const options = await getDefaultOptions(apiKey);
|
||||||
|
const ED = new EasyDebridClient(options);
|
||||||
|
return _getCachedLink(ED, infoHash, cachedEntryInfo, fileIndex, ip, isBrowser)
|
||||||
|
.catch(error => {
|
||||||
|
if (isAccessDeniedError(error)) {
|
||||||
|
console.log(`Access denied to EasyDebrid ${infoHash} [${fileIndex}]`);
|
||||||
|
return StaticResponse.FAILED_ACCESS;
|
||||||
|
}
|
||||||
|
return Promise.reject(`Failed EasyDebrid adding torrent ${JSON.stringify(error)}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function _getCachedLink(ED, infoHash, encodedFileName, fileIndex, ip, isBrowser) {
|
||||||
|
const magnetLink = magnet.encode({ infoHash })
|
||||||
|
const cachedTorrent = await ED.generateDebridLink(magnetLink);
|
||||||
|
if (cachedTorrent?.files?.length) {
|
||||||
|
const files = cachedTorrent.files.map(file => ({
|
||||||
|
...file,
|
||||||
|
path: file.directory.join("/") + `/${file.filename}`,
|
||||||
|
}))
|
||||||
|
const targetFileName = decodeURIComponent(encodedFileName);
|
||||||
|
const videos = files.filter(file => isVideo(file.path)).sort((a, b) => b.size - a.size);
|
||||||
|
const targetVideo = Number.isInteger(fileIndex)
|
||||||
|
&& videos.find(video => sameFilename(video.path, targetFileName))
|
||||||
|
|| videos[0];
|
||||||
|
if (!targetVideo && videos.every(video => isArchive(video.path))) {
|
||||||
|
console.log(`Only EasyDebrid archive is available for [${infoHash}] ${fileIndex}`)
|
||||||
|
return StaticResponse.FAILED_RAR;
|
||||||
|
}
|
||||||
|
const unrestrictedLink = targetVideo.url;
|
||||||
|
console.log(`Unrestricted EasyDebrid ${infoHash} [${fileIndex}] to ${unrestrictedLink}`);
|
||||||
|
return unrestrictedLink;
|
||||||
|
}
|
||||||
|
return Promise.reject('No cached entry found');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toCommonError(error) {
|
||||||
|
if (error && error.message === 'Not logged in.') {
|
||||||
|
return BadTokenError;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isAccessDeniedError(error) {
|
||||||
|
return ['Account not premium.'].some(value => error?.message?.includes(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getDefaultOptions(apiKey) {
|
||||||
|
return { accessToken: apiKey };
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ import * as realdebrid from './realdebrid.js';
|
||||||
import * as premiumize from './premiumize.js';
|
import * as premiumize from './premiumize.js';
|
||||||
import * as alldebrid from './alldebrid.js';
|
import * as alldebrid from './alldebrid.js';
|
||||||
import * as debridlink from './debridlink.js';
|
import * as debridlink from './debridlink.js';
|
||||||
|
import * as easydebrid from './easydebrid.js';
|
||||||
import * as offcloud from './offcloud.js';
|
import * as offcloud from './offcloud.js';
|
||||||
import * as torbox from './torbox.js';
|
import * as torbox from './torbox.js';
|
||||||
import * as putio from './putio.js';
|
import * as putio from './putio.js';
|
||||||
|
|
@ -44,6 +45,14 @@ export const MochOptions = {
|
||||||
shortName: 'DL',
|
shortName: 'DL',
|
||||||
catalogs: ['']
|
catalogs: ['']
|
||||||
},
|
},
|
||||||
|
easydebrid: {
|
||||||
|
key: 'easydebrid',
|
||||||
|
instance: easydebrid,
|
||||||
|
name: 'EasyDebrid',
|
||||||
|
shortName: 'ED',
|
||||||
|
catalogs: [],
|
||||||
|
noDownloads: true
|
||||||
|
},
|
||||||
offcloud: {
|
offcloud: {
|
||||||
key: 'offcloud',
|
key: 'offcloud',
|
||||||
instance: offcloud,
|
instance: offcloud,
|
||||||
|
|
@ -192,9 +201,10 @@ function populateDownloadLinks(streams, results, config) {
|
||||||
const torrentStreams = streams.filter(stream => stream.infoHash);
|
const torrentStreams = streams.filter(stream => stream.infoHash);
|
||||||
const seededStreams = streams.filter(stream => !stream.title.includes('👤 0'));
|
const seededStreams = streams.filter(stream => !stream.title.includes('👤 0'));
|
||||||
torrentStreams.forEach(stream => mochResults.forEach(mochResult => {
|
torrentStreams.forEach(stream => mochResults.forEach(mochResult => {
|
||||||
|
const supportDownloads = !mochResult.moch.noDownloads;
|
||||||
const cachedEntry = mochResult.mochStreams[`${stream.infoHash}@${stream.fileIdx}`];
|
const cachedEntry = mochResult.mochStreams[`${stream.infoHash}@${stream.fileIdx}`];
|
||||||
const isCached = cachedEntry?.cached;
|
const isCached = cachedEntry?.cached;
|
||||||
if (!isCached && isHealthyStreamForDebrid(seededStreams, stream)) {
|
if (supportDownloads && !isCached && isHealthyStreamForDebrid(seededStreams, stream)) {
|
||||||
streams.push({
|
streams.push({
|
||||||
name: `[${mochResult.moch.shortName} download] ${stream.name}`,
|
name: `[${mochResult.moch.shortName} download] ${stream.name}`,
|
||||||
title: stream.title,
|
title: stream.title,
|
||||||
|
|
|
||||||
13
addon/package-lock.json
generated
13
addon/package-lock.json
generated
|
|
@ -10,6 +10,7 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@keyv/mongo": "^3.0.1",
|
"@keyv/mongo": "^3.0.1",
|
||||||
|
"@paradise-cloud/easy-debrid": "^3.0.0",
|
||||||
"@putdotio/api-client": "^8.42.0",
|
"@putdotio/api-client": "^8.42.0",
|
||||||
"all-debrid-api": "^1.2.0",
|
"all-debrid-api": "^1.2.0",
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.7.7",
|
||||||
|
|
@ -118,6 +119,18 @@
|
||||||
"sparse-bitfield": "^3.0.3"
|
"sparse-bitfield": "^3.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@paradise-cloud/easy-debrid": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@paradise-cloud/easy-debrid/-/easy-debrid-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-UrkvWQgnapw2nZKc5ZgNU29B52RrVe+fIDidJZWx2MZBowar7CBDSEc/E54q/Am9OKnsttMw9/gh2o3IuXwOHA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.6.8"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@putdotio/api-client": {
|
"node_modules/@putdotio/api-client": {
|
||||||
"version": "8.42.0",
|
"version": "8.42.0",
|
||||||
"resolved": "https://registry.npmjs.org/@putdotio/api-client/-/api-client-8.42.0.tgz",
|
"resolved": "https://registry.npmjs.org/@putdotio/api-client/-/api-client-8.42.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@keyv/mongo": "^3.0.1",
|
"@keyv/mongo": "^3.0.1",
|
||||||
|
"@paradise-cloud/easy-debrid": "^3.0.0",
|
||||||
"@putdotio/api-client": "^8.42.0",
|
"@putdotio/api-client": "^8.42.0",
|
||||||
"all-debrid-api": "^1.2.0",
|
"all-debrid-api": "^1.2.0",
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.7.7",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue