Merge branch 'master' of github.com:KevinMidboe/seasonedShows

This commit is contained in:
2017-09-12 20:15:41 +02:00
23 changed files with 773 additions and 312 deletions

View File

@@ -1,12 +1,14 @@
class MediaInfo {
constructor(device, platform) {
this.device = undefined;
this.platform = undefined;
this.ip = undefined;
this.product = undefined;
this.title = undefined;
this.state = undefined;
constructor() {
this.duration = undefined;
this.height = undefined;
this.width = undefined;
this.bitrate = undefined;
this.resolution = undefined;
this.framerate = undefined;
this.protocol = undefined;
this.container = undefined;
this.audioCodec = undefined;
}
}

View File

@@ -5,11 +5,13 @@ const convertStreamToUser = require('src/plex/stream/convertStreamToUser');
const ConvertStreamToPlayback = require('src/plex/stream/convertStreamToPlayback');
function convertPlexToStream(plexStream) {
const stream = convertPlexToSeasoned(plexStream);
stream.mediaInfo = convertStreamToMediaInfo(plexStream.Media);
const stream = convertPlexToSeasoned(plexStream)
const plexStreamMedia = plexStream.Media[0]
stream.mediaInfo = convertStreamToMediaInfo(plexStreamMedia);
stream.player = convertStreamToPlayer(plexStream.Player);
stream.user = convertStreamToUser(plexStream.User);
stream.playback = new ConvertStreamToPlayback(plexStream.Media.Part);
stream.playback = new ConvertStreamToPlayback(plexStreamMedia.Part[0]);
return stream;
}

View File

@@ -6,6 +6,7 @@ function convertStreamToMediaInfo(plexStream) {
mediaInfo.duration = plexStream.duration;
mediaInfo.height = plexStream.height;
mediaInfo.width = plexStream.width;
if (plexStream.bitrate) {
mediaInfo.bitrate = plexStream.bitrate;
}

View File

@@ -51,7 +51,7 @@ class PlexRepository {
}
})
.catch((err) => {
throw new Error(err);
throw new Error('Error handling plex playing. Error: ' + err);
})
}
}

View File

