mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-12-21 03:09:37 +00:00
Add Subtitle and Narrarator fields, add server settings object, scanner to parse out subtitles
This commit is contained in:
parent
e566c6c9d5
commit
af05e78cdf
20 changed files with 213 additions and 31 deletions
|
|
@ -41,6 +41,8 @@ class ApiController {
|
|||
this.router.patch('/user/password', this.userChangePassword.bind(this))
|
||||
this.router.patch('/user/settings', this.userUpdateSettings.bind(this))
|
||||
|
||||
this.router.patch('/serverSettings', this.updateServerSettings.bind(this))
|
||||
|
||||
this.router.post('/authorize', this.authorize.bind(this))
|
||||
|
||||
this.router.get('/genres', this.getGenres.bind(this))
|
||||
|
|
@ -308,6 +310,21 @@ class ApiController {
|
|||
})
|
||||
}
|
||||
|
||||
async updateServerSettings(req, res) {
|
||||
var settingsUpdate = req.body
|
||||
if (!settingsUpdate || !isObject(settingsUpdate)) {
|
||||
return res.sendStatus(500)
|
||||
}
|
||||
var madeUpdates = this.db.serverSettings.update(settingsUpdate)
|
||||
if (madeUpdates) {
|
||||
await this.db.updateEntity('settings', this.db.serverSettings)
|
||||
}
|
||||
return res.json({
|
||||
success: true,
|
||||
serverSettings: this.db.serverSettings
|
||||
})
|
||||
}
|
||||
|
||||
async download(req, res) {
|
||||
var downloadId = req.params.id
|
||||
Logger.info('Download Request', downloadId)
|
||||
|
|
|
|||
34
server/Db.js
34
server/Db.js
|
|
@ -4,6 +4,7 @@ const jwt = require('jsonwebtoken')
|
|||
const Logger = require('./Logger')
|
||||
const Audiobook = require('./objects/Audiobook')
|
||||
const User = require('./objects/User')
|
||||
const ServerSettings = require('./objects/ServerSettings')
|
||||
|
||||
class Db {
|
||||
constructor(CONFIG_PATH) {
|
||||
|
|
@ -19,6 +20,8 @@ class Db {
|
|||
this.users = []
|
||||
this.audiobooks = []
|
||||
this.settings = []
|
||||
|
||||
this.serverSettings = null
|
||||
}
|
||||
|
||||
getEntityDb(entityName) {
|
||||
|
|
@ -39,15 +42,6 @@ class Db {
|
|||
return 'settings'
|
||||
}
|
||||
|
||||
getDefaultSettings() {
|
||||
return {
|
||||
config: {
|
||||
version: 1,
|
||||
cardSize: 'md'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getDefaultUser(token) {
|
||||
return new User({
|
||||
id: 'root',
|
||||
|
|
@ -71,6 +65,11 @@ class Db {
|
|||
Logger.debug('Generated default token', token)
|
||||
await this.insertUser(this.getDefaultUser(token))
|
||||
}
|
||||
|
||||
if (!this.serverSettings) {
|
||||
this.serverSettings = new ServerSettings()
|
||||
await this.insertSettings(this.serverSettings)
|
||||
}
|
||||
}
|
||||
|
||||
async load() {
|
||||
|
|
@ -83,11 +82,26 @@ class Db {
|
|||
Logger.info(`Users Loaded ${this.users.length}`)
|
||||
})
|
||||
var p3 = this.settingsDb.select(() => true).then((results) => {
|
||||
this.settings = results
|
||||
if (results.data && results.data.length) {
|
||||
this.settings = results.data
|
||||
var serverSettings = this.settings.find(s => s.id === 'server-settings')
|
||||
if (serverSettings) {
|
||||
this.serverSettings = new ServerSettings(serverSettings)
|
||||
}
|
||||
}
|
||||
})
|
||||
await Promise.all([p1, p2, p3])
|
||||
}
|
||||
|
||||
insertSettings(settings) {
|
||||
return this.settingsDb.insert(settings).then((results) => {
|
||||
Logger.debug(`[DB] Inserted ${results.inserted} settings`)
|
||||
this.settings = this.settings.concat(settings)
|
||||
}).catch((error) => {
|
||||
Logger.error(`[DB] Insert settings Failed ${error}`)
|
||||
})
|
||||
}
|
||||
|
||||
insertAudiobook(audiobook) {
|
||||
return this.insertAudiobooks([audiobook])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ class Scanner {
|
|||
}
|
||||
|
||||
const scanStart = Date.now()
|
||||
var audiobookDataFound = await getAllAudiobookFiles(this.AudiobookPath)
|
||||
var audiobookDataFound = await getAllAudiobookFiles(this.AudiobookPath, this.db.serverSettings)
|
||||
|
||||
// Set ino for each ab data as a string
|
||||
audiobookDataFound = await this.setAudiobookDataInos(audiobookDataFound)
|
||||
|
|
|
|||
|
|
@ -50,8 +50,8 @@ class Server {
|
|||
get audiobooks() {
|
||||
return this.db.audiobooks
|
||||
}
|
||||
get settings() {
|
||||
return this.db.settings
|
||||
get serverSettings() {
|
||||
return this.db.serverSettings
|
||||
}
|
||||
|
||||
emitter(ev, data) {
|
||||
|
|
@ -239,7 +239,7 @@ class Server {
|
|||
}
|
||||
|
||||
const initialPayload = {
|
||||
settings: this.settings,
|
||||
serverSettings: this.serverSettings.toJSON(),
|
||||
isScanning: this.isScanning,
|
||||
isInitialized: this.isInitialized,
|
||||
audiobookPath: this.AudiobookPath,
|
||||
|
|
|
|||
|
|
@ -6,9 +6,11 @@ class Book {
|
|||
constructor(book = null) {
|
||||
this.olid = null
|
||||
this.title = null
|
||||
this.subtitle = null
|
||||
this.author = null
|
||||
this.authorFL = null
|
||||
this.authorLF = null
|
||||
this.narrarator = null
|
||||
this.series = null
|
||||
this.volumeNumber = null
|
||||
this.publishYear = null
|
||||
|
|
@ -23,15 +25,19 @@ class Book {
|
|||
}
|
||||
|
||||
get _title() { return this.title || '' }
|
||||
get _subtitle() { return this.subtitle || '' }
|
||||
get _narrarator() { return this.narrarator || '' }
|
||||
get _author() { return this.author || '' }
|
||||
get _series() { return this.series || '' }
|
||||
|
||||
construct(book) {
|
||||
this.olid = book.olid
|
||||
this.title = book.title
|
||||
this.subtitle = book.subtitle || null
|
||||
this.author = book.author
|
||||
this.authorFL = book.authorFL || null
|
||||
this.authorLF = book.authorLF || null
|
||||
this.narrarator = book.narrarator || null
|
||||
this.series = book.series
|
||||
this.volumeNumber = book.volumeNumber || null
|
||||
this.publishYear = book.publishYear
|
||||
|
|
@ -45,9 +51,11 @@ class Book {
|
|||
return {
|
||||
olid: this.olid,
|
||||
title: this.title,
|
||||
subtitle: this.subtitle,
|
||||
author: this.author,
|
||||
authorFL: this.authorFL,
|
||||
authorLF: this.authorLF,
|
||||
narrarator: this.narrarator,
|
||||
series: this.series,
|
||||
volumeNumber: this.volumeNumber,
|
||||
publishYear: this.publishYear,
|
||||
|
|
@ -80,7 +88,9 @@ class Book {
|
|||
setData(data) {
|
||||
this.olid = data.olid || null
|
||||
this.title = data.title || null
|
||||
this.subtitle = data.subtitle || null
|
||||
this.author = data.author || null
|
||||
this.narrarator = data.narrarator || null
|
||||
this.series = data.series || null
|
||||
this.volumeNumber = data.volumeNumber || null
|
||||
this.publishYear = data.publishYear || null
|
||||
|
|
@ -151,7 +161,7 @@ class Book {
|
|||
}
|
||||
|
||||
isSearchMatch(search) {
|
||||
return this._title.toLowerCase().includes(search) || this._author.toLowerCase().includes(search) || this._series.toLowerCase().includes(search)
|
||||
return this._title.toLowerCase().includes(search) || this._subtitle.toLowerCase().includes(search) || this._author.toLowerCase().includes(search) || this._series.toLowerCase().includes(search)
|
||||
}
|
||||
}
|
||||
module.exports = Book
|
||||
39
server/objects/ServerSettings.js
Normal file
39
server/objects/ServerSettings.js
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
class ServerSettings {
|
||||
constructor(settings) {
|
||||
this.id = 'server-settings'
|
||||
this.autoTagNew = false
|
||||
this.newTagExpireDays = 15
|
||||
this.scannerParseSubtitle = false
|
||||
|
||||
if (settings) {
|
||||
this.construct(settings)
|
||||
}
|
||||
}
|
||||
|
||||
construct(settings) {
|
||||
this.autoTagNew = settings.autoTagNew
|
||||
this.newTagExpireDays = settings.newTagExpireDays
|
||||
this.scannerParseSubtitle = settings.scannerParseSubtitle
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
id: this.id,
|
||||
autoTagNew: this.autoTagNew,
|
||||
newTagExpireDays: this.newTagExpireDays,
|
||||
scannerParseSubtitle: this.scannerParseSubtitle
|
||||
}
|
||||
}
|
||||
|
||||
update(payload) {
|
||||
var hasUpdates = false
|
||||
for (const key in payload) {
|
||||
if (this[key] !== payload[key]) {
|
||||
this[key] = payload[key]
|
||||
hasUpdates = true
|
||||
}
|
||||
}
|
||||
return hasUpdates
|
||||
}
|
||||
}
|
||||
module.exports = ServerSettings
|
||||
|
|
@ -30,7 +30,9 @@ function getFileType(ext) {
|
|||
return 'unknown'
|
||||
}
|
||||
|
||||
async function getAllAudiobookFiles(abRootPath) {
|
||||
async function getAllAudiobookFiles(abRootPath, serverSettings = {}) {
|
||||
var parseSubtitle = !!serverSettings.scannerParseSubtitle
|
||||
|
||||
var paths = await getPaths(abRootPath)
|
||||
var audiobooks = {}
|
||||
|
||||
|
|
@ -53,6 +55,7 @@ async function getAllAudiobookFiles(abRootPath) {
|
|||
var title = splitDir.shift()
|
||||
|
||||
var publishYear = null
|
||||
var subtitle = null
|
||||
|
||||
// If Title is of format 1999 - Title, then use 1999 as publish year
|
||||
var publishYearMatch = title.match(/^([0-9]{4}) - (.+)/)
|
||||
|
|
@ -63,10 +66,17 @@ async function getAllAudiobookFiles(abRootPath) {
|
|||
}
|
||||
}
|
||||
|
||||
if (parseSubtitle && title.includes(' - ')) {
|
||||
var splitOnSubtitle = title.split(' - ')
|
||||
title = splitOnSubtitle.shift()
|
||||
subtitle = splitOnSubtitle.join(' - ')
|
||||
}
|
||||
|
||||
if (!audiobooks[path]) {
|
||||
audiobooks[path] = {
|
||||
author: author,
|
||||
title: title,
|
||||
author,
|
||||
title,
|
||||
subtitle,
|
||||
series: cleanString(series),
|
||||
publishYear: publishYear,
|
||||
path: path,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue