Feat Drone CI & dockerize 🐳 #132
							
								
								
									
										2
									
								
								.dockerignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.dockerignore
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | **/node_modules | ||||||
|  | **/yarn.lock | ||||||
							
								
								
									
										111
									
								
								.drone.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								.drone.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | |||||||
|  | --- | ||||||
|  | kind: pipeline | ||||||
|  | type: docker | ||||||
|  | name: seasoned api build | ||||||
|  |  | ||||||
|  | platform: | ||||||
|  |   os: linux | ||||||
|  |   arch: amd64 | ||||||
|  |  | ||||||
|  | volumes: | ||||||
|  |   - name: cache | ||||||
|  |     host: | ||||||
|  |       path: /tmp/cache | ||||||
|  |  | ||||||
|  | steps: | ||||||
|  |   - name: Load cached packages | ||||||
|  |     image: sinlead/drone-cache:1.0.0 | ||||||
|  |     settings: | ||||||
|  |       action: load | ||||||
|  |       key: yarn.lock | ||||||
|  |       mount: node_modules | ||||||
|  |       prefix: yarn-modules-seasoned_api | ||||||
|  |     volumes: | ||||||
|  |       - name: cache | ||||||
|  |         path: /cache | ||||||
|  |  | ||||||
|  |   - name: Install dependencies | ||||||
|  |     image: node:18.2.0 | ||||||
|  |     commands: | ||||||
|  |       - node -v | ||||||
|  |       - yarn --version | ||||||
|  |       - yarn | ||||||
|  |  | ||||||
|  |   - name: Cache packages | ||||||
|  |     image: sinlead/drone-cache:1.0.0 | ||||||
|  |     settings: | ||||||
|  |       action: save | ||||||
|  |       key: yarn.lock | ||||||
|  |       mount: node_modules | ||||||
|  |       prefix: yarn-modules-seasoned_api | ||||||
|  |     volumes: | ||||||
|  |       - name: cache | ||||||
|  |         path: /cache | ||||||
|  |  | ||||||
|  |   # - name: Compile typescript | ||||||
|  |   #   image: node:18.2.0 | ||||||
|  |   #   commands: | ||||||
|  |   #     - yarn build:ts | ||||||
|  |  | ||||||
|  |   - name: Run test suite | ||||||
|  |     image: node:18.2.0 | ||||||
|  |     commands: | ||||||
|  |       - yarn test | ||||||
|  |     failure: ignore | ||||||
|  |  | ||||||
|  |   - name: Lint project using eslint | ||||||
|  |     image: node:18.2.0 | ||||||
|  |     commands: | ||||||
|  |       - yarn lint | ||||||
|  |     failure: ignore | ||||||
|  |  | ||||||
|  |   - name: Build and publish docker image | ||||||
|  |     image: plugins/docker | ||||||
|  |     settings: | ||||||
|  |       registry: ghcr.io | ||||||
|  |       repo: ghcr.io/kevinmidboe/seasoned_shows | ||||||
|  |       dockerfile: Dockerfile | ||||||
|  |       username: | ||||||
|  |         from_secret: GITHUB_USERNAME | ||||||
|  |       password: | ||||||
|  |         from_secret: GITHUB_PASSWORD | ||||||
|  |       tags: latest | ||||||
|  |     environment: | ||||||
|  |       TMDB_APIKEY: | ||||||
|  |         from_secret: TMDB_APIKEY | ||||||
|  |       PLEX_IP: | ||||||
|  |         from_secret: PLEX_IP | ||||||
|  |       PLEX_TOKEN: | ||||||
|  |         from_secret: PLEX_TOKEN | ||||||
|  |     # when: | ||||||
|  |     #   event: | ||||||
|  |     #     - push | ||||||
|  |     #   branch: | ||||||
|  |     #     - master | ||||||
|  |  | ||||||
|  |   # - name: deploy | ||||||
|  |   #   image: appleboy/drone-ssh | ||||||
|  |   #   pull: true | ||||||
|  |   #   secrets: | ||||||
|  |   #     - ssh_key | ||||||
|  |   #   when: | ||||||
|  |   #     event: | ||||||
|  |   #       - push | ||||||
|  |   #     branch: | ||||||
|  |   #       - master | ||||||
|  |   #       - drone-test | ||||||
|  |   #     status: success | ||||||
|  |   #   settings: | ||||||
|  |   #     host: 10.0.0.54 | ||||||
|  |   #     username: root | ||||||
|  |   #     key: | ||||||
|  |   #       from_secret: ssh_key | ||||||
|  |   #     command_timeout: 600s | ||||||
|  |   #     script: | ||||||
|  |   #       - /home/kevin/deploy/seasoned.sh | ||||||
|  |  | ||||||
|  | trigger: | ||||||
|  |   event: | ||||||
|  |     include: | ||||||
|  |       - push | ||||||
|  |       # - pull_request | ||||||
							
								
								
									
										0
									
								
								_config.yml → .github/_config.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										0
									
								
								_config.yml → .github/_config.yml
									
									
									
									
										vendored
									
									
								
							
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,7 +1,8 @@ | |||||||
| .DS_Store | .DS_Store | ||||||
|  |  | ||||||
| development.json | development.json | ||||||
| env | .env | ||||||
| shows.db | shows.db | ||||||
|  |  | ||||||
|  | node_modules | ||||||
| */package-lock.json | */package-lock.json | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | FROM node:18 | ||||||
|  |  | ||||||
|  | RUN mkdir -p /opt/seasonedShows/seasoned_api | ||||||
|  |  | ||||||
|  | WORKDIR /opt/seasonedShows | ||||||
|  |  | ||||||
|  | COPY seasoned_api/ seasoned_api | ||||||
|  | COPY package.json . | ||||||
|  |  | ||||||
|  | RUN apt update | ||||||
|  | RUN apt install node-pre-gyp -y | ||||||
|  | RUN yarn | ||||||
|  | RUN cp seasoned_api/conf/development.json.example seasoned_api/conf/development.json | ||||||
|  |  | ||||||
|  | EXPOSE 31459 | ||||||
|  |  | ||||||
|  | CMD ["yarn", "start"] | ||||||
|  |  | ||||||
|  | LABEL org.opencontainers.image.source https://github.com/kevinmidboe/seasoned | ||||||
| @@ -7,14 +7,14 @@ | |||||||
|   }, |   }, | ||||||
|   "main": "webserver/server.js", |   "main": "webserver/server.js", | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "start": "cross-env SEASONED_CONFIG=conf/development.json NODE_ENV=production NODE_PATH=. babel-node src/webserver/server.js", |     "start": "yarn cross-env SEASONED_CONFIG=conf/development.json NODE_ENV=production babel-node seasoned_api/src/webserver/server.js", | ||||||
|     "test": "cross-env SEASONED_CONFIG=conf/test.json NODE_PATH=. mocha --require @babel/register --recursive test/unit test/system", |     "test": "cross-env SEASONED_CONFIG=conf/test.json NODE_PATH=. mocha --require @babel/register --recursive seasoned_api/test/unit seasoned_api/test//system", | ||||||
|     "coverage": "cross-env SEASONED_CONFIG=conf/test.json NODE_PATH=. nyc mocha --require @babel/register --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": "eslint seasoned_api/src", | ||||||
|     "update": "cross-env SEASONED_CONFIG=conf/development.json NODE_PATH=. node scripts/updateRequestsInPlex.js", |     "update": "cross-env SEASONED_CONFIG=conf/development.json NODE_PATH=. node seasoned_api/scripts/updateRequestsInPlex.js", | ||||||
|     "docs": "yarn apiDocs; yarn classDocs", |     "docs": "yarn apiDocs; yarn classDocs", | ||||||
|     "apiDocs": "", |     "apiDocs": "", | ||||||
|     "classDocs": "./script/generate-class-docs.sh" |     "classDocs": "seasoned_api/script/generate-class-docs.sh" | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "axios": "^0.18.0", |     "axios": "^0.18.0", | ||||||
| @@ -2,6 +2,10 @@ | |||||||
|   "database": { |   "database": { | ||||||
|     "host": "../shows.db" |     "host": "../shows.db" | ||||||
|   }, |   }, | ||||||
|  |   "redis": { | ||||||
|  |     "host": "localhost", | ||||||
|  |     "port": 6379 | ||||||
|  |   }, | ||||||
|   "webserver": { |   "webserver": { | ||||||
|     "port": 31459, |     "port": 31459, | ||||||
|     "origins": [] |     "origins": [] | ||||||
| @@ -10,7 +14,8 @@ | |||||||
|     "apiKey": "" |     "apiKey": "" | ||||||
|   }, |   }, | ||||||
|   "plex": { |   "plex": { | ||||||
|     "ip": "" |     "ip": "localhost", | ||||||
|  |     "token": "" | ||||||
|   }, |   }, | ||||||
|   "tautulli": { |   "tautulli": { | ||||||
|     "apiKey": "", |     "apiKey": "", | ||||||
|   | |||||||
							
								
								
									
										109
									
								
								seasoned_api/src/cache/redis.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										109
									
								
								seasoned_api/src/cache/redis.js
									
									
									
									
										vendored
									
									
								
							| @@ -1,52 +1,73 @@ | |||||||
| const redis = require("redis") | const { promisify } = require("util"); | ||||||
| const client = redis.createClient() | const configuration = require("../config/configuration").getInstance(); | ||||||
|  |  | ||||||
| class Cache { | let client; | ||||||
|   /** |  | ||||||
|    * Retrieve an unexpired cache entry by key. |  | ||||||
|    * @param {String} key of the cache entry |  | ||||||
|    * @returns {Promise} |  | ||||||
|    */ |  | ||||||
|   get(key) { |  | ||||||
|     return new Promise((resolve, reject) => { |  | ||||||
|       client.get(key, (error, reply) => { |  | ||||||
|         if (reply == null) { |  | ||||||
|           return reject(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         resolve(JSON.parse(reply)); | try { | ||||||
|       }); |   const redis = require("redis"); | ||||||
|     }); |   console.log("Trying to connect with redis.."); | ||||||
|   } |   const host = configuration.get("redis", "host"); | ||||||
|  |   const port = configuration.get("redis", "port"); | ||||||
|  |  | ||||||
|   /** |   console.log(`redis://${host}:${port}`); | ||||||
|    * Insert cache entry with key and value. |   client = redis.createClient({ | ||||||
|    * @param {String} key of the cache entry |     url: `redis://${host}:${port}` | ||||||
|    * @param {String} value of the cache entry |   }); | ||||||
|    * @param {Number} timeToLive the number of seconds before entry expires |  | ||||||
|    * @returns {Object} |  | ||||||
|    */ |  | ||||||
|   set(key, value, timeToLive = 10800) { |  | ||||||
|     if (value == null || key == null) return null; |  | ||||||
|  |  | ||||||
|     const json = JSON.stringify(value); |   client.on("connect", () => console.log("Redis connection established!")); | ||||||
|     client.set(key, json, (error, reply) => { |  | ||||||
|       if (reply == "OK") { |   client.on("error", function (err) { | ||||||
|         // successfully set value with key, now set TTL for key |     client.quit(); | ||||||
|         client.expire(key, timeToLive, e => { |     console.error("Unable to connect to redis, setting up redis-mock."); | ||||||
|           if (e) |  | ||||||
|             console.error( |     client = { | ||||||
|               "Unexpected error while setting expiration for key:", |       get: function () { | ||||||
|               key, |         console.log("redis-dummy get", arguments[0]); | ||||||
|               ". Error:", |         return Promise.resolve(); | ||||||
|               error |       }, | ||||||
|             ); |       set: function () { | ||||||
|         }); |         console.log("redis-dummy set", arguments[0]); | ||||||
|  |         return Promise.resolve(); | ||||||
|       } |       } | ||||||
|     }); |     }; | ||||||
|  |   }); | ||||||
|  | } catch (e) {} | ||||||
|  |  | ||||||
|     return value; | function set(key, value, TTL = 10800) { | ||||||
|   } |   if (value == null || key == null) return null; | ||||||
|  |  | ||||||
|  |   const json = JSON.stringify(value); | ||||||
|  |   client.set(key, json, (error, reply) => { | ||||||
|  |     if (reply == "OK") { | ||||||
|  |       // successfully set value with key, now set TTL for key | ||||||
|  |       client.expire(key, TTL, e => { | ||||||
|  |         if (e) | ||||||
|  |           console.error( | ||||||
|  |             "Unexpected error while setting expiration for key:", | ||||||
|  |             key, | ||||||
|  |             ". Error:", | ||||||
|  |             error | ||||||
|  |           ); | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   return value; | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = Cache; | function get() { | ||||||
|  |   return new Promise((resolve, reject) => { | ||||||
|  |     client.get(key, (error, reply) => { | ||||||
|  |       if (reply == null) { | ||||||
|  |         return reject(); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       resolve(JSON.parse(reply)); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = { | ||||||
|  |   get, | ||||||
|  |   set | ||||||
|  | }; | ||||||
|   | |||||||
| @@ -1,43 +1,47 @@ | |||||||
| const path = require('path'); | const path = require("path"); | ||||||
| const Field = require('./field.js'); | const Field = require("./field.js"); | ||||||
|  |  | ||||||
| let instance = null; | let instance = null; | ||||||
|  |  | ||||||
| class Config { | class Config { | ||||||
|    constructor() { |   constructor() { | ||||||
|       this.location = Config.determineLocation(); |     this.location = Config.determineLocation(); | ||||||
|       this.fields = require(`${this.location}`); |     this.fields = require(`${this.location}`); | ||||||
|    } |   } | ||||||
|  |  | ||||||
|    static getInstance() { |   static getInstance() { | ||||||
|       if (instance == null) { |     if (instance == null) { | ||||||
|          instance = new Config(); |       instance = new Config(); | ||||||
|       } |     } | ||||||
|       return instance; |     return instance; | ||||||
|    } |   } | ||||||
|  |  | ||||||
|    static determineLocation() { |   static determineLocation() { | ||||||
|       return path.join(__dirname, '..', '..', process.env.SEASONED_CONFIG); |     return path.join(__dirname, "..", "..", process.env.SEASONED_CONFIG); | ||||||
|    } |   } | ||||||
|  |  | ||||||
|    get(section, option) { |   get(section, option) { | ||||||
|       if (this.fields[section] === undefined || this.fields[section][option] === undefined) { |     if ( | ||||||
|          throw new Error(`Field "${section} => ${option}" does not exist.`); |       this.fields[section] === undefined || | ||||||
|       } |       this.fields[section][option] === undefined | ||||||
|  |     ) { | ||||||
|  |       throw new Error(`Field "${section} => ${option}" does not exist.`); | ||||||
|  |     } | ||||||
|  |  | ||||||
|       const field = new Field(this.fields[section][option]); |     const field = new Field(this.fields[section][option]); | ||||||
|  |  | ||||||
|       if (field.value === '') { |     const envField = | ||||||
|          const envField = process.env[[section.toUpperCase(), option.toUpperCase()].join('_')]; |       process.env[[section.toUpperCase(), option.toUpperCase()].join("_")]; | ||||||
|          if (envField !== undefined && envField.length !== 0) { return envField; } |     if (envField !== undefined && envField.length !== 0) { | ||||||
|       } |       return envField; | ||||||
|  |     } | ||||||
|  |  | ||||||
|       if (field.value === undefined) { |     if (field.value === undefined) { | ||||||
|          throw new Error(`${section} => ${option} is empty.`); |       throw new Error(`${section} => ${option} is empty.`); | ||||||
|       } |     } | ||||||
|  |  | ||||||
|       return field.value; |     return field.value; | ||||||
|    } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = Config; | module.exports = Config; | ||||||
|   | |||||||
| @@ -1,14 +1,13 @@ | |||||||
| const configuration = require('src/config/configuration').getInstance(); | const configuration = require("../config/configuration").getInstance(); | ||||||
| const SqliteDatabase = require('src/database/sqliteDatabase'); | const SqliteDatabase = require("./sqliteDatabase"); | ||||||
|  |  | ||||||
| const database = new SqliteDatabase(configuration.get('database', 'host')); | const database = new SqliteDatabase(configuration.get("database", "host")); | ||||||
| /** | /** | ||||||
|  * This module establishes a connection to the database |  * This module establishes a connection to the database | ||||||
|  * specified in the confgiuration file. It tries to setup |  * specified in the confgiuration file. It tries to setup | ||||||
|  * the required tables after successfully connecting. |  * the required tables after successfully connecting. | ||||||
|  * If the tables already exists, it simply proceeds. |  * If the tables already exists, it simply proceeds. | ||||||
|  */ |  */ | ||||||
| Promise.resolve() | Promise.resolve().then(() => database.setUp()); | ||||||
|    .then(() => database.setUp()); |  | ||||||
|  |  | ||||||
| module.exports = database; | module.exports = database; | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ CREATE TABLE IF NOT EXISTS search_history ( | |||||||
|     foreign key(user_name) REFERENCES user(user_name) ON DELETE CASCADE |     foreign key(user_name) REFERENCES user(user_name) ON DELETE CASCADE | ||||||
| ); | ); | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS requests( | CREATE TABLE IF NOT EXISTS requests ( | ||||||
|     id NUMBER, |     id NUMBER, | ||||||
|     title TEXT, |     title TEXT, | ||||||
|     year NUMBER, |     year NUMBER, | ||||||
| @@ -41,8 +41,8 @@ CREATE TABLE IF NOT EXISTS requests( | |||||||
|     date DATE DEFAULT CURRENT_TIMESTAMP, |     date DATE DEFAULT CURRENT_TIMESTAMP, | ||||||
|     status CHAR(25) DEFAULT 'requested' NOT NULL, |     status CHAR(25) DEFAULT 'requested' NOT NULL, | ||||||
|     user_agent CHAR(255) DEFAULT NULL, |     user_agent CHAR(255) DEFAULT NULL, | ||||||
|     type CHAR(50) DEFAULT 'movie', |     type CHAR(50) DEFAULT 'movie' | ||||||
|     foreign key(requested_by) REFERENCES user(user_name) ON DELETE SET NULL |     -- foreign key(requested_by) REFERENCES user(user_name) ON DELETE SET NULL | ||||||
| ); | ); | ||||||
|  |  | ||||||
| CREATE TABLE IF NOT EXISTS request( | CREATE TABLE IF NOT EXISTS request( | ||||||
|   | |||||||
| @@ -1,120 +1,119 @@ | |||||||
| const fs = require('fs'); | const fs = require("fs"); | ||||||
| const path = require('path'); | const path = require("path"); | ||||||
| const sqlite3 = require('sqlite3').verbose(); | const sqlite3 = require("sqlite3").verbose(); | ||||||
|  |  | ||||||
| class SqliteDatabase { | class SqliteDatabase { | ||||||
|    constructor(host) { |   constructor(host) { | ||||||
|       this.host = host; |     this.host = host; | ||||||
|       this.connection = new sqlite3.Database(this.host); |     this.connection = new sqlite3.Database(this.host); | ||||||
|       this.execute('pragma foreign_keys = on;'); |     this.execute("pragma foreign_keys = on;"); | ||||||
|       this.schemaDirectory = path.join(__dirname, 'schemas'); |     this.schemaDirectory = path.join(__dirname, "schemas"); | ||||||
|    } |   } | ||||||
|  |  | ||||||
|    /** |   /** | ||||||
|    * Connect to the database. |    * Connect to the database. | ||||||
|    * @returns {Promise} succeeds if connection was established |    * @returns {Promise} succeeds if connection was established | ||||||
|    */ |    */ | ||||||
|    // connect() { |   // connect() { | ||||||
|    //    let database = ; |   //    let database = ; | ||||||
|    //    this.connection = database; |   //    this.connection = database; | ||||||
|    //    return database; |   //    return database; | ||||||
|    // } |   // } | ||||||
|  |  | ||||||
|    /** |   /** | ||||||
|    * Run a SQL query against the database. |    * Run a SQL query against the database. | ||||||
|    * @param {String} sql SQL query |    * @param {String} sql SQL query | ||||||
|    * @param {Array} parameters in the SQL query |    * @param {Array} parameters in the SQL query | ||||||
|    * @returns {Promise} |    * @returns {Promise} | ||||||
|    */ |    */ | ||||||
|    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) reject(error); | ||||||
|                reject(error); |         resolve(result); | ||||||
|             resolve(result) |  | ||||||
|          }); |  | ||||||
|       }); |       }); | ||||||
|    } |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|    /** |   /** | ||||||
|    * Run a SQL query against the database and retrieve all the rows. |    * Run a SQL query against the database and retrieve all the rows. | ||||||
|    * @param {String} sql SQL query |    * @param {String} sql SQL query | ||||||
|    * @param {Array} parameters in the SQL query |    * @param {Array} parameters in the SQL query | ||||||
|    * @returns {Promise} |    * @returns {Promise} | ||||||
|    */ |    */ | ||||||
|    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) { | ||||||
|                reject(err); |           reject(err); | ||||||
|             } |         } | ||||||
|             resolve(rows); |         resolve(rows); | ||||||
|          }) |       }); | ||||||
|       }) |     }); | ||||||
|    } |   } | ||||||
|  |  | ||||||
|    /** |   /** | ||||||
|    * Run a SQL query against the database and retrieve one row. |    * Run a SQL query against the database and retrieve one row. | ||||||
|    * @param {String} sql SQL query |    * @param {String} sql SQL query | ||||||
|    * @param {Array} parameters in the SQL query |    * @param {Array} parameters in the SQL query | ||||||
|    * @returns {Promise} |    * @returns {Promise} | ||||||
|    */ |    */ | ||||||
|    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) { | ||||||
|                reject(err); |           reject(err); | ||||||
|             } |         } | ||||||
|             resolve(rows); |         resolve(rows); | ||||||
|          }) |       }); | ||||||
|       }) |     }); | ||||||
|    } |   } | ||||||
|  |  | ||||||
|    /** |   /** | ||||||
|    * Run a SQL query against the database and retrieve the status. |    * Run a SQL query against the database and retrieve the status. | ||||||
|    * @param {String} sql SQL query |    * @param {String} sql SQL query | ||||||
|    * @param {Array} parameters in the SQL query |    * @param {Array} parameters in the SQL query | ||||||
|    * @returns {Promise} |    * @returns {Promise} | ||||||
|    */ |    */ | ||||||
|    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) { | ||||||
|                console.log('ERROR: ', err); |           console.log("ERROR: ", err); | ||||||
|                reject(err); |           reject(err); | ||||||
|             } |         } | ||||||
|             resolve(); |         resolve(); | ||||||
|          }) |       }); | ||||||
|       }) |     }); | ||||||
|    } |   } | ||||||
|  |  | ||||||
|    /** |   /** | ||||||
|    * Setup the database by running setup.sql file in schemas/. |    * Setup the database by running setup.sql file in schemas/. | ||||||
|    * @returns {Promise} |    * @returns {Promise} | ||||||
|    */ |    */ | ||||||
|    setUp() { |   setUp() { | ||||||
|       const setupSchema = this.readSqlFile('setup.sql'); |     const setupSchema = this.readSqlFile("setup.sql"); | ||||||
|       return Promise.resolve(this.execute(setupSchema)); |     return Promise.resolve(this.execute(setupSchema)); | ||||||
|    } |   } | ||||||
|  |  | ||||||
|    /** |   /** | ||||||
|    * Tears down the database by running tearDown.sql file in schemas/. |    * Tears down the database by running tearDown.sql file in schemas/. | ||||||
|    * @returns {Promise} |    * @returns {Promise} | ||||||
|    */ |    */ | ||||||
|    tearDown() { |   tearDown() { | ||||||
|       const tearDownSchema = this.readSqlFile('teardown.sql'); |     const tearDownSchema = this.readSqlFile("teardown.sql"); | ||||||
|       return Promise.resolve(this.execute(tearDownSchema)); |     return Promise.resolve(this.execute(tearDownSchema)); | ||||||
|    } |   } | ||||||
|  |  | ||||||
|    /** |   /** | ||||||
|    * Returns the file contents of a SQL file in schemas/. |    * Returns the file contents of a SQL file in schemas/. | ||||||
|    * @returns {String} |    * @returns {String} | ||||||
|    */ |    */ | ||||||
|    readSqlFile(filename) { |   readSqlFile(filename) { | ||||||
|       const schemaPath = path.join(this.schemaDirectory, filename); |     const schemaPath = path.join(this.schemaDirectory, filename); | ||||||
|       const schema = fs.readFileSync(schemaPath).toString('utf-8'); |     const schema = fs.readFileSync(schemaPath).toString("utf-8"); | ||||||
|       return schema; |     return schema; | ||||||
|    } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = SqliteDatabase; | module.exports = SqliteDatabase; | ||||||
|   | |||||||
| @@ -1,22 +1,31 @@ | |||||||
|  | const Media = require("./media"); | ||||||
| const Media = require('src/media_classes/media'); |  | ||||||
|  |  | ||||||
| class Plex extends Media { | class Plex extends Media { | ||||||
|    constructor(title, year, type, summary, poster_path, background_path, added, seasons, episodes) { |   constructor( | ||||||
|       super(title, year, type); |     title, | ||||||
|  |     year, | ||||||
|  |     type, | ||||||
|  |     summary, | ||||||
|  |     poster_path, | ||||||
|  |     background_path, | ||||||
|  |     added, | ||||||
|  |     seasons, | ||||||
|  |     episodes | ||||||
|  |   ) { | ||||||
|  |     super(title, year, type); | ||||||
|  |  | ||||||
|       this.summary = summary; |     this.summary = summary; | ||||||
|       this.poster_path = poster_path; |     this.poster_path = poster_path; | ||||||
|       this.background_path = background_path; |     this.background_path = background_path; | ||||||
|       this.added = added; |     this.added = added; | ||||||
|  |  | ||||||
|       this.seasons = seasons; |     this.seasons = seasons; | ||||||
|       this.episodes = episodes; |     this.episodes = episodes; | ||||||
|    } |   } | ||||||
|  |  | ||||||
|    print() { |   print() { | ||||||
|       super.print(); |     super.print(); | ||||||
|    } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = Plex; | module.exports = Plex; | ||||||
|   | |||||||
| @@ -1,33 +1,46 @@ | |||||||
|  | const Media = require("./media"); | ||||||
| const Media = require('src/media_classes/media'); |  | ||||||
|  |  | ||||||
| class TMDB extends Media { | class TMDB extends Media { | ||||||
|    // constructor(...args) { |   // constructor(...args) { | ||||||
|    constructor(title, year, type, id, summary, poster_path, background_path, popularity, score, release_status, tagline, seasons, episodes) { |   constructor( | ||||||
|       super(title, year, type); |     title, | ||||||
|  |     year, | ||||||
|  |     type, | ||||||
|  |     id, | ||||||
|  |     summary, | ||||||
|  |     poster_path, | ||||||
|  |     background_path, | ||||||
|  |     popularity, | ||||||
|  |     score, | ||||||
|  |     release_status, | ||||||
|  |     tagline, | ||||||
|  |     seasons, | ||||||
|  |     episodes | ||||||
|  |   ) { | ||||||
|  |     super(title, year, type); | ||||||
|  |  | ||||||
|       this.id = id; |     this.id = id; | ||||||
|       this.summary = summary; |     this.summary = summary; | ||||||
|       this.poster_path = poster_path; |     this.poster_path = poster_path; | ||||||
|       this.background_path = background_path; |     this.background_path = background_path; | ||||||
|       this.popularity = popularity; |     this.popularity = popularity; | ||||||
|       this.score = score; |     this.score = score; | ||||||
|  |  | ||||||
|       this.release_status = release_status; |     this.release_status = release_status; | ||||||
|       this.tagline = tagline; |     this.tagline = tagline; | ||||||
|  |  | ||||||
|       this.seasons = seasons; |     this.seasons = seasons; | ||||||
|       this.episodes = episodes; |     this.episodes = episodes; | ||||||
|    } |   } | ||||||
|  |  | ||||||
|    toString() { |   toString() { | ||||||
|       return `${super.toString()} | ID: ${this.id}`; |     return `${super.toString()} | ID: ${this.id}`; | ||||||
|    } |   } | ||||||
|  |  | ||||||
|    print() { |   print() { | ||||||
|       /* eslint-disable no-console */ |     /* eslint-disable no-console */ | ||||||
|       console.log(this.toString()); |     console.log(this.toString()); | ||||||
|    } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = TMDB; | module.exports = TMDB; | ||||||
|   | |||||||
| @@ -1,35 +1,35 @@ | |||||||
| const request = require("request"); | const request = require("request"); | ||||||
| const configuration = require('src/config/configuration').getInstance(); | const configuration = require("../config/configuration").getInstance(); | ||||||
|  |  | ||||||
| const sendSMS = (message) => { | const sendSMS = message => { | ||||||
|   const apiKey = configuration.get('sms', 'apikey') |   const apiKey = configuration.get("sms", "apikey"); | ||||||
|  |  | ||||||
|   if (!apiKey) { |   if (!apiKey) { | ||||||
|     console.warning("api key for sms not set, cannot send sms.") |     console.warning("api key for sms not set, cannot send sms."); | ||||||
|     return null |     return null; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   const sender = configuration.get('sms', 'sender') |   const sender = configuration.get("sms", "sender"); | ||||||
|   const recipient = configuration.get('sms', 'recipient') |   const recipient = configuration.get("sms", "recipient"); | ||||||
|  |  | ||||||
|   return new Promise((resolve, reject) => { |   return new Promise((resolve, reject) => { | ||||||
|   request.post( |     request.post( | ||||||
|     { |       { | ||||||
|       url: `https://gatewayapi.com/rest/mtsms?token=${apiKey}`, |         url: `https://gatewayapi.com/rest/mtsms?token=${apiKey}`, | ||||||
|       json: true, |         json: true, | ||||||
|       body: { |         body: { | ||||||
|         sender, |           sender, | ||||||
|         message, |           message, | ||||||
|         recipients: [{ msisdn: `47${recipient}` }] |           recipients: [{ msisdn: `47${recipient}` }] | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       function (err, r, body) { | ||||||
|  |         console.log(err ? err : body); | ||||||
|  |         console.log("sms provider response:", body); | ||||||
|  |         resolve(); | ||||||
|       } |       } | ||||||
|     }, |     ); | ||||||
|     function(err, r, body) { |   }); | ||||||
|       console.log(err ? err : body); | }; | ||||||
|       console.log("sms provider response:", body) |  | ||||||
|       resolve() |  | ||||||
|     } |  | ||||||
|   ); |  | ||||||
|   }) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| module.exports = { sendSMS } | module.exports = { sendSMS }; | ||||||
|   | |||||||
| @@ -3,10 +3,9 @@ const http = require("http"); | |||||||
| const { URL } = require("url"); | const { URL } = require("url"); | ||||||
| const PythonShell = require("python-shell"); | const PythonShell = require("python-shell"); | ||||||
|  |  | ||||||
| const establishedDatabase = require("src/database/database"); | const establishedDatabase = require("../database/database"); | ||||||
|  |  | ||||||
| const RedisCache = require("src/cache/redis"); | const cache = require("../cache/redis"); | ||||||
| const cache = new RedisCache(); |  | ||||||
|  |  | ||||||
| function getMagnetFromURL(url) { | function getMagnetFromURL(url) { | ||||||
|   return new Promise((resolve, reject) => { |   return new Promise((resolve, reject) => { | ||||||
|   | |||||||
| @@ -1,7 +1,11 @@ | |||||||
| const Episode = require('src/plex/types/episode'); | const Episode = require("./types/episode"); | ||||||
|  |  | ||||||
| function convertPlexToEpisode(plexEpisode) { | function convertPlexToEpisode(plexEpisode) { | ||||||
|   const episode = new Episode(plexEpisode.title, plexEpisode.grandparentTitle, plexEpisode.year); |   const episode = new Episode( | ||||||
|  |     plexEpisode.title, | ||||||
|  |     plexEpisode.grandparentTitle, | ||||||
|  |     plexEpisode.year | ||||||
|  |   ); | ||||||
|   episode.season = plexEpisode.parentIndex; |   episode.season = plexEpisode.parentIndex; | ||||||
|   episode.episode = plexEpisode.index; |   episode.episode = plexEpisode.index; | ||||||
|   episode.summary = plexEpisode.summary; |   episode.summary = plexEpisode.summary; | ||||||
| @@ -12,7 +16,7 @@ function convertPlexToEpisode(plexEpisode) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (plexEpisode.originallyAvailableAt !== undefined) { |   if (plexEpisode.originallyAvailableAt !== undefined) { | ||||||
|     episode.airdate = new Date(plexEpisode.originallyAvailableAt) |     episode.airdate = new Date(plexEpisode.originallyAvailableAt); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   return episode; |   return episode; | ||||||
|   | |||||||
| @@ -1,10 +1,10 @@ | |||||||
| const Movie = require('src/plex/types/movie'); | const Movie = require("./types/movie"); | ||||||
|  |  | ||||||
| function convertPlexToMovie(plexMovie) { | function convertPlexToMovie(plexMovie) { | ||||||
|   const movie = new Movie(plexMovie.title, plexMovie.year); |   const movie = new Movie(plexMovie.title, plexMovie.year); | ||||||
|   movie.rating = plexMovie.rating; |   movie.rating = plexMovie.rating; | ||||||
|   movie.tagline = plexMovie.tagline; |   movie.tagline = plexMovie.tagline; | ||||||
|    |  | ||||||
|   if (plexMovie.summary !== undefined) { |   if (plexMovie.summary !== undefined) { | ||||||
|     movie.summary = plexMovie.summary; |     movie.summary = plexMovie.summary; | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -1,24 +1,34 @@ | |||||||
| const Plex = require('src/media_classes/plex'); | const Plex = require("../media_classes/plex"); | ||||||
|  |  | ||||||
| function translateAdded(date_string) { | function translateAdded(date_string) { | ||||||
|    return new Date(date_string * 1000); |   return new Date(date_string * 1000); | ||||||
| } | } | ||||||
|  |  | ||||||
| function convertPlexToSeasoned(plex) { | function convertPlexToSeasoned(plex) { | ||||||
|    const title = plex.title; |   const title = plex.title; | ||||||
|    const year = plex.year; |   const year = plex.year; | ||||||
|    const type = plex.type; |   const type = plex.type; | ||||||
|    const summary = plex.summary; |   const summary = plex.summary; | ||||||
|    const poster_path = plex.thumb; |   const poster_path = plex.thumb; | ||||||
|    const background_path = plex.art; |   const background_path = plex.art; | ||||||
|    const added = translateAdded(plex.addedAt); |   const added = translateAdded(plex.addedAt); | ||||||
|    // const genre = plex.genre; |   // const genre = plex.genre; | ||||||
|    const seasons = plex.childCount; |   const seasons = plex.childCount; | ||||||
|    const episodes = plex.leafCount; |   const episodes = plex.leafCount; | ||||||
|  |  | ||||||
|    const seasoned = new Plex(title, year, type, summary, poster_path, background_path, added, seasons, episodes); |   const seasoned = new Plex( | ||||||
|    // seasoned.print(); |     title, | ||||||
|    return seasoned; |     year, | ||||||
|  |     type, | ||||||
|  |     summary, | ||||||
|  |     poster_path, | ||||||
|  |     background_path, | ||||||
|  |     added, | ||||||
|  |     seasons, | ||||||
|  |     episodes | ||||||
|  |   ); | ||||||
|  |   // seasoned.print(); | ||||||
|  |   return seasoned; | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = convertPlexToSeasoned; | module.exports = convertPlexToSeasoned; | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| const Show = require('src/plex/types/show'); | const Show = require("./types/show"); | ||||||
|  |  | ||||||
| function convertPlexToShow(plexShow) { | function convertPlexToShow(plexShow) { | ||||||
|   const show = new Show(plexShow.title, plexShow.year); |   const show = new Show(plexShow.title, plexShow.year); | ||||||
|   | |||||||
| @@ -1,19 +1,19 @@ | |||||||
| const convertPlexToSeasoned = require('src/plex/convertPlexToSeasoned'); | const convertPlexToSeasoned = require("./convertPlexToSeasoned"); | ||||||
| const convertStreamToMediaInfo = require('src/plex/convertStreamToMediaInfo'); | const convertStreamToMediaInfo = require("./convertStreamToMediaInfo"); | ||||||
| const convertStreamToPlayer = require('src/plex/stream/convertStreamToPlayer'); | const convertStreamToPlayer = require("./stream/convertStreamToPlayer"); | ||||||
| const convertStreamToUser = require('src/plex/stream/convertStreamToUser'); | const convertStreamToUser = require("./stream/convertStreamToUser"); | ||||||
| const ConvertStreamToPlayback = require('src/plex/stream/convertStreamToPlayback'); | const ConvertStreamToPlayback = require("./stream/convertStreamToPlayback"); | ||||||
|  |  | ||||||
| function convertPlexToStream(plexStream) { | function convertPlexToStream(plexStream) { | ||||||
|    const stream = convertPlexToSeasoned(plexStream); |   const stream = convertPlexToSeasoned(plexStream); | ||||||
|    const plexStreamMedia = plexStream.Media[0]; |   const plexStreamMedia = plexStream.Media[0]; | ||||||
|    stream.mediaInfo = convertStreamToMediaInfo(plexStreamMedia); |   stream.mediaInfo = convertStreamToMediaInfo(plexStreamMedia); | ||||||
|    stream.player = convertStreamToPlayer(plexStream.Player); |   stream.player = convertStreamToPlayer(plexStream.Player); | ||||||
|  |  | ||||||
|    stream.user = convertStreamToUser(plexStream.User); |   stream.user = convertStreamToUser(plexStream.User); | ||||||
|    stream.playback = new ConvertStreamToPlayback(plexStreamMedia.Part[0]); |   stream.playback = new ConvertStreamToPlayback(plexStreamMedia.Part[0]); | ||||||
|  |  | ||||||
|    return stream; |   return stream; | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = convertPlexToStream; | module.exports = convertPlexToStream; | ||||||
|   | |||||||
| @@ -1,22 +1,22 @@ | |||||||
| const MediaInfo = require('src/media_classes/mediaInfo'); | const MediaInfo = require("../media_classes/mediaInfo"); | ||||||
|  |  | ||||||
| function convertStreamToMediaInfo(plexStream) { | function convertStreamToMediaInfo(plexStream) { | ||||||
|    const mediaInfo = new MediaInfo(); |   const mediaInfo = new MediaInfo(); | ||||||
|  |  | ||||||
|    mediaInfo.duration = plexStream.duration; |   mediaInfo.duration = plexStream.duration; | ||||||
|    mediaInfo.height = plexStream.height; |   mediaInfo.height = plexStream.height; | ||||||
|    mediaInfo.width = plexStream.width; |   mediaInfo.width = plexStream.width; | ||||||
|  |  | ||||||
|    if (plexStream.bitrate) { |   if (plexStream.bitrate) { | ||||||
|       mediaInfo.bitrate = plexStream.bitrate; |     mediaInfo.bitrate = plexStream.bitrate; | ||||||
|    } |   } | ||||||
|    mediaInfo.resolution = plexStream.videoResolution; |   mediaInfo.resolution = plexStream.videoResolution; | ||||||
|    mediaInfo.framerate = plexStream.videoFrameRate; |   mediaInfo.framerate = plexStream.videoFrameRate; | ||||||
|    mediaInfo.protocol = plexStream.protocol; |   mediaInfo.protocol = plexStream.protocol; | ||||||
|    mediaInfo.container = plexStream.container; |   mediaInfo.container = plexStream.container; | ||||||
|    mediaInfo.audioCodec = plexStream.audioCodec; |   mediaInfo.audioCodec = plexStream.audioCodec; | ||||||
|  |  | ||||||
|    return mediaInfo; |   return mediaInfo; | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = convertStreamToMediaInfo; | module.exports = convertStreamToMediaInfo; | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| const configuration = require('src/config/configuration').getInstance(); | const configuration = require("../config/configuration").getInstance(); | ||||||
|  |  | ||||||
| function hookDumpController(req, res) { | function hookDumpController(req, res) { | ||||||
|    console.log(req); |   console.log(req); | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = hookDumpController; | module.exports = hookDumpController; | ||||||
|   | |||||||
| @@ -1,12 +1,11 @@ | |||||||
| const fetch = require("node-fetch"); | const fetch = require("node-fetch"); | ||||||
| const convertPlexToMovie = require("src/plex/convertPlexToMovie"); | const convertPlexToMovie = require("./convertPlexToMovie"); | ||||||
| const convertPlexToShow = require("src/plex/convertPlexToShow"); | const convertPlexToShow = require("./convertPlexToShow"); | ||||||
| const convertPlexToEpisode = require("src/plex/convertPlexToEpisode"); | const convertPlexToEpisode = require("./convertPlexToEpisode"); | ||||||
|  |  | ||||||
| const { Movie, Show, Person } = require("src/tmdb/types"); | const { Movie, Show, Person } = require("../tmdb/types"); | ||||||
|  |  | ||||||
| const RedisCache = require("src/cache/redis"); | const redisCache = require("../cache/redis"); | ||||||
| const redisCache = new RedisCache(); |  | ||||||
|  |  | ||||||
| const sanitize = string => string.toLowerCase().replace(/[^\w]/gi, ""); | const sanitize = string => string.toLowerCase().replace(/[^\w]/gi, ""); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,102 +1,110 @@ | |||||||
| const convertPlexToSeasoned = require('src/plex/convertPlexToSeasoned'); | const convertPlexToSeasoned = require("./convertPlexToSeasoned"); | ||||||
| const convertPlexToStream = require('src/plex/convertPlexToStream'); | const convertPlexToStream = require("./convertPlexToStream"); | ||||||
| const rp = require('request-promise'); | const rp = require("request-promise"); | ||||||
|  |  | ||||||
| class PlexRepository { | class PlexRepository { | ||||||
|    constructor(plexIP) { |   constructor(plexIP) { | ||||||
|     this.plexIP = plexIP; |     this.plexIP = plexIP; | ||||||
|    } |   } | ||||||
|  |  | ||||||
|    inPlex(tmdbResult) { |   inPlex(tmdbResult) { | ||||||
|       return Promise.resolve() |     return Promise.resolve() | ||||||
|          .then(() => this.search(tmdbResult.title)) |       .then(() => this.search(tmdbResult.title)) | ||||||
|          .then(plexResult => this.compareTmdbToPlex(tmdbResult, plexResult)) |       .then(plexResult => this.compareTmdbToPlex(tmdbResult, plexResult)) | ||||||
|          .catch((error) => { |       .catch(error => { | ||||||
|             console.log(error) |         console.log(error); | ||||||
|             tmdbResult.matchedInPlex = false; |         tmdbResult.matchedInPlex = false; | ||||||
|             return tmdbResult; |         return tmdbResult; | ||||||
|          }); |       }); | ||||||
|    } |   } | ||||||
|  |  | ||||||
|    search(query) { |   search(query) { | ||||||
|      const queryUri = encodeURIComponent(query) |     const queryUri = encodeURIComponent(query); | ||||||
|      const uri = encodeURI(`http://${this.plexIP}:32400/search?query=${queryUri}`) |     const uri = encodeURI( | ||||||
|       const options = { |       `http://${this.plexIP}:32400/search?query=${queryUri}` | ||||||
|          uri: uri, |     ); | ||||||
|          headers: { |     const options = { | ||||||
|             Accept: 'application/json', |       uri: uri, | ||||||
|          }, |       headers: { | ||||||
|          json: true, |         Accept: "application/json" | ||||||
|       }; |       }, | ||||||
|  |       json: true | ||||||
|  |     }; | ||||||
|  |  | ||||||
|       return rp(options) |     return rp(options) | ||||||
|          .catch((error) => { |       .catch(error => { | ||||||
|             console.log(error) |         console.log(error); | ||||||
|             throw new Error('Unable to search plex.') |         throw new Error("Unable to search plex."); | ||||||
|          }) |       }) | ||||||
|          .then(result => this.mapResults(result)) |       .then(result => this.mapResults(result)) | ||||||
|          .then(([mappedResults, resultCount]) => ({ results: mappedResults, total_results: resultCount })); |       .then(([mappedResults, resultCount]) => ({ | ||||||
|    } |         results: mappedResults, | ||||||
|  |         total_results: resultCount | ||||||
|  |       })); | ||||||
|  |   } | ||||||
|  |  | ||||||
|    compareTmdbToPlex(tmdb, plexResult) { |   compareTmdbToPlex(tmdb, plexResult) { | ||||||
|       return Promise.resolve() |     return Promise.resolve().then(() => { | ||||||
|          .then(() => { |       if (plexResult.results.length === 0) { | ||||||
|             if (plexResult.results.length === 0) { |         tmdb.matchedInPlex = false; | ||||||
|                tmdb.matchedInPlex = false |       } else { | ||||||
|             }  |         // console.log('plex and tmdb:', plexResult, '\n',  tmdb) | ||||||
|             else { |         plexResult.results.map(plexItem => { | ||||||
|                // console.log('plex and tmdb:', plexResult, '\n',  tmdb) |           if (tmdb.title === plexItem.title && tmdb.year === plexItem.year) | ||||||
|                plexResult.results.map((plexItem) => { |             tmdb.matchedInPlex = true; | ||||||
|                   if (tmdb.title === plexItem.title && tmdb.year === plexItem.year) |           return tmdb; | ||||||
|                      tmdb.matchedInPlex = true; |         }); | ||||||
|                   return tmdb; |       } | ||||||
|                }); |       return tmdb; | ||||||
|             } |     }); | ||||||
|             return tmdb; |   } | ||||||
|          }); |  | ||||||
|    } |  | ||||||
|  |  | ||||||
|    mapResults(response) { |   mapResults(response) { | ||||||
|       return Promise.resolve() |     return Promise.resolve() | ||||||
|          .then(() => { |       .then(() => { | ||||||
|             if (!response.MediaContainer.hasOwnProperty('Metadata')) return [[], 0]; |         if (!response.MediaContainer.hasOwnProperty("Metadata")) return [[], 0]; | ||||||
|  |  | ||||||
|             const mappedResults = response.MediaContainer.Metadata.filter((element) => { |         const mappedResults = response.MediaContainer.Metadata.filter( | ||||||
|                return (element.type === 'movie' || element.type === 'show'); |           element => { | ||||||
|             }).map((element) => convertPlexToSeasoned(element)); |             return element.type === "movie" || element.type === "show"; | ||||||
|             return [mappedResults, mappedResults.length]; |           } | ||||||
|          }) |         ).map(element => convertPlexToSeasoned(element)); | ||||||
|          .catch((error) => { throw new Error(error); }); |         return [mappedResults, mappedResults.length]; | ||||||
|    } |       }) | ||||||
|  |       .catch(error => { | ||||||
|  |         throw new Error(error); | ||||||
|  |       }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|    nowPlaying() { |   nowPlaying() { | ||||||
|       const options = { |     const options = { | ||||||
|          uri: `http://${this.plexIP}:32400/status/sessions`, |       uri: `http://${this.plexIP}:32400/status/sessions`, | ||||||
|          headers: { |       headers: { | ||||||
|             Accept: 'application/json', |         Accept: "application/json" | ||||||
|          }, |       }, | ||||||
|          json: true, |       json: true | ||||||
|       }; |     }; | ||||||
|  |  | ||||||
|       return rp(options) |     return rp(options) | ||||||
|          .then((result) => { |       .then(result => { | ||||||
|             if (result.MediaContainer.size > 0) { |         if (result.MediaContainer.size > 0) { | ||||||
|                const playing = result.MediaContainer.Metadata.map(convertPlexToStream); |           const playing = | ||||||
|                return { size: Object.keys(playing).length, video: playing }; |             result.MediaContainer.Metadata.map(convertPlexToStream); | ||||||
|             } |           return { size: Object.keys(playing).length, video: playing }; | ||||||
|             return { size: 0, video: [] }; |         } | ||||||
|          }) |         return { size: 0, video: [] }; | ||||||
|          .catch((err) => { |       }) | ||||||
|             throw new Error(`Error handling plex playing. Error: ${err}`); |       .catch(err => { | ||||||
|          }); |         throw new Error(`Error handling plex playing. Error: ${err}`); | ||||||
|    } |       }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|    // multipleInPlex(tmdbResults) { |   // multipleInPlex(tmdbResults) { | ||||||
|    //    const results = tmdbResults.results.map(async (tmdb) => { |   //    const results = tmdbResults.results.map(async (tmdb) => { | ||||||
|    //       return this.inPlex(tmdb) |   //       return this.inPlex(tmdb) | ||||||
|    //    }) |   //    }) | ||||||
|    //    return Promise.all(results) |   //    return Promise.all(results) | ||||||
|    // } |   // } | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = PlexRepository; | module.exports = PlexRepository; | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| const PlexRepository = require("src/plex/plexRepository"); | const PlexRepository = require("./plexRepository"); | ||||||
| const configuration = require("src/config/configuration").getInstance(); | const configuration = require("../config/configuration").getInstance(); | ||||||
| const TMDB = require("src/tmdb/tmdb"); | const TMDB = require("../tmdb/tmdb"); | ||||||
| const establishedDatabase = require("src/database/database"); | const establishedDatabase = require("../database/database"); | ||||||
|  |  | ||||||
| const plexRepository = new PlexRepository(configuration.get("plex", "ip")); | const plexRepository = new PlexRepository(configuration.get("plex", "ip")); | ||||||
| const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | ||||||
|   | |||||||
| @@ -1,13 +1,13 @@ | |||||||
| const Player = require('src/media_classes/player'); | const Player = require("../../media_classes/player"); | ||||||
|  |  | ||||||
| function convertStreamToPlayer(plexStream) { | function convertStreamToPlayer(plexStream) { | ||||||
|    const player = new Player(plexStream.device, plexStream.address); |   const player = new Player(plexStream.device, plexStream.address); | ||||||
|    player.platform = plexStream.platform; |   player.platform = plexStream.platform; | ||||||
|    player.product = plexStream.product; |   player.product = plexStream.product; | ||||||
|    player.title = plexStream.title; |   player.title = plexStream.title; | ||||||
|    player.state = plexStream.state; |   player.state = plexStream.state; | ||||||
|  |  | ||||||
|    return player; |   return player; | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = convertStreamToPlayer; | module.exports = convertStreamToPlayer; | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| const User = require('src/media_classes/user'); | const User = require("../../media_classes/user"); | ||||||
|  |  | ||||||
| function convertStreamToUser(plexStream) { | function convertStreamToUser(plexStream) { | ||||||
|    return new User(plexStream.id, plexStream.title); |   return new User(plexStream.id, plexStream.title); | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = convertStreamToUser; | module.exports = convertStreamToUser; | ||||||
|   | |||||||
| @@ -1,28 +1,34 @@ | |||||||
| const assert = require('assert') | const assert = require("assert"); | ||||||
| const configuration = require('src/config/configuration').getInstance(); | const configuration = require("../config/configuration").getInstance(); | ||||||
| const TMDB = require('src/tmdb/tmdb'); | const TMDB = require("../tmdb/tmdb"); | ||||||
| const tmdb = new TMDB(configuration.get('tmdb', 'apiKey')); | const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | ||||||
| const establishedDatabase = require('src/database/database'); | const establishedDatabase = require("../database/database"); | ||||||
| const utils = require('./utils'); | const utils = require("./utils"); | ||||||
|  |  | ||||||
| class RequestRepository { | class RequestRepository { | ||||||
|   constructor(database) { |   constructor(database) { | ||||||
|     this.database = database || establishedDatabase; |     this.database = database || establishedDatabase; | ||||||
|     this.queries = { |     this.queries = { | ||||||
|       add: 'insert into requests (id,title,year,poster_path,background_path,requested_by,ip,user_agent,type) values(?,?,?,?,?,?,?,?,?)', |       add: "insert into requests (id,title,year,poster_path,background_path,requested_by,ip,user_agent,type) values(?,?,?,?,?,?,?,?,?)", | ||||||
|       fetchAll: 'select * from requests where status != "downloaded" order by date desc LIMIT 25 OFFSET ?*25-25', |       fetchAll: | ||||||
|       fetchAllFilteredStatus: 'select * from requests where status = ? order by date desc LIMIT 25 offset ?*25-25', |         'select * from requests where status != "downloaded" order by date desc LIMIT 25 OFFSET ?*25-25', | ||||||
|       totalRequests: 'select count(*) as totalRequests from requests where status != "downloaded"', |       fetchAllFilteredStatus: | ||||||
|       totalRequestsFilteredStatus: 'select count(*) as totalRequests from requests where status = ?', |         "select * from requests where status = ? order by date desc LIMIT 25 offset ?*25-25", | ||||||
|  |       totalRequests: | ||||||
|  |         'select count(*) as totalRequests from requests where status != "downloaded"', | ||||||
|  |       totalRequestsFilteredStatus: | ||||||
|  |         "select count(*) as totalRequests from requests where status = ?", | ||||||
|       fetchAllSort: `select id, type from request order by ? ?`, |       fetchAllSort: `select id, type from request order by ? ?`, | ||||||
|       fetchAllFilter: `select id, type from request where ? is "?"`, |       fetchAllFilter: `select id, type from request where ? is "?"`, | ||||||
|       fetchAllQuery: `select id, type from request where title like "%?%" or year like "%?%"`, |       fetchAllQuery: `select id, type from request where title like "%?%" or year like "%?%"`, | ||||||
|       fetchAllFilterAndSort: `select id, type from request where ? is "?" order by ? ?`, |       fetchAllFilterAndSort: `select id, type from request where ? is "?" order by ? ?`, | ||||||
|       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 ?', |       readWithoutUserData: | ||||||
|       read: 'select id, title, year, type, status, requested_by, ip, date, user_agent from requests where id is ? and type is ?' |         "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 ?" | ||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -31,52 +37,58 @@ class RequestRepository { | |||||||
|  |  | ||||||
|     if (query !== undefined) { |     if (query !== undefined) { | ||||||
|       const dbParams = [query, query]; |       const dbParams = [query, query]; | ||||||
|       const dbquery = this.queries.fetchAllQuery |       const dbquery = this.queries.fetchAllQuery; | ||||||
|  |  | ||||||
|       dbQuery = dbquery.split('').map((char) => char === '?' ? dbParams.shift() : char).join('') |       dbQuery = dbquery | ||||||
|     } |         .split("") | ||||||
|     else if (by !== undefined && filter !== undefined) { |         .map(char => (char === "?" ? dbParams.shift() : char)) | ||||||
|  |         .join(""); | ||||||
|  |     } else if (by !== undefined && filter !== undefined) { | ||||||
|       const paramToColumnAndValue = { |       const paramToColumnAndValue = { | ||||||
|         movie: ['type', 'movie'], |         movie: ["type", "movie"], | ||||||
|         show: ['type', 'show'] |         show: ["type", "show"] | ||||||
|       } |       }; | ||||||
|       const dbParams = paramToColumnAndValue[filter].concat([by, direction]); |       const dbParams = paramToColumnAndValue[filter].concat([by, direction]); | ||||||
|       const query = this.queries.fetchAllFilterAndSort; |       const query = this.queries.fetchAllFilterAndSort; | ||||||
|  |  | ||||||
|       dbQuery = query.split('').map((char) => char === '?' ? dbParams.shift() : char).join('') |       dbQuery = query | ||||||
|     } |         .split("") | ||||||
|     else if (by !== undefined) { |         .map(char => (char === "?" ? dbParams.shift() : char)) | ||||||
|  |         .join(""); | ||||||
|  |     } else if (by !== undefined) { | ||||||
|       const dbParams = [by, direction]; |       const dbParams = [by, direction]; | ||||||
|       const query = this.queries.fetchAllSort; |       const query = this.queries.fetchAllSort; | ||||||
|  |  | ||||||
|       dbQuery = query.split('').map((char) => char === '?' ? dbParams.shift() : char).join('') |       dbQuery = query | ||||||
|     } |         .split("") | ||||||
|     else if (filter !== undefined) { |         .map(char => (char === "?" ? dbParams.shift() : char)) | ||||||
|  |         .join(""); | ||||||
|  |     } else if (filter !== undefined) { | ||||||
|       const paramToColumnAndValue = { |       const paramToColumnAndValue = { | ||||||
|         movie: ['type', 'movie'], |         movie: ["type", "movie"], | ||||||
|         show: ['type', 'show'], |         show: ["type", "show"], | ||||||
|         downloaded: [this.queries.downloaded, 'downloaded'] |         downloaded: [this.queries.downloaded, "downloaded"] | ||||||
|         // downloading: [this.database.delugeStatus, 'downloading'] |         // downloading: [this.database.delugeStatus, 'downloading'] | ||||||
|       } |       }; | ||||||
|       const dbParams = paramToColumnAndValue[filter] |       const dbParams = paramToColumnAndValue[filter]; | ||||||
|       const query = this.queries.fetchAllFilter; |       const query = this.queries.fetchAllFilter; | ||||||
|  |  | ||||||
|       dbQuery = query.split('').map((char) => char === '?' ? dbParams.shift() : char).join('') |       dbQuery = query | ||||||
|     } |         .split("") | ||||||
|     else { |         .map(char => (char === "?" ? dbParams.shift() : char)) | ||||||
|  |         .join(""); | ||||||
|  |     } else { | ||||||
|       dbQuery = this.queries.fetchAll; |       dbQuery = this.queries.fetchAll; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return dbQuery |     return dbQuery; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   mapToTmdbByType(rows) { |   mapToTmdbByType(rows) { | ||||||
|     return rows.map((row) => { |     return rows.map(row => { | ||||||
|       if (row.type === 'movie') |       if (row.type === "movie") return tmdb.movieInfo(row.id); | ||||||
|         return tmdb.movieInfo(row.id) |       else if (row.type === "show") return tmdb.showInfo(row.id); | ||||||
|       else if (row.type === 'show') |     }); | ||||||
|         return tmdb.showInfo(row.id) |  | ||||||
|     }) |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
| @@ -87,14 +99,31 @@ class RequestRepository { | |||||||
|   requestFromTmdb(tmdb, ip, user_agent, username) { |   requestFromTmdb(tmdb, ip, user_agent, username) { | ||||||
|     return Promise.resolve() |     return Promise.resolve() | ||||||
|       .then(() => this.database.get(this.queries.read, [tmdb.id, tmdb.type])) |       .then(() => this.database.get(this.queries.read, [tmdb.id, tmdb.type])) | ||||||
|       .then(row => assert.equal(row, undefined, 'Id has already been requested')) |       .then(row => | ||||||
|       .then(() => this.database.run(this.queries.add, [tmdb.id, tmdb.title, tmdb.year, tmdb.poster, tmdb.backdrop, username, ip, user_agent, tmdb.type])) |         assert.equal(row, undefined, "Id has already been requested") | ||||||
|       .catch((error) => { |       ) | ||||||
|         if (error.name === 'AssertionError' || error.message.endsWith('been requested')) { |       .then(() => | ||||||
|           throw new Error('This id is already requested', error.message); |         this.database.run(this.queries.add, [ | ||||||
|  |           tmdb.id, | ||||||
|  |           tmdb.title, | ||||||
|  |           tmdb.year, | ||||||
|  |           tmdb.poster, | ||||||
|  |           tmdb.backdrop, | ||||||
|  |           username, | ||||||
|  |           ip, | ||||||
|  |           user_agent, | ||||||
|  |           tmdb.type | ||||||
|  |         ]) | ||||||
|  |       ) | ||||||
|  |       .catch(error => { | ||||||
|  |         if ( | ||||||
|  |           error.name === "AssertionError" || | ||||||
|  |           error.message.endsWith("been requested") | ||||||
|  |         ) { | ||||||
|  |           throw new Error("This id is already requested", error.message); | ||||||
|         } |         } | ||||||
|         console.log('Error @ request.addTmdb:', error); |         console.log("Error @ request.addTmdb:", error); | ||||||
|         throw new Error('Could not add request'); |         throw new Error("Could not add request"); | ||||||
|       }); |       }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -105,9 +134,10 @@ class RequestRepository { | |||||||
|    * @returns {Promise} |    * @returns {Promise} | ||||||
|    */ |    */ | ||||||
|   getRequestByIdAndType(id, type) { |   getRequestByIdAndType(id, type) { | ||||||
|     return this.database.get(this.queries.readWithoutUserData, [id, type]) |     return this.database | ||||||
|  |       .get(this.queries.readWithoutUserData, [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 { |         return { | ||||||
|           id: row.id, |           id: row.id, | ||||||
|           title: row.title, |           title: row.title, | ||||||
| @@ -115,8 +145,8 @@ class RequestRepository { | |||||||
|           type: row.type, |           type: row.type, | ||||||
|           status: row.status, |           status: row.status, | ||||||
|           requested_date: new Date(row.date) |           requested_date: new Date(row.date) | ||||||
|         } |         }; | ||||||
|       }) |       }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
| @@ -127,40 +157,68 @@ class RequestRepository { | |||||||
|    * @param {String} query param to filter result on. Filters on title and year |    * @param {String} query param to filter result on. Filters on title and year | ||||||
|    * @returns {Promise} |    * @returns {Promise} | ||||||
|    */ |    */ | ||||||
|   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) |     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]; | ||||||
|  |  | ||||||
|     if (filter && (filter === 'downloading' || filter === 'downloaded' || filter === 'requested')) { |     if ( | ||||||
|       console.log('tes') |       filter && | ||||||
|       fetchQuery = this.queries.fetchAllFilteredStatus |       (filter === "downloading" || | ||||||
|       fetchTotalResults = this.queries.totalRequestsFilteredStatus |         filter === "downloaded" || | ||||||
|       fetchParams = [filter, page] |         filter === "requested") | ||||||
|  |     ) { | ||||||
|  |       console.log("tes"); | ||||||
|  |       fetchQuery = this.queries.fetchAllFilteredStatus; | ||||||
|  |       fetchTotalResults = this.queries.totalRequestsFilteredStatus; | ||||||
|  |       fetchParams = [filter, page]; | ||||||
|     } else { |     } else { | ||||||
|       filter = undefined |       filter = undefined; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return Promise.resolve() |     return Promise.resolve() | ||||||
|       .then((dbQuery) => this.database.all(fetchQuery, fetchParams)) |       .then(dbQuery => this.database.all(fetchQuery, fetchParams)) | ||||||
|       .then(async (rows) => { |       .then(async rows => { | ||||||
|         const sqliteResponse = await this.database.get(fetchTotalResults, filter ? filter : undefined) |         const sqliteResponse = await this.database.get( | ||||||
|         const totalRequests = sqliteResponse['totalRequests'] |           fetchTotalResults, | ||||||
|         const totalPages = Math.ceil(totalRequests / 26) |           filter ? filter : undefined | ||||||
|  |         ); | ||||||
|  |         const totalRequests = sqliteResponse["totalRequests"]; | ||||||
|  |         const totalPages = Math.ceil(totalRequests / 26); | ||||||
|  |  | ||||||
|         return [ rows.map(item => { |         return [ | ||||||
|           item.poster = item.poster_path; delete item.poster_path; |           rows.map(item => { | ||||||
|           item.backdrop = item.background_path; delete item.background_path; |             item.poster = item.poster_path; | ||||||
|           return item |             delete item.poster_path; | ||||||
|         }), totalPages, totalRequests ] |             item.backdrop = item.background_path; | ||||||
|         return Promise.all(this.mapToTmdbByType(rows)) |             delete item.background_path; | ||||||
| }) |             return item; | ||||||
|       .then(([result, totalPages, totalRequests]) => Promise.resolve({ |           }), | ||||||
|         results: result, total_results: totalRequests, page: page, total_pages: totalPages |           totalPages, | ||||||
|       })) |           totalRequests | ||||||
|       .catch(error => { console.log(error);throw error }) |         ]; | ||||||
|  |         return Promise.all(this.mapToTmdbByType(rows)); | ||||||
|  |       }) | ||||||
|  |       .then(([result, totalPages, totalRequests]) => | ||||||
|  |         Promise.resolve({ | ||||||
|  |           results: result, | ||||||
|  |           total_results: totalRequests, | ||||||
|  |           page: page, | ||||||
|  |           total_pages: totalPages | ||||||
|  |         }) | ||||||
|  |       ) | ||||||
|  |       .catch(error => { | ||||||
|  |         console.log(error); | ||||||
|  |         throw error; | ||||||
|  |       }); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,52 +1,57 @@ | |||||||
| const establishedDatabase = require('src/database/database'); | const establishedDatabase = require("../database/database"); | ||||||
|  |  | ||||||
| class SearchHistory { | class SearchHistory { | ||||||
|    constructor(database) { |   constructor(database) { | ||||||
|       this.database = database || establishedDatabase; |     this.database = database || establishedDatabase; | ||||||
|       this.queries = { |     this.queries = { | ||||||
|          'create': 'insert into search_history (search_query, user_name) values (?, ?)', |       create: | ||||||
|          'read': 'select search_query from search_history where user_name = ? order by id desc', |         "insert into search_history (search_query, user_name) values (?, ?)", | ||||||
|       }; |       read: "select search_query from search_history where user_name = ? order by id desc" | ||||||
|    } |     }; | ||||||
|  |   } | ||||||
|  |  | ||||||
|    /** |   /** | ||||||
|    * Retrive a search queries for a user from the database. |    * Retrive a search queries for a user from the database. | ||||||
|    * @param {User} user existing user |    * @param {User} user existing user | ||||||
|    * @returns {Promise} |    * @returns {Promise} | ||||||
|    */ |    */ | ||||||
|    read(user) { |   read(user) { | ||||||
|       return new Promise((resolve, reject) => this.database.all(this.queries.read, user) |     return new Promise((resolve, reject) => | ||||||
|          .then((result, error) => { |       this.database | ||||||
|             if (error) throw new Error(error); |         .all(this.queries.read, user) | ||||||
|             resolve(result.map(row => row.search_query)); |         .then((result, error) => { | ||||||
|          }) |           if (error) throw new Error(error); | ||||||
|          .catch((error) => { |           resolve(result.map(row => row.search_query)); | ||||||
|             console.log('Error when fetching history from database:', error) |         }) | ||||||
|             reject('Unable to get history.'); |         .catch(error => { | ||||||
|          })); |           console.log("Error when fetching history from database:", error); | ||||||
|    } |           reject("Unable to get history."); | ||||||
|  |         }) | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|    /** |   /** | ||||||
|    * Creates a new search entry in the database. |    * Creates a new search entry in the database. | ||||||
|    * @param {String} username logged in user doing the search |    * @param {String} username logged in user doing the search | ||||||
|    * @param {String} searchQuery the query the user searched for |    * @param {String} searchQuery the query the user searched for | ||||||
|    * @returns {Promise} |    * @returns {Promise} | ||||||
|    */ |    */ | ||||||
|    create(username, searchQuery) { |   create(username, searchQuery) { | ||||||
|       return this.database.run(this.queries.create, [searchQuery, username]) |     return this.database | ||||||
|          .catch(error => { |       .run(this.queries.create, [searchQuery, username]) | ||||||
|             if (error.message.includes('FOREIGN')) { |       .catch(error => { | ||||||
|                throw new Error('Could not create search history.'); |         if (error.message.includes("FOREIGN")) { | ||||||
|             } |           throw new Error("Could not create search history."); | ||||||
|  |         } | ||||||
|  |  | ||||||
|             throw { |         throw { | ||||||
|                success: false, |           success: false, | ||||||
|                status: 500, |           status: 500, | ||||||
|                message: 'An unexpected error occured', |           message: "An unexpected error occured", | ||||||
|                source: 'database' |           source: "database" | ||||||
|             } |         }; | ||||||
|          }); |       }); | ||||||
|    } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = SearchHistory; | module.exports = SearchHistory; | ||||||
|   | |||||||
| @@ -1,62 +1,68 @@ | |||||||
| const assert = require('assert'); | const assert = require("assert"); | ||||||
| const Stray = require('src/seasoned/stray'); | const Stray = require("./stray"); | ||||||
| const establishedDatabase = require('src/database/database'); | const establishedDatabase = require("../database/database"); | ||||||
| const pythonShell = require('python-shell'); | const pythonShell = require("python-shell"); | ||||||
|  |  | ||||||
| class StrayRepository { | class StrayRepository { | ||||||
|    constructor(database) { |   constructor(database) { | ||||||
|       this.database = database || establishedDatabase; |     this.database = database || establishedDatabase; | ||||||
|       this.queries = { |     this.queries = { | ||||||
|          read: 'SELECT * FROM stray_eps WHERE id = ?', |       read: "SELECT * FROM stray_eps WHERE id = ?", | ||||||
|          readAll: 'SELECT id, name, season, episode, verified FROM stray_eps', |       readAll: "SELECT id, name, season, episode, verified FROM stray_eps", | ||||||
|          readAllFiltered: 'SELECT id, name, season, episode, verified FROM stray_eps WHERE verified = ', |       readAllFiltered: | ||||||
|          checkVerified: 'SELECT id FROM stray_eps WHERE verified = 0 AND id = ?', |         "SELECT id, name, season, episode, verified FROM stray_eps WHERE verified = ", | ||||||
|          verify: 'UPDATE stray_eps SET verified = 1 WHERE id = ?', |       checkVerified: "SELECT id FROM stray_eps WHERE verified = 0 AND id = ?", | ||||||
|  |       verify: "UPDATE stray_eps SET verified = 1 WHERE id = ?" | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   read(strayId) { | ||||||
|  |     return this.database.get(this.queries.read, strayId).then(row => { | ||||||
|  |       assert.notEqual( | ||||||
|  |         row, | ||||||
|  |         undefined, | ||||||
|  |         `Could not find list with id ${strayId}.` | ||||||
|  |       ); | ||||||
|  |       return row; | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   readAll(verified = null) { | ||||||
|  |     let dbSearchQuery = this.queries.readAll; | ||||||
|  |     if (verified != null) { | ||||||
|  |       dbSearchQuery = this.queries.readAllFiltered + verified.toString(); | ||||||
|  |     } | ||||||
|  |     return this.database.all(dbSearchQuery).then(rows => | ||||||
|  |       rows.map(row => { | ||||||
|  |         const stray = new Stray(row.id); | ||||||
|  |         stray.name = row.name; | ||||||
|  |         stray.season = row.season; | ||||||
|  |         stray.episode = row.episode; | ||||||
|  |         stray.verified = row.verified; | ||||||
|  |         return stray; | ||||||
|  |       }) | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   verifyStray(strayId) { | ||||||
|  |     return this.database.get(this.queries.checkVerified, strayId).then(row => { | ||||||
|  |       assert.notEqual(row, undefined, `Stray '${strayId}' already verified.`); | ||||||
|  |  | ||||||
|  |       const options = { | ||||||
|  |         pythonPath: "../app/env/bin/python3", | ||||||
|  |         args: [strayId] | ||||||
|       }; |       }; | ||||||
|    } |  | ||||||
|  |  | ||||||
|    read(strayId) { |       pythonShell.run("../app/moveSeasoned.py", options, (err, results) => { | ||||||
|       return this.database.get(this.queries.read, strayId).then((row) => { |         if (err) throw err; | ||||||
|          assert.notEqual(row, undefined, `Could not find list with id ${strayId}.`); |         // TODO Add error handling!! StrayRepository.ERROR | ||||||
|          return row; |         // results is an array consisting of messages collected during execution | ||||||
|  |         console.log("results: %j", results); | ||||||
|       }); |       }); | ||||||
|    } |  | ||||||
|  |  | ||||||
|    readAll(verified = null) { |       return this.database.run(this.queries.verify, strayId); | ||||||
|       let dbSearchQuery = this.queries.readAll; |     }); | ||||||
|       if (verified != null) { |   } | ||||||
|          dbSearchQuery = this.queries.readAllFiltered + verified.toString(); |  | ||||||
|       } |  | ||||||
|       return this.database.all(dbSearchQuery).then(rows => |  | ||||||
|          rows.map((row) => { |  | ||||||
|             const stray = new Stray(row.id); |  | ||||||
|             stray.name = row.name; |  | ||||||
|             stray.season = row.season; |  | ||||||
|             stray.episode = row.episode; |  | ||||||
|             stray.verified = row.verified; |  | ||||||
|             return stray; |  | ||||||
|          })); |  | ||||||
|    } |  | ||||||
|  |  | ||||||
|    verifyStray(strayId) { |  | ||||||
|       return this.database.get(this.queries.checkVerified, strayId).then((row) => { |  | ||||||
|          assert.notEqual(row, undefined, `Stray '${strayId}' already verified.`); |  | ||||||
|  |  | ||||||
|          const options = { |  | ||||||
| 	    pythonPath: '../app/env/bin/python3', |  | ||||||
|             args: [strayId], |  | ||||||
|          }; |  | ||||||
|  |  | ||||||
|          pythonShell.run('../app/moveSeasoned.py', options, (err, results) => { |  | ||||||
|             if (err) throw err; |  | ||||||
|             // TODO Add error handling!! StrayRepository.ERROR |  | ||||||
|             // results is an array consisting of messages collected during execution |  | ||||||
|             console.log('results: %j', results); |  | ||||||
|          }); |  | ||||||
|  |  | ||||||
|          return this.database.run(this.queries.verify, strayId); |  | ||||||
|       }); |  | ||||||
|    } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = StrayRepository; | module.exports = StrayRepository; | ||||||
|   | |||||||
| @@ -1,44 +1,48 @@ | |||||||
| const assert = require('assert'); | const assert = require("assert"); | ||||||
| const establishedDatabase = require('src/database/database'); | const establishedDatabase = require("../database/database"); | ||||||
|  |  | ||||||
| class Cache { | class Cache { | ||||||
|    constructor(database) { |   constructor(database) { | ||||||
|       this.database = database || establishedDatabase; |     this.database = database || establishedDatabase; | ||||||
|       this.queries = { |     this.queries = { | ||||||
|          read: 'SELECT value, time_to_live, created_at, DATETIME("now", "localtime") as now, ' + |       read: | ||||||
|          'DATETIME(created_at, "+" || time_to_live || " seconds") as expires ' + |         'SELECT value, time_to_live, created_at, DATETIME("now", "localtime") as now, ' + | ||||||
|          'FROM cache WHERE key = ? AND now < expires', |         'DATETIME(created_at, "+" || time_to_live || " seconds") as expires ' + | ||||||
|          create: 'INSERT OR REPLACE INTO cache (key, value, time_to_live) VALUES (?, ?, ?)', |         "FROM cache WHERE key = ? AND now < expires", | ||||||
|       }; |       create: | ||||||
|    } |         "INSERT OR REPLACE INTO cache (key, value, time_to_live) VALUES (?, ?, ?)" | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  |  | ||||||
|    /** |   /** | ||||||
|     * Retrieve an unexpired cache entry by key. |    * Retrieve an unexpired cache entry by key. | ||||||
|     * @param {String} key of the cache entry |    * @param {String} key of the cache entry | ||||||
|     * @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 entry with that key.'); |         assert(row, "Could not find cache entry with that key."); | ||||||
|          return JSON.parse(row.value); |         return JSON.parse(row.value); | ||||||
|        }) |       }); | ||||||
|    } |   } | ||||||
|  |  | ||||||
|    /** |   /** | ||||||
|     * Insert cache entry with key and value. |    * Insert cache entry with key and value. | ||||||
|     * @param {String} key of the cache entry |    * @param {String} key of the cache entry | ||||||
|     * @param {String} value of the cache entry |    * @param {String} value of the cache entry | ||||||
|     * @param {Number} timeToLive the number of seconds before entry expires |    * @param {Number} timeToLive the number of seconds before entry expires | ||||||
|     * @returns {Object} |    * @returns {Object} | ||||||
|     */ |    */ | ||||||
|    set(key, value, timeToLive = 10800) { |   set(key, value, timeToLive = 10800) { | ||||||
|       const json = JSON.stringify(value); |     const json = JSON.stringify(value); | ||||||
|       return Promise.resolve() |     return Promise.resolve() | ||||||
|          .then(() => this.database.run(this.queries.create, [key, json, timeToLive])) |       .then(() => | ||||||
|          .then(() => value); |         this.database.run(this.queries.create, [key, json, timeToLive]) | ||||||
|    } |       ) | ||||||
|  |       .then(() => value); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = Cache; | module.exports = Cache; | ||||||
|   | |||||||
| @@ -1,14 +1,7 @@ | |||||||
| const moviedb = require("km-moviedb"); | const moviedb = require("km-moviedb"); | ||||||
| const RedisCache = require("src/cache/redis"); | const redisCache = require("../cache/redis"); | ||||||
| const redisCache = new RedisCache(); |  | ||||||
|  |  | ||||||
| const { | const { Movie, Show, Person, Credits, ReleaseDates } = require("./types"); | ||||||
|   Movie, |  | ||||||
|   Show, |  | ||||||
|   Person, |  | ||||||
|   Credits, |  | ||||||
|   ReleaseDates |  | ||||||
| } = require("src/tmdb/types"); |  | ||||||
|  |  | ||||||
| const tmdbErrorResponse = (error, typeString = undefined) => { | const tmdbErrorResponse = (error, typeString = undefined) => { | ||||||
|   if (error.status === 404) { |   if (error.status === 404) { | ||||||
| @@ -107,14 +100,20 @@ class TMDB { | |||||||
|    * @returns {Promise} movie release dates object |    * @returns {Promise} movie release dates object | ||||||
|    */ |    */ | ||||||
|   movieReleaseDates(identifier) { |   movieReleaseDates(identifier) { | ||||||
|     const query = { id: identifier } |     const query = { id: identifier }; | ||||||
|     const cacheKey = `tmdb/${this.cacheTags.movieReleaseDates}:${identifier}` |     const cacheKey = `tmdb/${this.cacheTags.movieReleaseDates}:${identifier}`; | ||||||
|  |  | ||||||
|     return this.getFromCacheOrFetchFromTmdb(cacheKey, 'movieReleaseDates', query) |     return this.getFromCacheOrFetchFromTmdb( | ||||||
|       .then(releaseDates => this.cache.set(cacheKey, releaseDates, this.defaultTTL)) |       cacheKey, | ||||||
|       .then(releaseDates => ReleaseDates.convertFromTmdbResponse(releaseDates)) |       "movieReleaseDates", | ||||||
|  |       query | ||||||
|  |     ) | ||||||
|  |       .then(releaseDates => | ||||||
|  |         this.cache.set(cacheKey, releaseDates, this.defaultTTL) | ||||||
|  |       ) | ||||||
|  |       .then(releaseDates => ReleaseDates.convertFromTmdbResponse(releaseDates)); | ||||||
|   } |   } | ||||||
|   |  | ||||||
|   /** |   /** | ||||||
|    * Retrieve a specific show by id from TMDB. |    * Retrieve a specific show by id from TMDB. | ||||||
|    * @param {Number} identifier of the show you want to retrieve |    * @param {Number} identifier of the show you want to retrieve | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| const User = require("src/user/user"); | const User = require("./user"); | ||||||
| const jwt = require("jsonwebtoken"); | const jwt = require("jsonwebtoken"); | ||||||
|  |  | ||||||
| class Token { | class Token { | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| const assert = require("assert"); | const assert = require("assert"); | ||||||
| const establishedDatabase = require("src/database/database"); | const establishedDatabase = require("../database/database"); | ||||||
|  |  | ||||||
| class UserRepository { | class UserRepository { | ||||||
|   constructor(database) { |   constructor(database) { | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| const bcrypt = require("bcrypt"); | const bcrypt = require("bcrypt"); | ||||||
| const UserRepository = require("src/user/userRepository"); | const UserRepository = require("./userRepository"); | ||||||
|  |  | ||||||
| class UserSecurity { | class UserSecurity { | ||||||
|   constructor(database) { |   constructor(database) { | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ const Raven = require("raven"); | |||||||
| const cookieParser = require("cookie-parser"); | const cookieParser = require("cookie-parser"); | ||||||
| const bodyParser = require("body-parser"); | const bodyParser = require("body-parser"); | ||||||
|  |  | ||||||
| const configuration = require("src/config/configuration").getInstance(); | const configuration = require("../config/configuration").getInstance(); | ||||||
|  |  | ||||||
| const reqTokenToUser = require("./middleware/reqTokenToUser"); | const reqTokenToUser = require("./middleware/reqTokenToUser"); | ||||||
| const mustBeAuthenticated = require("./middleware/mustBeAuthenticated"); | const mustBeAuthenticated = require("./middleware/mustBeAuthenticated"); | ||||||
|   | |||||||
| @@ -1,15 +1,16 @@ | |||||||
| const GitRepository = require('src/git/gitRepository'); | const GitRepository = require("../../../git/gitRepository"); | ||||||
|  |  | ||||||
| const gitRepository = new GitRepository(); | const gitRepository = new GitRepository(); | ||||||
|  |  | ||||||
| function dumpHookController(req, res) { | function dumpHookController(req, res) { | ||||||
|    gitRepository.dumpHook(req.body) |   gitRepository | ||||||
|       .then(() => { |     .dumpHook(req.body) | ||||||
|          res.status(200); |     .then(() => { | ||||||
|       }) |       res.status(200); | ||||||
|       .catch((error) => { |     }) | ||||||
|          res.status(500); |     .catch(error => { | ||||||
|       }); |       res.status(500); | ||||||
|  |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = dumpHookController; | module.exports = dumpHookController; | ||||||
|   | |||||||
| @@ -1,15 +1,15 @@ | |||||||
| const configuration = require('src/config/configuration').getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
| const TMDB = require('src/tmdb/tmdb'); | const TMDB = require("../../../tmdb/tmdb"); | ||||||
| const tmdb = new TMDB(configuration.get('tmdb', 'apiKey')); | const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | ||||||
|  |  | ||||||
| // there should be a translate function from query params to  | // there should be a translate function from query params to | ||||||
| // tmdb list that is valid. Should it be a helper function or does it  | // tmdb list that is valid. Should it be a helper function or does it | ||||||
| // belong in tmdb.  | // belong in tmdb. | ||||||
| // + could also have default value that are sent to the client. | // + could also have default value that are sent to the client. | ||||||
| //   * have the same class create a getListNames() and a fetchList() | //   * have the same class create a getListNames() and a fetchList() | ||||||
| // * dicover list might be overkill_https://tinyurl.com/y7f8ragw | // * dicover list might be overkill_https://tinyurl.com/y7f8ragw | ||||||
| // + trending! https://tinyurl.com/ydywrqox  | // + trending! https://tinyurl.com/ydywrqox | ||||||
| //   by all, mediatype, or person. Can also define time periode to  | //   by all, mediatype, or person. Can also define time periode to | ||||||
| //   get more trending view of what people are checking out. | //   get more trending view of what people are checking out. | ||||||
| // + newly created (tv/latest). | // + newly created (tv/latest). | ||||||
| // + movie/latest | // + movie/latest | ||||||
| @@ -18,44 +18,57 @@ function handleError(error, res) { | |||||||
|   const { status, message } = error; |   const { status, message } = error; | ||||||
|  |  | ||||||
|   if (status && message) { |   if (status && message) { | ||||||
|     res.status(status).send({ success: false, message }) |     res.status(status).send({ success: false, message }); | ||||||
|   } else { |   } else { | ||||||
|     console.log('caught list controller error', error) |     console.log("caught list controller error", error); | ||||||
|     res.status(500).send({ message: 'An unexpected error occured while requesting list'}) |     res | ||||||
|  |       .status(500) | ||||||
|  |       .send({ message: "An unexpected error occured while requesting list" }); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| function handleListResponse(response, res) { | function handleListResponse(response, res) { | ||||||
|   return res.send(response) |   return res.send(response).catch(error => handleError(error, res)); | ||||||
|     .catch(error => handleError(error, res)) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| function fetchTmdbList(req, res, listname, type) { | function fetchTmdbList(req, res, listname, type) { | ||||||
|   const { page } = req.query; |   const { page } = req.query; | ||||||
|  |  | ||||||
|   if (type === 'movie') { |   if (type === "movie") { | ||||||
|     return tmdb.movieList(listname, page) |     return tmdb | ||||||
|  |       .movieList(listname, page) | ||||||
|       .then(listResponse => res.send(listResponse)) |       .then(listResponse => res.send(listResponse)) | ||||||
|       .catch(error => handleError(error, res)) |       .catch(error => handleError(error, res)); | ||||||
|   } else if (type === 'show') { |   } else if (type === "show") { | ||||||
|     return tmdb.showList(listname, page) |     return tmdb | ||||||
|  |       .showList(listname, page) | ||||||
|       .then(listResponse => res.send(listResponse)) |       .then(listResponse => res.send(listResponse)) | ||||||
|       .catch(error => handleError(error, res)) |       .catch(error => handleError(error, res)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleError({ |   handleError( | ||||||
|     status: 400, |     { | ||||||
|     message: `'${type}' is not a valid list type.` |       status: 400, | ||||||
|   }, res) |       message: `'${type}' is not a valid list type.` | ||||||
|  |     }, | ||||||
|  |     res | ||||||
|  |   ); | ||||||
| } | } | ||||||
|  |  | ||||||
| const nowPlayingMovies = (req, res) => fetchTmdbList(req, res, 'miscNowPlayingMovies', 'movie') | const nowPlayingMovies = (req, res) => | ||||||
| const popularMovies = (req, res) => fetchTmdbList(req, res, 'miscPopularMovies', 'movie') |   fetchTmdbList(req, res, "miscNowPlayingMovies", "movie"); | ||||||
| const topRatedMovies = (req, res) => fetchTmdbList(req, res, 'miscTopRatedMovies', 'movie') | const popularMovies = (req, res) => | ||||||
| const upcomingMovies = (req, res) => fetchTmdbList(req, res, 'miscUpcomingMovies', 'movie') |   fetchTmdbList(req, res, "miscPopularMovies", "movie"); | ||||||
| const nowPlayingShows = (req, res) => fetchTmdbList(req, res, 'tvOnTheAir', 'show') | const topRatedMovies = (req, res) => | ||||||
| const popularShows = (req, res) => fetchTmdbList(req, res, 'miscPopularTvs', 'show') |   fetchTmdbList(req, res, "miscTopRatedMovies", "movie"); | ||||||
| const topRatedShows = (req, res) => fetchTmdbList(req, res, 'miscTopRatedTvs', 'show') | 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"); | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|   nowPlayingMovies, |   nowPlayingMovies, | ||||||
| @@ -65,4 +78,4 @@ module.exports = { | |||||||
|   nowPlayingShows, |   nowPlayingShows, | ||||||
|   popularShows, |   popularShows, | ||||||
|   topRatedShows |   topRatedShows | ||||||
| } | }; | ||||||
|   | |||||||
| @@ -1,24 +1,30 @@ | |||||||
| const configuration = require('src/config/configuration').getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
| const TMDB = require('src/tmdb/tmdb'); | const TMDB = require("../../../tmdb/tmdb"); | ||||||
|  |  | ||||||
| const tmdb = new TMDB(configuration.get('tmdb', 'apiKey')); | const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | ||||||
|  |  | ||||||
| const movieCreditsController = (req, res) => { | const movieCreditsController = (req, res) => { | ||||||
|   const movieId = req.params.id; |   const movieId = req.params.id; | ||||||
|  |  | ||||||
|   tmdb.movieCredits(movieId) |   tmdb | ||||||
|  |     .movieCredits(movieId) | ||||||
|     .then(credits => res.send(credits.createJsonResponse())) |     .then(credits => res.send(credits.createJsonResponse())) | ||||||
|     .catch(error => { |     .catch(error => { | ||||||
|       const { status, message } = error; |       const { status, message } = error; | ||||||
|  |  | ||||||
|       if (status && message) { |       if (status && message) { | ||||||
|         res.status(status).send({ success: false, message }) |         res.status(status).send({ success: false, message }); | ||||||
|       } else { |       } else { | ||||||
|         // TODO log unhandled errors |         // TODO log unhandled errors | ||||||
|         console.log('caugth movie credits controller error', error) |         console.log("caugth movie credits controller error", error); | ||||||
|         res.status(500).send({ message: 'An unexpected error occured while requesting movie credits' }) |         res | ||||||
|  |           .status(500) | ||||||
|  |           .send({ | ||||||
|  |             message: | ||||||
|  |               "An unexpected error occured while requesting movie credits" | ||||||
|  |           }); | ||||||
|       } |       } | ||||||
|     }) |     }); | ||||||
| } | }; | ||||||
|  |  | ||||||
| module.exports = movieCreditsController; | module.exports = movieCreditsController; | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| const configuration = require("src/config/configuration").getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
| const TMDB = require("src/tmdb/tmdb"); | const TMDB = require("../../../tmdb/tmdb"); | ||||||
| const Plex = require("src/plex/plex"); | const Plex = require("../../../plex/plex"); | ||||||
| const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | ||||||
| const plex = new Plex(configuration.get("plex", "ip")); | const plex = new Plex(configuration.get("plex", "ip")); | ||||||
|  |  | ||||||
| @@ -58,7 +58,7 @@ async function movieInfoController(req, res) { | |||||||
|         } else { |         } else { | ||||||
|           console.log("Unkown error from plex!"); |           console.log("Unkown error from plex!"); | ||||||
|         } |         } | ||||||
|         console.log(error); |         console.log(error?.message); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,24 +1,30 @@ | |||||||
| const configuration = require('src/config/configuration').getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
| const TMDB = require('src/tmdb/tmdb'); | const TMDB = require("../../../tmdb/tmdb"); | ||||||
|  |  | ||||||
| const tmdb = new TMDB(configuration.get('tmdb', 'apiKey')); | const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | ||||||
|  |  | ||||||
| const movieReleaseDatesController = (req, res) => { | const movieReleaseDatesController = (req, res) => { | ||||||
|   const movieId = req.params.id; |   const movieId = req.params.id; | ||||||
|  |  | ||||||
|   tmdb.movieReleaseDates(movieId) |   tmdb | ||||||
|  |     .movieReleaseDates(movieId) | ||||||
|     .then(releaseDates => res.send(releaseDates.createJsonResponse())) |     .then(releaseDates => res.send(releaseDates.createJsonResponse())) | ||||||
|     .catch(error => { |     .catch(error => { | ||||||
|       const { status, message } = error; |       const { status, message } = error; | ||||||
|  |  | ||||||
|       if (status && message) { |       if (status && message) { | ||||||
|         res.status(status).send({ success: false, message }) |         res.status(status).send({ success: false, message }); | ||||||
|       } else { |       } else { | ||||||
|         // TODO log unhandled errors : here our at tmdbReleaseError ? |         // TODO log unhandled errors : here our at tmdbReleaseError ? | ||||||
|         console.log('caugth release dates controller error', error) |         console.log("caugth release dates controller error", error); | ||||||
|         res.status(500).send({ message: 'An unexpected error occured while requesting movie credits' }) |         res | ||||||
|  |           .status(500) | ||||||
|  |           .send({ | ||||||
|  |             message: | ||||||
|  |               "An unexpected error occured while requesting movie credits" | ||||||
|  |           }); | ||||||
|       } |       } | ||||||
|     }) |     }); | ||||||
| } | }; | ||||||
|  |  | ||||||
| module.exports = movieReleaseDatesController; | module.exports = movieReleaseDatesController; | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| const configuration = require("src/config/configuration").getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
| const TMDB = require("src/tmdb/tmdb"); | const TMDB = require("../../../tmdb/tmdb"); | ||||||
| const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | ||||||
|  |  | ||||||
| const personCreditsController = (req, res) => { | const personCreditsController = (req, res) => { | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| const configuration = require("src/config/configuration").getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
| const TMDB = require("src/tmdb/tmdb"); | const TMDB = require("../../../tmdb/tmdb"); | ||||||
| const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | ||||||
|  |  | ||||||
| function handleError(error, res) { | function handleError(error, res) { | ||||||
|   | |||||||
| @@ -1,25 +1,24 @@ | |||||||
|  |  | ||||||
| /* | /* | ||||||
| * @Author: KevinMidboe |  * @Author: KevinMidboe | ||||||
| * @Date:   2017-10-21 09:54:31 |  * @Date:   2017-10-21 09:54:31 | ||||||
| * @Last Modified by:   KevinMidboe |  * @Last Modified by:   KevinMidboe | ||||||
| * @Last Modified time: 2017-10-21 15:32:43 |  * @Last Modified time: 2017-10-21 15:32:43 | ||||||
| */ |  */ | ||||||
|  |  | ||||||
| const PirateRepository = require('src/pirate/pirateRepository'); | const PirateRepository = require("../../../pirate/pirateRepository"); | ||||||
|  |  | ||||||
| function addMagnet(req, res) { | function addMagnet(req, res) { | ||||||
|    const magnet = req.body.magnet; |   const magnet = req.body.magnet; | ||||||
|    const name = req.body.name; |   const name = req.body.name; | ||||||
|    const tmdb_id = req.body.tmdb_id; |   const tmdb_id = req.body.tmdb_id; | ||||||
|  |  | ||||||
|    PirateRepository.AddMagnet(magnet, name, tmdb_id) |   PirateRepository.AddMagnet(magnet, name, tmdb_id) | ||||||
|       .then((result) => { |     .then(result => { | ||||||
|          res.send(result); |       res.send(result); | ||||||
|       }) |     }) | ||||||
|       .catch(error => { |     .catch(error => { | ||||||
|          res.status(500).send({ success: false, message: error.message }); |       res.status(500).send({ success: false, message: error.message }); | ||||||
|       }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = addMagnet; | module.exports = addMagnet; | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|  * @Last Modified time: 2018-02-26 19:56:32 |  * @Last Modified time: 2018-02-26 19:56:32 | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| const PirateRepository = require("src/pirate/pirateRepository"); | const PirateRepository = require("../../../pirate/pirateRepository"); | ||||||
| // const pirateRepository = new PirateRepository(); | // const pirateRepository = new PirateRepository(); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| const RequestRepository = require('src/plex/requestRepository.js'); | const RequestRepository = require("../../../plex/requestRepository.js"); | ||||||
|  |  | ||||||
| const requestRepository = new RequestRepository(); | const requestRepository = new RequestRepository(); | ||||||
|  |  | ||||||
| @@ -9,16 +9,21 @@ const requestRepository = new RequestRepository(); | |||||||
|  * @returns {Callback} |  * @returns {Callback} | ||||||
|  */ |  */ | ||||||
| function fetchRequestedController(req, res) { | function fetchRequestedController(req, res) { | ||||||
|    // const user = req.loggedInUser; |   // const user = req.loggedInUser; | ||||||
|    const { status, page } = req.query; |   const { status, page } = req.query; | ||||||
|  |  | ||||||
|    requestRepository.fetchRequested(status, page) |   requestRepository | ||||||
|       .then((requestedItems) => { |     .fetchRequested(status, page) | ||||||
|          res.send({ success: true, results: requestedItems, total_results: requestedItems.length }); |     .then(requestedItems => { | ||||||
|       }) |       res.send({ | ||||||
|       .catch((error) => { |         success: true, | ||||||
|          res.status(401).send({ success: false, message: error.message }); |         results: requestedItems, | ||||||
|  |         total_results: requestedItems.length | ||||||
|       }); |       }); | ||||||
|  |     }) | ||||||
|  |     .catch(error => { | ||||||
|  |       res.status(401).send({ success: false, message: error.message }); | ||||||
|  |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = fetchRequestedController; | module.exports = fetchRequestedController; | ||||||
|   | |||||||
| @@ -1,16 +1,17 @@ | |||||||
| const PlexRepository = require('src/plex/plexRepository'); | const PlexRepository = require("../../../plex/plexRepository"); | ||||||
| const configuration = require('src/config/configuration').getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
|  |  | ||||||
| const plexRepository = new PlexRepository(configuration.get('plex', 'ip')); | const plexRepository = new PlexRepository(configuration.get("plex", "ip")); | ||||||
|  |  | ||||||
| function playingController(req, res) { | function playingController(req, res) { | ||||||
|    plexRepository.nowPlaying() |   plexRepository | ||||||
|       .then(movies => { |     .nowPlaying() | ||||||
|          res.send(movies); |     .then(movies => { | ||||||
|       }) |       res.send(movies); | ||||||
|       .catch(error => { |     }) | ||||||
|          res.status(500).send({ success: false, message: error.message }); |     .catch(error => { | ||||||
|       }); |       res.status(500).send({ success: false, message: error.message }); | ||||||
|  |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = playingController; | module.exports = playingController; | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| const RequestRepository = require('src/plex/requestRepository'); | const RequestRepository = require("../../../plex/requestRepository"); | ||||||
|  |  | ||||||
| const requestRepository = new RequestRepository(); | const requestRepository = new RequestRepository(); | ||||||
|  |  | ||||||
| @@ -9,14 +9,16 @@ const requestRepository = new RequestRepository(); | |||||||
|  * @returns {Callback} |  * @returns {Callback} | ||||||
|  */ |  */ | ||||||
| function readRequestController(req, res) { | 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 | ||||||
|       .then(movies => { |     .lookup(mediaId, type) | ||||||
|          res.send(movies); |     .then(movies => { | ||||||
|       }).catch(error => { |       res.send(movies); | ||||||
|          res.status(404).send({ success: false, message: error.message }); |     }) | ||||||
|       }); |     .catch(error => { | ||||||
|  |       res.status(404).send({ success: false, message: error.message }); | ||||||
|  |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = readRequestController; | module.exports = readRequestController; | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| const configuration = require('src/config/configuration').getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
| const Plex = require('src/plex/plex'); | const Plex = require("../../../plex/plex"); | ||||||
| const plex = new Plex(configuration.get('plex', 'ip')); | const plex = new Plex(configuration.get("plex", "ip")); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Controller: Search plex for movies, shows and episodes by query |  * Controller: Search plex for movies, shows and episodes by query | ||||||
| @@ -9,17 +9,24 @@ const plex = new Plex(configuration.get('plex', 'ip')); | |||||||
|  * @returns {Callback} |  * @returns {Callback} | ||||||
|  */ |  */ | ||||||
| function searchPlexController(req, res) { | function searchPlexController(req, res) { | ||||||
|    const { query, type } = req.query; |   const { query, type } = req.query; | ||||||
|    plex.search(query, type) |   plex | ||||||
|       .then(movies => { |     .search(query, type) | ||||||
|          if (movies.length > 0) { |     .then(movies => { | ||||||
|             res.send(movies); |       if (movies.length > 0) { | ||||||
|          } else { |         res.send(movies); | ||||||
|             res.status(404).send({ success: false, message: 'Search query did not give any results from plex.'}) |       } else { | ||||||
|          } |         res | ||||||
|       }).catch(error => { |           .status(404) | ||||||
|          res.status(500).send({ success: false, message: error.message }); |           .send({ | ||||||
|       }); |             success: false, | ||||||
|  |             message: "Search query did not give any results from plex." | ||||||
|  |           }); | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  |     .catch(error => { | ||||||
|  |       res.status(500).send({ success: false, message: error.message }); | ||||||
|  |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = searchPlexController; | module.exports = searchPlexController; | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| const PlexRepository = require('src/plex/plexRepository'); | const PlexRepository = require("../../../plex/plexRepository"); | ||||||
| const configuration = require('src/config/configuration').getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
|  |  | ||||||
| const plexRepository = new PlexRepository(configuration.get('plex', 'ip')); | const plexRepository = new PlexRepository(configuration.get("plex", "ip")); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Controller: Search for media and check existence |  * Controller: Search for media and check existence | ||||||
| @@ -11,19 +11,25 @@ const plexRepository = new PlexRepository(configuration.get('plex', 'ip')); | |||||||
|  * @returns {Callback} |  * @returns {Callback} | ||||||
|  */ |  */ | ||||||
| function searchMediaController(req, res) { | function searchMediaController(req, res) { | ||||||
|    const { query } = req.query; |   const { query } = req.query; | ||||||
|  |  | ||||||
|    plexRepository.search(query) |   plexRepository | ||||||
|       .then(media => { |     .search(query) | ||||||
|          if (media !== undefined || media.length > 0) { |     .then(media => { | ||||||
|             res.send(media); |       if (media !== undefined || media.length > 0) { | ||||||
|          } else { |         res.send(media); | ||||||
|             res.status(404).send({ success: false, message: 'Search query did not return any results.' }); |       } else { | ||||||
|          } |         res | ||||||
|       }) |           .status(404) | ||||||
|       .catch(error => { |           .send({ | ||||||
|          res.status(500).send({ success: false, message: error.message }); |             success: false, | ||||||
|       }); |             message: "Search query did not return any results." | ||||||
|  |           }); | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  |     .catch(error => { | ||||||
|  |       res.status(500).send({ success: false, message: error.message }); | ||||||
|  |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = searchMediaController; | module.exports = searchMediaController; | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| const SearchHistory = require("src/searchHistory/searchHistory"); | const SearchHistory = require("../../../searchHistory/searchHistory"); | ||||||
| const Cache = require("src/tmdb/cache"); | const Cache = require("../../../tmdb/cache"); | ||||||
| const RequestRepository = require("src/plex/requestRepository.js"); | const RequestRepository = require("../../../plex/requestRepository.js"); | ||||||
|  |  | ||||||
| const cache = new Cache(); | const cache = new Cache(); | ||||||
| const requestRepository = new RequestRepository(cache); | const requestRepository = new RequestRepository(cache); | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| const configuration = require("src/config/configuration").getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
| const RequestRepository = require("src/request/request"); | const RequestRepository = require("../../../request/request"); | ||||||
| const TMDB = require("src/tmdb/tmdb"); | const TMDB = require("../../../tmdb/tmdb"); | ||||||
| const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | ||||||
| const request = new RequestRepository(); | const request = new RequestRepository(); | ||||||
|  |  | ||||||
| @@ -35,12 +35,10 @@ function submitRequestController(req, res) { | |||||||
|     console.log("show"); |     console.log("show"); | ||||||
|     mediaFunction = tmdbShowInfo; |     mediaFunction = tmdbShowInfo; | ||||||
|   } else { |   } else { | ||||||
|     res |     res.status(422).send({ | ||||||
|       .status(422) |       success: false, | ||||||
|       .send({ |       message: 'Incorrect type. Allowed types: "movie" or "show"' | ||||||
|         success: false, |     }); | ||||||
|         message: 'Incorrect type. Allowed types: "movie" or "show"' |  | ||||||
|       }); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (mediaFunction === undefined) { |   if (mediaFunction === undefined) { | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| const RequestRepository = require('src/plex/requestRepository'); | const RequestRepository = require("../../../plex/requestRepository"); | ||||||
|  |  | ||||||
| const requestRepository = new RequestRepository(); | const requestRepository = new RequestRepository(); | ||||||
|  |  | ||||||
| @@ -9,17 +9,18 @@ const requestRepository = new RequestRepository(); | |||||||
|  * @returns {Callback} |  * @returns {Callback} | ||||||
|  */ |  */ | ||||||
| function updateRequested(req, res) { | function updateRequested(req, res) { | ||||||
|    const id = req.params.requestId; |   const id = req.params.requestId; | ||||||
|    const type = req.body.type; |   const type = req.body.type; | ||||||
|    const status = req.body.status; |   const status = req.body.status; | ||||||
|  |  | ||||||
|    requestRepository.updateRequestedById(id, type, status) |   requestRepository | ||||||
|       .then(() => { |     .updateRequestedById(id, type, status) | ||||||
|          res.send({ success: true }); |     .then(() => { | ||||||
|       }) |       res.send({ success: true }); | ||||||
|       .catch((error) => { |     }) | ||||||
|          res.status(401).send({ success: false, message: error.message }); |     .catch(error => { | ||||||
|       }); |       res.status(401).send({ success: false, message: error.message }); | ||||||
|  |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = updateRequested; | module.exports = updateRequested; | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| const configuration = require('src/config/configuration').getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
| const Plex = require('src/plex/plex'); | const Plex = require("../../../plex/plex"); | ||||||
| const plex = new Plex(configuration.get('plex', 'ip')); | const plex = new Plex(configuration.get("plex", "ip")); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Controller: Search plex for movies, shows and episodes by query |  * Controller: Search plex for movies, shows and episodes by query | ||||||
| @@ -9,18 +9,18 @@ const plex = new Plex(configuration.get('plex', 'ip')); | |||||||
|  * @returns {Callback} |  * @returns {Callback} | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| function watchDirectLink (req, res) { | function watchDirectLink(req, res) { | ||||||
|    const { title, year } = req.query; |   const { title, year } = req.query; | ||||||
|  |  | ||||||
|   plex.getDirectLinkByTitleAndYear(title, year) |   plex | ||||||
|  |     .getDirectLinkByTitleAndYear(title, year) | ||||||
|     .then(plexDirectLink => { |     .then(plexDirectLink => { | ||||||
|       if (plexDirectLink == false) |       if (plexDirectLink == false) | ||||||
|         res.status(404).send({ success: true, link: null }) |         res.status(404).send({ success: true, link: null }); | ||||||
|       else |       else res.status(200).send({ success: true, link: plexDirectLink }); | ||||||
|         res.status(200).send({ success: true, link: plexDirectLink }) |  | ||||||
|     }) |     }) | ||||||
|     .catch(error => { |     .catch(error => { | ||||||
|        res.status(500).send({ success: false, message: error.message }); |       res.status(500).send({ success: false, message: error.message }); | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| const RequestRepository = require('src/request/request'); | const RequestRepository = require("../../../request/request"); | ||||||
| const request = new RequestRepository(); | const request = new RequestRepository(); | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -12,16 +12,16 @@ function fetchAllRequests(req, res) { | |||||||
|   let sort_by = sort; |   let sort_by = sort; | ||||||
|   let sort_direction = undefined; |   let sort_direction = undefined; | ||||||
|  |  | ||||||
|   if (sort !== undefined && sort.includes(':')) { |   if (sort !== undefined && sort.includes(":")) { | ||||||
|     [sort_by, sort_direction] = sort.split(':') |     [sort_by, sort_direction] = sort.split(":"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   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, message: error.message }); |       res.status(404).send({ success: false, message: error.message }); | ||||||
|   }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = fetchAllRequests; | module.exports = fetchAllRequests; | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| const RequestRepository = require('src/request/request'); | const RequestRepository = require("../../../request/request"); | ||||||
| const request = new RequestRepository(); | const request = new RequestRepository(); | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -11,7 +11,8 @@ function fetchAllRequests(req, res) { | |||||||
|   const id = req.params.id; |   const id = req.params.id; | ||||||
|   const { type } = req.query; |   const { type } = req.query; | ||||||
|  |  | ||||||
|   request.getRequestByIdAndType(id, type) |   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, message: error.message }); | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| const configuration = require("src/config/configuration").getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
| const TMDB = require("src/tmdb/tmdb"); | const TMDB = require("../../../tmdb/tmdb"); | ||||||
| const RequestRepository = require("src/request/request"); | const RequestRepository = require("../../../request/request"); | ||||||
| const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | ||||||
| const request = new RequestRepository(); | const request = new RequestRepository(); | ||||||
| // const { sendSMS } = require("src/notifications/sms"); | // const { sendSMS } = require("src/notifications/sms"); | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| const configuration = require("src/config/configuration").getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
| const TMDB = require("src/tmdb/tmdb"); | const TMDB = require("../../../tmdb/tmdb"); | ||||||
| const SearchHistory = require("src/searchHistory/searchHistory"); | const SearchHistory = require("../../../searchHistory/searchHistory"); | ||||||
| const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | ||||||
| const searchHistory = new SearchHistory(); | const searchHistory = new SearchHistory(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| const configuration = require("src/config/configuration").getInstance(); | const configuration = require("../../..//config/configuration").getInstance(); | ||||||
| const TMDB = require("src/tmdb/tmdb"); | const TMDB = require("../../../tmdb/tmdb"); | ||||||
| const SearchHistory = require("src/searchHistory/searchHistory"); | const SearchHistory = require("../../../searchHistory/searchHistory"); | ||||||
| const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | ||||||
| const searchHistory = new SearchHistory(); | const searchHistory = new SearchHistory(); | ||||||
|  |  | ||||||
| @@ -36,11 +36,9 @@ function multiSearchController(req, res) { | |||||||
|       } else { |       } else { | ||||||
|         // TODO log unhandled errors |         // TODO log unhandled errors | ||||||
|         console.log("caugth multi search controller error", error); |         console.log("caugth multi search controller error", error); | ||||||
|         res |         res.status(500).send({ | ||||||
|           .status(500) |           message: `An unexpected error occured while searching with query: ${query}` | ||||||
|           .send({ |         }); | ||||||
|             message: `An unexpected error occured while searching with query: ${query}` |  | ||||||
|           }); |  | ||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| const configuration = require("src/config/configuration").getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
| const TMDB = require("src/tmdb/tmdb"); | const TMDB = require("../../../tmdb/tmdb"); | ||||||
| const SearchHistory = require("src/searchHistory/searchHistory"); | const SearchHistory = require("../../../searchHistory/searchHistory"); | ||||||
| const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | ||||||
| const searchHistory = new SearchHistory(); | const searchHistory = new SearchHistory(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| const SearchHistory = require("src/searchHistory/searchHistory"); | const SearchHistory = require("../../../searchHistory/searchHistory"); | ||||||
| const configuration = require("src/config/configuration").getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
| const TMDB = require("src/tmdb/tmdb"); | const TMDB = require("../../../tmdb/tmdb"); | ||||||
| const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | ||||||
| const searchHistory = new SearchHistory(); | const searchHistory = new SearchHistory(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,17 +1,17 @@ | |||||||
| const StrayRepository = require('src/seasoned/strayRepository'); | const StrayRepository = require("../../../seasoned/strayRepository"); | ||||||
|  |  | ||||||
| const strayRepository = new StrayRepository(); | const strayRepository = new StrayRepository(); | ||||||
|  |  | ||||||
|  |  | ||||||
| function readStraysController(req, res) { | function readStraysController(req, res) { | ||||||
|    const { verified, page } = req.query; |   const { verified, page } = req.query; | ||||||
|    strayRepository.readAll(verified, page) |   strayRepository | ||||||
|       .then((strays) => { |     .readAll(verified, page) | ||||||
|          res.send(strays); |     .then(strays => { | ||||||
|       }) |       res.send(strays); | ||||||
|       .catch((error) => { |     }) | ||||||
|          res.status(500).send({ success: false, message: error.message }); |     .catch(error => { | ||||||
|       }); |       res.status(500).send({ success: false, message: error.message }); | ||||||
|  |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = readStraysController; | module.exports = readStraysController; | ||||||
|   | |||||||
| @@ -1,17 +1,18 @@ | |||||||
| const StrayRepository = require('src/seasoned/strayRepository'); | const StrayRepository = require("../../../seasoned/strayRepository"); | ||||||
|  |  | ||||||
| const strayRepository = new StrayRepository(); | const strayRepository = new StrayRepository(); | ||||||
|  |  | ||||||
| function strayByIdController(req, res) { | function strayByIdController(req, res) { | ||||||
|    const id = req.params.strayId; |   const id = req.params.strayId; | ||||||
|  |  | ||||||
|    strayRepository.read(id) |   strayRepository | ||||||
|       .then((stray) => { |     .read(id) | ||||||
|          res.send(stray); |     .then(stray => { | ||||||
|       }) |       res.send(stray); | ||||||
|       .catch((error) => { |     }) | ||||||
|          res.status(500).send({ success: false, message: error.message }); |     .catch(error => { | ||||||
|       }); |       res.status(500).send({ success: false, message: error.message }); | ||||||
|  |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = strayByIdController; | module.exports = strayByIdController; | ||||||
|   | |||||||
| @@ -1,17 +1,18 @@ | |||||||
| const StrayRepository = require('src/seasoned/strayRepository'); | const StrayRepository = require("../../../seasoned/strayRepository"); | ||||||
|  |  | ||||||
| const strayRepository = new StrayRepository(); | const strayRepository = new StrayRepository(); | ||||||
|  |  | ||||||
| function verifyStrayController(req, res) { | function verifyStrayController(req, res) { | ||||||
|    const id = req.params.strayId; |   const id = req.params.strayId; | ||||||
|  |  | ||||||
|    strayRepository.verifyStray(id) |   strayRepository | ||||||
|       .then(() => { |     .verifyStray(id) | ||||||
|          res.send({ success: true, message: 'Episode verified' }); |     .then(() => { | ||||||
|       }) |       res.send({ success: true, message: "Episode verified" }); | ||||||
|       .catch((error) => { |     }) | ||||||
|          res.status(500).send({ success: false, message: error.message }); |     .catch(error => { | ||||||
|       }); |       res.status(500).send({ success: false, message: error.message }); | ||||||
|  |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = verifyStrayController; | module.exports = verifyStrayController; | ||||||
|   | |||||||
| @@ -1,23 +1,28 @@ | |||||||
| const configuration = require('src/config/configuration').getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
| const TMDB = require('src/tmdb/tmdb'); | const TMDB = require("../../../tmdb/tmdb"); | ||||||
| const tmdb = new TMDB(configuration.get('tmdb', 'apiKey')); | const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | ||||||
|  |  | ||||||
| const showCreditsController = (req, res) => { | const showCreditsController = (req, res) => { | ||||||
|   const showId = req.params.id; |   const showId = req.params.id; | ||||||
|  |  | ||||||
|   tmdb.showCredits(showId) |   tmdb | ||||||
|  |     .showCredits(showId) | ||||||
|     .then(credits => res.send(credits.createJsonResponse())) |     .then(credits => res.send(credits.createJsonResponse())) | ||||||
|     .catch(error => { |     .catch(error => { | ||||||
|       const { status, message } = error; |       const { status, message } = error; | ||||||
|  |  | ||||||
|       if (status && message) { |       if (status && message) { | ||||||
|         res.status(status).send({ success: false, message }) |         res.status(status).send({ success: false, message }); | ||||||
|       } else { |       } else { | ||||||
|         // TODO log unhandled errors |         // TODO log unhandled errors | ||||||
|         console.log('caugth show credits controller error', error) |         console.log("caugth show credits controller error", error); | ||||||
|         res.status(500).send({ message: 'An unexpected error occured while requesting show credits' }) |         res | ||||||
|  |           .status(500) | ||||||
|  |           .send({ | ||||||
|  |             message: "An unexpected error occured while requesting show credits" | ||||||
|  |           }); | ||||||
|       } |       } | ||||||
|     }) |     }); | ||||||
| } | }; | ||||||
|  |  | ||||||
| module.exports = showCreditsController; | module.exports = showCreditsController; | ||||||
|   | |||||||
| @@ -1,24 +1,24 @@ | |||||||
| const configuration = require('src/config/configuration').getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
| const TMDB = require('src/tmdb/tmdb'); | const TMDB = require("../../../tmdb/tmdb"); | ||||||
| const Plex = require('src/plex/plex'); | const Plex = require("../../../plex/plex"); | ||||||
| const tmdb = new TMDB(configuration.get('tmdb', 'apiKey')); | const tmdb = new TMDB(configuration.get("tmdb", "apiKey")); | ||||||
| const plex = new Plex(configuration.get('plex', 'ip')); | const plex = new Plex(configuration.get("plex", "ip")); | ||||||
|  |  | ||||||
| function handleError(error, res) { | function handleError(error, res) { | ||||||
|   const { status, message } = error; |   const { status, message } = error; | ||||||
|  |  | ||||||
|   if (status && message) { |   if (status && message) { | ||||||
|     res.status(status).send({ success: false, message }) |     res.status(status).send({ success: false, message }); | ||||||
|   } else { |   } else { | ||||||
|     console.log('caught showinfo controller error', error) |     console.log("caught showinfo controller error", error); | ||||||
|     res.status(500).send({ |     res.status(500).send({ | ||||||
|       message: 'An unexpected error occured while requesting show info.' |       message: "An unexpected error occured while requesting show info." | ||||||
|     }) |     }); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Controller: Retrieve information for a show  |  * Controller: Retrieve information for a show | ||||||
|  * @param {Request} req http request variable |  * @param {Request} req http request variable | ||||||
|  * @param {Response} res |  * @param {Response} res | ||||||
|  * @returns {Callback} |  * @returns {Callback} | ||||||
| @@ -28,26 +28,27 @@ async function showInfoController(req, res) { | |||||||
|   const showId = req.params.id; |   const showId = req.params.id; | ||||||
|   let { credits, check_existance } = req.query; |   let { credits, check_existance } = req.query; | ||||||
|  |  | ||||||
|   credits && credits.toLowerCase() === 'true' ? credits = true : credits = false |   credits && credits.toLowerCase() === "true" | ||||||
|   check_existance && check_existance.toLowerCase() === 'true' ? check_existance = true : check_existance = false |     ? (credits = true) | ||||||
|  |     : (credits = false); | ||||||
|  |   check_existance && check_existance.toLowerCase() === "true" | ||||||
|  |     ? (check_existance = true) | ||||||
|  |     : (check_existance = false); | ||||||
|  |  | ||||||
|   let tmdbQueue = [tmdb.showInfo(showId)] |   let tmdbQueue = [tmdb.showInfo(showId)]; | ||||||
|   if (credits) |   if (credits) tmdbQueue.push(tmdb.showCredits(showId)); | ||||||
|     tmdbQueue.push(tmdb.showCredits(showId)) |  | ||||||
|  |  | ||||||
|   try { |   try { | ||||||
|     const [Show, Credits] = await Promise.all(tmdbQueue) |     const [Show, Credits] = await Promise.all(tmdbQueue); | ||||||
|  |  | ||||||
|     const show = Show.createJsonResponse() |     const show = Show.createJsonResponse(); | ||||||
|     if (credits) |     if (credits) show.credits = Credits.createJsonResponse(); | ||||||
|       show.credits = Credits.createJsonResponse() |  | ||||||
|  |  | ||||||
|     if (check_existance) |     if (check_existance) show.exists_in_plex = await plex.existsInPlex(show); | ||||||
|       show.exists_in_plex = await plex.existsInPlex(show) |  | ||||||
|  |  | ||||||
|     res.send(show) |     res.send(show); | ||||||
|   } catch(error) { |   } catch (error) { | ||||||
|     handleError(error, res) |     handleError(error, res); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| const UserRepository = require("src/user/userRepository"); | const UserRepository = require("../../../user/userRepository"); | ||||||
| const userRepository = new UserRepository(); | const userRepository = new UserRepository(); | ||||||
| const fetch = require("node-fetch"); | const fetch = require("node-fetch"); | ||||||
| const FormData = require("form-data"); | const FormData = require("form-data"); | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| const User = require("src/user/user"); | const User = require("../../../user/user"); | ||||||
| const Token = require("src/user/token"); | const Token = require("../../../user/token"); | ||||||
| const UserSecurity = require("src/user/userSecurity"); | const UserSecurity = require("../../../user/userSecurity"); | ||||||
| const UserRepository = require("src/user/userRepository"); | const UserRepository = require("../../../user/userRepository"); | ||||||
| const configuration = require("src/config/configuration").getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
|  |  | ||||||
| const secret = configuration.get("authentication", "secret"); | const secret = configuration.get("authentication", "secret"); | ||||||
| const userSecurity = new UserSecurity(); | const userSecurity = new UserSecurity(); | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| const User = require("src/user/user"); | const User = require("../../../user/user"); | ||||||
| const Token = require("src/user/token"); | const Token = require("../../../user/token"); | ||||||
| const UserSecurity = require("src/user/userSecurity"); | const UserSecurity = require("../../../user/userSecurity"); | ||||||
| const UserRepository = require("src/user/userRepository"); | const UserRepository = require("../../../user/userRepository"); | ||||||
| const configuration = require("src/config/configuration").getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
|  |  | ||||||
| const secret = configuration.get("authentication", "secret"); | const secret = configuration.get("authentication", "secret"); | ||||||
| const userSecurity = new UserSecurity(); | const userSecurity = new UserSecurity(); | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| const RequestRepository = require("src/plex/requestRepository.js"); | const RequestRepository = require("../../../plex/requestRepository.js"); | ||||||
|  |  | ||||||
| const requestRepository = new RequestRepository(); | const requestRepository = new RequestRepository(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| const SearchHistory = require("src/searchHistory/searchHistory"); | const SearchHistory = require("../../../searchHistory/searchHistory"); | ||||||
|  |  | ||||||
| const searchHistory = new SearchHistory(); | const searchHistory = new SearchHistory(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| const UserRepository = require("src/user/userRepository"); | const UserRepository = require("../../../user/userRepository"); | ||||||
| const userRepository = new UserRepository(); | const userRepository = new UserRepository(); | ||||||
| /** | /** | ||||||
|  * Controller: Retrieves settings of a logged in user |  * Controller: Retrieves settings of a logged in user | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| const configuration = require("src/config/configuration").getInstance(); | const configuration = require("../../../config/configuration").getInstance(); | ||||||
| const Tautulli = require("src/tautulli/tautulli"); | const Tautulli = require("../../../tautulli/tautulli"); | ||||||
| const apiKey = configuration.get("tautulli", "apiKey"); | const apiKey = configuration.get("tautulli", "apiKey"); | ||||||
| const ip = configuration.get("tautulli", "ip"); | const ip = configuration.get("tautulli", "ip"); | ||||||
| const port = configuration.get("tautulli", "port"); | const port = configuration.get("tautulli", "port"); | ||||||
|   | |||||||
| @@ -1,27 +1,31 @@ | |||||||
| const establishedDatabase = require('src/database/database'); | const establishedDatabase = require("../../database/database"); | ||||||
|  |  | ||||||
| const mustBeAdmin = (req, res, next) => { | const mustBeAdmin = (req, res, next) => { | ||||||
|    let database = establishedDatabase; |   let database = establishedDatabase; | ||||||
|  |  | ||||||
|    if (req.loggedInUser === undefined) { |   if (req.loggedInUser === undefined) { | ||||||
|       return res.status(401).send({ |     return res.status(401).send({ | ||||||
|          success: false, |       success: false, | ||||||
|          message: 'You must be logged in.', |       message: "You must be logged in." | ||||||
|  |     }); | ||||||
|  |   } else { | ||||||
|  |     database | ||||||
|  |       .get( | ||||||
|  |         `SELECT admin FROM user WHERE user_name IS ?`, | ||||||
|  |         req.loggedInUser.username | ||||||
|  |       ) | ||||||
|  |       .then(isAdmin => { | ||||||
|  |         console.log(isAdmin, req.loggedInUser); | ||||||
|  |         if (isAdmin.admin == 0) { | ||||||
|  |           return res.status(401).send({ | ||||||
|  |             success: false, | ||||||
|  |             message: "You must be logged in as a admin." | ||||||
|  |           }); | ||||||
|  |         } | ||||||
|       }); |       }); | ||||||
|    } else { |   } | ||||||
|       database.get(`SELECT admin FROM user WHERE user_name IS ?`, req.loggedInUser.username) |  | ||||||
|       .then((isAdmin) => { |  | ||||||
|          console.log(isAdmin, req.loggedInUser) |  | ||||||
|          if (isAdmin.admin == 0) { |  | ||||||
|             return res.status(401).send({ |  | ||||||
|                success: false, |  | ||||||
|                message: 'You must be logged in as a admin.' |  | ||||||
|             }) |  | ||||||
|          } |  | ||||||
|       }) |  | ||||||
|    } |  | ||||||
|  |  | ||||||
|    return next(); |   return next(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| module.exports = mustBeAdmin; | module.exports = mustBeAdmin; | ||||||
|   | |||||||
| @@ -1,31 +1,35 @@ | |||||||
| const establishedDatabase = require('src/database/database'); | const establishedDatabase = require("../../database/database"); | ||||||
|  |  | ||||||
| const mustHaveAccountLinkedToPlex = (req, res, next) => { | const mustHaveAccountLinkedToPlex = (req, res, next) => { | ||||||
|    let database = establishedDatabase; |   let database = establishedDatabase; | ||||||
|    const loggedInUser = req.loggedInUser; |   const loggedInUser = req.loggedInUser; | ||||||
|  |  | ||||||
|    if (loggedInUser === undefined) { |   if (loggedInUser === undefined) { | ||||||
|       return res.status(401).send({ |     return res.status(401).send({ | ||||||
|          success: false, |       success: false, | ||||||
|          message: 'You must have your account linked to a plex account.', |       message: "You must have your account linked to a plex account." | ||||||
|       }); |     }); | ||||||
|    } else { |   } else { | ||||||
|       database.get(`SELECT plex_userid FROM settings WHERE user_name IS ?`, loggedInUser.username) |     database | ||||||
|  |       .get( | ||||||
|  |         `SELECT plex_userid FROM settings WHERE user_name IS ?`, | ||||||
|  |         loggedInUser.username | ||||||
|  |       ) | ||||||
|       .then(row => { |       .then(row => { | ||||||
|          const plex_userid = row.plex_userid; |         const plex_userid = row.plex_userid; | ||||||
|  |  | ||||||
|          if (plex_userid === null || plex_userid === undefined) { |  | ||||||
|             return res.status(403).send({ |  | ||||||
|                success: false, |  | ||||||
|                message: 'No plex account user id found for your user. Please authenticate your plex account at /user/authenticate.' |  | ||||||
|             }) |  | ||||||
|          } else { |  | ||||||
|             req.loggedInUser.plex_userid = plex_userid; |  | ||||||
|             return next(); |  | ||||||
|          } |  | ||||||
|       }) |  | ||||||
|    } |  | ||||||
|  |  | ||||||
|  |         if (plex_userid === null || plex_userid === undefined) { | ||||||
|  |           return res.status(403).send({ | ||||||
|  |             success: false, | ||||||
|  |             message: | ||||||
|  |               "No plex account user id found for your user. Please authenticate your plex account at /user/authenticate." | ||||||
|  |           }); | ||||||
|  |         } else { | ||||||
|  |           req.loggedInUser.plex_userid = plex_userid; | ||||||
|  |           return next(); | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| module.exports = mustHaveAccountLinkedToPlex; | module.exports = mustHaveAccountLinkedToPlex; | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| /* eslint-disable no-param-reassign */ | /* eslint-disable no-param-reassign */ | ||||||
| const configuration = require("src/config/configuration").getInstance(); | const configuration = require("../../config/configuration").getInstance(); | ||||||
| const Token = require("src/user/token"); | const Token = require("../../user/token"); | ||||||
|  |  | ||||||
| const secret = configuration.get("authentication", "secret"); | const secret = configuration.get("authentication", "secret"); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,11 +1,11 @@ | |||||||
| const config = require('src/config/configuration').getInstance(); | const config = require("../config/configuration").getInstance(); | ||||||
| const app = require('./app'); | const app = require("./app"); | ||||||
|  |  | ||||||
| module.exports = app.listen(config.get('webserver', 'port'), () => { | module.exports = app.listen(config.get("webserver", "port"), () => { | ||||||
|    /* eslint-disable no-console */ |   /* eslint-disable no-console */ | ||||||
|    console.log('seasonedAPI'); |   console.log("seasonedAPI"); | ||||||
|    /* eslint-disable no-console */ |   /* eslint-disable no-console */ | ||||||
|    console.log(`Database is located at ${config.get('database', 'host')}`); |   console.log(`Database is located at ${config.get("database", "host")}`); | ||||||
|    /* eslint-disable no-console */ |   /* eslint-disable no-console */ | ||||||
|    console.log(`Webserver is listening on ${config.get('webserver', 'port')}`); |   console.log(`Webserver is listening on ${config.get("webserver", "port")}`); | ||||||
| }); | }); | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user