@@ -67,13 +67,16 @@ class RequestRepository {
});
}
sendRequest(identifier) {
/**
* Send request for given media id.
* @param {identifier, type} the id of the media object and type of media must be defined
* @returns {Promise} If nothing has gone wrong.
*/
sendRequest(identifier, type) {
// TODO add to DB so can have a admin page
// TODO try a cache hit on the movie item
tmdb.lookup(identifier).then(movie => {
console.log(movie.title)
tmdb.lookup(identifier, type).then(movie => {
// create reusable transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({
@@ -110,6 +113,7 @@ class RequestRepository {
})
// TODO add better response when done.
return Promise.resolve();
}

View File

@@ -4,6 +4,11 @@ class convertStreamToPlayback {
this.width = plexStream.width;
this.height = plexStream.height;
this.decision = plexStream.decision;
this.audioProfile = plexStream.audioProfile;
this.videoProfile = plexStream.videoProfile;
this.duration = plexStream.duration;
this.container = plexStream.container;
}
}

View File

@@ -1,8 +1,8 @@
const Movie = require('src/media_classes/movie');
const Show = require('src/media_classes/show');
function convertTmdbToSeasoned(tmdbObject) {
const mediaType = tmdbObject.media_type;
function convertTmdbToSeasoned(tmdbObject, strictType=undefined) {
const mediaType = strictType || tmdbObject.media_type;
// There are many diff types of content, we only want to look at movies and tv shows
if (mediaType === 'movie') {
@@ -16,6 +16,7 @@ function convertTmdbToSeasoned(tmdbObject) {
const movie = new Movie(title, year, mediaType);
movie.id = tmdbObject.id;
movie.summary = tmdbObject.overview;
movie.rating = tmdbObject.vote_average;
movie.poster = tmdbObject.poster_path;
@@ -27,11 +28,12 @@ function convertTmdbToSeasoned(tmdbObject) {
return movie;
}
else if (mediaType === 'tv') {
else if (mediaType === 'tv' || mediaType === 'show') {
const year = new Date(tmdbObject.first_air_date).getFullYear();
const show = new Show(tmdbObject.title, year, mediaType);
const show = new Show(tmdbObject.name, year, 'show');
show.id = tmdbObject.id;
show.summary = tmdbObject.overview;
show.rating = tmdbObject.vote_average;
show.poster = tmdbObject.poster_path;

View File

@@ -1,7 +1,10 @@
const moviedb = require('moviedb');
const convertTmdbToSeasoned = require('src/tmdb/convertTmdbToSeasoned');
var methodTypes = { 'movie': 'searchMovie', 'tv': 'searchTv', 'multi': 'searchMulti', 'movieInfo': 'movieInfo',
'tvInfo': 'tvInfo' };
var methodTypes = { 'movie': 'searchMovie', 'show': 'searchTv', 'multi': 'searchMulti', 'movieInfo': 'movieInfo',
'tvInfo': 'tvInfo', 'upcomingMovies': 'miscUpcomingMovies', 'discoverMovie': 'discoverMovie',
'discoverShow': 'discoverTv', 'popularMovies': 'miscPopularMovies', 'popularShows': 'miscPopularTvs',
'nowPlayingMovies': 'miscNowPlayingMovies', 'nowAiringShows': 'tvOnTheAir', 'movieSimilar': 'movieSimilar',
'showSimilar': 'tvSimilar' };
class TMDB {
constructor(apiKey, tmdbLibrary) {
@@ -9,7 +12,7 @@ class TMDB {
}
search(text, page = 1, type = 'multi') {
const query = { query: text, page };
const query = { 'query': text, 'page': page };
return Promise.resolve()
.then(() => this.tmdb(type, query))
.catch(() => { throw new Error('Could not search for movies.'); })
@@ -26,27 +29,235 @@ class TMDB {
}
/**
* Retrive list of discover section of movies from TMDB.
* @param {Page, type} the page number to specify in the request for discover,
* and type for movie or show
* @returns {Promise} dict with query results, current page and total_pages
*/
discover(page, type='movie') {
// Sets the tmdb function type to the corresponding type from query
var tmdbType;
if (type === 'movie') {
tmdbType = 'discoverMovie';
} else if (type === 'show') {
tmdbType = 'discoverShow';
} else {
// Throw error if invalid type from query
return Promise.resolve()
.then(() => {
throw new Error('Invalid type declaration.')
})
}
// Build a query for tmdb with pagenumber
const query = { 'page': page }
return Promise.resolve()
.then(() => this.tmdb(tmdbType, query))
.catch(() => { throw new Error('Could not fetch discover.'); })
.then((response) => {
try {
// Return a object that has the results and a variable for page, total_pages
// and seasonedResponse
var seasonedResponse = response.results.map((result) => {
return convertTmdbToSeasoned(result, type); }
);
return { 'results': seasonedResponse,
'page': response.page, 'total_pages': response.total_pages };
} catch (error) {
console.log(error)
throw new Error('Error while parsing discover list.')
}
});
}
/**
* Retrive list of popular section of movies or shows from TMDB.
* @param {Page, type} the page number to specify in the request for popular,
* and type for movie or show
* @returns {Promise} dict with query results, current page and total_pages
*/
// TODO add filter for language
popular(page, type='movie') {
// Sets the tmdb function type to the corresponding type from query
var tmdbType;
if (type === 'movie') {
tmdbType = 'popularMovies';
} else if (type === 'show') {
tmdbType = 'popularShows';
} else {
// Throw error if invalid type from query
return Promise.resolve()
.then(() => {
throw new Error('Invalid type declaration.')
})
}
// Build a query for tmdb with pagenumber
const query = { 'page': page }
return Promise.resolve()
.then(() => this.tmdb(tmdbType, query))
.catch(() => { throw new Error('Could not fetch popular.'); })
.then((response) => {
try {
var seasonedResponse = response.results.map((result) => {
return convertTmdbToSeasoned(result, type); }
);
// Return a object that has the results and a variable for page, total_pages
// and seasonedResponse
return { 'results': seasonedResponse,
'page': response.page, 'total_pages': response.total_pages };
} catch (error) {
console.log(error)
throw new Error('Error while parsing discover list.')
}
});
}
/**
* Retrive list of now playing/airing section of movies or shows from TMDB.
* @param {Page, type} the page number to specify in the request for now playing/airing,
* and type for movie or show
* @returns {Promise} dict with query results, current page and total_pages
*/
// TODO add filter for language
nowplaying(page, type='movie') {
// Sets the tmdb function type to the corresponding type from query
var tmdbType;
if (type === 'movie') {
tmdbType = 'nowPlayingMovies';
} else if (type === 'show') {
tmdbType = 'nowAiringShows';
} else {
// Throw error if invalid type from query
return Promise.resolve()
.then(() => {
throw new Error('Invalid type declaration.')
})
}
// Build a query for tmdb with pagenumber
const query = { 'page': page }
return Promise.resolve()
.then(() => this.tmdb(tmdbType, query))
.catch(() => { throw new Error('Could not fetch popular.'); })
.then((response) => {
try {
var seasonedResponse = response.results.map((result) => {
return convertTmdbToSeasoned(result, type); }
);
// Return a object that has the results and a variable for page, total_pages
// and seasonedResponse
return { 'results': seasonedResponse,
'page': response.page, 'total_pages': response.total_pages };
} catch (error) {
console.log(error)
throw new Error('Error while parsing discover list.')
}
});
}
/**
* Retrive list of upcmoing movies from TMDB.
* @param {Page} the page number to specify in the request for upcoming movies
* @returns {Promise} dict with query results, current page and total_pages
*/
// TODO add filter for language
upcoming(page) {
const query = { 'page': page }
return Promise.resolve()
.then(() => this.tmdb('upcomingMovies', query))
.catch(() => { throw new Error('Could not fetch upcoming movies.'); })
.then((response) => {
try {
var seasonedResponse = response.results.map((result) => {
return convertTmdbToSeasoned(result, 'movie'); }
);
// Return a object that has the results and a variable for page, total_pages
// and seasonedResponse
return { 'results': seasonedResponse,
'page': response.page, 'total_pages': response.total_pages };
} catch (parseError) {
throw new Error('Error while parsing upcoming movies list.')
}
});
}
/**
* Retrive list of upcmoing movies from TMDB.
* @param {Page} the page number to specify in the request for upcoming movies
* @returns {Promise} dict with query results, current page and total_pages
*/
// TODO add filter for language
similar(identifier, type) {
var tmdbType;
if (type === 'movie') {
tmdbType = 'movieSimilar';
} else if (type === 'show') {
tmdbType = 'showSimilar';
} else {
// Throw error if invalid type from query
return Promise.resolve()
.then(() => {
throw new Error('Invalid type declaration.')
})
}
const query = { id: identifier }
return Promise.resolve()
.then(() => this.tmdb(tmdbType, query))
.catch(() => { throw new Error('Could not fetch upcoming movies.'); })
.then((response) => {
try {
var seasonedResponse = response.results.map((result) => {
return convertTmdbToSeasoned(result, type); }
);
// Return a object that has the results and a variable for page, total_pages
// and seasonedResponse
return { 'results': seasonedResponse,
'page': response.page, 'total_pages': response.total_pages };
} catch (parseError) {
throw new Error('Error while parsing silimar media list.')
}
});
}
/**
* Retrieve a specific movie by id from TMDB.
* @param {Number} identifier of the movie you want to retrieve
* @returns {Promise} succeeds if movie was found
*/
lookup(identifier, type = 'movie') {
if (type === 'movie') { type = 'movieInfo'}
else if (type === 'tv') { type = 'tvInfo'}
lookup(identifier, queryType = 'movie') {
var type;
if (queryType === 'movie') { type = 'movieInfo'}
else if (queryType === 'show') { type = 'tvInfo'}
else {
return Promise.resolve()
.then(() => {
throw new Error('Invalid type declaration.')
})
}
const query = { id: identifier };
return Promise.resolve()
.then(() => this.tmdb(type, query))
.catch(() => { throw new Error('Could not find a movie with that id.'); })
.then((response) => {
try {
return convertTmdbToSeasoned(response);
} catch (parseError) {
throw new Error('Could not parse movie.');
}
});
.then(() => this.tmdb(type, query))
.catch(() => { throw new Error('Could not find a movie with that id.'); })
.then((response) => {
try {
var car = convertTmdbToSeasoned(response, queryType);
console.log(car);
return car;
} catch (parseError) {
throw new Error('Could not parse movie.');
}
});
}
// TODO ADD CACHE LOOKUP
tmdb(method, argument) {
return new Promise((resolve, reject) => {
const callback = (error, reponse) => {
@@ -58,6 +269,7 @@ class TMDB {
if (!argument) {
this.tmdbLibrary[methodTypes[method]](callback);
// this.tmdbLibrary['miscUpcomingMovies']
} else {
this.tmdbLibrary[methodTypes[method]](argument, callback);
}

View File

@@ -15,7 +15,8 @@ var allowedOrigins = ['https://kevinmidboe.com', 'http://localhost:8080']
router.use(function(req, res, next) {
console.log('Something is happening.');
// TODO add logging of all incoming
console.log('Request: ', req.originalUrl);
var origin = req.headers.origin;
if (allowedOrigins.indexOf(origin) > -1) {
res.setHeader('Access-Control-Allow-Origin', origin);
@@ -40,6 +41,12 @@ router.post('/v1/plex/request/:mediaId', require('./controllers/plex/submitReque
router.get('/v1/plex/hook', require('./controllers/plex/hookDump.js'));
router.get('/v1/tmdb/search', require('./controllers/tmdb/searchMedia.js'));
router.get('/v1/tmdb/discover', require('./controllers/tmdb/discoverMedia.js'));
router.get('/v1/tmdb/popular', require('./controllers/tmdb/popularMedia.js'));
router.get('/v1/tmdb/nowplaying', require('./controllers/tmdb/nowPlayingMedia.js'));
router.get('/v1/tmdb/upcoming', require('./controllers/tmdb/getUpcoming.js'));
router.get('/v1/tmdb/similar/:mediaId', require('./controllers/tmdb/searchSimilar.js'));
router.get('/v1/tmdb/:mediaId', require('./controllers/tmdb/readMedia.js'));
router.post('/v1/git/dump', require('./controllers/git/dumpHook.js'));

View File

@@ -11,8 +11,9 @@ const requestRepository = new RequestRepository();
function submitRequestController(req, res) {
// This is the id that is the param of the url
const id = req.params.mediaId;
const type = req.query.type;
requestRepository.sendRequest(id)
requestRepository.sendRequest(id, type)
.then(() => {
res.send({ success: true, message: 'Media item sucessfully requested!' });
})

View File

@@ -0,0 +1,21 @@
const configuration = require('src/config/configuration').getInstance();
const TMDB = require('src/tmdb/tmdb');
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
/**
* Controller: Retrieve a list of movies or shows in discover section in TMDB
* @param {Request} req http request variable
* @param {Response} res
* @returns {Callback}
*/
function discoverMediaController(req, res) {
const { page, type } = req.query;
tmdb.discover(page, type)
.then((results) => {
res.send(results);
}).catch((error) => {
res.status(404).send({ success: false, error: error.message });
});
}
module.exports = discoverMediaController;

View File

@@ -0,0 +1,21 @@
const configuration = require('src/config/configuration').getInstance();
const TMDB = require('src/tmdb/tmdb');
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
/**
* Controller: Retrieve upcoming movies
* @param {Request} req http request variable
* @param {Response} res
* @returns {Callback}
*/
function getUpcomingController(req, res) {
const { page } = req.query;
tmdb.upcoming(page)
.then((results) => {
res.send(results);
}).catch((error) => {
res.status(404).send({ success: false, error: error.message });
});
}
module.exports = getUpcomingController;

View File

@@ -0,0 +1,21 @@
const configuration = require('src/config/configuration').getInstance();
const TMDB = require('src/tmdb/tmdb');
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
/**
* Controller: Retrieve nowplaying movies / now airing shows
* @param {Request} req http request variable
* @param {Response} res
* @returns {Callback}
*/
function nowPlayingMediaController(req, res) {
const { page, type } = req.query;
tmdb.nowplaying(page, type)
.then((results) => {
res.send(results);
}).catch((error) => {
res.status(404).send({ success: false, error: error.message });
});
}
module.exports = nowPlayingMediaController;

View File

@@ -0,0 +1,21 @@
const configuration = require('src/config/configuration').getInstance();
const TMDB = require('src/tmdb/tmdb');
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
/**
* Controller: Retrieve information for a movie
* @param {Request} req http request variable
* @param {Response} res
* @returns {Callback}
*/
function popularMediaController(req, res) {
const { page, type } = req.query;
tmdb.popular(page, type)
.then((results) => {
res.send(results);
}).catch((error) => {
res.status(404).send({ success: false, error: error.message });
});
}
module.exports = popularMediaController;

View File

@@ -14,7 +14,7 @@ function searchMoviesController(req, res) {
Promise.resolve()
.then(() => tmdb.search(query, page, type))
.then((movies) => {
if (movies.length > 0) {
if (movies !== undefined || movies.length > 0) {
res.send(movies);
} else {
res.status(404).send({ success: false, error: 'Search query did not return any results.'})

View File

@@ -0,0 +1,22 @@
const configuration = require('src/config/configuration').getInstance();
const TMDB = require('src/tmdb/tmdb');
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
/**
* Controller: Retrieve similar movies or shows
* @param {Request} req http request variable
* @param {Response} res
* @returns {Callback}
*/
function similarMediaController(req, res) {
const mediaId = req.params.mediaId;
const { type } = req.query;
tmdb.similar(mediaId, type)
.then((results) => {
res.send(results);
}).catch((error) => {
res.status(404).send({ success: false, error: error.message });
});
}
module.exports = similarMediaController;