mirror of
https://github.com/knightcrawler-stremio/knightcrawler.git
synced 2024-12-20 03:29:51 +00:00
[addon] moves rd resolver to addon
This commit is contained in:
2
.github/workflows/deploy.yml
vendored
2
.github/workflows/deploy.yml
vendored
@@ -40,5 +40,5 @@ jobs:
|
|||||||
docker load -i /tmp/docker/torrentio_addon_latest.tar
|
docker load -i /tmp/docker/torrentio_addon_latest.tar
|
||||||
docker stop torrentio-addon
|
docker stop torrentio-addon
|
||||||
docker rm torrentio-addon
|
docker rm torrentio-addon
|
||||||
docker run -p 80:7000 -d --name torrentio-addon --restart always -e MONGODB_URI=${{ secrets.MONGODB_URI }} -e DATABASE_URI=${{ secrets.DATABASE_URI }} -e RESOLVER_HOST=${{ secrets.RESOLVER_HOST }} torrentio-addon:latest
|
docker run -p 80:7000 -d --name torrentio-addon --restart always -e MONGODB_URI=${{ secrets.MONGODB_URI }} -e DATABASE_URI=${{ secrets.DATABASE_URI }} -e RESOLVER_HOST=${{ secrets.RESOLVER_HOST }} -e PROXY_HOSTS=${{ secrets.PROXY_HOSTS }} -e PROXY_USERNAME=${{ secrets.PROXY_USERNAME }} -e PROXY_PASSWORD=${{ secrets.PROXY_PASSWORD }} torrentio-addon:latest
|
||||||
docker image prune -f
|
docker image prune -f
|
||||||
|
|||||||
@@ -3,17 +3,24 @@ const mangodbStore = require('cache-manager-mongodb');
|
|||||||
|
|
||||||
const GLOBAL_KEY_PREFIX = 'torrentio-addon';
|
const GLOBAL_KEY_PREFIX = 'torrentio-addon';
|
||||||
const STREAM_KEY_PREFIX = `${GLOBAL_KEY_PREFIX}|stream`;
|
const STREAM_KEY_PREFIX = `${GLOBAL_KEY_PREFIX}|stream`;
|
||||||
|
const RESOLVED_URL_KEY_PREFIX = `${GLOBAL_KEY_PREFIX}|resolved`;
|
||||||
|
const PROXY_KEY_PREFIX = `${GLOBAL_KEY_PREFIX}|proxy`;
|
||||||
|
const USER_AGENT_KEY_PREFIX = `${GLOBAL_KEY_PREFIX}|agent`;
|
||||||
|
|
||||||
const STREAM_TTL = process.env.STREAM_TTL || 4 * 60 * 60; // 4 hours
|
const STREAM_TTL = process.env.STREAM_TTL || 4 * 60 * 60; // 4 hours
|
||||||
const STREAM_EMPTY_TTL = process.env.STREAM_EMPTY_TTL || 30 * 60; // 30 minutes
|
const STREAM_EMPTY_TTL = process.env.STREAM_EMPTY_TTL || 30 * 60; // 30 minutes
|
||||||
|
const RESOLVED_URL_TTL = 2 * 60; // 2 minutes
|
||||||
|
const PROXY_TTL = 60 * 60; // 60 minutes
|
||||||
|
const USER_AGENT_TTL = 2 * 24 * 60 * 60; // 2 days
|
||||||
// When the streams are empty we want to cache it for less time in case of timeouts or failures
|
// When the streams are empty we want to cache it for less time in case of timeouts or failures
|
||||||
|
|
||||||
const MONGO_URI = process.env.MONGODB_URI;
|
const MONGO_URI = process.env.MONGODB_URI;
|
||||||
const NO_CACHE = process.env.NO_CACHE || false;
|
const NO_CACHE = process.env.NO_CACHE || false;
|
||||||
|
|
||||||
const remoteCache = initiateCache();
|
const memoryCache = initiateMemoryCache();
|
||||||
|
const remoteCache = initiateRemoteCache();
|
||||||
|
|
||||||
function initiateCache() {
|
function initiateRemoteCache() {
|
||||||
if (NO_CACHE) {
|
if (NO_CACHE) {
|
||||||
return null;
|
return null;
|
||||||
} else if (MONGO_URI) {
|
} else if (MONGO_URI) {
|
||||||
@@ -37,6 +44,13 @@ function initiateCache() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function initiateMemoryCache() {
|
||||||
|
return cacheManager.caching({
|
||||||
|
store: 'memory',
|
||||||
|
ttl: STREAM_TTL
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function cacheWrap(cache, key, method, options) {
|
function cacheWrap(cache, key, method, options) {
|
||||||
if (NO_CACHE || !cache) {
|
if (NO_CACHE || !cache) {
|
||||||
return method();
|
return method();
|
||||||
@@ -50,5 +64,17 @@ function cacheWrapStream(id, method) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { cacheWrapStream };
|
function cacheWrapResolvedUrl(id, method) {
|
||||||
|
return cacheWrap(memoryCache, `${RESOLVED_URL_KEY_PREFIX}:${id}`, method, { ttl: { RESOLVED_URL_TTL } });
|
||||||
|
}
|
||||||
|
|
||||||
|
function cacheWrapProxy(id, method) {
|
||||||
|
return cacheWrap(memoryCache, `${PROXY_KEY_PREFIX}:${id}`, method, { ttl: { PROXY_TTL } });
|
||||||
|
}
|
||||||
|
|
||||||
|
function cacheUserAgent(id, method) {
|
||||||
|
return cacheWrap(memoryCache, `${USER_AGENT_KEY_PREFIX}:${id}`, method, { ttl: { USER_AGENT_TTL } });
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { cacheWrapStream, cacheWrapResolvedUrl, cacheWrapProxy, cacheUserAgent };
|
||||||
|
|
||||||
|
|||||||
20
addon/lib/request_helper.js
Normal file
20
addon/lib/request_helper.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
const UserAgent = require('user-agents');
|
||||||
|
|
||||||
|
const PROXY_HOSTS = process.env.PROXY_HOSTS && process.env.PROXY_HOSTS.split(',');
|
||||||
|
const PROXY_USERNAME = process.env.PROXY_USERNAME;
|
||||||
|
const PROXY_PASSWORD = process.env.PROXY_PASSWORD;
|
||||||
|
const userAgent = new UserAgent();
|
||||||
|
|
||||||
|
function getRandomUserAgent() {
|
||||||
|
return userAgent.random().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRandomProxy() {
|
||||||
|
if (PROXY_HOSTS && PROXY_HOSTS.length && PROXY_USERNAME && PROXY_PASSWORD) {
|
||||||
|
return `http://${PROXY_USERNAME}:${PROXY_PASSWORD}@${PROXY_HOSTS[Math.floor(Math.random() * PROXY_HOSTS.length)]}`;
|
||||||
|
}
|
||||||
|
console.warn('No proxy configured!');
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { getRandomUserAgent, getRandomProxy };
|
||||||
@@ -1,10 +1,19 @@
|
|||||||
const RealDebridClient = require('real-debrid-api');
|
const RealDebridClient = require('real-debrid-api');
|
||||||
|
const namedQueue = require('named-queue');
|
||||||
|
const { encode } = require('magnet-uri');
|
||||||
const isVideo = require('../lib/video');
|
const isVideo = require('../lib/video');
|
||||||
|
const { getRandomProxy, getRandomUserAgent } = require('../lib/request_helper');
|
||||||
|
const { cacheWrapResolvedUrl, cacheWrapProxy, cacheUserAgent } = require('../lib/cache');
|
||||||
|
|
||||||
const RESOLVER_HOST = process.env.RESOLVER_HOST || 'http://localhost:7000';
|
const RESOLVER_HOST = process.env.RESOLVER_HOST || 'http://localhost:7050';
|
||||||
|
|
||||||
|
const unrestrictQueue = new namedQueue((task, callback) => task.method()
|
||||||
|
.then(result => callback(false, result))
|
||||||
|
.catch((error => callback(error))));
|
||||||
|
|
||||||
async function applyMoch(streams, apiKey) {
|
async function applyMoch(streams, apiKey) {
|
||||||
const RD = new RealDebridClient(apiKey);
|
const options = await getDefaultOptions(apiKey);
|
||||||
|
const RD = new RealDebridClient(apiKey, options);
|
||||||
const hashes = streams.map(stream => stream.infoHash);
|
const hashes = streams.map(stream => stream.infoHash);
|
||||||
const available = await RD.torrents.instantAvailability(hashes)
|
const available = await RD.torrents.instantAvailability(hashes)
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
@@ -14,7 +23,7 @@ async function applyMoch(streams, apiKey) {
|
|||||||
if (available) {
|
if (available) {
|
||||||
streams.forEach(stream => {
|
streams.forEach(stream => {
|
||||||
const cachedEntry = available[stream.infoHash];
|
const cachedEntry = available[stream.infoHash];
|
||||||
const cachedIds = getCachedFileIds(stream.fileIdx, cachedEntry).join(',');
|
const cachedIds = _getCachedFileIds(stream.fileIdx, cachedEntry).join(',');
|
||||||
if (cachedIds.length) {
|
if (cachedIds.length) {
|
||||||
stream.name = `[RD+] ${stream.name}`;
|
stream.name = `[RD+] ${stream.name}`;
|
||||||
stream.url = `${RESOLVER_HOST}/realdebrid/${apiKey}/${stream.infoHash}/${cachedIds}/${stream.fileIdx}`;
|
stream.url = `${RESOLVER_HOST}/realdebrid/${apiKey}/${stream.infoHash}/${cachedIds}/${stream.fileIdx}`;
|
||||||
@@ -27,7 +36,19 @@ async function applyMoch(streams, apiKey) {
|
|||||||
return streams;
|
return streams;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCachedFileIds(fileIndex, hosterResults) {
|
async function resolve(apiKey, infoHash, cachedFileIds, fileIndex) {
|
||||||
|
if (!apiKey || !infoHash || !cachedFileIds || !cachedFileIds.length) {
|
||||||
|
return Promise.reject("No valid parameters passed");
|
||||||
|
}
|
||||||
|
const id = `${apiKey}_${infoHash}_${fileIndex}`;
|
||||||
|
const method = () => cacheWrapResolvedUrl(id, () => _unrestrict(apiKey, infoHash, cachedFileIds, fileIndex));
|
||||||
|
|
||||||
|
return new Promise(((resolve, reject) => {
|
||||||
|
unrestrictQueue.push({ id, method }, (error, result) => result ? resolve(result) : reject(error));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getCachedFileIds(fileIndex, hosterResults) {
|
||||||
if (!hosterResults || Array.isArray(hosterResults)) {
|
if (!hosterResults || Array.isArray(hosterResults)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -41,4 +62,59 @@ function getCachedFileIds(fileIndex, hosterResults) {
|
|||||||
return cachedTorrents.length && cachedTorrents[0] || [];
|
return cachedTorrents.length && cachedTorrents[0] || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { applyMoch };
|
async function _unrestrict(apiKey, infoHash, cachedFileIds, fileIndex) {
|
||||||
|
console.log(`Unrestricting ${infoHash} [${fileIndex}]`);
|
||||||
|
const options = await getDefaultOptions(apiKey);
|
||||||
|
const RD = new RealDebridClient(apiKey, options);
|
||||||
|
const torrentId = await _createOrFindTorrentId(RD, infoHash, cachedFileIds);
|
||||||
|
if (torrentId) {
|
||||||
|
const info = await RD.torrents.info(torrentId);
|
||||||
|
const targetFile = info.files.find(file => file.id === fileIndex + 1)
|
||||||
|
|| info.files.filter(file => file.selected).sort((a, b) => b.bytes - a.bytes)[0];
|
||||||
|
const selectedFiles = info.files.filter(file => file.selected);
|
||||||
|
const fileLink = info.links.length === 1
|
||||||
|
? info.links[0]
|
||||||
|
: info.links[selectedFiles.indexOf(targetFile)];
|
||||||
|
const unrestrictedLink = await _unrestrictLink(RD, fileLink);
|
||||||
|
console.log(`Unrestricted ${infoHash} [${fileIndex}] to ${unrestrictedLink}`);
|
||||||
|
return unrestrictedLink;
|
||||||
|
}
|
||||||
|
return Promise.reject("Failed adding torrent");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function _createOrFindTorrentId(RD, infoHash, cachedFileIds) {
|
||||||
|
return RD.torrents.get(0, 1)
|
||||||
|
.then(torrents => torrents.find(torrent => torrent.hash.toLowerCase() === infoHash))
|
||||||
|
.then(torrent => torrent && torrent.id || Promise.reject('No recent torrent found'))
|
||||||
|
.catch((error) => RD.torrents.addMagnet(encode({ infoHash }))
|
||||||
|
.then(response => RD.torrents.selectFiles(response.id, cachedFileIds)
|
||||||
|
.then((() => response.id))))
|
||||||
|
.catch(error => {
|
||||||
|
console.warn('Failed RealDebrid torrent retrieval', error);
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function _unrestrictLink(RD, link) {
|
||||||
|
if (!link || !link.length) {
|
||||||
|
return Promise.reject("No available links found");
|
||||||
|
}
|
||||||
|
return RD.unrestrict.link(link)
|
||||||
|
.then(unrestrictedLink => unrestrictedLink.download);
|
||||||
|
// .then(unrestrictedLink => RD.streaming.transcode(unrestrictedLink.id))
|
||||||
|
// .then(transcodedLink => {
|
||||||
|
// const url = transcodedLink.apple && transcodedLink.apple.full
|
||||||
|
// || transcodedLink[Object.keys(transcodedLink)[0]].full;
|
||||||
|
// console.log(`Unrestricted ${link} to ${url}`);
|
||||||
|
// return url;
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getDefaultOptions(id) {
|
||||||
|
const userAgent = await cacheUserAgent(id, () => getRandomUserAgent()).catch(() => getRandomUserAgent());
|
||||||
|
const proxy = await cacheWrapProxy('realdebrid', () => getRandomProxy()).catch(() => getRandomProxy());
|
||||||
|
|
||||||
|
return { proxy: proxy, headers: { 'User-Agent': userAgent } };
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { applyMoch, resolve };
|
||||||
61
addon/package-lock.json
generated
61
addon/package-lock.json
generated
@@ -420,6 +420,16 @@
|
|||||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||||
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||||
},
|
},
|
||||||
|
"detect-indent": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA=="
|
||||||
|
},
|
||||||
|
"docopt": {
|
||||||
|
"version": "0.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/docopt/-/docopt-0.6.2.tgz",
|
||||||
|
"integrity": "sha1-so6eIiDaXsSffqW7JKR3h0Be6xE="
|
||||||
|
},
|
||||||
"doctrine": {
|
"doctrine": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
|
||||||
@@ -429,6 +439,16 @@
|
|||||||
"esutils": "^2.0.2"
|
"esutils": "^2.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dot-json": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/dot-json/-/dot-json-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-4bEM7KHFl/U9gAI5nIvU0/fwVzNnE713K339vcxAMtxd2D9mZP6o65UwlcXigJL4rfk90UM0J+D7IPIFYZMQ8Q==",
|
||||||
|
"requires": {
|
||||||
|
"detect-indent": "~6.0.0",
|
||||||
|
"docopt": "~0.6.2",
|
||||||
|
"underscore-keypath": "~0.0.22"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dottie": {
|
"dottie": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz",
|
||||||
@@ -1339,6 +1359,15 @@
|
|||||||
"yallist": "^2.0.0"
|
"yallist": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"magnet-uri": {
|
||||||
|
"version": "5.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/magnet-uri/-/magnet-uri-5.2.4.tgz",
|
||||||
|
"integrity": "sha512-VYaJMxhr8B9BrCiNINUsuhaEe40YnG+AQBwcqUKO66lSVaI9I3A1iH/6EmEwRI8OYUg5Gt+4lLE7achg676lrg==",
|
||||||
|
"requires": {
|
||||||
|
"thirty-two": "^1.0.1",
|
||||||
|
"uniq": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"media-typer": {
|
"media-typer": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
@@ -1441,6 +1470,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
|
||||||
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
|
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
|
||||||
},
|
},
|
||||||
|
"named-queue": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/named-queue/-/named-queue-2.2.1.tgz",
|
||||||
|
"integrity": "sha1-GBRURVNZnVqeQD0N+pN6TODR5qc="
|
||||||
|
},
|
||||||
"natural-compare": {
|
"natural-compare": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||||
@@ -2251,6 +2285,11 @@
|
|||||||
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
|
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"thirty-two": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/thirty-two/-/thirty-two-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-TKL//AKlEpDSdEueP1V2k8prYno="
|
||||||
|
},
|
||||||
"through": {
|
"through": {
|
||||||
"version": "2.3.8",
|
"version": "2.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||||
@@ -2330,6 +2369,19 @@
|
|||||||
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.2.tgz",
|
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.2.tgz",
|
||||||
"integrity": "sha512-D39qtimx0c1fI3ya1Lnhk3E9nONswSKhnffBI0gME9C99fYOkNi04xs8K6pePLhvl1frbDemkaBQ5ikWllR2HQ=="
|
"integrity": "sha512-D39qtimx0c1fI3ya1Lnhk3E9nONswSKhnffBI0gME9C99fYOkNi04xs8K6pePLhvl1frbDemkaBQ5ikWllR2HQ=="
|
||||||
},
|
},
|
||||||
|
"underscore-keypath": {
|
||||||
|
"version": "0.0.22",
|
||||||
|
"resolved": "https://registry.npmjs.org/underscore-keypath/-/underscore-keypath-0.0.22.tgz",
|
||||||
|
"integrity": "sha1-SKUoOSu278QkvhyqVtpLX6zPJk0=",
|
||||||
|
"requires": {
|
||||||
|
"underscore": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uniq": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8="
|
||||||
|
},
|
||||||
"unpipe": {
|
"unpipe": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
@@ -2343,6 +2395,15 @@
|
|||||||
"punycode": "^2.1.0"
|
"punycode": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"user-agents": {
|
||||||
|
"version": "1.0.559",
|
||||||
|
"resolved": "https://registry.npmjs.org/user-agents/-/user-agents-1.0.559.tgz",
|
||||||
|
"integrity": "sha512-HdAlNS3vDxOGMRwmv8or05xL96MV3CEwQhUSFTCRoOvTOEnWhTEBPAHRry/xZpVTTOtx77UHMal8YKcx6fs7Lg==",
|
||||||
|
"requires": {
|
||||||
|
"dot-json": "^1.2.0",
|
||||||
|
"lodash.clonedeep": "^4.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"util-deprecate": {
|
"util-deprecate": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
|
|||||||
@@ -11,13 +11,16 @@
|
|||||||
"cache-manager": "^2.11.1",
|
"cache-manager": "^2.11.1",
|
||||||
"cache-manager-mongodb": "^0.2.2",
|
"cache-manager-mongodb": "^0.2.2",
|
||||||
"express-rate-limit": "^5.1.1",
|
"express-rate-limit": "^5.1.1",
|
||||||
|
"named-queue": "^2.2.1",
|
||||||
"needle": "^2.2.4",
|
"needle": "^2.2.4",
|
||||||
|
"magnet-uri": "^5.1.7",
|
||||||
"parse-torrent-title": "git://github.com/TheBeastLT/parse-torrent-title.git#afd4a374276420c13c52df8e3d07ae7699c46b60",
|
"parse-torrent-title": "git://github.com/TheBeastLT/parse-torrent-title.git#afd4a374276420c13c52df8e3d07ae7699c46b60",
|
||||||
"pg": "^7.8.2",
|
"pg": "^7.8.2",
|
||||||
"pg-hstore": "^2.3.2",
|
"pg-hstore": "^2.3.2",
|
||||||
"real-debrid-api": "git://github.com/TheBeastLT/node-real-debrid.git#935a5c23ae809edbcd2a111526a7f74d6767c50d",
|
"real-debrid-api": "git://github.com/TheBeastLT/node-real-debrid.git#935a5c23ae809edbcd2a111526a7f74d6767c50d",
|
||||||
"sequelize": "^4.43.0",
|
"sequelize": "^4.43.0",
|
||||||
"stremio-addon-sdk": "^1.6.1"
|
"stremio-addon-sdk": "^1.6.1",
|
||||||
|
"user-agents": "^1.0.559"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^6.4.0",
|
"eslint": "^6.4.0",
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ const addonInterface = require('./addon');
|
|||||||
const { manifest } = require('./lib/manifest');
|
const { manifest } = require('./lib/manifest');
|
||||||
const parseConfiguration = require('./lib/configuration');
|
const parseConfiguration = require('./lib/configuration');
|
||||||
const landingTemplate = require('./lib/landingTemplate');
|
const landingTemplate = require('./lib/landingTemplate');
|
||||||
|
const realDebrid = require('./moch/realdebrid');
|
||||||
|
|
||||||
const router = getRouter(addonInterface);
|
const router = getRouter(addonInterface);
|
||||||
const limiter = rateLimit({
|
const limiter = rateLimit({
|
||||||
@@ -68,6 +69,20 @@ router.get('/:configuration/:resource/:type/:id.json', (req, res, next) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.get('/realdebrid/:apiKey/:infoHash/:cachedFileIds/:fileIndex?', (req, res) => {
|
||||||
|
const { apiKey, infoHash, cachedFileIds, fileIndex } = req.params;
|
||||||
|
realDebrid.resolve(apiKey, infoHash, cachedFileIds, isNaN(fileIndex) ? undefined : parseInt(fileIndex))
|
||||||
|
.then(url => {
|
||||||
|
res.writeHead(301, { Location: url });
|
||||||
|
res.end();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(error);
|
||||||
|
res.statusCode = 404;
|
||||||
|
res.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
module.exports = function (req, res) {
|
module.exports = function (req, res) {
|
||||||
router(req, res, function () {
|
router(req, res, function () {
|
||||||
res.statusCode = 404;
|
res.statusCode = 404;
|
||||||
|
|||||||
Reference in New Issue
Block a user