mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-08-04 18:24:46 +02:00
Update global search, fix toggling between automated backup, add open search cover in new tab #83
This commit is contained in:
parent
59d12ef5de
commit
32bc9d5282
16 changed files with 254 additions and 52 deletions
|
@ -30,6 +30,7 @@ class ApiController {
|
|||
this.router.get('/find/:method', this.find.bind(this))
|
||||
|
||||
this.router.get('/libraries', this.getLibraries.bind(this))
|
||||
this.router.get('/library/:id/search', this.searchLibrary.bind(this))
|
||||
this.router.get('/library/:id', this.getLibrary.bind(this))
|
||||
this.router.delete('/library/:id', this.deleteLibrary.bind(this))
|
||||
this.router.patch('/library/:id', this.updateLibrary.bind(this))
|
||||
|
@ -97,6 +98,53 @@ class ApiController {
|
|||
res.json(libraries)
|
||||
}
|
||||
|
||||
searchLibrary(req, res) {
|
||||
var library = this.db.libraries.find(lib => lib.id === req.params.id)
|
||||
if (!library) {
|
||||
return res.status(404).send('Library not found')
|
||||
}
|
||||
if (!req.query.q) {
|
||||
return res.status(400).send('No query string')
|
||||
}
|
||||
var maxResults = req.query.max || 3
|
||||
|
||||
var bookMatches = []
|
||||
var authorMatches = {}
|
||||
var seriesMatches = {}
|
||||
|
||||
var audiobooksInLibrary = this.db.audiobooks.filter(ab => ab.libraryId === library.id)
|
||||
audiobooksInLibrary.forEach((ab) => {
|
||||
var queryResult = ab.searchQuery(req.query.q)
|
||||
if (queryResult.book) {
|
||||
bookMatches.push({
|
||||
audiobook: ab,
|
||||
matchKey: queryResult.book
|
||||
})
|
||||
}
|
||||
if (queryResult.author && !authorMatches[queryResult.author]) {
|
||||
authorMatches[queryResult.author] = {
|
||||
author: queryResult.author
|
||||
}
|
||||
}
|
||||
if (queryResult.series) {
|
||||
if (!seriesMatches[queryResult.series]) {
|
||||
seriesMatches[queryResult.series] = {
|
||||
series: queryResult.series,
|
||||
audiobooks: [ab]
|
||||
}
|
||||
} else {
|
||||
seriesMatches[queryResult.series].audiobooks.push(ab)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
res.json({
|
||||
audiobooks: bookMatches.slice(0, maxResults),
|
||||
authors: Object.values(authorMatches).slice(0, maxResults),
|
||||
series: Object.values(seriesMatches).slice(0, maxResults)
|
||||
})
|
||||
}
|
||||
|
||||
getLibrary(req, res) {
|
||||
var library = this.db.libraries.find(lib => lib.id === req.params.id)
|
||||
if (!library) {
|
||||
|
@ -563,8 +611,14 @@ class ApiController {
|
|||
if (!settingsUpdate || !isObject(settingsUpdate)) {
|
||||
return res.status(500).send('Invalid settings update object')
|
||||
}
|
||||
|
||||
var madeUpdates = this.db.serverSettings.update(settingsUpdate)
|
||||
if (madeUpdates) {
|
||||
// If backup schedule is updated - update backup manager
|
||||
if (settingsUpdate.backupSchedule !== undefined) {
|
||||
this.backupManager.updateCronSchedule()
|
||||
}
|
||||
|
||||
await this.db.updateEntity('settings', this.db.serverSettings)
|
||||
}
|
||||
return res.json({
|
||||
|
|
|
@ -21,6 +21,8 @@ class BackupManager {
|
|||
this.Gid = Gid
|
||||
this.db = db
|
||||
|
||||
this.scheduleTask = null
|
||||
|
||||
this.backups = []
|
||||
}
|
||||
|
||||
|
@ -28,7 +30,7 @@ class BackupManager {
|
|||
return this.db.serverSettings || {}
|
||||
}
|
||||
|
||||
async init(overrideCron = null) {
|
||||
async init() {
|
||||
var backupsDirExists = await fs.pathExists(this.BackupPath)
|
||||
if (!backupsDirExists) {
|
||||
await fs.ensureDir(this.BackupPath)
|
||||
|
@ -36,16 +38,34 @@ class BackupManager {
|
|||
}
|
||||
|
||||
await this.loadBackups()
|
||||
this.scheduleCron()
|
||||
}
|
||||
|
||||
scheduleCron() {
|
||||
if (!this.serverSettings.backupSchedule) {
|
||||
Logger.info(`[BackupManager] Auto Backups are disabled`)
|
||||
return
|
||||
}
|
||||
try {
|
||||
var cronSchedule = overrideCron || this.serverSettings.backupSchedule
|
||||
cron.schedule(cronSchedule, this.runBackup.bind(this))
|
||||
var cronSchedule = this.serverSettings.backupSchedule
|
||||
this.scheduleTask = cron.schedule(cronSchedule, this.runBackup.bind(this))
|
||||
} catch (error) {
|
||||
Logger.error(`[BackupManager] Failed to schedule backup cron ${this.serverSettings.backupSchedule}`)
|
||||
Logger.error(`[BackupManager] Failed to schedule backup cron ${this.serverSettings.backupSchedule}`, error)
|
||||
}
|
||||
}
|
||||
|
||||
updateCronSchedule() {
|
||||
if (this.scheduleTask && !this.serverSettings.backupSchedule) {
|
||||
Logger.info(`[BackupManager] Disabling backup schedule`)
|
||||
if (this.scheduleTask.destroy) this.scheduleTask.destroy()
|
||||
this.scheduleTask = null
|
||||
} else if (!this.scheduleTask && this.serverSettings.backupSchedule) {
|
||||
Logger.info(`[BackupManager] Starting backup schedule ${this.serverSettings.backupSchedule}`)
|
||||
this.scheduleCron()
|
||||
} else if (this.serverSettings.backupSchedule) {
|
||||
Logger.info(`[BackupManager] Restarting backup schedule ${this.serverSettings.backupSchedule}`)
|
||||
if (this.scheduleTask.destroy) this.scheduleTask.destroy()
|
||||
this.scheduleCron()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -623,6 +623,10 @@ class Audiobook {
|
|||
return this.book.isSearchMatch(search.toLowerCase().trim())
|
||||
}
|
||||
|
||||
searchQuery(search) {
|
||||
return this.book.getQueryMatches(search.toLowerCase().trim())
|
||||
}
|
||||
|
||||
getAudioFileByIno(ino) {
|
||||
return this.audioFiles.find(af => af.ino === ino)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ const parseAuthors = require('../utils/parseAuthors')
|
|||
|
||||
class Book {
|
||||
constructor(book = null) {
|
||||
this.olid = null
|
||||
this.title = null
|
||||
this.subtitle = null
|
||||
this.author = null
|
||||
|
@ -46,7 +45,6 @@ class Book {
|
|||
}
|
||||
|
||||
construct(book) {
|
||||
this.olid = book.olid
|
||||
this.title = book.title
|
||||
this.subtitle = book.subtitle || null
|
||||
this.author = book.author
|
||||
|
@ -69,7 +67,6 @@ class Book {
|
|||
|
||||
toJSON() {
|
||||
return {
|
||||
olid: this.olid,
|
||||
title: this.title,
|
||||
subtitle: this.subtitle,
|
||||
author: this.author,
|
||||
|
@ -111,7 +108,6 @@ class Book {
|
|||
}
|
||||
|
||||
setData(data) {
|
||||
this.olid = data.olid || null
|
||||
this.title = data.title || null
|
||||
this.subtitle = data.subtitle || null
|
||||
this.author = data.author || null
|
||||
|
@ -217,6 +213,17 @@ class Book {
|
|||
return this._title.toLowerCase().includes(search) || this._subtitle.toLowerCase().includes(search) || this._author.toLowerCase().includes(search) || this._series.toLowerCase().includes(search)
|
||||
}
|
||||
|
||||
getQueryMatches(search) {
|
||||
var titleMatch = this._title.toLowerCase().includes(search) || this._subtitle.toLowerCase().includes(search)
|
||||
var authorMatch = this._author.toLowerCase().includes(search)
|
||||
var seriesMatch = this._series.toLowerCase().includes(search)
|
||||
return {
|
||||
book: titleMatch ? 'title' : authorMatch ? 'author' : seriesMatch ? 'series' : false,
|
||||
author: authorMatch ? this._author : false,
|
||||
series: seriesMatch ? this._series : false
|
||||
}
|
||||
}
|
||||
|
||||
setDetailsFromFileMetadata(audioFileMetadata) {
|
||||
const MetadataMapArray = [
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@ class Library {
|
|||
this.id = null
|
||||
this.name = null
|
||||
this.folders = []
|
||||
this.icon = 'database'
|
||||
|
||||
this.lastScan = 0
|
||||
|
||||
|
@ -24,6 +25,8 @@ class Library {
|
|||
this.id = library.id
|
||||
this.name = library.name
|
||||
this.folders = (library.folders || []).map(f => new Folder(f))
|
||||
this.icon = library.icon || 'database'
|
||||
|
||||
this.createdAt = library.createdAt
|
||||
this.lastUpdate = library.lastUpdate
|
||||
}
|
||||
|
@ -33,6 +36,7 @@ class Library {
|
|||
id: this.id,
|
||||
name: this.name,
|
||||
folders: (this.folders || []).map(f => f.toJSON()),
|
||||
icon: this.icon,
|
||||
createdAt: this.createdAt,
|
||||
lastUpdate: this.lastUpdate
|
||||
}
|
||||
|
@ -55,6 +59,7 @@ class Library {
|
|||
return newFolder
|
||||
})
|
||||
}
|
||||
this.icon = data.icon || 'database'
|
||||
this.createdAt = Date.now()
|
||||
this.lastUpdate = Date.now()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue