From 0125fc6fe5b25faad80a77af488ad0c5aa738c3f Mon Sep 17 00:00:00 2001 From: TheBeastLT Date: Mon, 17 Feb 2020 09:49:24 +0100 Subject: [PATCH] adds episode decomposing based on date --- lib/cache.js | 19 ++++++++++++++----- lib/metadata.js | 1 + lib/torrentFiles.js | 44 +++++++++++++++++++++++++++++++++++++++----- manual/manual.js | 30 +++++++++++++++++++----------- package-lock.json | 2 +- 5 files changed, 74 insertions(+), 22 deletions(-) diff --git a/lib/cache.js b/lib/cache.js index 3542a36..d509fb4 100644 --- a/lib/cache.js +++ b/lib/cache.js @@ -7,10 +7,12 @@ 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 MEMORY_TTL = process.env.METADATA_TTL || 2 * 60 * 60; // 2 hours const MONGO_URI = process.env.MONGODB_URI; -const cache = initiateCache(); +const memoryCache = initiateMemoryCache(); +const remoteCache = initiateRemoteCache(); const torrentFilesCache = initiateTorrentFilesCache(); function initiateTorrentFilesCache() { @@ -27,7 +29,7 @@ function initiateTorrentFilesCache() { } } -function initiateCache() { +function initiateRemoteCache() { if (MONGO_URI) { return cacheManager.caching({ store: mangodbStore, @@ -46,6 +48,13 @@ function initiateCache() { } } +function initiateMemoryCache() { + return cacheManager.caching({ + store: 'memory', + ttl: MEMORY_TTL + }); +} + function retrieveTorrentFiles(infoHash) { return torrentFilesCache.get(`${TORRENT_FILES_KEY_PREFIX}:${infoHash}`) .then((results) => { @@ -56,16 +65,16 @@ function retrieveTorrentFiles(infoHash) { }); } -function cacheWrap(key, method, options) { +function cacheWrap(cache, key, method, options) { return cache.wrap(key, method, options); } function cacheWrapImdbId(key, method) { - return cacheWrap(`${IMDB_ID_PREFIX}:${key}`, method, { ttl: GLOBAL_TTL }); + return cacheWrap(remoteCache, `${IMDB_ID_PREFIX}:${key}`, method, { ttl: GLOBAL_TTL }); } function cacheWrapMetadata(id, method) { - return cacheWrap(`${METADATA_PREFIX}:${id}`, method, { ttl: GLOBAL_TTL }); + return cacheWrap(memoryCache, `${METADATA_PREFIX}:${id}`, method, { ttl: GLOBAL_TTL }); } module.exports = { cacheWrapImdbId, cacheWrapMetadata, retrieveTorrentFiles }; diff --git a/lib/metadata.js b/lib/metadata.js index 5a1f479..a911cb5 100644 --- a/lib/metadata.js +++ b/lib/metadata.js @@ -20,6 +20,7 @@ function getMetadata(id, type = Type.SERIES) { imdbId: body.meta.imdb_id, title: body.meta.name, year: body.meta.year, + country: body.meta.country, genres: body.meta.genres, videos: (body.meta.videos || []) .map((video) => video.imdbSeason diff --git a/lib/torrentFiles.js b/lib/torrentFiles.js index 75bdf64..5bf6ccc 100644 --- a/lib/torrentFiles.js +++ b/lib/torrentFiles.js @@ -1,6 +1,7 @@ +const moment = require('moment'); +const { parse } = require('parse-torrent-title'); const { torrentFiles } = require('../lib/torrent'); const { escapeTitle, getMetadata, getImdbId } = require('../lib/metadata'); -const { parse } = require('parse-torrent-title'); const { Type } = require('./types'); const MIN_SIZE = 20 * 1024 * 1024; // 20 MB @@ -116,7 +117,7 @@ function parseSeriesFile(file, parsedTorrentName) { } async function decomposeEpisodes(torrent, files, metadata = { episodeCount: {} }) { - if (files.every(file => !file.episodes)) { + if (files.every(file => !file.episodes && !file.date)) { return files; } // for anime type episodes are always absolute and for a single season @@ -137,12 +138,12 @@ async function decomposeEpisodes(torrent, files, metadata = { episodeCount: {} } && sortedEpisodes.every(ep => metadata.episodeCount[div100(ep) - 1] >= mod100(ep)) && files.every(file => !file.season || file.episodes.every(ep => div100(ep) === file.season))) { decomposeConcatSeasonAndEpisodeFiles(torrent, files, metadata); - } - - if ((files.every(file => !file.season) || files.some(file => file.season && file.episodes + } else if ((files.every(file => !file.season && file.episodes) || files.some(file => file.season && file.episodes && file.episodes.every(ep => metadata.episodeCount[file.season - 1] < ep))) && (sortedEpisodes.length <= 1 || sortedEpisodes.slice(1).every((ep, i) => ep - sortedEpisodes[i] <= 2))) { decomposeAbsoluteEpisodeFiles(torrent, files, metadata); + } else if (files.every(file => !file.season && file.date)) { + decomposeDateEpisodeFiles(torrent, files, metadata); } return files; @@ -179,6 +180,39 @@ function decomposeAbsoluteEpisodeFiles(torrent, files, metadata) { }); } +function decomposeDateEpisodeFiles(torrent, files, metadata) { + if (!metadata || !metadata.videos || !metadata.videos.length) { + return; + } + + const timeZoneOffset = getTimeZoneOffset(metadata.country); + const offsetVideos = metadata.videos + .reduce((map, video) => { + const releaseDate = moment(video.released).utcOffset(timeZoneOffset).format('YYYY-MM-DD'); + map[releaseDate] = video; + return map; + }, {}); + + files + .filter(file => file.date) + .forEach(file => { + const video = offsetVideos[file.date]; + if (video) { + file.season = video.season; + file.episodes = [video.episode]; + } + }); +} + +function getTimeZoneOffset(country) { + switch (country) { + case 'USA': + return '-08:00'; + default: + return '00:00'; + } +} + function assignKitsuOrImdbEpisodes(files, metadata) { if (!metadata || !metadata.videos || !metadata.videos.length) { return files; diff --git a/manual/manual.js b/manual/manual.js index 9084cd3..cdca616 100644 --- a/manual/manual.js +++ b/manual/manual.js @@ -30,40 +30,48 @@ async function findAllFiles() { const torrent = { infoHash: '6b95e5cfde9aaa71970a14f6bb6b9de19e2cbfa1', title: '[OMDA] Bleach + Filmes + Ovas (480p-720p x264 AAC-MP3) [rich_jc]', - type: Type.SERIES + type: Type.SERIES, + imdbId: 'tt0434665' }; - const imdbId = 'tt0434665'; /* Season and concat episodes */ // const torrent = { // infoHash: '235e8ed73b6cc9679b0842c39e17223c47b51f68', // title: 'Daria - The Complete Animated Series [2010] DVDRip', - // type: Type.SERIES + // type: Type.SERIES, + // imdbId: 'tt0118298' // }; - // const imdbId = 'tt0118298'; /* Series Season and absolute episodes */ // const torrent = { // infoHash: '16b4560beb05397c0eeb35487a997caf789243ea', // title: 'Seinfeld - Complete Collection', - // type: Type.SERIES + // type: Type.SERIES, + // imdbId: 'tt0098904' // }; - // const imdbId = 'tt0098904'; /* Series Season and episodes */ // const torrent = { // infoHash: 'd0f120c1bbfb988eb35b648e1c78ca3e5d45ef39', // title: 'Seinfeld Complete Series-720p WEBrip EN-SUB x264-[MULVAcoded]', - // type: Type.SERIES + // type: Type.SERIES, + // imdbId: 'tt0098904' // }; - // const imdbId = 'tt0098904'; /* Anime single absolute episode */ // const torrent = { // infoHash: 'e81e12880980086c476aa8bfdd22bed9d41b1dfe', // title: '[Vision] Naruto Shippuuden - 451 (1080p x264 AAC) [rich_jc].mp4', // size: 467361138, - // type: Type.SERIES + // type: Type.SERIES, + // imdbId: 'tt0988824' + // }; + /* Date based episode */ + // const torrent = { + // infoHash: '5a8e9e64fa04e3541236f049cb6b0d35e4ca12cc', + // title: 'Jimmy.Fallon.2020.02.14.Steve.Buscemi.WEB.x264-XLF[TGx]', + // size: 618637331, + // type: Type.SERIES, + // imdbId: 'tt3444938' // }; - // const imdbId = 'tt0988824'; - return parseTorrentFiles(torrent, imdbId) + return parseTorrentFiles(torrent) .then((files) => console.log(files)); } diff --git a/package-lock.json b/package-lock.json index deb4906..fe1b312 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1714,7 +1714,7 @@ } }, "parse-torrent-title": { - "version": "git://github.com/TheBeastLT/parse-torrent-title.git#e05b0e0121a944c1ab399e767640a0c8f9300e8e", + "version": "git://github.com/TheBeastLT/parse-torrent-title.git#bfa710a62818723049b39869756bb198056ddde3", "from": "git://github.com/TheBeastLT/parse-torrent-title.git#master" }, "parseurl": {