mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-07-27 11:41:36 +00:00
merge upstream
This commit is contained in:
commit
61bf30e08a
89 changed files with 2963 additions and 1805 deletions
|
|
@ -11,6 +11,9 @@ class AudioFile {
|
|||
this.ext = null
|
||||
this.path = null
|
||||
this.fullPath = null
|
||||
this.mtimeMs = null
|
||||
this.ctimeMs = null
|
||||
this.birthtimeMs = null
|
||||
this.addedAt = null
|
||||
|
||||
this.trackNumFromMeta = null
|
||||
|
|
@ -51,6 +54,9 @@ class AudioFile {
|
|||
ext: this.ext,
|
||||
path: this.path,
|
||||
fullPath: this.fullPath,
|
||||
mtimeMs: this.mtimeMs,
|
||||
ctimeMs: this.ctimeMs,
|
||||
birthtimeMs: this.birthtimeMs,
|
||||
addedAt: this.addedAt,
|
||||
trackNumFromMeta: this.trackNumFromMeta,
|
||||
discNumFromMeta: this.discNumFromMeta,
|
||||
|
|
@ -82,6 +88,9 @@ class AudioFile {
|
|||
this.ext = data.ext
|
||||
this.path = data.path
|
||||
this.fullPath = data.fullPath
|
||||
this.mtimeMs = data.mtimeMs || 0
|
||||
this.ctimeMs = data.ctimeMs || 0
|
||||
this.birthtimeMs = data.birthtimeMs || 0
|
||||
this.addedAt = data.addedAt
|
||||
this.manuallyVerified = !!data.manuallyVerified
|
||||
this.invalid = !!data.invalid
|
||||
|
|
@ -124,6 +133,9 @@ class AudioFile {
|
|||
this.ext = fileData.ext
|
||||
this.path = fileData.path
|
||||
this.fullPath = fileData.fullPath
|
||||
this.mtimeMs = fileData.mtimeMs || 0
|
||||
this.ctimeMs = fileData.ctimeMs || 0
|
||||
this.birthtimeMs = fileData.birthtimeMs || 0
|
||||
this.addedAt = Date.now()
|
||||
|
||||
this.trackNumFromMeta = fileData.trackNumFromMeta
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
const Path = require('path')
|
||||
const fs = require('fs-extra')
|
||||
const { bytesPretty, readTextFile } = require('../utils/fileUtils')
|
||||
const { comparePaths, getIno, getId, elapsedPretty } = require('../utils/index')
|
||||
const { bytesPretty, readTextFile, getIno } = require('../utils/fileUtils')
|
||||
const { comparePaths, getId, elapsedPretty } = require('../utils/index')
|
||||
const { parseOpfMetadataXML } = require('../utils/parseOpfMetadata')
|
||||
const { extractCoverArt } = require('../utils/ffmpegHelpers')
|
||||
const nfoGenerator = require('../utils/nfoGenerator')
|
||||
const abmetadataGenerator = require('../utils/abmetadataGenerator')
|
||||
const Logger = require('../Logger')
|
||||
const Book = require('./Book')
|
||||
const AudioTrack = require('./AudioTrack')
|
||||
|
|
@ -21,6 +22,9 @@ class Audiobook {
|
|||
|
||||
this.path = null
|
||||
this.fullPath = null
|
||||
this.mtimeMs = null
|
||||
this.ctimeMs = null
|
||||
this.birthtimeMs = null
|
||||
this.addedAt = null
|
||||
this.lastUpdate = null
|
||||
this.lastScan = null
|
||||
|
|
@ -44,6 +48,9 @@ class Audiobook {
|
|||
if (audiobook) {
|
||||
this.construct(audiobook)
|
||||
}
|
||||
|
||||
// Temp flags
|
||||
this.isSavingMetadata = false
|
||||
}
|
||||
|
||||
construct(audiobook) {
|
||||
|
|
@ -53,6 +60,9 @@ class Audiobook {
|
|||
this.folderId = audiobook.folderId || 'audiobooks'
|
||||
this.path = audiobook.path
|
||||
this.fullPath = audiobook.fullPath
|
||||
this.mtimeMs = audiobook.mtimeMs || 0
|
||||
this.ctimeMs = audiobook.ctimeMs || 0
|
||||
this.birthtimeMs = audiobook.birthtimeMs || 0
|
||||
this.addedAt = audiobook.addedAt
|
||||
this.lastUpdate = audiobook.lastUpdate || this.addedAt
|
||||
this.lastScan = audiobook.lastScan || null
|
||||
|
|
@ -173,11 +183,11 @@ class Audiobook {
|
|||
ino: this.ino,
|
||||
libraryId: this.libraryId,
|
||||
folderId: this.folderId,
|
||||
title: this.title,
|
||||
author: this.author,
|
||||
cover: this.cover,
|
||||
path: this.path,
|
||||
fullPath: this.fullPath,
|
||||
mtimeMs: this.mtimeMs,
|
||||
ctimeMs: this.ctimeMs,
|
||||
birthtimeMs: this.birthtimeMs,
|
||||
addedAt: this.addedAt,
|
||||
lastUpdate: this.lastUpdate,
|
||||
lastScan: this.lastScan,
|
||||
|
|
@ -204,6 +214,9 @@ class Audiobook {
|
|||
tags: this.tags,
|
||||
path: this.path,
|
||||
fullPath: this.fullPath,
|
||||
mtimeMs: this.mtimeMs,
|
||||
ctimeMs: this.ctimeMs,
|
||||
birthtimeMs: this.birthtimeMs,
|
||||
addedAt: this.addedAt,
|
||||
lastUpdate: this.lastUpdate,
|
||||
duration: this.duration,
|
||||
|
|
@ -227,6 +240,9 @@ class Audiobook {
|
|||
folderId: this.folderId,
|
||||
path: this.path,
|
||||
fullPath: this.fullPath,
|
||||
mtimeMs: this.mtimeMs,
|
||||
ctimeMs: this.ctimeMs,
|
||||
birthtimeMs: this.birthtimeMs,
|
||||
addedAt: this.addedAt,
|
||||
lastUpdate: this.lastUpdate,
|
||||
duration: this.duration,
|
||||
|
|
@ -334,6 +350,9 @@ class Audiobook {
|
|||
|
||||
this.path = data.path
|
||||
this.fullPath = data.fullPath
|
||||
this.mtimeMs = data.mtimeMs || 0
|
||||
this.ctimeMs = data.ctimeMs || 0
|
||||
this.birthtimeMs = data.birthtimeMs || 0
|
||||
this.addedAt = Date.now()
|
||||
this.lastUpdate = this.addedAt
|
||||
|
||||
|
|
@ -425,13 +444,8 @@ class Audiobook {
|
|||
hasUpdates = true
|
||||
}
|
||||
|
||||
if (payload.book) {
|
||||
if (!this.book) {
|
||||
this.setBook(payload.book)
|
||||
hasUpdates = true
|
||||
} else if (this.book.update(payload.book)) {
|
||||
hasUpdates = true
|
||||
}
|
||||
if (payload.book && this.book.update(payload.book)) {
|
||||
hasUpdates = true
|
||||
}
|
||||
|
||||
if (hasUpdates) {
|
||||
|
|
@ -526,7 +540,7 @@ class Audiobook {
|
|||
}
|
||||
|
||||
// On scan check other files found with other files saved
|
||||
async syncOtherFiles(newOtherFiles, metadataPath, opfMetadataOverrideDetails, forceRescan = false) {
|
||||
async syncOtherFiles(newOtherFiles, opfMetadataOverrideDetails) {
|
||||
var hasUpdates = false
|
||||
|
||||
var currOtherFileNum = this.otherFiles.length
|
||||
|
|
@ -535,6 +549,8 @@ class Audiobook {
|
|||
var alreadyHasDescTxt = otherFilenamesAlreadyInBook.includes('desc.txt')
|
||||
var alreadyHasReaderTxt = otherFilenamesAlreadyInBook.includes('reader.txt')
|
||||
|
||||
var existingAbMetadata = this.otherFiles.find(file => file.filename === 'metadata.abs')
|
||||
|
||||
// Filter out other files no longer in directory
|
||||
var newOtherFilePaths = newOtherFiles.map(f => f.path)
|
||||
this.otherFiles = this.otherFiles.filter(f => newOtherFilePaths.includes(f.path))
|
||||
|
|
@ -543,9 +559,9 @@ class Audiobook {
|
|||
hasUpdates = true
|
||||
}
|
||||
|
||||
// If desc.txt is new or forcing rescan then read it and update description (will overwrite)
|
||||
// If desc.txt is new then read it and update description (will overwrite)
|
||||
var descriptionTxt = newOtherFiles.find(file => file.filename === 'desc.txt')
|
||||
if (descriptionTxt && (!alreadyHasDescTxt || forceRescan)) {
|
||||
if (descriptionTxt && !alreadyHasDescTxt) {
|
||||
var newDescription = await readTextFile(descriptionTxt.fullPath)
|
||||
if (newDescription) {
|
||||
Logger.debug(`[Audiobook] Sync Other File desc.txt: ${newDescription}`)
|
||||
|
|
@ -553,9 +569,9 @@ class Audiobook {
|
|||
hasUpdates = true
|
||||
}
|
||||
}
|
||||
// If reader.txt is new or forcing rescan then read it and update narrator (will overwrite)
|
||||
// If reader.txt is new then read it and update narrator (will overwrite)
|
||||
var readerTxt = newOtherFiles.find(file => file.filename === 'reader.txt')
|
||||
if (readerTxt && (!alreadyHasReaderTxt || forceRescan)) {
|
||||
if (readerTxt && !alreadyHasReaderTxt) {
|
||||
var newReader = await readTextFile(readerTxt.fullPath)
|
||||
if (newReader) {
|
||||
Logger.debug(`[Audiobook] Sync Other File reader.txt: ${newReader}`)
|
||||
|
|
@ -564,7 +580,28 @@ class Audiobook {
|
|||
}
|
||||
}
|
||||
|
||||
// If OPF file and was not already there
|
||||
|
||||
// If metadata.abs is new OR modified then read it and set all defined keys (will overwrite)
|
||||
var metadataAbs = newOtherFiles.find(file => file.filename === 'metadata.abs')
|
||||
var shouldUpdateAbs = !!metadataAbs && (metadataAbs.modified || !existingAbMetadata)
|
||||
if (metadataAbs && metadataAbs.modified) {
|
||||
Logger.debug(`[Audiobook] metadata.abs file was modified for "${this.title}"`)
|
||||
}
|
||||
|
||||
if (shouldUpdateAbs) {
|
||||
var abmetadataText = await readTextFile(metadataAbs.fullPath)
|
||||
if (abmetadataText) {
|
||||
var metadataUpdateObject = abmetadataGenerator.parse(abmetadataText)
|
||||
if (metadataUpdateObject && metadataUpdateObject.book) {
|
||||
if (this.update(metadataUpdateObject)) {
|
||||
Logger.debug(`[Audiobook] Some details were updated from metadata.abs for "${this.title}"`, metadataUpdateObject)
|
||||
hasUpdates = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If OPF file and was not already there OR prefer opf metadata
|
||||
var metadataOpf = newOtherFiles.find(file => file.ext === '.opf' || file.filename === 'metadata.xml')
|
||||
if (metadataOpf && (!otherFilenamesAlreadyInBook.includes(metadataOpf.filename) || opfMetadataOverrideDetails)) {
|
||||
var xmlText = await readTextFile(metadataOpf.fullPath)
|
||||
|
|
@ -643,7 +680,7 @@ class Audiobook {
|
|||
if (bookCoverPath && bookCoverPath.startsWith('/metadata')) {
|
||||
// Fixing old cover paths
|
||||
if (!this.book.coverFullPath) {
|
||||
this.book.coverFullPath = Path.join(metadataPath, this.book.cover.substr('/metadata/'.length)).replace(/\\/g, '/').replace(/\/\//g, '/')
|
||||
this.book.coverFullPath = Path.join(global.MetadataPath, this.book.cover.substr('/metadata/'.length)).replace(/\\/g, '/').replace(/\/\//g, '/')
|
||||
Logger.debug(`[Audiobook] Metadata cover full path set "${this.book.coverFullPath}" for "${this.title}"`)
|
||||
hasUpdates = true
|
||||
}
|
||||
|
|
@ -800,9 +837,10 @@ class Audiobook {
|
|||
return false
|
||||
}
|
||||
|
||||
// Look for desc.txt and reader.txt and update details if found
|
||||
// Look for desc.txt, reader.txt, metadata.abs and opf file then update details if found
|
||||
async saveDataFromTextFiles(opfMetadataOverrideDetails) {
|
||||
var bookUpdatePayload = {}
|
||||
|
||||
var descriptionText = await this.fetchTextFromTextFile('desc.txt')
|
||||
if (descriptionText) {
|
||||
Logger.debug(`[Audiobook] "${this.title}" found desc.txt updating description with "${descriptionText.slice(0, 20)}..."`)
|
||||
|
|
@ -814,6 +852,22 @@ class Audiobook {
|
|||
bookUpdatePayload.narrator = readerText
|
||||
}
|
||||
|
||||
// abmetadata will always overwrite
|
||||
var abmetadataText = await this.fetchTextFromTextFile('metadata.abs')
|
||||
if (abmetadataText) {
|
||||
var metadataUpdateObject = abmetadataGenerator.parse(abmetadataText)
|
||||
if (metadataUpdateObject && metadataUpdateObject.book) {
|
||||
Logger.debug(`[Audiobook] "${this.title}" found metadata.abs file`)
|
||||
for (const key in metadataUpdateObject.book) {
|
||||
var value = metadataUpdateObject.book[key]
|
||||
if (key && value !== undefined) {
|
||||
bookUpdatePayload[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Opf only overwrites if detail is empty
|
||||
var metadataOpf = this.otherFiles.find(file => file.isOPFFile || file.filename === 'metadata.xml')
|
||||
if (metadataOpf) {
|
||||
var xmlText = await readTextFile(metadataOpf.fullPath)
|
||||
|
|
@ -873,12 +927,6 @@ class Audiobook {
|
|||
}
|
||||
}
|
||||
|
||||
if (existingFile.filename !== fileFound.filename) {
|
||||
existingFile.filename = fileFound.filename
|
||||
existingFile.ext = fileFound.ext
|
||||
hasUpdated = true
|
||||
}
|
||||
|
||||
if (existingFile.path !== fileFound.path) {
|
||||
existingFile.path = fileFound.path
|
||||
existingFile.fullPath = fileFound.fullPath
|
||||
|
|
@ -888,6 +936,20 @@ class Audiobook {
|
|||
hasUpdated = true
|
||||
}
|
||||
|
||||
var keysToCheck = ['filename', 'ext', 'mtimeMs', 'ctimeMs', 'birthtimeMs', 'size']
|
||||
keysToCheck.forEach((key) => {
|
||||
if (existingFile[key] !== fileFound[key]) {
|
||||
|
||||
// Add modified flag on file data object if exists and was changed
|
||||
if (key === 'mtimeMs' && existingFile[key]) {
|
||||
fileFound.modified = true
|
||||
}
|
||||
|
||||
existingFile[key] = fileFound[key]
|
||||
hasUpdated = true
|
||||
}
|
||||
})
|
||||
|
||||
if (!isAudioFile && existingFile.filetype !== fileFound.filetype) {
|
||||
existingFile.filetype = fileFound.filetype
|
||||
hasUpdated = true
|
||||
|
|
@ -927,6 +989,14 @@ class Audiobook {
|
|||
hasUpdated = true
|
||||
}
|
||||
|
||||
var keysToCheck = ['mtimeMs', 'ctimeMs', 'birthtimeMs']
|
||||
keysToCheck.forEach((key) => {
|
||||
if (dataFound[key] != this[key]) {
|
||||
this[key] = dataFound[key] || 0
|
||||
hasUpdated = true
|
||||
}
|
||||
})
|
||||
|
||||
var newAudioFileData = []
|
||||
var newOtherFileData = []
|
||||
var existingAudioFileData = []
|
||||
|
|
@ -1017,14 +1087,14 @@ class Audiobook {
|
|||
}
|
||||
|
||||
// Temp fix for cover is set but coverFullPath is not set
|
||||
fixFullCoverPath(metadataPath) {
|
||||
fixFullCoverPath() {
|
||||
if (!this.book.cover) return
|
||||
var bookCoverPath = this.book.cover.replace(/\\/g, '/')
|
||||
var newFullCoverPath = null
|
||||
if (bookCoverPath.startsWith('/s/book/')) {
|
||||
newFullCoverPath = Path.join(this.fullPath, bookCoverPath.substr(`/s/book/${this.id}`.length)).replace(/\/\//g, '/')
|
||||
} else if (bookCoverPath.startsWith('/metadata/')) {
|
||||
newFullCoverPath = Path.join(metadataPath, bookCoverPath.substr('/metadata/'.length)).replace(/\/\//g, '/')
|
||||
newFullCoverPath = Path.join(global.MetadataPath, bookCoverPath.substr('/metadata/'.length)).replace(/\/\//g, '/')
|
||||
}
|
||||
if (newFullCoverPath) {
|
||||
Logger.debug(`[Audiobook] "${this.title}" fixing full cover path "${this.book.cover}" => "${newFullCoverPath}"`)
|
||||
|
|
@ -1033,5 +1103,26 @@ class Audiobook {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
async saveAbMetadata() {
|
||||
if (this.isSavingMetadata) return
|
||||
this.isSavingMetadata = true
|
||||
|
||||
var metadataPath = Path.join(global.MetadataPath, 'books', this.id)
|
||||
if (global.ServerSettings.storeMetadataWithBook) {
|
||||
metadataPath = this.fullPath
|
||||
} else {
|
||||
// Make sure metadata book dir exists
|
||||
await fs.ensureDir(metadataPath)
|
||||
}
|
||||
metadataPath = Path.join(metadataPath, 'metadata.abs')
|
||||
|
||||
return abmetadataGenerator.generate(this, metadataPath).then((success) => {
|
||||
this.isSavingMetadata = false
|
||||
if (!success) Logger.error(`[Audiobook] Failed saving abmetadata to "${metadataPath}"`)
|
||||
else Logger.debug(`[Audiobook] Success saving abmetadata to "${metadataPath}"`)
|
||||
return success
|
||||
})
|
||||
}
|
||||
}
|
||||
module.exports = Audiobook
|
||||
|
|
@ -6,6 +6,11 @@ class AudiobookFile {
|
|||
this.ext = null
|
||||
this.path = null
|
||||
this.fullPath = null
|
||||
this.size = null
|
||||
this.mtimeMs = null
|
||||
this.ctimeMs = null
|
||||
this.birthtimeMs = null
|
||||
|
||||
this.addedAt = null
|
||||
|
||||
if (data) {
|
||||
|
|
@ -25,6 +30,10 @@ class AudiobookFile {
|
|||
ext: this.ext,
|
||||
path: this.path,
|
||||
fullPath: this.fullPath,
|
||||
size: this.size,
|
||||
mtimeMs: this.mtimeMs,
|
||||
ctimeMs: this.ctimeMs,
|
||||
birthtimeMs: this.birthtimeMs,
|
||||
addedAt: this.addedAt
|
||||
}
|
||||
}
|
||||
|
|
@ -36,6 +45,10 @@ class AudiobookFile {
|
|||
this.ext = data.ext
|
||||
this.path = data.path
|
||||
this.fullPath = data.fullPath
|
||||
this.size = data.size || 0
|
||||
this.mtimeMs = data.mtimeMs || 0
|
||||
this.ctimeMs = data.ctimeMs || 0
|
||||
this.birthtimeMs = data.birthtimeMs || 0
|
||||
this.addedAt = data.addedAt
|
||||
}
|
||||
|
||||
|
|
@ -46,6 +59,10 @@ class AudiobookFile {
|
|||
this.ext = data.ext
|
||||
this.path = data.path
|
||||
this.fullPath = data.fullPath
|
||||
this.size = data.size || 0
|
||||
this.mtimeMs = data.mtimeMs || 0
|
||||
this.ctimeMs = data.ctimeMs || 0
|
||||
this.birthtimeMs = data.birthtimeMs || 0
|
||||
this.addedAt = Date.now()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,20 @@ class Book {
|
|||
get _asin() { return this.asin || '' }
|
||||
get genresCommaSeparated() { return this._genres.join(', ') }
|
||||
|
||||
get titleIgnorePrefix() {
|
||||
if (this._title.toLowerCase().startsWith('the ')) {
|
||||
return this._title.substr(4) + ', The'
|
||||
}
|
||||
return this._title
|
||||
}
|
||||
|
||||
get seriesIgnorePrefix() {
|
||||
if (this._series.toLowerCase().startsWith('the ')) {
|
||||
return this._series.substr(4) + ', The'
|
||||
}
|
||||
return this._series
|
||||
}
|
||||
|
||||
get shouldSearchForCover() {
|
||||
if (this.cover) return false
|
||||
if (this.authorFL !== this.lastCoverSearchAuthor || this.title !== this.lastCoverSearchTitle || !this.lastCoverSearch) return true
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ class Library {
|
|||
this.folders = []
|
||||
this.displayOrder = 1
|
||||
this.icon = 'database'
|
||||
this.provider = 'google'
|
||||
this.disableWatcher = false
|
||||
|
||||
this.lastScan = 0
|
||||
|
||||
|
|
@ -29,6 +31,8 @@ class Library {
|
|||
this.folders = (library.folders || []).map(f => new Folder(f))
|
||||
this.displayOrder = library.displayOrder || 1
|
||||
this.icon = library.icon || 'database'
|
||||
this.provider = library.provider || 'google'
|
||||
this.disableWatcher = !!library.disableWatcher
|
||||
|
||||
this.createdAt = library.createdAt
|
||||
this.lastUpdate = library.lastUpdate
|
||||
|
|
@ -41,6 +45,8 @@ class Library {
|
|||
folders: (this.folders || []).map(f => f.toJSON()),
|
||||
displayOrder: this.displayOrder,
|
||||
icon: this.icon,
|
||||
provider: this.provider,
|
||||
disableWatcher: this.disableWatcher,
|
||||
createdAt: this.createdAt,
|
||||
lastUpdate: this.lastUpdate
|
||||
}
|
||||
|
|
@ -65,6 +71,7 @@ class Library {
|
|||
}
|
||||
this.displayOrder = data.displayOrder || 1
|
||||
this.icon = data.icon || 'database'
|
||||
this.disableWatcher = !!data.disableWatcher
|
||||
this.createdAt = Date.now()
|
||||
this.lastUpdate = Date.now()
|
||||
}
|
||||
|
|
@ -75,6 +82,14 @@ class Library {
|
|||
this.name = payload.name
|
||||
hasUpdates = true
|
||||
}
|
||||
if (payload.provider && payload.provider !== this.provider) {
|
||||
this.provider = payload.provider
|
||||
hasUpdates = true
|
||||
}
|
||||
if (payload.disableWatcher !== this.disableWatcher) {
|
||||
this.disableWatcher = !!payload.disableWatcher
|
||||
hasUpdates = true
|
||||
}
|
||||
if (!isNaN(payload.displayOrder) && payload.displayOrder !== this.displayOrder) {
|
||||
this.displayOrder = Number(payload.displayOrder)
|
||||
hasUpdates = true
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
const { CoverDestination, BookCoverAspectRatio, BookshelfView } = require('../utils/constants')
|
||||
const { BookCoverAspectRatio, BookshelfView } = require('../utils/constants')
|
||||
const Logger = require('../Logger')
|
||||
|
||||
class ServerSettings {
|
||||
|
|
@ -15,10 +15,11 @@ class ServerSettings {
|
|||
this.scannerCoverProvider = 'google'
|
||||
this.scannerPreferAudioMetadata = false
|
||||
this.scannerPreferOpfMetadata = false
|
||||
this.scannerDisableWatcher = false
|
||||
|
||||
// Metadata
|
||||
this.coverDestination = CoverDestination.METADATA
|
||||
this.saveMetadataFile = false
|
||||
this.storeCoverWithBook = false
|
||||
this.storeMetadataWithBook = false
|
||||
|
||||
// Security/Rate limits
|
||||
this.rateLimitLoginRequests = 10
|
||||
|
|
@ -38,6 +39,8 @@ class ServerSettings {
|
|||
this.coverAspectRatio = BookCoverAspectRatio.SQUARE
|
||||
this.bookshelfView = BookshelfView.STANDARD
|
||||
|
||||
this.sortingIgnorePrefix = false
|
||||
this.chromecastEnabled = false
|
||||
this.logLevel = Logger.logLevel
|
||||
this.version = null
|
||||
|
||||
|
|
@ -54,9 +57,14 @@ class ServerSettings {
|
|||
this.scannerParseSubtitle = settings.scannerParseSubtitle
|
||||
this.scannerPreferAudioMetadata = !!settings.scannerPreferAudioMetadata
|
||||
this.scannerPreferOpfMetadata = !!settings.scannerPreferOpfMetadata
|
||||
this.scannerDisableWatcher = !!settings.scannerDisableWatcher
|
||||
|
||||
this.storeCoverWithBook = settings.storeCoverWithBook
|
||||
if (this.storeCoverWithBook == undefined) { // storeCoverWithBook added in 1.7.1 to replace coverDestination
|
||||
this.storeCoverWithBook = !!settings.coverDestination
|
||||
}
|
||||
this.storeMetadataWithBook = !!settings.storeCoverWithBook
|
||||
|
||||
this.coverDestination = settings.coverDestination || CoverDestination.METADATA
|
||||
this.saveMetadataFile = !!settings.saveMetadataFile
|
||||
this.rateLimitLoginRequests = !isNaN(settings.rateLimitLoginRequests) ? Number(settings.rateLimitLoginRequests) : 10
|
||||
this.rateLimitLoginWindow = !isNaN(settings.rateLimitLoginWindow) ? Number(settings.rateLimitLoginWindow) : 10 * 60 * 1000 // 10 Minutes
|
||||
|
||||
|
|
@ -70,6 +78,8 @@ class ServerSettings {
|
|||
this.coverAspectRatio = !isNaN(settings.coverAspectRatio) ? settings.coverAspectRatio : BookCoverAspectRatio.SQUARE
|
||||
this.bookshelfView = settings.bookshelfView || BookshelfView.STANDARD
|
||||
|
||||
this.sortingIgnorePrefix = !!settings.sortingIgnorePrefix
|
||||
this.chromecastEnabled = !!settings.chromecastEnabled
|
||||
this.logLevel = settings.logLevel || Logger.logLevel
|
||||
this.version = settings.version || null
|
||||
|
||||
|
|
@ -88,8 +98,9 @@ class ServerSettings {
|
|||
scannerParseSubtitle: this.scannerParseSubtitle,
|
||||
scannerPreferAudioMetadata: this.scannerPreferAudioMetadata,
|
||||
scannerPreferOpfMetadata: this.scannerPreferOpfMetadata,
|
||||
coverDestination: this.coverDestination,
|
||||
saveMetadataFile: !!this.saveMetadataFile,
|
||||
scannerDisableWatcher: this.scannerDisableWatcher,
|
||||
storeCoverWithBook: this.storeCoverWithBook,
|
||||
storeMetadataWithBook: this.storeMetadataWithBook,
|
||||
rateLimitLoginRequests: this.rateLimitLoginRequests,
|
||||
rateLimitLoginWindow: this.rateLimitLoginWindow,
|
||||
backupSchedule: this.backupSchedule,
|
||||
|
|
@ -99,6 +110,8 @@ class ServerSettings {
|
|||
loggerScannerLogsToKeep: this.loggerScannerLogsToKeep,
|
||||
coverAspectRatio: this.coverAspectRatio,
|
||||
bookshelfView: this.bookshelfView,
|
||||
sortingIgnorePrefix: this.sortingIgnorePrefix,
|
||||
chromecastEnabled: this.chromecastEnabled,
|
||||
logLevel: this.logLevel,
|
||||
version: this.version
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,11 +175,6 @@ class Stream extends EventEmitter {
|
|||
return false
|
||||
}
|
||||
|
||||
updateClientCurrentTime(currentTime) {
|
||||
Logger.debug('[Stream] Updated client current time', secondsToTimestamp(currentTime))
|
||||
this.clientCurrentTime = currentTime
|
||||
}
|
||||
|
||||
syncStream({ timeListened, currentTime }) {
|
||||
var syncLog = ''
|
||||
// Set user current time
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue