mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-12-15 00:09:38 +00:00
Add db migration file to change audiobooks to library items with new data model
This commit is contained in:
parent
65793f7109
commit
b97ed953f7
17 changed files with 719 additions and 127 deletions
243
server/objects/AudioFile.js
Normal file
243
server/objects/AudioFile.js
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
const { isNullOrNaN } = require('../utils/index')
|
||||
const AudioFileMetadata = require('./metadata/AudioMetaTags')
|
||||
|
||||
class AudioFile {
|
||||
constructor(data) {
|
||||
this.index = null
|
||||
this.ino = null
|
||||
this.filename = null
|
||||
this.ext = null
|
||||
this.path = null
|
||||
this.fullPath = null
|
||||
this.mtimeMs = null
|
||||
this.ctimeMs = null
|
||||
this.birthtimeMs = null
|
||||
this.addedAt = null
|
||||
|
||||
this.trackNumFromMeta = null
|
||||
this.discNumFromMeta = null
|
||||
this.trackNumFromFilename = null
|
||||
this.discNumFromFilename = null
|
||||
|
||||
this.format = null
|
||||
this.duration = null
|
||||
this.size = null
|
||||
this.bitRate = null
|
||||
this.language = null
|
||||
this.codec = null
|
||||
this.timeBase = null
|
||||
this.channels = null
|
||||
this.channelLayout = null
|
||||
this.chapters = []
|
||||
this.embeddedCoverArt = null
|
||||
|
||||
// Tags scraped from the audio file
|
||||
this.metadata = null
|
||||
|
||||
this.manuallyVerified = false
|
||||
this.invalid = false
|
||||
this.exclude = false
|
||||
this.error = null
|
||||
|
||||
if (data) {
|
||||
this.construct(data)
|
||||
}
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
index: this.index,
|
||||
ino: this.ino,
|
||||
filename: this.filename,
|
||||
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,
|
||||
trackNumFromFilename: this.trackNumFromFilename,
|
||||
discNumFromFilename: this.discNumFromFilename,
|
||||
manuallyVerified: !!this.manuallyVerified,
|
||||
invalid: !!this.invalid,
|
||||
exclude: !!this.exclude,
|
||||
error: this.error || null,
|
||||
format: this.format,
|
||||
duration: this.duration,
|
||||
size: this.size,
|
||||
bitRate: this.bitRate,
|
||||
language: this.language,
|
||||
codec: this.codec,
|
||||
timeBase: this.timeBase,
|
||||
channels: this.channels,
|
||||
channelLayout: this.channelLayout,
|
||||
chapters: this.chapters,
|
||||
embeddedCoverArt: this.embeddedCoverArt,
|
||||
metadata: this.metadata ? this.metadata.toJSON() : {}
|
||||
}
|
||||
}
|
||||
|
||||
construct(data) {
|
||||
this.index = data.index
|
||||
this.ino = data.ino
|
||||
this.filename = data.filename
|
||||
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
|
||||
this.exclude = !!data.exclude
|
||||
this.error = data.error || null
|
||||
|
||||
this.trackNumFromMeta = data.trackNumFromMeta
|
||||
this.discNumFromMeta = data.discNumFromMeta
|
||||
this.trackNumFromFilename = data.trackNumFromFilename
|
||||
|
||||
if (data.cdNumFromFilename !== undefined) this.discNumFromFilename = data.cdNumFromFilename // TEMP:Support old var name
|
||||
else this.discNumFromFilename = data.discNumFromFilename
|
||||
|
||||
this.format = data.format
|
||||
this.duration = data.duration
|
||||
this.size = data.size
|
||||
this.bitRate = data.bitRate
|
||||
this.language = data.language
|
||||
this.codec = data.codec || null
|
||||
this.timeBase = data.timeBase
|
||||
this.channels = data.channels
|
||||
this.channelLayout = data.channelLayout
|
||||
this.chapters = data.chapters
|
||||
this.embeddedCoverArt = data.embeddedCoverArt || null
|
||||
|
||||
// Old version of AudioFile used `tagAlbum` etc.
|
||||
var isOldVersion = Object.keys(data).find(key => key.startsWith('tag'))
|
||||
if (isOldVersion) {
|
||||
this.metadata = new AudioFileMetadata(data)
|
||||
} else {
|
||||
this.metadata = new AudioFileMetadata(data.metadata || {})
|
||||
}
|
||||
}
|
||||
|
||||
// New scanner creates AudioFile from AudioFileScanner
|
||||
setDataFromProbe(fileData, probeData) {
|
||||
this.index = fileData.index || null
|
||||
this.ino = fileData.ino || null
|
||||
this.filename = fileData.filename
|
||||
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
|
||||
this.discNumFromMeta = fileData.discNumFromMeta
|
||||
this.trackNumFromFilename = fileData.trackNumFromFilename
|
||||
this.discNumFromFilename = fileData.discNumFromFilename
|
||||
|
||||
this.format = probeData.format
|
||||
this.duration = probeData.duration
|
||||
this.size = probeData.size
|
||||
this.bitRate = probeData.bitRate || null
|
||||
this.language = probeData.language
|
||||
this.codec = probeData.codec || null
|
||||
this.timeBase = probeData.timeBase
|
||||
this.channels = probeData.channels
|
||||
this.channelLayout = probeData.channelLayout
|
||||
this.chapters = probeData.chapters || []
|
||||
this.metadata = probeData.audioFileMetadata
|
||||
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 }))
|
||||
return true
|
||||
} else if (updatedChapters.length === 0) {
|
||||
if (this.chapters.length > 0) {
|
||||
this.chapters = []
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var hasUpdates = false
|
||||
for (let i = 0; i < updatedChapters.length; i++) {
|
||||
if (JSON.stringify(updatedChapters[i]) !== JSON.stringify(this.chapters[i])) {
|
||||
hasUpdates = true
|
||||
}
|
||||
}
|
||||
if (hasUpdates) {
|
||||
this.chapters = updatedChapters.map(ch => ({ ...ch }))
|
||||
}
|
||||
return hasUpdates
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new AudioFile(this.toJSON())
|
||||
}
|
||||
|
||||
// If the file or parent directory was renamed it is synced here
|
||||
syncFile(newFile) {
|
||||
var hasUpdates = false
|
||||
var keysToSync = ['path', 'fullPath', 'ext', 'filename']
|
||||
keysToSync.forEach((key) => {
|
||||
if (newFile[key] !== undefined && newFile[key] !== this[key]) {
|
||||
hasUpdates = true
|
||||
this[key] = newFile[key]
|
||||
}
|
||||
})
|
||||
return hasUpdates
|
||||
}
|
||||
|
||||
updateFromScan(scannedAudioFile) {
|
||||
var hasUpdated = false
|
||||
|
||||
var newjson = scannedAudioFile.toJSON()
|
||||
if (this.manuallyVerified) newjson.manuallyVerified = true
|
||||
if (this.exclude) newjson.exclude = true
|
||||
newjson.addedAt = this.addedAt
|
||||
|
||||
for (const key in newjson) {
|
||||
if (key === 'metadata') {
|
||||
if (!this.metadata || !this.metadata.isEqual(scannedAudioFile.metadata)) {
|
||||
this.metadata = scannedAudioFile.metadata
|
||||
hasUpdated = true
|
||||
}
|
||||
} else if (key === 'chapters') {
|
||||
if (this.syncChapters(newjson.chapters || [])) {
|
||||
hasUpdated = true
|
||||
}
|
||||
} else if (this[key] !== newjson[key]) {
|
||||
// console.log(this.filename, 'key', key, 'updated', this[key], newjson[key])
|
||||
this[key] = newjson[key]
|
||||
hasUpdated = true
|
||||
}
|
||||
}
|
||||
return hasUpdated
|
||||
}
|
||||
}
|
||||
module.exports = AudioFile
|
||||
|
|
@ -9,7 +9,7 @@ const abmetadataGenerator = require('../utils/abmetadataGenerator')
|
|||
const Logger = require('../Logger')
|
||||
const Book = require('./Book')
|
||||
const AudioTrack = require('./AudioTrack')
|
||||
const AudioFile = require('./files/AudioFile')
|
||||
const AudioFile = require('./AudioFile')
|
||||
const AudiobookFile = require('./AudiobookFile')
|
||||
|
||||
class Audiobook {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
const { getId } = require('../../utils/index')
|
||||
|
||||
class Author {
|
||||
constructor(author) {
|
||||
this.id = null
|
||||
this.asin = null
|
||||
this.name = null
|
||||
this.imagePath = null
|
||||
this.imageFullPath = null
|
||||
this.relImagePath = null
|
||||
this.addedAt = null
|
||||
this.updatedAt = null
|
||||
|
||||
|
|
@ -18,7 +20,7 @@ class Author {
|
|||
this.asin = author.asin
|
||||
this.name = author.name
|
||||
this.imagePath = author.imagePath
|
||||
this.imageFullPath = author.imageFullPath
|
||||
this.relImagePath = author.relImagePath
|
||||
this.addedAt = author.addedAt
|
||||
this.updatedAt = author.updatedAt
|
||||
}
|
||||
|
|
@ -29,9 +31,9 @@ class Author {
|
|||
asin: this.asin,
|
||||
name: this.name,
|
||||
imagePath: this.imagePath,
|
||||
imageFullPath: this.imageFullPath,
|
||||
relImagePath: this.relImagePath,
|
||||
addedAt: this.addedAt,
|
||||
updatedAt: this.updatedAt
|
||||
lastUpdate: this.updatedAt
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -41,5 +43,15 @@ class Author {
|
|||
name: this.name
|
||||
}
|
||||
}
|
||||
|
||||
setData(data) {
|
||||
this.id = getId('aut')
|
||||
this.name = data.name
|
||||
this.asin = data.asin || null
|
||||
this.imagePath = data.imagePath || null
|
||||
this.relImagePath = data.relImagePath || null
|
||||
this.addedAt = Date.now()
|
||||
this.updatedAt = Date.now()
|
||||
}
|
||||
}
|
||||
module.exports = Author
|
||||
|
|
@ -1,39 +1,41 @@
|
|||
const BookMetadata = require('../metadata/BookMetadata')
|
||||
const AudioFile = require('../files/AudioFile')
|
||||
const EBookFile = require('../files/EBookFile')
|
||||
const AudioTrack = require('../AudioTrack')
|
||||
|
||||
class Book {
|
||||
constructor(book) {
|
||||
this.metadata = null
|
||||
|
||||
this.coverPath = null
|
||||
this.relCoverPath = null
|
||||
this.tags = []
|
||||
this.audioFiles = []
|
||||
this.ebookFiles = []
|
||||
this.audioTracks = []
|
||||
this.chapters = []
|
||||
|
||||
if (books) {
|
||||
if (book) {
|
||||
this.construct(book)
|
||||
}
|
||||
}
|
||||
|
||||
construct(book) {
|
||||
this.metadata = new BookMetadata(book.metadata)
|
||||
this.coverPath = book.coverPath
|
||||
this.relCoverPath = book.relCoverPath
|
||||
this.tags = [...book.tags]
|
||||
this.audioFiles = book.audioFiles.map(f => new AudioFile(f))
|
||||
this.ebookFiles = book.ebookFiles.map(f => new EBookFile(f))
|
||||
this.audioTracks = book.audioTracks.map(a => new AudioTrack(a))
|
||||
this.chapters = book.chapters.map(c => ({ ...c }))
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
metadata: this.metadata.toJSON(),
|
||||
coverPath: this.coverPath,
|
||||
relCoverPath: this.relCoverPath,
|
||||
tags: [...this.tags],
|
||||
audioFiles: this.audioFiles.map(f => f.toJSON()),
|
||||
ebookFiles: this.ebookFiles.map(f => f.toJSON()),
|
||||
audioTracks: this.audioTracks.map(a => a.toJSON()),
|
||||
chapters: this.chapters.map(c => ({ ...c }))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
const { getId } = require('../../utils/index')
|
||||
|
||||
class Series {
|
||||
constructor(series) {
|
||||
this.id = null
|
||||
this.name = null
|
||||
this.sequence = null
|
||||
this.addedAt = null
|
||||
this.updatedAt = null
|
||||
|
||||
|
|
@ -14,7 +15,6 @@ class Series {
|
|||
construct(series) {
|
||||
this.id = series.id
|
||||
this.name = series.name
|
||||
this.sequence = series.sequence
|
||||
this.addedAt = series.addedAt
|
||||
this.updatedAt = series.updatedAt
|
||||
}
|
||||
|
|
@ -23,18 +23,24 @@ class Series {
|
|||
return {
|
||||
id: this.id,
|
||||
name: this.name,
|
||||
sequence: this.sequence,
|
||||
addedAt: this.addedAt,
|
||||
updatedAt: this.updatedAt
|
||||
}
|
||||
}
|
||||
|
||||
toJSONMinimal() {
|
||||
toJSONMinimal(sequence) {
|
||||
return {
|
||||
id: this.id,
|
||||
name: this.name,
|
||||
sequence: this.sequence
|
||||
sequence
|
||||
}
|
||||
}
|
||||
|
||||
setData(data) {
|
||||
this.id = getId('ser')
|
||||
this.name = data.name
|
||||
this.addedAt = Date.now()
|
||||
this.updatedAt = Date.now()
|
||||
}
|
||||
}
|
||||
module.exports = Series
|
||||
|
|
@ -1,20 +1,14 @@
|
|||
const { isNullOrNaN } = require('../../utils/index')
|
||||
|
||||
const Logger = require('../../Logger')
|
||||
const AudioFileMetadata = require('../metadata/AudioFileMetadata')
|
||||
const AudioMetaTags = require('../metadata/AudioMetaTags')
|
||||
const FileMetadata = require('../metadata/FileMetadata')
|
||||
|
||||
class AudioFile {
|
||||
constructor(data) {
|
||||
this.index = null
|
||||
this.ino = null
|
||||
this.filename = null
|
||||
this.ext = null
|
||||
this.path = null
|
||||
this.fullPath = null
|
||||
this.mtimeMs = null
|
||||
this.ctimeMs = null
|
||||
this.birthtimeMs = null
|
||||
this.metadata = null
|
||||
this.addedAt = null
|
||||
this.updatedAt = null
|
||||
|
||||
this.trackNumFromMeta = null
|
||||
this.discNumFromMeta = null
|
||||
|
|
@ -23,7 +17,6 @@ class AudioFile {
|
|||
|
||||
this.format = null
|
||||
this.duration = null
|
||||
this.size = null
|
||||
this.bitRate = null
|
||||
this.language = null
|
||||
this.codec = null
|
||||
|
|
@ -34,7 +27,7 @@ class AudioFile {
|
|||
this.embeddedCoverArt = null
|
||||
|
||||
// Tags scraped from the audio file
|
||||
this.metadata = null
|
||||
this.metaTags = null
|
||||
|
||||
this.manuallyVerified = false
|
||||
this.invalid = false
|
||||
|
|
@ -50,14 +43,9 @@ class AudioFile {
|
|||
return {
|
||||
index: this.index,
|
||||
ino: this.ino,
|
||||
filename: this.filename,
|
||||
ext: this.ext,
|
||||
path: this.path,
|
||||
fullPath: this.fullPath,
|
||||
mtimeMs: this.mtimeMs,
|
||||
ctimeMs: this.ctimeMs,
|
||||
birthtimeMs: this.birthtimeMs,
|
||||
metadata: this.metadata.toJSON(),
|
||||
addedAt: this.addedAt,
|
||||
updatedAt: this.updatedAt,
|
||||
trackNumFromMeta: this.trackNumFromMeta,
|
||||
discNumFromMeta: this.discNumFromMeta,
|
||||
trackNumFromFilename: this.trackNumFromFilename,
|
||||
|
|
@ -68,7 +56,6 @@ class AudioFile {
|
|||
error: this.error || null,
|
||||
format: this.format,
|
||||
duration: this.duration,
|
||||
size: this.size,
|
||||
bitRate: this.bitRate,
|
||||
language: this.language,
|
||||
codec: this.codec,
|
||||
|
|
@ -77,21 +64,16 @@ class AudioFile {
|
|||
channelLayout: this.channelLayout,
|
||||
chapters: this.chapters,
|
||||
embeddedCoverArt: this.embeddedCoverArt,
|
||||
metadata: this.metadata ? this.metadata.toJSON() : {}
|
||||
metaTags: this.metaTags ? this.metaTags.toJSON() : {}
|
||||
}
|
||||
}
|
||||
|
||||
construct(data) {
|
||||
this.index = data.index
|
||||
this.ino = data.ino
|
||||
this.filename = data.filename
|
||||
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.metadata = new FileMetadata(data.metadata || {})
|
||||
this.addedAt = data.addedAt
|
||||
this.updatedAt = data.updatedAt
|
||||
this.manuallyVerified = !!data.manuallyVerified
|
||||
this.invalid = !!data.invalid
|
||||
this.exclude = !!data.exclude
|
||||
|
|
@ -106,7 +88,6 @@ class AudioFile {
|
|||
|
||||
this.format = data.format
|
||||
this.duration = data.duration
|
||||
this.size = data.size
|
||||
this.bitRate = data.bitRate
|
||||
this.language = data.language
|
||||
this.codec = data.codec || null
|
||||
|
|
@ -116,27 +97,17 @@ class AudioFile {
|
|||
this.chapters = data.chapters
|
||||
this.embeddedCoverArt = data.embeddedCoverArt || null
|
||||
|
||||
// Old version of AudioFile used `tagAlbum` etc.
|
||||
var isOldVersion = Object.keys(data).find(key => key.startsWith('tag'))
|
||||
if (isOldVersion) {
|
||||
this.metadata = new AudioFileMetadata(data)
|
||||
} else {
|
||||
this.metadata = new AudioFileMetadata(data.metadata || {})
|
||||
}
|
||||
this.metaTags = new AudioMetaTags(data.metaTags || {})
|
||||
}
|
||||
|
||||
// New scanner creates AudioFile from AudioFileScanner
|
||||
setDataFromProbe(fileData, probeData) {
|
||||
this.index = fileData.index || null
|
||||
this.ino = fileData.ino || null
|
||||
this.filename = fileData.filename
|
||||
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
|
||||
|
||||
// TODO: Update file metadata for set data from probe
|
||||
this.addedAt = Date.now()
|
||||
this.updatedAt = Date.now()
|
||||
|
||||
this.trackNumFromMeta = fileData.trackNumFromMeta
|
||||
this.discNumFromMeta = fileData.discNumFromMeta
|
||||
|
|
@ -145,7 +116,6 @@ class AudioFile {
|
|||
|
||||
this.format = probeData.format
|
||||
this.duration = probeData.duration
|
||||
this.size = probeData.size
|
||||
this.bitRate = probeData.bitRate || null
|
||||
this.language = probeData.language
|
||||
this.codec = probeData.codec || null
|
||||
|
|
@ -153,7 +123,7 @@ class AudioFile {
|
|||
this.channels = probeData.channels
|
||||
this.channelLayout = probeData.channelLayout
|
||||
this.chapters = probeData.chapters || []
|
||||
this.metadata = probeData.audioFileMetadata
|
||||
this.metaTags = probeData.audioFileMetadata
|
||||
this.embeddedCoverArt = probeData.embeddedCoverArt
|
||||
}
|
||||
|
||||
|
|
@ -204,15 +174,17 @@ class AudioFile {
|
|||
|
||||
// If the file or parent directory was renamed it is synced here
|
||||
syncFile(newFile) {
|
||||
var hasUpdates = false
|
||||
var keysToSync = ['path', 'fullPath', 'ext', 'filename']
|
||||
keysToSync.forEach((key) => {
|
||||
if (newFile[key] !== undefined && newFile[key] !== this[key]) {
|
||||
hasUpdates = true
|
||||
this[key] = newFile[key]
|
||||
}
|
||||
})
|
||||
return hasUpdates
|
||||
// TODO: Sync file would update the file info if needed
|
||||
return false
|
||||
// var hasUpdates = false
|
||||
// var keysToSync = ['path', 'relPath', 'ext', 'filename']
|
||||
// keysToSync.forEach((key) => {
|
||||
// if (newFile[key] !== undefined && newFile[key] !== this[key]) {
|
||||
// hasUpdates = true
|
||||
// this[key] = newFile[key]
|
||||
// }
|
||||
// })
|
||||
// return hasUpdates
|
||||
}
|
||||
|
||||
updateFromScan(scannedAudioFile) {
|
||||
|
|
@ -224,9 +196,9 @@ class AudioFile {
|
|||
newjson.addedAt = this.addedAt
|
||||
|
||||
for (const key in newjson) {
|
||||
if (key === 'metadata') {
|
||||
if (!this.metadata || !this.metadata.isEqual(scannedAudioFile.metadata)) {
|
||||
this.metadata = scannedAudioFile.metadata
|
||||
if (key === 'metaTags') {
|
||||
if (!this.metaTags || !this.metaTags.isEqual(scannedAudioFile.metadata)) {
|
||||
this.metaTags = scannedAudioFile.metadata
|
||||
hasUpdated = true
|
||||
}
|
||||
} else if (key === 'chapters') {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ class EBookFile {
|
|||
this.metadata = null
|
||||
this.ebookFormat = null
|
||||
this.addedAt = null
|
||||
this.lastUpdate = null
|
||||
this.updatedAt = null
|
||||
|
||||
if (file) {
|
||||
this.construct(file)
|
||||
|
|
@ -18,7 +18,7 @@ class EBookFile {
|
|||
this.metadata = new FileMetadata(file)
|
||||
this.ebookFormat = file.ebookFormat
|
||||
this.addedAt = file.addedAt
|
||||
this.lastUpdate = file.lastUpdate
|
||||
this.updatedAt = file.updatedAt
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
|
@ -27,7 +27,7 @@ class EBookFile {
|
|||
metadata: this.metadata.toJSON(),
|
||||
ebookFormat: this.ebookFormat,
|
||||
addedAt: this.addedAt,
|
||||
lastUpdate: this.lastUpdate
|
||||
updatedAt: this.updatedAt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
129
server/objects/metadata/AudioMetaTags.js
Normal file
129
server/objects/metadata/AudioMetaTags.js
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
class AudioMetaTags {
|
||||
constructor(metadata) {
|
||||
this.tagAlbum = null
|
||||
this.tagArtist = null
|
||||
this.tagGenre = null
|
||||
this.tagTitle = null
|
||||
this.tagSeries = null
|
||||
this.tagSeriesPart = null
|
||||
this.tagTrack = null
|
||||
this.tagDisc = null
|
||||
this.tagSubtitle = null
|
||||
this.tagAlbumArtist = null
|
||||
this.tagDate = null
|
||||
this.tagComposer = null
|
||||
this.tagPublisher = null
|
||||
this.tagComment = null
|
||||
this.tagDescription = null
|
||||
this.tagEncoder = null
|
||||
this.tagEncodedBy = null
|
||||
this.tagIsbn = null
|
||||
this.tagLanguage = null
|
||||
this.tagASIN = null
|
||||
|
||||
if (metadata) {
|
||||
this.construct(metadata)
|
||||
}
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
// Only return the tags that are actually set
|
||||
var json = {}
|
||||
for (const key in this) {
|
||||
if (key.startsWith('tag') && this[key]) {
|
||||
json[key] = this[key]
|
||||
}
|
||||
}
|
||||
return json
|
||||
}
|
||||
|
||||
construct(metadata) {
|
||||
this.tagAlbum = metadata.tagAlbum || null
|
||||
this.tagArtist = metadata.tagArtist || null
|
||||
this.tagGenre = metadata.tagGenre || null
|
||||
this.tagTitle = metadata.tagTitle || null
|
||||
this.tagSeries = metadata.tagSeries || null
|
||||
this.tagSeriesPart = metadata.tagSeriesPart || null
|
||||
this.tagTrack = metadata.tagTrack || null
|
||||
this.tagDisc = metadata.tagDisc || null
|
||||
this.tagSubtitle = metadata.tagSubtitle || null
|
||||
this.tagAlbumArtist = metadata.tagAlbumArtist || null
|
||||
this.tagDate = metadata.tagDate || null
|
||||
this.tagComposer = metadata.tagComposer || null
|
||||
this.tagPublisher = metadata.tagPublisher || null
|
||||
this.tagComment = metadata.tagComment || null
|
||||
this.tagDescription = metadata.tagDescription || null
|
||||
this.tagEncoder = metadata.tagEncoder || null
|
||||
this.tagEncodedBy = metadata.tagEncodedBy || null
|
||||
this.tagIsbn = metadata.tagIsbn || null
|
||||
this.tagLanguage = metadata.tagLanguage || null
|
||||
this.tagASIN = metadata.tagASIN || null
|
||||
}
|
||||
|
||||
// Data parsed in prober.js
|
||||
setData(payload) {
|
||||
this.tagAlbum = payload.file_tag_album || null
|
||||
this.tagArtist = payload.file_tag_artist || null
|
||||
this.tagGenre = payload.file_tag_genre || null
|
||||
this.tagTitle = payload.file_tag_title || null
|
||||
this.tagSeries = payload.file_tag_series || null
|
||||
this.tagSeriesPart = payload.file_tag_seriespart || null
|
||||
this.tagTrack = payload.file_tag_track || null
|
||||
this.tagDisc = payload.file_tag_disc || null
|
||||
this.tagSubtitle = payload.file_tag_subtitle || null
|
||||
this.tagAlbumArtist = payload.file_tag_albumartist || null
|
||||
this.tagDate = payload.file_tag_date || null
|
||||
this.tagComposer = payload.file_tag_composer || null
|
||||
this.tagPublisher = payload.file_tag_publisher || null
|
||||
this.tagComment = payload.file_tag_comment || null
|
||||
this.tagDescription = payload.file_tag_description || null
|
||||
this.tagEncoder = payload.file_tag_encoder || null
|
||||
this.tagEncodedBy = payload.file_tag_encodedby || null
|
||||
this.tagIsbn = payload.file_tag_isbn || null
|
||||
this.tagLanguage = payload.file_tag_language || null
|
||||
this.tagASIN = payload.file_tag_asin || null
|
||||
}
|
||||
|
||||
updateData(payload) {
|
||||
const dataMap = {
|
||||
tagAlbum: payload.file_tag_album || null,
|
||||
tagArtist: payload.file_tag_artist || null,
|
||||
tagGenre: payload.file_tag_genre || null,
|
||||
tagTitle: payload.file_tag_title || null,
|
||||
tagSeries: payload.file_tag_series || null,
|
||||
tagSeriesPart: payload.file_tag_seriespart || null,
|
||||
tagTrack: payload.file_tag_track || null,
|
||||
tagDisc: payload.file_tag_disc || null,
|
||||
tagSubtitle: payload.file_tag_subtitle || null,
|
||||
tagAlbumArtist: payload.file_tag_albumartist || null,
|
||||
tagDate: payload.file_tag_date || null,
|
||||
tagComposer: payload.file_tag_composer || null,
|
||||
tagPublisher: payload.file_tag_publisher || null,
|
||||
tagComment: payload.file_tag_comment || null,
|
||||
tagDescription: payload.file_tag_description || null,
|
||||
tagEncoder: payload.file_tag_encoder || null,
|
||||
tagEncodedBy: payload.file_tag_encodedby || null,
|
||||
tagIsbn: payload.file_tag_isbn || null,
|
||||
tagLanguage: payload.file_tag_language || null,
|
||||
tagASIN: payload.file_tag_asin || null
|
||||
}
|
||||
|
||||
var hasUpdates = false
|
||||
for (const key in dataMap) {
|
||||
if (dataMap[key] !== this[key]) {
|
||||
this[key] = dataMap[key]
|
||||
hasUpdates = true
|
||||
}
|
||||
}
|
||||
return hasUpdates
|
||||
}
|
||||
|
||||
isEqual(audioFileMetadata) {
|
||||
if (!audioFileMetadata || !audioFileMetadata.toJSON) return false
|
||||
for (const key in audioFileMetadata.toJSON()) {
|
||||
if (audioFileMetadata[key] !== this[key]) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
module.exports = AudioMetaTags
|
||||
|
|
@ -22,12 +22,12 @@ class BookMetadata {
|
|||
construct(metadata) {
|
||||
this.title = metadata.title
|
||||
this.subtitle = metadata.subtitle
|
||||
this.authors = metadata.authors.map(a => ({ ...a }))
|
||||
this.narrators = [...metadata.narrators]
|
||||
this.series = metadata.series.map(s => ({ ...s }))
|
||||
this.genres = [...metadata.genres]
|
||||
this.publishedYear = metadata.publishedYear
|
||||
this.publishedDate = metadata.publishedDate
|
||||
this.authors = (metadata.authors && metadata.authors.map) ? metadata.authors.map(a => ({ ...a })) : []
|
||||
this.narrators = metadata.narrators ? [...metadata.narrators] : []
|
||||
this.series = (metadata.series && metadata.series.map) ? metadata.series.map(s => ({ ...s })) : []
|
||||
this.genres = metadata.genres ? [...metadata.genres] : []
|
||||
this.publishedYear = metadata.publishedYear || null
|
||||
this.publishedDate = metadata.publishedDate || null
|
||||
this.publisher = metadata.publisher
|
||||
this.description = metadata.description
|
||||
this.isbn = metadata.isbn
|
||||
|
|
|
|||
|
|
@ -37,5 +37,9 @@ class FileMetadata {
|
|||
birthtimeMs: this.birthtimeMs
|
||||
}
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new FileMetadata(this.toJSON())
|
||||
}
|
||||
}
|
||||
module.exports = FileMetadata
|
||||
Loading…
Add table
Add a link
Reference in a new issue