diff --git a/scraper/lib/metadata.js b/scraper/lib/metadata.js index 7acb3c1..ff063d6 100644 --- a/scraper/lib/metadata.js +++ b/scraper/lib/metadata.js @@ -83,7 +83,7 @@ function escapeTitle(title) { .normalize('NFKD') // normalize non-ASCII characters .replace(/[\u0300-\u036F]/g, '') .replace(/&/g, 'and') - .replace(/[;, ~.]+/g, ' ') // replace dots, commas or underscores with spaces + .replace(/[;, ~./]+/g, ' ') // replace dots, commas or underscores with spaces .replace(/[^\w \-()+#@!']+/g, '') // remove all non-alphanumeric chars .replace(/\s{2,}/, ' ') // replace multiple spaces .trim(); @@ -121,7 +121,7 @@ async function getImdbId(info, type) { } async function getKitsuId(info) { - const title = escapeTitle(info.title); + const title = escapeTitle(info.title.replace(/\s\|\s.*/, '')); const year = info.year ? ` ${info.year}` : ''; const season = info.season > 1 ? ` S${info.season}` : ''; const query = `${title}${year}${season}`; diff --git a/scraper/lib/torrent.js b/scraper/lib/torrent.js index dc91152..ec952a4 100644 --- a/scraper/lib/torrent.js +++ b/scraper/lib/torrent.js @@ -126,7 +126,7 @@ function filterVideos(files) { const videos = files.filter(file => isVideo(file.path)); const maxSize = Math.max(...videos.map(video => video.size)); const minSampleRatio = videos.length <= 3 ? 5 : 10; - const minAnimeExtraRatio = 7; + const minAnimeExtraRatio = 5; const minRedundantRatio = videos.length <= 3 ? 30 : Number.MAX_VALUE; const isSample = video => video.path.match(/sample/i) && maxSize / parseInt(video.size) > minSampleRatio; const isRedundant = video => maxSize / parseInt(video.size) > minRedundantRatio; diff --git a/scraper/lib/torrentFiles.js b/scraper/lib/torrentFiles.js index 973a4d3..3acf765 100644 --- a/scraper/lib/torrentFiles.js +++ b/scraper/lib/torrentFiles.js @@ -160,6 +160,9 @@ async function decomposeEpisodes(torrent, files, metadata = { episodeCount: [] } // because of imdb season naming/absolute per series naming/multiple seasons // So in these cases we need to fetch cinemeta based metadata and decompose episodes using that await updateToCinemetaMetadata(metadata); + files + .filter(file => file.season === undefined && file.episodes) + .forEach(file => file.season = 1); } else { // otherwise for anime type episodes are always absolute and for a single season files @@ -395,14 +398,15 @@ function needsCinemetaMetadataForAnime(files, metadata) { return false; } + const minSeason = Math.min(...metadata.videos.map(video => video.imdbSeason)) || Number.MAX_VALUE; const maxSeason = Math.max(...metadata.videos.map(video => video.imdbSeason)) || Number.MAX_VALUE; const differentSeasons = new Set(metadata.videos .map(video => video.imdbSeason) .filter(season => Number.isInteger(season))).size; - const totalEpisodes = metadata.totalCount || Number.MAX_VALUE; + const total = metadata.totalCount || Number.MAX_VALUE; return differentSeasons > 1 || files .filter(file => !file.isMovie && file.episodes) - .some(file => file.season > maxSeason || file.episodes.every(ep => ep > totalEpisodes)); + .some(file => file.season < minSeason || file.season > maxSeason || file.episodes.every(ep => ep > total)); } async function updateToCinemetaMetadata(metadata) { diff --git a/scraper/manual/manual.js b/scraper/manual/manual.js index 53c76b9..f9081ab 100644 --- a/scraper/manual/manual.js +++ b/scraper/manual/manual.js @@ -67,9 +67,12 @@ async function reapplyEpisodeDecomposing(infoHash, includeSourceFiles = true) { path: file.title, size: file.size })); - const imdbId = mostCommonValue(storedFiles.map(file => file.imdbId)) || await getImdbId(parse(torrent.title)); + const kitsuId = undefined; + const imdbId = kitsuId + ? undefined + : mostCommonValue(storedFiles.map(file => file.imdbId)) || await getImdbId(parse(torrent.title)); - return parseTorrentFiles({ ...torrent.get(), imdbId, files }) + return parseTorrentFiles({ ...torrent.get(), imdbId, kitsuId, files }) .then(torrentContents => torrentContents.videos) .then(newFiles => newFiles.map(file => { const fileIndex = file.fileIndex !== undefined ? file.fileIndex : null; @@ -91,7 +94,7 @@ async function reapplyEpisodeDecomposing(infoHash, includeSourceFiles = true) { })) .then(updatedFiles => Promise.all(updatedFiles .map(file => file.id ? file.save() : repository.createFile(file)))) - .then(() => console.log(`Updated files for ${torrent.title}`)); + .then(() => console.log(`Updated files for [${torrent.infoHash}] ${torrent.title}`)); } async function assignSubs() { @@ -188,6 +191,18 @@ async function findAllFiles() { // type: Type.SERIES, // imdbId: 'tt0912343' // }; + /* With two anime seasons counted as one season */ + // const torrent = { + // infoHash: 'ea02b20a87df600c11d2b405e52813de5d431102', + // title: '[zza] No Guns Life - (S01-S02) [1080p.x265][multisubs:eng,fre][Vostfr]', + // type: Type.ANIME, + // kitsuId: 42197 + // }; + /* With two anime seasons in absolute order counted as one season */ + // const torrent = { + // infoHash: '8b894d747451d50a3bd8d8fd962e4d49da6850ec', + // title: '[JacobSwaggedUp] Gate | Gate: Jieitai Kanochi nite, Kaku Tatakaeri | Gate: Thus the JSDF Fought There! - + // Complete (BD 1280x720) [MP4 Batch]', type: Type.ANIME, kitsuId: 10085 }; return parseTorrentFiles(torrent) .then((files) => console.log(files.videos)); @@ -195,7 +210,7 @@ async function findAllFiles() { //findAllFiles().then(() => console.log('Finished')); //updateMovieCollections().then(() => console.log('Finished')); -reapplyEpisodeDecomposing('3598d561d632c7a6be23fd9245f7323f89ca0ee8', false).then(() => console.log('Finished')); +reapplyEpisodeDecomposing('9bfabed62825874d2f2150ffb45c533f48636222', false).then(() => console.log('Finished')); //reapplySeriesSeasonsSavedAsMovies().then(() => console.log('Finished')); //reapplyDecomposingToTorrentsOnRegex('.*Boku no Hero Academia.*').then(() => console.log('Finished')); //reapplyManualHashes().then(() => console.log('Finished'));