diff --git a/api/controllers/BooksController.js b/api/controllers/BooksController.js index e60a688..1c2ed2c 100644 --- a/api/controllers/BooksController.js +++ b/api/controllers/BooksController.js @@ -22,12 +22,15 @@ module.exports = { if (!body.metadata) throw new HttpError(400, 'Missing OPDS metadata') if (!body.metadata['@type'] || body.metadata['@type'] !== 'http://schema.org/Book') throw new HttpError(400, 'Invalid \'@type\': expected \'http://schema.org/Book\'') + let tags = (body.metadata.tags || '').split(/,\s*/) + if (!tags.length && body.metadata.title) tags = body.metadata.title.split(/\s+/).filter(x => x.length < 3) const query = { hostname: host, title: body.metadata.title, author: body.metadata.author, publisher: body.metadata.publisher, identifier: body.metadata.identifier, + tags: JSON.stringify(tags), version: body.metadata.modified.replace(/\D/g, '') } @@ -49,7 +52,10 @@ module.exports = { } sendUpdatesAsync(result) - return res.json(result) + return res.json({ + ...result, + tags: JSON.parse(result.tags || '[]') + }) } catch (e) { if (e instanceof HttpError) return e.send(res) return res.status(500).json({ @@ -67,9 +73,8 @@ async function sendUpdatesAsync (book) { try { const item = targets[i] const user = await User.findOne({ id: item.user }) - const { author: fAuthor, publisher: fPublisher, title: fTitle, identifier: fIsbn, url } = item - const { author: bAuthor, publisher: bPublisher, title: bTitle, identifier: bIsbn, opds } = book - sails.log('sending ' + book.id + ' info to ' + url) + const { author: fAuthor, publisher: fPublisher, title: fTitle, identifier: fIsbn, tags: fTags, url } = item + const { author: bAuthor, publisher: bPublisher, title: bTitle, identifier: bIsbn, tags: bTags, opds } = book if (uriRegex.test(url)) { if (fAuthor && !((bAuthor || '').includes(fAuthor))) continue @@ -77,6 +82,13 @@ async function sendUpdatesAsync (book) { if (fTitle && !((bTitle || '').includes(fTitle))) continue if (fIsbn && !((bIsbn || '').includes(fIsbn))) continue + const filterTags = JSON.parse(fTags || '[]') + if (filterTags.length && filterTags[0].length) { + const otherSet = new Set(filterTags) + if (!([...new Set(JSON.parse(bTags || '[]'))].filter(x => otherSet.has(x)).length)) continue + } + sails.log('sending ' + book.id + ' info to ' + url) + let content = opds const timestamp = Date.now() request.post({ diff --git a/api/controllers/CatalogController.js b/api/controllers/CatalogController.js index bf1a82a..0df32cd 100644 --- a/api/controllers/CatalogController.js +++ b/api/controllers/CatalogController.js @@ -42,7 +42,17 @@ module.exports = { page = Math.abs(+body.page) || 1 delete body.page } - let books = await Book.find(body || {}).skip((page * perPage) - perPage).limit(perPage) + const searchBody = { ...body } + if (searchBody.tags) { + const tags = searchBody.tags.split(/,\s*/) + searchBody.tags = { + or: [ + ...tags.map(tag => ({ contains: tag })), + { in: tags } + ] + } + } + let books = await Book.find(body ? searchBody : {}).skip((page * perPage) - perPage).limit(perPage) if (!books.length) { throw new HttpError(404, 'No books matching those parameters were found.') diff --git a/api/controllers/TargetController.js b/api/controllers/TargetController.js index 6497265..84d4971 100644 --- a/api/controllers/TargetController.js +++ b/api/controllers/TargetController.js @@ -25,13 +25,15 @@ module.exports = { const publisher = req.param('publisher') || '' const title = req.param('title') || '' const isbn = req.param('isbn') || '' + const tags = req.param('tags') || '' if (value.length) { const url = await TargetUrl.update({ id, user: req.user.id }, { url: value, author, publisher, title, - isbn + isbn, + tags: JSON.stringify(tags.split(/,\s*/)) }).fetch() return res.json(url) } else { @@ -52,9 +54,13 @@ module.exports = { }, list: async function (req, res) { try { - const urls = await TargetUrl.find({ + let urls = await TargetUrl.find({ user: req.user.id }) + urls = urls.map(url => ({ + ...url, + tags: JSON.parse(url.tags || '[]') + })) return res.json(urls) } catch (e) { return (new HttpError(500, e.message)).send(res) diff --git a/api/models/Book.js b/api/models/Book.js index 7b360c1..4cf0c29 100644 --- a/api/models/Book.js +++ b/api/models/Book.js @@ -23,7 +23,8 @@ module.exports = { identifier: { type: 'string' }, version: { type: 'string' }, hostname: { type: 'string' }, - opds: { type: 'json' } + opds: { type: 'json' }, + tags: { type: 'string' } // ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗ // ║╣ ║║║╠╩╗║╣ ║║╚═╗ diff --git a/api/models/TargetUrl.js b/api/models/TargetUrl.js index 413dced..d8a323e 100644 --- a/api/models/TargetUrl.js +++ b/api/models/TargetUrl.js @@ -15,6 +15,7 @@ module.exports = { author: 'string', publisher: 'string', title: 'string', - isbn: 'string' + isbn: 'string', + tags: 'string' } } diff --git a/assets/js/containers/UriListItem.js b/assets/js/containers/UriListItem.js index 961a347..1f95e00 100644 --- a/assets/js/containers/UriListItem.js +++ b/assets/js/containers/UriListItem.js @@ -30,7 +30,7 @@ class UriListItem extends React.Component {