Fixed eslint errors & improved a lot of error handling
This commit is contained in:
19
src/cache/redis.js
vendored
19
src/cache/redis.js
vendored
@@ -3,29 +3,29 @@ const configuration = require("../config/configuration").getInstance();
|
||||
let client;
|
||||
|
||||
try {
|
||||
const redis = require("redis");
|
||||
console.log("Trying to connect with redis..");
|
||||
const redis = require("redis"); // eslint-disable-line global-require
|
||||
console.log("Trying to connect with redis.."); // eslint-disable-line no-console
|
||||
const host = configuration.get("redis", "host");
|
||||
const port = configuration.get("redis", "port");
|
||||
|
||||
console.log(`redis://${host}:${port}`);
|
||||
console.log(`redis://${host}:${port}`); // eslint-disable-line no-console
|
||||
client = redis.createClient({
|
||||
url: `redis://${host}:${port}`
|
||||
});
|
||||
|
||||
client.on("connect", () => console.log("Redis connection established!"));
|
||||
client.on("connect", () => console.log("Redis connection established!")); // eslint-disable-line no-console
|
||||
|
||||
client.on("error", () => {
|
||||
client.quit();
|
||||
console.error("Unable to connect to redis, setting up redis-mock.");
|
||||
console.error("Unable to connect to redis, setting up redis-mock."); // eslint-disable-line no-console
|
||||
|
||||
client = {
|
||||
get() {
|
||||
console.log("redis-dummy get", arguments[0]);
|
||||
get(command) {
|
||||
console.log(`redis-dummy get: ${command}`); // eslint-disable-line no-console
|
||||
return Promise.resolve();
|
||||
},
|
||||
set() {
|
||||
console.log("redis-dummy set", arguments[0]);
|
||||
set(command) {
|
||||
console.log(`redis-dummy set: ${command}`); // eslint-disable-line no-console
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
@@ -41,6 +41,7 @@ function set(key, value, TTL = 10800) {
|
||||
// successfully set value with key, now set TTL for key
|
||||
client.expire(key, TTL, e => {
|
||||
if (e)
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(
|
||||
"Unexpected error while setting expiration for key:",
|
||||
key,
|
||||
|
||||
@@ -6,6 +6,7 @@ let instance = null;
|
||||
class Config {
|
||||
constructor() {
|
||||
this.location = Config.determineLocation();
|
||||
// eslint-disable-next-line import/no-dynamic-require, global-require
|
||||
this.fields = require(`${this.location}`);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ class Field {
|
||||
}
|
||||
|
||||
static base64Decode(string) {
|
||||
return new Buffer(string, "base64").toString("utf-8");
|
||||
return Buffer.from(string, "base64").toString("utf-8");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ const sendSMS = message => {
|
||||
const apiKey = configuration.get("sms", "apikey");
|
||||
|
||||
if (!apiKey) {
|
||||
console.warning("api key for sms not set, cannot send sms.");
|
||||
return null;
|
||||
console.warning("api key for sms not set, cannot send sms."); // eslint-disable-line no-console
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
const sender = configuration.get("sms", "sender");
|
||||
@@ -32,10 +32,9 @@ const sendSMS = message => {
|
||||
recipients: [{ msisdn: `47${recipient}` }]
|
||||
}
|
||||
},
|
||||
function (err, r, body) {
|
||||
const smsError = new SMSUnexpectedError(err || body);
|
||||
console.error(smsError.message);
|
||||
resolve();
|
||||
(err, r, body) => {
|
||||
if (err) reject(new SMSUnexpectedError(err || body));
|
||||
resolve(body);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -46,8 +46,10 @@ async function callPythonAddMagnet(url, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
async function SearchPiratebay(query) {
|
||||
if (query && query.includes("+")) {
|
||||
async function SearchPiratebay(_query) {
|
||||
let query = String(_query);
|
||||
|
||||
if (query?.includes("+")) {
|
||||
query = query.replace("+", "%20");
|
||||
}
|
||||
|
||||
@@ -60,7 +62,7 @@ async function SearchPiratebay(query) {
|
||||
.catch(() =>
|
||||
find(query, (err, results) => {
|
||||
if (err) {
|
||||
console.log("THERE WAS A FUCKING ERROR!\n", err);
|
||||
console.log("THERE WAS A FUCKING ERROR!\n", err); // eslint-disable-line no-console
|
||||
reject(Error("There was a error when searching for torrents"));
|
||||
}
|
||||
|
||||
@@ -74,8 +76,8 @@ async function SearchPiratebay(query) {
|
||||
);
|
||||
}
|
||||
|
||||
async function AddMagnet(magnet, name, tmdbId) {
|
||||
return await new Promise((resolve, reject) =>
|
||||
function AddMagnet(magnet, name, tmdbId) {
|
||||
return new Promise((resolve, reject) =>
|
||||
callPythonAddMagnet(magnet, (err, results) => {
|
||||
if (err) {
|
||||
/* eslint-disable no-console */
|
||||
@@ -86,11 +88,10 @@ async function AddMagnet(magnet, name, tmdbId) {
|
||||
console.log("result/error:", err, results);
|
||||
|
||||
const database = establishedDatabase;
|
||||
const insert_query =
|
||||
"INSERT INTO requested_torrent(magnet,torrent_name,tmdb_id) \
|
||||
VALUES (?,?,?)";
|
||||
const insertQuery =
|
||||
"INSERT INTO requested_torrent(magnet,torrent_name,tmdb_id) VALUES (?,?,?)";
|
||||
|
||||
const response = database.run(insert_query, [magnet, name, tmdbId]);
|
||||
const response = database.run(insertQuery, [magnet, name, tmdbId]);
|
||||
console.log(`Response from requsted_torrent insert: ${response}`);
|
||||
|
||||
resolve({ success: true });
|
||||
|
||||
166
src/plex/plex.js
166
src/plex/plex.js
@@ -2,17 +2,28 @@ const fetch = require("node-fetch");
|
||||
const convertPlexToMovie = require("./convertPlexToMovie");
|
||||
const convertPlexToShow = require("./convertPlexToShow");
|
||||
const convertPlexToEpisode = require("./convertPlexToEpisode");
|
||||
|
||||
const redisCache = require("../cache/redis");
|
||||
|
||||
const sanitize = string => string.toLowerCase().replace(/[^\w]/gi, "");
|
||||
class PlexRequestTimeoutError extends Error {
|
||||
constructor() {
|
||||
const message = "Timeout: Plex did not respond.";
|
||||
|
||||
function fixedEncodeURIComponent(str) {
|
||||
return encodeURIComponent(str).replace(/[!'()*]/g, function (c) {
|
||||
return `%${c.charCodeAt(0).toString(16).toUpperCase()}`;
|
||||
});
|
||||
super(message);
|
||||
this.statusCode = 408;
|
||||
}
|
||||
}
|
||||
|
||||
class PlexUnexpectedError extends Error {
|
||||
constructor(plexError = null) {
|
||||
const message = "Unexpected plex error occured.";
|
||||
|
||||
super(message);
|
||||
this.statusCode = 500;
|
||||
this.plexError = plexError;
|
||||
}
|
||||
}
|
||||
|
||||
const sanitize = string => string.toLowerCase().replace(/[^\w]/gi, "");
|
||||
const matchingTitleAndYear = (plex, tmdb) => {
|
||||
let matchingTitle;
|
||||
let matchingYear;
|
||||
@@ -30,25 +41,62 @@ const matchingTitleAndYear = (plex, tmdb) => {
|
||||
return matchingTitle && matchingYear;
|
||||
};
|
||||
|
||||
function fixedEncodeURIComponent(str) {
|
||||
return encodeURIComponent(str).replace(/[!'()*]/g, c => {
|
||||
return `%${c.charCodeAt(0).toString(16).toUpperCase()}`;
|
||||
});
|
||||
}
|
||||
|
||||
function matchTmdbAndPlexMedia(plex, tmdb) {
|
||||
let match;
|
||||
|
||||
if (plex === null || tmdb === null) return false;
|
||||
|
||||
if (plex instanceof Array) {
|
||||
const possibleMatches = plex.map(plexItem =>
|
||||
matchingTitleAndYear(plexItem, tmdb)
|
||||
);
|
||||
match = possibleMatches.includes(true);
|
||||
} else {
|
||||
match = matchingTitleAndYear(plex, tmdb);
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
const successfullResponse = response => {
|
||||
if (response && response.MediaContainer) return response;
|
||||
|
||||
if (
|
||||
response === null ||
|
||||
response.status === null ||
|
||||
response.statusText === null
|
||||
) {
|
||||
throw Error("Unable to decode response");
|
||||
}
|
||||
|
||||
const { status, statusText } = response;
|
||||
|
||||
if (status === 200) {
|
||||
return response.json();
|
||||
if (status !== 200) {
|
||||
throw new PlexUnexpectedError(statusText);
|
||||
}
|
||||
throw { message: statusText, status };
|
||||
|
||||
if (response?.MediaContainer) return response;
|
||||
|
||||
return response.json();
|
||||
};
|
||||
|
||||
function mapResults(response) {
|
||||
if (response?.MediaContainer?.Hub === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return response.MediaContainer.Hub.filter(category => category.size > 0)
|
||||
.map(category => {
|
||||
if (category.type === "movie") {
|
||||
return category.Metadata.map(convertPlexToMovie);
|
||||
}
|
||||
if (category.type === "show") {
|
||||
return category.Metadata.map(convertPlexToShow);
|
||||
}
|
||||
if (category.type === "episode") {
|
||||
return category.Metadata.map(convertPlexToEpisode);
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
.filter(result => result !== null);
|
||||
}
|
||||
|
||||
class Plex {
|
||||
constructor(ip, port = 32400, cache = null) {
|
||||
this.plexIP = ip;
|
||||
@@ -72,44 +120,23 @@ class Plex {
|
||||
return new Promise((resolve, reject) =>
|
||||
this.cache
|
||||
.get(cacheKey)
|
||||
.then(machineInfo => resolve(machineInfo.machineIdentifier))
|
||||
.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))
|
||||
.then(machineInfo => resolve(machineInfo?.machineIdentifier))
|
||||
.catch(error => {
|
||||
if (error !== undefined && error.type === "request-timeout") {
|
||||
reject({
|
||||
message: "Plex did not respond",
|
||||
status: 408,
|
||||
success: false
|
||||
});
|
||||
if (error?.type === "request-timeout") {
|
||||
reject(new PlexRequestTimeoutError());
|
||||
}
|
||||
|
||||
reject(error);
|
||||
reject(new PlexUnexpectedError());
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
matchTmdbAndPlexMedia(plex, tmdb) {
|
||||
let match;
|
||||
|
||||
if (plex === null || tmdb === null) return false;
|
||||
|
||||
if (plex instanceof Array) {
|
||||
const 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,
|
||||
@@ -123,7 +150,7 @@ class Plex {
|
||||
|
||||
return this.search(title).then(plexResults => {
|
||||
const matchesInPlex = plexResults.map(plex =>
|
||||
this.matchTmdbAndPlexMedia(plex, query)
|
||||
matchTmdbAndPlexMedia(plex, query)
|
||||
);
|
||||
const matchesIndex = matchesInPlex.findIndex(el => el === true);
|
||||
return matchesInPlex !== -1 ? plexResults[matchesIndex] : null;
|
||||
@@ -171,18 +198,14 @@ class Plex {
|
||||
.catch(() => fetch(url, options)) // else fetch fresh data
|
||||
.then(successfullResponse)
|
||||
.then(results => this.cache.set(cacheKey, results, 21600)) // 6 hours
|
||||
.then(this.mapResults)
|
||||
.then(mapResults)
|
||||
.then(resolve)
|
||||
.catch(error => {
|
||||
if (error !== undefined && error.type === "request-timeout") {
|
||||
reject({
|
||||
message: "Plex did not respond",
|
||||
status: 408,
|
||||
success: false
|
||||
});
|
||||
if (error?.type === "request-timeout") {
|
||||
reject(new PlexRequestTimeoutError());
|
||||
}
|
||||
|
||||
reject(error);
|
||||
reject(new PlexUnexpectedError());
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -195,40 +218,13 @@ class Plex {
|
||||
const query = title;
|
||||
const cacheKey = `${this.cacheTags.search}/${query}*`;
|
||||
|
||||
this.cache.del(
|
||||
cacheKey,
|
||||
(error,
|
||||
response => {
|
||||
if (response === 1) return true;
|
||||
|
||||
this.cache.del(cacheKey, (error, response) => {
|
||||
// TODO improve cache key matching by lowercasing it on the backend.
|
||||
// what do we actually need to check for if the key was deleted or not
|
||||
// it might be an error or another response code.
|
||||
console.log("Unable to delete, key might not exists");
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
mapResults(response) {
|
||||
if (response?.MediaContainer?.Hub === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return response.MediaContainer.Hub.filter(category => category.size > 0)
|
||||
.map(category => {
|
||||
if (category.type === "movie") {
|
||||
return category.Metadata;
|
||||
}
|
||||
if (category.type === "show") {
|
||||
return category.Metadata.map(convertPlexToShow);
|
||||
}
|
||||
if (category.type === "episode") {
|
||||
return category.Metadata.map(convertPlexToEpisode);
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
.filter(result => result !== null);
|
||||
return response === 1;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,17 +2,54 @@ const rp = require("request-promise");
|
||||
const convertPlexToSeasoned = require("./convertPlexToSeasoned");
|
||||
const convertPlexToStream = require("./convertPlexToStream");
|
||||
|
||||
// eslint-disable-next-line
|
||||
function addAttributeIfTmdbInPlex(_tmdb, plexResult) {
|
||||
const tmdb = { ..._tmdb };
|
||||
|
||||
if (plexResult?.results?.length > 0) {
|
||||
plexResult.results.map(plexItem => {
|
||||
tmdb.matchedInPlex =
|
||||
tmdb.title === plexItem.title && tmdb.year === plexItem.year;
|
||||
return tmdb;
|
||||
});
|
||||
} else {
|
||||
tmdb.matchedInPlex = false;
|
||||
}
|
||||
|
||||
return Promise.resolve(tmdb);
|
||||
}
|
||||
|
||||
function mapResults(response) {
|
||||
return Promise.resolve()
|
||||
.then(() => {
|
||||
if (!response?.MediaContainer?.Metadata) return [[], 0];
|
||||
|
||||
const mappedResults = response.MediaContainer.Metadata.filter(element => {
|
||||
return element.type === "movie" || element.type === "show";
|
||||
}).map(element => convertPlexToSeasoned(element));
|
||||
return [mappedResults, mappedResults.length];
|
||||
})
|
||||
.catch(error => {
|
||||
throw new Error(error);
|
||||
});
|
||||
}
|
||||
|
||||
class PlexRepository {
|
||||
constructor(plexIP) {
|
||||
this.plexIP = plexIP;
|
||||
}
|
||||
|
||||
inPlex(tmdbResult) {
|
||||
return Promise.resolve()
|
||||
.then(() => this.search(tmdbResult.title))
|
||||
.then(plexResult => this.compareTmdbToPlex(tmdbResult, plexResult))
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
inPlex(_tmdbResult) {
|
||||
const tmdbResult = { ..._tmdbResult };
|
||||
this.search(tmdbResult.title)
|
||||
.then(plexResult => addAttributeIfTmdbInPlex(tmdbResult, plexResult))
|
||||
.catch(() => {
|
||||
/**
|
||||
* If something crashes with search from this function it probably
|
||||
* fine to set the `matchedInPlex` attribute to false and return
|
||||
* original tmdb object
|
||||
* */
|
||||
|
||||
tmdbResult.matchedInPlex = false;
|
||||
return tmdbResult;
|
||||
});
|
||||
@@ -32,50 +69,13 @@ class PlexRepository {
|
||||
};
|
||||
|
||||
return rp(options)
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
throw new Error("Unable to search plex.");
|
||||
})
|
||||
.then(result => this.mapResults(result))
|
||||
.then(result => mapResults(result))
|
||||
.then(([mappedResults, resultCount]) => ({
|
||||
results: mappedResults,
|
||||
total_results: resultCount
|
||||
}));
|
||||
}
|
||||
|
||||
compareTmdbToPlex(tmdb, plexResult) {
|
||||
return Promise.resolve().then(() => {
|
||||
if (plexResult.results.length === 0) {
|
||||
tmdb.matchedInPlex = false;
|
||||
} else {
|
||||
// console.log('plex and tmdb:', plexResult, '\n', tmdb)
|
||||
plexResult.results.map(plexItem => {
|
||||
if (tmdb.title === plexItem.title && tmdb.year === plexItem.year)
|
||||
tmdb.matchedInPlex = true;
|
||||
return tmdb;
|
||||
});
|
||||
}
|
||||
return tmdb;
|
||||
});
|
||||
}
|
||||
|
||||
mapResults(response) {
|
||||
return Promise.resolve()
|
||||
.then(() => {
|
||||
if (!response.MediaContainer.hasOwnProperty("Metadata")) return [[], 0];
|
||||
|
||||
const mappedResults = response.MediaContainer.Metadata.filter(
|
||||
element => {
|
||||
return element.type === "movie" || element.type === "show";
|
||||
}
|
||||
).map(element => convertPlexToSeasoned(element));
|
||||
return [mappedResults, mappedResults.length];
|
||||
})
|
||||
.catch(error => {
|
||||
throw new Error(error);
|
||||
});
|
||||
}
|
||||
|
||||
nowPlaying() {
|
||||
const options = {
|
||||
uri: `http://${this.plexIP}:32400/status/sessions`,
|
||||
|
||||
@@ -28,15 +28,15 @@ class RequestRepository {
|
||||
};
|
||||
}
|
||||
|
||||
search(query, type, page) {
|
||||
return Promise.resolve()
|
||||
.then(() => tmdb.search(query, type, page))
|
||||
static search(query, type, page) {
|
||||
return tmdb
|
||||
.search(query, type, page)
|
||||
.catch(error => Error(`error in the house${error}`));
|
||||
}
|
||||
|
||||
lookup(identifier, type = "movie") {
|
||||
return Promise.resolve()
|
||||
.then(() => tmdb.lookup(identifier, type))
|
||||
return tmdb
|
||||
.lookup(identifier, type)
|
||||
.then(tmdbMovie => this.checkID(tmdbMovie))
|
||||
.then(tmdbMovie => plexRepository.inPlex(tmdbMovie))
|
||||
.catch(error => {
|
||||
@@ -44,18 +44,16 @@ class RequestRepository {
|
||||
});
|
||||
}
|
||||
|
||||
checkID(tmdbMovie) {
|
||||
return Promise.resolve()
|
||||
.then(() =>
|
||||
this.database.get(this.queries.checkIfIdRequested, [
|
||||
tmdbMovie.id,
|
||||
tmdbMovie.type
|
||||
])
|
||||
)
|
||||
checkID(_tmdbMovie) {
|
||||
const tmdbMovie = _tmdbMovie;
|
||||
|
||||
return this.database
|
||||
.get(this.queries.checkIfIdRequested, [tmdbMovie.id, tmdbMovie.type])
|
||||
.then((result, error) => {
|
||||
if (error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
tmdbMovie.requested = !!result;
|
||||
return tmdbMovie;
|
||||
});
|
||||
@@ -67,9 +65,7 @@ class RequestRepository {
|
||||
* @returns {Promise} If nothing has gone wrong.
|
||||
*/
|
||||
sendRequest(identifier, type, ip, userAgent, user) {
|
||||
return Promise.resolve()
|
||||
.then(() => tmdb.lookup(identifier, type))
|
||||
.then(movie => {
|
||||
return tmdb.lookup(identifier, type).then(movie => {
|
||||
const username = user === undefined ? undefined : user.username;
|
||||
// Add request to database
|
||||
return this.database.run(this.queries.insertRequest, [
|
||||
@@ -87,7 +83,6 @@ class RequestRepository {
|
||||
}
|
||||
|
||||
fetchRequested(status, page = "1", type = "%") {
|
||||
return Promise.resolve().then(() => {
|
||||
if (
|
||||
status === "requested" ||
|
||||
status === "downloading" ||
|
||||
@@ -98,13 +93,13 @@ class RequestRepository {
|
||||
type,
|
||||
page
|
||||
]);
|
||||
|
||||
return this.database.all(this.queries.fetchRequestedItems, page);
|
||||
});
|
||||
}
|
||||
|
||||
userRequests(username) {
|
||||
return Promise.resolve()
|
||||
.then(() => this.database.all(this.queries.userRequests, username))
|
||||
return this.database
|
||||
.all(this.queries.userRequests, username)
|
||||
.catch(error => {
|
||||
if (String(error).includes("no such column")) {
|
||||
throw new Error("Username not found");
|
||||
@@ -113,8 +108,11 @@ class RequestRepository {
|
||||
})
|
||||
.then(result => {
|
||||
// TODO do a correct mapping before sending, not just a dump of the database
|
||||
result.map(item => (item.poster = item.poster_path));
|
||||
return result;
|
||||
return result.map(_item => {
|
||||
const item = { ..._item };
|
||||
item.poster = item.poster_path;
|
||||
return item;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
const assert = require("assert");
|
||||
const configuration = require("../config/configuration").getInstance();
|
||||
const TMDB = require("../tmdb/tmdb");
|
||||
|
||||
const tmdb = new TMDB(configuration.get("tmdb", "apiKey"));
|
||||
// const configuration = require("../config/configuration").getInstance();
|
||||
// const TMDB = require("../tmdb/tmdb");
|
||||
const establishedDatabase = require("../database/database");
|
||||
|
||||
// const tmdb = new TMDB(configuration.get("tmdb", "apiKey"));
|
||||
|
||||
// function mapToTmdbByType(rows) {
|
||||
// return rows.map(row => {
|
||||
// if (row.type === "movie") return tmdb.movieInfo(row.id);
|
||||
// if (row.type === "show") return tmdb.showInfo(row.id);
|
||||
// return null;
|
||||
// });
|
||||
// }
|
||||
|
||||
class RequestRepository {
|
||||
constructor(database) {
|
||||
this.database = database || establishedDatabase;
|
||||
@@ -30,14 +38,6 @@ class RequestRepository {
|
||||
};
|
||||
}
|
||||
|
||||
mapToTmdbByType(rows) {
|
||||
return rows.map(row => {
|
||||
if (row.type === "movie") return tmdb.movieInfo(row.id);
|
||||
if (row.type === "show") return tmdb.showInfo(row.id);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add tmdb movie|show to requests
|
||||
* @param {tmdb} tmdb class of movie|show to add
|
||||
@@ -69,7 +69,6 @@ class RequestRepository {
|
||||
) {
|
||||
throw new Error("This id is already requested", error.message);
|
||||
}
|
||||
console.log("Error @ request.addTmdb:", error);
|
||||
throw new Error("Could not add request");
|
||||
});
|
||||
}
|
||||
@@ -104,7 +103,7 @@ class RequestRepository {
|
||||
*/
|
||||
fetchAll(_page = 1, filter = null) {
|
||||
// TODO implemented sort and filter
|
||||
const page = parseInt(_page);
|
||||
const page = parseInt(_page, 10);
|
||||
let fetchQuery = this.queries.fetchAll;
|
||||
let fetchTotalResults = this.queries.totalRequests;
|
||||
let fetchParams = [page];
|
||||
@@ -143,7 +142,7 @@ class RequestRepository {
|
||||
totalRequests
|
||||
];
|
||||
|
||||
return this.mapToTmdbByType(rows);
|
||||
// return mapToTmdbByType(rows);
|
||||
})
|
||||
.then(([result, totalPages, totalRequests]) =>
|
||||
Promise.resolve({
|
||||
@@ -154,7 +153,6 @@ class RequestRepository {
|
||||
})
|
||||
)
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -10,6 +10,10 @@ class TautulliUnexpectedError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
function logTautulliError(error) {
|
||||
throw new TautulliUnexpectedError(error);
|
||||
}
|
||||
|
||||
class Tautulli {
|
||||
constructor(apiKey, ip, port) {
|
||||
this.apiKey = apiKey;
|
||||
@@ -26,11 +30,6 @@ class Tautulli {
|
||||
return url;
|
||||
}
|
||||
|
||||
/* eslint-disable-next-line class-methods-use-this */
|
||||
logTautulliError(error) {
|
||||
throw new TautulliUnexpectedError(error);
|
||||
}
|
||||
|
||||
getPlaysByDayOfWeek(plexUserId, days, yAxis) {
|
||||
const url = this.buildUrlWithCmdAndUserid(
|
||||
"get_plays_by_dayofweek",
|
||||
@@ -41,7 +40,7 @@ class Tautulli {
|
||||
|
||||
return fetch(url.href)
|
||||
.then(resp => resp.json())
|
||||
.catch(error => this.logTautulliError(error));
|
||||
.catch(error => logTautulliError(error));
|
||||
}
|
||||
|
||||
getPlaysByDays(plexUserId, days, yAxis) {
|
||||
@@ -51,7 +50,7 @@ class Tautulli {
|
||||
|
||||
return fetch(url.href)
|
||||
.then(resp => resp.json())
|
||||
.catch(error => this.logTautulliError(error));
|
||||
.catch(error => logTautulliError(error));
|
||||
}
|
||||
|
||||
watchTimeStats(plexUserId) {
|
||||
@@ -63,7 +62,7 @@ class Tautulli {
|
||||
|
||||
return fetch(url.href)
|
||||
.then(resp => resp.json())
|
||||
.catch(error => this.logTautulliError(error));
|
||||
.catch(error => logTautulliError(error));
|
||||
}
|
||||
|
||||
viewHistory(plexUserId) {
|
||||
@@ -74,7 +73,7 @@ class Tautulli {
|
||||
|
||||
return fetch(url.href)
|
||||
.then(resp => resp.json())
|
||||
.catch(error => this.logTautulliError(error));
|
||||
.catch(error => logTautulliError(error));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
186
src/tmdb/tmdb.js
186
src/tmdb/tmdb.js
@@ -20,14 +20,23 @@ class TMDBUnauthorizedError extends Error {
|
||||
}
|
||||
|
||||
class TMDBUnexpectedError extends Error {
|
||||
constructor(type) {
|
||||
constructor(type, errorMessage) {
|
||||
const message = `An unexpected error occured while fetching ${type} from tmdb`;
|
||||
super(message);
|
||||
|
||||
this.errorMessage = errorMessage;
|
||||
this.statusCode = 500;
|
||||
}
|
||||
}
|
||||
|
||||
class TMDBNotReachableError extends Error {
|
||||
constructor(
|
||||
message = "TMDB api not reachable, check your internet connection"
|
||||
) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
const tmdbErrorResponse = (error, type = null) => {
|
||||
if (error.status === 404) {
|
||||
const message = error.response.body.status_message;
|
||||
@@ -35,11 +44,45 @@ const tmdbErrorResponse = (error, type = null) => {
|
||||
throw new TMDBNotFoundError(`${message.slice(0, -1)} in tmdb.`);
|
||||
} else if (error.status === 401) {
|
||||
throw new TMDBUnauthorizedError(error?.response?.body?.status_message);
|
||||
} else if (error?.code === "ENOTFOUND") {
|
||||
throw new TMDBNotReachableError();
|
||||
}
|
||||
|
||||
throw new TMDBUnexpectedError(type);
|
||||
throw new TMDBUnexpectedError(type, error);
|
||||
};
|
||||
|
||||
/**
|
||||
* Maps our response from tmdb api to a movie/show object.
|
||||
* @param {String} response from tmdb.
|
||||
* @param {String} The type declared in listSearch.
|
||||
* @returns {Promise} dict with tmdb results, mapped as movie/show objects.
|
||||
*/
|
||||
function mapResults(response, type = null) {
|
||||
const results = response?.results?.map(result => {
|
||||
if (type === "movie" || result.media_type === "movie") {
|
||||
const movie = Movie.convertFromTmdbResponse(result);
|
||||
return movie.createJsonResponse();
|
||||
}
|
||||
if (type === "show" || result.media_type === "tv") {
|
||||
const show = Show.convertFromTmdbResponse(result);
|
||||
return show.createJsonResponse();
|
||||
}
|
||||
if (type === "person" || result.media_type === "person") {
|
||||
const person = Person.convertFromTmdbResponse(result);
|
||||
return person.createJsonResponse();
|
||||
}
|
||||
|
||||
return {};
|
||||
});
|
||||
|
||||
return {
|
||||
results,
|
||||
page: response?.page,
|
||||
total_results: response?.total_results,
|
||||
total_pages: response?.total_pages
|
||||
};
|
||||
}
|
||||
|
||||
class TMDB {
|
||||
constructor(apiKey, cache, tmdbLibrary) {
|
||||
this.tmdbLibrary = tmdbLibrary || moviedb(apiKey);
|
||||
@@ -69,15 +112,17 @@ class TMDB {
|
||||
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)))
|
||||
);
|
||||
async getFromCacheOrFetchFromTmdb(cacheKey, tmdbMethod, query) {
|
||||
try {
|
||||
const result = await this.cache.get(cacheKey);
|
||||
if (!result) throw new Error();
|
||||
|
||||
return result;
|
||||
} catch {
|
||||
return this.tmdb(tmdbMethod, query)
|
||||
.then(result => this.cache.set(cacheKey, result, this.defaultTTL))
|
||||
.catch(error => tmdbErrorResponse(error, tmdbMethod));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,9 +136,9 @@ class TMDB {
|
||||
const query = { id: identifier };
|
||||
const cacheKey = `tmdb/${this.cacheTags.movieInfo}:${identifier}`;
|
||||
|
||||
return this.getFromCacheOrFetchFromTmdb(cacheKey, "movieInfo", query)
|
||||
.then(movie => this.cache.set(cacheKey, movie, this.defaultTTL))
|
||||
.then(movie => Movie.convertFromTmdbResponse(movie));
|
||||
return this.getFromCacheOrFetchFromTmdb(cacheKey, "movieInfo", query).then(
|
||||
movie => Movie.convertFromTmdbResponse(movie)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,9 +150,11 @@ class TMDB {
|
||||
const query = { id: identifier };
|
||||
const cacheKey = `tmdb/${this.cacheTags.movieCredits}:${identifier}`;
|
||||
|
||||
return this.getFromCacheOrFetchFromTmdb(cacheKey, "movieCredits", query)
|
||||
.then(credits => this.cache.set(cacheKey, credits, this.defaultTTL))
|
||||
.then(credits => Credits.convertFromTmdbResponse(credits));
|
||||
return this.getFromCacheOrFetchFromTmdb(
|
||||
cacheKey,
|
||||
"movieCredits",
|
||||
query
|
||||
).then(credits => Credits.convertFromTmdbResponse(credits));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,11 +170,7 @@ class TMDB {
|
||||
cacheKey,
|
||||
"movieReleaseDates",
|
||||
query
|
||||
)
|
||||
.then(releaseDates =>
|
||||
this.cache.set(cacheKey, releaseDates, this.defaultTTL)
|
||||
)
|
||||
.then(releaseDates => ReleaseDates.convertFromTmdbResponse(releaseDates));
|
||||
).then(releaseDates => ReleaseDates.convertFromTmdbResponse(releaseDates));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,18 +183,18 @@ class TMDB {
|
||||
const query = { id: identifier };
|
||||
const cacheKey = `tmdb/${this.cacheTags.showInfo}:${identifier}`;
|
||||
|
||||
return this.getFromCacheOrFetchFromTmdb(cacheKey, "tvInfo", query)
|
||||
.then(show => this.cache.set(cacheKey, show, this.defaultTTL))
|
||||
.then(show => Show.convertFromTmdbResponse(show));
|
||||
return this.getFromCacheOrFetchFromTmdb(cacheKey, "tvInfo", query).then(
|
||||
show => Show.convertFromTmdbResponse(show)
|
||||
);
|
||||
}
|
||||
|
||||
showCredits(identifier) {
|
||||
const query = { id: identifier };
|
||||
const cacheKey = `tmdb/${this.cacheTags.showCredits}:${identifier}`;
|
||||
|
||||
return this.getFromCacheOrFetchFromTmdb(cacheKey, "tvCredits", query)
|
||||
.then(credits => this.cache.set(cacheKey, credits, this.defaultTTL))
|
||||
.then(credits => Credits.convertFromTmdbResponse(credits));
|
||||
return this.getFromCacheOrFetchFromTmdb(cacheKey, "tvCredits", query).then(
|
||||
credits => Credits.convertFromTmdbResponse(credits)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,9 +207,9 @@ class TMDB {
|
||||
const query = { id: identifier };
|
||||
const cacheKey = `tmdb/${this.cacheTags.personInfo}:${identifier}`;
|
||||
|
||||
return this.getFromCacheOrFetchFromTmdb(cacheKey, "personInfo", query)
|
||||
.then(person => this.cache.set(cacheKey, person, this.defaultTTL))
|
||||
.then(person => Person.convertFromTmdbResponse(person));
|
||||
return this.getFromCacheOrFetchFromTmdb(cacheKey, "personInfo", query).then(
|
||||
person => Person.convertFromTmdbResponse(person)
|
||||
);
|
||||
}
|
||||
|
||||
personCredits(identifier) {
|
||||
@@ -177,18 +220,18 @@ class TMDB {
|
||||
cacheKey,
|
||||
"personCombinedCredits",
|
||||
query
|
||||
)
|
||||
.then(credits => this.cache.set(cacheKey, credits, this.defaultTTL))
|
||||
.then(credits => Credits.convertFromTmdbResponse(credits));
|
||||
).then(credits => Credits.convertFromTmdbResponse(credits));
|
||||
}
|
||||
|
||||
multiSearch(searchQuery, page = 1, includeAdult = true) {
|
||||
const query = { query: searchQuery, page, include_adult: includeAdult };
|
||||
const cacheKey = `tmdb/${this.cacheTags.multiSearch}:${page}:${searchQuery}:${includeAdult}`;
|
||||
|
||||
return this.getFromCacheOrFetchFromTmdb(cacheKey, "searchMulti", query)
|
||||
.then(response => this.cache.set(cacheKey, response, this.defaultTTL))
|
||||
.then(response => this.mapResults(response));
|
||||
return this.getFromCacheOrFetchFromTmdb(
|
||||
cacheKey,
|
||||
"searchMulti",
|
||||
query
|
||||
).then(response => mapResults(response));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,9 +248,11 @@ class TMDB {
|
||||
};
|
||||
const cacheKey = `tmdb/${this.cacheTags.movieSearch}:${page}:${searchQuery}:${includeAdult}`;
|
||||
|
||||
return this.getFromCacheOrFetchFromTmdb(cacheKey, "searchMovie", tmdbquery)
|
||||
.then(response => this.cache.set(cacheKey, response, this.defaultTTL))
|
||||
.then(response => this.mapResults(response, "movie"));
|
||||
return this.getFromCacheOrFetchFromTmdb(
|
||||
cacheKey,
|
||||
"searchMovie",
|
||||
tmdbquery
|
||||
).then(response => mapResults(response, "movie"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -224,9 +269,11 @@ class TMDB {
|
||||
};
|
||||
const cacheKey = `tmdb/${this.cacheTags.showSearch}:${page}:${searchQuery}:${includeAdult}`;
|
||||
|
||||
return this.getFromCacheOrFetchFromTmdb(cacheKey, "searchTv", tmdbquery)
|
||||
.then(response => this.cache.set(cacheKey, response, this.defaultTTL))
|
||||
.then(response => this.mapResults(response, "show"));
|
||||
return this.getFromCacheOrFetchFromTmdb(
|
||||
cacheKey,
|
||||
"searchTv",
|
||||
tmdbquery
|
||||
).then(response => mapResults(response, "show"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -243,60 +290,29 @@ class TMDB {
|
||||
};
|
||||
const cacheKey = `tmdb/${this.cacheTags.personSearch}:${page}:${searchQuery}:${includeAdult}`;
|
||||
|
||||
return this.getFromCacheOrFetchFromTmdb(cacheKey, "searchPerson", tmdbquery)
|
||||
.then(response => this.cache.set(cacheKey, response, this.defaultTTL))
|
||||
.then(response => this.mapResults(response, "person"));
|
||||
return this.getFromCacheOrFetchFromTmdb(
|
||||
cacheKey,
|
||||
"searchPerson",
|
||||
tmdbquery
|
||||
).then(response => mapResults(response, "person"));
|
||||
}
|
||||
|
||||
movieList(listName, page = 1) {
|
||||
const query = { page };
|
||||
const cacheKey = `tmdb/${this.cacheTags[listName]}:${page}`;
|
||||
|
||||
return this.getFromCacheOrFetchFromTmdb(cacheKey, listName, query)
|
||||
.then(response => this.cache.set(cacheKey, response, this.defaultTTL))
|
||||
.then(response => this.mapResults(response, "movie"));
|
||||
return this.getFromCacheOrFetchFromTmdb(cacheKey, listName, query).then(
|
||||
response => mapResults(response, "movie")
|
||||
);
|
||||
}
|
||||
|
||||
showList(listName, page = 1) {
|
||||
const query = { page };
|
||||
const cacheKey = `tmdb/${this.cacheTags[listName]}:${page}`;
|
||||
|
||||
return this.getFromCacheOrFetchFromTmdb(cacheKey, listName, query)
|
||||
.then(response => this.cache.set(cacheKey, response, this.defaultTTL))
|
||||
.then(response => this.mapResults(response, "show"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps our response from tmdb api to a movie/show object.
|
||||
* @param {String} response from tmdb.
|
||||
* @param {String} The type declared in listSearch.
|
||||
* @returns {Promise} dict with tmdb results, mapped as movie/show objects.
|
||||
*/
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
mapResults(response, type = undefined) {
|
||||
const results = response?.results?.map(result => {
|
||||
if (type === "movie" || result.media_type === "movie") {
|
||||
const movie = Movie.convertFromTmdbResponse(result);
|
||||
return movie.createJsonResponse();
|
||||
}
|
||||
if (type === "show" || result.media_type === "tv") {
|
||||
const show = Show.convertFromTmdbResponse(result);
|
||||
return show.createJsonResponse();
|
||||
}
|
||||
if (type === "person" || result.media_type === "person") {
|
||||
const person = Person.convertFromTmdbResponse(result);
|
||||
return person.createJsonResponse();
|
||||
}
|
||||
|
||||
return {};
|
||||
});
|
||||
|
||||
return {
|
||||
results,
|
||||
page: response.page,
|
||||
total_results: response.total_results,
|
||||
total_pages: response.total_pages
|
||||
};
|
||||
return this.getFromCacheOrFetchFromTmdb(cacheKey, listName, query).then(
|
||||
response => mapResults(response, "show")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,69 @@
|
||||
const assert = require("assert");
|
||||
const establishedDatabase = require("../database/database");
|
||||
|
||||
class LinkPlexUserError extends Error {
|
||||
constructor(errorMessage = null) {
|
||||
const message =
|
||||
"An unexpected error occured while linking plex and seasoned accounts";
|
||||
super(message);
|
||||
|
||||
this.statusCode = 500;
|
||||
this.errorMessage = errorMessage;
|
||||
this.source = "database";
|
||||
}
|
||||
}
|
||||
|
||||
class UnlinkPlexUserError extends Error {
|
||||
constructor(errorMessage = null) {
|
||||
const message =
|
||||
"An unexpected error occured while unlinking plex and seasoned accounts";
|
||||
super(message);
|
||||
|
||||
this.statusCode = 500;
|
||||
this.errorMessage = errorMessage;
|
||||
this.source = "database";
|
||||
}
|
||||
}
|
||||
|
||||
class UnexpectedUserSettingsError extends Error {
|
||||
constructor(errorMessage = null) {
|
||||
const message =
|
||||
"An unexpected error occured while fetching settings for your account";
|
||||
super(message);
|
||||
|
||||
this.statusCode = 500;
|
||||
this.errorMessage = errorMessage;
|
||||
this.source = "database";
|
||||
}
|
||||
}
|
||||
|
||||
class NoSettingsUserNotFoundError extends Error {
|
||||
constructor() {
|
||||
const message = "User not found, no settings to get";
|
||||
super(message);
|
||||
|
||||
this.statusCode = 404;
|
||||
}
|
||||
}
|
||||
|
||||
const rejectUnexpectedDatabaseError = (
|
||||
message,
|
||||
status,
|
||||
error,
|
||||
reject = null
|
||||
) => {
|
||||
const body = {
|
||||
status,
|
||||
message,
|
||||
source: "seasoned database"
|
||||
};
|
||||
|
||||
if (reject == null) {
|
||||
return new Promise((_, reject) => reject(body));
|
||||
}
|
||||
return reject(body);
|
||||
};
|
||||
|
||||
class UserRepository {
|
||||
constructor(database) {
|
||||
this.database = database || establishedDatabase;
|
||||
@@ -77,14 +140,7 @@ class UserRepository {
|
||||
this.database
|
||||
.run(this.queries.link, [plexUserID, username])
|
||||
.then(row => resolve(row))
|
||||
.catch(error =>
|
||||
reject({
|
||||
status: 500,
|
||||
message:
|
||||
"An unexpected error occured while linking plex and seasoned accounts",
|
||||
source: "seasoned database"
|
||||
})
|
||||
);
|
||||
.catch(error => reject(new LinkPlexUserError(error)));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -98,14 +154,7 @@ class UserRepository {
|
||||
this.database
|
||||
.run(this.queries.unlink, username)
|
||||
.then(row => resolve(row))
|
||||
.catch(error =>
|
||||
reject({
|
||||
status: 500,
|
||||
message:
|
||||
"An unexpected error occured while unlinking plex and seasoned accounts",
|
||||
source: "seasoned database"
|
||||
})
|
||||
);
|
||||
.catch(error => reject(new UnlinkPlexUserError(error)));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -131,6 +180,7 @@ class UserRepository {
|
||||
.get(this.queries.getSettings, username)
|
||||
.then(async row => {
|
||||
if (row == null) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.debug(
|
||||
`settings do not exist for user: ${username}. Creating settings entry.`
|
||||
);
|
||||
@@ -146,23 +196,13 @@ class UserRepository {
|
||||
reject(error);
|
||||
}
|
||||
} else {
|
||||
reject({
|
||||
status: 404,
|
||||
message: "User not found, no settings to get"
|
||||
});
|
||||
reject(new NoSettingsUserNotFoundError());
|
||||
}
|
||||
}
|
||||
|
||||
resolve(row);
|
||||
})
|
||||
.catch(() =>
|
||||
reject({
|
||||
status: 500,
|
||||
message:
|
||||
"An unexpected error occured while fetching settings for your account",
|
||||
source: "seasoned database"
|
||||
})
|
||||
);
|
||||
.catch(error => reject(new UnexpectedUserSettingsError(error)));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -173,10 +213,10 @@ class UserRepository {
|
||||
* @param {String} emoji
|
||||
* @returns {Promsie}
|
||||
*/
|
||||
updateSettings(username, darkMode = null, emoji = null) {
|
||||
updateSettings(username, _darkMode = null, _emoji = null) {
|
||||
const settings = this.getSettings(username);
|
||||
darkMode = darkMode ? darkMode : settings.darkMode;
|
||||
emoji = emoji ? emoji : settings.emoji;
|
||||
const darkMode = _darkMode || settings.darkMode;
|
||||
const emoji = _emoji || settings.emoji;
|
||||
|
||||
return this.dbUpdateSettings(username, darkMode, emoji).catch(error => {
|
||||
if (error.status && error.message) {
|
||||
@@ -223,22 +263,4 @@ class UserRepository {
|
||||
}
|
||||
}
|
||||
|
||||
const rejectUnexpectedDatabaseError = (
|
||||
message,
|
||||
status,
|
||||
error,
|
||||
reject = null
|
||||
) => {
|
||||
const body = {
|
||||
status,
|
||||
message,
|
||||
source: "seasoned database"
|
||||
};
|
||||
|
||||
if (reject == null) {
|
||||
return new Promise((_, reject) => reject(body));
|
||||
}
|
||||
reject(body);
|
||||
};
|
||||
|
||||
module.exports = UserRepository;
|
||||
|
||||
@@ -56,11 +56,11 @@ router.get("/", (req, res) => {
|
||||
res.send("welcome to seasoned api");
|
||||
});
|
||||
|
||||
app.use(Raven.errorHandler());
|
||||
app.use((err, req, res) => {
|
||||
res.statusCode = 500;
|
||||
res.end(`${res.sentry}\n`);
|
||||
});
|
||||
// app.use(Raven.errorHandler());
|
||||
// app.use((err, req, res) => {
|
||||
// res.statusCode = 500;
|
||||
// res.end(`${res.sentry}\n`);
|
||||
// });
|
||||
|
||||
/**
|
||||
* User
|
||||
|
||||
@@ -15,16 +15,13 @@ const tmdb = new TMDB(configuration.get("tmdb", "apiKey"));
|
||||
// + newly created (tv/latest).
|
||||
// + movie/latest
|
||||
//
|
||||
function handleError(error, res) {
|
||||
const { status, message } = error;
|
||||
|
||||
if (status && message) {
|
||||
res.status(status).send({ success: false, message });
|
||||
} else {
|
||||
res
|
||||
.status(500)
|
||||
.send({ message: "An unexpected error occured while requesting list" });
|
||||
}
|
||||
function handleError(listname, error, res) {
|
||||
return res.status(error?.statusCode || 500).send({
|
||||
success: false,
|
||||
message:
|
||||
error?.message ||
|
||||
`An unexpected error occured while requesting list with id: ${listname}`
|
||||
});
|
||||
}
|
||||
|
||||
function fetchTmdbList(req, res, listname, type) {
|
||||
@@ -34,16 +31,17 @@ function fetchTmdbList(req, res, listname, type) {
|
||||
return tmdb
|
||||
.movieList(listname, page)
|
||||
.then(listResponse => res.send(listResponse))
|
||||
.catch(error => handleError(error, res));
|
||||
.catch(error => handleError(listname, error, res));
|
||||
}
|
||||
if (type === "show") {
|
||||
return tmdb
|
||||
.showList(listname, page)
|
||||
.then(listResponse => res.send(listResponse))
|
||||
.catch(error => handleError(error, res));
|
||||
.catch(error => handleError(listname, error, res));
|
||||
}
|
||||
|
||||
return handleError(
|
||||
listname,
|
||||
{
|
||||
status: 400,
|
||||
message: `'${type}' is not a valid list type.`
|
||||
|
||||
@@ -10,15 +10,12 @@ const movieCreditsController = (req, res) => {
|
||||
.movieCredits(movieId)
|
||||
.then(credits => res.send(credits.createJsonResponse()))
|
||||
.catch(error => {
|
||||
const { status, message } = error;
|
||||
|
||||
if (status && message) {
|
||||
res.status(status).send({ success: false, message });
|
||||
} else {
|
||||
res.status(500).send({
|
||||
message: "An unexpected error occured while requesting movie credits"
|
||||
return res.status(error?.statusCode || 500).send({
|
||||
success: false,
|
||||
message:
|
||||
error?.message ||
|
||||
`An unexpected error occured while requesting credits for movie with id: ${movieId}`
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -5,20 +5,6 @@ const Plex = require("../../../plex/plex");
|
||||
const tmdb = new TMDB(configuration.get("tmdb", "apiKey"));
|
||||
const plex = new Plex(configuration.get("plex", "ip"));
|
||||
|
||||
function handleError(error, res) {
|
||||
const { status, message } = error;
|
||||
|
||||
if (status && message) {
|
||||
res.status(status).send({ success: false, message });
|
||||
} else {
|
||||
res.status(500).send({
|
||||
success: false,
|
||||
message: "An unexpected error occured while requesting movie info",
|
||||
errorResponse: error?.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Controller: Retrieve information for a movie
|
||||
* @param {Request} req http request variable
|
||||
@@ -32,9 +18,9 @@ async function movieInfoController(req, res) {
|
||||
let releaseDates = req.query?.release_dates;
|
||||
let checkExistance = req.query?.check_existance;
|
||||
|
||||
credits = credits.toLowerCase() === "true";
|
||||
releaseDates = releaseDates.toLowerCase() === "true";
|
||||
checkExistance = checkExistance.toLowerCase() === "true";
|
||||
credits = credits?.toLowerCase() === "true";
|
||||
releaseDates = releaseDates?.toLowerCase() === "true";
|
||||
checkExistance = checkExistance?.toLowerCase() === "true";
|
||||
|
||||
const tmdbQueue = [tmdb.movieInfo(movieId)];
|
||||
if (credits) tmdbQueue.push(tmdb.movieCredits(movieId));
|
||||
@@ -54,9 +40,14 @@ async function movieInfoController(req, res) {
|
||||
} catch {}
|
||||
}
|
||||
|
||||
res.send(movie);
|
||||
return res.send(movie);
|
||||
} catch (error) {
|
||||
handleError(error, res);
|
||||
return res.status(error?.statusCode || 500).send({
|
||||
success: false,
|
||||
message:
|
||||
error?.message ||
|
||||
`An unexpected error occured while requesting info for with id: ${movieId}`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,15 +10,12 @@ const movieReleaseDatesController = (req, res) => {
|
||||
.movieReleaseDates(movieId)
|
||||
.then(releaseDates => res.send(releaseDates.createJsonResponse()))
|
||||
.catch(error => {
|
||||
const { status, message } = error;
|
||||
|
||||
if (status && message) {
|
||||
res.status(status).send({ success: false, message });
|
||||
} else {
|
||||
res.status(500).send({
|
||||
message: "An unexpected error occured while requesting movie credits"
|
||||
return res.status(error?.statusCode || 500).send({
|
||||
success: false,
|
||||
message:
|
||||
error?.message ||
|
||||
`An unexpected error occured while requesting release dates for movie with id: ${movieId}`
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -10,15 +10,12 @@ const personCreditsController = (req, res) => {
|
||||
.personCredits(personId)
|
||||
.then(credits => res.send(credits))
|
||||
.catch(error => {
|
||||
const { status, message } = error;
|
||||
|
||||
if (status && message) {
|
||||
res.status(status).send({ success: false, message });
|
||||
} else {
|
||||
res.status(500).send({
|
||||
message: "An unexpected error occured while requesting person credits"
|
||||
return res.status(error?.statusCode || 500).send({
|
||||
success: false,
|
||||
message:
|
||||
error?.message ||
|
||||
`An unexpected error occured while requesting info for person with id ${personId}.`
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -3,18 +3,6 @@ const TMDB = require("../../../tmdb/tmdb");
|
||||
|
||||
const tmdb = new TMDB(configuration.get("tmdb", "apiKey"));
|
||||
|
||||
function handleError(error, res) {
|
||||
const { status, message } = error;
|
||||
|
||||
if (status && message) {
|
||||
res.status(status).send({ success: false, message });
|
||||
} else {
|
||||
res.status(500).send({
|
||||
message: "An unexpected error occured while requesting person info."
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Controller: Retrieve information for a person
|
||||
* @param {Request} req http request variable
|
||||
@@ -26,7 +14,7 @@ async function personInfoController(req, res) {
|
||||
const personId = req.params.id;
|
||||
let { credits } = req.query;
|
||||
|
||||
credits = credits.toLowerCase() === "true";
|
||||
credits = credits?.toLowerCase() === "true";
|
||||
|
||||
const tmdbQueue = [tmdb.personInfo(personId)];
|
||||
if (credits) tmdbQueue.push(tmdb.personCredits(personId));
|
||||
@@ -39,7 +27,12 @@ async function personInfoController(req, res) {
|
||||
|
||||
return res.send(person);
|
||||
} catch (error) {
|
||||
return handleError(error, res);
|
||||
return res.status(error?.statusCode || 500).send({
|
||||
success: false,
|
||||
message:
|
||||
error?.message ||
|
||||
`An unexpected error occured while requesting info for person with id: ${personId}`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,12 @@ function fetchAllRequests(req, res) {
|
||||
.fetchAll(page, filter)
|
||||
.then(result => res.send(result))
|
||||
.catch(error => {
|
||||
res.status(404).send({ success: false, message: error.message });
|
||||
return res.status(error?.statusCode || 500).send({
|
||||
success: false,
|
||||
message:
|
||||
error?.message ||
|
||||
`An unexpected error occured while requesting all requests`
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,12 @@ function fetchAllRequests(req, res) {
|
||||
.getRequestByIdAndType(id, type)
|
||||
.then(result => res.send(result))
|
||||
.catch(error => {
|
||||
res.status(404).send({ success: false, message: error.message });
|
||||
return res.status(error?.statusCode || 500).send({
|
||||
success: false,
|
||||
message:
|
||||
error?.message ||
|
||||
`An unexpected error occured while requesting request with id: ${id}`
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -24,15 +24,12 @@ function movieSearchController(req, res) {
|
||||
.movieSearch(query, page, includeAdult)
|
||||
.then(movieSearchResults => res.send(movieSearchResults))
|
||||
.catch(error => {
|
||||
const { status, message } = error;
|
||||
|
||||
if (status && message) {
|
||||
res.status(status).send({ success: false, message });
|
||||
} else {
|
||||
res.status(500).send({
|
||||
message: `An unexpected error occured while searching movies with query: ${query}`
|
||||
return res.status(error?.statusCode || 500).send({
|
||||
success: false,
|
||||
message:
|
||||
error?.message ||
|
||||
`An unexpected error occured while searching movies with query: ${query}`
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -24,15 +24,12 @@ function multiSearchController(req, res) {
|
||||
.multiSearch(query, page, includeAdult)
|
||||
.then(multiSearchResults => res.send(multiSearchResults))
|
||||
.catch(error => {
|
||||
const { status, message } = error;
|
||||
|
||||
if (status && message) {
|
||||
res.status(status).send({ success: false, message });
|
||||
} else {
|
||||
res.status(500).send({
|
||||
message: `An unexpected error occured while searching with query: ${query}`
|
||||
return res.status(error?.statusCode || 500).send({
|
||||
success: false,
|
||||
message:
|
||||
error?.message ||
|
||||
`An unexpected error occured while searching with query: ${query}`
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -24,15 +24,12 @@ function personSearchController(req, res) {
|
||||
.personSearch(query, page, includeAdult)
|
||||
.then(persons => res.send(persons))
|
||||
.catch(error => {
|
||||
const { status, message } = error;
|
||||
|
||||
if (status && message) {
|
||||
res.status(status).send({ success: false, message });
|
||||
} else {
|
||||
res.status(500).send({
|
||||
message: `An unexpected error occured while searching people with query: ${query}`
|
||||
return res.status(error?.statusCode || 500).send({
|
||||
success: false,
|
||||
message:
|
||||
error?.message ||
|
||||
`An unexpected error occured while searching person with query: ${query}`
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,12 @@ function showSearchController(req, res) {
|
||||
res.send(shows);
|
||||
})
|
||||
.catch(error => {
|
||||
res.status(500).send({ success: false, message: error.message });
|
||||
res.status(error?.statusCode || 500).send({
|
||||
success: false,
|
||||
message:
|
||||
error?.message ||
|
||||
`An unexpected error occured while searching person with query: ${query}`
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -10,15 +10,12 @@ const showCreditsController = (req, res) => {
|
||||
.showCredits(showId)
|
||||
.then(credits => res.send(credits.createJsonResponse()))
|
||||
.catch(error => {
|
||||
const { status, message } = error;
|
||||
|
||||
if (status && message) {
|
||||
res.status(status).send({ success: false, message });
|
||||
} else {
|
||||
res.status(500).send({
|
||||
message: "An unexpected error occured while requesting show credits"
|
||||
return res.status(error?.statusCode || 500).send({
|
||||
success: false,
|
||||
message:
|
||||
error?.message ||
|
||||
`An unexpected error occured while requesting credits for show with id: ${showId}.`
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -5,18 +5,6 @@ const Plex = require("../../../plex/plex");
|
||||
const tmdb = new TMDB(configuration.get("tmdb", "apiKey"));
|
||||
const plex = new Plex(configuration.get("plex", "ip"));
|
||||
|
||||
function handleError(error, res) {
|
||||
const { status, message } = error;
|
||||
|
||||
if (status && message) {
|
||||
res.status(status).send({ success: false, message });
|
||||
} else {
|
||||
res.status(500).send({
|
||||
message: "An unexpected error occured while requesting show info."
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Controller: Retrieve information for a show
|
||||
* @param {Request} req http request variable
|
||||
@@ -48,9 +36,14 @@ async function showInfoController(req, res) {
|
||||
} catch {}
|
||||
}
|
||||
|
||||
res.send(show);
|
||||
return res.send(show);
|
||||
} catch (error) {
|
||||
handleError(error, res);
|
||||
return res.status(error?.statusCode || 500).send({
|
||||
success: false,
|
||||
message:
|
||||
error?.message ||
|
||||
`An unexpected error occured while requesting info for show with id: ${showId}`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user