142 lines
5.1 KiB
JavaScript
142 lines
5.1 KiB
JavaScript
const ApiError = require("../errorClass");
|
||
|
||
async function isAuthorExists(authorId) {
|
||
if (!authorId) return false;
|
||
return (
|
||
(
|
||
await global.database.authors
|
||
.promiseMode()
|
||
.get({ where: { id: authorId } })
|
||
).length !== 0
|
||
);
|
||
}
|
||
|
||
async function isAuthorsExists(authorsId) {
|
||
if (!Array.isArray(authorsId)) return false;
|
||
const authors = (await global.database.authors.promiseMode().get()).map(
|
||
(i) => i.id,
|
||
);
|
||
return authorsId.map((authorId) => authors.includes(authorId));
|
||
}
|
||
|
||
async function checkSyntaxArgs(req, res) {
|
||
return !!(
|
||
// Проверка поля author.
|
||
(req.query.author === undefined
|
||
? true
|
||
: await isAuthorExists(+req.query.author)) && // Проверка поля authors.
|
||
(req.query.authors === undefined
|
||
? true
|
||
: await isAuthorsExists(req.query.authors.split(",").map((i) => +i))) && // Проверка поля offset
|
||
(req.query.offset === undefined
|
||
? true
|
||
: Number.isInteger(+req.query.offset)) && // Проверка поля count
|
||
(req.query.count === undefined
|
||
? true
|
||
: Number.isInteger(+req.query.count)) && // Проверка поля min_date
|
||
(req.query.min_date === undefined
|
||
? true
|
||
: Number.isInteger(+req.query.min_date)) && // Проверка поля max_date
|
||
(req.query.max_date === undefined
|
||
? true
|
||
: Number.isInteger(+req.query.max_date)) && // Проверка поля q. (Ключевые слова для поиска)
|
||
true && // (Проверки нет, query всегда строка, необязательный параметр) // Проверка поля searchByAuthor (Флаг для 'q'. 0 - отключить)
|
||
true && // (Проверки нет, query всегда строка, необязательный параметр) // Проверка поля searchByName (Флаг для 'q'. 0 - отключить)
|
||
true // (Проверки нет, query всегда строка, необязательный параметр)
|
||
);
|
||
}
|
||
|
||
module.exports = async (req, res) => {
|
||
if (req.method !== "GET") {
|
||
throw new ApiError("METHOD_MUST_BE_GET", {
|
||
request_method: req.method,
|
||
});
|
||
}
|
||
if (!(await checkSyntaxArgs(req, res))) {
|
||
throw new ApiError("INVALID_OR_UNSYNTAX_PARAMS", {
|
||
request_method: req.method,
|
||
params: {
|
||
author: req.query?.author === undefined ? null : req.query.author,
|
||
authors: req.query?.authors === undefined ? null : req.query.authors,
|
||
q: req.query?.q === undefined ? null : req.query.q,
|
||
offset: req.query?.offset === undefined ? null : req.query.offset,
|
||
count: req.query?.count === undefined ? null : req.query.count,
|
||
searchByAuthor:
|
||
req.query?.searchByAuthor === undefined
|
||
? null
|
||
: req.query.searchByAuthor,
|
||
searchByName:
|
||
req.query?.searchByName === undefined ? null : req.query.searchByName,
|
||
min_date: req.query?.min_date === undefined ? null : req.query.min_date,
|
||
max_date: req.query?.max_date === undefined ? null : req.query.max_date,
|
||
},
|
||
});
|
||
}
|
||
|
||
// Оптимизация: флаг searchByAuthor выставится на 0, если была запрошена выборка по музыке определённого автора
|
||
// Тем самым, мы ускоряем время ответа, поскольку мы не перебираем массив searchedAuthors с целью поиска совпадений
|
||
let searchByAuthor =
|
||
req.query.author === undefined ? req.query.searchByAuthor : "0";
|
||
|
||
const offset = req.query.offset === undefined ? 0 : +req.query.offset;
|
||
const countFromNull =
|
||
req.query.count === undefined ? undefined : offset + +req.query.count;
|
||
|
||
let result = (
|
||
await global.database.muzic.promiseMode().get(
|
||
req.query?.author === undefined
|
||
? {}
|
||
: {
|
||
where: {
|
||
author_id: +req.query.author,
|
||
},
|
||
},
|
||
)
|
||
).map((i) => ({
|
||
id: i.id,
|
||
name: i.name,
|
||
author_id: i.author_id,
|
||
is_data_exists: i.data !== null,
|
||
date: i.time,
|
||
}));
|
||
// Если просят выборку по authors
|
||
if (req.query.authors) {
|
||
let authors = req.query.authors.split(",").map((author) => +author);
|
||
result = result.filter((res) => authors.includes(res.author_id));
|
||
}
|
||
// Если просят выборку по времени
|
||
if (req.query.min_date || req.query.max_date) {
|
||
const minDate = req.query.min_date === undefined ? 0 : +req.query.min_date;
|
||
const maxDate =
|
||
req.query.max_date === undefined ? 1e32 : +req.query.max_date;
|
||
|
||
result = result.filter((res) => minDate <= res.date && res.date <= maxDate);
|
||
}
|
||
|
||
if (req.query?.q !== undefined) {
|
||
let authors = await global.database.authors.promiseMode().get();
|
||
let searchedAuthors = result.map((i) => {
|
||
let author_id = i.author_id;
|
||
return authors.filter((a) => a.id === author_id)[0];
|
||
});
|
||
result = result.filter((i) => {
|
||
const search = req.query.q.toLowerCase();
|
||
return (
|
||
(req.query.searchByName !== "0" &&
|
||
i.name.toLowerCase().includes(search)) ||
|
||
!!(
|
||
searchByAuthor !== "0" &&
|
||
searchedAuthors
|
||
.filter((a) => a.id === i.author_id)[0]
|
||
?.name.toLowerCase()
|
||
.includes(search)
|
||
)
|
||
);
|
||
});
|
||
}
|
||
result = result.slice(offset, countFromNull);
|
||
return {
|
||
count: result.length,
|
||
items: result,
|
||
};
|
||
}; |