mirror of
https://github.com/knightcrawler-stremio/knightcrawler.git
synced 2024-12-20 03:29:51 +00:00
[addon] updates premiumize moch
This commit is contained in:
@@ -8,5 +8,6 @@ app.use(express.static('static', { maxAge: '1y' }));
|
|||||||
app.use((req, res, next) => serverless(req, res, next));
|
app.use((req, res, next) => serverless(req, res, next));
|
||||||
app.listen(process.env.PORT || 7000, () => {
|
app.listen(process.env.PORT || 7000, () => {
|
||||||
initBestTrackers()
|
initBestTrackers()
|
||||||
.then(() => console.log(`Started addon at: http://localhost:${process.env.PORT || 7000}`));
|
.then(() => console.log(`Started addon at: http://localhost:${process.env.PORT || 7000}`))
|
||||||
|
.catch(error => console.error('Failed init trackers', error));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
const needle = require('needle');
|
const needle = require('needle');
|
||||||
const magnet = require('magnet-uri');
|
const magnet = require('magnet-uri');
|
||||||
const { getRandomProxy, getProxyAgent, getRandomUserAgent } = require('../lib/requestHelper');
|
const { getRandomUserAgent } = require('../lib/requestHelper');
|
||||||
const { cacheWrapProxy } = require('../lib/cache');
|
|
||||||
const { getTorrent } = require('../lib/repository');
|
const { getTorrent } = require('../lib/repository');
|
||||||
const { Type } = require('../lib/types');
|
const { Type } = require('../lib/types');
|
||||||
|
|
||||||
@@ -33,10 +32,7 @@ async function getMagnetLink(infoHash) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function initBestTrackers() {
|
async function initBestTrackers() {
|
||||||
const userAgent = getRandomUserAgent();
|
const options = { timeout: 30000, headers: { 'User-Agent': getRandomUserAgent() } };
|
||||||
const proxy = await cacheWrapProxy('moch', () => getRandomProxy()).catch(() => getRandomProxy());
|
|
||||||
const agent = getProxyAgent(proxy);
|
|
||||||
const options = { timeout: 30000, agent: agent, headers: { 'User-Agent': userAgent } };
|
|
||||||
|
|
||||||
BEST_TRACKERS = await needle('get', TRACKERS_URL, options)
|
BEST_TRACKERS = await needle('get', TRACKERS_URL, options)
|
||||||
.then(response => response.body && response.body.trim())
|
.then(response => response.body && response.body.trim())
|
||||||
@@ -46,6 +42,7 @@ async function initBestTrackers() {
|
|||||||
return [];
|
return [];
|
||||||
});
|
});
|
||||||
ALL_TRACKERS = BEST_TRACKERS.concat(ANIME_TRACKERS);
|
ALL_TRACKERS = BEST_TRACKERS.concat(ANIME_TRACKERS);
|
||||||
|
console.log('Retrieved best trackers: ', BEST_TRACKERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { initBestTrackers, getAllTrackers, getMagnetLink };
|
module.exports = { initBestTrackers, getAllTrackers, getMagnetLink };
|
||||||
@@ -25,7 +25,7 @@ function manifest(config = {}) {
|
|||||||
.map(moch => moch.name)
|
.map(moch => moch.name)
|
||||||
.join(' & ');
|
.join(' & ');
|
||||||
const possibleMochs = Object.values(MochOptions).map(moch => moch.name).join('/')
|
const possibleMochs = Object.values(MochOptions).map(moch => moch.name).join('/')
|
||||||
const mochsDesc = enabledMochs ? ` and ${enabledMochs} enabled ` : '';
|
const mochsDesc = enabledMochs ? ` and ${enabledMochs} enabled` : '';
|
||||||
return {
|
return {
|
||||||
id: 'com.stremio.torrentio.addon',
|
id: 'com.stremio.torrentio.addon',
|
||||||
version: '0.0.7',
|
version: '0.0.7',
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ function getRandomProxy() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getProxyAgent(proxy) {
|
function getProxyAgent(proxy) {
|
||||||
return new HttpsProxyAgent(proxy);
|
return proxy && new HttpsProxyAgent(proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
function blacklistProxy(proxy) {
|
function blacklistProxy(proxy) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const putio = require('./putio');
|
|||||||
const StaticResponse = require('./static');
|
const StaticResponse = require('./static');
|
||||||
const { cacheWrapResolvedUrl } = require('../lib/cache');
|
const { cacheWrapResolvedUrl } = require('../lib/cache');
|
||||||
|
|
||||||
const MIN_API_KEY_SYMBOLS = 20;
|
const MIN_API_KEY_SYMBOLS = 15;
|
||||||
const RESOLVER_HOST = process.env.RESOLVER_HOST || 'http://localhost:7050';
|
const RESOLVER_HOST = process.env.RESOLVER_HOST || 'http://localhost:7050';
|
||||||
const MOCHS = {
|
const MOCHS = {
|
||||||
realdebrid: {
|
realdebrid: {
|
||||||
@@ -16,13 +16,12 @@ const MOCHS = {
|
|||||||
name: "RealDebrid",
|
name: "RealDebrid",
|
||||||
shortName: 'RD'
|
shortName: 'RD'
|
||||||
},
|
},
|
||||||
// @TODO disabled until it is possible to resolve stream url for specific ip
|
premiumize: {
|
||||||
// premiumize: {
|
key: 'premiumize',
|
||||||
// key: 'premiumize',
|
instance: premiumize,
|
||||||
// instance: premiumize,
|
name: 'Premiumize',
|
||||||
// name: 'Premiumize',
|
shortName: 'PM'
|
||||||
// shortName: 'PM'
|
},
|
||||||
// },
|
|
||||||
alldebrid: {
|
alldebrid: {
|
||||||
key: 'alldebrid',
|
key: 'alldebrid',
|
||||||
instance: alldebrid,
|
instance: alldebrid,
|
||||||
@@ -113,6 +112,7 @@ async function getMochItemMeta(mochKey, itemId, config) {
|
|||||||
meta.videos
|
meta.videos
|
||||||
.map(video => video.streams)
|
.map(video => video.streams)
|
||||||
.reduce((a, b) => a.concat(b), [])
|
.reduce((a, b) => a.concat(b), [])
|
||||||
|
.filter(stream => !stream.url.startsWith('http'))
|
||||||
.forEach(stream => stream.url = `${RESOLVER_HOST}/${moch.key}/${stream.url}`)
|
.forEach(stream => stream.url = `${RESOLVER_HOST}/${moch.key}/${stream.url}`)
|
||||||
return meta;
|
return meta;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
const PremiumizeClient = require('premiumize-api');
|
const PremiumizeClient = require('premiumize-api');
|
||||||
|
const magnet = require('magnet-uri');
|
||||||
|
const { Type } = require('../lib/types');
|
||||||
const { isVideo } = require('../lib/extension');
|
const { isVideo } = require('../lib/extension');
|
||||||
const StaticResponse = require('./static');
|
const StaticResponse = require('./static');
|
||||||
const { getRandomProxy, getProxyAgent, getRandomUserAgent } = require('../lib/requestHelper');
|
const { getRandomProxy, getProxyAgent, getRandomUserAgent } = require('../lib/requestHelper');
|
||||||
const { cacheWrapProxy, cacheUserAgent } = require('../lib/cache');
|
const { cacheWrapProxy, cacheUserAgent } = require('../lib/cache');
|
||||||
const { getMagnetLink } = require('../lib/magnetHelper');
|
const { getMagnetLink } = require('../lib/magnetHelper');
|
||||||
|
|
||||||
|
const KEY = 'premiumize';
|
||||||
|
|
||||||
async function getCachedStreams(streams, apiKey) {
|
async function getCachedStreams(streams, apiKey) {
|
||||||
const options = await getDefaultOptions(apiKey);
|
const options = await getDefaultOptions(apiKey);
|
||||||
const PM = new PremiumizeClient(apiKey, options);
|
const PM = new PremiumizeClient(apiKey, options);
|
||||||
@@ -28,19 +32,70 @@ async function getCachedStreams(streams, apiKey) {
|
|||||||
}, {})
|
}, {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getCatalog(apiKey, offset = 0) {
|
||||||
|
if (offset > 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const options = await getDefaultOptions(apiKey);
|
||||||
|
const PM = new PremiumizeClient(apiKey, options);
|
||||||
|
return PM.folder.list()
|
||||||
|
.then(response => response.content)
|
||||||
|
.then(torrents => (torrents || [])
|
||||||
|
.filter(torrent => torrent && torrent.type === 'folder')
|
||||||
|
.map(torrent => ({
|
||||||
|
id: `${KEY}:${torrent.id}`,
|
||||||
|
type: Type.OTHER,
|
||||||
|
name: torrent.name
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getItemMeta(itemId, apiKey) {
|
||||||
|
const options = await getDefaultOptions(apiKey);
|
||||||
|
const PM = new PremiumizeClient(apiKey, options);
|
||||||
|
const rootFolder = await PM.folder.list(itemId, null);
|
||||||
|
return getFolderContents(PM, itemId)
|
||||||
|
.then(contents => ({
|
||||||
|
id: `${KEY}:${itemId}`,
|
||||||
|
type: Type.OTHER,
|
||||||
|
name: rootFolder.name,
|
||||||
|
videos: contents
|
||||||
|
.map((file, index) => ({
|
||||||
|
id: `${KEY}:${file.id}:${index}`,
|
||||||
|
title: file.name,
|
||||||
|
released: new Date(file.created_at * 1000 - index).toISOString(),
|
||||||
|
streams: [
|
||||||
|
{ url: file.stream_link || file.link }
|
||||||
|
]
|
||||||
|
}))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getFolderContents(PM, itemId, ip, folderPrefix = '') {
|
||||||
|
return PM.folder.list(itemId, null, ip)
|
||||||
|
.then(response => response.content)
|
||||||
|
.then(contents => Promise.all(contents
|
||||||
|
.filter(content => content.type === 'folder')
|
||||||
|
.map(content => getFolderContents(PM, content.id, ip, [folderPrefix, content.name].join('/'))))
|
||||||
|
.then(otherContents => otherContents.reduce((a, b) => a.concat(b), []))
|
||||||
|
.then(otherContents => contents
|
||||||
|
.filter(content => content.type === 'file' && isVideo(content.name))
|
||||||
|
.map(content => ({ ...content, name: [folderPrefix, content.name].join('/') }))
|
||||||
|
.concat(otherContents)));
|
||||||
|
}
|
||||||
|
|
||||||
async function resolve({ ip, apiKey, infoHash, cachedEntryInfo, fileIndex }) {
|
async function resolve({ ip, apiKey, infoHash, cachedEntryInfo, fileIndex }) {
|
||||||
console.log(`Unrestricting ${infoHash} [${fileIndex}]`);
|
console.log(`Unrestricting ${infoHash} [${fileIndex}] for IP ${ip}`);
|
||||||
const options = await getDefaultOptions(apiKey, ip);
|
const options = await getDefaultOptions(apiKey, ip);
|
||||||
const PM = new PremiumizeClient(apiKey, options);
|
const PM = new PremiumizeClient(apiKey, options);
|
||||||
|
|
||||||
const cachedLink = await _getCachedLink(PM, infoHash, cachedEntryInfo, fileIndex).catch(() => undefined);
|
const cachedLink = await _getCachedLink(PM, infoHash, cachedEntryInfo, fileIndex, ip).catch(() => undefined);
|
||||||
if (cachedLink) {
|
if (cachedLink) {
|
||||||
return cachedLink;
|
return cachedLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
const torrent = await _createOrFindTorrent(PM, infoHash, cachedEntryInfo, fileIndex);
|
const torrent = await _createOrFindTorrent(PM, infoHash);
|
||||||
if (torrent && statusReady(torrent.status)) {
|
if (torrent && statusReady(torrent.status)) {
|
||||||
return _getCachedLink(PM, infoHash, cachedEntryInfo, fileIndex);
|
return _getCachedLink(PM, infoHash, cachedEntryInfo, fileIndex, ip);
|
||||||
} else if (torrent && statusDownloading(torrent.status)) {
|
} else if (torrent && statusDownloading(torrent.status)) {
|
||||||
return StaticResponse.DOWNLOADING;
|
return StaticResponse.DOWNLOADING;
|
||||||
} else if (torrent && statusError(torrent.status)) {
|
} else if (torrent && statusError(torrent.status)) {
|
||||||
@@ -49,8 +104,8 @@ async function resolve({ ip, apiKey, infoHash, cachedEntryInfo, fileIndex }) {
|
|||||||
return Promise.reject("Failed Premiumize adding torrent");
|
return Promise.reject("Failed Premiumize adding torrent");
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _getCachedLink(PM, infoHash, encodedFileName, fileIndex) {
|
async function _getCachedLink(PM, infoHash, encodedFileName, fileIndex, ip) {
|
||||||
const cachedTorrent = await PM.transfer.directDownload(encode({ infoHash }));
|
const cachedTorrent = await PM.transfer.directDownload(magnet.encode({ infoHash }), ip);
|
||||||
if (cachedTorrent && cachedTorrent.content && cachedTorrent.content.length) {
|
if (cachedTorrent && cachedTorrent.content && cachedTorrent.content.length) {
|
||||||
const targetFileName = decodeURIComponent(encodedFileName);
|
const targetFileName = decodeURIComponent(encodedFileName);
|
||||||
const videos = cachedTorrent.content.filter(file => isVideo(file.path));
|
const videos = cachedTorrent.content.filter(file => isVideo(file.path));
|
||||||
@@ -113,4 +168,4 @@ async function getDefaultOptions(id, ip) {
|
|||||||
return { timeout: 30000, agent: agent, headers: { 'User-Agent': userAgent } };
|
return { timeout: 30000, agent: agent, headers: { 'User-Agent': userAgent } };
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { getCachedStreams, resolve };
|
module.exports = { getCachedStreams, resolve, getCatalog, getItemMeta };
|
||||||
19
addon/package-lock.json
generated
19
addon/package-lock.json
generated
@@ -1426,6 +1426,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
|
||||||
"integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0="
|
"integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0="
|
||||||
},
|
},
|
||||||
|
"is_js": {
|
||||||
|
"version": "0.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is_js/-/is_js-0.9.0.tgz",
|
||||||
|
"integrity": "sha1-CrlFQFArp6+iTIVqqYVWFmnpxS0="
|
||||||
|
},
|
||||||
"isarray": {
|
"isarray": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||||
@@ -1913,9 +1918,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"premiumize-api": {
|
"premiumize-api": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/premiumize-api/-/premiumize-api-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/premiumize-api/-/premiumize-api-1.0.2.tgz",
|
||||||
"integrity": "sha512-2lhZ7x2C6ESaQ0WraYyDCD7sy6JuV5c2KmoypmJpD17CGzyPjQT7/eDqLzAqnDSK0LeICEaRy+rB9KZMBX5+SQ==",
|
"integrity": "sha512-lp5AJ+0dP3wWH/UhciNvUW6OVXKJAj3uNXjN5TWlKIS62aEynlPaYWms7DnacwwZ1cFfJXY8RblBsUUja6p97w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"request": "^2.83.0"
|
"request": "^2.83.0"
|
||||||
}
|
}
|
||||||
@@ -2044,6 +2049,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"request-ip": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/request-ip/-/request-ip-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-J3qdE/IhVM3BXkwMIVO4yFrvhJlU3H7JH16+6yHucadT4fePnR8dyh+vEs6FIx0S2x5TCt2ptiPfHcn0sqhbYQ==",
|
||||||
|
"requires": {
|
||||||
|
"is_js": "^0.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"require_optional": {
|
"require_optional": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
|
||||||
|
|||||||
@@ -21,8 +21,9 @@
|
|||||||
"parse-torrent-title": "git://github.com/TheBeastLT/parse-torrent-title.git#3e3932737604f4a9215a6800f6c263bb2f92f1ce",
|
"parse-torrent-title": "git://github.com/TheBeastLT/parse-torrent-title.git#3e3932737604f4a9215a6800f6c263bb2f92f1ce",
|
||||||
"pg": "^7.8.2",
|
"pg": "^7.8.2",
|
||||||
"pg-hstore": "^2.3.2",
|
"pg-hstore": "^2.3.2",
|
||||||
"premiumize-api": "^1.0.1",
|
"premiumize-api": "^1.0.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",
|
||||||
|
"request-ip": "^2.1.3",
|
||||||
"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"
|
"user-agents": "^1.0.559"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
const rateLimit = require('express-rate-limit');
|
const rateLimit = require('express-rate-limit');
|
||||||
const { getRouter } = require('stremio-addon-sdk');
|
const { getRouter } = require('stremio-addon-sdk');
|
||||||
|
const requestIp = require('request-ip');
|
||||||
const addonInterface = require('./addon');
|
const addonInterface = require('./addon');
|
||||||
const qs = require('querystring')
|
const qs = require('querystring')
|
||||||
const { manifest } = require('./lib/manifest');
|
const { manifest } = require('./lib/manifest');
|
||||||
@@ -77,7 +78,7 @@ router.get('/:moch/:apiKey/:infoHash/:cachedEntryInfo/:fileIndex?', (req, res) =
|
|||||||
infoHash: req.params.infoHash,
|
infoHash: req.params.infoHash,
|
||||||
fileIndex: isNaN(req.params.fileIndex) ? undefined : parseInt(req.params.fileIndex),
|
fileIndex: isNaN(req.params.fileIndex) ? undefined : parseInt(req.params.fileIndex),
|
||||||
cachedEntryInfo: req.params.cachedEntryInfo,
|
cachedEntryInfo: req.params.cachedEntryInfo,
|
||||||
ip: req.ip
|
ip: requestIp.getClientIp(req)
|
||||||
}
|
}
|
||||||
moch.resolve(parameters)
|
moch.resolve(parameters)
|
||||||
.then(url => {
|
.then(url => {
|
||||||
|
|||||||
Reference in New Issue
Block a user