Merge pull request #80 from KevinMidboe/linting

Linting
This commit is contained in:
2018-02-07 14:24:43 +01:00
committed by GitHub
54 changed files with 852 additions and 877 deletions

View File

@@ -1,3 +1,12 @@
{ {
"extends": "airbnb-base" "extends": [
} "airbnb-base"
],
"rules": {
"indent": ["error", 3],
"prefer-destructuring": 0,
"camelcase": 0,
"import/no-unresolved": 0,
"import/no-extraneous-dependencies": 0
}
}

View File

@@ -5,7 +5,7 @@
"start": "cross-env SEASONED_CONFIG=conf/development.json NODE_PATH=. node src/webserver/server.js", "start": "cross-env SEASONED_CONFIG=conf/development.json NODE_PATH=. node src/webserver/server.js",
"test": "cross-env SEASONED_CONFIG=conf/development.json NODE_PATH=. mocha --recursive test/system", "test": "cross-env SEASONED_CONFIG=conf/development.json NODE_PATH=. mocha --recursive test/system",
"coverage": "cross-env PLANFLIX_CONFIG=conf/test.json NODE_PATH=. istanbul cover -x script/autogenerate-documentation.js --include-all-sources --dir test/.coverage node_modules/mocha/bin/_mocha --recursive test/**/* -- --report lcovonly && cat test/.coverage/lcov.info | coveralls && rm -rf test/.coverage", "coverage": "cross-env PLANFLIX_CONFIG=conf/test.json NODE_PATH=. istanbul cover -x script/autogenerate-documentation.js --include-all-sources --dir test/.coverage node_modules/mocha/bin/_mocha --recursive test/**/* -- --report lcovonly && cat test/.coverage/lcov.info | coveralls && rm -rf test/.coverage",
"lint": "./node_modules/.bin/eslint src/webserver/" "lint": "./node_modules/.bin/eslint src/"
}, },
"dependencies": { "dependencies": {
"bcrypt-nodejs": "^0.0.3", "bcrypt-nodejs": "^0.0.3",

View File

@@ -4,40 +4,40 @@ 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 (this.fields[section] === undefined || this.fields[section][option] === undefined) {
throw new Error(`Filed "${section} => ${option}" does not exist.`); throw new Error(`Filed "${section} => ${option}" does not exist.`);
} }
const field = new Field(this.fields[section][option]) const field = new Field(this.fields[section][option]);
if (field.value === '') { if (field.value === '') {
const envField = process.env[[section.toUpperCase(), option.toUpperCase()].join('_')] const envField = 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;

View File

@@ -1,16 +1,15 @@
class EnvironmentVariables { class EnvironmentVariables {
constructor(variables) {
this.variables = variables || process.env;
}
constructor(variables) { get(variable) {
this.variables = variables || process.env; return this.variables[variable];
} }
get(variable) { has(variable) {
return this.variables[variable]; return this.get(variable) !== undefined;
} }
has(variable) {
return this.get(variable) !== undefined;
}
} }
module.exports = EnvironmentVariables; module.exports = EnvironmentVariables;

View File

@@ -2,49 +2,48 @@ const Filters = require('./filters.js');
const EnvironmentVariables = require('./environmentVariables.js'); const EnvironmentVariables = require('./environmentVariables.js');
class Field { class Field {
constructor(rawValue, environmentVariables) {
this.rawValue = rawValue;
this.filters = new Filters(rawValue);
this.valueWithoutFilters = this.filters.removeFiltersFromValue();
this.environmentVariables = new EnvironmentVariables(environmentVariables);
}
constructor(rawValue, environmentVariables) { get value() {
this.rawValue = rawValue; if (this.filters.isEmpty()) {
this.filters = new Filters(rawValue); return this.valueWithoutFilters;
this.valueWithoutFilters = this.filters.removeFiltersFromValue(); }
this.environmentVariables = new EnvironmentVariables(environmentVariables);
}
get value() { if (this.filters.has('base64') && !this.filters.has('env')) {
if (this.filters.isEmpty()) { return Field.base64Decode(this.valueWithoutFilters);
return this.valueWithoutFilters; }
}
if (this.filters.has('base64') && !this.filters.has('env')) { if (this.environmentVariables.has(this.valueWithoutFilters) &&
return Field.base64Decode(this.valueWithoutFilters); this.environmentVariables.get(this.valueWithoutFilters) === '') {
} return undefined;
}
if (this.environmentVariables.has(this.valueWithoutFilters) && if (!this.filters.has('base64') && this.filters.has('env')) {
this.environmentVariables.get(this.valueWithoutFilters) === '') { if (this.environmentVariables.has(this.valueWithoutFilters)) {
return undefined; return this.environmentVariables.get(this.valueWithoutFilters);
} }
return undefined;
}
if (!this.filters.has('base64') && this.filters.has('env')) { if (this.filters.has('env') && this.filters.has('base64')) {
if (this.environmentVariables.has(this.valueWithoutFilters)) { if (this.environmentVariables.has(this.valueWithoutFilters)) {
return this.environmentVariables.get(this.valueWithoutFilters); const encodedEnvironmentVariable = this.environmentVariables.get(this.valueWithoutFilters);
} return Field.base64Decode(encodedEnvironmentVariable);
return undefined; }
} return undefined;
}
if (this.filters.has('env') && this.filters.has('base64')) { return this.valueWithoutFilters;
if (this.environmentVariables.has(this.valueWithoutFilters)) { }
const encodedEnvironmentVariable = this.environmentVariables.get(this.valueWithoutFilters);
return Field.base64Decode(encodedEnvironmentVariable);
}
return undefined;
}
return this.valueWithoutFilters; static base64Decode(string) {
} return new Buffer(string, 'base64').toString('utf-8');
}
static base64Decode(string) {
return new Buffer(string, 'base64').toString('utf-8');
}
} }
module.exports = Field; module.exports = Field;

View File

@@ -1,35 +1,34 @@
class Filters { class Filters {
constructor(value) {
this.value = value;
this.delimiter = '|';
}
constructor(value) { get filters() {
this.value = value; return this.value.split(this.delimiter).slice(0, -1);
this.delimiter = '|'; }
}
get filters() { isEmpty() {
return this.value.split(this.delimiter).slice(0, -1); return !this.hasValidType() || this.value.length === 0;
} }
isEmpty() { has(filter) {
return !this.hasValidType() || this.value.length === 0; return this.filters.includes(filter);
} }
has(filter) { hasValidType() {
return this.filters.includes(filter); return (typeof this.value === 'string');
} }
hasValidType() { removeFiltersFromValue() {
return (typeof this.value === 'string'); if (this.hasValidType() === false) {
} return this.value;
}
removeFiltersFromValue() { let filtersCombined = this.filters.join(this.delimiter);
if (this.hasValidType() === false) { filtersCombined += this.filters.length >= 1 ? this.delimiter : '';
return this.value; return this.value.replace(filtersCombined, '');
} }
let filtersCombined = this.filters.join(this.delimiter);
filtersCombined += this.filters.length >= 1 ? this.delimiter : '';
return this.value.replace(filtersCombined, '');
}
} }
module.exports = Filters; module.exports = Filters;

View File

@@ -1,5 +1,6 @@
const configuration = require('src/config/configuration').getInstance(); const configuration = require('src/config/configuration').getInstance();
const SqliteDatabase = require('src/database/sqliteDatabase'); const SqliteDatabase = require('src/database/sqliteDatabase');
const database = new SqliteDatabase(configuration.get('database', 'host')); const database = new SqliteDatabase(configuration.get('database', 'host'));
/** /**
@@ -9,7 +10,7 @@ const database = new SqliteDatabase(configuration.get('database', 'host'));
* If the tables already exists, it simply proceeds. * If the tables already exists, it simply proceeds.
*/ */
Promise.resolve() Promise.resolve()
.then(() => database.connect()) .then(() => database.connect())
.then(() => database.setUp()); .then(() => database.setUp());
module.exports = database; module.exports = database;

View File

@@ -16,8 +16,8 @@ class SqliteDatabase {
*/ */
connect() { connect() {
return Promise.resolve() return Promise.resolve()
.then(() => sqlite.open(this.host)) .then(() => sqlite.open(this.host))
.then(() => sqlite.exec('pragma foreign_keys = on;')); .then(() => sqlite.exec('pragma foreign_keys = on;'));
} }
/** /**
@@ -73,10 +73,10 @@ class SqliteDatabase {
* 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 this.execute(tearDownSchema); return this.execute(tearDownSchema);
} }
/** /**
* Returns the file contents of a SQL file in schemas/. * Returns the file contents of a SQL file in schemas/.

View File

@@ -1,10 +1,9 @@
const assert = require('assert');
class GitRepository { class GitRepository {
static dumpHook(body) {
dumpHook(body) { /* eslint-disable no-console */
console.log(body); console.log(body);
} }
} }
module.exports = GitRepository; module.exports = GitRepository;

View File

@@ -1,15 +1,15 @@
class MediaInfo { class MediaInfo {
constructor() { constructor() {
this.duration = undefined; this.duration = undefined;
this.height = undefined; this.height = undefined;
this.width = undefined; this.width = undefined;
this.bitrate = undefined; this.bitrate = undefined;
this.resolution = undefined; this.resolution = undefined;
this.framerate = undefined; this.framerate = undefined;
this.protocol = undefined; this.protocol = undefined;
this.container = undefined; this.container = undefined;
this.audioCodec = undefined; this.audioCodec = undefined;
} }
} }
module.exports = MediaInfo; module.exports = MediaInfo;

View File

@@ -1,13 +1,12 @@
class Player { class Player {
constructor(device, address) { constructor(device, address) {
this.device = device; this.device = device;
this.ip = address; this.ip = address;
this.platform = undefined; this.platform = undefined;
this.product = undefined; this.product = undefined;
this.title = undefined; this.title = undefined;
this.state = undefined; this.state = undefined;
}
}
} }
module.exports = Player; module.exports = Player;

View File

@@ -1,8 +1,8 @@
class User { class User {
constructor(id, title) { constructor(id, title) {
this.id = id; this.id = id;
this.title = title; this.title = title;
} }
} }
module.exports = User; module.exports = User;

View File

