Compare commits
	
		
			54 Commits
		
	
	
		
			renovate/c
			...
			research/g
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 488da889d8 | |||
| 8da7c159b1 | |||
| ea5bc36956 | |||
| fd475265c1 | |||
| b0804f8a08 | |||
| 6b737b8ab4 | |||
| 5623344666 | |||
| f8cc19b510 | |||
| c589457a6c | |||
| b802a7b62b | |||
| 879a02b388 | |||
| bc3d4881bd | |||
| ef8d4d90b2 | |||
| d2d396bb7a | |||
| 500b75eaf6 | |||
| 9308d4ea9b | |||
| 6c2c81a1a1 | |||
| 90aa4d2485 | |||
| 0ca3f81bf8 | |||
| b9831c6b3d | |||
| 4781e9ae65 | |||
|  | eb0881f19e | ||
| bc4d73821d | |||
| ab6144eb81 | |||
| c3d87e2200 | |||
| e391ce7ef9 | |||
| ca707078d9 | |||
|  | 53228a2662 | ||
| 2a9fa27341 | |||
| 3068281461 | |||
| 81e9fe5b15 | |||
| 5d2e375213 | |||
| 7ede37039a | |||
| 8e23ae5a27 | |||
| 04ba094a14 | |||
| 23f9911237 | |||
| 3b27af1f83 | |||
| afb7af46b8 | |||
| 6ba8ca2add | |||
| 135375cb94 | |||
| e5d5bdefd6 | |||
| 6f9ca9e067 | |||
| c42195d242 | |||
| a5aaf1bfca | |||
| af7b1f2424 | |||
| 6aba9774c6 | |||
| e19cfb5870 | |||
| 144b27f128 | |||
| 12afbf6364 | |||
| 8a5ab204e1 | |||
| 3f04d9bc56 | |||
| de50805d1e | |||
|  | 4eaa60b044 | ||
|  | 7db8f752c5 | 
| @@ -1,5 +1,5 @@ | |||||||
| language: node_js | language: node_js | ||||||
| node_js: '8.7.0' | node_js: '11.9.0' | ||||||
| git: | git: | ||||||
|    submodules: true |    submodules: true | ||||||
| script: | script: | ||||||
|   | |||||||
| @@ -10,8 +10,8 @@ | |||||||
|     <img src="https://travis-ci.org/KevinMidboe/seasonedShows.svg?branch=master" |     <img src="https://travis-ci.org/KevinMidboe/seasonedShows.svg?branch=master" | ||||||
|          alt="Travis CI"> |          alt="Travis CI"> | ||||||
|   </a> |   </a> | ||||||
|   <a href="https://coveralls.io/github/KevinMidboe/seasonedShows?branch=coverage"> |   <a href="https://coveralls.io/github/KevinMidboe/seasonedShows?branch=api/v2"> | ||||||
|     <img src="https://coveralls.io/repos/github/KevinMidboe/seasonedShows/badge.svg?branch=coverage" alt=""> |     <img src="https://coveralls.io/repos/github/KevinMidboe/seasonedShows/badge.svg?branch=api/v2" alt=""> | ||||||
|   </a> |   </a> | ||||||
|   <a href="https://snyk.io/test/github/KevinMidboe/seasonedShows?targetFile=seasoned_api/package.json"> |   <a href="https://snyk.io/test/github/KevinMidboe/seasonedShows?targetFile=seasoned_api/package.json"> | ||||||
|     <img src="https://snyk.io/test/github/KevinMidboe/seasonedShows/badge.svg?targetFile=seasoned_api/package.json" alt=""> |     <img src="https://snyk.io/test/github/KevinMidboe/seasonedShows/badge.svg?targetFile=seasoned_api/package.json" alt=""> | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "clean-webpack-plugin": "^0.1.17", |     "clean-webpack-plugin": "^0.1.17", | ||||||
|     "css-loader": "^0.28.4", |     "css-loader": "^1.0.0", | ||||||
|     "html-webpack-plugin": "^2.28.0", |     "html-webpack-plugin": "^2.28.0", | ||||||
|     "path": "^0.12.7", |     "path": "^0.12.7", | ||||||
|     "react": "^15.6.1", |     "react": "^15.6.1", | ||||||
| @@ -30,8 +30,8 @@ | |||||||
|     "redux-thunk": "^2.2.0", |     "redux-thunk": "^2.2.0", | ||||||
|     "urijs": "^1.18.12", |     "urijs": "^1.18.12", | ||||||
|     "webfontloader": "^1.6.28", |     "webfontloader": "^1.6.28", | ||||||
|     "webpack": "^3.5.5", |     "webpack": "^4.0.0", | ||||||
|     "webpack-dev-server": "^2.4.5", |     "webpack-dev-server": "^3.1.11", | ||||||
|     "webpack-merge": "^4.1.0" |     "webpack-merge": "^4.1.0" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|   | |||||||
| @@ -7,39 +7,51 @@ | |||||||
|   }, |   }, | ||||||
|   "main": "webserver/server.js", |   "main": "webserver/server.js", | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "start": "cross-env SEASONED_CONFIG=conf/development.json PROD=true NODE_PATH=. node src/webserver/server.js", |     "start": "cross-env SEASONED_CONFIG=conf/development.json PROD=true NODE_PATH=. babel-node src/webserver/server.js", | ||||||
|     "test": "cross-env SEASONED_CONFIG=conf/test.json NODE_PATH=. mocha --recursive test/unit test/system", |     "test": "cross-env SEASONED_CONFIG=conf/test.json NODE_PATH=. mocha --require @babel/register --recursive test/unit test/system", | ||||||
|     "coverage": "cross-env SEASONED_CONFIG=conf/test.json NODE_PATH=. nyc mocha --recursive test && nyc report --reporter=text-lcov | coveralls", |     "coverage": "cross-env SEASONED_CONFIG=conf/test.json NODE_PATH=. nyc mocha --require @babel/register --recursive test && nyc report --reporter=text-lcov | coveralls", | ||||||
|     "lint": "./node_modules/.bin/eslint src/", |     "lint": "./node_modules/.bin/eslint src/", | ||||||
|     "update": "cross-env SEASONED_CONFIG=conf/development.json NODE_PATH=. node src/plex/updateRequestsInPlex.js" |     "update": "cross-env SEASONED_CONFIG=conf/development.json NODE_PATH=. node src/plex/updateRequestsInPlex.js", | ||||||
|  |     "docs": "yarn apiDocs; yarn classDocs", | ||||||
|  |     "apiDocs": "", | ||||||
|  |     "classDocs": "./script/generate-class-docs.sh" | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "axios": "^0.18.0", |     "axios": "^0.18.0", | ||||||
|     "bcrypt-nodejs": "^0.0.3", |     "bcrypt": "^3.0.6", | ||||||
|     "body-parser": "~1.18.2", |     "body-parser": "~1.18.2", | ||||||
|     "cross-env": "~5.1.4", |     "cross-env": "~5.1.4", | ||||||
|     "express": "~4.16.0", |     "express": "~4.16.0", | ||||||
|     "jsonwebtoken": "^8.0.1", |     "express-graphql": "^0.9.0", | ||||||
|     "km-moviedb": "^0.2.13", |     "express-reload": "^1.2.0", | ||||||
|     "mongoose": "~5.0.11", |     "graphql": "^14.5.8", | ||||||
|  |     "jsonwebtoken": "^8.2.0", | ||||||
|     "km-moviedb": "^0.2.12", |     "km-moviedb": "^0.2.12", | ||||||
|     "node-cache": "^4.1.1", |     "node-cache": "^4.1.1", | ||||||
|  |     "node-fetch": "^2.6.0", | ||||||
|     "python-shell": "^0.5.0", |     "python-shell": "^0.5.0", | ||||||
|     "request": "^2.85.0", |     "raven": "^2.4.2", | ||||||
|  |     "request": "^2.87.0", | ||||||
|     "request-promise": "^4.2", |     "request-promise": "^4.2", | ||||||
|     "sqlite3": "^4.0.0" |     "sqlite3": "^4.0.0" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "coveralls": "^3.0.0", |     "@babel/core": "^7.5.5", | ||||||
|  |     "@babel/node": "^7.5.5", | ||||||
|  |     "@babel/preset-env": "^7.5.5", | ||||||
|  |     "@babel/register": "^7.5.5", | ||||||
|  |     "@types/node": "^12.6.8", | ||||||
|  |     "coveralls": "^3.0.5", | ||||||
|  |     "documentation": "^12.0.3", | ||||||
|     "eslint": "^4.9.0", |     "eslint": "^4.9.0", | ||||||
|     "eslint-config-airbnb-base": "^12.1.0", |     "eslint-config-airbnb-base": "^12.1.0", | ||||||
|     "eslint-plugin-import": "^2.8.0", |     "eslint-plugin-import": "^2.8.0", | ||||||
|     "istanbul": "^0.4.5", |     "istanbul": "^0.4.5", | ||||||
|     "mocha": "^5.0.4", |     "mocha": "^6.2.0", | ||||||
|     "mocha-lcov-reporter": "^1.3.0", |     "mocha-lcov-reporter": "^1.3.0", | ||||||
|     "nyc": "^11.6.0", |     "nyc": "^11.6.0", | ||||||
|     "raven": "^2.4.2", |  | ||||||
|     "supertest": "^3.0.0", |     "supertest": "^3.0.0", | ||||||
|     "supertest-as-promised": "^4.0.1" |     "supertest-as-promised": "^4.0.1", | ||||||
|  |     "typescript": "^3.5.3" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ class SqliteDatabase { | |||||||
|    * @param {Array} parameters in the SQL query |    * @param {Array} parameters in the SQL query | ||||||
|    * @returns {Promise} |    * @returns {Promise} | ||||||
|    */ |    */ | ||||||
|    async run(sql, parameters) { |    run(sql, parameters) { | ||||||
|       return new Promise((resolve, reject) => { |       return new Promise((resolve, reject) => { | ||||||
|          this.connection.run(sql, parameters, (error, result) => { |          this.connection.run(sql, parameters, (error, result) => { | ||||||
|             if (error) |             if (error) | ||||||
| @@ -41,7 +41,7 @@ class SqliteDatabase { | |||||||
|    * @param {Array} parameters in the SQL query |    * @param {Array} parameters in the SQL query | ||||||
|    * @returns {Promise} |    * @returns {Promise} | ||||||
|    */ |    */ | ||||||
|    async all(sql, parameters) { |    all(sql, parameters) { | ||||||
|       return new Promise((resolve, reject) => { |       return new Promise((resolve, reject) => { | ||||||
|          this.connection.all(sql, parameters, (err, rows) => { |          this.connection.all(sql, parameters, (err, rows) => { | ||||||
|             if (err) { |             if (err) { | ||||||
| @@ -58,7 +58,7 @@ class SqliteDatabase { | |||||||
|    * @param {Array} parameters in the SQL query |    * @param {Array} parameters in the SQL query | ||||||
|    * @returns {Promise} |    * @returns {Promise} | ||||||
|    */ |    */ | ||||||
|    async get(sql, parameters) { |    get(sql, parameters) { | ||||||
|       return new Promise((resolve, reject) => { |       return new Promise((resolve, reject) => { | ||||||
|          this.connection.get(sql, parameters, (err, rows) => { |          this.connection.get(sql, parameters, (err, rows) => { | ||||||
|             if (err) { |             if (err) { | ||||||
| @@ -75,7 +75,7 @@ class SqliteDatabase { | |||||||
|    * @param {Array} parameters in the SQL query |    * @param {Array} parameters in the SQL query | ||||||
|    * @returns {Promise} |    * @returns {Promise} | ||||||
|    */ |    */ | ||||||
|    async execute(sql) { |    execute(sql) { | ||||||
|       return new Promise(resolve => { |       return new Promise(resolve => { | ||||||
|          this.connection.exec(sql, (err, database) => { |          this.connection.exec(sql, (err, database) => { | ||||||
|              if (err) { |              if (err) { | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ function getMagnetFromURL(url) { | |||||||
|          resolve(url) |          resolve(url) | ||||||
|  |  | ||||||
|       http.get(options, (res) => { |       http.get(options, (res) => { | ||||||
|          if (res.statusCode == 301) { |          if (res.statusCode == 301 || res.statusCode == 302) { | ||||||
|             resolve(res.headers.location) |             resolve(res.headers.location) | ||||||
|          } |          } | ||||||
|       }); |       }); | ||||||
| @@ -21,7 +21,7 @@ function getMagnetFromURL(url) { | |||||||
|  |  | ||||||
| async function find(searchterm, callback) { | async function find(searchterm, callback) { | ||||||
|    const options = { |    const options = { | ||||||
|       pythonPath: '../torrent_search/env/bin/python3.6', |       pythonPath: '../torrent_search/env/bin/python3', | ||||||
|       scriptPath: '../torrent_search', |       scriptPath: '../torrent_search', | ||||||
|       args: [searchterm, '-s', 'jackett', '-f', '--print'] |       args: [searchterm, '-s', 'jackett', '-f', '--print'] | ||||||
|    } |    } | ||||||
| @@ -35,7 +35,7 @@ async function callPythonAddMagnet(url, callback) { | |||||||
|    getMagnetFromURL(url) |    getMagnetFromURL(url) | ||||||
|    .then((magnet) => { |    .then((magnet) => { | ||||||
|       const options = { |       const options = { | ||||||
|         pythonPath: '../delugeClient/env/bin/python3.6', |         pythonPath: '../delugeClient/env/bin/python3', | ||||||
|         scriptPath: '../delugeClient', |         scriptPath: '../delugeClient', | ||||||
|         args: ['add', magnet] |         args: ['add', magnet] | ||||||
|       }; |       }; | ||||||
| @@ -51,13 +51,10 @@ async function callPythonAddMagnet(url, callback) { | |||||||
| async function SearchPiratebay(query) { | async function SearchPiratebay(query) { | ||||||
|    return await new Promise((resolve, reject) => find(query, (err, results) => { |    return await new Promise((resolve, reject) => find(query, (err, results) => { | ||||||
|       if (err) { |       if (err) { | ||||||
|          /* eslint-disable no-console */ |  | ||||||
|          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) { | ||||||
|          /* eslint-disable no-console */ |  | ||||||
|          console.log('result', results); |  | ||||||
|          resolve(JSON.parse(results, null, '\t')); |          resolve(JSON.parse(results, null, '\t')); | ||||||
|       } |       } | ||||||
|    })); |    })); | ||||||
|   | |||||||
| @@ -1,59 +1,89 @@ | |||||||
| const axios = require('axios') | const fetch = require('node-fetch') | ||||||
| const convertPlexToMovie = require('src/plex/convertPlexToMovie') | 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, }  | ||||||
|  | // TODO? import class definitions to compare types ? | ||||||
|  | // what would typescript do? | ||||||
|  |  | ||||||
| class Plex { | class Plex { | ||||||
|   constructor(ip) { |   constructor(ip, port=32400) { | ||||||
|     this.plexIP = ip |     this.plexIP = ip | ||||||
|     this.plexPort = 32400 |     this.plexPort = port | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   matchTmdbAndPlexMedia(plex, tmdb) { | ||||||
|  |     if (plex === undefined || tmdb === undefined) | ||||||
|  |       return false | ||||||
|  |  | ||||||
|  |     const sanitize = (string) => string.toLowerCase() | ||||||
|  |  | ||||||
|  |     const matchTitle = sanitize(plex.title) === sanitize(tmdb.title) | ||||||
|  |     const matchYear = plex.year === tmdb.year | ||||||
|  |  | ||||||
|  |     return matchTitle && matchYear | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   existsInPlex(tmdbMovie) { |   existsInPlex(tmdbMovie) { | ||||||
|     return Promise.resolve() |     return this.search(tmdbMovie.title) | ||||||
|       .then(() => this.search(tmdbMovie.title)) |       .then(plexMovies => plexMovies.some(plex => this.matchTmdbAndPlexMedia(plex, tmdbMovie))) | ||||||
|       // TODO handle this when whitelist of local ip is not set in plex |   } | ||||||
|       .catch((error) => { console.error('Unable to search plex')}) |  | ||||||
|       .then((plexMovies) => { |  | ||||||
|         const matches = plexMovies.some((plexMovie) => { |  | ||||||
|           return tmdbMovie.title === plexMovie.title && tmdbMovie.type === plexMovie.type |  | ||||||
|         }) |  | ||||||
|  |  | ||||||
|         tmdbMovie.existsInPlex = matches |   successfullResponse(response) { | ||||||
|         return tmdbMovie |     const { status, statusText } = response | ||||||
|       }) |  | ||||||
|  |     if (status === 200) { | ||||||
|  |       return response.json() | ||||||
|  |     } else { | ||||||
|  |       throw { message: statusText, status: status } | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   search(query) { |   search(query) { | ||||||
|  |     const url = `http://${this.plexIP}:${this.plexPort}/hubs/search?query=${query}` | ||||||
|     const options = { |     const options = { | ||||||
|       baseURL: `http://${this.plexIP}:${this.plexPort}`, |       timeout: 2000, | ||||||
|       url: '/hubs/search', |       headers: { 'Accept': 'application/json' } | ||||||
|       params: { query: query }, |  | ||||||
|       responseType: 'json', |  | ||||||
|       timeout: 3000 |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return Promise.resolve() |     return fetch(url, options) | ||||||
|       .then(() => axios.request(options)) |       .then(this.successfullResponse) | ||||||
|       .catch((error) => { throw new Error(`Unable to search plex library`, error) }) |       .then(this.mapResults) | ||||||
|       .then(response => this.mapResults(response)) |       .catch(error => { | ||||||
|  |         if (error.type === 'request-timeout') { | ||||||
|  |           throw { message: 'Plex did not respond', status: 408, success: false } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         throw error | ||||||
|  |       }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   mapResults(response) { |   mapResults(response) { | ||||||
|     return response.data.MediaContainer.Hub.reduce((result, hub) => { |     if (response === undefined || response.MediaContainer === undefined) { | ||||||
|       if (hub.type === 'movie' && hub.Metadata !== undefined) { |       console.log('response was not valid to map', response) | ||||||
|         return [...result, ...hub.Metadata.map(convertPlexToMovie)] |       return [] | ||||||
|       } |     } | ||||||
|       else if (hub.type === 'show' && hub.Metadata !== undefined) { |  | ||||||
|         return [...result, ...hub.Metadata.map(convertPlexToShow)] |  | ||||||
|       } |  | ||||||
|       else if (hub.type === 'episode' && hub.Metadata !== undefined) { |  | ||||||
|         return [...result, ...hub.Metadata.map(convertPlexToEpisode)] |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       return result |     return response.MediaContainer.Hub | ||||||
|     }, []) |       .filter(category => category.size > 0) | ||||||
|  |       .map(category => { | ||||||
|  |         if (category.type === 'movie') { | ||||||
|  |           return category.Metadata.map(movie => { | ||||||
|  |             const ovie = Movie.convertFromPlexResponse(movie) | ||||||
|  |             return ovie.createJsonResponse() | ||||||
|  |           }) | ||||||
|  |         } else if (category.type === 'show') { | ||||||
|  |           return category.Metadata.map(convertPlexToShow) | ||||||
|  |         } else if (category.type === 'episode') { | ||||||
|  |           return category.Metadata.map(convertPlexToEpisode) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |       .filter(result => result !== undefined) | ||||||
|  |       .flat() | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ class Show { | |||||||
|     this.rating = null; |     this.rating = null; | ||||||
|     this.seasons = null; |     this.seasons = null; | ||||||
|     this.episodes = null; |     this.episodes = null; | ||||||
|     this.type = 'show'; |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										39
									
								
								seasoned_api/src/plex/updateRequestsInPlex.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								seasoned_api/src/plex/updateRequestsInPlex.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | const Plex = require('src/plex/plex') | ||||||
|  | const configuration = require('src/config/configuration').getInstance(); | ||||||
|  | const plex = new Plex(configuration.get('plex', 'ip')) | ||||||
|  | const establishedDatabase = require('src/database/database');  | ||||||
|  |  | ||||||
|  | class UpdateRequestsInPlex { | ||||||
|  |   constructor() { | ||||||
|  |      this.database = establishedDatabase; | ||||||
|  |      this.queries = { | ||||||
|  |         getMovies: `SELECT * FROM requests WHERE status = 'requested' OR status = 'downloading'`, | ||||||
|  | //         getMovies: "select * from requests where status is 'reset'", | ||||||
|  |         saveNewStatus: `UPDATE requests SET status = ? WHERE id IS ? and type IS ?`, | ||||||
|  |      } | ||||||
|  |   } | ||||||
|  |   getByStatus() { | ||||||
|  |      return this.database.all(this.queries.getMovies); | ||||||
|  |   } | ||||||
|  |   scrub() { | ||||||
|  |      return this.getByStatus() | ||||||
|  |         .then((requests) => Promise.all(requests.map(movie => plex.existsInPlex(movie)))) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   commitNewStatus(status, id, type, title) { | ||||||
|  |     console.log(type, title, 'updated to:', status) | ||||||
|  |     this.database.run(this.queries.saveNewStatus, [status, id, type]) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |     | ||||||
|  |   updateStatus(status) { | ||||||
|  |     this.getByStatus() | ||||||
|  |       .then(requests => Promise.all(requests.map(request => plex.existsInPlex(request)))) | ||||||
|  |       .then(matchedRequests => matchedRequests.filter(request => request.existsInPlex)) | ||||||
|  |       .then(newMatches => newMatches.map(match => this.commitNewStatus(status, match.id, match.type, match.title))) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | var requestsUpdater = new UpdateRequestsInPlex(); | ||||||
|  | requestsUpdater.updateStatus('downloaded') | ||||||
|  |  | ||||||
|  | module.exports = UpdateRequestsInPlex | ||||||
| @@ -23,6 +23,7 @@ class RequestRepository { | |||||||
|       downloaded: '(select status from requests where id is request.id and type is request.type limit 1)', |       downloaded: '(select status from requests where id is request.id and type is request.type limit 1)', | ||||||
|       // deluge: '(select status from deluge_torrent where id is request.id and type is request.type limit 1)', |       // deluge: '(select status from deluge_torrent where id is request.id and type is request.type limit 1)', | ||||||
|       // fetchAllFilterStatus: 'select * from request where ' |       // fetchAllFilterStatus: 'select * from request where ' | ||||||
|  |       readWithoutUserData: 'select id, title, year, type, status, date from requests where id is ? and type is ?', | ||||||
|       read: 'select id, title, year, type, status, requested_by, ip, date, user_agent from requests where id is ? and type is ?' |       read: 'select id, title, year, type, status, requested_by, ip, date, user_agent from requests where id is ? and type is ?' | ||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
| @@ -106,11 +107,17 @@ class RequestRepository { | |||||||
|    * @returns {Promise} |    * @returns {Promise} | ||||||
|    */ |    */ | ||||||
|   getRequestByIdAndType(id, type) { |   getRequestByIdAndType(id, type) { | ||||||
|     return Promise.resolve() |     return this.database.get(this.queries.readWithoutUserData, [id, type]) | ||||||
|       .then(() => this.database.get(this.queries.read, [id, type])) |  | ||||||
|       .then(row => { |       .then(row => { | ||||||
|         assert(row, 'Could not find request item with that id and type') |         assert(row, 'Could not find request item with that id and type') | ||||||
|         return JSON.stringify(row) |         return { | ||||||
|  |           id: row.id, | ||||||
|  |           title: row.title, | ||||||
|  |           year: row.year, | ||||||
|  |           type: row.type, | ||||||
|  |           status: row.status, | ||||||
|  |           requested_date: new Date(row.date) | ||||||
|  |         } | ||||||
|       }) |       }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -124,6 +131,7 @@ class RequestRepository { | |||||||
|    */ |    */ | ||||||
|   fetchAll(page=1, sort_by=undefined, sort_direction='asc', filter=undefined, query=undefined) { |   fetchAll(page=1, sort_by=undefined, sort_direction='asc', filter=undefined, query=undefined) { | ||||||
|     // TODO implemented sort and filter |     // TODO implemented sort and filter | ||||||
|  |     page = parseInt(page) | ||||||
|     let fetchQuery = this.queries.fetchAll |     let fetchQuery = this.queries.fetchAll | ||||||
|     let fetchTotalResults = this.queries.totalRequests |     let fetchTotalResults = this.queries.totalRequests | ||||||
|     let fetchParams = [page] |     let fetchParams = [page] | ||||||
| @@ -144,11 +152,15 @@ class RequestRepository { | |||||||
|         const totalRequests = sqliteResponse['totalRequests'] |         const totalRequests = sqliteResponse['totalRequests'] | ||||||
|         const totalPages = Math.ceil(totalRequests / 26) |         const totalPages = Math.ceil(totalRequests / 26) | ||||||
|  |  | ||||||
|         return [ rows.map(item => { item.poster = item.poster_path; return item }), totalPages ] |         return [ rows.map(item => { | ||||||
|  |           item.poster = item.poster_path; delete item.poster_path; | ||||||
|  |           item.backdrop = item.background_path; delete item.background_path; | ||||||
|  |           return item | ||||||
|  |         }), totalPages, totalRequests ] | ||||||
|         return Promise.all(this.mapToTmdbByType(rows)) |         return Promise.all(this.mapToTmdbByType(rows)) | ||||||
| }) | }) | ||||||
|       .then(([result, totalPages]) => Promise.resolve({ |       .then(([result, totalPages, totalRequests]) => Promise.resolve({ | ||||||
|         results: result, total_results: result.length, page: page, total_pages: totalPages |         results: result, total_results: totalRequests, page: page, total_pages: totalPages | ||||||
|       })) |       })) | ||||||
|       .catch(error => { console.log(error);throw error }) |       .catch(error => { console.log(error);throw error }) | ||||||
|   } |   } | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								seasoned_api/src/tmdb/.babelrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								seasoned_api/src/tmdb/.babelrc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | { | ||||||
|  |   "presets": ["@babel/preset-env"] | ||||||
|  | } | ||||||
| @@ -18,12 +18,12 @@ class Cache { | |||||||
|     * @returns {Object} |     * @returns {Object} | ||||||
|     */ |     */ | ||||||
|    get(key) { |    get(key) { | ||||||
|       return Promise.resolve() |      return Promise.resolve() | ||||||
|          .then(() => this.database.get(this.queries.read, [key])) |        .then(() => this.database.get(this.queries.read, [key])) | ||||||
|          .then((row) => { |        .then(row => { | ||||||
|             assert(row, 'Could not find cache enrty with that key.'); |          assert(row, 'Could not find cache entry with that key.'); | ||||||
|             return JSON.parse(row.value); |          return JSON.parse(row.value); | ||||||
|          }); |        }) | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    /** |    /** | ||||||
|   | |||||||
| @@ -1,49 +0,0 @@ | |||||||
| const Movie = require('src/tmdb/types/movie'); |  | ||||||
|  |  | ||||||
| const tmdbSwitcher = (tmdbMovie, property) => tmdbMovie[property] |  | ||||||
|  |  | ||||||
| function convertTmdbToMovie(tmdbMovie, credits=undefined) { |  | ||||||
|   const movie = new Movie(tmdbMovie.id, tmdbMovie.title) |  | ||||||
|   movie.overview = tmdbMovie.overview; |  | ||||||
|   movie.rank = tmdbMovie.vote_average; |  | ||||||
|  |  | ||||||
|   if (credits) { |  | ||||||
|     movie.credits = credits; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (tmdbMovie.release_date !== undefined) { |  | ||||||
|     movie.release_date = new Date(tmdbMovie.release_date); |  | ||||||
|     movie.year = movie.release_date.getFullYear(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (tmdbMovie.poster_path !== undefined) { |  | ||||||
|     movie.poster = tmdbMovie.poster_path; |  | ||||||
|   } |  | ||||||
|   if (tmdbMovie.backdrop_path !== undefined) { |  | ||||||
|     movie.backdrop = tmdbMovie.backdrop_path; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (tmdbMovie.status !== undefined) { |  | ||||||
|     movie.status = tmdbMovie.status; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (tmdbMovie.genres !== undefined) { |  | ||||||
|     movie.genres = tmdbMovie.genres.map(genre => genre.name); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (tmdbMovie.tagline !== undefined) { |  | ||||||
|     movie.tagline = tmdbMovie.tagline; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (tmdbMovie.runtime !== undefined) { |  | ||||||
|     movie.runtime = tmdbMovie.runtime; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (tmdbMovie.imdb_id !== undefined) { |  | ||||||
|     movie.imdb_id = tmdbMovie.imdb_id; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return movie; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| module.exports = convertTmdbToMovie; |  | ||||||
| @@ -1,30 +0,0 @@ | |||||||
| const Person = require('src/tmdb/types/person'); |  | ||||||
| const convertTmdbToMovie = require('src/tmdb/convertTmdbToMovie'); |  | ||||||
|  |  | ||||||
| function convertTmdbToPerson(tmdbPerson, cast=undefined) { |  | ||||||
|   const person = new Person(tmdbPerson.id, tmdbPerson.name); |  | ||||||
|  |  | ||||||
|   if (tmdbPerson.profile_path !== undefined) { |  | ||||||
|     person.poster = tmdbPerson.profile_path; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (tmdbPerson.birthday !== undefined) { |  | ||||||
|     person.birthday = new Date(tmdbPerson.birthday); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (tmdbPerson.deathday !== undefined) { |  | ||||||
|     person.deathday = tmdbPerson.deathday; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (tmdbPerson.known_for !== undefined) { |  | ||||||
|     person.known_for = tmdbPerson.known_for.map(convertTmdbToMovie); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (cast) { |  | ||||||
|     person.cast = cast.cast; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return person; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| module.exports = convertTmdbToPerson; |  | ||||||
| @@ -1,62 +0,0 @@ | |||||||
| const TMDB = require('src/media_classes/tmdb'); |  | ||||||
| const Movie = require('src/types/movie'); |  | ||||||
|  |  | ||||||
| function translateYear(tmdbReleaseDate) { |  | ||||||
|    return new Date(tmdbReleaseDate).getFullYear(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function translateGenre(tmdbGenres) { |  | ||||||
|    return tmdbGenres.map(genre => genre.name); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function convertType(tmdbType) { |  | ||||||
|    if (tmdbType === 'tv') return 'show'; |  | ||||||
|    return undefined; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function convertTmdbToMovie(tmdb) { |  | ||||||
|   const year =  |  | ||||||
|   const movie = new Movie(); |  | ||||||
|   let seasoned = undefined; |  | ||||||
|  |  | ||||||
|   if (tmdb.id && tmdb.title && tmdb.release_date) { |  | ||||||
|     const year = tmdb.release_date.getFullYear(); |  | ||||||
|     seasoned = new Movie(tmdb.id, tmdb.title, year); |  | ||||||
|   } |  | ||||||
|   else if (tmdb.id && tmdb.name && tmdb.first_air_date) { |  | ||||||
|     const year = tmdb.first_air_date.getFullYear(); |  | ||||||
|     seasoned = new Show(tmdb.id, tmdb.name, year); |  | ||||||
|     seasoned.seasons = tmdb.number_of_season; |  | ||||||
|     seasoned.episodes = tmdb.episodes; |  | ||||||
|     return  |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|    |  | ||||||
|    |  | ||||||
|   const title = tmdb.title || tmdb.name; |  | ||||||
|    const year = translateYear(tmdb.release_date || tmdb.first_air_date); |  | ||||||
|    const type = manualType || convertType(tmdb.type) || 'movie'; |  | ||||||
|  |  | ||||||
|    const id = tmdb.id; |  | ||||||
|    const summary = tmdb.overview; |  | ||||||
|    const poster_path = tmdb.poster_path; |  | ||||||
|    const background_path = tmdb.backdrop_path; |  | ||||||
|    const popularity = tmdb.popularity; |  | ||||||
|    const score = tmdb.vote_average; |  | ||||||
|    // const genres = translateGenre(tmdb.genres); |  | ||||||
|    const release_status = tmdb.status; |  | ||||||
|    const tagline = tmdb.tagline; |  | ||||||
|  |  | ||||||
|    const seasons = tmdb.number_of_seasons; |  | ||||||
|    const episodes = tmdb.episodes; |  | ||||||
|  |  | ||||||
|    const seasoned = new TMDB( |  | ||||||
|       title, year, type, id, summary, poster_path, background_path, |  | ||||||
|       popularity, score, release_status, tagline, seasons, episodes |  | ||||||
|    ); |  | ||||||
|  |  | ||||||
|    // seasoned.print() |  | ||||||
|    return seasoned; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| module.exports = convertTmdbToSeasoned; |  | ||||||
| @@ -1,41 +0,0 @@ | |||||||
| const Show = require('src/tmdb/types/show'); |  | ||||||
|  |  | ||||||
| function convertTmdbToShow(tmdbShow, credits=undefined) { |  | ||||||
|   const show = new Show(tmdbShow.id, tmdbShow.name) |  | ||||||
|   show.seasons = tmdbShow.number_of_seasons; |  | ||||||
|   show.episodes = tmdbShow.number_of_episodes; |  | ||||||
|   show.overview = tmdbShow.overview; |  | ||||||
|   show.rank = tmdbShow.vote_average; |  | ||||||
|  |  | ||||||
|   if (credits) { |  | ||||||
|     show.credits = credits |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (tmdbShow.genres !== undefined) { |  | ||||||
|     show.genres = tmdbShow.genres.map(genre => genre.name); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (tmdbShow.first_air_date !== undefined) { |  | ||||||
|     show.first_air_date = new Date(tmdbShow.first_air_date); |  | ||||||
|     show.year = show.first_air_date.getFullYear(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (tmdbShow.poster_path !== undefined) { |  | ||||||
|     show.poster = tmdbShow.poster_path; |  | ||||||
|   } |  | ||||||
|   if (tmdbShow.backdrop_path !== undefined) { |  | ||||||
|     show.backdrop = tmdbShow.backdrop_path; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (tmdbShow.status !== undefined) { |  | ||||||
|     show.status = tmdbShow.status; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (tmdbShow.episode_run_time !== undefined) { |  | ||||||
|     show.runtime = tmdbShow.runtime; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return show; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| module.exports = convertTmdbToShow; |  | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| const moviedb = require('km-moviedb'); | const moviedb = require('km-moviedb'); | ||||||
| const convertTmdbToMovie = require('src/tmdb/convertTmdbToMovie'); |  | ||||||
| const convertTmdbToShow = require('src/tmdb/convertTmdbToShow'); | const { Movie, Show, Person, Credits, ReleaseDates } = require('src/tmdb/types'); | ||||||
| const convertTmdbToPerson = require('src/tmdb/convertTmdbToPerson'); | // const { tmdbInfo } = require('src/tmdb/types') | ||||||
|  |  | ||||||
| class TMDB { | class TMDB { | ||||||
|   constructor(cache, apiKey, tmdbLibrary) { |   constructor(cache, apiKey, tmdbLibrary) { | ||||||
| @@ -13,7 +13,10 @@ class TMDB { | |||||||
|       showSearch: 'ss', |       showSearch: 'ss', | ||||||
|       personSearch: 'ps', |       personSearch: 'ps', | ||||||
|       movieInfo: 'mi', |       movieInfo: 'mi', | ||||||
|  |       movieCredits: 'mc', | ||||||
|  |       movieReleaseDates: 'mrd', | ||||||
|       showInfo: 'si', |       showInfo: 'si', | ||||||
|  |       showCredits: 'sc', | ||||||
|       personInfo: 'pi', |       personInfo: 'pi', | ||||||
|       miscNowPlayingMovies: 'npm', |       miscNowPlayingMovies: 'npm', | ||||||
|       miscPopularMovies: 'pm', |       miscPopularMovies: 'pm', | ||||||
| @@ -25,70 +28,54 @@ class TMDB { | |||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|    /** |  | ||||||
|    * Retrieve a specific movie by id from TMDB. |  | ||||||
|    * @param {Number} identifier of the movie you want to retrieve |  | ||||||
|    * @param {String} type filter results by type (default movie). |  | ||||||
|    * @returns {Promise} succeeds if movie was found |  | ||||||
|    */ |  | ||||||
|    lookup(identifier, type = 'movie') { |  | ||||||
|       const query = { id: identifier }; |  | ||||||
|       const cacheKey = `${this.cacheTags.info}:${type}:${identifier}`; |  | ||||||
|       return Promise.resolve() |  | ||||||
|          .then(() => this.cache.get(cacheKey)) |  | ||||||
|          .catch(() => this.tmdb(TMDB_METHODS['info'][type], query)) |  | ||||||
|          .catch(() => { throw new Error('Could not find a movie with that id.'); }) |  | ||||||
|          .then(response => this.cache.set(cacheKey, response)) |  | ||||||
|          .then(response => { |  | ||||||
|             try { |  | ||||||
|                return convertTmdbToSeasoned(response, type); |  | ||||||
|             } catch (parseError) { |  | ||||||
|                console.error(parseError); |  | ||||||
|                throw new Error('Could not parse movie.'); |  | ||||||
|             } |  | ||||||
|          }); |  | ||||||
|    } |  | ||||||
|  |  | ||||||
|    /** |  | ||||||
|    * Retrive search results from TMDB. |  | ||||||
|    * @param {String} text query you want to search for |  | ||||||
|    * @param {Number} page representing pagination of results |  | ||||||
|    * @param {String} type filter results by type (default multi) |  | ||||||
|    * @returns {Promise} dict with query results, current page and total_pages |  | ||||||
|    */ |  | ||||||
|    search(text, page = 1, type = 'multi') { |  | ||||||
|       const query = { query: text, page: page }; |  | ||||||
|       const cacheKey = `${this.cacheTags.search}:${page}:${type}:${text}`; |  | ||||||
|       return Promise.resolve() |  | ||||||
|          .then(() => this.cache.get(cacheKey)) |  | ||||||
|          .catch(() => this.tmdb(TMDB_METHODS['search'][type], query)) |  | ||||||
|          .catch(() => { throw new Error('Could not search for movies/shows at tmdb.'); }) |  | ||||||
|          .then(response => this.cache.set(cacheKey, response)) |  | ||||||
|          .then(response => this.mapResults(response)); |  | ||||||
|    } |  | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Retrieve a specific movie by id from TMDB. |    * Retrieve a specific movie by id from TMDB. | ||||||
|    * @param {Number} identifier of the movie you want to retrieve |    * @param {Number} identifier of the movie you want to retrieve | ||||||
|    * @param {String} type filter results by type (default movie). |    * @param {Boolean} add credits (cast & crew) for movie | ||||||
|  |    * @param {Boolean} add release dates for every country | ||||||
|    * @returns {Promise} succeeds if movie was found |    * @returns {Promise} succeeds if movie was found | ||||||
|    */ |    */ | ||||||
|   movieInfo(identifier, credits=false) { |   movieInfo(identifier) { | ||||||
|     const query = { id: identifier }; |     const query = { id: identifier }; | ||||||
|     const cacheKey = `${this.cacheTags.movieInfo}:${identifier}:${credits}`; |     const cacheKey = `${this.cacheTags.movieInfo}:${identifier}`; | ||||||
|  |  | ||||||
|     const requests = [this.tmdb('movieInfo', query)] |     return this.cache.get(cacheKey) | ||||||
|  |       .catch(() => this.tmdb('movieInfo', query)) | ||||||
|  |       .catch(tmdbError => tmdbErrorResponse(tmdbError, 'movie info')) | ||||||
|  |       .then(movie => this.cache.set(cacheKey, movie, 1)) | ||||||
|  |       .then(movie => Movie.convertFromTmdbResponse(movie)) | ||||||
|  |   } | ||||||
|  |  | ||||||
|     if (credits) { |   /** | ||||||
|       requests.push(this.tmdb('movieCredits', query)) |    * Retrieve credits for a movie | ||||||
|     } |    * @param {Number} identifier of the movie to get credits for | ||||||
|  |    * @returns {Promise} movie cast object | ||||||
|  |    */ | ||||||
|  |   movieCredits(identifier) { | ||||||
|  |     const query = { id: identifier } | ||||||
|  |     const cacheKey = `${this.cacheTags.movieCredits}:${identifier}` | ||||||
|  |  | ||||||
|     return Promise.resolve() |     return this.cache.get(cacheKey) | ||||||
|       .then(() => this.cache.get(cacheKey)) |       .catch(() => this.tmdb('movieCredits', query)) | ||||||
|       .catch(() => Promise.all(requests)) |       .catch(tmdbError => tmdbErrorResponse(tmdbError, 'movie credits')) | ||||||
|       .catch((error) => { console.log(error); throw new Error('Could not find a movie with that id.'); }) |       .then(credits => this.cache.set(cacheKey, credits, 1)) | ||||||
|       .then(([movies, credits]) => this.cache.set(cacheKey, [movies, credits])) |       .then(credits => Credits.convertFromTmdbResponse(credits)) | ||||||
|       .then(([movies, credits]) => convertTmdbToMovie(movies, credits)) |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * Retrieve release dates for a movie | ||||||
|  |    * @param {Number} identifier of the movie to get release dates for | ||||||
|  |    * @returns {Promise} movie release dates object | ||||||
|  |    */ | ||||||
|  |   movieReleaseDates(identifier) { | ||||||
|  |     const query = { id: identifier } | ||||||
|  |     const cacheKey = `${this.cacheTags.movieReleaseDates}:${identifier}` | ||||||
|  |  | ||||||
|  |     return this.cache.get(cacheKey) | ||||||
|  |       .catch(() => this.tmdb('movieReleaseDates', query)) | ||||||
|  |       .catch(tmdbError => tmdbErrorResponse(tmdbError, 'movie release dates')) | ||||||
|  |       .then(releaseDates => this.cache.set(cacheKey, releaseDates, 1)) | ||||||
|  |       .then(releaseDates => ReleaseDates.convertFromTmdbResponse(releaseDates)) | ||||||
|   } |   } | ||||||
|   |   | ||||||
|   /** |   /** | ||||||
| @@ -97,22 +84,26 @@ class TMDB { | |||||||
|    * @param {String} type filter results by type (default show). |    * @param {String} type filter results by type (default show). | ||||||
|    * @returns {Promise} succeeds if show was found |    * @returns {Promise} succeeds if show was found | ||||||
|    */ |    */ | ||||||
|   showInfo(identifier, credits=false) { |   showInfo(identifier) { | ||||||
|     const query = { id: identifier }; |     const query = { id: identifier }; | ||||||
|     const cacheKey = `${this.cacheTags.showInfo}:${identifier}:${credits}`; |     const cacheKey = `${this.cacheTags.showInfo}:${identifier}`; | ||||||
|  |  | ||||||
|     const requests = [this.tmdb('tvInfo', query)] |     return this.cache.get(cacheKey) | ||||||
|  |       .catch(() => this.tmdb('tvInfo', query)) | ||||||
|  |       .catch(tmdbError => tmdbErrorResponse(tmdbError, 'tv info')) | ||||||
|  |       .then(show => this.cache.set(cacheKey, show, 1)) | ||||||
|  |       .then(show => Show.convertFromTmdbResponse(show)) | ||||||
|  |   } | ||||||
|  |  | ||||||
|     if (credits) { |   showCredits(identifier) { | ||||||
|       requests.push(this.tmdb('tvCredits', query)) |     const query = { id: identifier } | ||||||
|     } |     const cacheKey = `${this.cacheTags.showCredits}:${identifier}` | ||||||
|  |  | ||||||
|     return Promise.resolve() |     return this.cache.get(cacheKey) | ||||||
|     .then(() => this.cache.get(cacheKey)) |       .catch(() => this.tmdb('tvCredits', query)) | ||||||
|       .catch(() => Promise.all(requests)) |       .catch(tmdbError => tmdbErrorResponse(tmdbError, 'show credits')) | ||||||
|     .catch(() => { throw new Error('Could not find a show with that id.'); }) |       .then(credits => this.cache.set(cacheKey, credits, 1)) | ||||||
|     .then(([shows, credits]) => this.cache.set(cacheKey, [shows, credits])) |       .then(credits => Credits.convertFromTmdbResponse(credits)) | ||||||
|     .then(([shows, credits]) => convertTmdbToShow(shows, credits)) |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
| @@ -125,25 +116,20 @@ class TMDB { | |||||||
|     const query = { id: identifier }; |     const query = { id: identifier }; | ||||||
|     const cacheKey = `${this.cacheTags.personInfo}:${identifier}`; |     const cacheKey = `${this.cacheTags.personInfo}:${identifier}`; | ||||||
|  |  | ||||||
|     return Promise.resolve() |     return this.cache.get(cacheKey) | ||||||
|       .then(() => this.cache.get(cacheKey)) |       .catch(() => this.tmdb('personInfo', query)) | ||||||
|       .catch(() => Promise.all([this.tmdb('personInfo', query), this.tmdb('personCombinedCredits', query)])) |       .catch(tmdbError => tmdbErrorResponse(tmdbError, 'person info')) | ||||||
|       .catch(() => { throw new Error('Could not find a person with that id.'); }) |       .then(person => this.cache.set(cacheKey, person, 1)) | ||||||
|       .then(([person, cast]) => this.cache.set(cacheKey, [person, cast])) |       .then(person => Person.convertFromTmdbResponse(person)) | ||||||
|       .then(([person, cast]) => convertTmdbToPerson(person, cast)) |  | ||||||
|       .catch(err => new Error('Unable to convert result to person', err)) |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   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 = `${this.cacheTags.multiSearch}:${page}:${search_query}`; | ||||||
|     return Promise.resolve() |     return this.cache.get(cacheKey) | ||||||
|       .then(() => this.cache.get(cacheKey)) |  | ||||||
|       .catch(() => this.tmdb('searchMulti', query)) |       .catch(() => this.tmdb('searchMulti', query)) | ||||||
|       .catch(() => { throw new Error('Could not complete search to tmdb'); }) |       .catch(tmdbError => tmdbErrorResponse(tmdbError, 'search results')) | ||||||
|       .then(response => this.cache.set(cacheKey, response)) |       .then(response => this.cache.set(cacheKey, response, 1)) | ||||||
|       .then(response => this.mapResults(response)); |       .then(response => this.mapResults(response)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -157,13 +143,11 @@ class TMDB { | |||||||
|     const tmdbquery = { query: query, page: page }; |     const tmdbquery = { query: query, page: page }; | ||||||
|     const cacheKey = `${this.cacheTags.movieSearch}:${page}:${query}`; |     const cacheKey = `${this.cacheTags.movieSearch}:${page}:${query}`; | ||||||
|  |  | ||||||
|     return Promise.resolve() |     return this.cache.get(cacheKey) | ||||||
|     .then(() => this.cache.get(cacheKey)) |       .catch(() => this.tmdb('searchMovie', tmdbquery)) | ||||||
|     .catch(() => this.tmdb('searchMovie', tmdbquery)) |       .catch(tmdbError => tmdbErrorResponse(tmdbError, 'movie search results')) | ||||||
|     .catch(() => { throw new Error('Could not complete movie search to tmdb'); }) |       .then(response => this.cache.set(cacheKey, response, 1)) | ||||||
|     .then(response => this.cache.set(cacheKey, response)) |       .then(response => this.mapResults(response, 'movie')) | ||||||
|     .then(response => this.mapAndCreateResponse(response, convertTmdbToMovie)) |  | ||||||
|     .catch((error) => { console.log(error); throw new Error('Could not parse movie search result') }) |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
| @@ -175,13 +159,12 @@ 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 = `${this.cacheTags.showSearch}:${page}:${query}`; | ||||||
|     return Promise.resolve() |  | ||||||
|     .then(() => this.cache.get(cacheKey)) |     return this.cache.get(cacheKey) | ||||||
|     .catch(() => this.tmdb('searchTv', tmdbquery)) |       .catch(() => this.tmdb('searchTv', tmdbquery)) | ||||||
|     .catch(() => { throw new Error('Could not complete show search to tmdb'); }) |       .catch(tmdbError => tmdbErrorResponse(tmdbError, 'tv search results')) | ||||||
|     .then(response => this.cache.set(cacheKey, response)) |       .then(response => this.cache.set(cacheKey, response, 1)) | ||||||
|     .then(response => this.mapAndCreateResponse(response, convertTmdbToShow)) |       .then(response => this.mapResults(response, 'show')) | ||||||
|     .catch((error) => { console.log(error); throw new Error('Could not parse show search result') }) |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
| @@ -191,78 +174,36 @@ class TMDB { | |||||||
|    * @returns {Promise} dict with query results, current page and total_pages |    * @returns {Promise} dict with query results, current page and total_pages | ||||||
|    */ |    */ | ||||||
|   personSearch(query, page=1) { |   personSearch(query, page=1) { | ||||||
|     const tmdbquery = { query: query, page: page }; |  | ||||||
|  |     const tmdbquery = { query: query, page: page, include_adult: true }; | ||||||
|     const cacheKey = `${this.cacheTags.personSearch}:${page}:${query}`; |     const cacheKey = `${this.cacheTags.personSearch}:${page}:${query}`; | ||||||
|     return Promise.resolve() |  | ||||||
|     .then(() => this.cache.get(cacheKey)) |  | ||||||
|     .catch(() => this.tmdb('searchPerson', tmdbquery)) |  | ||||||
|     .catch(() => { throw new Error('Could not complete person search to tmdb'); }) |  | ||||||
|     .then(response => this.cache.set(cacheKey, response)) |  | ||||||
|     .then(response => this.mapAndCreateResponse(response, convertTmdbToPerson)) |  | ||||||
|     .catch((error) => { console.log(error); throw new Error('Could not parse person search result') }) |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   mapAndCreateResponse(response, resultConvertFunction) { |     return this.cache.get(cacheKey) | ||||||
|     // console.log(response) |       .catch(() => this.tmdb('searchPerson', tmdbquery)) | ||||||
|     return { |       .catch(tmdbError => tmdbErrorResponse(tmdbError, 'person search results')) | ||||||
|       results: response.results.map(resultConvertFunction), |       .then(response => this.cache.set(cacheKey, response, 1)) | ||||||
|       page: response.page, |       .then(response => this.mapResults(response, 'person')) | ||||||
|       total_results: response.total_results, |  | ||||||
|       total_pages: response.total_pages |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   movieList(listname, page = 1) { |   movieList(listname, page = 1) { | ||||||
|     const query = { page: page }; |     const query = { page: page }; | ||||||
|     const cacheKey = `${this.cacheTags[listname]}:${page}`; |     const cacheKey = `${this.cacheTags[listname]}:${page}`; | ||||||
|     return Promise.resolve() |     return this.cache.get(cacheKey) | ||||||
|       .then(() => this.cache.get(cacheKey)) |  | ||||||
|       .catch(() => this.tmdb(listname, query)) |       .catch(() => this.tmdb(listname, query)) | ||||||
|       .catch(() => { throw new Error('Unable to get movie list from tmdb')}) |       .catch(tmdbError => this.tmdbErrorResponse(tmdbError, 'movie list ' + listname)) | ||||||
|       .then(response => this.cache.set(cacheKey, response)) |       .then(response => this.cache.set(cacheKey, response, 1)) | ||||||
|       .then(response => this.mapAndCreateResponse(response, convertTmdbToMovie)); |       .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 = `${this.cacheTags[listname]}:${page}`; | ||||||
|     return Promise.resolve() |  | ||||||
|       .then(() => this.cache.get(cacheKey)) |     return this.cache.get(cacheKey) | ||||||
|       .catch(() => this.tmdb(listname, query)) |       .catch(() => this.tmdb(listname, query)) | ||||||
|       .catch(() => { throw new Error('Unable to get show list from tmdb')}) |       .catch(tmdbError => this.tmdbErrorResponse(tmdbError, 'show list ' + listname)) | ||||||
|       .then(response => this.cache.set(cacheKey, response)) |       .then(response => this.cache.set(cacheKey, response, 1)) | ||||||
|       .then(response => this.mapAndCreateResponse(response, convertTmdbToShow)); |       .then(response => this.mapResults(response, 'show')) | ||||||
|   } |  | ||||||
|  |  | ||||||
|    /** |  | ||||||
|    * Fetches a given list from tmdb. |  | ||||||
|    * @param {String} listName Name of list |  | ||||||
|    * @param {String} type filter results by type (default movie) |  | ||||||
|    * @param {Number} page representing pagination of results |  | ||||||
|    * @returns {Promise} dict with query results, current page and total_pages |  | ||||||
|    */ |  | ||||||
|    listSearch(listName, type = 'movie', page = '1') { |  | ||||||
|       const query = { page: page }; |  | ||||||
|       console.log(query); |  | ||||||
|       const cacheKey = `${this.cacheTags[listName]}:${type}:${page}`; |  | ||||||
|       return Promise.resolve() |  | ||||||
|          .then(() => this.cache.get(cacheKey)) |  | ||||||
|          .catch(() => this.tmdb(TMDB_METHODS[listName][type], query)) |  | ||||||
|          .catch(() => { throw new Error('Error fetching list from tmdb.'); }) |  | ||||||
|          .then(response => this.cache.set(cacheKey, response)) |  | ||||||
|          .then(response => this.mapResults(response, type)); |  | ||||||
|    } |  | ||||||
|  |  | ||||||
|   popular(type='movie', page=1) { |  | ||||||
|     const query = { type: type, page: page }; |  | ||||||
|     const cacheKey = `${this.cacheTags.popular}:${type}:${page}`; |  | ||||||
|     return Promise.resolve() |  | ||||||
|       .then(() => this.cache.get(cacheKey)) |  | ||||||
|       .catch(() => this.tmdb('miscPopularMovies', query)) |  | ||||||
|       .catch((e) => { throw new Error(`Error fetching popular list of type ${type} : ${e}`) }) |  | ||||||
|       .then(response => this.cache.set(cacheKey, response)) |  | ||||||
|       .then(response => this.mapResults(response, type)); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
| @@ -271,14 +212,20 @@ class TMDB { | |||||||
|    * @param {String} The type declared in listSearch. |    * @param {String} The type declared in listSearch. | ||||||
|    * @returns {Promise} dict with tmdb results, mapped as movie/show objects. |    * @returns {Promise} dict with tmdb results, mapped as movie/show objects. | ||||||
|    */ |    */ | ||||||
|   mapResults(response, _) { |   mapResults(response, type=undefined) { | ||||||
|     let results = response.results.map((result) => { |     // console.log(response.results) | ||||||
|       if (result.media_type === 'movie') { |     // response.results.map(te => console.table(te)) | ||||||
|         return convertTmdbToMovie(result); |  | ||||||
|       } else if (result.media_type === 'tv') { |     let results = response.results.map(result => { | ||||||
|         return convertTmdbToShow(result); |       if (type === 'movie' || result.media_type === 'movie') { | ||||||
|       } else if (result.media_type === 'person') { |         const movie = Movie.convertFromTmdbResponse(result) | ||||||
|         return convertTmdbToPerson(result); |         return movie.createJsonResponse() | ||||||
|  |       } else if (type === 'show' || result.media_type === 'tv') { | ||||||
|  |         const show = Show.convertFromTmdbResponse(result) | ||||||
|  |         return show.createJsonResponse() | ||||||
|  |       } else if (type === 'person' || result.media_type === 'person') { | ||||||
|  |         const person = Person.convertFromTmdbResponse(result) | ||||||
|  |         return person.createJsonResponse() | ||||||
|       } |       } | ||||||
|     }) |     }) | ||||||
|  |  | ||||||
| @@ -312,6 +259,28 @@ 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; | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								seasoned_api/src/tmdb/tmdb.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								seasoned_api/src/tmdb/tmdb.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | import { Movie } from './types' | ||||||
|  |  | ||||||
|  | Movie('str', 123) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | module.exports = TMDB; | ||||||
							
								
								
									
										7
									
								
								seasoned_api/src/tmdb/types.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								seasoned_api/src/tmdb/types.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | import Movie from './types/movie.js' | ||||||
|  | import Show from './types/show.js' | ||||||
|  | import Person from './types/person.js' | ||||||
|  | import Credits from './types/credits.js' | ||||||
|  | import ReleaseDates from './types/releaseDates.js' | ||||||
|  |  | ||||||
|  | module.exports = { Movie, Show, Person, Credits, ReleaseDates } | ||||||
							
								
								
									
										64
									
								
								seasoned_api/src/tmdb/types.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								seasoned_api/src/tmdb/types.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | |||||||
|  | interface Movie { | ||||||
|  |   adult: boolean; | ||||||
|  |   backdrop: string; | ||||||
|  |   genres: Genre[]; | ||||||
|  |   id: number; | ||||||
|  |   imdb_id: number; | ||||||
|  |   overview: string; | ||||||
|  |   popularity: number; | ||||||
|  |   poster: string; | ||||||
|  |   release_date: Date; | ||||||
|  |   rank: number; | ||||||
|  |   runtime: number; | ||||||
|  |   status: string; | ||||||
|  |   tagline: string; | ||||||
|  |   title: string; | ||||||
|  |   vote_count: number; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | interface Show { | ||||||
|  |   adult: boolean; | ||||||
|  |   backdrop: string; | ||||||
|  |   episodes: number; | ||||||
|  |   genres: Genre[]; | ||||||
|  |   id: number; | ||||||
|  |   imdb_id: number; | ||||||
|  |   overview: string; | ||||||
|  |   popularity: number; | ||||||
|  |   poster: string; | ||||||
|  |   rank: number; | ||||||
|  |   runtime: number; | ||||||
|  |   seasons: number; | ||||||
|  |   status: string; | ||||||
|  |   tagline: string; | ||||||
|  |   title: string; | ||||||
|  |   vote_count: number; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | interface Person { | ||||||
|  |   birthday: Date; | ||||||
|  |   deathday: Date; | ||||||
|  |   id: number; | ||||||
|  |   known_for: string; | ||||||
|  |   name: string; | ||||||
|  |   poster: string; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | interface SearchResult { | ||||||
|  |   adult: boolean; | ||||||
|  |   backdrop_path: string; | ||||||
|  |   id: number; | ||||||
|  |   original_title: string; | ||||||
|  |   release_date: Date; | ||||||
|  |   poster_path: string; | ||||||
|  |   popularity: number; | ||||||
|  |   vote_average: number; | ||||||
|  |   vote_counte: number; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | interface Genre { | ||||||
|  |   id: number; | ||||||
|  |   name: string; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export { Movie, Show, Person, Genre } | ||||||
							
								
								
									
										75
									
								
								seasoned_api/src/tmdb/types/credits.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								seasoned_api/src/tmdb/types/credits.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | |||||||
|  | class Credits {  | ||||||
|  |   constructor(id, cast=[], crew=[]) { | ||||||
|  |     this.id = id; | ||||||
|  |     this.cast = cast; | ||||||
|  |     this.crew = crew; | ||||||
|  |     this.type = 'credits'; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static convertFromTmdbResponse(response) { | ||||||
|  |     const { id, cast, crew } = response; | ||||||
|  |  | ||||||
|  |     const allCast = cast.map(cast =>  | ||||||
|  |       new CastMember(cast.character, cast.gender, cast.id, cast.name, cast.profile_path)) | ||||||
|  |     const allCrew = crew.map(crew => | ||||||
|  |       new CrewMember(crew.department, crew.gender, crew.id, crew.job, crew.name, crew.profile_path)) | ||||||
|  |  | ||||||
|  |     return new Credits(id, allCast, allCrew) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   createJsonResponse() { | ||||||
|  |     return { | ||||||
|  |       id: this.id, | ||||||
|  |       cast: this.cast.map(cast => cast.createJsonResponse()), | ||||||
|  |       crew: this.crew.map(crew => crew.createJsonResponse()) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class CastMember { | ||||||
|  |   constructor(character, gender, id, name, profile_path) { | ||||||
|  |     this.character = character; | ||||||
|  |     this.gender = gender; | ||||||
|  |     this.id = id; | ||||||
|  |     this.name = name; | ||||||
|  |     this.profile_path = profile_path; | ||||||
|  |     this.type = 'cast member'; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   createJsonResponse() { | ||||||
|  |     return { | ||||||
|  |       character: this.character, | ||||||
|  |       gender: this.gender, | ||||||
|  |       id: this.id, | ||||||
|  |       name: this.name, | ||||||
|  |       profile_path: this.profile_path, | ||||||
|  |       type: this.type | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class CrewMember { | ||||||
|  |   constructor(department, gender, id, job, name, profile_path) { | ||||||
|  |     this.department = department; | ||||||
|  |     this.gender = gender; | ||||||
|  |     this.id = id; | ||||||
|  |     this.job = job; | ||||||
|  |     this.name = name; | ||||||
|  |     this.profile_path = profile_path; | ||||||
|  |     this.type = 'crew member'; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   createJsonResponse() { | ||||||
|  |     return { | ||||||
|  |       department: this.department, | ||||||
|  |       gender: this.gender, | ||||||
|  |       id: this.id, | ||||||
|  |       job: this.job, | ||||||
|  |       name: this.name, | ||||||
|  |       profile_path: this.profile_path, | ||||||
|  |       type: this.type | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = Credits; | ||||||
| @@ -1,20 +1,62 @@ | |||||||
| class Movie { | class Movie { | ||||||
|   constructor(id, title, year=null, overview=null, poster=null, backdrop=null, rank=null, genres=null, status=null, |   constructor(id, title, year=undefined, overview=undefined, poster=undefined, backdrop=undefined, | ||||||
|               tagline=null, runtime=null, imdb_id=null) { |               releaseDate=undefined, rating=undefined, genres=undefined, productionStatus=undefined, | ||||||
|  |               tagline=undefined, runtime=undefined, imdb_id=undefined, popularity=undefined) { | ||||||
|     this.id = id; |     this.id = id; | ||||||
|     this.title = title; |     this.title = title; | ||||||
|     this.year = year; |     this.year = year; | ||||||
|     this.overview = overview; |     this.overview = overview; | ||||||
|     this.poster = poster; |     this.poster = poster; | ||||||
|     this.backdrop = backdrop; |     this.backdrop = backdrop; | ||||||
|     this.rank = rank; |     this.releaseDate = releaseDate; | ||||||
|  |     this.rating = rating; | ||||||
|     this.genres = genres; |     this.genres = genres; | ||||||
|     this.status = status; |     this.productionStatus = productionStatus; | ||||||
|     this.tagline = tagline; |     this.tagline = tagline; | ||||||
|     this.runtime = runtime; |     this.runtime = runtime; | ||||||
|     this.imdb_id = imdb_id; |     this.imdb_id = imdb_id; | ||||||
|  |     this.popularity = popularity; | ||||||
|     this.type = 'movie'; |     this.type = 'movie'; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static convertFromTmdbResponse(response) { | ||||||
|  |     const { id, title, release_date, overview, poster_path, backdrop_path, vote_average, genres, status, | ||||||
|  |             tagline, runtime, imdb_id, popularity } = response; | ||||||
|  |  | ||||||
|  |     const releaseDate = new Date(release_date); | ||||||
|  |     const year = releaseDate.getFullYear(); | ||||||
|  |     const genreNames = genres ? genres.map(g => g.name) : undefined | ||||||
|  |  | ||||||
|  |     return new Movie(id, title, year, overview, poster_path, backdrop_path, releaseDate, vote_average, genreNames, status, | ||||||
|  |                      tagline, runtime, imdb_id, popularity) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static convertFromPlexResponse(response) { | ||||||
|  |     // console.log('response', response) | ||||||
|  |     const { title, year, rating, tagline, summary } = response; | ||||||
|  |     const _ = undefined | ||||||
|  |  | ||||||
|  |     return new Movie(null, title, year, summary, _, _, _, rating, _, _, tagline) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   createJsonResponse() { | ||||||
|  |     return { | ||||||
|  |       id: this.id, | ||||||
|  |       title: this.title, | ||||||
|  |       year: this.year, | ||||||
|  |       overview: this.overview, | ||||||
|  |       poster: this.poster, | ||||||
|  |       backdrop: this.backdrop, | ||||||
|  |       release_date: this.releaseDate, | ||||||
|  |       rating: this.rating, | ||||||
|  |       genres: this.genres, | ||||||
|  |       production_status: this.productionStatus, | ||||||
|  |       tagline: this.tagline, | ||||||
|  |       runtime: this.runtime, | ||||||
|  |       imdb_id: this.imdb_id, | ||||||
|  |       type: this.type | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = Movie; | module.exports = Movie; | ||||||
|   | |||||||
| @@ -1,13 +1,37 @@ | |||||||
| class Person {  | class Person {  | ||||||
|   constructor(id, name, poster=null, birthday=null, deathday=null, known_for=null) { |   constructor(id, name, poster=undefined, birthday=undefined, deathday=undefined, | ||||||
|  |               adult=undefined, knownForDepartment=undefined) { | ||||||
|     this.id = id; |     this.id = id; | ||||||
|     this.name = name; |     this.name = name; | ||||||
|     this.poster = poster; |     this.poster = poster; | ||||||
|     this.birthday = birthday; |     this.birthday = birthday; | ||||||
|     this.deathday = deathday; |     this.deathday = deathday; | ||||||
|     this.known_for = known_for; |     this.adult = adult; | ||||||
|  |     this.knownForDepartment = knownForDepartment; | ||||||
|     this.type = 'person'; |     this.type = 'person'; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static convertFromTmdbResponse(response) { | ||||||
|  |     const { id, name, poster, birthday, deathday, adult, known_for_department } = response; | ||||||
|  |  | ||||||
|  |     const birthDay = new Date(birthday) | ||||||
|  |     const deathDay = deathday ? new Date(deathday) : null | ||||||
|  |  | ||||||
|  |     return new Person(id, name, poster, birthDay, deathDay, adult, known_for_department) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   createJsonResponse() { | ||||||
|  |     return { | ||||||
|  |       id: this.id, | ||||||
|  |       name: this.name, | ||||||
|  |       poster: this.poster, | ||||||
|  |       birthday: this.birthday, | ||||||
|  |       deathday: this.deathday, | ||||||
|  |       known_for_department: this.knownForDepartment, | ||||||
|  |       adult: this.adult, | ||||||
|  |       type: this.type | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = Person; | module.exports = Person; | ||||||
|   | |||||||
							
								
								
									
										78
									
								
								seasoned_api/src/tmdb/types/releaseDates.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								seasoned_api/src/tmdb/types/releaseDates.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | |||||||
|  | class ReleaseDates {  | ||||||
|  |   constructor(id, releases) { | ||||||
|  |     this.id = id; | ||||||
|  |     this.releases = releases; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static convertFromTmdbResponse(response) { | ||||||
|  |     const { id, results } = response; | ||||||
|  |  | ||||||
|  |     const releases = results.map(countryRelease =>  | ||||||
|  |       new Release( | ||||||
|  |         countryRelease.iso_3166_1,  | ||||||
|  |         countryRelease.release_dates.map(rd => new ReleaseDate(rd.certification, rd.iso_639_1, rd.release_date, rd.type, rd.note)) | ||||||
|  |       )) | ||||||
|  |  | ||||||
|  |     return new ReleaseDates(id, releases) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   createJsonResponse() { | ||||||
|  |     return { | ||||||
|  |       id: this.id, | ||||||
|  |       results: this.releases.map(release => release.createJsonResponse()) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class Release {  | ||||||
|  |   constructor(country, releaseDates) { | ||||||
|  |     this.country = country; | ||||||
|  |     this.releaseDates = releaseDates; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   createJsonResponse() { | ||||||
|  |     return { | ||||||
|  |       country: this.country, | ||||||
|  |       release_dates: this.releaseDates.map(releaseDate => releaseDate.createJsonResponse()) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class ReleaseDate { | ||||||
|  |   constructor(certification, language, releaseDate, type, note) { | ||||||
|  |     this.certification = certification; | ||||||
|  |     this.language = language; | ||||||
|  |     this.releaseDate = releaseDate; | ||||||
|  |     this.type = this.releaseTypeLookup(type); | ||||||
|  |     this.note = note; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   releaseTypeLookup(releaseTypeKey) { | ||||||
|  |     const releaseTypeEnum = { | ||||||
|  |       1: 'Premier', | ||||||
|  |       2: 'Limited theatrical', | ||||||
|  |       3: 'Theatrical', | ||||||
|  |       4: 'Digital', | ||||||
|  |       5: 'Physical', | ||||||
|  |       6: 'TV' | ||||||
|  |     } | ||||||
|  |     if (releaseTypeKey <= Object.keys(releaseTypeEnum).length) { | ||||||
|  |       return releaseTypeEnum[releaseTypeKey] | ||||||
|  |     } else { | ||||||
|  |       // TODO log | Release type not defined, does this need updating? | ||||||
|  |       return null | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   createJsonResponse() { | ||||||
|  |     return { | ||||||
|  |       certification: this.certification, | ||||||
|  |       language: this.language, | ||||||
|  |       release_date: this.releaseDate, | ||||||
|  |       type: this.type, | ||||||
|  |       note: this.note | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = ReleaseDates; | ||||||
| @@ -1,20 +1,50 @@ | |||||||
| class Show { | class Show { | ||||||
|   constructor(id, title, year=null, seasons=null, episodes=null, overview=null, rank=null, genres=null,  |   constructor(id, title, year=undefined, overview=undefined, poster=undefined, backdrop=undefined, | ||||||
|               poster=null, backdrop=null, status=null, runtime=null) {  |               seasons=undefined, episodes=undefined, rank=undefined, genres=undefined, status=undefined, | ||||||
|  |               runtime=undefined) { | ||||||
|     this.id = id; |     this.id = id; | ||||||
|     this.title = title; |     this.title = title; | ||||||
|     this.year = year; |     this.year = year; | ||||||
|     this.seasons = seasons; |  | ||||||
|     this.episodes = episodes; |  | ||||||
|     this.overview = overview; |     this.overview = overview; | ||||||
|     this.rank = rank; |  | ||||||
|     this.genres = genres; |  | ||||||
|     this.poster = poster; |     this.poster = poster; | ||||||
|     this.backdrop = backdrop; |     this.backdrop = backdrop; | ||||||
|     this.status = status; |     this.seasons = seasons; | ||||||
|  |     this.episodes = episodes; | ||||||
|  |     this.rank = rank; | ||||||
|  |     this.genres = genres; | ||||||
|  |     this.productionStatus = status; | ||||||
|     this.runtime = runtime; |     this.runtime = runtime; | ||||||
|     this.type = 'show'; |     this.type = 'show'; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static convertFromTmdbResponse(response) { | ||||||
|  |     const { id, name, first_air_date, overview, poster_path, backdrop_path, number_of_seasons, number_of_episodes, | ||||||
|  |             rank, genres, status, episode_run_time, popularity } = response; | ||||||
|  |  | ||||||
|  |     const year = new Date(first_air_date).getFullYear() | ||||||
|  |     const genreNames = genres ? genres.map(g => g.name) : undefined | ||||||
|  |  | ||||||
|  |     return new Show(id, name, year, overview, poster_path, backdrop_path, number_of_seasons, number_of_episodes, | ||||||
|  |                      rank, genreNames, status, episode_run_time, popularity) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   createJsonResponse() { | ||||||
|  |     return { | ||||||
|  |       id: this.id, | ||||||
|  |       title: this.title, | ||||||
|  |       year: this.year, | ||||||
|  |       overview: this.overview, | ||||||
|  |       poster: this.poster, | ||||||
|  |       backdrop: this.backdrop, | ||||||
|  |       seasons: this.seasons, | ||||||
|  |       episodes: this.episodes, | ||||||
|  |       rank: this.rank, | ||||||
|  |       genres: this.genres, | ||||||
|  |       production_status: this.productionStatus, | ||||||
|  |       runtime: this.runtime, | ||||||
|  |       type: this.type | ||||||
|  |      } | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = Show; | module.exports = Show; | ||||||
|   | |||||||
| @@ -2,36 +2,44 @@ const User = require('src/user/user'); | |||||||
| const jwt = require('jsonwebtoken'); | const jwt = require('jsonwebtoken'); | ||||||
|  |  | ||||||
| class Token { | class Token { | ||||||
|    constructor(user) { |   constructor(user, admin=false) { | ||||||
|       this.user = user; |     this.user = user; | ||||||
|    } |     this.admin = admin; | ||||||
|  |   } | ||||||
|  |  | ||||||
|    /** |   /** | ||||||
|     * Generate a new token. |     * Generate a new token. | ||||||
|     * @param {String} secret a cipher of the token |     * @param {String} secret a cipher of the token | ||||||
|     * @returns {String} |     * @returns {String} | ||||||
|     */ |     */ | ||||||
|    toString(secret) { |   toString(secret) { | ||||||
|       return jwt.sign({ username: this.user.username }, secret); |     const username = this.user.username; | ||||||
|    } |     const admin = this.admin; | ||||||
|  |     let data = { username } | ||||||
|  |  | ||||||
|    /** |     if (admin) | ||||||
|  |       data = { ...data, admin } | ||||||
|  |  | ||||||
|  |     return jwt.sign(data, secret, { expiresIn: '90d' }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|    * Decode a token. |    * Decode a token. | ||||||
|    * @param {Token} jwtToken an encrypted token |    * @param {Token} jwtToken an encrypted token | ||||||
|    * @param {String} secret a cipher of the token |    * @param {String} secret a cipher of the token | ||||||
|    * @returns {Token} |    * @returns {Token} | ||||||
|    */ |    */ | ||||||
|    static fromString(jwtToken, secret) { |   static fromString(jwtToken, secret) { | ||||||
|       let username = null; |     let username = null; | ||||||
|  |  | ||||||
|       try { |     const token = jwt.verify(jwtToken, secret, { clockTolerance: 10000 }) | ||||||
|          username = jwt.verify(jwtToken, secret).username; |     if (token.username === undefined || token.username === null) | ||||||
|       } catch (error) { |       throw new Error('Malformed token') | ||||||
|          throw new Error('The token is invalid.'); |  | ||||||
|       } |     username = token.username | ||||||
|       const user = new User(username); |     const user = new User(username) | ||||||
|       return new Token(user); |     return new Token(user) | ||||||
|    } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = Token; | module.exports = Token; | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ class UserRepository { | |||||||
|             if (error.name === 'AssertionError' || error.message.endsWith('user_name')) { |             if (error.name === 'AssertionError' || error.message.endsWith('user_name')) { | ||||||
|                throw new Error('That username is already registered'); |                throw new Error('That username is already registered'); | ||||||
|             } |             } | ||||||
|  |             throw Error(error) | ||||||
|          }); |          }); | ||||||
|    } |    } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,73 +1,72 @@ | |||||||
| const bcrypt = require('bcrypt-nodejs'); | const bcrypt = require('bcrypt'); | ||||||
| const UserRepository = require('src/user/userRepository'); | const UserRepository = require('src/user/userRepository'); | ||||||
|  |  | ||||||
| class UserSecurity { | class UserSecurity { | ||||||
|    constructor(database) { |   constructor(database) { | ||||||
|       this.userRepository = new UserRepository(database); |   this.userRepository = new UserRepository(database); | ||||||
|    } | } | ||||||
|  |  | ||||||
|    /** |   /** | ||||||
|    * Create a new user in PlanFlix. |    * Create a new user in PlanFlix. | ||||||
|    * @param {User} user the new user you want to create |    * @param {User} user the new user you want to create | ||||||
|    * @param {String} clearPassword a password of the user |    * @param {String} clearPassword a password of the user | ||||||
|    * @returns {Promise} |    * @returns {Promise} | ||||||
|    */ |    */ | ||||||
|    createNewUser(user, clearPassword) { |   createNewUser(user, clearPassword) { | ||||||
|       if (user.username.trim() === '') { |     if (user.username.trim() === '') { | ||||||
|          throw new Error('The username is empty.'); |       throw new Error('The username is empty.'); | ||||||
|       } else if (clearPassword.trim() === '') { |     } else if (clearPassword.trim() === '') { | ||||||
|          throw new Error('The password is empty.'); |       throw new Error('The password is empty.'); | ||||||
|       } else { |     } else { | ||||||
|          return Promise.resolve() |       return Promise.resolve() | ||||||
|             .then(() => this.userRepository.create(user)) |         .then(() => this.userRepository.create(user)) | ||||||
|             .then(() => UserSecurity.hashPassword(clearPassword)) |         .then(() => UserSecurity.hashPassword(clearPassword)) | ||||||
|             .then(hash => this.userRepository.changePassword(user, hash)); |         .then(hash => this.userRepository.changePassword(user, hash)) | ||||||
|       } |     } | ||||||
|    } |   } | ||||||
|  |  | ||||||
|    /** |   /** | ||||||
|    * Login into PlanFlix. |    * Login into PlanFlix. | ||||||
|    * @param {User} user the user you want to login |    * @param {User} user the user you want to login | ||||||
|    * @param {String} clearPassword the user's password |    * @param {String} clearPassword the user's password | ||||||
|    * @returns {Promise} |    * @returns {Promise} | ||||||
|    */ |    */ | ||||||
|    login(user, clearPassword) { |   login(user, clearPassword) { | ||||||
|       return Promise.resolve() |     return Promise.resolve() | ||||||
|          .then(() => this.userRepository.retrieveHash(user)) |       .then(() => this.userRepository.retrieveHash(user)) | ||||||
|          .then(hash => UserSecurity.compareHashes(hash, clearPassword)) |       .then(hash => UserSecurity.compareHashes(hash, clearPassword)) | ||||||
|          .catch(() => { throw new Error('Wrong username or password.'); }); |       .catch(() => { throw new Error('Incorrect username or password.'); }); | ||||||
|    } |   } | ||||||
|  |  | ||||||
|    /** |    /** | ||||||
|    * Compare between a password and a hash password from database. |     * Compare between a password and a hash password from database. | ||||||
|    * @param {String} hash the hash password from database |     * @param {String} hash the hash password from database | ||||||
|    * @param {String} clearPassword the user's password |     * @param {String} clearPassword the user's password | ||||||
|    * @returns {Promise} |     * @returns {Promise} | ||||||
|    */ |     */ | ||||||
|    static compareHashes(hash, clearPassword) { |   static compareHashes(hash, clearPassword) { | ||||||
|       return new Promise((resolve, reject) => { |     return new Promise((resolve, reject) => { | ||||||
|          bcrypt.compare(clearPassword, hash, (error, matches) => { |       bcrypt.compare(clearPassword, hash, (error, match) => { | ||||||
|             if (matches === true) { |         if (match) | ||||||
|                resolve(); |           resolve() | ||||||
|             } else { |         reject() | ||||||
|                reject(); |  | ||||||
|             } |  | ||||||
|          }); |  | ||||||
|       }); |       }); | ||||||
|    } |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|    /** |   /** | ||||||
|    * Hashes a password. |    * Hashes a password. | ||||||
|    * @param {String} clearPassword the user's password |    * @param {String} clearPassword the user's password | ||||||
|    * @returns {Promise} |    * @returns {Promise} | ||||||
|    */ |    */ | ||||||
|    static hashPassword(clearPassword) { |   static hashPassword(clearPassword) { | ||||||
|       return new Promise((resolve) => { |     return new Promise((resolve) => { | ||||||
|          bcrypt.hash(clearPassword, null, null, (error, hash) => { |       const saltRounds = 10; | ||||||
|             resolve(hash); |       bcrypt.hash(clearPassword, saltRounds, (error, hash) => { | ||||||
|          }); |         resolve(hash); | ||||||
|       }); |       }); | ||||||
|    } |     }); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = UserSecurity; | module.exports = UserSecurity; | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| const express = require('express'); | const express = require('express'); | ||||||
|  | // const reload = require('express-reload'); | ||||||
| const Raven = require('raven'); | const Raven = require('raven'); | ||||||
| const bodyParser = require('body-parser'); | const bodyParser = require('body-parser'); | ||||||
| const tokenToUser = require('./middleware/tokenToUser'); | const tokenToUser = require('./middleware/tokenToUser'); | ||||||
| @@ -23,13 +24,11 @@ const allowedOrigins = ['https://kevinmidboe.com', 'http://localhost:8080']; | |||||||
| app.use(bodyParser.urlencoded({ extended: true })); | app.use(bodyParser.urlencoded({ extended: true })); | ||||||
|  |  | ||||||
| /* Decode the Authorization header if provided */ | /* Decode the Authorization header if provided */ | ||||||
| router.use(tokenToUser); | app.use(tokenToUser); | ||||||
|  |  | ||||||
| // TODO: Should have a separate middleware/router for handling headers. | // TODO: Should have a separate middleware/router for handling headers. | ||||||
| router.use((req, res, next) => { | router.use((req, res, next) => { | ||||||
|    // TODO add logging of all incoming |    // TODO add logging of all incoming | ||||||
|    console.log('Request: ', req.originalUrl); |  | ||||||
|  |  | ||||||
|   const origin = req.headers.origin; |   const origin = req.headers.origin; | ||||||
|    if (allowedOrigins.indexOf(origin) > -1) { |    if (allowedOrigins.indexOf(origin) > -1) { | ||||||
|        res.setHeader('Access-Control-Allow-Origin', origin); |        res.setHeader('Access-Control-Allow-Origin', origin); | ||||||
| @@ -50,6 +49,32 @@ app.use(function onError(err, req, res, next) { | |||||||
|    res.end(res.sentry + '\n'); |    res.end(res.sentry + '\n'); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * GraphQL | ||||||
|  |  */ | ||||||
|  | var graphqlHTTP = require('express-graphql'); | ||||||
|  | var { buildSchema } = require('graphql'); | ||||||
|  |  | ||||||
|  | // var schema = buildSchema(` | ||||||
|  | //   type Query { | ||||||
|  | //     hello: String | ||||||
|  | //   }`); | ||||||
|  | const schema = require('./graphql/requests.js'); | ||||||
|  |  | ||||||
|  | const roots = { hello: () => 'Hello world!' }; | ||||||
|  |  | ||||||
|  | app.use('/graphql', graphqlHTTP({ | ||||||
|  |   schema: schema.schema, | ||||||
|  |   graphiql: true | ||||||
|  | })) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * User |  * User | ||||||
|  */ |  */ | ||||||
| @@ -79,9 +104,14 @@ router.get('/v2/show/now_playing', listController.nowPlayingShows); | |||||||
| router.get('/v2/show/popular', listController.popularShows); | router.get('/v2/show/popular', listController.popularShows); | ||||||
| router.get('/v2/show/top_rated', listController.topRatedShows); | router.get('/v2/show/top_rated', listController.topRatedShows); | ||||||
|  |  | ||||||
| router.get('/v2/movie/:id', require('./controllers/info/movieInfo.js')); | router.get('/v2/movie/:id/credits', require('./controllers/movie/credits.js')); | ||||||
| router.get('/v2/show/:id', require('./controllers/info/showInfo.js')); | router.get('/v2/movie/:id/release_dates', require('./controllers/movie/releaseDates.js')); | ||||||
| router.get('/v2/person/:id', require('./controllers/info/personInfo.js')); | router.get('/v2/show/:id/credits', require('./controllers/show/credits.js')); | ||||||
|  |  | ||||||
|  | router.get('/v2/movie/:id', require('./controllers/movie/info.js')); | ||||||
|  | router.get('/v2/show/:id', require('./controllers/show/info.js')); | ||||||
|  | router.get('/v2/person/:id', require('./controllers/person/info.js')); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Plex |  * Plex | ||||||
|  */ |  */ | ||||||
| @@ -113,13 +143,6 @@ router.put('/v1/plex/request/:requestId', mustBeAuthenticated, require('./contro | |||||||
| router.get('/v1/pirate/search', mustBeAuthenticated, require('./controllers/pirate/searchTheBay.js')); | router.get('/v1/pirate/search', mustBeAuthenticated, require('./controllers/pirate/searchTheBay.js')); | ||||||
| router.post('/v1/pirate/add', mustBeAuthenticated, require('./controllers/pirate/addMagnet.js')); | router.post('/v1/pirate/add', mustBeAuthenticated, require('./controllers/pirate/addMagnet.js')); | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * TMDB |  | ||||||
|  */ |  | ||||||
| router.get('/v1/tmdb/search', require('./controllers/tmdb/searchMedia.js')); |  | ||||||
| router.get('/v1/tmdb/list/:listname', require('./controllers/tmdb/listSearch.js')); |  | ||||||
| router.get('/v1/tmdb/:mediaId', require('./controllers/tmdb/readMedia.js')); |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * git |  * git | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -1,30 +0,0 @@ | |||||||
| const configuration = require('src/config/configuration').getInstance(); |  | ||||||
| const Cache = require('src/tmdb/cache'); |  | ||||||
| const TMDB = require('src/tmdb/tmdb'); |  | ||||||
| const Plex = require('src/plex/plex'); |  | ||||||
| const cache = new Cache(); |  | ||||||
| const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); |  | ||||||
| const plex = new Plex(configuration.get('plex', 'ip')); |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Controller: Retrieve information for a movie |  | ||||||
|  * @param {Request} req http request variable |  | ||||||
|  * @param {Response} res |  | ||||||
|  * @returns {Callback} |  | ||||||
|  */ |  | ||||||
| async function movieInfoController(req, res) { |  | ||||||
|   const movieId = req.params.id; |  | ||||||
|   const { credits } = req.query; |  | ||||||
|   const movie = await tmdb.movieInfo(movieId, credits); |  | ||||||
|  |  | ||||||
|   plex.existsInPlex(movie) |  | ||||||
|   .catch((error) => { console.log('Error when searching plex'); }) |  | ||||||
|   .then(() => { |  | ||||||
|     console.log('movie', movie) |  | ||||||
|     res.send(movie); |  | ||||||
|   }).catch((error) => { |  | ||||||
|     res.status(404).send({ success: false, error: error.message }); |  | ||||||
|   }); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| module.exports = movieInfoController; |  | ||||||
| @@ -1,31 +0,0 @@ | |||||||
| const configuration = require('src/config/configuration').getInstance(); |  | ||||||
| const Cache = require('src/tmdb/cache'); |  | ||||||
| const TMDB = require('src/tmdb/tmdb'); |  | ||||||
| const Plex = require('src/plex/plex'); |  | ||||||
| const cache = new Cache(); |  | ||||||
| const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); |  | ||||||
| const plex = new Plex(configuration.get('plex', 'ip')); |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Controller: Retrieve information for a show  |  | ||||||
|  * @param {Request} req http request variable |  | ||||||
|  * @param {Response} res |  | ||||||
|  * @returns {Callback} |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| async function showInfoController(req, res) { |  | ||||||
|   const showId = req.params.id; |  | ||||||
|   const { credits } = req.query; |  | ||||||
|   const show = await tmdb.showInfo(showId, credits); |  | ||||||
|  |  | ||||||
|   plex.existsInPlex(show) |  | ||||||
|   .catch((error) => { console.log('Error when searching plex'); }) |  | ||||||
|   .then(() => { |  | ||||||
|     console.log('show', show) |  | ||||||
|     res.send(show); |  | ||||||
|   }).catch((error) => { |  | ||||||
|     res.status(404).send({ success: false, error: error.message }); |  | ||||||
|   }); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| module.exports = showInfoController; |  | ||||||
| @@ -16,70 +16,55 @@ const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); | |||||||
| // + newly created (tv/latest). | // + newly created (tv/latest). | ||||||
| // + movie/latest | // + movie/latest | ||||||
| // | // | ||||||
|  | function handleError(error, res) { | ||||||
|  |   const { status, message } = error; | ||||||
|  |  | ||||||
| function getTmdbMovieList(res, listname, page) { |   if (status && message) { | ||||||
|   Promise.resolve() |     res.status(status).send({ success: false, message }) | ||||||
|   .then(() => tmdb.movieList(listname, page)) |   } else { | ||||||
|   .then((response) => res.send(response)) |     console.log('caught list controller error', error) | ||||||
|   .catch((error) => { |     res.status(500).send({ message: 'An unexpected error occured while requesting list'}) | ||||||
|     res.status(500).send({ success: false, error: error.message }); |   } | ||||||
|   }) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| function getTmdbShowList(res, listname, page) { | function handleListResponse(response, res) { | ||||||
|   Promise.resolve() |   return res.send(response) | ||||||
|   .then(() => tmdb.showList(listname, page)) |     .catch(error => handleError(error, res)) | ||||||
|   .then((response) => res.send(response)) |  | ||||||
|   .catch((error) => { |  | ||||||
|     res.status(500).send({ success: false, error: error.message }); |  | ||||||
|   }) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| exports.nowPlayingMovies = (req, res) => { | function fetchTmdbList(req, res, listname, type) { | ||||||
|   const { page } = req.query; |   const { page } = req.query; | ||||||
|   const listname = 'miscNowPlayingMovies' |  | ||||||
|  |  | ||||||
|   getTmdbMovieList(res, listname, page); |   if (type === 'movie') { | ||||||
|  |     return tmdb.movieList(listname, page) | ||||||
|  |       .then(listResponse => res.send(listResponse)) | ||||||
|  |       .catch(error => handleError(error, res)) | ||||||
|  |   } else if (type === 'show') { | ||||||
|  |     return tmdb.showList(listname, page) | ||||||
|  |       .then(listResponse => res.send(listResponse)) | ||||||
|  |       .catch(error => handleError(error, res)) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   handleError({ | ||||||
|  |     status: 400, | ||||||
|  |     message: `'${type}' is not a valid list type.` | ||||||
|  |   }, res) | ||||||
| } | } | ||||||
|  |  | ||||||
| exports.popularMovies = (req, res) => { | const nowPlayingMovies = (req, res) => fetchTmdbList(req, res, 'miscNowPlayingMovies', 'movie') | ||||||
|   const { page } = req.query; | const popularMovies = (req, res) => fetchTmdbList(req, res, 'miscPopularMovies', 'movie') | ||||||
|   const listname = 'miscPopularMovies' | const topRatedMovies = (req, res) => fetchTmdbList(req, res, 'miscTopRatedMovies', 'movie') | ||||||
|  | const upcomingMovies = (req, res) => fetchTmdbList(req, res, 'miscUpcomingMovies', 'movie') | ||||||
|  | const nowPlayingShows = (req, res) => fetchTmdbList(req, res, 'tvOnTheAir', 'show') | ||||||
|  | const popularShows = (req, res) => fetchTmdbList(req, res, 'miscPopularTvs', 'show') | ||||||
|  | const topRatedShows = (req, res) => fetchTmdbList(req, res, 'miscTopRatedTvs', 'show') | ||||||
|  |  | ||||||
|   getTmdbMovieList(res, listname, page); | module.exports = { | ||||||
| } |   nowPlayingMovies, | ||||||
|  |   popularMovies, | ||||||
| exports.topRatedMovies = (req, res) => { |   topRatedMovies, | ||||||
|   const { page } = req.query; |   upcomingMovies, | ||||||
|   const listname = 'miscTopRatedMovies' |   nowPlayingShows, | ||||||
|  |   popularShows, | ||||||
|   getTmdbMovieList(res, listname, page); |   topRatedShows | ||||||
| } |  | ||||||
|  |  | ||||||
| exports.upcomingMovies = (req, res) => { |  | ||||||
|   const { page } = req.query; |  | ||||||
|   const listname = 'miscUpcomingMovies' |  | ||||||
|  |  | ||||||
|   getTmdbMovieList(res, listname, page); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| exports.nowPlayingShows = (req, res) => { |  | ||||||
|   const { page } = req.query; |  | ||||||
|   const listname = 'tvOnTheAir' |  | ||||||
|  |  | ||||||
|   getTmdbShowList(res, listname, page); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| exports.popularShows = (req, res) => { |  | ||||||
|   const { page } = req.query; |  | ||||||
|   const listname = 'miscPopularTvs' |  | ||||||
|  |  | ||||||
|   getTmdbShowList(res, listname, page); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| exports.topRatedShows = (req, res) => { |  | ||||||
|   const { page } = req.query; |  | ||||||
|   const listname = 'miscTopRatedTvs' |  | ||||||
|  |  | ||||||
|   getTmdbShowList(res, listname, page); |  | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								seasoned_api/src/webserver/controllers/movie/credits.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								seasoned_api/src/webserver/controllers/movie/credits.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | const configuration = require('src/config/configuration').getInstance(); | ||||||
|  | const Cache = require('src/tmdb/cache'); | ||||||
|  | const TMDB = require('src/tmdb/tmdb'); | ||||||
|  |  | ||||||
|  | const cache = new Cache(); | ||||||
|  | const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); | ||||||
|  |  | ||||||
|  | const movieCreditsController = (req, res) => { | ||||||
|  |   const movieId = req.params.id; | ||||||
|  |  | ||||||
|  |   tmdb.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 { | ||||||
|  |         // TODO log unhandled errors | ||||||
|  |         console.log('caugth movie credits controller error', error) | ||||||
|  |         res.status(500).send({ message: 'An unexpected error occured while requesting movie credits' }) | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = movieCreditsController; | ||||||
							
								
								
									
										58
									
								
								seasoned_api/src/webserver/controllers/movie/info.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								seasoned_api/src/webserver/controllers/movie/info.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | |||||||
|  | const configuration = require('src/config/configuration').getInstance(); | ||||||
|  | const Cache = require('src/tmdb/cache'); | ||||||
|  | const TMDB = require('src/tmdb/tmdb'); | ||||||
|  | const Plex = require('src/plex/plex'); | ||||||
|  | const cache = new Cache(); | ||||||
|  | const tmdb = new TMDB(cache, 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 { | ||||||
|  |     console.log('caught movieinfo controller error', error) | ||||||
|  |     res.status(500).send({ message: 'An unexpected error occured while requesting movie info'}) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Controller: Retrieve information for a movie | ||||||
|  |  * @param {Request} req http request variable | ||||||
|  |  * @param {Response} res | ||||||
|  |  * @returns {Callback} | ||||||
|  |  */ | ||||||
|  | async function movieInfoController(req, res) { | ||||||
|  |   const movieId = req.params.id; | ||||||
|  |   let { credits, release_dates, check_existance } = req.query; | ||||||
|  |  | ||||||
|  |   credits && credits.toLowerCase() === 'true' ? credits = true : credits = false | ||||||
|  |   release_dates && release_dates.toLowerCase() === 'true' ? release_dates = true : release_dates = false | ||||||
|  |   check_existance && check_existance.toLowerCase() === 'true' ? check_existance = true : check_existance = false | ||||||
|  |  | ||||||
|  |   let tmdbQueue = [tmdb.movieInfo(movieId)] | ||||||
|  |   if (credits) | ||||||
|  |     tmdbQueue.push(tmdb.movieCredits(movieId)) | ||||||
|  |   if (release_dates) | ||||||
|  |     tmdbQueue.push(tmdb.movieReleaseDates(movieId)) | ||||||
|  |  | ||||||
|  |   try { | ||||||
|  |     const [ Movie, Credits, ReleaseDates ] = await Promise.all(tmdbQueue) | ||||||
|  |  | ||||||
|  |     const movie = Movie.createJsonResponse() | ||||||
|  |     if (Credits) | ||||||
|  |       movie.credits = Credits.createJsonResponse() | ||||||
|  |     if (ReleaseDates) | ||||||
|  |       movie.release_dates = ReleaseDates.createJsonResponse().results | ||||||
|  |  | ||||||
|  |     if (check_existance) | ||||||
|  |       movie.exists_in_plex = await plex.existsInPlex(movie) | ||||||
|  |    | ||||||
|  |     res.send(movie) | ||||||
|  |   } catch(error) { | ||||||
|  |     handleError(error, res) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = movieInfoController; | ||||||
							
								
								
									
										26
									
								
								seasoned_api/src/webserver/controllers/movie/releaseDates.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								seasoned_api/src/webserver/controllers/movie/releaseDates.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | const configuration = require('src/config/configuration').getInstance(); | ||||||
|  | const Cache = require('src/tmdb/cache'); | ||||||
|  | const TMDB = require('src/tmdb/tmdb'); | ||||||
|  |  | ||||||
|  | const cache = new Cache(); | ||||||
|  | const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); | ||||||
|  |  | ||||||
|  | const movieReleaseDatesController = (req, res) => { | ||||||
|  |   const movieId = req.params.id; | ||||||
|  |  | ||||||
|  |   tmdb.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 { | ||||||
|  |         // TODO log unhandled errors : here our at tmdbReleaseError ? | ||||||
|  |         console.log('caugth release dates controller error', error) | ||||||
|  |         res.status(500).send({ message: 'An unexpected error occured while requesting movie credits' }) | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = movieReleaseDatesController; | ||||||
| @@ -13,11 +13,12 @@ const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); | |||||||
| 
 | 
 | ||||||
| function personInfoController(req, res) { | function personInfoController(req, res) { | ||||||
|   const personId = req.params.id; |   const personId = req.params.id; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|   tmdb.personInfo(personId) |   tmdb.personInfo(personId) | ||||||
|   .then((person) => { |   .then(person => res.send(person.createJsonResponse())) | ||||||
|     res.send(person); |   .catch(error => { | ||||||
|   }).catch((error) => { |     res.status(404).send({ success: false, message: error.message }); | ||||||
|     res.status(404).send({ success: false, error: error.message }); |  | ||||||
|   }); |   }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -17,8 +17,8 @@ function addMagnet(req, res) { | |||||||
|       .then((result) => { |       .then((result) => { | ||||||
|          res.send(result); |          res.send(result); | ||||||
|       }) |       }) | ||||||
|       .catch((error) => { |       .catch(error => { | ||||||
|          res.status(500).send({ success: false, error: error.message }); |          res.status(500).send({ success: false, message: error.message }); | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,8 +21,8 @@ function updateRequested(req, res) { | |||||||
|       .then((result) => { |       .then((result) => { | ||||||
|          res.send({ success: true, results: result }); |          res.send({ success: true, results: result }); | ||||||
|       }) |       }) | ||||||
|       .catch((error) => { |       .catch(error => { | ||||||
|          res.status(401).send({ success: false, error: error.message }); |          res.status(401).send({ success: false, message: error.message }); | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ function fetchRequestedController(req, res) { | |||||||
|          res.send({ success: true, results: requestedItems, total_results: requestedItems.length }); |          res.send({ success: true, results: requestedItems, total_results: requestedItems.length }); | ||||||
|       }) |       }) | ||||||
|       .catch((error) => { |       .catch((error) => { | ||||||
|          res.status(401).send({ success: false, error: error.message }); |          res.status(401).send({ success: false, message: error.message }); | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,11 +5,11 @@ const plexRepository = new PlexRepository(configuration.get('plex', 'ip')); | |||||||
|  |  | ||||||
| function playingController(req, res) { | function playingController(req, res) { | ||||||
|    plexRepository.nowPlaying() |    plexRepository.nowPlaying() | ||||||
|       .then((movies) => { |       .then(movies => { | ||||||
|          res.send(movies); |          res.send(movies); | ||||||
|       }) |       }) | ||||||
|       .catch((error) => { |       .catch(error => { | ||||||
|          res.status(500).send({ success: false, error: error.message }); |          res.status(500).send({ success: false, message: error.message }); | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,10 +12,10 @@ function readRequestController(req, res) { | |||||||
|    const mediaId = req.params.mediaId; |    const mediaId = req.params.mediaId; | ||||||
|    const { type } = req.query; |    const { type } = req.query; | ||||||
|    requestRepository.lookup(mediaId, type) |    requestRepository.lookup(mediaId, type) | ||||||
|       .then((movies) => { |       .then(movies => { | ||||||
|          res.send(movies); |          res.send(movies); | ||||||
|       }).catch((error) => { |       }).catch(error => { | ||||||
|          res.status(404).send({ success: false, error: error.message }); |          res.status(404).send({ success: false, message: error.message }); | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,14 +11,14 @@ const plex = new Plex(configuration.get('plex', 'ip')); | |||||||
| function searchPlexController(req, res) { | function searchPlexController(req, res) { | ||||||
|    const { query, type } = req.query; |    const { query, type } = req.query; | ||||||
|    plex.search(query, type) |    plex.search(query, type) | ||||||
|       .then((movies) => { |       .then(movies => { | ||||||
|          if (movies.length > 0) { |          if (movies.length > 0) { | ||||||
|             res.send(movies); |             res.send(movies); | ||||||
|          } else { |          } else { | ||||||
|             res.status(404).send({ success: false, error: 'Search query did not give any results from plex.'}) |             res.status(404).send({ success: false, message: 'Search query did not give any results from plex.'}) | ||||||
|          } |          } | ||||||
|       }).catch((error) => { |       }).catch(error => { | ||||||
|          res.status(500).send({ success: false, error: error.message }); |          res.status(500).send({ success: false, message: error.message }); | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -14,15 +14,15 @@ function searchMediaController(req, res) { | |||||||
|    const { query } = req.query; |    const { query } = req.query; | ||||||
|  |  | ||||||
|    plexRepository.search(query) |    plexRepository.search(query) | ||||||
|       .then((media) => { |       .then(media => { | ||||||
|          if (media !== undefined || media.length > 0) { |          if (media !== undefined || media.length > 0) { | ||||||
|             res.send(media); |             res.send(media); | ||||||
|          } else { |          } else { | ||||||
|             res.status(404).send({ success: false, error: 'Search query did not return any results.' }); |             res.status(404).send({ success: false, message: 'Search query did not return any results.' }); | ||||||
|          } |          } | ||||||
|       }) |       }) | ||||||
|       .catch((error) => { |       .catch(error => { | ||||||
|          res.status(500).send({ success: false, error: error.message }); |          res.status(500).send({ success: false, message: error.message }); | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,8 +18,8 @@ function searchRequestController(req, res) { | |||||||
|       .then((searchResult) => { |       .then((searchResult) => { | ||||||
|          res.send(searchResult); |          res.send(searchResult); | ||||||
|       }) |       }) | ||||||
|       .catch((error) => { |       .catch(error => { | ||||||
|          res.status(500).send({ success: false, error: error }); |          res.status(500).send({ success: false, message: error.message }); | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ function submitRequestController(req, res) { | |||||||
|     console.log('show') |     console.log('show') | ||||||
|     mediaFunction = tmdbShowInfo |     mediaFunction = tmdbShowInfo | ||||||
|   } else { |   } else { | ||||||
|     res.status(422).send({ success: false, error: 'Incorrect type. Allowed types: "movie" or "show"'}) |     res.status(422).send({ success: false, message: 'Incorrect type. Allowed types: "movie" or "show"'}) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (mediaFunction === undefined) { res.status(200); return } |   if (mediaFunction === undefined) { res.status(200); return } | ||||||
| @@ -45,7 +45,7 @@ function submitRequestController(req, res) { | |||||||
|   mediaFunction(id) |   mediaFunction(id) | ||||||
|     .then(tmdbMedia => request.requestFromTmdb(tmdbMedia, ip, user_agent, user)) |     .then(tmdbMedia => request.requestFromTmdb(tmdbMedia, ip, user_agent, user)) | ||||||
|     .then(() => res.send({ success: true, message: 'Media item successfully requested' })) |     .then(() => res.send({ success: true, message: 'Media item successfully requested' })) | ||||||
|     .catch(err => res.status(500).send({ success: false, error: err.message })) |     .catch(err => res.status(500).send({ success: false, message: err.message })) | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = submitRequestController; | module.exports = submitRequestController; | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ function updateRequested(req, res) { | |||||||
|          res.send({ success: true }); |          res.send({ success: true }); | ||||||
|       }) |       }) | ||||||
|       .catch((error) => { |       .catch((error) => { | ||||||
|          res.status(401).send({ success: false, error: error.message }); |          res.status(401).send({ success: false, message: error.message }); | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,9 +18,9 @@ function fetchAllRequests(req, res) { | |||||||
|  |  | ||||||
|   Promise.resolve() |   Promise.resolve() | ||||||
|   .then(() => request.fetchAll(page, sort_by, sort_direction, filter, query)) |   .then(() => request.fetchAll(page, sort_by, sort_direction, filter, query)) | ||||||
|   .then((result) => res.send(result)) |   .then(result => res.send(result)) | ||||||
|   .catch((error) => { |   .catch(error => { | ||||||
|     res.status(404).send({ success: false, error: error.message }); |     res.status(404).send({ success: false, message: error.message }); | ||||||
|   }); |   }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,11 +11,10 @@ function fetchAllRequests(req, res) { | |||||||
|   const id = req.params.id; |   const id = req.params.id; | ||||||
|   const { type } = req.query; |   const { type } = req.query; | ||||||
|  |  | ||||||
|   Promise.resolve() |   request.getRequestByIdAndType(id, type) | ||||||
|     .then(() => request.getRequestByIdAndType(id, type)) |     .then(result => res.send(result)) | ||||||
|     .then((result) => res.send(result)) |     .catch(error => { | ||||||
|     .catch((error) => { |       res.status(404).send({ success: false, message: error.message }); | ||||||
|       res.status(404).send({ success: false, error: error.message }); |  | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -22,30 +22,31 @@ const tmdbShowInfo = (id) => { | |||||||
|  */ |  */ | ||||||
| function requestTmdbIdController(req, res) { | function requestTmdbIdController(req, res) { | ||||||
|   const { id, type } = req.body |   const { id, type } = req.body | ||||||
|   console.log('body', req.body) |  | ||||||
|   console.log('id & type', id, type) |  | ||||||
|  |  | ||||||
|   const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; |   const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; | ||||||
|   const user_agent = req.headers['user-agent']; |   const user_agent = req.headers['user-agent']; | ||||||
|   const user = req.loggedInUser; |   const user = req.loggedInUser; | ||||||
|  |  | ||||||
|   let mediaFunction = undefined |   let mediaFunction = undefined | ||||||
|  |  | ||||||
|  |   if (id === undefined || type === undefined) { | ||||||
|  |     res.status(422).send({ success: false, message: "'Missing parameteres: 'id' and/or 'type'"}) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   if (type === 'movie') { |   if (type === 'movie') { | ||||||
|     console.log('movie') |  | ||||||
|     mediaFunction = tmdbMovieInfo |     mediaFunction = tmdbMovieInfo | ||||||
|   } else if (type === 'show') { |   } else if (type === 'show') { | ||||||
|     console.log('show') |  | ||||||
|     mediaFunction = tmdbShowInfo |     mediaFunction = tmdbShowInfo | ||||||
|   } else { |   } else { | ||||||
|     res.status(422).send({ success: false, error: 'Incorrect type. Allowed types: "movie" or "show"'}) |     res.status(422).send({ success: false, message: 'Incorrect type. Allowed types: "movie" or "show"'}) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   mediaFunction(id) |   mediaFunction(id) | ||||||
|     .catch((error) => { console.error(error); res.status(404).send({ success: false, error: 'Id not found' }) }) |     // .catch((error) => { console.error(error); res.status(404).send({ success: false, error: 'Id not found' }) }) | ||||||
|     .then((tmdbMedia) => request.requestFromTmdb(tmdbMedia, ip, user_agent, user)) |     .then(tmdbMedia => request.requestFromTmdb(tmdbMedia, ip, user_agent, user)) | ||||||
|     .then(() => res.send({success: true, message: 'Request has been submitted.'})) |     .then(() => res.send({success: true, message: 'Request has been submitted.'})) | ||||||
|     .catch((error) => { |     .catch(error => { | ||||||
|       res.status(501).send({ success: false, error: error.message }); |       res.send({ success: false, message: error.message }); | ||||||
|     }) |     }) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| 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 Cache = require('src/tmdb/cache'); | ||||||
| const TMDB = require('src/tmdb/tmdb'); | const TMDB = require('src/tmdb/tmdb'); | ||||||
|  | const SearchHistory = require('src/searchHistory/searchHistory'); | ||||||
| const cache = new Cache(); | const cache = new Cache(); | ||||||
| const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); | const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); | ||||||
| const searchHistory = new SearchHistory(); | const searchHistory = new SearchHistory(); | ||||||
| @@ -16,20 +16,25 @@ function movieSearchController(req, res) { | |||||||
|   const user = req.loggedInUser; |   const user = req.loggedInUser; | ||||||
|   const { query, page } = req.query; |   const { query, page } = req.query; | ||||||
|  |  | ||||||
|   Promise.resolve() |   if (user) { | ||||||
|   .then(() => { |     return searchHistory.create(user, query); | ||||||
|     if (user) { |   } | ||||||
|       return searchHistory.create(user, query); |  | ||||||
|     } |   tmdb.movieSearch(query, page) | ||||||
|     return null |     .then(movieSearchResults => res.send(movieSearchResults)) | ||||||
|   }) |     .catch(error => { | ||||||
|   .then(() => tmdb.movieSearch(query, page)) |       const { status, message } = error; | ||||||
|   .then((movies) => { |  | ||||||
|     res.send(movies); |       if (status && message) { | ||||||
|   }) |         res.status(status).send({ success: false, message }) | ||||||
|   .catch((error) => { |       } else { | ||||||
|     res.status(500).send({ success: false, error: error.message }); |         // TODO log unhandled errors | ||||||
|   }); |         console.log('caugth movie search controller error', error) | ||||||
|  |         res.status(500).send({ | ||||||
|  |           message: `An unexpected error occured while searching movies with query: ${query}` | ||||||
|  |         }) | ||||||
|  |       } | ||||||
|  |     }) | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = movieSearchController; | module.exports = movieSearchController; | ||||||
|   | |||||||
| @@ -1,11 +1,18 @@ | |||||||
| 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 Cache = require('src/tmdb/cache'); | ||||||
| const TMDB = require('src/tmdb/tmdb'); | const TMDB = require('src/tmdb/tmdb'); | ||||||
|  | const SearchHistory = require('src/searchHistory/searchHistory'); | ||||||
| const cache = new Cache(); | const cache = new Cache(); | ||||||
| const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); | const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); | ||||||
| const searchHistory = new SearchHistory(); | const searchHistory = new SearchHistory(); | ||||||
|  |  | ||||||
|  | function checkAndCreateJsonResponse(result) { | ||||||
|  |   if (typeof result['createJsonResponse'] === 'function') { | ||||||
|  |     return result.createJsonResponse() | ||||||
|  |   } | ||||||
|  |   return result | ||||||
|  | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Controller: Search for multi (movies, shows and people by query and pagey |  * Controller: Search for multi (movies, shows and people by query and pagey | ||||||
|  * @param {Request} req http request variable |  * @param {Request} req http request variable | ||||||
| @@ -16,20 +23,23 @@ function multiSearchController(req, res) { | |||||||
|   const user = req.loggedInUser; |   const user = req.loggedInUser; | ||||||
|   const { query, page } = req.query; |   const { query, page } = req.query; | ||||||
|  |  | ||||||
|   Promise.resolve() |   if (user) { | ||||||
|   .then(() => { |     searchHistory.create(user, query) | ||||||
|     if (user) { |   } | ||||||
|       return searchHistory.create(user, query); |  | ||||||
|  |   return tmdb.multiSearch(query, page) | ||||||
|  |   .then(multiSearchResults => res.send(multiSearchResults)) | ||||||
|  |   .catch(error => { | ||||||
|  |     const { status, message } = error; | ||||||
|  |  | ||||||
|  |     if (status && message) { | ||||||
|  |       res.status(status).send({ success: false, message }) | ||||||
|  |     } else { | ||||||
|  |       // TODO log unhandled errors | ||||||
|  |       console.log('caugth multi search controller error', error) | ||||||
|  |       res.status(500).send({ message: `An unexpected error occured while searching with query: ${query}` }) | ||||||
|     } |     } | ||||||
|     return null |  | ||||||
|   }) |   }) | ||||||
|   .then(() => tmdb.multiSearch(query, page)) |  | ||||||
|   .then((result) => { |  | ||||||
|     res.send(result); |  | ||||||
|   }) |  | ||||||
|   .catch((error) => { |  | ||||||
|     res.status(500).send({ success: false, error: error.message }); |  | ||||||
|   }); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = multiSearchController; | module.exports = multiSearchController; | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| 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 Cache = require('src/tmdb/cache'); | ||||||
| const TMDB = require('src/tmdb/tmdb'); | const TMDB = require('src/tmdb/tmdb'); | ||||||
|  | const SearchHistory = require('src/searchHistory/searchHistory'); | ||||||
| const cache = new Cache(); | const cache = new Cache(); | ||||||
| const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); | const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); | ||||||
| const searchHistory = new SearchHistory(); | const searchHistory = new SearchHistory(); | ||||||
| @@ -16,20 +16,27 @@ function personSearchController(req, res) { | |||||||
|   const user = req.loggedInUser; |   const user = req.loggedInUser; | ||||||
|   const { query, page } = req.query; |   const { query, page } = req.query; | ||||||
|  |  | ||||||
|   Promise.resolve() |   if (user) { | ||||||
|   .then(() => { |     return searchHistory.create(user, query); | ||||||
|     if (user) { |   } | ||||||
|       return searchHistory.create(user, query); |    | ||||||
|     } |   tmdb.personSearch(query, page) | ||||||
|     return null |     .then((person) => { | ||||||
|   }) |       res.send(person); | ||||||
|   .then(() => tmdb.personSearch(query, page)) |     }) | ||||||
|   .then((person) => { |     .catch(error => { | ||||||
|     res.send(person); |       const { status, message } = error; | ||||||
|   }) |  | ||||||
|   .catch((error) => { |       if (status && message) { | ||||||
|     res.status(500).send({ success: false, error: error.message }); |         res.status(status).send({ success: false, message }) | ||||||
|   }); |       } else { | ||||||
|  |         // TODO log unhandled errors | ||||||
|  |         console.log('caugth person search controller error', error) | ||||||
|  |         res.status(500).send({ | ||||||
|  |           message: `An unexpected error occured while searching people with query: ${query}` | ||||||
|  |         }) | ||||||
|  |       } | ||||||
|  |     }) | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = personSearchController; | module.exports = personSearchController; | ||||||
|   | |||||||
| @@ -27,8 +27,8 @@ function showSearchController(req, res) { | |||||||
|   .then((shows) => { |   .then((shows) => { | ||||||
|     res.send(shows); |     res.send(shows); | ||||||
|   }) |   }) | ||||||
|   .catch((error) => { |   .catch(error => { | ||||||
|     res.status(500).send({ success: false, error: error.message }); |     res.status(500).send({ success: false, message: error.message }); | ||||||
|   }); |   }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ function readStraysController(req, res) { | |||||||
|          res.send(strays); |          res.send(strays); | ||||||
|       }) |       }) | ||||||
|       .catch((error) => { |       .catch((error) => { | ||||||
|          res.status(500).send({ success: false, error: error.message }); |          res.status(500).send({ success: false, message: error.message }); | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ function strayByIdController(req, res) { | |||||||
|          res.send(stray); |          res.send(stray); | ||||||
|       }) |       }) | ||||||
|       .catch((error) => { |       .catch((error) => { | ||||||
|          res.status(500).send({ success: false, error: error.message }); |          res.status(500).send({ success: false, message: error.message }); | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ function verifyStrayController(req, res) { | |||||||
|          res.send({ success: true, message: 'Episode verified' }); |          res.send({ success: true, message: 'Episode verified' }); | ||||||
|       }) |       }) | ||||||
|       .catch((error) => { |       .catch((error) => { | ||||||
|          res.status(500).send({ success: false, error: error.message }); |          res.status(500).send({ success: false, message: error.message }); | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								seasoned_api/src/webserver/controllers/show/credits.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								seasoned_api/src/webserver/controllers/show/credits.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | const configuration = require('src/config/configuration').getInstance(); | ||||||
|  | const Cache = require('src/tmdb/cache'); | ||||||
|  | const TMDB = require('src/tmdb/tmdb'); | ||||||
|  |  | ||||||
|  | const cache = new Cache(); | ||||||
|  | const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); | ||||||
|  |  | ||||||
|  | const showCreditsController = (req, res) => { | ||||||
|  |   const showId = req.params.id; | ||||||
|  |  | ||||||
|  |   tmdb.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 { | ||||||
|  |         // TODO log unhandled errors | ||||||
|  |         console.log('caugth show credits controller error', error) | ||||||
|  |         res.status(500).send({ message: 'An unexpected error occured while requesting show credits' }) | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = showCreditsController; | ||||||
							
								
								
									
										56
									
								
								seasoned_api/src/webserver/controllers/show/info.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								seasoned_api/src/webserver/controllers/show/info.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | |||||||
|  | const configuration = require('src/config/configuration').getInstance(); | ||||||
|  | const Cache = require('src/tmdb/cache'); | ||||||
|  | const TMDB = require('src/tmdb/tmdb'); | ||||||
|  | const Plex = require('src/plex/plex'); | ||||||
|  | const cache = new Cache(); | ||||||
|  | const tmdb = new TMDB(cache, 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 { | ||||||
|  |     console.log('caught showinfo controller error', error) | ||||||
|  |     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 | ||||||
|  |  * @param {Response} res | ||||||
|  |  * @returns {Callback} | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | async function showInfoController(req, res) { | ||||||
|  |   const showId = req.params.id; | ||||||
|  |   let { credits, check_existance } = req.query; | ||||||
|  |  | ||||||
|  |   credits && credits.toLowerCase() === 'true' ? credits = true : credits = false | ||||||
|  |   check_existance && check_existance.toLowerCase() === 'true' ? check_existance = true : check_existance = false | ||||||
|  |  | ||||||
|  |   let tmdbQueue = [tmdb.showInfo(showId)] | ||||||
|  |   if (credits) | ||||||
|  |     tmdbQueue.push(tmdb.showCredits(showId)) | ||||||
|  |  | ||||||
|  |   try { | ||||||
|  |     const [Show, Credits] = await Promise.all(tmdbQueue) | ||||||
|  |  | ||||||
|  |     const show = Show.createJsonResponse() | ||||||
|  |     if (credits) | ||||||
|  |       show.credits = Credits.createJsonResponse() | ||||||
|  |  | ||||||
|  |     if (check_existance) | ||||||
|  |       show.exists_in_plex = await plex.existsInPlex(show) | ||||||
|  |  | ||||||
|  |     res.send(show) | ||||||
|  |   } catch(error) { | ||||||
|  |     handleError(error, res) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = showInfoController; | ||||||
| @@ -1,25 +0,0 @@ | |||||||
| const configuration = require('src/config/configuration').getInstance(); |  | ||||||
| const Cache = require('src/tmdb/cache'); |  | ||||||
| const TMDB = require('src/tmdb/tmdb'); |  | ||||||
|  |  | ||||||
| const cache = new Cache(); |  | ||||||
| const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Controller: Retrieve nowplaying movies / now airing shows |  | ||||||
|  * @param {Request} req http request variable |  | ||||||
|  * @param {Response} res |  | ||||||
|  * @returns {Callback} |  | ||||||
|  */ |  | ||||||
| function listSearchController(req, res) { |  | ||||||
|    const listname = req.params.listname; |  | ||||||
|    const { type, page } = req.query; |  | ||||||
|    tmdb.listSearch(listname, type, page) |  | ||||||
|       .then((results) => { |  | ||||||
|          res.send(results); |  | ||||||
|       }).catch((error) => { |  | ||||||
|          res.status(404).send({ success: false, error: error.message }); |  | ||||||
|       }); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| module.exports = listSearchController; |  | ||||||
| @@ -1,25 +0,0 @@ | |||||||
| const configuration = require('src/config/configuration').getInstance(); |  | ||||||
| const Cache = require('src/tmdb/cache'); |  | ||||||
| const TMDB = require('src/tmdb/tmdb'); |  | ||||||
|  |  | ||||||
| const cache = new Cache(); |  | ||||||
| const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Controller: Retrieve information for a movie |  | ||||||
|  * @param {Request} req http request variable |  | ||||||
|  * @param {Response} res |  | ||||||
|  * @returns {Callback} |  | ||||||
|  */ |  | ||||||
| function readMediaController(req, res) { |  | ||||||
|    const mediaId = req.params.mediaId; |  | ||||||
|    const { type } = req.query; |  | ||||||
|    tmdb.lookup(mediaId, type) |  | ||||||
|       .then((movies) => { |  | ||||||
|          res.send(movies); |  | ||||||
|       }).catch((error) => { |  | ||||||
|          res.status(404).send({ success: false, error: error.message }); |  | ||||||
|       }); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| module.exports = readMediaController; |  | ||||||
| @@ -1,31 +0,0 @@ | |||||||
| const configuration = require('src/config/configuration').getInstance(); |  | ||||||
| const Cache = require('src/tmdb/cache'); |  | ||||||
| const TMDB = require('src/tmdb/tmdb'); |  | ||||||
|  |  | ||||||
| const cache = new Cache(); |  | ||||||
| const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Controller: Search for movies by query, page and optional type |  | ||||||
|  * @param {Request} req http request variable |  | ||||||
|  * @param {Response} res |  | ||||||
|  * @returns {Callback} |  | ||||||
|  */ |  | ||||||
| function searchMediaController(req, res) { |  | ||||||
|    const { query, page, type } = req.query; |  | ||||||
|  |  | ||||||
|    Promise.resolve() |  | ||||||
|       .then(() => tmdb.search(query, page, type)) |  | ||||||
|       .then((movies) => { |  | ||||||
|          if (movies !== undefined || movies.length > 0) { |  | ||||||
|             res.send(movies); |  | ||||||
|          } else { |  | ||||||
|             res.status(404).send({ success: false, error: 'Search query did not return any results.' }); |  | ||||||
|          } |  | ||||||
|       }) |  | ||||||
|       .catch((error) => { |  | ||||||
|          res.status(500).send({ success: false, error: error.message }); |  | ||||||
|       }); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| module.exports = searchMediaController; |  | ||||||
| @@ -13,11 +13,11 @@ function historyController(req, res) { | |||||||
|    const username = user === undefined ? undefined : user.username; |    const username = user === undefined ? undefined : user.username; | ||||||
|  |  | ||||||
|    searchHistory.read(username) |    searchHistory.read(username) | ||||||
|       .then((searchQueries) => { |       .then(searchQueries => { | ||||||
|          res.send({ success: true, searchQueries }); |          res.send({ success: true, searchQueries }); | ||||||
|       }) |       }) | ||||||
|       .catch((error) => { |       .catch(error => { | ||||||
|          res.status(404).send({ success: false, error: error }); |          res.status(404).send({ success: false, message: error.message }); | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -20,13 +20,13 @@ function loginController(req, res) { | |||||||
|  |  | ||||||
|    userSecurity.login(user, password) |    userSecurity.login(user, password) | ||||||
|       .then(() => userRepository.checkAdmin(user)) |       .then(() => userRepository.checkAdmin(user)) | ||||||
|       .then((checkAdmin) => { |       .then(checkAdmin => { | ||||||
|          const token = new Token(user).toString(secret); |          const isAdmin = checkAdmin === 1 ? true : false; | ||||||
|          const admin_state = checkAdmin === 1 ? true : false; |          const token = new Token(user, isAdmin).toString(secret); | ||||||
|          res.send({ success: true, token, admin: admin_state }); |          res.send({ success: true, token }); | ||||||
|       }) |       }) | ||||||
|       .catch((error) => { |       .catch(error => { | ||||||
|          res.status(401).send({ success: false, error: error.message }); |          res.status(401).send({ success: false, message: error.message }); | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -20,15 +20,15 @@ function registerController(req, res) { | |||||||
|  |  | ||||||
|    userSecurity.createNewUser(user, password) |    userSecurity.createNewUser(user, password) | ||||||
|       .then(() => userRepository.checkAdmin(user)) |       .then(() => userRepository.checkAdmin(user)) | ||||||
|       .then((checkAdmin) => { |       .then(checkAdmin => { | ||||||
|          const token = new Token(user).toString(secret); |          const isAdmin = checkAdmin === 1 ? true : false; | ||||||
|          const admin_state = checkAdmin === 1 ? true : false; |          const token = new Token(user, isAdmin).toString(secret); | ||||||
|          res.send({ |          res.send({ | ||||||
|             success: true, message: 'Welcome to Seasoned!', token, admin: admin_state, |             success: true, message: 'Welcome to Seasoned!', token | ||||||
|          }); |          }); | ||||||
|       }) |       }) | ||||||
|       .catch((error) => { |       .catch(error => { | ||||||
|          res.status(401).send({ success: false, error: error.message }); |          res.status(401).send({ success: false, message: error.message }); | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,12 +12,11 @@ function requestsController(req, res) { | |||||||
|    const user = req.loggedInUser; |    const user = req.loggedInUser; | ||||||
|  |  | ||||||
|    requestRepository.userRequests(user) |    requestRepository.userRequests(user) | ||||||
|       .then((requests) => { |       .then(requests => { | ||||||
|          res.send({ success: true, results: requests, total_results: requests.length }); |          res.send({ success: true, results: requests, total_results: requests.length }); | ||||||
|       }) |       }) | ||||||
|       .catch((error) => { |       .catch(error => { | ||||||
|          console.log(error) |          res.status(500).send({ success: false, message: error.message }); | ||||||
|          res.status(500).send({ success: false, error: error }); |  | ||||||
|       }); |       }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										294
									
								
								seasoned_api/src/webserver/graphql/requests.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										294
									
								
								seasoned_api/src/webserver/graphql/requests.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,294 @@ | |||||||
|  | const graphql = require("graphql"); | ||||||
|  | const establishedDatabase = require('src/database/database'); | ||||||
|  | const fetch = require('node-fetch'); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | const TorrentType = new graphql.GraphQLObjectType({ | ||||||
|  |   name: "Torrent", | ||||||
|  |   fields: { | ||||||
|  |     magnet: { type: graphql.GraphQLString }, | ||||||
|  |     torrent_name: { type: graphql.GraphQLString}, | ||||||
|  |     tmdb_id: { type: graphql.GraphQLString } | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | const RequestType = new graphql.GraphQLObjectType({ | ||||||
|  |   name: "Request", | ||||||
|  |   fields: { | ||||||
|  |     id: { type: graphql.GraphQLID }, | ||||||
|  |     title: { type: graphql.GraphQLString }, | ||||||
|  |     year: { type: graphql.GraphQLInt}, | ||||||
|  |     poster_path: { type: graphql.GraphQLString }, | ||||||
|  |     background_path: { type: graphql.GraphQLString }, | ||||||
|  |     requested_by: { type: graphql.GraphQLString }, | ||||||
|  |     ip: { type: graphql.GraphQLString }, | ||||||
|  |     date: { type: graphql.GraphQLString }, | ||||||
|  |     status: { type: graphql.GraphQLString }, | ||||||
|  |     user_agent: { type: graphql.GraphQLString }, | ||||||
|  |     type: { type: graphql.GraphQLString } | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | const RequestsType = new graphql.GraphQLObjectType({ | ||||||
|  |   name: 'Requests', | ||||||
|  |   type: graphql.GraphQLList(RequestType), | ||||||
|  |   resolve: (root, args, context, info) => { | ||||||
|  |     return establishedDatabase.all("SELECT * FROM requests;") | ||||||
|  |       .catch(error => console.error("something went wrong fetching 'all' query. Error:", error)) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | const ProgressType = new graphql.GraphQLObjectType({ | ||||||
|  |   name: 'TorrentProgress', | ||||||
|  |   fields: { | ||||||
|  |     eta: { type: graphql.GraphQLInt }, | ||||||
|  |     finished: { type: graphql.GraphQLBoolean }, | ||||||
|  |     key: { type: graphql.GraphQLString }, | ||||||
|  |     name: { type: graphql.GraphQLString }, | ||||||
|  |     progress: { type: graphql.GraphQLFloat }, | ||||||
|  |     state: { type: graphql.GraphQLString }, | ||||||
|  |     Torrent: { | ||||||
|  |       type: TorrentType, | ||||||
|  |       resolve(parent) { | ||||||
|  |         console.log('prante: ', parent.name) | ||||||
|  |         console.log(parent.name.slice(0,10)) | ||||||
|  |         return establishedDatabase.get(`select magnet, torrent_name, tmdb_id from requested_torrent where torrent_name like (?);`, [parent.name.slice(0, 10) + '%']) | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     Requested: { | ||||||
|  |       type: graphql.GraphQLList(RequestType), | ||||||
|  |       // resolve: () => fetch('https://api.kevinmidboe.com/api/v2/request?page=1/').then(resp => resp.json()) | ||||||
|  |       // .then(data => { | ||||||
|  |       //   // console.log('data', data) | ||||||
|  |       //   return data.results | ||||||
|  |       // }) | ||||||
|  |       resolve: (parent) => { | ||||||
|  |         return establishedDatabase.all("SELECT * FROM requests;") | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | const TorrentsRequestedType = new graphql.GraphQLObjectType({ | ||||||
|  |   name: 'TorrentsRequested', | ||||||
|  |   fields: { | ||||||
|  |     magnet: { type: graphql.GraphQLString }, | ||||||
|  |     torrent_name: { type: graphql.GraphQLString }, | ||||||
|  |     tmdb_id: { type: graphql.GraphQLString }, | ||||||
|  |     date_added: { type: graphql.GraphQLString }, | ||||||
|  |     Request: { | ||||||
|  |       type: RequestType, | ||||||
|  |       // resolve: () => fetch('https://api.kevinmidboe.com/api/v2/request?page=1/').then(resp => resp.json()) | ||||||
|  |       // .then(data => { | ||||||
|  |       //   return data.results | ||||||
|  |       // }) | ||||||
|  |       resolve(parentValue, args) { | ||||||
|  |         return establishedDatabase.get('select * from requests where id = (?);', [parentValue.tmdb_id]) | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     Progress: { | ||||||
|  |       type: ProgressType, | ||||||
|  |       resolve(parentValue, args) { | ||||||
|  |         return fetch('http://localhost:5000/') | ||||||
|  |           .then(resp => resp.json()) | ||||||
|  |           // .then(data => { console.log('data', data); return data.filter(download => download.name === parentValue.torrent_name) }) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // create a graphql query to select all and by id | ||||||
|  | var queryType = new graphql.GraphQLObjectType({ | ||||||
|  |     name: 'Query', | ||||||
|  |     fields: { | ||||||
|  |         //first query to select all | ||||||
|  |         Requests: { | ||||||
|  |             type: graphql.GraphQLList(RequestType), | ||||||
|  |             resolve: (root, args, context, info) => { | ||||||
|  |                 return establishedDatabase.all("SELECT * FROM requests;") | ||||||
|  |                   .catch(error => console.error("something went wrong fetching 'all' query. Error:", error)) | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         Progress: { | ||||||
|  |           type: graphql.GraphQLList(ProgressType), | ||||||
|  |           resolve: (root, args, context, info) => { | ||||||
|  |             console.log('user', context.loggedInUser) | ||||||
|  |             return fetch('http://localhost:5000') | ||||||
|  |               .then(resp => resp.json()) | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         ProgressRequested: { | ||||||
|  |           type: graphql.GraphQLList(ProgressType), | ||||||
|  |           resolve: (root, args, context, info) => { | ||||||
|  |             console.log('root & args', root, args) | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         TorrentsRequested: { | ||||||
|  |           type: graphql.GraphQLList(TorrentsRequestedType), | ||||||
|  |           resolve: (root, args, context, info) => { | ||||||
|  |             return establishedDatabase.all("SELECT * FROM requested_torrent;") | ||||||
|  |               .then(data => data.filter(request => { if (request.tmdb_id === '83666') { console.log('request', request, root);}; return request })) | ||||||
|  |               .catch(error => console.error("something went wrong fetching 'all' query. Error:", error)) | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         DownloadingRequestByName: { | ||||||
|  |           type: RequestType, | ||||||
|  |           args:{ | ||||||
|  |             name:{ | ||||||
|  |               type: new graphql.GraphQLNonNull(graphql.GraphQLString) | ||||||
|  |             }                | ||||||
|  |           }, | ||||||
|  |           resolve: (root, { name }, context, info) => { | ||||||
|  |             return establishedDatabase.all("SELECT * FROM requests where requested_by = (?);", [name]) | ||||||
|  |               .catch(error => console.error("something went wrong fetching 'all' query. Error:", error)) | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         //second query to select by id | ||||||
|  |         Request:{ | ||||||
|  |             type: RequestType, | ||||||
|  |             args:{ | ||||||
|  |                 id:{ | ||||||
|  |                     type: new graphql.GraphQLNonNull(graphql.GraphQLID) | ||||||
|  |                 }                | ||||||
|  |             }, | ||||||
|  |             resolve: (root, {id}, context, info) => { | ||||||
|  |               return establishedDatabase.get("SELECT * FROM requests WHERE id = (?);",[id]) | ||||||
|  |                 .catch(error => console.error(`something went wrong fetching by id: '${ id }'. Error: ${ error }`)) | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         Torrents: { | ||||||
|  |           type: graphql.GraphQLList(TorrentType), | ||||||
|  |           resolve: (root, {id}, context, info) => { | ||||||
|  |             // console.log('parent', parent) | ||||||
|  |             return establishedDatabase.all("SELECT * FROM requested_torrent") | ||||||
|  |               .catch(error => console.error(`something went wrong fetching all torrents. Error: ${ error }`)) | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         Torrent: { | ||||||
|  |           type: TorrentType, | ||||||
|  |           args: { | ||||||
|  |             id: { | ||||||
|  |               type: new graphql.GraphQLNonNull(graphql.GraphQLID) | ||||||
|  |             } | ||||||
|  |           }, | ||||||
|  |           resolve: (parent, {id}, context, info) => { | ||||||
|  |             // console.log('searcing from parent', parent) | ||||||
|  |             return establishedDatabase.get("SELECT * FROM requested_torrent WHERE tmdb_id = (?);", [id]) | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | }); | ||||||
|  | //mutation type is a type of object to modify data (INSERT,DELETE,UPDATE) | ||||||
|  | // var mutationType = new graphql.GraphQLObjectType({ | ||||||
|  | //     name: 'Mutation', | ||||||
|  | //     fields: { | ||||||
|  | //       //mutation for creacte | ||||||
|  | //       createPost: { | ||||||
|  | //         //type of object to return after create in SQLite | ||||||
|  | //         type: PostType, | ||||||
|  | //         //argument of mutation creactePost to get from request | ||||||
|  | //         args: { | ||||||
|  | //           title: { | ||||||
|  | //             type: new graphql.GraphQLNonNull(graphql.GraphQLString) | ||||||
|  | //           }, | ||||||
|  | //           description:{ | ||||||
|  | //               type: new graphql.GraphQLNonNull(graphql.GraphQLString) | ||||||
|  | //           }, | ||||||
|  | //           createDate:{ | ||||||
|  | //               type: new graphql.GraphQLNonNull(graphql.GraphQLString) | ||||||
|  | //           }, | ||||||
|  | //           author:{ | ||||||
|  | //               type: new graphql.GraphQLNonNull(graphql.GraphQLString) | ||||||
|  | //           } | ||||||
|  | //         }, | ||||||
|  | //         resolve: (root, {title, description, createDate, author}) => { | ||||||
|  | //             return new Promise((resolve, reject) => { | ||||||
|  | //                 //raw SQLite to insert a new post in post table | ||||||
|  | //                 database.run('INSERT INTO Posts (title, description, createDate, author) VALUES (?,?,?,?);', [title, description, createDate, author], (err) => { | ||||||
|  | //                     if(err) { | ||||||
|  | //                         reject(null); | ||||||
|  | //                     } | ||||||
|  | //                     database.get("SELECT last_insert_rowid() as id", (err, row) => { | ||||||
|  |                          | ||||||
|  | //                         resolve({ | ||||||
|  | //                             id: row["id"], | ||||||
|  | //                             title: title, | ||||||
|  | //                             description: description, | ||||||
|  | //                             createDate:createDate, | ||||||
|  | //                             author: author | ||||||
|  | //                         }); | ||||||
|  | //                     }); | ||||||
|  | //                 }); | ||||||
|  | //             }) | ||||||
|  | //         } | ||||||
|  | //       }, | ||||||
|  | //       //mutation for update | ||||||
|  | //       updatePost: { | ||||||
|  | //         //type of object to return afater update in SQLite | ||||||
|  | //         type: graphql.GraphQLString, | ||||||
|  | //         //argument of mutation creactePost to get from request | ||||||
|  | //         args:{ | ||||||
|  | //             id:{ | ||||||
|  | //                 type: new graphql.GraphQLNonNull(graphql.GraphQLID) | ||||||
|  | //             }, | ||||||
|  | //             title: { | ||||||
|  | //                 type: new graphql.GraphQLNonNull(graphql.GraphQLString) | ||||||
|  | //             }, | ||||||
|  | //             description:{ | ||||||
|  | //                   type: new graphql.GraphQLNonNull(graphql.GraphQLString) | ||||||
|  | //             }, | ||||||
|  | //             createDate:{ | ||||||
|  | //                   type: new graphql.GraphQLNonNull(graphql.GraphQLString) | ||||||
|  | //             }, | ||||||
|  | //             author:{ | ||||||
|  | //                   type: new graphql.GraphQLNonNull(graphql.GraphQLString) | ||||||
|  | //             }              | ||||||
|  | //         }, | ||||||
|  | //         resolve: (root, {id, title, description, createDate, author}) => { | ||||||
|  | //             return new Promise((resolve, reject) => { | ||||||
|  | //                 //raw SQLite to update a post in post table | ||||||
|  | //                 database.run('UPDATE Posts SET title = (?), description = (?), createDate = (?), author = (?) WHERE id = (?);', [title, description, createDate, author, id], (err) => { | ||||||
|  | //                     if(err) { | ||||||
|  | //                         reject(err); | ||||||
|  | //                     } | ||||||
|  | //                     resolve(`Post #${id} updated`); | ||||||
|  | //                 }); | ||||||
|  | //             }) | ||||||
|  | //         } | ||||||
|  | //       }, | ||||||
|  | //       //mutation for update | ||||||
|  | //       deletePost: { | ||||||
|  | //          //type of object resturn after delete in SQLite | ||||||
|  | //         type: graphql.GraphQLString, | ||||||
|  | //         args:{ | ||||||
|  | //             id:{ | ||||||
|  | //                 type: new graphql.GraphQLNonNull(graphql.GraphQLID) | ||||||
|  | //             }                | ||||||
|  | //         }, | ||||||
|  | //         resolve: (root, {id}) => { | ||||||
|  | //             return new Promise((resolve, reject) => { | ||||||
|  | //                 //raw query to delete from post table by id | ||||||
|  | //                 database.run('DELETE from Posts WHERE id =(?);', [id], (err) => { | ||||||
|  | //                     if(err) { | ||||||
|  | //                         reject(err); | ||||||
|  | //                     } | ||||||
|  | //                     resolve(`Post #${id} deleted`);                     | ||||||
|  | //                 }); | ||||||
|  | //             }) | ||||||
|  | //         } | ||||||
|  | //       } | ||||||
|  | //     } | ||||||
|  | // }); | ||||||
|  |  | ||||||
|  | //define schema with post object, queries, and mustation  | ||||||
|  | const schema = new graphql.GraphQLSchema({ | ||||||
|  |     query: queryType, | ||||||
|  |     // mutation: mutationType  | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | //export schema to use on index.js | ||||||
|  | module.exports = { | ||||||
|  |     schema | ||||||
|  | } | ||||||
| @@ -8,16 +8,16 @@ const Token = require('src/user/token'); | |||||||
| // curl -i -H "Authorization:[token]" localhost:31459/api/v1/user/history | // curl -i -H "Authorization:[token]" localhost:31459/api/v1/user/history | ||||||
|  |  | ||||||
| const tokenToUser = (req, res, next) => { | const tokenToUser = (req, res, next) => { | ||||||
|    const rawToken = req.headers.authorization; |   const rawToken = req.headers.authorization; | ||||||
|    if (rawToken) { |   if (rawToken) { | ||||||
|       try { |     try { | ||||||
|          const token = Token.fromString(rawToken, secret); |       const token = Token.fromString(rawToken, secret); | ||||||
|          req.loggedInUser = token.user; |       req.loggedInUser = token.user; | ||||||
|       } catch (error) { |     } catch (error) { | ||||||
|          req.loggedInUser = undefined; |       req.loggedInUser = undefined; | ||||||
|       } |     } | ||||||
|    } |   } | ||||||
|    next(); |   next(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| module.exports = tokenToUser; | module.exports = tokenToUser; | ||||||
|   | |||||||
| @@ -1 +1 @@ | |||||||
| {"adult":false,"backdrop_path":"/mVr0UiqyltcfqxbAUcLl9zWL8ah.jpg","belongs_to_collection":{"id":422837,"name":"Blade Runner Collection","poster_path":"/cWESb1o9lW2i2Z3Xllv9u40aNIk.jpg","backdrop_path":"/bSHZIvLoPBWyGLeiAudN1mXdvQX.jpg"},"budget":150000000,"genres":[{"id":9648,"name":"Mystery"},{"id":878,"name":"Science Fiction"},{"id":53,"name":"Thriller"}],"homepage":"http://bladerunnermovie.com/","id":335984,"imdb_id":"tt1856101","original_language":"en","original_title":"Blade Runner 2049","overview":"Thirty years after the events of the first film, a new blade runner, LAPD Officer K, unearths a long-buried secret that has the potential to plunge what's left of society into chaos. K's discovery leads him on a quest to find Rick Deckard, a former LAPD blade runner who has been missing for 30 years.","popularity":30.03,"poster_path":"/gajva2L0rPYkEWjzgFlBXCAVBE5.jpg","production_companies":[{"id":79529,"logo_path":"/gVN3k8emmKy4iV4KREWcCtxusZK.png","name":"Torridon Films","origin_country":"US"},{"id":101829,"logo_path":"/8IOjCvgjq0zTrtP91cWD3kL2jMK.png","name":"16:14 Entertainment","origin_country":"US"},{"id":1645,"logo_path":"/6Ry6uNBaa0IbbSs1XYIgX5DkA9r.png","name":"Scott Free Productions","origin_country":""},{"id":5,"logo_path":"/71BqEFAF4V3qjjMPCpLuyJFB9A.png","name":"Columbia Pictures","origin_country":"US"},{"id":1088,"logo_path":"/9WOE5AQUXbOtLU6GTwfjS8OMF0v.png","name":"Alcon Entertainment","origin_country":"US"},{"id":78028,"logo_path":"/sTFcDFfJaSVT3sv3DoaZDE4SlGB.png","name":"Thunderbird Entertainment","origin_country":"CA"},{"id":174,"logo_path":"/ky0xOc5OrhzkZ1N6KyUxacfQsCk.png","name":"Warner Bros. Pictures","origin_country":"US"}],"production_countries":[{"iso_3166_1":"CA","name":"Canada"},{"iso_3166_1":"US","name":"United States of America"},{"iso_3166_1":"HU","name":"Hungary"},{"iso_3166_1":"GB","name":"United Kingdom"}],"release_date":"2017-10-04","revenue":259239658,"runtime":163,"spoken_languages":[{"iso_639_1":"en","name":"English"},{"iso_639_1":"fi","name":"suomi"}],"status":"Released","tagline":"There's still a page left.","title":"Blade Runner 2049","video":false,"vote_average":7.3,"vote_count":5478} | [{"adult":false,"backdrop_path":"/mVr0UiqyltcfqxbAUcLl9zWL8ah.jpg","belongs_to_collection":{"id":422837,"name":"Blade Runner Collection","poster_path":"/cWESb1o9lW2i2Z3Xllv9u40aNIk.jpg","backdrop_path":"/bSHZIvLoPBWyGLeiAudN1mXdvQX.jpg"},"budget":150000000,"genres":[{"id":9648,"name":"Mystery"},{"id":878,"name":"Science Fiction"},{"id":53,"name":"Thriller"}],"homepage":"http://bladerunnermovie.com/","id":335984,"imdb_id":"tt1856101","original_language":"en","original_title":"Blade Runner 2049","overview":"Thirty years after the events of the first film, a new blade runner, LAPD Officer K, unearths a long-buried secret that has the potential to plunge what's left of society into chaos. K's discovery leads him on a quest to find Rick Deckard, a former LAPD blade runner who has been missing for 30 years.","popularity":30.03,"poster_path":"/gajva2L0rPYkEWjzgFlBXCAVBE5.jpg","production_companies":[{"id":79529,"logo_path":"/gVN3k8emmKy4iV4KREWcCtxusZK.png","name":"Torridon Films","origin_country":"US"},{"id":101829,"logo_path":"/8IOjCvgjq0zTrtP91cWD3kL2jMK.png","name":"16:14 Entertainment","origin_country":"US"},{"id":1645,"logo_path":"/6Ry6uNBaa0IbbSs1XYIgX5DkA9r.png","name":"Scott Free Productions","origin_country":""},{"id":5,"logo_path":"/71BqEFAF4V3qjjMPCpLuyJFB9A.png","name":"Columbia Pictures","origin_country":"US"},{"id":1088,"logo_path":"/9WOE5AQUXbOtLU6GTwfjS8OMF0v.png","name":"Alcon Entertainment","origin_country":"US"},{"id":78028,"logo_path":"/sTFcDFfJaSVT3sv3DoaZDE4SlGB.png","name":"Thunderbird Entertainment","origin_country":"CA"},{"id":174,"logo_path":"/ky0xOc5OrhzkZ1N6KyUxacfQsCk.png","name":"Warner Bros. Pictures","origin_country":"US"}],"production_countries":[{"iso_3166_1":"CA","name":"Canada"},{"iso_3166_1":"US","name":"United States of America"},{"iso_3166_1":"HU","name":"Hungary"},{"iso_3166_1":"GB","name":"United Kingdom"}],"release_date":"2017-10-04","revenue":259239658,"runtime":163,"spoken_languages":[{"iso_639_1":"en","name":"English"},{"iso_639_1":"fi","name":"suomi"}],"status":"Released","tagline":"There's still a page left.","title":"Blade Runner 2049","video":false,"vote_average":7.3,"vote_count":5478}] | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								seasoned_api/test/fixtures/empty-query-success-response.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								seasoned_api/test/fixtures/empty-query-success-response.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | { | ||||||
|  |     "page":1, | ||||||
|  |     "results":[], | ||||||
|  |     "total_results":0, | ||||||
|  |     "total_pages":1 | ||||||
|  | } | ||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										16
									
								
								seasoned_api/test/helpers/tmdbMock2.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								seasoned_api/test/helpers/tmdbMock2.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | const tmdbMock = () => ({ | ||||||
|  |     error: null, | ||||||
|  |     response: null, | ||||||
|  |     searchMovie(query, callback) { | ||||||
|  |         callback(this.error, this.response); | ||||||
|  |     }, | ||||||
|  |     movieInfo(query, callback) { | ||||||
|  |       callback(this.error, this.response); | ||||||
|  |     }, | ||||||
|  |     miscPopularMovies(callback) { | ||||||
|  |       console.log('miscPopMovies callback', callback) | ||||||
|  |       callback(this.error, this.response); | ||||||
|  |     }, | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | module.exports = tmdbMock; | ||||||
| @@ -5,8 +5,8 @@ xdescribe('As a developer I want the server to start', () => { | |||||||
|   beforeEach(() => |   beforeEach(() => | ||||||
|     this.server = require('src/webserver/server')); |     this.server = require('src/webserver/server')); | ||||||
|  |  | ||||||
|   it('should listen on port 31459', (done) => { |   it('should listen on port 31400', (done) => { | ||||||
|     net.createConnection(31459, done); |     net.createConnection(31400, done); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   afterEach(() => |   afterEach(() => | ||||||
|   | |||||||
| @@ -15,6 +15,6 @@ describe('As a user I want error when registering existing username', () => { | |||||||
|     .post('/api/v1/user') |     .post('/api/v1/user') | ||||||
|     .send({ username: 'test_user', password: 'password' }) |     .send({ username: 'test_user', password: 'password' }) | ||||||
|     .expect(401) |     .expect(401) | ||||||
|     .then(response => assert.equal(response.text, '{"success":false,"error":"That username is already registered"}')) |     .then(response => assert.equal(response.text, '{"success":false,"message":"That username is already registered"}')) | ||||||
|   ); |   ); | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -7,17 +7,17 @@ const createToken = require('test/helpers/createToken'); | |||||||
| const infoMovieSuccess = require('test/fixtures/blade_runner_2049-info-success-response.json'); | const infoMovieSuccess = require('test/fixtures/blade_runner_2049-info-success-response.json'); | ||||||
|  |  | ||||||
| describe('As a user I want to request a movie', () => { | describe('As a user I want to request a movie', () => { | ||||||
|   before(() => { |   before(async () => { | ||||||
|    return resetDatabase() |     await resetDatabase() | ||||||
|    .then(() => createUser('test_user', 'test@gmail.com', 'password')); |     await createUser('test_user', 'test@gmail.com', 'password') | ||||||
|    }) |    }) | ||||||
|   before(() => createCacheEntry('mi:335984', infoMovieSuccess)); |   before(() => createCacheEntry('mi:335984:false', infoMovieSuccess)); | ||||||
|  |  | ||||||
|   it('should return 200 when item is requested', () => |   it('should return 200 when item is requested', () => | ||||||
|     request(app) |     request(app) | ||||||
|     .post('/api/v2/request') |     .post('/api/v2/request') | ||||||
|  |     .set('authorization', createToken('test_user', 'secret')) | ||||||
|     .send({ id: 335984, type: 'movie' }) |     .send({ id: 335984, type: 'movie' }) | ||||||
|     .set('Authorization', createToken('test_user', 'secret')) |  | ||||||
|     .expect(200) |     .expect(200) | ||||||
|   ); |   ); | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -1,28 +1,29 @@ | |||||||
| const assert = require('assert'); | const assert = require('assert'); | ||||||
| const convertTmdbToMovie = require('src/tmdb/convertTmdbToMovie'); | // const convertTmdbToMovie = require('src/tmdb/convertTmdbToMovie'); | ||||||
|  | const { Movie } = require('src/tmdb/types'); | ||||||
| const bladeRunnerQuerySuccess = require('test/fixtures/blade_runner_2049-info-success-response.json')  | const bladeRunnerQuerySuccess = require('test/fixtures/blade_runner_2049-info-success-response.json')  | ||||||
|  |  | ||||||
| describe('Convert tmdb movieInfo to movie', () => { | describe('Convert tmdb movieInfo to movie', () => { | ||||||
|   beforeEach(() => this.bladeRunnerTmdbMovie = bladeRunnerQuerySuccess); |   beforeEach(() => [this.bladeRunnerTmdbMovie] = bladeRunnerQuerySuccess); | ||||||
|  |  | ||||||
|   it('should translate the tmdb release date to movie year', () => { |   it('should translate the tmdb release date to movie year', () => { | ||||||
|     const bladeRunner = convertTmdbToMovie(this.bladeRunnerTmdbMovie); |     const bladeRunner = Movie.convertFromTmdbResponse(this.bladeRunnerTmdbMovie); | ||||||
|     assert.strictEqual(bladeRunner.year, 2017); |     assert.strictEqual(bladeRunner.year, 2017); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   it('should translate the tmdb release date to instance of Date', () => { |   it('should translate the tmdb release date to instance of Date', () => { | ||||||
|     const bladeRunner = convertTmdbToMovie(this.bladeRunnerTmdbMovie); |     const bladeRunner = Movie.convertFromTmdbResponse(this.bladeRunnerTmdbMovie); | ||||||
|     assert(bladeRunner.release_date instanceof Date); |     assert(bladeRunner.releaseDate instanceof Date); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   it('should translate the tmdb title to title', () => { |   it('should translate the tmdb title to title', () => { | ||||||
|     const bladeRunner = convertTmdbToMovie(this.bladeRunnerTmdbMovie); |     const bladeRunner = Movie.convertFromTmdbResponse(this.bladeRunnerTmdbMovie); | ||||||
|     assert.equal(bladeRunner.title, 'Blade Runner 2049'); |     assert.equal(bladeRunner.title, 'Blade Runner 2049'); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   it('should translate the tmdb vote_average to rank', () => { |   it('should translate the tmdb vote_average to rating', () => { | ||||||
|     const bladeRunner = convertTmdbToMovie(this.bladeRunnerTmdbMovie); |     const bladeRunner = Movie.convertFromTmdbResponse(this.bladeRunnerTmdbMovie); | ||||||
|     assert.equal(bladeRunner.rank, 7.3); |     assert.equal(bladeRunner.rating, 7.3); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|     |     | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ describe('TMDB', function test() { | |||||||
|       it('should return the "Blade Runner 2049" year in the collection of popular movies', () => { |       it('should return the "Blade Runner 2049" year in the collection of popular movies', () => { | ||||||
|         this.mockMoviedb.response = popularMovieSuccessResponse; |         this.mockMoviedb.response = popularMovieSuccessResponse; | ||||||
|           const cache = new Cache(this.database); |           const cache = new Cache(this.database); | ||||||
|           const tmdb = new TMDB(cache, 'bogus-api-key', this.mockMoviedb); |           const tmdb = new TMDB(cache, 'bogus-pi-key', this.mockMoviedb); | ||||||
|           return tmdb.popular() |           return tmdb.popular() | ||||||
|           .then(movies => |           .then(movies => | ||||||
|             assert.equal(movies[0].title, "Blade Runner 2049") |             assert.equal(movies[0].title, "Blade Runner 2049") | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user