trakt.tv-images
Version:
Plugin to get images, extends trakt.tv module
465 lines (424 loc) • 15 kB
JavaScript
var Images = module.exports = {}; // Skeleton
var Trakt; // the main API for trakt (npm: 'trakt.tv')
var got = require('got');
var Omdb = require('omdbapi');
var fanart = require('fanart.tv');
var Fanart = false;
var TmdbApiKey = false;
var TvdbApiKey = false;
var Small = false;
var Cached = false;
// Initialize the module
Images.init = function (trakt, opts) {
Trakt = trakt;
if (opts.smallerImages)
Small = true;
if (opts.fanartApiKey)
Fanart = new fanart(opts.fanartApiKey);
if (opts.tmdbApiKey)
TmdbApiKey = opts.tmdbApiKey;
if (opts.tvdbApiKey) {
got('https://api.thetvdb.com/login', {
json: true,
headers: {
'content-type': 'application/json'
},
method: 'POST',
body: {
apikey: opts.tvdbApiKey
}
})
.then(function (res) {
if (res.body && res.body.token) {
TvdbApiKey = res.body.token;
}
})
.catch(function (err) {});
};
if(opts.cached)
Cached = true;
};
var reduce = function (link) {
if (!link) {
return null;
}
if (link.match('assets.fanart.tv')) {
link = link.replace('fanart.tv/fanart', 'fanart.tv/preview');
} else if (link.match('image.tmdb.org')) {
link = link
.replace('w780', 'w342')
.replace('/original/', '/w1280/');
} else if (link.match('tvdb.com')) {
link = link.replace('banners/', 'banners/_cache/');
}
return link;
};
var format = function (res) {
var background = {
priority: 0,
url: null
};
var poster = {
priority: 0,
url: null
};
var profile = {
url: null
};
var map = {
fanart: 3,
omdb: 1,
tvdb: 2,
tmdb: 2
};
for (var i in res) {
var source = res[i].source;
var img = res[i].img;
var priority = map[source];
if (img && img.background && priority > background.priority) {
background.priority = priority;
background.url = img.background;
}
if (img && img.poster && priority > poster.priority) {
poster.priority = priority;
poster.url = img.poster;
}
if (img && img.profile) {
profile.url = img.profile;
}
}
if (Small) {
background.url = reduce(background.url);
poster.url = reduce(poster.url);
profile.url = reduce(profile.url);
}
return {background: background.url, poster: poster.url, profile: profile.url};
};
var getFanart = function (id, type) {
return new Promise(function (resolve) {
if (!Fanart || !id || !type) {
return resolve({source: 'fanart', img: null});
}
var fanartCat = type === 'movie'
? 'movies'
: 'shows';
return Fanart[fanartCat]
.get(id)
.then(function (images) {
// build output
var obj = null;
var poster,
background;
if (fanartCat === 'movies') {
poster = images.movieposter
? images.movieposter[0].url
: null;
background = images.moviebackground
? images.moviebackground[0].url
: images.hdmovieclearart
? images.hdmovieclearart[0].url
: images.moviethumb
? images.moviethumb[0].url
: null;
} else {
poster = images.tvposter
? images.tvposter[0].url
: null;
background = images.showbackground
? images.showbackground[0].url
: images.hdclearart
? images.hdclearart[0].url
: images.clearart
? images.clearart[0].url
: images.tvthumb
? images.tvthumb[0].url
: null;
}
if (poster || background) {
obj = {
poster: poster,
background: background
};
}
return resolve({source: 'fanart', img: obj});
})
.catch(function (err) {
return resolve({source: 'fanart', img: null});
});
});
};
var getOmdb = function (id, type) {
return new Promise(function (resolve) {
if (!id || !type) {
return resolve({source: 'omdb', img: null});
}
var omdbCat = type === 'movie'
? 'movie'
: type === 'show'
? 'series'
: 'episode';
return Omdb
.get({id: id, type: omdbCat})
.then(function (images) {
// build output
var obj = null;
if (images.poster) {
obj = {
poster: images.poster,
background: null
};
}
// return
return resolve({source: 'omdb', img: obj});
})
.catch(function (err) {
resolve({source: 'omdb', img: null});
});
});
};
var getTmdb = function (id, type) {
return new Promise(function (resolve) {
if (!TmdbApiKey || !id) {
return resolve({source: 'tmdb', img: null});
}
if (!type) {
type = 'movie';
}
// ditry tmdb v3 calls, because all 3rd party modules are (rightfully) bloated
return got('https://api.themoviedb.org/3/' + type + '/' + id + '/images?api_key=' + TmdbApiKey, {
json: true,
headers: {
'content-type': 'application/json'
},
timeout: 1000
})
.then(function (res) {
if (type === 'movie') {
var url = 'https://image.tmdb.org/t/p/';
var bsize = 'original'; // or w1280
var psize = 'w780'; // or w780
var built = null,
bg = null,
pos = null;
if (res.body) {
if (res.body.backdrops && res.body.backdrops[0]) {
bg = url + bsize + res.body.backdrops[0].file_path;
}
if (res.body.posters && res.body.posters[0]) {
pos = url + psize + res.body.posters[0].file_path;
}
if (bg || pos) {
built = {
background: bg,
poster: pos
};
}
}
} else if (type === "person") {
var url = 'https://image.tmdb.org/t/p/';
var bsize = 'original'; // or w1280
var psize = 'w780'; // or w780
var built = null,
bg = null,
pos = null;
if (res.body) {
if (res.body.profiles && res.body.profiles[0]) {
bg = url + bsize + res.body.profiles[0].file_path;
}
if (bg || pos) {
built = {
profile: bg
};
}
}
}
return resolve({source: 'tmdb', img: built});
})
.catch(function (error) {
return resolve({source: 'tmdb', img: null});
});
});
};
var getTvdb = function (id) {
return new Promise(function (resolve) {
if (!TvdbApiKey || !id) {
return resolve({source: 'tvdb', img: null});
}
var url = 'https://api.thetvdb.com/series/' + id + '/images/query';
var imbase = 'http://thetvdb.com/banners/';
var opts = {
json: true,
method: 'GET',
headers: {
Authorization: 'Bearer ' + TvdbApiKey
}
};
function tvCall(key, name) {
return new Promise(function (resol) {
var ret = {};
ret[name] = null;
return got(url + '?keyType=' + key, opts).then(function (res) {
var i = res.body;
if (i && i.data && i.data[0]) {
ret[name] = imbase + i.data[0].fileName;
}
return resol(ret);
})
.catch(function (err) {
return resol(ret);
});
});
};
return Promise.all([
tvCall('fanart', 'background'),
tvCall('poster', 'poster')
])
.then(function (responses) {
var obj = {};
obj[Object.keys(responses[0])[0]] = responses[0][Object.keys(responses[0])[0]];
obj[Object.keys(responses[1])[0]] = responses[1][Object.keys(responses[1])[0]];
return resolve({source: 'tvdb', img: obj});
})
.catch(function (err) {
return resolve({source: 'tvdb', img: null});
});
});
};
var parseItem = function (input) {
var output = {};
// check if it's a trakt object
if (input.ids) {
if (input.ids.imdb !== undefined && (input.ids.tmdb !== undefined || input.ids.tvdb !== undefined)) {
for (var i in input.ids) {
if (i.indexOf('imdb') !== -1)
output.imdb = input.ids[i];
if (i.indexOf('tvdb') !== -1)
output.tvdb = input.ids[i];
if (i.indexOf('tmdb') !== -1)
output.tmdb = input.ids[i];
}
}
}
for (var i in input) {
if (input[i]) {
if (i.indexOf('imdb') !== -1)
output.imdb = input[i];
if (i.indexOf('tvdb') !== -1)
output.tvdb = input[i];
if (i.indexOf('tmdb') !== -1)
output.tmdb = input[i];
if (i.indexOf('type') !== -1 && input[i]) {
switch (input[i]) {
case "movie":
output.type = input[i];
break;
case "show":
output.type = input[i];
break;
case "person":
output.type = input[i];
break;
default:
output.type = "show";
break;
}
}
if (!output.imdb && !output.tvdb && !output.tvdb) {
if (i === 'id' && input[i]) {
output.id = input[i];
}
}
}
}
return output;
};
var getMovie = function (item) {
return Promise.all([
getFanart(item.imdb, item.type),
getOmdb(item.imdb, item.type),
getTmdb(item.tmdb, item.type)
])
.then(function (obj) {
return format(obj);
});
};
var getPerson = function (item) {
return Promise
.all([getTmdb(item.tmdb, item.type)])
.then(function (obj) {
return format(obj);
});
};
var getShow = function (item) {
return Promise.all([
getFanart(item.tvdb, item.type),
getOmdb(item.imdb, item.type),
getTvdb(item.tvdb)
])
.then(function (obj) {
return format(obj);
});
};
var notFound = function () {
return new Promise(function (resolve) {
resolve({poster: null, background: null, profile: null});
});
};
//cacheEnabled = false to optionally disable cached requests
//default is true
Images.get = function (input, cacheEnabled = true) {
var item = parseItem(input);
if (item.type && (item.imdb || item.tvdb || item.tmdb)) {
if (item.type === 'movie') {
return getMovie(item);
} else if (item.type === 'person') {
return getPerson(item);
} else {
return getShow(item);
}
} else if (item.imdb || item.tvdb || item.tmdb || item.id) {
var id_type;
if (item.id) {
id_type = item
.id
.toString()
.indexOf('tt') !== -1
? 'imdb'
: 'tvdb';
} else {
id_type = item.imdb
? 'imdb'
: item.tvdb
? 'tvdb'
: item.tmdb
? 'tmdb'
: false;
}
if (!id_type) {
Trakt._debug('Image retrieval failed for: ' + JSON.stringify(input));
return notFound();
}
var TraktInstance = Cached && cacheEnabled ? Trakt.cached : Trakt;
return TraktInstance
.search
.id({
id_type: id_type,
id: item[id_type] || item.id
})
.then(function (res) {
if (res[0] && res[0].type === 'movie') {
return getMovie({imdb: res[0].movie.ids.imdb, tmdb: res[0].movie.ids.tmdb, type: 'movie'});
} else if (res[0] && res[0].type === 'person') {
return getPerson({tmdb: res[0].movie.ids.tmdb, type: 'person'});
} else {
return getShow({imdb: res[0].show.ids.imdb, tvdb: res[0].show.ids.tvdb});
}
})
.catch(function (err) {
return notFound();
});
} else {
Trakt._debug('Image retrieval failed for: ' + JSON.stringify(input));
return notFound();
}
};