@@ -1,54 +1,53 @@
const assert = require('assert'); const assert = require('assert');
var PythonShell = require('python-shell'); const PythonShell = require('python-shell');
var async = require('async');
async function find(searchterm, callback) { async function find(searchterm, callback) {
const options = {
pythonPath: '/usr/bin/python3',
// pythonPath: '/Library/Frameworks/Python.framework/Versions/3.6/bin/python3',
args: [searchterm, '-s', 'piratebay', '--print'],
};
var options = { PythonShell.run('../app/torrent_search/torrentSearch/search.py', options, callback);
pythonPath: '/usr/bin/python3', // PythonShell does not support return
// pythonPath: '/Library/Frameworks/Python.framework/Versions/3.6/bin/python3', }
args: [searchterm, '-s', 'piratebay', '--print']
}
PythonShell.run('../app/torrent_search/torrentSearch/search.py', options, callback);
// PythonShell does not support return
};
async function callPythonAddMagnet(magnet, callback) { async function callPythonAddMagnet(magnet, callback) {
var options = { const options = {
pythonPath: '/usr/bin/python', pythonPath: '/usr/bin/python',
// pythonPath: '/Library/Frameworks/Python.framework/Versions/3.6/bin/python3', // pythonPath: '/Library/Frameworks/Python.framework/Versions/3.6/bin/python3',
args: [magnet] args: [magnet],
} };
PythonShell.run('../app/magnet.py', options, callback); PythonShell.run('../app/magnet.py', options, callback);
} }
async function SearchPiratebay(query) { async function SearchPiratebay(query) {
return await new Promise((resolve, reject) => { return await new Promise((resolve, reject) => find(query, (err, results) => {
return find(query, function(err, results) { if (err) {
if (err) { /* eslint-disable no-console */
console.log('THERE WAS A FUCKING ERROR!') console.log('THERE WAS A FUCKING ERROR!');
reject(Error('There was a error when searching for torrents')) reject(Error('There was a error when searching for torrents'));
} }
if (results) { if (results) {
console.log('result', results); /* eslint-disable no-console */
resolve(JSON.parse(results, null, '\t')); console.log('result', results);
} resolve(JSON.parse(results, null, '\t'));
}) }
}) }));
} }
async function AddMagnet(magnet) { async function AddMagnet(magnet) {
return await new Promise((resolve) => { return await new Promise(resolve => callPythonAddMagnet(magnet, (err, results) => {
return callPythonAddMagnet(magnet, function(err, results) { if (err) {
if (err) { /* eslint-disable no-console */
console.log(err) console.log(err);
} }
resolve({ success: true }) /* eslint-disable no-console */
}) console.log(results);
}) resolve({ success: true });
}));
} }
module.exports = { SearchPiratebay, AddMagnet } module.exports = { SearchPiratebay, AddMagnet };

View File

@@ -5,15 +5,15 @@ const convertStreamToUser = require('src/plex/stream/convertStreamToUser');
const ConvertStreamToPlayback = require('src/plex/stream/convertStreamToPlayback'); const ConvertStreamToPlayback = require('src/plex/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;

View File

@@ -1,22 +1,22 @@
const MediaInfo = require('src/media_classes/mediaInfo'); const MediaInfo = require('src/media_classes/mediaInfo');
function convertStreamToMediaInfo(plexStream) { function convertStreamToMediaInfo(plexStream) {
const mediaInfo = new MediaInfo(); const mediaInfo = new MediaInfo();
mediaInfo.duration = plexStream.duration;
mediaInfo.height = plexStream.height;
mediaInfo.width = plexStream.width;
if (plexStream.bitrate) { mediaInfo.duration = plexStream.duration;
mediaInfo.bitrate = plexStream.bitrate; mediaInfo.height = plexStream.height;
} mediaInfo.width = plexStream.width;
mediaInfo.resolution = plexStream.videoResolution;
mediaInfo.framerate = plexStream.videoFrameRate;
mediaInfo.protocol = plexStream.protocol;
mediaInfo.container = plexStream.container;
mediaInfo.audioCodec = plexStream.audioCodec;
return mediaInfo; if (plexStream.bitrate) {
mediaInfo.bitrate = plexStream.bitrate;
}
mediaInfo.resolution = plexStream.videoResolution;
mediaInfo.framerate = plexStream.videoFrameRate;
mediaInfo.protocol = plexStream.protocol;
mediaInfo.container = plexStream.container;
mediaInfo.audioCodec = plexStream.audioCodec;
return mediaInfo;
} }
module.exports = convertStreamToMediaInfo; module.exports = convertStreamToMediaInfo;

View File

@@ -1,14 +1,7 @@
/*
* @Author: KevinMidboe
* @Date: 2017-05-03 23:26:46
* @Last Modified by: KevinMidboe
* @Last Modified time: 2017-05-03 23:27:59
*/
const configuration = require('src/config/configuration').getInstance(); const configuration = require('src/config/configuration').getInstance();
function hookDumpController(req, res) { function hookDumpController(req, res) {
console.log(req); console.log(req);
} }
module.exports = hookDumpController; module.exports = hookDumpController;

View File

@@ -1,26 +1,25 @@
class mailTemplate { class mailTemplate {
constructor(mediaItem) {
constructor(mediaItem) { this.mediaItem = mediaItem;
this.mediaItem = mediaItem; this.posterURL = 'https://image.tmdb.org/t/p/w600';
this.posterURL = 'https://image.tmdb.org/t/p/w600'; }
}
toText() { toText() {
return this.mediaItem.title + ' (' + this.mediaItem.year + ')'; // plain text body return `${this.mediaItem.title} (${this.mediaItem.year})`; // plain text body
} }
toHTML() { toHTML() {
const info = { const info = {
name: this.mediaItem.title, name: this.mediaItem.title,
year: '(' + this.mediaItem.year + ')', year: `(${this.mediaItem.year})`,
poster: this.posterURL + this.mediaItem.poster poster: this.posterURL + this.mediaItem.poster,
} };
return ` return `
<h1>${info.name} ${info.year}</h1> <h1>${info.name} ${info.year}</h1>
<img src="${info.poster}"> <img src="${info.poster}">
` `;
} }
} }
module.exports = mailTemplate; module.exports = mailTemplate;

View File

@@ -1,87 +1,80 @@
const assert = require('assert');
const convertPlexToSeasoned = require('src/plex/convertPlexToSeasoned'); const convertPlexToSeasoned = require('src/plex/convertPlexToSeasoned');
const convertPlexToStream = require('src/plex/convertPlexToStream'); const convertPlexToStream = require('src/plex/convertPlexToStream');
var rp = require('request-promise'); const rp = require('request-promise');
const PLEX_METHODS = ['lookup', 'playing']
class PlexRepository { class PlexRepository {
inPlex(tmdbResult) {
return Promise.resolve()
.then(() => this.search(tmdbResult.title))
.then(plexResult => this.compareTmdbToPlex(tmdbResult, plexResult));
}
search(query, callback) { search(query) {
var options = { const options = {
uri: 'http://10.0.0.44:32400/search?query=' + query, uri: `http://10.0.0.44:32400/search?query=${query}`,
headers: { headers: {
'Accept': 'application/json' Accept: 'application/json',
}, },
json: true json: true,
} };
return rp(options) return rp(options)
.then((result) => this.mapResults(result)) .then(result => this.mapResults(result))
.then(([mappedResults, resultCount]) => { .then(([mappedResults, resultCount]) => ({ results: mappedResults, total_results: resultCount }));
return { 'results': mappedResults, 'total_results': resultCount } }
})
}
compareTmdbToPlex(tmdb, plexResult) { static compareTmdbToPlex(tmdb, plexResult) {
return Promise.resolve() return Promise.resolve()
.then(() => { .then(() => {
plexResult.results.map((plexItem) => { plexResult.results.map((plexItem) => {
if (tmdb.title === plexItem.title && tmdb.year === plexItem.year) if (tmdb.title === plexItem.title && tmdb.year === plexItem.year) { tmdb.matchedInPlex = true; }
tmdb.matchedInPlex = true; return tmdb;
}) });
return tmdb return tmdb;
}) });
} }
inPlex(tmdbResult) { static mapResults(response) {
return Promise.resolve() return Promise.resolve()
.then(() => this.search(tmdbResult.title)) .then(() => {
.then((plexResult) => this.compareTmdbToPlex(tmdbResult, plexResult)) if (!response.MediaContainer.hasOwnProperty('Metadata')) return [[], 0];
}
mapResults(response) { const mappedResults = response.MediaContainer.Metadata.filter((element) => {
return Promise.resolve() return (element.type === 'movie' || element.type === 'show');
.then(() => { }).map((element) => convertPlexToSeasoned(element));
if (! response.MediaContainer.hasOwnProperty('Metadata')) return [[], 0] return [mappedResults, mappedResults.length];
})
.catch((error) => { throw new Error(error); });
}
const mappedResults = response.MediaContainer.Metadata.filter((element) => { nowPlaying() {
return (element.type === 'movie' || element.type === 'show') const options = {
}).map((element) => convertPlexToSeasoned(element)) uri: 'http://10.0.0.44:32400/status/sessions',
return [mappedResults, mappedResults.length] headers: {
}) Accept: 'application/json',
.catch((error) => {throw new Error(error)}) },
} json: true,
};
nowPlaying() { return rp(options)
var options = { .then((result) => {
uri: 'http://10.0.0.44:32400/status/sessions', if (result.MediaContainer.size > 0) {
headers: { const playing = result.MediaContainer.Video.map(convertPlexToStream);
'Accept': 'application/json' return { size: Object.keys(playing).length, video: playing };
}, }
json: true return { size: 0, video: [] };
} })
.catch((err) => {
throw new Error(`Error handling plex playing. Error: ${err}`);
});
}
return rp(options) // multipleInPlex(tmdbResults) {
.then((result) => { // const results = tmdbResults.results.map(async (tmdb) => {
if (result.MediaContainer.size > 0) { // return this.inPlex(tmdb)
var playing = result.MediaContainer.Video.map(convertPlexToStream); // })
return {'size': Object.keys(playing).length, 'video': playing }; // return Promise.all(results)
} else { // }
return { 'size': 0, 'video': [] };
}
})
.catch((err) => {
throw new Error('Error handling plex playing. Error: ' + err);
})
}
// multipleInPlex(tmdbResults) {
// const results = tmdbResults.results.map(async (tmdb) => {
// return this.inPlex(tmdb)
// })
// return Promise.all(results)
// }
} }
module.exports = PlexRepository; module.exports = PlexRepository;

View File

@@ -1,132 +1,117 @@
const assert = require('assert');
const PlexRepository = require('src/plex/plexRepository'); const PlexRepository = require('src/plex/plexRepository');
const plexRepository = new PlexRepository();
const configuration = require('src/config/configuration').getInstance();
const Cache = require('src/tmdb/cache'); const Cache = require('src/tmdb/cache');
const configuration = require('src/config/configuration').getInstance();
const TMDB = require('src/tmdb/tmdb'); const TMDB = require('src/tmdb/tmdb');
const cache = new Cache();
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
var Promise = require('bluebird');
var rp = require('request-promise');
const establishedDatabase = require('src/database/database'); const establishedDatabase = require('src/database/database');
const MailTemplate = require('src/plex/mailTemplate') const plexRepository = new PlexRepository();
const cache = new Cache();
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
var pythonShell = require('python-shell'); const MailTemplate = require('src/plex/mailTemplate');
const nodemailer = require('nodemailer'); const nodemailer = require('nodemailer');
class RequestRepository { class RequestRepository {
constructor(cache, database) {
this.database = database || establishedDatabase;
this.queries = {
insertRequest: "INSERT INTO requests VALUES (?, ?, ?, ?, ?, ?, ?, CURRENT_DATE, 'requested', ?, ?)",
fetchRequstedItems: 'SELECT * FROM requests',
updateRequestedById: 'UPDATE requests SET status = ? WHERE id is ? AND type is ?',
checkIfIdRequested: 'SELECT * FROM requests WHERE id IS ? AND type IS ?',
};
}
constructor(cache, database) { search(query, type, page) {
this.database = database || establishedDatabase; return Promise.resolve()
this.queries = { .then(() => tmdb.search(query, type, page))
'insertRequest': "INSERT INTO requests VALUES (?, ?, ?, ?, ?, ?, ?, CURRENT_DATE, 'requested', ?, ?)", // .then((tmdbResult) => plexRepository.multipleInPlex(tmdbResult))
'fetchRequstedItems': "SELECT * FROM requests", .then(result => result)
'updateRequestedById': "UPDATE requests SET status = ? WHERE id is ? AND type is ?", .catch(error => `error in the house${error}`);
'checkIfIdRequested': "SELECT * FROM requests WHERE id IS ? AND type IS ?", }
}
}
search(query, type, page) { lookup(identifier, type = 'movie') {
return Promise.resolve() return Promise.resolve()
.then(() => tmdb.search(query, type, page)) .then(() => tmdb.lookup(identifier, type))
// .then((tmdbResult) => plexRepository.multipleInPlex(tmdbResult)) .then(tmdbMovie => this.checkID(tmdbMovie))
.then((result) => { .then(tmdbMovie => plexRepository.inPlex(tmdbMovie))
return result .catch((error) => {
}) throw new Error(error);
.catch((error) => {return 'error in the house' + error}) });
} }
lookup(identifier, type = 'movie') { checkID(tmdbMovie) {
return Promise.resolve() return Promise.resolve()
.then(() => tmdb.lookup(identifier, type)) .then(() => this.database.get(this.queries.checkIfIdRequested, [tmdbMovie.id, tmdbMovie.type]))
.then((tmdbMovie) => this.checkID(tmdbMovie)) .then((result, error) => {
.then((tmdbMovie) => plexRepository.inPlex(tmdbMovie)) if (error) { throw new Error(error); }
.catch((error) => { let already_requested = false;
console.log(error) if (result) { already_requested = true; }
})
}
checkID(tmdbMovie) { tmdbMovie.requested = already_requested;
return Promise.resolve() return tmdbMovie;
.then(() => this.database.get(this.queries.checkIfIdRequested, [tmdbMovie.id, tmdbMovie.type])) });
.then((result, error) => { }
let already_requested = false;
if (result)
already_requested = true
tmdbMovie.requested = already_requested; /**
return tmdbMovie; * Send request for given media id.
}) * @param {identifier, type} the id of the media object and type of media must be defined
* @returns {Promise} If nothing has gone wrong.
} */
sendRequest(identifier, type, ip, user_agent, user) {
/** tmdb.lookup(identifier, type).then((movie) => {
* Send request for given media id. if (user === 'false') { user = 'NULL'; }
* @param {identifier, type} the id of the media object and type of media must be defined // Add request to database
* @returns {Promise} If nothing has gone wrong. this.database.run(this.queries.insertRequest, [movie.id, movie.title, movie.year, movie.poster_path, movie.background_path, user, ip, user_agent, movie.type]);
*/
sendRequest(identifier, type, ip, user_agent, user) {
tmdb.lookup(identifier, type).then(movie => {
if (user === 'false')
user = 'NULL';
console.log(user)
// Add request to database
this.database.run(this.queries.insertRequest, [movie.id, movie.title, movie.year, movie.poster_path, movie.background_path, user, ip, user_agent, movie.type])
// create reusable transporter object using the default SMTP transport // create reusable transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({ const transporter = nodemailer.createTransport({
service: 'gmail', service: 'gmail',
auth: { auth: {
user: configuration.get('mail', 'user_pi'), user: configuration.get('mail', 'user_pi'),
pass: configuration.get('mail', 'password_pi') pass: configuration.get('mail', 'password_pi'),
} },
// host: configuration.get('mail', 'host'), // host: configuration.get('mail', 'host'),
// port: 26, // port: 26,
// ignoreTLS: true, // ignoreTLS: true,
// tls :{rejectUnauthorized: false}, // tls :{rejectUnauthorized: false},
// secure: false, // secure:true for port 465, secure:false for port 587 // secure: false, // secure:true for port 465, secure:false for port 587
}); });
const mailTemplate = new MailTemplate(movie) const mailTemplate = new MailTemplate(movie);
// setup email data with unicode symbols // setup email data with unicode symbols
let mailOptions = { const mailOptions = {
// TODO get the mail adr from global location (easy to add) // TODO get the mail adr from global location (easy to add)
from: 'MovieRequester <pi.midboe@gmail.com>', // sender address from: 'MovieRequester <pi.midboe@gmail.com>', // sender address
to: 'kevin.midboe@gmail.com', // list of receivers to: 'kevin.midboe@gmail.com', // list of receivers
subject: 'Download request', // Subject line subject: 'Download request', // Subject line
text: mailTemplate.toText(), text: mailTemplate.toText(),
html: mailTemplate.toHTML() html: mailTemplate.toHTML(),
}; };
// send mail with defined transport object // send mail with defined transport object
transporter.sendMail(mailOptions, (error, info) => { transporter.sendMail(mailOptions, (error, info) => {
if (error) { if (error) {
return console.log(error); return console.log(error);
} }
console.log('Message %s sent: %s', info.messageId, info.response); console.log('Message %s sent: %s', info.messageId, info.response);
}); });
});
}) // TODO add better response when done.
return Promise.resolve();
}
// TODO add better response when done. fetchRequested() {
return Promise.resolve(); return this.database.all(this.queries.fetchRequstedItems);
}
}
fetchRequested() {
return this.database.all(this.queries.fetchRequstedItems);
}
updateRequestedById(id, type, status) {
return this.database.run(this.queries.updateRequestedById, [status, id, type]);
}
updateRequestedById(id, type, status) {
return this.database.run(this.queries.updateRequestedById, [status, id, type]);
}
} }
module.exports = RequestRepository; module.exports = RequestRepository;

View File

@@ -1,15 +1,14 @@
class convertStreamToPlayback { class convertStreamToPlayback {
constructor(plexStream) { constructor(plexStream) {
this.bitrate = plexStream.bitrate; this.bitrate = plexStream.bitrate;
this.width = plexStream.width; this.width = plexStream.width;
this.height = plexStream.height; this.height = plexStream.height;
this.decision = plexStream.decision; this.decision = plexStream.decision;
this.audioProfile = plexStream.audioProfile; this.audioProfile = plexStream.audioProfile;
this.videoProfile = plexStream.videoProfile; this.videoProfile = plexStream.videoProfile;
this.duration = plexStream.duration; this.duration = plexStream.duration;
this.container = plexStream.container; this.container = plexStream.container;
}
}
} }
module.exports = convertStreamToPlayback; module.exports = convertStreamToPlayback;

View File

@@ -1,13 +1,13 @@
const Player = require('src/media_classes/player'); const Player = require('src/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;

View File

@@ -1,7 +1,7 @@
const User = require('src/media_classes/user'); const User = require('src/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;

View File

@@ -1,39 +1,38 @@
const establishedDatabase = require('src/database/database'); const establishedDatabase = require('src/database/database');
class SearchHistory { class SearchHistory {
constructor(database) {
this.database = database || establishedDatabase;
this.queries = {
'create': 'insert into search_history (search_query, user_name) values (?, ?)',
'read': 'select search_query from search_history where user_name = ? order by id desc',
};
}
constructor(database) { /**
this.database = database || establishedDatabase;
this.queries = {
'create': '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 this.database.all(this.queries.read, user) return this.database.all(this.queries.read, user)
.then(rows => rows.map(row => row.search_query)); .then(rows => rows.map(row => row.search_query));
} }
/** /**
* Creates a new search entry in the database. * Creates a new search entry in the database.
* @param {User} user a new user * @param {User} user a new user
* @param {String} searchQuery the query the user searched for * @param {String} searchQuery the query the user searched for
* @returns {Promise} * @returns {Promise}
*/ */
create(user, searchQuery) { create(user, searchQuery) {
return this.database.run(this.queries.create, [searchQuery, user]).catch((error) => { return this.database.run(this.queries.create, [searchQuery, user])
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.');
}); }
} });
}
} }
module.exports = SearchHistory; module.exports = SearchHistory;

View File

@@ -1,7 +1,7 @@
class Stray { class Stray {
constructor(id) { constructor(id) {
this.id = id; this.id = id;
} }
} }
module.exports = Stray; module.exports = Stray;

View File

@@ -1,67 +1,62 @@
const assert = require('assert'); const assert = require('assert');
const Stray = require('src/seasoned/stray'); const Stray = require('src/seasoned/stray');
const establishedDatabase = require('src/database/database'); const establishedDatabase = require('src/database/database');
var pythonShell = require('python-shell'); const pythonShell = require('python-shell');
function foo(e) {
throw('Foooo');
}
class StrayRepository { class StrayRepository {
constructor(database) {
this.database = database || establishedDatabase;
this.queries = {
read: 'SELECT * FROM stray_eps WHERE id = ?',
readAll: 'SELECT id, name, season, episode, verified FROM stray_eps',
readAllFiltered: 'SELECT id, name, season, episode, verified FROM stray_eps WHERE verified = ',
checkVerified: 'SELECT id FROM stray_eps WHERE verified = 0 AND id = ?',
verify: 'UPDATE stray_eps SET verified = 1 WHERE id = ?',
};
}
constructor(database) { read(strayId) {
this.database = database || establishedDatabase; return this.database.get(this.queries.read, strayId).then((row) => {
this.queries = { assert.notEqual(row, undefined, `Could not find list with id ${strayId}.`);
'read': 'SELECT * FROM stray_eps WHERE id = ?', return row;
'readAll': 'SELECT id, name, season, episode, verified FROM stray_eps', });
'readAllFiltered': 'SELECT id, name, season, episode, verified FROM stray_eps WHERE verified = ', }
'checkVerified': 'SELECT id FROM stray_eps WHERE verified = 0 AND id = ?',
'verify': 'UPDATE stray_eps SET verified = 1 WHERE id = ?',
};
}
read(strayId) { readAll(verified = null) {
return this.database.get(this.queries.read, strayId).then((row) => { let dbSearchQuery = this.queries.readAll;
assert.notEqual(row, undefined, `Could not find list with id ${strayId}.`); if (verified != null) {
return row; 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;
}));
}
readAll(verified = null, page = 1) { verifyStray(strayId) {
var dbSearchQuery = this.queries.readAll; return this.database.get(this.queries.checkVerified, strayId).then((row) => {
if (verified != null) { assert.notEqual(row, undefined, `Stray '${strayId}' already verified.`);
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) { const options = {
return this.database.get(this.queries.checkVerified, strayId).then((row) => { pythonPath: '/usr/bin/python3',
assert.notEqual(row, undefined, `Stray '${strayId}' already verified.`); args: [strayId],
};
var options = { pythonShell.run('../app/moveSeasoned.py', options, (err, results) => {
pythonPath: '/usr/bin/python3', if (err) throw err;
args: [strayId] // TODO Add error handling!! StrayRepository.ERROR
} // results is an array consisting of messages collected during execution
console.log('results: %j', results);
});
pythonShell.run('../app/moveSeasoned.py', options, function (err, results) { return this.database.run(this.queries.verify, strayId);
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;

View File

@@ -2,43 +2,43 @@ const assert = require('assert');
const establishedDatabase = require('src/database/database'); const establishedDatabase = require('src/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: 'SELECT value, time_to_live, created_at, DATETIME("now", "localtime") as now, ' +
'DATETIME(created_at, "+" || time_to_live || " seconds") as expires ' + 'DATETIME(created_at, "+" || time_to_live || " seconds") as expires ' +
'FROM cache WHERE key = ? AND now < expires', 'FROM cache WHERE key = ? AND now < expires',
'create': 'INSERT OR REPLACE INTO cache (key, value, time_to_live) VALUES (?, ?, ?)', 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 enrty with that key.'); assert(row, 'Could not find cache enrty 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 = 172800) { set(key, value, timeToLive = 172800) {
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(() => this.database.run(this.queries.create, [key, json, timeToLive]))
.then(() => value); .then(() => value);
} }
} }
module.exports = Cache; module.exports = Cache;

View File

@@ -2,37 +2,36 @@ const User = require('src/user/user');
const jwt = require('jsonwebtoken'); const jwt = require('jsonwebtoken');
class Token { class Token {
constructor(user) {
this.user = user;
}
constructor(user) { /**
this.user = user; * Generate a new token.
} * @param {String} secret a cipher of the token
* @returns {String}
*/
toString(secret) {
return jwt.sign({ username: this.user.username }, secret);
}
/** /**
* Generate a new token.
* @param {String} secret a cipher of the token
* @returns {String}
*/
toString(secret) {
return jwt.sign({ username: this.user.username }, secret);
}
/**
* Decode a token. * Decode a token.
* @param {Token} jwtToken an encrypted token * @param {Token} jwtToken an encrypted token
* @param {String} secret a cipher of the token * @param {String} secret a cipher of the token
* @returns {Token} * @returns {Token}
*/ */
static fromString(jwtToken, secret) { static fromString(jwtToken, secret) {
let username = null; let username = null;
try { try {
username = jwt.verify(jwtToken, secret).username; username = jwt.verify(jwtToken, secret).username;
} catch (error) { } catch (error) {
throw new Error('The token is invalid.'); throw new Error('The token is invalid.');
} }
const user = new User(username); const user = new User(username);
return new Token(user); return new Token(user);
} }
} }
module.exports = Token; module.exports = Token;

View File

@@ -1,8 +1,8 @@
class User { class User {
constructor(username, email) { constructor(username, email) {
this.username = username; this.username = username;
this.email = email; this.email = email;
} }
} }
module.exports = User; module.exports = User;

View File

@@ -2,58 +2,56 @@ const assert = require('assert');
const establishedDatabase = require('src/database/database'); const establishedDatabase = require('src/database/database');
class UserRepository { class UserRepository {
constructor(database) {
this.database = database || establishedDatabase;
this.queries = {
read: 'select * from user where lower(user_name) = lower(?)',
create: 'insert into user (user_name, email) values(?, ?)',
change: 'update user set password = ? where user_name = ?',
retrieveHash: 'select * from user where user_name = ?',
};
}
constructor(database) { /**
this.database = database || establishedDatabase;
this.queries = {
read: 'select * from user where lower(user_name) = lower(?)',
create: 'insert into user (user_name, email) values(?, ?)',
change: 'update user set password = ? where user_name = ?',
retrieveHash: 'select * from user where user_name = ?',
};
}
/**
* Create a user in a database. * Create a user in a database.
* @param {User} user the user you want to create * @param {User} user the user you want to create
* @returns {Promise} * @returns {Promise}
*/ */
create(user) { create(user) {
return Promise.resolve() return Promise.resolve()
.then(() => this.database.get(this.queries.read, user.username)) .then(() => this.database.get(this.queries.read, user.username))
.then(row => assert.equal(row, undefined)) .then(row => assert.equal(row, undefined))
.then(() => this.database.run(this.queries.create, [user.username, user.email])) .then(() => this.database.run(this.queries.create, [user.username, user.email]))
.catch((error) => { .catch((error) => {
if (error.message.endsWith('email')) { if (error.message.endsWith('email')) {
throw new Error('That email is already taken'); throw new Error('That email is already taken');
} else if (error.name === 'AssertionError' || error.message.endsWith('user_name')) { } else if (error.name === 'AssertionError' || error.message.endsWith('user_name')) {
throw new Error('That username is already taken'); throw new Error('That username is already taken');
} }
}); });
} }
/** /**
* Retrieve a password from a database. * Retrieve a password from a database.
* @param {User} user the user you want to retrieve the password * @param {User} user the user you want to retrieve the password
* @returns {Promise} * @returns {Promise}
*/ */
retrieveHash(user) { retrieveHash(user) {
return this.database.get(this.queries.retrieveHash, user.username).then((row) => { return this.database.get(this.queries.retrieveHash, user.username).then((row) => {
assert(row, 'The user does not exist.'); assert(row, 'The user does not exist.');
return row.password; return row.password;
}); });
} }
/** /**
* Change a user's password in a database. * Change a user's password in a database.
* @param {User} user the user you want to create * @param {User} user the user you want to create
* @param {String} password the new password you want to change * @param {String} password the new password you want to change
* @returns {Promise} * @returns {Promise}
*/ */
changePassword(user, password) { changePassword(user, password) {
return this.database.run(this.queries.change, [password, user.username]); return this.database.run(this.queries.change, [password, user.username]);
} }
} }
module.exports = UserRepository; module.exports = UserRepository;

View File

@@ -2,75 +2,74 @@ const bcrypt = require('bcrypt-nodejs');
const UserRepository = require('src/user/userRepository'); const UserRepository = require('src/user/userRepository');
class UserSecurity { class UserSecurity {
constructor(database) {
this.userRepository = new UserRepository(database);
}
constructor(database) { /**
this.userRepository = new UserRepository(database);
}
/**
* Create a new user in PlanFlix. * Create a new user in PlanFlix.
* @param {User} user the new user you want to create * @param {User} user the new user you want to create
* @param {String} clearPassword a password of the user * @param {String} clearPassword a password of the user
* @returns {Promise} * @returns {Promise}
*/ */
createNewUser(user, clearPassword) { createNewUser(user, clearPassword) {
if (user.username.trim() === '') { if (user.username.trim() === '') {
throw new Error('The username is empty.'); throw new Error('The username is empty.');
} else if (user.email.trim() === '') { } else if (user.email.trim() === '') {
throw new Error('The email is empty.'); throw new Error('The email is empty.');
} else if (clearPassword.trim() === '') { } else if (clearPassword.trim() === '') {
throw new Error('The password is empty.'); throw new Error('The password is empty.');
} else { } else {
return Promise.resolve() return Promise.resolve()
.then(() => this.userRepository.create(user)) .then(() => this.userRepository.create(user))
.then(() => UserSecurity.hashPassword(clearPassword)) .then(() => UserSecurity.hashPassword(clearPassword))
.then(hash => this.userRepository.changePassword(user, hash)); .then(hash => this.userRepository.changePassword(user, hash));
} }
} }
/** /**
* Login into PlanFlix. * Login into PlanFlix.
* @param {User} user the user you want to login * @param {User} user the user you want to login
* @param {String} clearPassword the user's password * @param {String} clearPassword the user's password
* @returns {Promise} * @returns {Promise}
*/ */
login(user, clearPassword) { login(user, clearPassword) {
return Promise.resolve() return Promise.resolve()
.then(() => this.userRepository.retrieveHash(user)) .then(() => this.userRepository.retrieveHash(user))
.then(hash => UserSecurity.compareHashes(hash, clearPassword)) .then(hash => UserSecurity.compareHashes(hash, clearPassword))
.catch(() => { throw new Error('Wrong username or password.'); }); .catch(() => { throw new Error('Wrong username or password.'); });
} }
/** /**
* Compare between a password and a hash password from database. * Compare between a password and a hash password from database.
* @param {String} hash the hash password from database * @param {String} hash the hash password from database
* @param {String} clearPassword the user's password * @param {String} clearPassword the user's password
* @returns {Promise} * @returns {Promise}
*/ */
static compareHashes(hash, clearPassword) { static compareHashes(hash, clearPassword) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
bcrypt.compare(clearPassword, hash, (error, matches) => { bcrypt.compare(clearPassword, hash, (error, matches) => {
if (matches === true) { if (matches === true) {
resolve(); resolve();
} else { } else {
reject(); reject();
} }
});
}); });
}); }
}
/** /**
* Hashes a password. * Hashes a password.
* @param {String} clearPassword the user's password * @param {String} clearPassword the user's password
* @returns {Promise} * @returns {Promise}
*/ */
static hashPassword(clearPassword) { static hashPassword(clearPassword) {
return new Promise((resolve) => { return new Promise((resolve) => {
bcrypt.hash(clearPassword, null, null, (error, hash) => { bcrypt.hash(clearPassword, null, null, (error, hash) => {
resolve(hash); resolve(hash);
});
}); });
}); }
}
} }
module.exports = UserSecurity; module.exports = UserSecurity;

View File

@@ -5,10 +5,9 @@ const tokenToUser = require('./middleware/tokenToUser');
const mustBeAuthenticated = require('./middleware/mustBeAuthenticated'); const mustBeAuthenticated = require('./middleware/mustBeAuthenticated');
const configuration = require('src/config/configuration').getInstance(); const configuration = require('src/config/configuration').getInstance();
// TODO: Have our raven router check if there is a value, if not don't enable raven. // TODO: Have our raven router check if there is a value, if not don't enable raven.
Raven.config(configuration.get('raven', 'DSN')).install(); Raven.config(configuration.get('raven', 'DSN')).install();
const app = express(); // define our app using express const app = express(); // define our app using express
app.use(Raven.requestHandler()); app.use(Raven.requestHandler());
// this will let us get the data from a POST // this will let us get the data from a POST
@@ -34,27 +33,27 @@ router.use(tokenToUser);
// TODO: Should have a separate middleware/router for handling headers. // TODO: Should have a separate middleware/router for handling headers.
router.use((req, res, next) => { router.use((req, res, next) => {
// TODO add logging of all incoming // TODO add logging of all incoming
console.log('Request: ', req.originalUrl); console.log('Request: ', req.originalUrl);
const origin = req.headers.origin; const origin = req.headers.origin;
if (allowedOrigins.indexOf(origin) > -1) { if (allowedOrigins.indexOf(origin) > -1) {
console.log('allowed'); console.log('allowed');
res.setHeader('Access-Control-Allow-Origin', origin); res.setHeader('Access-Control-Allow-Origin', origin);
} }
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, loggedinuser'); res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, loggedinuser');
res.header('Access-Control-Allow-Methods', 'POST, GET, PUT'); res.header('Access-Control-Allow-Methods', 'POST, GET, PUT');
next(); next();
}); });
router.get('/', function mainHandler(req, res) { router.get('/', function mainHandler(req, res) {
throw new Error('Broke!'); throw new Error('Broke!');
}); });
app.use(Raven.errorHandler()); app.use(Raven.errorHandler());
app.use(function onError(err, req, res, next) { app.use(function onError(err, req, res, next) {
res.statusCode = 500; res.statusCode = 500;
res.end(res.sentry + '\n'); res.end(res.sentry + '\n');
}); });
/** /**

View File

@@ -3,13 +3,13 @@ const GitRepository = require('src/git/gitRepository');
const gitRepository = new GitRepository(); const gitRepository = new GitRepository();
function dumpHookController(req, res) { function dumpHookController(req, res) {
gitRepository.dumpHook(req.body) gitRepository.dumpHook(req.body)
.then(() => { .then(() => {
res.status(200); res.status(200);
}) })
.catch((error) => { .catch((error) => {
res.status(500); res.status(500);
}); });
} }
module.exports = dumpHookController; module.exports = dumpHookController;

View File

@@ -9,15 +9,15 @@
const PirateRepository = require('src/pirate/pirateRepository'); const PirateRepository = require('src/pirate/pirateRepository');
function updateRequested(req, res) { function updateRequested(req, res) {
const magnet = req.body.magnet; const magnet = req.body.magnet;
PirateRepository.AddMagnet(magnet) PirateRepository.AddMagnet(magnet)
.then((result) => { .then((result) => {
res.send(result); res.send(result);
}) })
.catch((error) => { .catch((error) => {
res.status(401).send({ success: false, error: error.message }); res.status(401).send({ success: false, error: error.message });
}); });
} }
module.exports = updateRequested; module.exports = updateRequested;

View File

@@ -15,15 +15,15 @@ const PirateRepository = require('src/pirate/pirateRepository');
* @returns {Callback} * @returns {Callback}
*/ */
function updateRequested(req, res) { function updateRequested(req, res) {
const { query, page, type } = req.query; const { query, page, type } = req.query;
PirateRepository.SearchPiratebay(query, page, type) PirateRepository.SearchPiratebay(query, page, type)
.then((result) => { .then((result) => {
res.send({ success: true, torrents: result }); res.send({ success: true, torrents: result });
}) })
.catch((error) => { .catch((error) => {
res.status(401).send({ success: false, error: error.message }); res.status(401).send({ success: false, error: error.message });
}); });
} }
module.exports = updateRequested; module.exports = updateRequested;

View File

@@ -9,15 +9,15 @@ const requestRepository = new RequestRepository();
* @returns {Callback} * @returns {Callback}
*/ */
function historyController(req, res) { function historyController(req, res) {
const user = req.loggedInUser; // const user = req.loggedInUser;
requestRepository.fetchRequested() requestRepository.fetchRequested()
.then((requestedItems) => { .then((requestedItems) => {
res.send({ success: true, results: requestedItems, total_results: requestedItems.length }); res.send({ success: true, results: requestedItems, total_results: requestedItems.length });
}) })
.catch((error) => { .catch((error) => {
res.status(401).send({ success: false, error: error.message }); res.status(401).send({ success: false, error: error.message });
}); });
} }
module.exports = historyController; module.exports = historyController;

View File

@@ -2,13 +2,11 @@
* @Author: KevinMidboe * @Author: KevinMidboe
* @Date: 2017-05-03 23:26:46 * @Date: 2017-05-03 23:26:46
* @Last Modified by: KevinMidboe * @Last Modified by: KevinMidboe
* @Last Modified time: 2017-05-03 23:27:59 * @Last Modified time: 2018-02-06 20:54:22
*/ */
const configuration = require('src/config/configuration').getInstance();
function hookDumpController(req, res) { function hookDumpController(req, res) {
console.log(req); console.log(req);
} }
module.exports = hookDumpController; module.exports = hookDumpController;

View File

@@ -1,14 +1,15 @@
const PlexRepository = require('src/plex/plexRepository'); const PlexRepository = require('src/plex/plexRepository');
const plexRepository = new PlexRepository(); const plexRepository = new PlexRepository();
function playingController(req, res) { function playingController(req, res) {
plexRepository.nowPlaying() plexRepository.nowPlaying()
.then((movies) => { .then((movies) => {
res.send(movies); res.send(movies);
}) })
.catch((error) => { .catch((error) => {
res.status(500).send({success: false, error: error.message }); res.status(500).send({ success: false, error: error.message });
}) });
} }
module.exports = playingController; module.exports = playingController;

View File

@@ -1,4 +1,5 @@
const RequestRepository = require('src/plex/requestRepository'); const RequestRepository = require('src/plex/requestRepository');
const requestRepository = new RequestRepository(); const requestRepository = new RequestRepository();
/** /**
@@ -8,14 +9,14 @@ 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.lookup(mediaId, type)
.then((movies) => { .then((movies) => {
res.send(movies); res.send(movies);
}).catch((error) => { }).catch((error) => {
res.status(404).send({ success: false, error: error.message }); res.status(404).send({ success: false, error: error.message });
}); });
} }
module.exports = readRequestController; module.exports = readRequestController;

View File

@@ -1,27 +1,28 @@
const PlexRepository = require('src/plex/plexRepository'); const PlexRepository = require('src/plex/plexRepository');
const plexRepository = new PlexRepository(); const plexRepository = new PlexRepository();
/** /**
* Controller: Search for media and check existence * Controller: Search for media and check existence
* in plex by query and page * in plex by query and page
* @param {Request} req http request variable * @param {Request} req http request variable
* @param {Response} res * @param {Response} res
* @returns {Callback} * @returns {Callback}
*/ */
function searchMediaController(req, res) { function searchMediaController(req, res) {
const { query, page } = req.query; const { query } = req.query;
plexRepository.searchMedia(query) plexRepository.search(query)
.then((media) => { .then((media) => {
if (media !== undefined || media.length > 0) { if (media !== undefined || media.length > 0) {
res.send(media); res.send(media);
} else { } else {
res.status(404).send({ success: false, error: 'Search query did not return any results.'}) res.status(404).send({ success: false, error: 'Search query did not return any results.' });
} }
}) })
.catch((error) => { .catch((error) => {
res.status(500).send({success: false, error: error.message }); res.status(500).send({ success: false, error: error.message });
}) });
} }
module.exports = searchMediaController; module.exports = searchMediaController;

View File

@@ -1,24 +1,25 @@
const SearchHistory = require('src/searchHistory/searchHistory'); const SearchHistory = require('src/searchHistory/searchHistory');
const Cache = require('src/tmdb/cache'); const Cache = require('src/tmdb/cache');
const RequestRepository = require('src/plex/requestRepository.js'); const RequestRepository = require('src/plex/requestRepository.js');
const cache = new Cache(); const cache = new Cache();
const requestRepository = new RequestRepository(cache); const requestRepository = new RequestRepository(cache);
const searchHistory = new SearchHistory(); const searchHistory = new SearchHistory();
function searchRequestController(req, res) { function searchRequestController(req, res) {
const user = req.headers.loggedinuser; const user = req.headers.loggedinuser;
const { query, page, type } = req.query; const { query, page, type } = req.query;
Promise.resolve() Promise.resolve()
.then(() => searchHistory.create(user, query)) .then(() => searchHistory.create(user, query))
.then(() => requestRepository.search(query, page, type)) .then(() => requestRepository.search(query, page, type))
.then((searchResult) => { .then((searchResult) => {
res.send(searchResult); res.send(searchResult);
}) })
.catch((error) => { .catch((error) => {
res.status(500).send({success: false, error: error.message }); res.status(500).send({ success: false, error: error.message });
}) });
} }
module.exports = searchRequestController; module.exports = searchRequestController;

View File

@@ -1,4 +1,5 @@
const RequestRepository = require('src/plex/requestRepository.js'); const RequestRepository = require('src/plex/requestRepository.js');
const requestRepository = new RequestRepository(); const requestRepository = new RequestRepository();
/** /**
@@ -9,20 +10,20 @@ const requestRepository = new RequestRepository();
*/ */
function submitRequestController(req, res) { function submitRequestController(req, res) {
// This is the id that is the param of the url // This is the id that is the param of the url
const id = req.params.mediaId; const id = req.params.mediaId;
const type = req.query.type; const type = req.query.type;
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
const user_agent = req.headers['user-agent'] const user_agent = req.headers['user-agent'];
const user = req.headers.loggedinuser; const user = req.headers.loggedinuser;
requestRepository.sendRequest(id, type, ip, user_agent, user) requestRepository.sendRequest(id, type, ip, user_agent, user)
.then(() => { .then(() => {
res.send({ success: true, message: 'Media item sucessfully requested!' }); res.send({ success: true, message: 'Media item sucessfully requested!' });
}) })
.catch((error) => { .catch((error) => {
res.status(500).send({ success: false, error: error.message }); res.status(500).send({ success: false, error: error.message });
}); });
} }
module.exports = submitRequestController; module.exports = submitRequestController;

View File

@@ -1,4 +1,5 @@
const RequestRepository = require('src/plex/requestRepository'); const RequestRepository = require('src/plex/requestRepository');
const requestRepository = new RequestRepository(); const requestRepository = new RequestRepository();
/** /**
@@ -8,17 +9,17 @@ 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.updateRequestedById(id, type, status)
.then(() => { .then(() => {
res.send({ success: true }); res.send({ success: true });
}) })
.catch((error) => { .catch((error) => {
res.status(401).send({ success: false, error: error.message }); res.status(401).send({ success: false, error: error.message });
}); });
} }
module.exports = updateRequested; module.exports = updateRequested;

View File

@@ -1,16 +1,17 @@
const StrayRepository = require('src/seasoned/strayRepository'); const StrayRepository = require('src/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.readAll(verified, page)
.then((strays) => { .then((strays) => {
res.send(strays); res.send(strays);
}) })
.catch((error) => { .catch((error) => {
res.status(500).send({success: false, error: error.message }); res.status(500).send({ success: false, error: error.message });
}); });
} }
module.exports = readStraysController; module.exports = readStraysController;

View File

@@ -1,17 +1,17 @@
const configuration = require('src/config/configuration').getInstance();
const StrayRepository = require('src/seasoned/strayRepository'); const StrayRepository = require('src/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.read(id)
.then((stray) => { .then((stray) => {
res.send(stray); res.send(stray);
}) })
.catch((error) => { .catch((error) => {
res.status(500).send({ success: false, error: error.message }); res.status(500).send({ success: false, error: error.message });
}); });
} }
module.exports = strayByIdController; module.exports = strayByIdController;

View File

@@ -3,15 +3,15 @@ const StrayRepository = require('src/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.verifyStray(id)
.then(() => { .then(() => {
res.send({ success: true, message: 'Episode verified' }); res.send({ success: true, message: 'Episode verified' });
}) })
.catch((error) => { .catch((error) => {
res.status(500).send({ success: false, error: error.message }); res.status(500).send({ success: false, error: error.message });
}); });
} }
module.exports = verifyStrayController; module.exports = verifyStrayController;

View File

@@ -1,10 +1,10 @@
const configuration = require('src/config/configuration').getInstance(); const configuration = require('src/config/configuration').getInstance();
const Cache = require('src/tmdb/cache'); const Cache = require('src/tmdb/cache');
const TMDB = require('src/tmdb/tmdb'); const TMDB = require('src/tmdb/tmdb');
const cache = new Cache(); const cache = new Cache();
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
/** /**
* Controller: Retrieve nowplaying movies / now airing shows * Controller: Retrieve nowplaying movies / now airing shows
* @param {Request} req http request variable * @param {Request} req http request variable
@@ -12,15 +12,14 @@ const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
* @returns {Callback} * @returns {Callback}
*/ */
function listSearchController(req, res) { function listSearchController(req, res) {
const listname = req.params.listname; const listname = req.params.listname;
const { type, id, page } = req.query; const { type, id, page } = req.query;
console.log(listname, type, id, page) tmdb.listSearch(listname, type, id, page)
tmdb.listSearch(listname, type, id, page) .then((results) => {
.then((results) => { res.send(results);
res.send(results); }).catch((error) => {
}).catch((error) => { res.status(404).send({ success: false, error: error.message });
res.status(404).send({ success: false, error: error.message }); });
});
} }
module.exports = listSearchController; module.exports = listSearchController;

View File

@@ -1,6 +1,7 @@
const configuration = require('src/config/configuration').getInstance(); const configuration = require('src/config/configuration').getInstance();
const Cache = require('src/tmdb/cache'); const Cache = require('src/tmdb/cache');
const TMDB = require('src/tmdb/tmdb'); const TMDB = require('src/tmdb/tmdb');
const cache = new Cache(); const cache = new Cache();
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
@@ -11,14 +12,14 @@ const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
* @returns {Callback} * @returns {Callback}
*/ */
function readMediaController(req, res) { function readMediaController(req, res) {
const mediaId = req.params.mediaId; const mediaId = req.params.mediaId;
const { type } = req.query; const { type } = req.query;
tmdb.lookup(mediaId, type) tmdb.lookup(mediaId, type)
.then((movies) => { .then((movies) => {
res.send(movies); res.send(movies);
}).catch((error) => { }).catch((error) => {
res.status(404).send({ success: false, error: error.message }); res.status(404).send({ success: false, error: error.message });
}); });
} }
module.exports = readMediaController; module.exports = readMediaController;

View File

@@ -1,6 +1,7 @@
const configuration = require('src/config/configuration').getInstance(); const configuration = require('src/config/configuration').getInstance();
const Cache = require('src/tmdb/cache'); const Cache = require('src/tmdb/cache');
const TMDB = require('src/tmdb/tmdb'); const TMDB = require('src/tmdb/tmdb');
const cache = new Cache(); const cache = new Cache();
const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
@@ -11,20 +12,20 @@ const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey'));
* @returns {Callback} * @returns {Callback}
*/ */
function searchMediaController(req, res) { function searchMediaController(req, res) {
const { query, page, type } = req.query; const { query, page, type } = req.query;
Promise.resolve() Promise.resolve()
.then(() => tmdb.search(query, page, type)) .then(() => tmdb.search(query, page, type))
.then((movies) => { .then((movies) => {
if (movies !== undefined || movies.length > 0) { if (movies !== undefined || movies.length > 0) {
res.send(movies); res.send(movies);
} else { } else {
res.status(404).send({ success: false, error: 'Search query did not return any results.'}) res.status(404).send({ success: false, error: 'Search query did not return any results.' });
} }
}) })
.catch((error) => { .catch((error) => {
res.status(500).send({ success: false, error: error.message }); res.status(500).send({ success: false, error: error.message });
}); });
} }
module.exports = searchMediaController; module.exports = searchMediaController;

View File

@@ -1,4 +1,5 @@
const SearchHistory = require('src/searchHistory/searchHistory'); const SearchHistory = require('src/searchHistory/searchHistory');
const searchHistory = new SearchHistory(); const searchHistory = new SearchHistory();
/** /**
@@ -8,15 +9,15 @@ const searchHistory = new SearchHistory();
* @returns {Callback} * @returns {Callback}
*/ */
function historyController(req, res) { function historyController(req, res) {
const user = req.loggedInUser; const user = req.loggedInUser;
searchHistory.read(user) searchHistory.read(user)
.then((searchQueries) => { .then((searchQueries) => {
res.send({ success: true, searchQueries }); res.send({ success: true, searchQueries });
}) })
.catch((error) => { .catch((error) => {
res.status(401).send({ success: false, error: error.message }); res.status(401).send({ success: false, error: error.message });
}); });
} }
module.exports = historyController; module.exports = historyController;

View File

@@ -2,6 +2,7 @@ const User = require('src/user/user');
const Token = require('src/user/token'); const Token = require('src/user/token');
const UserSecurity = require('src/user/userSecurity'); const UserSecurity = require('src/user/userSecurity');
const configuration = require('src/config/configuration').getInstance(); const configuration = require('src/config/configuration').getInstance();
const secret = configuration.get('authentication', 'secret'); const secret = configuration.get('authentication', 'secret');
const userSecurity = new UserSecurity(); const userSecurity = new UserSecurity();
@@ -12,17 +13,17 @@ const userSecurity = new UserSecurity();
* @returns {Callback} * @returns {Callback}
*/ */
function loginController(req, res) { function loginController(req, res) {
const user = new User(req.body.username); const user = new User(req.body.username);
const password = req.body.password; const password = req.body.password;
userSecurity.login(user, password) userSecurity.login(user, password)
.then(() => { .then(() => {
const token = new Token(user).toString(secret); const token = new Token(user).toString(secret);
res.send({ success: true, token }); res.send({ success: true, token });
}) })
.catch((error) => { .catch((error) => {
res.status(401).send({ success: false, error: error.message }); res.status(401).send({ success: false, error: error.message });
}); });
} }
module.exports = loginController; module.exports = loginController;

View File

@@ -1,5 +1,6 @@
const User = require('src/user/user'); const User = require('src/user/user');
const UserSecurity = require('src/user/userSecurity'); const UserSecurity = require('src/user/userSecurity');
const userSecurity = new UserSecurity(); const userSecurity = new UserSecurity();
/** /**
@@ -9,16 +10,16 @@ const userSecurity = new UserSecurity();
* @returns {Callback} * @returns {Callback}
*/ */
function registerController(req, res) { function registerController(req, res) {
const user = new User(req.body.username, req.body.email); const user = new User(req.body.username, req.body.email);
const password = req.body.password; const password = req.body.password;
userSecurity.createNewUser(user, password) userSecurity.createNewUser(user, password)
.then(() => { .then(() => {
res.send({ success: true, message: 'Welcome to Seasoned!' }); res.send({ success: true, message: 'Welcome to Seasoned!' });
}) })
.catch((error) => { .catch((error) => {
res.status(401).send({ success: false, error: error.message }); res.status(401).send({ success: false, error: error.message });
}); });
} }
module.exports = registerController; module.exports = registerController;

View File

@@ -1,11 +1,11 @@
const mustBeAuthenticated = (req, res, next) => { const mustBeAuthenticated = (req, res, next) => {
if (req.loggedInUser === undefined) {
if (req.loggedInUser === undefined) { return res.status(401).send({
return res.status(401).send({ success: false,
success: false, error: 'You must be logged in.',
error: 'You must be logged in.', });
}); } }
return next(); return next();
}; };
module.exports = mustBeAuthenticated; module.exports = mustBeAuthenticated;

View File

@@ -1,5 +1,6 @@
/* eslint-disable no-param-reassign */ /* eslint-disable no-param-reassign */
const configuration = require('src/config/configuration').getInstance(); const configuration = require('src/config/configuration').getInstance();
const secret = configuration.get('authentication', 'secret'); const secret = configuration.get('authentication', 'secret');
const Token = require('src/user/token'); const Token = require('src/user/token');
@@ -7,16 +8,16 @@ const Token = require('src/user/token');
// curl -i -H "Authorization:[token]" localhost:31459/api/v1/user/history // curl -i -H "Authorization:[token]" localhost:31459/api/v1/user/history
const tokenToUser = (req, res, next) => { const tokenToUser = (req, res, next) => {
const rawToken = req.headers.authorization; const rawToken = req.headers.authorization;
if (rawToken) { if (rawToken) {
try { try {
const token = Token.fromString(rawToken, secret); const token = Token.fromString(rawToken, secret);
req.loggedInUser = token.user; req.loggedInUser = token.user;
} catch (error) { } catch (error) {
req.loggedInUser = undefined; req.loggedInUser = undefined;
} }
} }
next(); next();
}; };
module.exports = tokenToUser; module.exports = tokenToUser;

View File

@@ -2,7 +2,10 @@ const config = require('src/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'), () => {
console.log('seasonedAPI'); /* eslint-disable no-console */
console.log(`Database is located at ${config.get('database', 'host')}`); console.log('seasonedAPI');
console.log(`Webserver is listening on ${config.get('webserver', 'port')}`); /* eslint-disable no-console */
}) console.log(`Database is located at ${config.get('database', 'host')}`);
/* eslint-disable no-console */
console.log(`Webserver is listening on ${config.get('webserver', 'port')}`);
});