Refactored retrieval of categories and improved runtime search of files in category

Fixed issue with editing/saving categories

Database queries can now handle nested object paths

Code cleanup
This commit is contained in:
Isaac Abadi
2022-06-17 19:43:32 -04:00
parent c810d4d878
commit b56c66f705
10 changed files with 50 additions and 30 deletions

View File

@@ -933,20 +933,13 @@ app.post('/api/getAllFiles', optionalJwt, async function (req, res) {
else if (file_type_filter === 'video_only') filter_obj['isAudio'] = false;
files = await db_api.getRecords('files', filter_obj, false, sort, range, text_search);
let file_count = await db_api.getRecords('files', filter_obj, true);
playlists = await db_api.getRecords('playlists', {user_uid: uuid});
const categories = await categories_api.getCategoriesAsPlaylists(files);
if (categories) {
playlists = playlists.concat(categories);
}
const file_count = await db_api.getRecords('files', filter_obj, true);
files = JSON.parse(JSON.stringify(files));
res.send({
files: files,
file_count: file_count,
playlists: playlists
});
});
@@ -1383,7 +1376,7 @@ app.post('/api/getPlaylists', optionalJwt, async (req, res) => {
let playlists = await db_api.getRecords('playlists', {user_uid: uuid});
if (include_categories) {
const categories = await categories_api.getCategoriesAsPlaylists(files);
const categories = await categories_api.getCategoriesAsPlaylists();
if (categories) {
playlists = playlists.concat(categories);
}

View File

@@ -55,12 +55,12 @@ async function getCategories() {
return categories ? categories : null;
}
async function getCategoriesAsPlaylists(files = null) {
async function getCategoriesAsPlaylists() {
const categories_as_playlists = [];
const available_categories = await getCategories();
if (available_categories && files) {
if (available_categories) {
for (let category of available_categories) {
const files_that_match = utils.addUIDsToCategory(category, files);
const files_that_match = await db_api.getRecords('files', {'category.uid': category['uid']});
if (files_that_match && files_that_match.length > 0) {
category['thumbnailURL'] = files_that_match[0].thumbnailURL;
category['thumbnailPath'] = files_that_match[0].thumbnailPath;

View File

@@ -127,7 +127,7 @@ function setConfigItem(key, value) {
success = setConfigFile(config_json);
return success;
};
}
function setConfigItems(items) {
let success = false;

View File

@@ -387,9 +387,9 @@ exports.getPlaylist = async (playlist_id, user_uid = null, require_sharing = fal
if (!playlist) {
playlist = await exports.getRecord('categories', {uid: playlist_id});
if (playlist) {
// category found
const files = await exports.getFiles(user_uid);
utils.addUIDsToCategory(playlist, files);
const uids = (await exports.getRecords('files', {'category.uid': playlist_id})).map(file => file.uid);
playlist['uids'] = uids;
playlist['auto'] = true;
}
}
@@ -1090,7 +1090,7 @@ exports.applyFilterLocalDB = (db_path, filter_obj, operation) => {
const filter_prop = filter_props[i];
const filter_prop_value = filter_obj[filter_prop];
if (filter_prop_value === undefined || filter_prop_value === null) {
filtered &= record[filter_prop] === undefined || record[filter_prop] === null
filtered &= record[filter_prop] === undefined || record[filter_prop] === null;
} else {
if (typeof filter_prop_value === 'object') {
if ('$regex' in filter_prop_value) {
@@ -1099,7 +1099,11 @@ exports.applyFilterLocalDB = (db_path, filter_obj, operation) => {
filtered &= filter_prop in record && record[filter_prop] !== filter_prop_value['$ne'];
}
} else {
filtered &= record[filter_prop] === filter_prop_value;
// handle case of nested property check
if (filter_prop.includes('.'))
filtered &= utils.searchObjectByString(record, filter_prop) === filter_prop_value;
else
filtered &= record[filter_prop] === filter_prop_value;
}
}
}

View File

@@ -272,6 +272,11 @@ describe('Database', async function() {
const result = db_api.applyFilterLocalDB([{test: 'test'}, {test: 'test1'}], {test: filter}, 'find');
assert(result && result['test'] === 'test1');
});
it('Nested', async function() {
const result = db_api.applyFilterLocalDB([{test1: {test2: 'test3'}}, {test4: 'test5'}], {'test1.test2': 'test3'}, 'find');
assert(result && result['test1']['test2'] === 'test3');
});
})
});

View File

@@ -456,6 +456,21 @@ function injectArgs(original_args, new_args) {
return updated_args;
}
const searchObjectByString = function(o, s) {
s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
s = s.replace(/^\./, ''); // strip a leading dot
var a = s.split('.');
for (var i = 0, n = a.length; i < n; ++i) {
var k = a[i];
if (k in o) {
o = o[k];
} else {
return;
}
}
return o;
}
// objects
function File(id, title, thumbnailURL, isAudio, duration, url, uploader, size, path, upload_date, description, view_count, height, abr) {
@@ -489,7 +504,6 @@ module.exports = {
createContainerZipFile: createContainerZipFile,
durationStringToNumber: durationStringToNumber,
getMatchingCategoryFiles: getMatchingCategoryFiles,
addUIDsToCategory: addUIDsToCategory,
getCurrentDownloader: getCurrentDownloader,
recFindByExt: recFindByExt,
removeFileExtension: removeFileExtension,
@@ -501,5 +515,6 @@ module.exports = {
fetchFile: fetchFile,
restartServer: restartServer,
injectArgs: injectArgs,
searchObjectByString: searchObjectByString,
File: File
}