mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2024-11-07 16:44:16 +01:00
Fix:Update metadata.json when using item metadata utils #2837
This commit is contained in:
parent
29fc503503
commit
c4fd4ff9de
@ -329,6 +329,7 @@ class MiscController {
|
|||||||
await libraryItem.media.update({
|
await libraryItem.media.update({
|
||||||
tags: libraryItem.media.tags
|
tags: libraryItem.media.tags
|
||||||
})
|
})
|
||||||
|
await libraryItem.saveMetadataFile()
|
||||||
const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem)
|
const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem)
|
||||||
SocketAuthority.emitter('item_updated', oldLibraryItem.toJSONExpanded())
|
SocketAuthority.emitter('item_updated', oldLibraryItem.toJSONExpanded())
|
||||||
numItemsUpdated++
|
numItemsUpdated++
|
||||||
@ -370,6 +371,7 @@ class MiscController {
|
|||||||
await libraryItem.media.update({
|
await libraryItem.media.update({
|
||||||
tags: libraryItem.media.tags
|
tags: libraryItem.media.tags
|
||||||
})
|
})
|
||||||
|
await libraryItem.saveMetadataFile()
|
||||||
const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem)
|
const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem)
|
||||||
SocketAuthority.emitter('item_updated', oldLibraryItem.toJSONExpanded())
|
SocketAuthority.emitter('item_updated', oldLibraryItem.toJSONExpanded())
|
||||||
numItemsUpdated++
|
numItemsUpdated++
|
||||||
@ -462,6 +464,7 @@ class MiscController {
|
|||||||
await libraryItem.media.update({
|
await libraryItem.media.update({
|
||||||
genres: libraryItem.media.genres
|
genres: libraryItem.media.genres
|
||||||
})
|
})
|
||||||
|
await libraryItem.saveMetadataFile()
|
||||||
const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem)
|
const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem)
|
||||||
SocketAuthority.emitter('item_updated', oldLibraryItem.toJSONExpanded())
|
SocketAuthority.emitter('item_updated', oldLibraryItem.toJSONExpanded())
|
||||||
numItemsUpdated++
|
numItemsUpdated++
|
||||||
@ -503,6 +506,7 @@ class MiscController {
|
|||||||
await libraryItem.media.update({
|
await libraryItem.media.update({
|
||||||
genres: libraryItem.media.genres
|
genres: libraryItem.media.genres
|
||||||
})
|
})
|
||||||
|
await libraryItem.saveMetadataFile()
|
||||||
const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem)
|
const oldLibraryItem = Database.libraryItemModel.getOldLibraryItem(libraryItem)
|
||||||
SocketAuthority.emitter('item_updated', oldLibraryItem.toJSONExpanded())
|
SocketAuthority.emitter('item_updated', oldLibraryItem.toJSONExpanded())
|
||||||
numItemsUpdated++
|
numItemsUpdated++
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
|
const Path = require('path')
|
||||||
const { DataTypes, Model } = require('sequelize')
|
const { DataTypes, Model } = require('sequelize')
|
||||||
|
const fsExtra = require('../libs/fsExtra')
|
||||||
const Logger = require('../Logger')
|
const Logger = require('../Logger')
|
||||||
const oldLibraryItem = require('../objects/LibraryItem')
|
const oldLibraryItem = require('../objects/LibraryItem')
|
||||||
const libraryFilters = require('../utils/queries/libraryFilters')
|
const libraryFilters = require('../utils/queries/libraryFilters')
|
||||||
const { areEquivalent } = require('../utils/index')
|
const { areEquivalent } = require('../utils/index')
|
||||||
|
const { filePathToPOSIX, getFileTimestampsWithIno } = require('../utils/fileUtils')
|
||||||
|
const LibraryFile = require('../objects/files/LibraryFile')
|
||||||
const Book = require('./Book')
|
const Book = require('./Book')
|
||||||
const Podcast = require('./Podcast')
|
const Podcast = require('./Podcast')
|
||||||
|
|
||||||
@ -828,6 +832,147 @@ class LibraryItem extends Model {
|
|||||||
return this[mixinMethodName](options)
|
return this[mixinMethodName](options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns {Promise<Book|Podcast>}
|
||||||
|
*/
|
||||||
|
getMediaExpanded() {
|
||||||
|
if (this.mediaType === 'podcast') {
|
||||||
|
return this.getMedia({
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: this.sequelize.models.podcastEpisode
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return this.getMedia({
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: this.sequelize.models.author,
|
||||||
|
through: {
|
||||||
|
attributes: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: this.sequelize.models.series,
|
||||||
|
through: {
|
||||||
|
attributes: ['sequence']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
order: [
|
||||||
|
[this.sequelize.models.author, this.sequelize.models.bookAuthor, 'createdAt', 'ASC'],
|
||||||
|
[this.sequelize.models.series, 'bookSeries', 'createdAt', 'ASC']
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
async saveMetadataFile() {
|
||||||
|
let metadataPath = Path.join(global.MetadataPath, 'items', this.id)
|
||||||
|
let storeMetadataWithItem = global.ServerSettings.storeMetadataWithItem
|
||||||
|
if (storeMetadataWithItem && !this.isFile) {
|
||||||
|
metadataPath = this.path
|
||||||
|
} else {
|
||||||
|
// Make sure metadata book dir exists
|
||||||
|
storeMetadataWithItem = false
|
||||||
|
await fsExtra.ensureDir(metadataPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
const metadataFilePath = Path.join(metadataPath, `metadata.${global.ServerSettings.metadataFileFormat}`)
|
||||||
|
|
||||||
|
// Expanded with series, authors, podcastEpisodes
|
||||||
|
const mediaExpanded = this.media || await this.getMediaExpanded()
|
||||||
|
|
||||||
|
let jsonObject = {}
|
||||||
|
if (this.mediaType === 'book') {
|
||||||
|
jsonObject = {
|
||||||
|
tags: mediaExpanded.tags || [],
|
||||||
|
chapters: mediaExpanded.chapters?.map(c => ({ ...c })) || [],
|
||||||
|
title: mediaExpanded.title,
|
||||||
|
subtitle: mediaExpanded.subtitle,
|
||||||
|
authors: mediaExpanded.authors.map(a => a.name),
|
||||||
|
narrators: mediaExpanded.narrators,
|
||||||
|
series: mediaExpanded.series.map(se => {
|
||||||
|
const sequence = se.bookSeries?.sequence || ''
|
||||||
|
if (!sequence) return se.name
|
||||||
|
return `${se.name} #${sequence}`
|
||||||
|
}),
|
||||||
|
genres: mediaExpanded.genres || [],
|
||||||
|
publishedYear: mediaExpanded.publishedYear,
|
||||||
|
publishedDate: mediaExpanded.publishedDate,
|
||||||
|
publisher: mediaExpanded.publisher,
|
||||||
|
description: mediaExpanded.description,
|
||||||
|
isbn: mediaExpanded.isbn,
|
||||||
|
asin: mediaExpanded.asin,
|
||||||
|
language: mediaExpanded.language,
|
||||||
|
explicit: !!mediaExpanded.explicit,
|
||||||
|
abridged: !!mediaExpanded.abridged
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
jsonObject = {
|
||||||
|
tags: mediaExpanded.tags || [],
|
||||||
|
title: mediaExpanded.title,
|
||||||
|
author: mediaExpanded.author,
|
||||||
|
description: mediaExpanded.description,
|
||||||
|
releaseDate: mediaExpanded.releaseDate,
|
||||||
|
genres: mediaExpanded.genres || [],
|
||||||
|
feedURL: mediaExpanded.feedURL,
|
||||||
|
imageURL: mediaExpanded.imageURL,
|
||||||
|
itunesPageURL: mediaExpanded.itunesPageURL,
|
||||||
|
itunesId: mediaExpanded.itunesId,
|
||||||
|
itunesArtistId: mediaExpanded.itunesArtistId,
|
||||||
|
asin: mediaExpanded.asin,
|
||||||
|
language: mediaExpanded.language,
|
||||||
|
explicit: !!mediaExpanded.explicit,
|
||||||
|
podcastType: mediaExpanded.podcastType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return fsExtra.writeFile(metadataFilePath, JSON.stringify(jsonObject, null, 2)).then(async () => {
|
||||||
|
// Add metadata.json to libraryFiles array if it is new
|
||||||
|
let metadataLibraryFile = this.libraryFiles.find(lf => lf.metadata.path === filePathToPOSIX(metadataFilePath))
|
||||||
|
if (storeMetadataWithItem) {
|
||||||
|
if (!metadataLibraryFile) {
|
||||||
|
const newLibraryFile = new LibraryFile()
|
||||||
|
await newLibraryFile.setDataFromPath(metadataFilePath, `metadata.json`)
|
||||||
|
metadataLibraryFile = newLibraryFile.toJSON()
|
||||||
|
this.libraryFiles.push(metadataLibraryFile)
|
||||||
|
} else {
|
||||||
|
const fileTimestamps = await getFileTimestampsWithIno(metadataFilePath)
|
||||||
|
if (fileTimestamps) {
|
||||||
|
metadataLibraryFile.metadata.mtimeMs = fileTimestamps.mtimeMs
|
||||||
|
metadataLibraryFile.metadata.ctimeMs = fileTimestamps.ctimeMs
|
||||||
|
metadataLibraryFile.metadata.size = fileTimestamps.size
|
||||||
|
metadataLibraryFile.ino = fileTimestamps.ino
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const libraryItemDirTimestamps = await getFileTimestampsWithIno(this.path)
|
||||||
|
if (libraryItemDirTimestamps) {
|
||||||
|
this.mtime = libraryItemDirTimestamps.mtimeMs
|
||||||
|
this.ctime = libraryItemDirTimestamps.ctimeMs
|
||||||
|
let size = 0
|
||||||
|
this.libraryFiles.forEach((lf) => size += (!isNaN(lf.metadata.size) ? Number(lf.metadata.size) : 0))
|
||||||
|
this.size = size
|
||||||
|
await this.save()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.debug(`Success saving abmetadata to "${metadataFilePath}"`)
|
||||||
|
|
||||||
|
return metadataLibraryFile
|
||||||
|
}).catch((error) => {
|
||||||
|
Logger.error(`Failed to save json file at "${metadataFilePath}"`, error)
|
||||||
|
return null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize model
|
* Initialize model
|
||||||
* @param {import('../Database').sequelize} sequelize
|
* @param {import('../Database').sequelize} sequelize
|
||||||
|
@ -34,6 +34,10 @@ module.exports = {
|
|||||||
attributes: ['sequence']
|
attributes: ['sequence']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
order: [
|
||||||
|
[Database.authorModel, Database.bookAuthorModel, 'createdAt', 'ASC'],
|
||||||
|
[Database.seriesModel, 'bookSeries', 'createdAt', 'ASC']
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
for (const book of booksWithTag) {
|
for (const book of booksWithTag) {
|
||||||
@ -68,7 +72,7 @@ module.exports = {
|
|||||||
/**
|
/**
|
||||||
* Get all library items that have genres
|
* Get all library items that have genres
|
||||||
* @param {string[]} genres
|
* @param {string[]} genres
|
||||||
* @returns {Promise<LibraryItem[]>}
|
* @returns {Promise<import('../../models/LibraryItem')[]>}
|
||||||
*/
|
*/
|
||||||
async getAllLibraryItemsWithGenres(genres) {
|
async getAllLibraryItemsWithGenres(genres) {
|
||||||
const libraryItems = []
|
const libraryItems = []
|
||||||
|
Loading…
Reference in New Issue
Block a user