updating to use tpb cached torrent files

This commit is contained in:
TheBeastLT
2019-12-31 19:32:51 +01:00
parent 7aa0572fb8
commit 5cfc82134a
11 changed files with 147 additions and 23 deletions

View File

@@ -1,19 +1,45 @@
const cacheManager = require('cache-manager');
const mangodbStore = require('cache-manager-mongodb');
const GLOBAL_KEY_PREFIX = 'stremio-torrentio';
const IMDB_ID_PREFIX = `${GLOBAL_KEY_PREFIX}|imdb_id`;
const METADATA_PREFIX = `${GLOBAL_KEY_PREFIX}|metadata`;
const TORRENT_FILES_KEY_PREFIX = `stremio-tpb|files`;
const GLOBAL_TTL = process.env.METADATA_TTL || 7 * 24 * 60 * 60; // 7 days
const MONGO_URI = process.env.MONGODB_URI;
const cache = initiateCache();
function initiateCache() {
return cacheManager.caching({
store: 'memory',
ttl: GLOBAL_TTL
});
if (MONGO_URI) {
return cacheManager.caching({
store: mangodbStore,
uri: MONGO_URI,
options: {
collection: 'cacheManager',
},
ttl: GLOBAL_TTL,
ignoreCacheErrors: true
});
} else {
return cacheManager.caching({
store: 'memory',
ttl: GLOBAL_TTL
});
}
}
function retrieveTorrentFiles(infoHash) {
return cache.get(`${TORRENT_FILES_KEY_PREFIX}:${infoHash}`)
.then((results) => {
if (!results) {
throw new Error('No cached files found');
}
return results;
});
}
function cacheWrap(key, method, options) {
@@ -28,5 +54,5 @@ function cacheWrapMetadata(id, method) {
return cacheWrap(`${METADATA_PREFIX}:${id}`, method, { ttl: GLOBAL_TTL });
}
module.exports = { cacheWrapImdbId, cacheWrapMetadata };
module.exports = { cacheWrapImdbId, cacheWrapMetadata, retrieveTorrentFiles };

View File

@@ -13,7 +13,7 @@ const Provider = database.define('provider', {
const Torrent = database.define('torrent', {
infoHash: { type: Sequelize.STRING(64), primaryKey: true },
provider: { type: Sequelize.STRING(32), allowNull: false },
title: { type: Sequelize.STRING(128), allowNull: false },
title: { type: Sequelize.STRING(256), allowNull: false },
size: { type: Sequelize.BIGINT },
type: { type: Sequelize.STRING(16), allowNull: false },
uploadDate: { type: Sequelize.DATE, allowNull: false },
@@ -25,9 +25,9 @@ const File = database.define('file',
id: { type: Sequelize.BIGINT, autoIncrement: true, primaryKey: true },
infoHash: { type: Sequelize.STRING(64), allowNull: false, references: { model: Torrent, key: 'infoHash' }, onDelete: 'CASCADE' },
fileIndex: { type: Sequelize.INTEGER },
title: { type: Sequelize.STRING(128), allowNull: false },
title: { type: Sequelize.STRING(256), allowNull: false },
size: { type: Sequelize.BIGINT },
imdbId: { type: Sequelize.STRING(12) },
imdbId: { type: Sequelize.STRING(32) },
imdbSeason: { type: Sequelize.INTEGER },
imdbEpisode: { type: Sequelize.INTEGER },
kitsuId: { type: Sequelize.INTEGER },
@@ -49,7 +49,7 @@ const SkipTorrent = database.define('skip_torrent', {
const FailedImdbTorrent = database.define('failed_imdb_torrent', {
infoHash: {type: Sequelize.STRING(64), primaryKey: true},
title: { type: Sequelize.STRING(128), allowNull: false }
title: { type: Sequelize.STRING(256), allowNull: false }
});
function connect() {

View File

@@ -3,6 +3,7 @@ const cheerio = require('cheerio');
const needle = require('needle');
const parseTorrent = require('parse-torrent');
const Tracker = require("peer-search/tracker");
const { retrieveTorrentFiles } = require('./cache');
const MAX_PEER_CONNECTIONS = process.env.MAX_PEER_CONNECTIONS || 20;
const EXTENSIONS = ["3g2", "3gp", "avi", "flv", "mkv", "mov", "mp2", "mp4", "mpe", "mpeg", "mpg", "mpv", "webm", "wmv"];
@@ -16,6 +17,7 @@ module.exports.torrentFiles = function(torrent) {
return filesFromTorrentFile(torrent)
.catch(() => filesFromKat(torrent.infoHash))
.catch(() => filesFromTorrentStream(torrent))
.catch(() => filesFromCache(torrent.infoHash))
.then((files) => files.filter((file) => isVideo(file)));
};
@@ -42,6 +44,16 @@ module.exports.currentSeeders = function (torrent) {
// .then((match) => JSON.parse(match).props.pageProps.result.torrent.files)
// }
function filesFromCache(infoHash) {
return retrieveTorrentFiles(infoHash)
.then((files) => files.map((file) => ({
fileIndex: parseInt(file.match(/^(\d+)@@/)[1]),
name: file.replace(/.+\/|^\d+@@/, ''),
path: file.replace(/^\d+@@/, ''),
size: 300000000
})));
}
function filesFromKat(infoHash) {
if (!infoHash) {
return Promise.reject(new Error("no infoHash"));
@@ -100,7 +112,7 @@ async function filesFromTorrentStream(torrent) {
return Promise.reject(new Error("no infoHash or magnetLink"));
}
return new Promise((resolve, rejected) => {
const engine = new torrentStream(torrent.magnetLink || torrent.infoHash, { connections: MAX_PEER_CONNECTIONS, trackers: TRACKERS });
const engine = new torrentStream(torrent.magnetLink || torrent.infoHash, { connections: MAX_PEER_CONNECTIONS });
engine.ready(() => {
const files = engine.files
@@ -117,7 +129,7 @@ async function filesFromTorrentStream(torrent) {
setTimeout(() => {
engine.destroy();
rejected(new Error('No available connections for torrent!'));
}, dynamicTimeout(torrent));
}, 30000);
});
}

View File

@@ -63,15 +63,15 @@ function parseFile(file, parsedTorrentName) {
}
async function decomposeAbsoluteEpisodes(files, torrent, imdbId) {
if (files.every((file) => file.episodes.every((ep) => ep < 100))) {
return; // nothing to decompose
if (files.every((file) => !file.episodes || file.episodes.every((ep) => ep < 100))) {
return files; // nothing to decompose
}
const metadata = await getMetadata(imdbId, torrent.type || Type.MOVIE);
// decompose if season is inside path, but individual files are concatenated ex. 101 (S01E01)
files
.filter(file => file.season && metadata.episodeCount[file.season] < 100)
.filter(file => file.episodes.every(ep => ep / 100 === file.season))
.filter(file => file.episodes && file.episodes.every(ep => ep / 100 === file.season))
.forEach(file => file.episodes = file.episodes.map(ep => ep % 100));
// decompose if no season info is available, but individual files are concatenated ex. 101 (S01E01)
// based on total episodes count per season