This commit is contained in:
2022-01-03 18:03:53 +01:00
parent 559e32c059
commit 14775744b0
2 changed files with 151 additions and 122 deletions

View File

@@ -1,176 +1,205 @@
const fetch = require('node-fetch')
const convertPlexToMovie = require('src/plex/convertPlexToMovie')
const convertPlexToShow = require('src/plex/convertPlexToShow')
const convertPlexToEpisode = require('src/plex/convertPlexToEpisode')
const fetch = require("node-fetch");
const convertPlexToMovie = require("src/plex/convertPlexToMovie");
const convertPlexToShow = require("src/plex/convertPlexToShow");
const convertPlexToEpisode = require("src/plex/convertPlexToEpisode");
const { Movie, Show, Person } = require('src/tmdb/types')
const { Movie, Show, Person } = require("src/tmdb/types");
const RedisCache = require('src/cache/redis')
const redisCache = new RedisCache()
const RedisCache = require("src/cache/redis");
const redisCache = new RedisCache();
const sanitize = (string) => string.toLowerCase().replace(/[^\w\s]/gi, '')
const sanitize = string => string.toLowerCase().replace(/[^\w\s]/gi, "");
const matchingTitleAndYear = (plex, tmdb) => {
let matchingTitle, matchingYear;
if (plex['title'] != null && tmdb['title'] != null) {
const plexTitle = sanitize(plex.title)
const tmdbTitle = sanitize(tmdb.title)
if (plex["title"] != null && tmdb["title"] != null) {
const plexTitle = sanitize(plex.title);
const tmdbTitle = sanitize(tmdb.title);
matchingTitle = plexTitle == tmdbTitle;
matchingTitle = matchingTitle ? matchingTitle : plexTitle.startsWith(tmdbTitle)
}
else
matchingTitle = false;
matchingTitle = matchingTitle
? matchingTitle
: plexTitle.startsWith(tmdbTitle);
} else matchingTitle = false;
if (plex['year'] != null && tmdb['year'] != null)
if (plex["year"] != null && tmdb["year"] != null)
matchingYear = plex.year == tmdb.year;
else
matchingYear = false;
else matchingYear = false;
return matchingTitle && matchingYear
}
return matchingTitle && matchingYear;
};
const successfullResponse = (response) => {
const { status, statusText } = response
const successfullResponse = response => {
const { status, statusText } = response;
if (status === 200) {
return response.json()
return response.json();
} else {
throw { message: statusText, status: status }
throw { message: statusText, status: status };
}
}
};
class Plex {
constructor(ip, port=32400, cache=null) {
this.plexIP = ip
this.plexPort = port
constructor(ip, port = 32400, cache = null) {
this.plexIP = ip;
this.plexPort = port;
this.cache = cache || redisCache;
this.cacheTags = {
machineInfo: 'plex/mi',
search: 'plex/s'
}
machineInfo: "plex/mi",
search: "plex/s"
};
}
fetchMachineIdentifier() {
const cacheKey = `${this.cacheTags.machineInfo}`
const url = `http://${this.plexIP}:${this.plexPort}/`
const cacheKey = `${this.cacheTags.machineInfo}`;
const url = `http://${this.plexIP}:${this.plexPort}/`;
const options = {
timeout: 20000,
headers: { 'Accept': 'application/json' }
}
headers: { Accept: "application/json" }
};
return new Promise((resolve, reject) => this.cache.get(cacheKey)
.then(machineInfo => resolve(machineInfo['machineIdentifier']))
.catch(() => fetch(url, options))
.then(response => response.json())
.then(machineInfo => this.cache.set(cacheKey, machineInfo['MediaContainer'], 2628000))
.then(machineInfo => resolve(machineInfo['machineIdentifier']))
.catch(error => {
if (error != undefined && error.type === 'request-timeout') {
reject({ message: 'Plex did not respond', status: 408, success: false })
}
return new Promise((resolve, reject) =>
this.cache
.get(cacheKey)
.then(machineInfo => resolve(machineInfo["machineIdentifier"]))
.catch(() => fetch(url, options))
.then(response => response.json())
.then(machineInfo =>
this.cache.set(cacheKey, machineInfo["MediaContainer"], 2628000)
)
.then(machineInfo => resolve(machineInfo["machineIdentifier"]))
.catch(error => {
if (error != undefined && error.type === "request-timeout") {
reject({
message: "Plex did not respond",
status: 408,
success: false
});
}
reject(error)
})
)
reject(error);
})
);
}
matchTmdbAndPlexMedia(plex, tmdb) {
let match;
if (plex == null || tmdb == null)
return false
if (plex == null || tmdb == null) return false;
if (plex instanceof Array) {
let possibleMatches = plex.map(plexItem => matchingTitleAndYear(plexItem, tmdb))
match = possibleMatches.includes(true)
let possibleMatches = plex.map(plexItem =>
matchingTitleAndYear(plexItem, tmdb)
);
match = possibleMatches.includes(true);
} else {
match = matchingTitleAndYear(plex, tmdb)
match = matchingTitleAndYear(plex, tmdb);
}
return match
return match;
}
async existsInPlex(tmdb) {
const plexMatch = await this.findPlexItemByTitleAndYear(tmdb.title, tmdb.year)
return plexMatch ? true : false
const plexMatch = await this.findPlexItemByTitleAndYear(
tmdb.title,
tmdb.year
);
return plexMatch ? true : false;
}
findPlexItemByTitleAndYear(title, year) {
const query = { title, year }
const query = { title, year };
return this.search(query.title)
.then(plexSearchResults => {
const matchesInPlex = plexSearchResults.map(plex => this.matchTmdbAndPlexMedia(plex, query))
return this.search(query.title).then(plexSearchResults => {
const matchesInPlex = plexSearchResults.map(plex =>
this.matchTmdbAndPlexMedia(plex, query)
);
if (matchesInPlex.includes(true) === false)
return false;
if (matchesInPlex.includes(true) === false) return false;
const firstMatchIndex = matchesInPlex.indexOf(true)
return plexSearchResults[firstMatchIndex][0]
})
}
const firstMatchIndex = matchesInPlex.indexOf(true);
return plexSearchResults[firstMatchIndex][0];
});
}
getDirectLinkByTitleAndYear(title, year) {
const machineIdentifierPromise = this.fetchMachineIdentifier()
const matchingObjectInPlexPromise = this.findPlexItemByTitleAndYear(title, year)
return Promise.all([machineIdentifierPromise, matchingObjectInPlexPromise])
.then(([machineIdentifier, matchingObjectInPlex]) => {
if (matchingObjectInPlex == false || matchingObjectInPlex == null ||
matchingObjectInPlex['key'] == null || machineIdentifier == null)
return false
const machineIdentifierPromise = this.fetchMachineIdentifier();
const matchingObjectInPlexPromise = this.findPlexItemByTitleAndYear(
title,
year
);
const keyUriComponent = encodeURIComponent(matchingObjectInPlex.key)
return `https://app.plex.tv/desktop#!/server/${machineIdentifier}/details?key=${keyUriComponent}`
})
}
return Promise.all([
machineIdentifierPromise,
matchingObjectInPlexPromise
]).then(([machineIdentifier, matchingObjectInPlex]) => {
if (
matchingObjectInPlex == false ||
matchingObjectInPlex == null ||
matchingObjectInPlex["key"] == null ||
machineIdentifier == null
)
return false;
const keyUriComponent = encodeURIComponent(matchingObjectInPlex.key);
return `https://app.plex.tv/desktop#!/server/${machineIdentifier}/details?key=${keyUriComponent}`;
});
}
search(query) {
const cacheKey = `${this.cacheTags.search}:${query}`
const cacheKey = `${this.cacheTags.search}:${query}`;
const url = `http://${this.plexIP}:${this.plexPort}/hubs/search?query=${encodeURIComponent(query)}`
const url = `http://${this.plexIP}:${
this.plexPort
}/hubs/search?query=${encodeURIComponent(query)}`;
const options = {
timeout: 20000,
headers: { 'Accept': 'application/json' }
}
headers: { Accept: "application/json" }
};
return new Promise((resolve, reject) => this.cache.get(cacheKey)
.catch(() => fetch(url, options)) // else fetch fresh data
.then(successfullResponse)
.then(results => this.cache.set(cacheKey, results, 21600))
.then(this.mapResults)
.then(resolve)
.catch(error => {
if (error != undefined && error.type === 'request-timeout') {
reject({ message: 'Plex did not respond', status: 408, success: false })
}
return new Promise((resolve, reject) =>
this.cache
.get(cacheKey)
.catch(() => fetch(url, options)) // else fetch fresh data
.then(successfullResponse)
.then(results => this.cache.set(cacheKey, results, 21600))
.then(this.mapResults)
.then(resolve)
.catch(error => {
if (error != undefined && error.type === "request-timeout") {
reject({
message: "Plex did not respond",
status: 408,
success: false
});
}
reject(error)
})
)
reject(error);
})
);
}
mapResults(response) {
if (response == null || response.MediaContainer == null || response.MediaContainer.Hub == null) {
return []
if (
response == null ||
response.MediaContainer == null ||
response.MediaContainer.Hub == null
) {
return [];
}
return response.MediaContainer.Hub
.filter(category => category.size > 0)
return response.MediaContainer.Hub.filter(category => category.size > 0)
.map(category => {
if (category.type === 'movie') {
return category.Metadata
} else if (category.type === 'show') {
return category.Metadata.map(convertPlexToShow)
} else if (category.type === 'episode') {
return category.Metadata.map(convertPlexToEpisode)
if (category.type === "movie") {
return category.Metadata;
} else if (category.type === "show") {
return category.Metadata.map(convertPlexToShow);
} else if (category.type === "episode") {
return category.Metadata.map(convertPlexToEpisode);
}
})
.filter(result => result !== undefined)
.filter(result => result !== undefined);
}
}

View File

@@ -1,11 +1,11 @@
/*
* @Author: KevinMidboe
* @Date: 2017-10-21 09:54:31
* @Last Modified by: KevinMidboe
* @Last Modified time: 2018-02-26 19:56:32
*/
* @Author: KevinMidboe
* @Date: 2017-10-21 09:54:31
* @Last Modified by: KevinMidboe
* @Last Modified time: 2018-02-26 19:56:32
*/
const PirateRepository = require('src/pirate/pirateRepository');
const PirateRepository = require("src/pirate/pirateRepository");
// const pirateRepository = new PirateRepository();
/**
@@ -15,15 +15,15 @@ const PirateRepository = require('src/pirate/pirateRepository');
* @returns {Callback}
*/
function updateRequested(req, res) {
const { query, page, type } = req.query;
const { query, page, type } = req.query;
PirateRepository.SearchPiratebay(query, page, type)
.then((result) => {
res.send({ success: true, results: result });
})
.catch(error => {
res.status(401).send({ success: false, message: error.message });
});
PirateRepository.SearchPiratebay(query, page, type)
.then(result => {
res.send({ success: true, results: result });
})
.catch(error => {
res.status(401).send({ success: false, message: error.message });
});
}
module.exports = updateRequested;