mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-02-01 00:18:14 +01:00
New data model authors routes
This commit is contained in:
parent
65df377a49
commit
dad12537b6
@ -20,6 +20,10 @@
|
|||||||
<p class="text-center font-semibold truncate" :style="{ fontSize: sizeMultiplier + 'rem' }">{{ name }}</p>
|
<p class="text-center font-semibold truncate" :style="{ fontSize: sizeMultiplier + 'rem' }">{{ name }}</p>
|
||||||
<p class="text-center text-gray-200" :style="{ fontSize: sizeMultiplier * 0.85 + 'rem' }">{{ numBooks }} Book{{ numBooks === 1 ? '' : 's' }}</p>
|
<p class="text-center text-gray-200" :style="{ fontSize: sizeMultiplier * 0.85 + 'rem' }">{{ numBooks }} Book{{ numBooks === 1 ? '' : 's' }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="absolute top-0 right-0 p-2 cursor-pointer hover:text-white text-gray-200" @click.stop="searchAuthor">
|
||||||
|
<span class="material-icons">search</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -74,7 +78,15 @@ export default {
|
|||||||
return url.href + `?token=${this.userToken}&ts=${this.lastUpdate}`
|
return url.href + `?token=${this.userToken}&ts=${this.lastUpdate}`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {},
|
methods: {
|
||||||
|
async searchAuthor() {
|
||||||
|
var author = await this.$axios.$post(`/api/authors/${this.authorId}/match`, { q: this.name }).catch((error) => {
|
||||||
|
console.error('Failed', error)
|
||||||
|
return null
|
||||||
|
})
|
||||||
|
console.log('Got author', author)
|
||||||
|
}
|
||||||
|
},
|
||||||
mounted() {}
|
mounted() {}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
@ -16,6 +16,7 @@ const MeController = require('./controllers/MeController')
|
|||||||
const BackupController = require('./controllers/BackupController')
|
const BackupController = require('./controllers/BackupController')
|
||||||
const LibraryItemController = require('./controllers/LibraryItemController')
|
const LibraryItemController = require('./controllers/LibraryItemController')
|
||||||
const SeriesController = require('./controllers/SeriesController')
|
const SeriesController = require('./controllers/SeriesController')
|
||||||
|
const AuthorController = require('./controllers/AuthorController')
|
||||||
|
|
||||||
const BookFinder = require('./finders/BookFinder')
|
const BookFinder = require('./finders/BookFinder')
|
||||||
const AuthorFinder = require('./finders/AuthorFinder')
|
const AuthorFinder = require('./finders/AuthorFinder')
|
||||||
@ -161,12 +162,9 @@ class ApiController {
|
|||||||
//
|
//
|
||||||
// Author Routes
|
// Author Routes
|
||||||
//
|
//
|
||||||
this.router.get('/authors', this.getAuthors.bind(this))
|
this.router.get('/authors/:id', AuthorController.middleware.bind(this), AuthorController.findOne.bind(this))
|
||||||
this.router.get('/authors/search', this.searchAuthors.bind(this))
|
this.router.post('/authors/:id/match', AuthorController.middleware.bind(this), AuthorController.match.bind(this))
|
||||||
this.router.get('/authors/:id', this.getAuthor.bind(this))
|
this.router.get('/authors/search', AuthorController.search.bind(this))
|
||||||
this.router.post('/authors', this.createAuthor.bind(this))
|
|
||||||
this.router.patch('/authors/:id', this.updateAuthor.bind(this))
|
|
||||||
this.router.delete('/authors/:id', this.deleteAuthor.bind(this))
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Series Routes
|
// Series Routes
|
||||||
@ -230,64 +228,6 @@ class ApiController {
|
|||||||
res.json({ user: req.user })
|
res.json({ user: req.user })
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAuthors(req, res) {
|
|
||||||
res.json(this.db.authors)
|
|
||||||
}
|
|
||||||
|
|
||||||
searchAuthors(req, res) {
|
|
||||||
var query = req.query.q || ''
|
|
||||||
var limit = req.query.limit && !isNaN(req.query.limit) ? Number(req.query.limit) : 100
|
|
||||||
var authors = this.db.authors.filter(au => au.name.toLowerCase().includes(query.toLowerCase()))
|
|
||||||
authors = authors.slice(0, limit)
|
|
||||||
res.json(authors)
|
|
||||||
}
|
|
||||||
|
|
||||||
async getAuthor(req, res) {
|
|
||||||
var author = this.db.authors.find(p => p.id === req.params.id)
|
|
||||||
if (!author) {
|
|
||||||
return res.status(404).send('Author not found')
|
|
||||||
}
|
|
||||||
res.json(author.toJSON())
|
|
||||||
}
|
|
||||||
|
|
||||||
async createAuthor(req, res) {
|
|
||||||
var author = await this.authorFinder.createAuthor(req.body)
|
|
||||||
if (!author) {
|
|
||||||
return res.status(500).send('Failed to create author')
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.db.insertEntity('author', author)
|
|
||||||
this.emitter('author_added', author.toJSON())
|
|
||||||
res.json(author)
|
|
||||||
}
|
|
||||||
|
|
||||||
async updateAuthor(req, res) {
|
|
||||||
var author = this.db.authors.find(p => p.id === req.params.id)
|
|
||||||
if (!author) {
|
|
||||||
return res.status(404).send('Author not found')
|
|
||||||
}
|
|
||||||
|
|
||||||
var wasUpdated = author.update(req.body)
|
|
||||||
if (wasUpdated) {
|
|
||||||
await this.db.updateEntity('author', author)
|
|
||||||
this.emitter('author_updated', author.toJSON())
|
|
||||||
}
|
|
||||||
res.json(author)
|
|
||||||
}
|
|
||||||
|
|
||||||
async deleteAuthor(req, res) {
|
|
||||||
var author = this.db.authors.find(p => p.id === req.params.id)
|
|
||||||
if (!author) {
|
|
||||||
return res.status(404).send('Author not found')
|
|
||||||
}
|
|
||||||
|
|
||||||
var authorJson = author.toJSON()
|
|
||||||
|
|
||||||
await this.db.removeEntity('author', author.id)
|
|
||||||
this.emitter('author_removed', authorJson)
|
|
||||||
res.sendStatus(200)
|
|
||||||
}
|
|
||||||
|
|
||||||
async updateServerSettings(req, res) {
|
async updateServerSettings(req, res) {
|
||||||
if (!req.user.isRoot) {
|
if (!req.user.isRoot) {
|
||||||
Logger.error('User other than root attempting to update server settings', req.user)
|
Logger.error('User other than root attempting to update server settings', req.user)
|
||||||
|
56
server/controllers/AuthorController.js
Normal file
56
server/controllers/AuthorController.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
const Logger = require('../Logger')
|
||||||
|
|
||||||
|
class AuthorController {
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
async findOne(req, res) {
|
||||||
|
return res.json(req.author)
|
||||||
|
}
|
||||||
|
|
||||||
|
async search(req, res) {
|
||||||
|
var q = (req.query.q || '').toLowerCase()
|
||||||
|
if (!q) return res.json([])
|
||||||
|
var limit = (req.query.limit && !isNaN(req.query.limit)) ? Number(req.query.limit) : 25
|
||||||
|
var authors = this.db.authors.filter(au => au.name.toLowerCase().includes(q))
|
||||||
|
authors = authors.slice(0, limit)
|
||||||
|
res.json(authors)
|
||||||
|
}
|
||||||
|
|
||||||
|
async match(req, res) {
|
||||||
|
var authorData = await this.authorFinder.findAuthorByName(req.body.q)
|
||||||
|
if (!authorData) {
|
||||||
|
return res.status(404).send('Author not found')
|
||||||
|
}
|
||||||
|
req.author.asin = authorData.asin
|
||||||
|
if (authorData.image) {
|
||||||
|
var imageData = await this.authorFinder.saveAuthorImage(req.author.id, authorData.image)
|
||||||
|
if (imageData) {
|
||||||
|
req.author.imagePath = imageData.path
|
||||||
|
req.author.relImagePath = imageData.relPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (authorData.description) {
|
||||||
|
req.author.description = authorData.description
|
||||||
|
}
|
||||||
|
await this.db.updateEntity('author', req.author)
|
||||||
|
this.emitter('author_updated', req.author)
|
||||||
|
res.json(req.author)
|
||||||
|
}
|
||||||
|
|
||||||
|
middleware(req, res, next) {
|
||||||
|
var author = this.db.authors.find(au => au.id === req.params.id)
|
||||||
|
if (!author) return res.sendStatus(404)
|
||||||
|
|
||||||
|
if (req.method == 'DELETE' && !req.user.canDelete) {
|
||||||
|
Logger.warn(`[AuthorController] User attempted to delete without permission`, req.user)
|
||||||
|
return res.sendStatus(403)
|
||||||
|
} else if ((req.method == 'PATCH' || req.method == 'POST') && !req.user.canUpdate) {
|
||||||
|
Logger.warn('[AuthorController] User attempted to update without permission', req.user)
|
||||||
|
return res.sendStatus(403)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.author = author
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = new AuthorController()
|
@ -31,6 +31,27 @@ class AuthorFinder {
|
|||||||
return author
|
return author
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async saveAuthorImage(authorId, url) {
|
||||||
|
var authorDir = this.AuthorPath
|
||||||
|
var relAuthorDir = Path.posix.join('/metadata', 'authors')
|
||||||
|
await fs.ensureDir(authorDir)
|
||||||
|
|
||||||
|
var imageExtension = url.toLowerCase().split('.').pop()
|
||||||
|
var ext = imageExtension === 'png' ? 'png' : 'jpg'
|
||||||
|
var filename = authorId + '.' + ext
|
||||||
|
var outputPath = Path.posix.join(authorDir, filename)
|
||||||
|
var relPath = Path.posix.join(relAuthorDir, filename)
|
||||||
|
|
||||||
|
var success = await this.downloadImage(url, outputPath)
|
||||||
|
if (!success) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
path: outputPath,
|
||||||
|
relPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async createAuthor(payload) {
|
async createAuthor(payload) {
|
||||||
if (!payload || !payload.name) return null
|
if (!payload || !payload.name) return null
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ class Author {
|
|||||||
this.id = null
|
this.id = null
|
||||||
this.asin = null
|
this.asin = null
|
||||||
this.name = null
|
this.name = null
|
||||||
|
this.description = null
|
||||||
this.imagePath = null
|
this.imagePath = null
|
||||||
this.relImagePath = null
|
this.relImagePath = null
|
||||||
this.addedAt = null
|
this.addedAt = null
|
||||||
@ -19,6 +20,7 @@ class Author {
|
|||||||
this.id = author.id
|
this.id = author.id
|
||||||
this.asin = author.asin
|
this.asin = author.asin
|
||||||
this.name = author.name
|
this.name = author.name
|
||||||
|
this.description = author.description || null
|
||||||
this.imagePath = author.imagePath
|
this.imagePath = author.imagePath
|
||||||
this.relImagePath = author.relImagePath
|
this.relImagePath = author.relImagePath
|
||||||
this.addedAt = author.addedAt
|
this.addedAt = author.addedAt
|
||||||
@ -30,6 +32,7 @@ class Author {
|
|||||||
id: this.id,
|
id: this.id,
|
||||||
asin: this.asin,
|
asin: this.asin,
|
||||||
name: this.name,
|
name: this.name,
|
||||||
|
description: this.description,
|
||||||
imagePath: this.imagePath,
|
imagePath: this.imagePath,
|
||||||
relImagePath: this.relImagePath,
|
relImagePath: this.relImagePath,
|
||||||
addedAt: this.addedAt,
|
addedAt: this.addedAt,
|
||||||
@ -47,6 +50,7 @@ class Author {
|
|||||||
setData(data) {
|
setData(data) {
|
||||||
this.id = getId('aut')
|
this.id = getId('aut')
|
||||||
this.name = data.name
|
this.name = data.name
|
||||||
|
this.description = data.description || null
|
||||||
this.asin = data.asin || null
|
this.asin = data.asin || null
|
||||||
this.imagePath = data.imagePath || null
|
this.imagePath = data.imagePath || null
|
||||||
this.relImagePath = data.relImagePath || null
|
this.relImagePath = data.relImagePath || null
|
||||||
|
@ -4,6 +4,7 @@ class Series {
|
|||||||
constructor(series) {
|
constructor(series) {
|
||||||
this.id = null
|
this.id = null
|
||||||
this.name = null
|
this.name = null
|
||||||
|
this.description = null
|
||||||
this.addedAt = null
|
this.addedAt = null
|
||||||
this.updatedAt = null
|
this.updatedAt = null
|
||||||
|
|
||||||
@ -15,6 +16,7 @@ class Series {
|
|||||||
construct(series) {
|
construct(series) {
|
||||||
this.id = series.id
|
this.id = series.id
|
||||||
this.name = series.name
|
this.name = series.name
|
||||||
|
this.description = series.description || null
|
||||||
this.addedAt = series.addedAt
|
this.addedAt = series.addedAt
|
||||||
this.updatedAt = series.updatedAt
|
this.updatedAt = series.updatedAt
|
||||||
}
|
}
|
||||||
@ -23,6 +25,7 @@ class Series {
|
|||||||
return {
|
return {
|
||||||
id: this.id,
|
id: this.id,
|
||||||
name: this.name,
|
name: this.name,
|
||||||
|
description: this.description,
|
||||||
addedAt: this.addedAt,
|
addedAt: this.addedAt,
|
||||||
updatedAt: this.updatedAt
|
updatedAt: this.updatedAt
|
||||||
}
|
}
|
||||||
@ -39,6 +42,7 @@ class Series {
|
|||||||
setData(data) {
|
setData(data) {
|
||||||
this.id = getId('ser')
|
this.id = getId('ser')
|
||||||
this.name = data.name
|
this.name = data.name
|
||||||
|
this.description = data.description || null
|
||||||
this.addedAt = Date.now()
|
this.addedAt = Date.now()
|
||||||
this.updatedAt = Date.now()
|
this.updatedAt = Date.now()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user