mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-07-27 03:31:46 +00:00
Merge branch 'master' into social
This commit is contained in:
commit
92c393d2b6
351 changed files with 53592 additions and 1765 deletions
|
|
@ -1,5 +1,5 @@
|
|||
const Path = require('path')
|
||||
const date = require('date-and-time')
|
||||
const date = require('../libs/dateAndTime')
|
||||
const version = require('../../package.json').version
|
||||
|
||||
class Backup {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
const Path = require('path')
|
||||
const date = require('date-and-time')
|
||||
const date = require('../libs/dateAndTime')
|
||||
const fs = require('../libs/fsExtra')
|
||||
const { readTextFile } = require('../utils/fileUtils')
|
||||
const Logger = require('../Logger')
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
const { AudioMimeType } = require('../utils/constants')
|
||||
const { getAudioMimeTypeFromExtname } = require('../utils/fileUtils')
|
||||
const DEFAULT_EXPIRATION = 1000 * 60 * 60 // 60 minutes
|
||||
const DEFAULT_TIMEOUT = 1000 * 60 * 30 // 30 minutes
|
||||
|
||||
class Download {
|
||||
constructor(download) {
|
||||
this.id = null
|
||||
|
|
@ -32,16 +35,7 @@ class Download {
|
|||
}
|
||||
|
||||
get mimeType() {
|
||||
if (this.ext === '.mp3' || this.ext === '.m4b' || this.ext === '.m4a') {
|
||||
return 'audio/mpeg'
|
||||
} else if (this.ext === '.mp4') {
|
||||
return 'audio/mp4'
|
||||
} else if (this.ext === '.ogg') {
|
||||
return 'audio/ogg'
|
||||
} else if (this.ext === '.aac' || this.ext === '.m4p') {
|
||||
return 'audio/aac'
|
||||
}
|
||||
return 'audio/mpeg'
|
||||
return getAudioMimeTypeFromExtname(this.ext) || AudioMimeType.MP3
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
const Path = require('path')
|
||||
const date = require('date-and-time')
|
||||
const date = require('../libs/dateAndTime')
|
||||
const { secondsToTimestamp } = require('../utils/index')
|
||||
|
||||
class FeedEpisode {
|
||||
|
|
@ -85,7 +85,8 @@ class FeedEpisode {
|
|||
|
||||
setFromAudiobookTrack(libraryItem, serverAddress, slug, audioTrack, meta) {
|
||||
// Example: <pubDate>Fri, 04 Feb 2015 00:00:00 GMT</pubDate>
|
||||
const audiobookPubDate = date.format(new Date(libraryItem.addedAt), 'ddd, DD MMM YYYY HH:mm:ss [GMT]')
|
||||
const timeOffset = isNaN(audioTrack.index) ? 0 : (Number(audioTrack.index) * 1000) // Offset pubdate to ensure correct order
|
||||
const audiobookPubDate = date.format(new Date(libraryItem.addedAt + timeOffset), 'ddd, DD MMM YYYY HH:mm:ss [GMT]')
|
||||
|
||||
const contentUrl = `/feed/${slug}/item/${audioTrack.index}/${audioTrack.metadata.filename}`
|
||||
const media = libraryItem.media
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
const date = require('date-and-time')
|
||||
const date = require('../libs/dateAndTime')
|
||||
const { getId } = require('../utils/index')
|
||||
const { PlayMethod } = require('../utils/constants')
|
||||
const BookMetadata = require('./metadata/BookMetadata')
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ class PodcastEpisodeDownload {
|
|||
this.url = null
|
||||
this.libraryItem = null
|
||||
|
||||
this.isAutoDownload = false
|
||||
this.isDownloading = false
|
||||
this.isFinished = false
|
||||
this.failed = false
|
||||
|
|
@ -46,11 +47,12 @@ class PodcastEpisodeDownload {
|
|||
return this.libraryItem ? this.libraryItem.id : null
|
||||
}
|
||||
|
||||
setData(podcastEpisode, libraryItem) {
|
||||
setData(podcastEpisode, libraryItem, isAutoDownload) {
|
||||
this.id = getId('epdl')
|
||||
this.podcastEpisode = podcastEpisode
|
||||
this.url = podcastEpisode.enclosure.url
|
||||
this.libraryItem = libraryItem
|
||||
this.isAutoDownload = isAutoDownload
|
||||
this.createdAt = Date.now()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
const Ffmpeg = require('fluent-ffmpeg')
|
||||
const Ffmpeg = require('../libs/fluentFfmpeg')
|
||||
const EventEmitter = require('events')
|
||||
const Path = require('path')
|
||||
const fs = require('../libs/fsExtra')
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
const Path = require('path')
|
||||
const { getId } = require('../../utils/index')
|
||||
const AudioFile = require('../files/AudioFile')
|
||||
const AudioTrack = require('../files/AudioTrack')
|
||||
|
|
@ -126,7 +127,7 @@ class PodcastEpisode {
|
|||
setDataFromAudioFile(audioFile, index) {
|
||||
this.id = getId('ep')
|
||||
this.audioFile = audioFile
|
||||
this.title = audioFile.metadata.filename
|
||||
this.title = Path.basename(audioFile.metadata.filename, Path.extname(audioFile.metadata.filename))
|
||||
this.index = index
|
||||
this.addedAt = Date.now()
|
||||
this.updatedAt = Date.now()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
const { isNullOrNaN } = require('../../utils/index')
|
||||
const { AudioMimeType } = require('../../utils/constants')
|
||||
const AudioMetaTags = require('../metadata/AudioMetaTags')
|
||||
const FileMetadata = require('../metadata/FileMetadata')
|
||||
|
|
@ -111,7 +110,11 @@ class AudioFile {
|
|||
}
|
||||
}
|
||||
|
||||
// New scanner creates AudioFile from AudioFileScanner
|
||||
get isValidTrack() {
|
||||
return !this.invalid && !this.exclude
|
||||
}
|
||||
|
||||
// New scanner creates AudioFile from MediaFileScanner
|
||||
setDataFromProbe(libraryFile, probeData) {
|
||||
this.ino = libraryFile.ino || null
|
||||
|
||||
|
|
@ -132,23 +135,6 @@ class AudioFile {
|
|||
this.embeddedCoverArt = probeData.embeddedCoverArt
|
||||
}
|
||||
|
||||
validateTrackIndex() {
|
||||
var numFromMeta = isNullOrNaN(this.trackNumFromMeta) ? null : Number(this.trackNumFromMeta)
|
||||
var numFromFilename = isNullOrNaN(this.trackNumFromFilename) ? null : Number(this.trackNumFromFilename)
|
||||
|
||||
if (numFromMeta !== null) return numFromMeta
|
||||
if (numFromFilename !== null) return numFromFilename
|
||||
|
||||
this.invalid = true
|
||||
this.error = 'Failed to get track number'
|
||||
return null
|
||||
}
|
||||
|
||||
setDuplicateTrackNumber(num) {
|
||||
this.invalid = true
|
||||
this.error = 'Duplicate track number "' + num + '"'
|
||||
}
|
||||
|
||||
syncChapters(updatedChapters) {
|
||||
if (this.chapters.length !== updatedChapters.length) {
|
||||
this.chapters = updatedChapters.map(ch => ({ ...ch }))
|
||||
|
|
|
|||
|
|
@ -276,13 +276,18 @@ class Book {
|
|||
if (opfMetadata.genres.length && (!this.metadata.genres.length || opfMetadataOverrideDetails)) {
|
||||
metadataUpdatePayload[key] = opfMetadata.genres
|
||||
}
|
||||
} else if (key === 'author') {
|
||||
if (opfMetadata.author && (!this.metadata.authors.length || opfMetadataOverrideDetails)) {
|
||||
metadataUpdatePayload.authors = this.metadata.parseAuthorsTag(opfMetadata.author)
|
||||
} else if (key === 'authors') {
|
||||
if (opfMetadata.authors && opfMetadata.authors.length && (!this.metadata.authors.length || opfMetadataOverrideDetails)) {
|
||||
metadataUpdatePayload.authors = opfMetadata.authors.map(authorName => {
|
||||
return {
|
||||
id: `new-${Math.floor(Math.random() * 1000000)}`,
|
||||
name: authorName
|
||||
}
|
||||
})
|
||||
}
|
||||
} else if (key === 'narrator') {
|
||||
if (opfMetadata.narrator && (!this.metadata.narrators.length || opfMetadataOverrideDetails)) {
|
||||
metadataUpdatePayload.narrators = this.metadata.parseNarratorsTag(opfMetadata.narrator)
|
||||
} else if (key === 'narrators') {
|
||||
if (opfMetadata.narrators && opfMetadata.narrators.length && (!this.metadata.narrators.length || opfMetadataOverrideDetails)) {
|
||||
metadataUpdatePayload.narrators = opfMetadata.narrators
|
||||
}
|
||||
} else if (key === 'series') {
|
||||
if (opfMetadata.series && (!this.metadata.series.length || opfMetadataOverrideDetails)) {
|
||||
|
|
@ -402,9 +407,12 @@ class Book {
|
|||
var includedAudioFiles = this.audioFiles.filter(af => !af.exclude)
|
||||
|
||||
// If overdrive media markers are present and preferred, use those instead
|
||||
if (preferOverdriveMediaMarker && overdriveMediaMarkersExist(includedAudioFiles)) {
|
||||
Logger.info('[Book] Overdrive Media Markers and preference found! Using these for chapter definitions')
|
||||
return this.chapters = parseOverdriveMediaMarkersAsChapters(includedAudioFiles)
|
||||
if (preferOverdriveMediaMarker) {
|
||||
var overdriveChapters = parseOverdriveMediaMarkersAsChapters(includedAudioFiles)
|
||||
if (overdriveChapters) {
|
||||
Logger.info('[Book] Overdrive Media Markers and preference found! Using these for chapter definitions')
|
||||
return this.chapters = overdriveChapters
|
||||
}
|
||||
}
|
||||
|
||||
if (includedAudioFiles.length === 1) {
|
||||
|
|
@ -420,10 +428,10 @@ class Book {
|
|||
// If audio file has chapters use chapters
|
||||
if (file.chapters && file.chapters.length) {
|
||||
file.chapters.forEach((chapter) => {
|
||||
if (chapter.start > this.duration) {
|
||||
if (currStartTime > this.duration) {
|
||||
Logger.warn(`[Book] Invalid chapter start time > duration`)
|
||||
} else {
|
||||
var chapterAlreadyExists = this.chapters.find(ch => ch.start === chapter.start)
|
||||
var chapterAlreadyExists = this.chapters.find(ch => ch.start === currStartTime)
|
||||
if (!chapterAlreadyExists) {
|
||||
var chapterDuration = chapter.end - chapter.start
|
||||
if (chapterDuration > 0) {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ class Podcast {
|
|||
this.episodes = []
|
||||
|
||||
this.autoDownloadEpisodes = false
|
||||
this.autoDownloadSchedule = null
|
||||
this.lastEpisodeCheck = 0
|
||||
this.maxEpisodesToKeep = 0
|
||||
|
||||
this.lastCoverSearch = null
|
||||
this.lastCoverSearchQuery = null
|
||||
|
|
@ -39,7 +41,9 @@ class Podcast {
|
|||
return podcastEpisode
|
||||
})
|
||||
this.autoDownloadEpisodes = !!podcast.autoDownloadEpisodes
|
||||
this.autoDownloadSchedule = podcast.autoDownloadSchedule || '0 * * * *' // Added in 2.1.3 so default to hourly
|
||||
this.lastEpisodeCheck = podcast.lastEpisodeCheck || 0
|
||||
this.maxEpisodesToKeep = podcast.maxEpisodesToKeep || 0
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
|
@ -50,7 +54,9 @@ class Podcast {
|
|||
tags: [...this.tags],
|
||||
episodes: this.episodes.map(e => e.toJSON()),
|
||||
autoDownloadEpisodes: this.autoDownloadEpisodes,
|
||||
lastEpisodeCheck: this.lastEpisodeCheck
|
||||
autoDownloadSchedule: this.autoDownloadSchedule,
|
||||
lastEpisodeCheck: this.lastEpisodeCheck,
|
||||
maxEpisodesToKeep: this.maxEpisodesToKeep
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -61,7 +67,9 @@ class Podcast {
|
|||
tags: [...this.tags],
|
||||
numEpisodes: this.episodes.length,
|
||||
autoDownloadEpisodes: this.autoDownloadEpisodes,
|
||||
autoDownloadSchedule: this.autoDownloadSchedule,
|
||||
lastEpisodeCheck: this.lastEpisodeCheck,
|
||||
maxEpisodesToKeep: this.maxEpisodesToKeep,
|
||||
size: this.size
|
||||
}
|
||||
}
|
||||
|
|
@ -74,7 +82,9 @@ class Podcast {
|
|||
tags: [...this.tags],
|
||||
episodes: this.episodes.map(e => e.toJSONExpanded()),
|
||||
autoDownloadEpisodes: this.autoDownloadEpisodes,
|
||||
autoDownloadSchedule: this.autoDownloadSchedule,
|
||||
lastEpisodeCheck: this.lastEpisodeCheck,
|
||||
maxEpisodesToKeep: this.maxEpisodesToKeep,
|
||||
size: this.size
|
||||
}
|
||||
}
|
||||
|
|
@ -113,6 +123,9 @@ class Podcast {
|
|||
})
|
||||
return largestPublishedAt
|
||||
}
|
||||
get episodesWithPubDate() {
|
||||
return this.episodes.filter(ep => !!ep.publishedAt)
|
||||
}
|
||||
|
||||
update(payload) {
|
||||
var json = this.toJSON()
|
||||
|
|
@ -157,14 +170,15 @@ class Podcast {
|
|||
return null
|
||||
}
|
||||
|
||||
setData(mediaMetadata) {
|
||||
setData(mediaData) {
|
||||
this.metadata = new PodcastMetadata()
|
||||
if (mediaMetadata.metadata) {
|
||||
this.metadata.setData(mediaMetadata.metadata)
|
||||
if (mediaData.metadata) {
|
||||
this.metadata.setData(mediaData.metadata)
|
||||
}
|
||||
|
||||
this.coverPath = mediaMetadata.coverPath || null
|
||||
this.autoDownloadEpisodes = !!mediaMetadata.autoDownloadEpisodes
|
||||
this.coverPath = mediaData.coverPath || null
|
||||
this.autoDownloadEpisodes = !!mediaData.autoDownloadEpisodes
|
||||
this.autoDownloadSchedule = mediaData.autoDownloadSchedule || global.ServerSettings.podcastEpisodeSchedule
|
||||
this.lastEpisodeCheck = Date.now() // Makes sure new episodes are after this
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
const Logger = require('../../Logger')
|
||||
const { areEquivalent, copyValue, cleanStringForSearch } = require('../../utils/index')
|
||||
const { areEquivalent, copyValue, cleanStringForSearch, getTitleIgnorePrefix } = require('../../utils/index')
|
||||
const parseNameString = require('../../utils/parsers/parseNameString')
|
||||
class BookMetadata {
|
||||
constructor(metadata) {
|
||||
|
|
@ -109,15 +109,7 @@ class BookMetadata {
|
|||
}
|
||||
|
||||
get titleIgnorePrefix() {
|
||||
if (!this.title) return ''
|
||||
var prefixesToIgnore = global.ServerSettings.sortingPrefixes || []
|
||||
for (const prefix of prefixesToIgnore) {
|
||||
// e.g. for prefix "the". If title is "The Book Title" return "Book Title, The"
|
||||
if (this.title.toLowerCase().startsWith(`${prefix} `)) {
|
||||
return this.title.substr(prefix.length + 1) + `, ${prefix.substr(0, 1).toUpperCase() + prefix.substr(1)}`
|
||||
}
|
||||
}
|
||||
return this.title
|
||||
return getTitleIgnorePrefix(this.title)
|
||||
}
|
||||
get authorName() {
|
||||
if (!this.authors.length) return ''
|
||||
|
|
@ -134,6 +126,13 @@ class BookMetadata {
|
|||
return `${se.name} #${se.sequence}`
|
||||
}).join(', ')
|
||||
}
|
||||
get seriesNameIgnorePrefix() {
|
||||
if (!this.series.length) return ''
|
||||
return this.series.map(se => {
|
||||
if (!se.sequence) return getTitleIgnorePrefix(se.name)
|
||||
return `${getTitleIgnorePrefix(se.name)} #${se.sequence}`
|
||||
}).join(', ')
|
||||
}
|
||||
get narratorName() {
|
||||
return this.narrators.join(', ')
|
||||
}
|
||||
|
|
@ -191,6 +190,14 @@ class BookMetadata {
|
|||
return true
|
||||
}
|
||||
|
||||
replaceAuthor(oldAuthor, newAuthor) {
|
||||
this.authors = this.authors.filter(au => au.id !== oldAuthor.id) // Remove old author
|
||||
this.authors.push({
|
||||
id: newAuthor.id,
|
||||
name: newAuthor.name
|
||||
})
|
||||
}
|
||||
|
||||
setData(scanMediaData = {}) {
|
||||
this.title = scanMediaData.title || null
|
||||
this.subtitle = scanMediaData.subtitle || null
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
const { BookCoverAspectRatio } = require('../../utils/constants')
|
||||
const Logger = require('../../Logger')
|
||||
|
||||
class LibrarySettings {
|
||||
constructor(settings) {
|
||||
this.coverAspectRatio = BookCoverAspectRatio.SQUARE
|
||||
this.disableWatcher = false
|
||||
this.skipMatchingMediaWithAsin = false
|
||||
this.skipMatchingMediaWithIsbn = false
|
||||
this.autoScanCronExpression = null
|
||||
|
||||
if (settings) {
|
||||
this.construct(settings)
|
||||
|
|
@ -13,16 +14,20 @@ class LibrarySettings {
|
|||
}
|
||||
|
||||
construct(settings) {
|
||||
this.coverAspectRatio = !isNaN(settings.coverAspectRatio) ? settings.coverAspectRatio : BookCoverAspectRatio.SQUARE
|
||||
this.disableWatcher = !!settings.disableWatcher
|
||||
this.skipMatchingMediaWithAsin = !!settings.skipMatchingMediaWithAsin
|
||||
this.skipMatchingMediaWithIsbn = !!settings.skipMatchingMediaWithIsbn
|
||||
this.autoScanCronExpression = settings.autoScanCronExpression || null
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
coverAspectRatio: this.coverAspectRatio,
|
||||
disableWatcher: this.disableWatcher,
|
||||
skipMatchingMediaWithAsin: this.skipMatchingMediaWithAsin,
|
||||
skipMatchingMediaWithIsbn: this.skipMatchingMediaWithIsbn
|
||||
skipMatchingMediaWithIsbn: this.skipMatchingMediaWithIsbn,
|
||||
autoScanCronExpression: this.autoScanCronExpression
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
const { BookCoverAspectRatio, BookshelfView } = require('../../utils/constants')
|
||||
const { isNullOrNaN } = require('../../utils')
|
||||
const Logger = require('../../Logger')
|
||||
|
||||
class ServerSettings {
|
||||
constructor(settings) {
|
||||
this.id = 'server-settings'
|
||||
this.tokenSecret = null
|
||||
|
||||
// Scanner
|
||||
this.scannerParseSubtitle = false
|
||||
|
|
@ -14,6 +16,8 @@ class ServerSettings {
|
|||
this.scannerPreferMatchedMetadata = false
|
||||
this.scannerDisableWatcher = false
|
||||
this.scannerPreferOverdriveMediaMarker = false
|
||||
this.scannerUseSingleThreadedProber = true
|
||||
this.scannerMaxThreads = 0 // 0 = defaults to CPUs * 2
|
||||
|
||||
// Metadata - choose to store inside users library item folder
|
||||
this.storeCoverWithItem = false
|
||||
|
|
@ -35,7 +39,11 @@ class ServerSettings {
|
|||
this.loggerScannerLogsToKeep = 2
|
||||
|
||||
// Cover
|
||||
// TODO: Remove after mobile apps are configured to use library server settings
|
||||
this.coverAspectRatio = BookCoverAspectRatio.SQUARE
|
||||
|
||||
// Bookshelf Display
|
||||
this.homeBookshelfView = BookshelfView.STANDARD
|
||||
this.bookshelfView = BookshelfView.STANDARD
|
||||
|
||||
// Podcasts
|
||||
|
|
@ -61,6 +69,7 @@ class ServerSettings {
|
|||
}
|
||||
|
||||
construct(settings) {
|
||||
this.tokenSecret = settings.tokenSecret
|
||||
this.scannerFindCovers = !!settings.scannerFindCovers
|
||||
this.scannerCoverProvider = settings.scannerCoverProvider || 'google'
|
||||
this.scannerParseSubtitle = settings.scannerParseSubtitle
|
||||
|
|
@ -69,15 +78,14 @@ class ServerSettings {
|
|||
this.scannerPreferMatchedMetadata = !!settings.scannerPreferMatchedMetadata
|
||||
this.scannerDisableWatcher = !!settings.scannerDisableWatcher
|
||||
this.scannerPreferOverdriveMediaMarker = !!settings.scannerPreferOverdriveMediaMarker
|
||||
this.scannerUseSingleThreadedProber = !!settings.scannerUseSingleThreadedProber
|
||||
if (settings.scannerUseSingleThreadedProber === undefined) { // Default to original scanner
|
||||
this.scannerUseSingleThreadedProber = true
|
||||
}
|
||||
this.scannerMaxThreads = isNullOrNaN(settings.scannerMaxThreads) ? 0 : Number(settings.scannerMaxThreads)
|
||||
|
||||
this.storeCoverWithItem = !!settings.storeCoverWithItem
|
||||
if (settings.storeCoverWithBook != undefined) { // storeCoverWithBook was old name of setting < v2
|
||||
this.storeCoverWithItem = !!settings.storeCoverWithBook
|
||||
}
|
||||
this.storeMetadataWithItem = !!settings.storeMetadataWithItem
|
||||
if (settings.storeMetadataWithBook != undefined) { // storeMetadataWithBook was old name of setting < v2
|
||||
this.storeMetadataWithItem = !!settings.storeMetadataWithBook
|
||||
}
|
||||
|
||||
this.rateLimitLoginRequests = !isNaN(settings.rateLimitLoginRequests) ? Number(settings.rateLimitLoginRequests) : 10
|
||||
this.rateLimitLoginWindow = !isNaN(settings.rateLimitLoginWindow) ? Number(settings.rateLimitLoginWindow) : 10 * 60 * 1000 // 10 Minutes
|
||||
|
|
@ -91,6 +99,7 @@ class ServerSettings {
|
|||
this.loggerScannerLogsToKeep = settings.loggerScannerLogsToKeep || 2
|
||||
|
||||
this.coverAspectRatio = !isNaN(settings.coverAspectRatio) ? settings.coverAspectRatio : BookCoverAspectRatio.SQUARE
|
||||
this.homeBookshelfView = settings.homeBookshelfView || BookshelfView.STANDARD
|
||||
this.bookshelfView = settings.bookshelfView || BookshelfView.STANDARD
|
||||
|
||||
this.sortingIgnorePrefix = !!settings.sortingIgnorePrefix
|
||||
|
|
@ -102,14 +111,26 @@ class ServerSettings {
|
|||
this.logLevel = settings.logLevel || Logger.logLevel
|
||||
this.version = settings.version || null
|
||||
|
||||
// Migrations
|
||||
if (settings.storeCoverWithBook != undefined) { // storeCoverWithBook was renamed to storeCoverWithItem in 2.0.0
|
||||
this.storeCoverWithItem = !!settings.storeCoverWithBook
|
||||
}
|
||||
if (settings.storeMetadataWithBook != undefined) { // storeMetadataWithBook was renamed to storeMetadataWithItem in 2.0.0
|
||||
this.storeMetadataWithItem = !!settings.storeMetadataWithBook
|
||||
}
|
||||
if (settings.homeBookshelfView == undefined) { // homeBookshelfView was added in 2.1.3
|
||||
this.homeBookshelfView = settings.bookshelfView
|
||||
}
|
||||
|
||||
if (this.logLevel !== Logger.logLevel) {
|
||||
Logger.setLogLevel(this.logLevel)
|
||||
}
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
toJSON() { // Use toJSONForBrowser if sending to client
|
||||
return {
|
||||
id: this.id,
|
||||
tokenSecret: this.tokenSecret, // Do not return to client
|
||||
scannerFindCovers: this.scannerFindCovers,
|
||||
scannerCoverProvider: this.scannerCoverProvider,
|
||||
scannerParseSubtitle: this.scannerParseSubtitle,
|
||||
|
|
@ -118,6 +139,8 @@ class ServerSettings {
|
|||
scannerPreferMatchedMetadata: this.scannerPreferMatchedMetadata,
|
||||
scannerDisableWatcher: this.scannerDisableWatcher,
|
||||
scannerPreferOverdriveMediaMarker: this.scannerPreferOverdriveMediaMarker,
|
||||
scannerUseSingleThreadedProber: this.scannerUseSingleThreadedProber,
|
||||
scannerMaxThreads: this.scannerMaxThreads,
|
||||
storeCoverWithItem: this.storeCoverWithItem,
|
||||
storeMetadataWithItem: this.storeMetadataWithItem,
|
||||
rateLimitLoginRequests: this.rateLimitLoginRequests,
|
||||
|
|
@ -129,6 +152,7 @@ class ServerSettings {
|
|||
loggerDailyLogsToKeep: this.loggerDailyLogsToKeep,
|
||||
loggerScannerLogsToKeep: this.loggerScannerLogsToKeep,
|
||||
coverAspectRatio: this.coverAspectRatio,
|
||||
homeBookshelfView: this.homeBookshelfView,
|
||||
bookshelfView: this.bookshelfView,
|
||||
sortingIgnorePrefix: this.sortingIgnorePrefix,
|
||||
sortingPrefixes: [...this.sortingPrefixes],
|
||||
|
|
@ -141,6 +165,12 @@ class ServerSettings {
|
|||
}
|
||||
}
|
||||
|
||||
toJSONForBrowser() {
|
||||
const json = this.toJSON()
|
||||
delete json.tokenSecret
|
||||
return json
|
||||
}
|
||||
|
||||
update(payload) {
|
||||
var hasUpdates = false
|
||||
for (const key in payload) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
const Logger = require('../../Logger')
|
||||
|
||||
class MediaProgress {
|
||||
constructor(progress) {
|
||||
this.id = null
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue