Files
seasonedShows/seasoned_api/src/request/request.js

168 lines
6.7 KiB
JavaScript

const assert = require('assert')
const configuration = require('src/config/configuration').getInstance();
const TMDB = require('src/tmdb/tmdb');
const tmdb = new TMDB(configuration.get('tmdb', 'apiKey'));
const establishedDatabase = require('src/database/database');
const utils = require('./utils');
class RequestRepository {
constructor(database) {
this.database = database || establishedDatabase;
this.queries = {
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',
fetchAllFilteredStatus: '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 ? ?`,
fetchAllFilter: `select id, type from request where ? is "?"`,
fetchAllQuery: `select id, type from request where title like "%?%" or year like "%?%"`,
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)',
// deluge: '(select status from deluge_torrent where id is request.id and type is request.type limit 1)',
// fetchAllFilterStatus: 'select * from request where '
readWithoutUserData: 'select id, title, year, type, status, date from requests where id is ? and type is ?',
read: 'select id, title, year, type, status, requested_by, ip, date, user_agent from requests where id is ? and type is ?'
};
}
sortAndFilterToDbQuery(by, direction, filter, query) {
let dbQuery = undefined;
if (query !== undefined) {
const dbParams = [query, query];
const dbquery = this.queries.fetchAllQuery
dbQuery = dbquery.split('').map((char) => char === '?' ? dbParams.shift() : char).join('')
}
else if (by !== undefined && filter !== undefined) {
const paramToColumnAndValue = {
movie: ['type', 'movie'],
show: ['type', 'show']
}
const dbParams = paramToColumnAndValue[filter].concat([by, direction]);
const query = this.queries.fetchAllFilterAndSort;
dbQuery = query.split('').map((char) => char === '?' ? dbParams.shift() : char).join('')
}
else if (by !== undefined) {
const dbParams = [by, direction];
const query = this.queries.fetchAllSort;
dbQuery = query.split('').map((char) => char === '?' ? dbParams.shift() : char).join('')
}
else if (filter !== undefined) {
const paramToColumnAndValue = {
movie: ['type', 'movie'],
show: ['type', 'show'],
downloaded: [this.queries.downloaded, 'downloaded']
// downloading: [this.database.delugeStatus, 'downloading']
}
const dbParams = paramToColumnAndValue[filter]
const query = this.queries.fetchAllFilter;
dbQuery = query.split('').map((char) => char === '?' ? dbParams.shift() : char).join('')
}
else {
dbQuery = this.queries.fetchAll;
}
return dbQuery
}
mapToTmdbByType(rows) {
return rows.map((row) => {
if (row.type === 'movie')
return tmdb.movieInfo(row.id)
else if (row.type === 'show')
return tmdb.showInfo(row.id)
})
}
/**
* Add tmdb movie|show to requests
* @param {tmdb} tmdb class of movie|show to add
* @returns {Promise}
*/
requestFromTmdb(tmdb, ip, user_agent, username) {
return Promise.resolve()
.then(() => this.database.get(this.queries.read, [tmdb.id, tmdb.type]))
.then(row => assert.equal(row, undefined, 'Id has already been requested'))
.then(() => 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);
throw new Error('Could not add request');
});
}
/**
* Get request item by id
* @param {String} id
* @param {String} type
* @returns {Promise}
*/
getRequestByIdAndType(id, type) {
return this.database.get(this.queries.readWithoutUserData, [id, type])
.then(row => {
assert(row, 'Could not find request item with that id and type')
return {
id: row.id,
title: row.title,
year: row.year,
type: row.type,
status: row.status,
requested_date: new Date(row.date)
}
})
}
/**
* Fetch all requests with optional sort and filter params
* @param {String} what we are sorting by
* @param {String} direction that can be either 'asc' or 'desc', default 'asc'.
* @param {String} params to filter by
* @param {String} query param to filter result on. Filters on title and year
* @returns {Promise}
*/
fetchAll(page=1, sort_by=undefined, sort_direction='asc', filter=undefined, query=undefined) {
// TODO implemented sort and filter
page = parseInt(page)
let fetchQuery = this.queries.fetchAll
let fetchTotalResults = this.queries.totalRequests
let fetchParams = [page]
if (filter && (filter === 'downloading' || filter === 'downloaded' || filter === 'requested')) {
console.log('tes')
fetchQuery = this.queries.fetchAllFilteredStatus
fetchTotalResults = this.queries.totalRequestsFilteredStatus
fetchParams = [filter, page]
} else {
filter = undefined
}
return Promise.resolve()
.then((dbQuery) => this.database.all(fetchQuery, fetchParams))
.then(async (rows) => {
const sqliteResponse = await this.database.get(fetchTotalResults, filter ? filter : undefined)
const totalRequests = sqliteResponse['totalRequests']
const totalPages = Math.ceil(totalRequests / 26)
return [ rows.map(item => {
item.poster = item.poster_path; delete item.poster_path;
item.backdrop = item.background_path; delete item.background_path;
return item
}), totalPages, totalRequests ]
return Promise.all(this.mapToTmdbByType(rows))
})
.then(([result, totalPages, totalRequests]) => Promise.resolve({
results: result, total_results: totalRequests, page: page, total_pages: totalPages
}))
.catch(error => { console.log(error);throw error })
}
}
module.exports = RequestRepository;