Merge pull request #129 from KevinMidboe/feat/redis-cache
Feat/redis cache
This commit was merged in pull request #129.
This commit is contained in:
@@ -29,6 +29,7 @@
|
|||||||
"node-fetch": "^2.6.0",
|
"node-fetch": "^2.6.0",
|
||||||
"python-shell": "^0.5.0",
|
"python-shell": "^0.5.0",
|
||||||
"raven": "^2.4.2",
|
"raven": "^2.4.2",
|
||||||
|
"redis": "^3.0.2",
|
||||||
"request": "^2.87.0",
|
"request": "^2.87.0",
|
||||||
"request-promise": "^4.2",
|
"request-promise": "^4.2",
|
||||||
"sqlite3": "^4.0.0"
|
"sqlite3": "^4.0.0"
|
||||||
|
|||||||
49
seasoned_api/src/cache/redis.js
vendored
Normal file
49
seasoned_api/src/cache/redis.js
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
const redis = require("redis")
|
||||||
|
const client = redis.createClient()
|
||||||
|
|
||||||
|
class Cache {
|
||||||
|
/**
|
||||||
|
* Retrieve an unexpired cache entry by key.
|
||||||
|
* @param {String} key of the cache entry
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
get(key) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
client.get(key, (error, reply) => {
|
||||||
|
if (reply == null) {
|
||||||
|
return reject()
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(JSON.parse(reply))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert cache entry with key and value.
|
||||||
|
* @param {String} key of the cache entry
|
||||||
|
* @param {String} value of the cache entry
|
||||||
|
* @param {Number} timeToLive the number of seconds before entry expires
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
set(key, value, timeToLive = 10800) {
|
||||||
|
if (value == null || key == null)
|
||||||
|
return null
|
||||||
|
|
||||||
|
const json = JSON.stringify(value);
|
||||||
|
client.set(key, json, (error, reply) => {
|
||||||
|
if (reply == 'OK') {
|
||||||
|
|
||||||
|
// successfully set value with key, now set TTL for key
|
||||||
|
client.expire(key, timeToLive, (e) => {
|
||||||
|
if (e)
|
||||||
|
console.error('Unexpected error while setting expiration for key:', key, '. Error:', error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Cache;
|
||||||
@@ -31,7 +31,7 @@ CREATE TABLE IF NOT EXISTS search_history (
|
|||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS requests(
|
CREATE TABLE IF NOT EXISTS requests(
|
||||||
id TEXT,
|
id NUMBER,
|
||||||
title TEXT,
|
title TEXT,
|
||||||
year NUMBER,
|
year NUMBER,
|
||||||
poster_path TEXT DEFAULT NULL,
|
poster_path TEXT DEFAULT NULL,
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ const PythonShell = require('python-shell');
|
|||||||
|
|
||||||
const establishedDatabase = require('src/database/database');
|
const establishedDatabase = require('src/database/database');
|
||||||
|
|
||||||
|
const RedisCache = require('src/cache/redis')
|
||||||
|
const cache = new RedisCache()
|
||||||
|
|
||||||
function getMagnetFromURL(url) {
|
function getMagnetFromURL(url) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const options = new URL(url);
|
const options = new URL(url);
|
||||||
@@ -49,15 +52,23 @@ async function callPythonAddMagnet(url, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function SearchPiratebay(query) {
|
async function SearchPiratebay(query) {
|
||||||
return await new Promise((resolve, reject) => find(query, (err, results) => {
|
const cacheKey = `pirate/${query}`
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => cache.get(cacheKey)
|
||||||
|
.then(resolve)
|
||||||
|
.catch(() => find(query, (err, results) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('THERE WAS A FUCKING ERROR!\n', err);
|
console.log('THERE WAS A FUCKING ERROR!\n', err);
|
||||||
reject(Error('There was a error when searching for torrents'));
|
reject(Error('There was a error when searching for torrents'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results) {
|
if (results) {
|
||||||
resolve(JSON.parse(results, null, '\t'));
|
const jsonData = JSON.parse(results, null, '\t')
|
||||||
|
cache.set(cacheKey, jsonData)
|
||||||
|
resolve(jsonData);
|
||||||
}
|
}
|
||||||
}));
|
}))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function AddMagnet(magnet, name, tmdb_id) {
|
async function AddMagnet(magnet, name, tmdb_id) {
|
||||||
|
|||||||
@@ -3,60 +3,34 @@ const convertPlexToMovie = require('src/plex/convertPlexToMovie')
|
|||||||
const convertPlexToShow = require('src/plex/convertPlexToShow')
|
const convertPlexToShow = require('src/plex/convertPlexToShow')
|
||||||
const convertPlexToEpisode = require('src/plex/convertPlexToEpisode')
|
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 { Movie, }
|
// const { Movie, }
|
||||||
// TODO? import class definitions to compare types ?
|
// TODO? import class definitions to compare types ?
|
||||||
// what would typescript do?
|
// what would typescript do?
|
||||||
|
|
||||||
const matchingTitleOrName = (plex, tmdb) => {
|
|
||||||
if (plex['title'] !== undefined && tmdb['title'] !== undefined)
|
|
||||||
return sanitize(plex.title) === sanitize(tmdb.title)
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
const matchingYear = (plex, tmdb) => {
|
|
||||||
return plex.year === tmdb.year
|
|
||||||
}
|
|
||||||
|
|
||||||
const sanitize = (string) => string.toLowerCase()
|
const sanitize = (string) => string.toLowerCase()
|
||||||
|
|
||||||
class Plex {
|
const matchingTitleAndYear = (plex, tmdb) => {
|
||||||
constructor(ip, port=32400) {
|
let matchingTitle, matchingYear;
|
||||||
this.plexIP = ip
|
|
||||||
this.plexPort = port
|
|
||||||
}
|
|
||||||
|
|
||||||
matchTmdbAndPlexMedia(plex, tmdb) {
|
if (plex['title'] != null && tmdb['title'] != null)
|
||||||
if (plex === undefined || tmdb === undefined)
|
matchingTitle = sanitize(plex.title) == sanitize(tmdb.title);
|
||||||
return false
|
else
|
||||||
|
matchingTitle = false;
|
||||||
|
|
||||||
let titleMatches;
|
if (plex['year'] != null && tmdb['year'] != null)
|
||||||
let yearMatches;
|
matchingYear = plex.year == tmdb.year;
|
||||||
|
else
|
||||||
|
matchingYear = false;
|
||||||
|
|
||||||
if (plex instanceof Array) {
|
return matchingTitle && matchingYear
|
||||||
console.log('Plex object to compare is a list.')
|
}
|
||||||
const plexList = plex
|
|
||||||
console.log('List of plex objects:', plexList)
|
|
||||||
|
|
||||||
titleMatches = plexList.map(plexItem => matchingTitleOrName(plexItem, tmdb))
|
const successfullResponse = (response) => {
|
||||||
yearMatches = plexList.map(plexItem => matchingYear(plexItem, tmdb))
|
|
||||||
} else {
|
|
||||||
titleMatches = matchingTitleOrName(plex, tmdb)
|
|
||||||
yearMatches = matchingYear(plex, tmdb)
|
|
||||||
}
|
|
||||||
|
|
||||||
return titleMatches && yearMatches
|
|
||||||
}
|
|
||||||
|
|
||||||
existsInPlex(tmdbMovie) {
|
|
||||||
return this.search(tmdbMovie.title)
|
|
||||||
.then(plexMovies => plexMovies.some(plex => this.matchTmdbAndPlexMedia(plex, tmdbMovie)))
|
|
||||||
}
|
|
||||||
|
|
||||||
successfullResponse(response) {
|
|
||||||
const { status, statusText } = response
|
const { status, statusText } = response
|
||||||
|
|
||||||
if (status === 200) {
|
if (status === 200) {
|
||||||
@@ -64,30 +38,126 @@ class Plex {
|
|||||||
} else {
|
} 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
|
||||||
|
|
||||||
|
this.cache = cache || redisCache;
|
||||||
|
this.cacheTags = {
|
||||||
|
machineInfo: 'plex/mi',
|
||||||
|
search: 'plex/s'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
search(query) {
|
fetchMachineIdentifier() {
|
||||||
const url = `http://${this.plexIP}:${this.plexPort}/hubs/search?query=${query}`
|
const cacheKey = `${this.cacheTags.machineInfo}`
|
||||||
|
const url = `http://${this.plexIP}:${this.plexPort}/`
|
||||||
const options = {
|
const options = {
|
||||||
timeout: 2000,
|
timeout: 20000,
|
||||||
headers: { 'Accept': 'application/json' }
|
headers: { 'Accept': 'application/json' }
|
||||||
}
|
}
|
||||||
|
|
||||||
return fetch(url, options)
|
return new Promise((resolve, reject) => this.cache.get(cacheKey)
|
||||||
.then(this.successfullResponse)
|
.then(machineInfo => resolve(machineInfo['machineIdentifier']))
|
||||||
.then(this.mapResults)
|
.catch(() => fetch(url, options))
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(machineInfo => this.cache.set(cacheKey, machineInfo['MediaContainer'], 2628000))
|
||||||
|
.then(machineInfo => resolve(machineInfo['machineIdentifier']))
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
if (error.type === 'request-timeout') {
|
if (error != undefined && error.type === 'request-timeout') {
|
||||||
throw { message: 'Plex did not respond', status: 408, success: false }
|
reject({ message: 'Plex did not respond', status: 408, success: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
throw error
|
reject(error)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
matchTmdbAndPlexMedia(plex, tmdb) {
|
||||||
|
let match;
|
||||||
|
|
||||||
|
if (plex == null || tmdb == null)
|
||||||
|
return false
|
||||||
|
|
||||||
|
if (plex instanceof Array) {
|
||||||
|
let possibleMatches = plex.map(plexItem => matchingTitleAndYear(plexItem, tmdb))
|
||||||
|
match = possibleMatches.includes(true)
|
||||||
|
} else {
|
||||||
|
match = matchingTitleAndYear(plex, tmdb)
|
||||||
|
}
|
||||||
|
|
||||||
|
return match
|
||||||
|
}
|
||||||
|
|
||||||
|
async existsInPlex(tmdb) {
|
||||||
|
const plexMatch = await this.findPlexItemByTitleAndYear(tmdb.title, tmdb.year)
|
||||||
|
return plexMatch ? true : false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
findPlexItemByTitleAndYear(title, year) {
|
||||||
|
const query = { title, year }
|
||||||
|
|
||||||
|
return this.search(query.title)
|
||||||
|
.then(plexSearchResults => {
|
||||||
|
const matchesInPlex = plexSearchResults.map(plex => this.matchTmdbAndPlexMedia(plex, query))
|
||||||
|
|
||||||
|
if (matchesInPlex.includes(true) === false)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
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 keyUriComponent = encodeURIComponent(matchingObjectInPlex.key)
|
||||||
|
return `https://app.plex.tv/desktop#!/server/${machineIdentifier}/details?key=${keyUriComponent}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
search(query) {
|
||||||
|
const cacheKey = `${this.cacheTags.search}:${query}`
|
||||||
|
|
||||||
|
const url = `http://${this.plexIP}:${this.plexPort}/hubs/search?query=${encodeURIComponent(query)}`
|
||||||
|
const options = {
|
||||||
|
timeout: 20000,
|
||||||
|
headers: { 'Accept': 'application/json' }
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => this.cache.get(cacheKey)
|
||||||
|
.then(resolve) // if found in cache resolve
|
||||||
|
.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)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
mapResults(response) {
|
mapResults(response) {
|
||||||
if (response === undefined || response.MediaContainer === undefined) {
|
if (response == null || response.MediaContainer == null || response.MediaContainer.Hub == null) {
|
||||||
console.log('response was not valid to map', response)
|
console.log('No results to map in:', response)
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,10 +165,7 @@ class Plex {
|
|||||||
.filter(category => category.size > 0)
|
.filter(category => category.size > 0)
|
||||||
.map(category => {
|
.map(category => {
|
||||||
if (category.type === 'movie') {
|
if (category.type === 'movie') {
|
||||||
return category.Metadata.map(movie => {
|
return category.Metadata
|
||||||
const ovie = Movie.convertFromPlexResponse(movie)
|
|
||||||
return ovie.createJsonResponse()
|
|
||||||
})
|
|
||||||
} else if (category.type === 'show') {
|
} else if (category.type === 'show') {
|
||||||
return category.Metadata.map(convertPlexToShow)
|
return category.Metadata.map(convertPlexToShow)
|
||||||
} else if (category.type === 'episode') {
|
} else if (category.type === 'episode') {
|
||||||
@@ -106,7 +173,7 @@ class Plex {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(result => result !== undefined)
|
.filter(result => result !== undefined)
|
||||||
.flat()
|
// .flat()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
const PlexRepository = require('src/plex/plexRepository');
|
const PlexRepository = require('src/plex/plexRepository');
|
||||||
const Cache = require('src/tmdb/cache');
|
|
||||||
const configuration = require('src/config/configuration').getInstance();
|
const configuration = require('src/config/configuration').getInstance();
|
||||||
const TMDB = require('src/tmdb/tmdb');
|
const TMDB = require('src/tmdb/tmdb');
|
||||||
const establishedDatabase = require('src/database/database');
|
const establishedDatabase = require('src/database/database');
|
||||||
|
|
||||||
const plexRepository = new PlexRepository(configuration.get('plex', 'ip'));
|
const plexRepository = new PlexRepository(configuration.get('plex', 'ip'));
|
||||||
const cache = new Cache();
|
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
|
||||||
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
|
|
||||||
|
|
||||||
class RequestRepository {
|
class RequestRepository {
|
||||||
constructor(database) {
|
constructor(database) {
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
const assert = require('assert')
|
const assert = require('assert')
|
||||||
const configuration = require('src/config/configuration').getInstance();
|
const configuration = require('src/config/configuration').getInstance();
|
||||||
const Cache = require('src/tmdb/cache');
|
|
||||||
const TMDB = require('src/tmdb/tmdb');
|
const TMDB = require('src/tmdb/tmdb');
|
||||||
const cache = new Cache();
|
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
|
||||||
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
|
|
||||||
const establishedDatabase = require('src/database/database');
|
const establishedDatabase = require('src/database/database');
|
||||||
const utils = require('./utils');
|
const utils = require('./utils');
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,36 @@
|
|||||||
const moviedb = require('km-moviedb');
|
const moviedb = require('km-moviedb');
|
||||||
|
const RedisCache = require('src/cache/redis')
|
||||||
|
const redisCache = new RedisCache()
|
||||||
|
|
||||||
const { Movie, Show, Person, Credits, ReleaseDates } = require('src/tmdb/types');
|
const { Movie, Show, Person, Credits, ReleaseDates } = require('src/tmdb/types');
|
||||||
// const { tmdbInfo } = require('src/tmdb/types')
|
// const { tmdbInfo } = require('src/tmdb/types')
|
||||||
|
|
||||||
|
const tmdbErrorResponse = (error, typeString=undefined) => {
|
||||||
|
if (error.status === 404) {
|
||||||
|
let message = error.response.body.status_message;
|
||||||
|
|
||||||
|
throw {
|
||||||
|
status: 404,
|
||||||
|
message: message.slice(0, -1) + " in tmdb."
|
||||||
|
}
|
||||||
|
} else if (error.status === 401) {
|
||||||
|
throw {
|
||||||
|
status: 401,
|
||||||
|
message: error.response.body.status_message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw {
|
||||||
|
status: 500,
|
||||||
|
message: `An unexpected error occured while fetching ${typeString} from tmdb`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class TMDB {
|
class TMDB {
|
||||||
constructor(cache, apiKey, tmdbLibrary) {
|
constructor(apiKey, cache, tmdbLibrary) {
|
||||||
this.cache = cache;
|
|
||||||
this.tmdbLibrary = tmdbLibrary || moviedb(apiKey);
|
this.tmdbLibrary = tmdbLibrary || moviedb(apiKey);
|
||||||
|
|
||||||
|
this.cache = cache || redisCache;
|
||||||
this.cacheTags = {
|
this.cacheTags = {
|
||||||
multiSearch: 'mus',
|
multiSearch: 'mus',
|
||||||
movieSearch: 'mos',
|
movieSearch: 'mos',
|
||||||
@@ -26,6 +50,16 @@ class TMDB {
|
|||||||
miscPopularTvs: 'pt',
|
miscPopularTvs: 'pt',
|
||||||
miscTopRatedTvs: 'trt',
|
miscTopRatedTvs: 'trt',
|
||||||
};
|
};
|
||||||
|
this.defaultTTL = 86400
|
||||||
|
}
|
||||||
|
|
||||||
|
getFromCacheOrFetchFromTmdb(cacheKey, tmdbMethod, query) {
|
||||||
|
return new Promise((resolve, reject) => this.cache.get(cacheKey)
|
||||||
|
.then(resolve)
|
||||||
|
.catch(() => this.tmdb(tmdbMethod, query))
|
||||||
|
.then(resolve)
|
||||||
|
.catch(error => reject(tmdbErrorResponse(error, tmdbMethod)))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,12 +71,10 @@ class TMDB {
|
|||||||
*/
|
*/
|
||||||
movieInfo(identifier) {
|
movieInfo(identifier) {
|
||||||
const query = { id: identifier };
|
const query = { id: identifier };
|
||||||
const cacheKey = `${this.cacheTags.movieInfo}:${identifier}`;
|
const cacheKey = `tmdb/${this.cacheTags.movieInfo}:${identifier}`;
|
||||||
|
|
||||||
return this.cache.get(cacheKey)
|
return this.getFromCacheOrFetchFromTmdb(cacheKey, 'movieInfo', query)
|
||||||
.catch(() => this.tmdb('movieInfo', query))
|
.then(movie => this.cache.set(cacheKey, movie, this.defaultTTL))
|
||||||
.catch(tmdbError => tmdbErrorResponse(tmdbError, 'movie info'))
|
|
||||||
.then(movie => this.cache.set(cacheKey, movie, 1))
|
|
||||||
.then(movie => Movie.convertFromTmdbResponse(movie))
|
.then(movie => Movie.convertFromTmdbResponse(movie))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,12 +85,10 @@ class TMDB {
|
|||||||
*/
|
*/
|
||||||
movieCredits(identifier) {
|
movieCredits(identifier) {
|
||||||
const query = { id: identifier }
|
const query = { id: identifier }
|
||||||
const cacheKey = `${this.cacheTags.movieCredits}:${identifier}`
|
const cacheKey = `tmdb/${this.cacheTags.movieCredits}:${identifier}`
|
||||||
|
|
||||||
return this.cache.get(cacheKey)
|
return this.getFromCacheOrFetchFromTmdb(cacheKey, 'movieCredits', query)
|
||||||
.catch(() => this.tmdb('movieCredits', query))
|
.then(credits => this.cache.set(cacheKey, credits, this.defaultTTL))
|
||||||
.catch(tmdbError => tmdbErrorResponse(tmdbError, 'movie credits'))
|
|
||||||
.then(credits => this.cache.set(cacheKey, credits, 1))
|
|
||||||
.then(credits => Credits.convertFromTmdbResponse(credits))
|
.then(credits => Credits.convertFromTmdbResponse(credits))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,12 +99,10 @@ class TMDB {
|
|||||||
*/
|
*/
|
||||||
movieReleaseDates(identifier) {
|
movieReleaseDates(identifier) {
|
||||||
const query = { id: identifier }
|
const query = { id: identifier }
|
||||||
const cacheKey = `${this.cacheTags.movieReleaseDates}:${identifier}`
|
const cacheKey = `tmdb/${this.cacheTags.movieReleaseDates}:${identifier}`
|
||||||
|
|
||||||
return this.cache.get(cacheKey)
|
return this.getFromCacheOrFetchFromTmdb(cacheKey, 'movieReleaseDates', query)
|
||||||
.catch(() => this.tmdb('movieReleaseDates', query))
|
.then(releaseDates => this.cache.set(cacheKey, releaseDates, this.defaultTTL))
|
||||||
.catch(tmdbError => tmdbErrorResponse(tmdbError, 'movie release dates'))
|
|
||||||
.then(releaseDates => this.cache.set(cacheKey, releaseDates, 1))
|
|
||||||
.then(releaseDates => ReleaseDates.convertFromTmdbResponse(releaseDates))
|
.then(releaseDates => ReleaseDates.convertFromTmdbResponse(releaseDates))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,23 +114,19 @@ class TMDB {
|
|||||||
*/
|
*/
|
||||||
showInfo(identifier) {
|
showInfo(identifier) {
|
||||||
const query = { id: identifier };
|
const query = { id: identifier };
|
||||||
const cacheKey = `${this.cacheTags.showInfo}:${identifier}`;
|
const cacheKey = `tmdb/${this.cacheTags.showInfo}:${identifier}`;
|
||||||
|
|
||||||
return this.cache.get(cacheKey)
|
return this.getFromCacheOrFetchFromTmdb(cacheKey, 'tvInfo', query)
|
||||||
.catch(() => this.tmdb('tvInfo', query))
|
.then(show => this.cache.set(cacheKey, show, this.defaultTTL))
|
||||||
.catch(tmdbError => tmdbErrorResponse(tmdbError, 'tv info'))
|
|
||||||
.then(show => this.cache.set(cacheKey, show, 1))
|
|
||||||
.then(show => Show.convertFromTmdbResponse(show))
|
.then(show => Show.convertFromTmdbResponse(show))
|
||||||
}
|
}
|
||||||
|
|
||||||
showCredits(identifier) {
|
showCredits(identifier) {
|
||||||
const query = { id: identifier }
|
const query = { id: identifier }
|
||||||
const cacheKey = `${this.cacheTags.showCredits}:${identifier}`
|
const cacheKey = `tmdb/${this.cacheTags.showCredits}:${identifier}`
|
||||||
|
|
||||||
return this.cache.get(cacheKey)
|
return this.getFromCacheOrFetchFromTmdb(cacheKey, 'tvCredits', query)
|
||||||
.catch(() => this.tmdb('tvCredits', query))
|
.then(credits => this.cache.set(cacheKey, credits, this.defaultTTL))
|
||||||
.catch(tmdbError => tmdbErrorResponse(tmdbError, 'show credits'))
|
|
||||||
.then(credits => this.cache.set(cacheKey, credits, 1))
|
|
||||||
.then(credits => Credits.convertFromTmdbResponse(credits))
|
.then(credits => Credits.convertFromTmdbResponse(credits))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,22 +138,19 @@ class TMDB {
|
|||||||
*/
|
*/
|
||||||
personInfo(identifier) {
|
personInfo(identifier) {
|
||||||
const query = { id: identifier };
|
const query = { id: identifier };
|
||||||
const cacheKey = `${this.cacheTags.personInfo}:${identifier}`;
|
const cacheKey = `tmdb/${this.cacheTags.personInfo}:${identifier}`;
|
||||||
|
|
||||||
return this.cache.get(cacheKey)
|
return this.getFromCacheOrFetchFromTmdb(cacheKey, 'personInfo', query)
|
||||||
.catch(() => this.tmdb('personInfo', query))
|
.then(person => this.cache.set(cacheKey, person, this.defaultTTL))
|
||||||
.catch(tmdbError => tmdbErrorResponse(tmdbError, 'person info'))
|
|
||||||
.then(person => this.cache.set(cacheKey, person, 1))
|
|
||||||
.then(person => Person.convertFromTmdbResponse(person))
|
.then(person => Person.convertFromTmdbResponse(person))
|
||||||
}
|
}
|
||||||
|
|
||||||
multiSearch(search_query, page=1) {
|
multiSearch(search_query, page=1) {
|
||||||
const query = { query: search_query, page: page };
|
const query = { query: search_query, page: page };
|
||||||
const cacheKey = `${this.cacheTags.multiSearch}:${page}:${search_query}`;
|
const cacheKey = `tmdb/${this.cacheTags.multiSearch}:${page}:${search_query}`;
|
||||||
return this.cache.get(cacheKey)
|
|
||||||
.catch(() => this.tmdb('searchMulti', query))
|
return this.getFromCacheOrFetchFromTmdb(cacheKey, 'searchMulti', query)
|
||||||
.catch(tmdbError => tmdbErrorResponse(tmdbError, 'search results'))
|
.then(response => this.cache.set(cacheKey, response, this.defaultTTL))
|
||||||
.then(response => this.cache.set(cacheKey, response, 1))
|
|
||||||
.then(response => this.mapResults(response));
|
.then(response => this.mapResults(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,12 +162,10 @@ class TMDB {
|
|||||||
*/
|
*/
|
||||||
movieSearch(query, page=1) {
|
movieSearch(query, page=1) {
|
||||||
const tmdbquery = { query: query, page: page };
|
const tmdbquery = { query: query, page: page };
|
||||||
const cacheKey = `${this.cacheTags.movieSearch}:${page}:${query}`;
|
const cacheKey = `tmdb/${this.cacheTags.movieSearch}:${page}:${query}`;
|
||||||
|
|
||||||
return this.cache.get(cacheKey)
|
return this.getFromCacheOrFetchFromTmdb(cacheKey, 'searchMovie', query)
|
||||||
.catch(() => this.tmdb('searchMovie', tmdbquery))
|
.then(response => this.cache.set(cacheKey, response, this.defaultTTL))
|
||||||
.catch(tmdbError => tmdbErrorResponse(tmdbError, 'movie search results'))
|
|
||||||
.then(response => this.cache.set(cacheKey, response, 1))
|
|
||||||
.then(response => this.mapResults(response, 'movie'))
|
.then(response => this.mapResults(response, 'movie'))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,12 +177,10 @@ class TMDB {
|
|||||||
*/
|
*/
|
||||||
showSearch(query, page=1) {
|
showSearch(query, page=1) {
|
||||||
const tmdbquery = { query: query, page: page };
|
const tmdbquery = { query: query, page: page };
|
||||||
const cacheKey = `${this.cacheTags.showSearch}:${page}:${query}`;
|
const cacheKey = `tmdb/${this.cacheTags.showSearch}:${page}:${query}`;
|
||||||
|
|
||||||
return this.cache.get(cacheKey)
|
return this.getFromCacheOrFetchFromTmdb(cacheKey, 'searchTv', query)
|
||||||
.catch(() => this.tmdb('searchTv', tmdbquery))
|
.then(response => this.cache.set(cacheKey, response, this.defaultTTL))
|
||||||
.catch(tmdbError => tmdbErrorResponse(tmdbError, 'tv search results'))
|
|
||||||
.then(response => this.cache.set(cacheKey, response, 1))
|
|
||||||
.then(response => this.mapResults(response, 'show'))
|
.then(response => this.mapResults(response, 'show'))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,33 +193,28 @@ class TMDB {
|
|||||||
personSearch(query, page=1) {
|
personSearch(query, page=1) {
|
||||||
|
|
||||||
const tmdbquery = { query: query, page: page, include_adult: true };
|
const tmdbquery = { query: query, page: page, include_adult: true };
|
||||||
const cacheKey = `${this.cacheTags.personSearch}:${page}:${query}`;
|
const cacheKey = `tmdb/${this.cacheTags.personSearch}:${page}:${query}`;
|
||||||
|
|
||||||
return this.cache.get(cacheKey)
|
return this.getFromCacheOrFetchFromTmdb(cacheKey, 'searchPerson', query)
|
||||||
.catch(() => this.tmdb('searchPerson', tmdbquery))
|
.then(response => this.cache.set(cacheKey, response, this.defaultTTL))
|
||||||
.catch(tmdbError => tmdbErrorResponse(tmdbError, 'person search results'))
|
|
||||||
.then(response => this.cache.set(cacheKey, response, 1))
|
|
||||||
.then(response => this.mapResults(response, 'person'))
|
.then(response => this.mapResults(response, 'person'))
|
||||||
}
|
}
|
||||||
|
|
||||||
movieList(listname, page = 1) {
|
movieList(listname, page = 1) {
|
||||||
const query = { page: page };
|
const query = { page: page };
|
||||||
const cacheKey = `${this.cacheTags[listname]}:${page}`;
|
const cacheKey = `tmdb/${this.cacheTags[listname]}:${page}`;
|
||||||
return this.cache.get(cacheKey)
|
|
||||||
.catch(() => this.tmdb(listname, query))
|
return this.getFromCacheOrFetchFromTmdb(cacheKey, listname, query)
|
||||||
.catch(tmdbError => this.tmdbErrorResponse(tmdbError, 'movie list ' + listname))
|
.then(response => this.cache.set(cacheKey, response, this.defaultTTL))
|
||||||
.then(response => this.cache.set(cacheKey, response, 1))
|
|
||||||
.then(response => this.mapResults(response, 'movie'))
|
.then(response => this.mapResults(response, 'movie'))
|
||||||
}
|
}
|
||||||
|
|
||||||
showList(listname, page = 1) {
|
showList(listname, page = 1) {
|
||||||
const query = { page: page };
|
const query = { page: page };
|
||||||
const cacheKey = `${this.cacheTags[listname]}:${page}`;
|
const cacheKey = `tmdb/${this.cacheTags[listname]}:${page}`;
|
||||||
|
|
||||||
return this.cache.get(cacheKey)
|
return this.getFromCacheOrFetchFromTmdb(cacheKey, listName, query)
|
||||||
.catch(() => this.tmdb(listname, query))
|
.then(response => this.cache.set(cacheKey, response, this.defaultTTL))
|
||||||
.catch(tmdbError => this.tmdbErrorResponse(tmdbError, 'show list ' + listname))
|
|
||||||
.then(response => this.cache.set(cacheKey, response, 1))
|
|
||||||
.then(response => this.mapResults(response, 'show'))
|
.then(response => this.mapResults(response, 'show'))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,25 +274,6 @@ class TMDB {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function tmdbErrorResponse(error, typeString=undefined) {
|
|
||||||
if (error.status === 404) {
|
|
||||||
let message = error.response.body.status_message;
|
|
||||||
|
|
||||||
throw {
|
|
||||||
status: 404,
|
|
||||||
message: message.slice(0, -1) + " in tmdb."
|
|
||||||
}
|
|
||||||
} else if (error.status === 401) {
|
|
||||||
throw {
|
|
||||||
status: 401,
|
|
||||||
message: error.response.body.status_message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw {
|
|
||||||
status: 500,
|
|
||||||
message: `An unexpected error occured while fetching ${typeString} from tmdb`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = TMDB;
|
module.exports = TMDB;
|
||||||
|
|||||||
@@ -113,6 +113,8 @@ router.get('/v1/plex/request/:mediaId', require('./controllers/plex/readRequest.
|
|||||||
router.post('/v1/plex/request/:mediaId', require('./controllers/plex/submitRequest.js'));
|
router.post('/v1/plex/request/:mediaId', require('./controllers/plex/submitRequest.js'));
|
||||||
router.post('/v1/plex/hook', require('./controllers/plex/hookDump.js'));
|
router.post('/v1/plex/hook', require('./controllers/plex/hookDump.js'));
|
||||||
|
|
||||||
|
router.get('/v1/plex/watch-link', mustBeAuthenticated, require('./controllers/plex/watchDirectLink.js'));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests
|
* Requests
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
const configuration = require('src/config/configuration').getInstance();
|
const configuration = require('src/config/configuration').getInstance();
|
||||||
const Cache = require('src/tmdb/cache');
|
|
||||||
const TMDB = require('src/tmdb/tmdb');
|
const TMDB = require('src/tmdb/tmdb');
|
||||||
const cache = new Cache();
|
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
|
||||||
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
|
|
||||||
|
|
||||||
// there should be a translate function from query params to
|
// there should be a translate function from query params to
|
||||||
// tmdb list that is valid. Should it be a helper function or does it
|
// tmdb list that is valid. Should it be a helper function or does it
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
const configuration = require('src/config/configuration').getInstance();
|
const configuration = require('src/config/configuration').getInstance();
|
||||||
const Cache = require('src/tmdb/cache');
|
|
||||||
const TMDB = require('src/tmdb/tmdb');
|
const TMDB = require('src/tmdb/tmdb');
|
||||||
|
|
||||||
const cache = new Cache();
|
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
|
||||||
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
|
|
||||||
|
|
||||||
const movieCreditsController = (req, res) => {
|
const movieCreditsController = (req, res) => {
|
||||||
const movieId = req.params.id;
|
const movieId = req.params.id;
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
const configuration = require('src/config/configuration').getInstance();
|
const configuration = require('src/config/configuration').getInstance();
|
||||||
const Cache = require('src/tmdb/cache');
|
|
||||||
const TMDB = require('src/tmdb/tmdb');
|
const TMDB = require('src/tmdb/tmdb');
|
||||||
const Plex = require('src/plex/plex');
|
const Plex = require('src/plex/plex');
|
||||||
const cache = new Cache();
|
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
|
||||||
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
|
|
||||||
const plex = new Plex(configuration.get('plex', 'ip'));
|
const plex = new Plex(configuration.get('plex', 'ip'));
|
||||||
|
|
||||||
function handleError(error, res) {
|
function handleError(error, res) {
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
const configuration = require('src/config/configuration').getInstance();
|
const configuration = require('src/config/configuration').getInstance();
|
||||||
const Cache = require('src/tmdb/cache');
|
|
||||||
const TMDB = require('src/tmdb/tmdb');
|
const TMDB = require('src/tmdb/tmdb');
|
||||||
|
|
||||||
const cache = new Cache();
|
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
|
||||||
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
|
|
||||||
|
|
||||||
const movieReleaseDatesController = (req, res) => {
|
const movieReleaseDatesController = (req, res) => {
|
||||||
const movieId = req.params.id;
|
const movieId = req.params.id;
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
const configuration = require('src/config/configuration').getInstance();
|
const configuration = require('src/config/configuration').getInstance();
|
||||||
const Cache = require('src/tmdb/cache');
|
|
||||||
const TMDB = require('src/tmdb/tmdb');
|
const TMDB = require('src/tmdb/tmdb');
|
||||||
const cache = new Cache();
|
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
|
||||||
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller: Retrieve information for a person
|
* Controller: Retrieve information for a person
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
const configuration = require('src/config/configuration').getInstance()
|
const configuration = require('src/config/configuration').getInstance()
|
||||||
const RequestRepository = require('src/request/request');
|
const RequestRepository = require('src/request/request');
|
||||||
const Cache = require('src/tmdb/cache')
|
|
||||||
const TMDB = require('src/tmdb/tmdb')
|
const TMDB = require('src/tmdb/tmdb')
|
||||||
|
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'))
|
||||||
const cache = new Cache()
|
|
||||||
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'))
|
|
||||||
const request = new RequestRepository()
|
const request = new RequestRepository()
|
||||||
|
|
||||||
const tmdbMovieInfo = (id) => {
|
const tmdbMovieInfo = (id) => {
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
const configuration = require('src/config/configuration').getInstance();
|
||||||
|
const Plex = require('src/plex/plex');
|
||||||
|
const plex = new Plex(configuration.get('plex', 'ip'));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller: Search plex for movies, shows and episodes by query
|
||||||
|
* @param {Request} req http request variable
|
||||||
|
* @param {Response} res
|
||||||
|
* @returns {Callback}
|
||||||
|
*/
|
||||||
|
|
||||||
|
function watchDirectLink (req, res) {
|
||||||
|
const { title, year } = req.query;
|
||||||
|
|
||||||
|
plex.getDirectLinkByTitleAndYear(title, year)
|
||||||
|
.then(plexDirectLink => {
|
||||||
|
if (plexDirectLink == false)
|
||||||
|
res.status(404).send({ success: true, link: null })
|
||||||
|
else
|
||||||
|
res.status(200).send({ success: true, link: plexDirectLink })
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
res.status(500).send({ success: false, message: error.message });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = watchDirectLink;
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
const configuration = require('src/config/configuration').getInstance();
|
const configuration = require('src/config/configuration').getInstance();
|
||||||
const Cache = require('src/tmdb/cache');
|
|
||||||
const TMDB = require('src/tmdb/tmdb');
|
const TMDB = require('src/tmdb/tmdb');
|
||||||
const RequestRepository = require('src/request/request');
|
const RequestRepository = require('src/request/request');
|
||||||
const cache = new Cache();
|
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
|
||||||
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
|
|
||||||
const request = new RequestRepository();
|
const request = new RequestRepository();
|
||||||
|
|
||||||
const tmdbMovieInfo = (id) => {
|
const tmdbMovieInfo = (id) => {
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
const configuration = require('src/config/configuration').getInstance();
|
const configuration = require('src/config/configuration').getInstance();
|
||||||
const Cache = require('src/tmdb/cache');
|
|
||||||
const TMDB = require('src/tmdb/tmdb');
|
const TMDB = require('src/tmdb/tmdb');
|
||||||
const SearchHistory = require('src/searchHistory/searchHistory');
|
const SearchHistory = require('src/searchHistory/searchHistory');
|
||||||
const cache = new Cache();
|
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
|
||||||
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
|
|
||||||
const searchHistory = new SearchHistory();
|
const searchHistory = new SearchHistory();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
const configuration = require('src/config/configuration').getInstance();
|
const configuration = require('src/config/configuration').getInstance();
|
||||||
const Cache = require('src/tmdb/cache');
|
|
||||||
const TMDB = require('src/tmdb/tmdb');
|
const TMDB = require('src/tmdb/tmdb');
|
||||||
const SearchHistory = require('src/searchHistory/searchHistory');
|
const SearchHistory = require('src/searchHistory/searchHistory');
|
||||||
const cache = new Cache();
|
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
|
||||||
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
|
|
||||||
const searchHistory = new SearchHistory();
|
const searchHistory = new SearchHistory();
|
||||||
|
|
||||||
function checkAndCreateJsonResponse(result) {
|
function checkAndCreateJsonResponse(result) {
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
const configuration = require('src/config/configuration').getInstance();
|
const configuration = require('src/config/configuration').getInstance();
|
||||||
const Cache = require('src/tmdb/cache');
|
|
||||||
const TMDB = require('src/tmdb/tmdb');
|
const TMDB = require('src/tmdb/tmdb');
|
||||||
const SearchHistory = require('src/searchHistory/searchHistory');
|
const SearchHistory = require('src/searchHistory/searchHistory');
|
||||||
const cache = new Cache();
|
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
|
||||||
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
|
|
||||||
const searchHistory = new SearchHistory();
|
const searchHistory = new SearchHistory();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
const SearchHistory = require('src/searchHistory/searchHistory');
|
const SearchHistory = require('src/searchHistory/searchHistory');
|
||||||
const configuration = require('src/config/configuration').getInstance();
|
const configuration = require('src/config/configuration').getInstance();
|
||||||
const Cache = require('src/tmdb/cache');
|
|
||||||
const TMDB = require('src/tmdb/tmdb');
|
const TMDB = require('src/tmdb/tmdb');
|
||||||
const cache = new Cache();
|
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
|
||||||
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
|
|
||||||
const searchHistory = new SearchHistory();
|
const searchHistory = new SearchHistory();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
const configuration = require('src/config/configuration').getInstance();
|
const configuration = require('src/config/configuration').getInstance();
|
||||||
const Cache = require('src/tmdb/cache');
|
|
||||||
const TMDB = require('src/tmdb/tmdb');
|
const TMDB = require('src/tmdb/tmdb');
|
||||||
|
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
|
||||||
const cache = new Cache();
|
|
||||||
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
|
|
||||||
|
|
||||||
const showCreditsController = (req, res) => {
|
const showCreditsController = (req, res) => {
|
||||||
const showId = req.params.id;
|
const showId = req.params.id;
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
const configuration = require('src/config/configuration').getInstance();
|
const configuration = require('src/config/configuration').getInstance();
|
||||||
const Cache = require('src/tmdb/cache');
|
|
||||||
const TMDB = require('src/tmdb/tmdb');
|
const TMDB = require('src/tmdb/tmdb');
|
||||||
const Plex = require('src/plex/plex');
|
const Plex = require('src/plex/plex');
|
||||||
const cache = new Cache();
|
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
|
||||||
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
|
|
||||||
const plex = new Plex(configuration.get('plex', 'ip'));
|
const plex = new Plex(configuration.get('plex', 'ip'));
|
||||||
|
|
||||||
function handleError(error, res) {
|
function handleError(error, res) {
|
||||||
|
|||||||
Reference in New Issue
Block a user