mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-02-07 02:39:41 +00:00
parent
58ebde2982
commit
eb7f66c89e
9 changed files with 296 additions and 18 deletions
|
|
@ -684,13 +684,12 @@ class LibraryController {
|
|||
}
|
||||
|
||||
async getAuthors(req, res) {
|
||||
var libraryItems = req.libraryItems
|
||||
var authors = {}
|
||||
libraryItems.forEach((li) => {
|
||||
const authors = {}
|
||||
req.libraryItems.forEach((li) => {
|
||||
if (li.media.metadata.authors && li.media.metadata.authors.length) {
|
||||
li.media.metadata.authors.forEach((au) => {
|
||||
if (!authors[au.id]) {
|
||||
var _author = this.db.authors.find(_au => _au.id === au.id)
|
||||
const _author = this.db.authors.find(_au => _au.id === au.id)
|
||||
if (_author) {
|
||||
authors[au.id] = _author.toJSON()
|
||||
authors[au.id].numBooks = 1
|
||||
|
|
@ -707,6 +706,83 @@ class LibraryController {
|
|||
})
|
||||
}
|
||||
|
||||
async getNarrators(req, res) {
|
||||
const narrators = {}
|
||||
req.libraryItems.forEach((li) => {
|
||||
if (li.media.metadata.narrators && li.media.metadata.narrators.length) {
|
||||
li.media.metadata.narrators.forEach((n) => {
|
||||
if (!narrators[n]) {
|
||||
narrators[n] = {
|
||||
id: encodeURIComponent(Buffer.from(n).toString('base64')),
|
||||
name: n,
|
||||
numBooks: 1
|
||||
}
|
||||
} else {
|
||||
narrators[n].numBooks++
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
res.json({
|
||||
narrators: naturalSort(Object.values(narrators)).asc(n => n.name)
|
||||
})
|
||||
}
|
||||
|
||||
async updateNarrator(req, res) {
|
||||
if (!req.user.canUpdate) {
|
||||
Logger.error(`[LibraryController] Unauthorized user "${req.user.username}" attempted to update narrator`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
const narratorName = libraryHelpers.decode(req.params.narratorId)
|
||||
const updatedName = req.body.name
|
||||
if (!updatedName) {
|
||||
return res.status(400).send('Invalid request payload. Name not specified.')
|
||||
}
|
||||
|
||||
const itemsUpdated = []
|
||||
for (const libraryItem of req.libraryItems) {
|
||||
if (libraryItem.media.metadata.updateNarrator(narratorName, updatedName)) {
|
||||
itemsUpdated.push(libraryItem)
|
||||
}
|
||||
}
|
||||
|
||||
if (itemsUpdated.length) {
|
||||
await this.db.updateLibraryItems(itemsUpdated)
|
||||
SocketAuthority.emitter('items_updated', itemsUpdated.map(li => li.toJSONExpanded()))
|
||||
}
|
||||
|
||||
res.json({
|
||||
updated: itemsUpdated.length
|
||||
})
|
||||
}
|
||||
|
||||
async removeNarrator(req, res) {
|
||||
if (!req.user.canUpdate) {
|
||||
Logger.error(`[LibraryController] Unauthorized user "${req.user.username}" attempted to remove narrator`)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
const narratorName = libraryHelpers.decode(req.params.narratorId)
|
||||
|
||||
const itemsUpdated = []
|
||||
for (const libraryItem of req.libraryItems) {
|
||||
if (libraryItem.media.metadata.removeNarrator(narratorName)) {
|
||||
itemsUpdated.push(libraryItem)
|
||||
}
|
||||
}
|
||||
|
||||
if (itemsUpdated.length) {
|
||||
await this.db.updateLibraryItems(itemsUpdated)
|
||||
SocketAuthority.emitter('items_updated', itemsUpdated.map(li => li.toJSONExpanded()))
|
||||
}
|
||||
|
||||
res.json({
|
||||
updated: itemsUpdated.length
|
||||
})
|
||||
}
|
||||
|
||||
async matchAll(req, res) {
|
||||
if (!req.user.isAdminOrUp) {
|
||||
Logger.error(`[LibraryController] Non-root user attempted to match library items`, req.user)
|
||||
|
|
@ -776,7 +852,7 @@ class LibraryController {
|
|||
return res.sendStatus(404)
|
||||
}
|
||||
|
||||
var library = this.db.libraries.find(lib => lib.id === req.params.id)
|
||||
const library = this.db.libraries.find(lib => lib.id === req.params.id)
|
||||
if (!library) {
|
||||
return res.status(404).send('Library not found')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -221,6 +221,32 @@ class BookMetadata {
|
|||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Update narrator name if narrator is in book
|
||||
* @param {String} oldNarratorName - Narrator name to get updated
|
||||
* @param {String} newNarratorName - Updated narrator name
|
||||
* @return {Boolean} True if narrator was updated
|
||||
*/
|
||||
updateNarrator(oldNarratorName, newNarratorName) {
|
||||
if (!this.hasNarrator(oldNarratorName)) return false
|
||||
this.narrators = this.narrators.filter(n => n !== oldNarratorName)
|
||||
if (!this.hasNarrator(newNarratorName)) {
|
||||
this.narrators.push(newNarratorName)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove narrator name if narrator is in book
|
||||
* @param {String} narratorName - Narrator name to remove
|
||||
* @return {Boolean} True if narrator was updated
|
||||
*/
|
||||
removeNarrator(narratorName) {
|
||||
if (!this.hasNarrator(narratorName)) return false
|
||||
this.narrators = this.narrators.filter(n => n !== narratorName)
|
||||
return true
|
||||
}
|
||||
|
||||
setData(scanMediaData = {}) {
|
||||
this.title = scanMediaData.title || null
|
||||
this.subtitle = scanMediaData.subtitle || null
|
||||
|
|
|
|||
|
|
@ -84,6 +84,9 @@ class ApiRouter {
|
|||
this.router.get('/libraries/:id/search', LibraryController.middleware.bind(this), LibraryController.search.bind(this))
|
||||
this.router.get('/libraries/:id/stats', LibraryController.middleware.bind(this), LibraryController.stats.bind(this))
|
||||
this.router.get('/libraries/:id/authors', LibraryController.middleware.bind(this), LibraryController.getAuthors.bind(this))
|
||||
this.router.get('/libraries/:id/narrators', LibraryController.middleware.bind(this), LibraryController.getNarrators.bind(this))
|
||||
this.router.patch('/libraries/:id/narrators/:narratorId', LibraryController.middleware.bind(this), LibraryController.updateNarrator.bind(this))
|
||||
this.router.delete('/libraries/:id/narrators/:narratorId', LibraryController.middleware.bind(this), LibraryController.removeNarrator.bind(this))
|
||||
this.router.get('/libraries/:id/matchall', LibraryController.middleware.bind(this), LibraryController.matchAll.bind(this))
|
||||
this.router.post('/libraries/:id/scan', LibraryController.middleware.bind(this), LibraryController.scan.bind(this))
|
||||
this.router.get('/libraries/:id/recent-episodes', LibraryController.middleware.bind(this), LibraryController.getRecentEpisodes.bind(this))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue