accept opds publication only for publish
parent
962aa0acb6
commit
c5d05eb89c
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const HttpError = require('../errors/HttpError')
|
const HttpError = require('../errors/HttpError')
|
||||||
const { asyncRead, hmacSign } = require('../util')
|
const { hmacSign } = require('../util')
|
||||||
const request = require('request')
|
const request = require('request')
|
||||||
const uriRegex = /^(.+:\/\/)?(.+\.)*(.+\.).{1,}(:\d+)?(.+)?/i
|
const uriRegex = /^(.+:\/\/)?(.+\.)*(.+\.).{1,}(:\d+)?(.+)?/i
|
||||||
|
|
||||||
|
@ -19,37 +19,37 @@ module.exports = {
|
||||||
|
|
||||||
if (!host) throw new HttpError(400, 'Missing hostname')
|
if (!host) throw new HttpError(400, 'Missing hostname')
|
||||||
if (!body) throw new HttpError(400, 'Missing body')
|
if (!body) throw new HttpError(400, 'Missing body')
|
||||||
|
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\'')
|
||||||
|
|
||||||
const bookExists = await Book.findOne(body)
|
const query = {
|
||||||
|
source: host,
|
||||||
|
title: body.metadata.title,
|
||||||
|
author: body.metadata.author,
|
||||||
|
publisher: body.metadata.publisher,
|
||||||
|
identifier: body.metadata.identifier,
|
||||||
|
version: body.metadata.modified.replace(/\D/g, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
const bookExists = await Book.findOne(query)
|
||||||
|
|
||||||
if (bookExists) {
|
if (bookExists) {
|
||||||
throw new HttpError(400, 'Version already exists')
|
throw new HttpError(400, 'Ebook already exists')
|
||||||
} else {
|
} else {
|
||||||
const { title, isbn, author, publisher } = body
|
const { publisher, title, author, identifier } = body.metadata
|
||||||
// require at least 2 fields to be filled out
|
// require at least 3 fields to be filled out
|
||||||
if ([title, isbn, author, publisher].reduce((a, x) => a + (x ? 1 : 0), 0) >= 2) {
|
if ([title, identifier, author, publisher].reduce((a, x) => a + (x ? 1 : 0), 0) >= 3) {
|
||||||
result = await Book.create(body).fetch()
|
result = await Book.create({
|
||||||
|
...query,
|
||||||
|
opds: body
|
||||||
|
}).fetch()
|
||||||
} else {
|
} else {
|
||||||
throw new HttpError(400, 'Please fill out at least 2 fields (title, author, publisher, isbn)')
|
throw new HttpError(400, 'Please fill out at least 3 opds metadata fields (title, author, publisher, identifier)')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.file('opds')) {
|
sendUpdatesAsync(result)
|
||||||
req.file('opds').upload(sails.config.skipperConfig, async function (err, uploaded) {
|
return res.json(result)
|
||||||
if (err) {
|
|
||||||
await Book.destroy({ id: result.id })
|
|
||||||
throw new HttpError(500, err.message)
|
|
||||||
}
|
|
||||||
const fd = (uploaded[0] || {}).fd
|
|
||||||
await Book.update({ id: result.id }, { storage: fd })
|
|
||||||
sendUpdatesAsync(result.id)
|
|
||||||
return res.json({
|
|
||||||
...result
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
throw new HttpError(400, 'Missing OPDS file upload')
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof HttpError) return e.send(res)
|
if (e instanceof HttpError) return e.send(res)
|
||||||
return res.status(500).json({
|
return res.status(500).json({
|
||||||
|
@ -59,16 +59,16 @@ module.exports = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sendUpdatesAsync (id) {
|
async function sendUpdatesAsync (book) {
|
||||||
const book = await Book.findOne({ id })
|
const id = book.id
|
||||||
const targets = await TargetUrl.find()
|
const targets = await TargetUrl.find()
|
||||||
if (!book) return
|
if (!book) return
|
||||||
for (const i in targets) {
|
for (const i in targets) {
|
||||||
try {
|
try {
|
||||||
const item = targets[i]
|
const item = targets[i]
|
||||||
const user = await User.findOne({ id: item.user })
|
const user = await User.findOne({ id: item.user })
|
||||||
const { author: fAuthor, publisher: fPublisher, title: fTitle, isbn: fIsbn, url } = item
|
const { author: fAuthor, publisher: fPublisher, title: fTitle, identifier: fIsbn, url } = item
|
||||||
const { author: bAuthor, publisher: bPublisher, title: bTitle, isbn: bIsbn } = book
|
const { author: bAuthor, publisher: bPublisher, title: bTitle, identifier: bIsbn, opds } = book
|
||||||
sails.log('sending ' + book.id + ' info to ' + url)
|
sails.log('sending ' + book.id + ' info to ' + url)
|
||||||
|
|
||||||
if (uriRegex.test(url)) {
|
if (uriRegex.test(url)) {
|
||||||
|
@ -77,17 +77,7 @@ async function sendUpdatesAsync (id) {
|
||||||
if (fTitle && !((bTitle || '').includes(fTitle))) continue
|
if (fTitle && !((bTitle || '').includes(fTitle))) continue
|
||||||
if (fIsbn && !((bIsbn || '').includes(fIsbn))) continue
|
if (fIsbn && !((bIsbn || '').includes(fIsbn))) continue
|
||||||
|
|
||||||
let content
|
let content = opds
|
||||||
const skipperConfig = sails.config.skipperConfig
|
|
||||||
const adapterConfig = { ...skipperConfig, adapter: undefined }
|
|
||||||
const skipperAdapter = skipperConfig.adapter(adapterConfig)
|
|
||||||
const opdsHelper = await sails.helpers.opds()
|
|
||||||
try {
|
|
||||||
if (!book.storage.length) throw new Error('missing book opds file')
|
|
||||||
content = await asyncRead(skipperAdapter, opdsHelper, book.storage)
|
|
||||||
} catch (e) {
|
|
||||||
content = await opdsHelper.book2opds(book)
|
|
||||||
}
|
|
||||||
const timestamp = Date.now()
|
const timestamp = Date.now()
|
||||||
request.post({
|
request.post({
|
||||||
url: url,
|
url: url,
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
const HttpError = require('../errors/HttpError')
|
const HttpError = require('../errors/HttpError')
|
||||||
const { asyncRead } = require('../util')
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
navigation: async function (req, res) {
|
navigation: async function (req, res) {
|
||||||
|
@ -49,19 +48,7 @@ module.exports = {
|
||||||
throw new HttpError(404, 'No books matching those parameters were found.')
|
throw new HttpError(404, 'No books matching those parameters were found.')
|
||||||
}
|
}
|
||||||
|
|
||||||
const skipperConfig = sails.config.skipperConfig
|
books = books.map(b => b.opds)
|
||||||
const adapterConfig = { ...skipperConfig, adapter: undefined }
|
|
||||||
const skipperAdapter = skipperConfig.adapter(adapterConfig)
|
|
||||||
const opdsHelper = await sails.helpers.opds()
|
|
||||||
|
|
||||||
books = await Promise.all(books.map(book => {
|
|
||||||
try {
|
|
||||||
if (!book.storage.length) throw new Error('missing book opds file')
|
|
||||||
return asyncRead(skipperAdapter, opdsHelper, book.storage)
|
|
||||||
} catch (e) {
|
|
||||||
return opdsHelper.book2opds(book)
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
|
|
||||||
return res.json({
|
return res.json({
|
||||||
metadata: {
|
metadata: {
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
exports.up = function (knex, Promise) {
|
||||||
|
return Promise.all([
|
||||||
|
knex.schema.table('book', t => {
|
||||||
|
t.json('opds')
|
||||||
|
t.renameColumn('isbn', 'identifier')
|
||||||
|
t.dropColumns('storage')
|
||||||
|
})
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.down = function (knex, Promise) {
|
||||||
|
return Promise.all([
|
||||||
|
knex.schema.table('book', t => {
|
||||||
|
t.dropColumns('opds')
|
||||||
|
t.renameColumn('identifier', 'isbn')
|
||||||
|
t.string('storage')
|
||||||
|
})
|
||||||
|
])
|
||||||
|
}
|
Loading…
Reference in New Issue