mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-06-04 09:50:42 +02:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e56b8edc0a | |||
| 8ab0a0a14d | |||
| 4e01722ba6 | |||
| 87eaacea22 | |||
| 3ad4f05449 | |||
| 817be40959 | |||
| d18592eaeb | |||
| 0aae672e19 | |||
| cfd9a01da7 | |||
| 19cf3bfb9f | |||
| 8b39b01269 | |||
| f7849d2956 |
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "audiobookshelf-client",
|
"name": "audiobookshelf-client",
|
||||||
"version": "2.4.2",
|
"version": "2.4.3",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "audiobookshelf-client",
|
"name": "audiobookshelf-client",
|
||||||
"version": "2.4.2",
|
"version": "2.4.3",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxtjs/axios": "^5.13.6",
|
"@nuxtjs/axios": "^5.13.6",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "audiobookshelf-client",
|
"name": "audiobookshelf-client",
|
||||||
"version": "2.4.2",
|
"version": "2.4.3",
|
||||||
"description": "Self-hosted audiobook and podcast client",
|
"description": "Self-hosted audiobook and podcast client",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "audiobookshelf",
|
"name": "audiobookshelf",
|
||||||
"version": "2.4.2",
|
"version": "2.4.3",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "audiobookshelf",
|
"name": "audiobookshelf",
|
||||||
"version": "2.4.2",
|
"version": "2.4.3",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "audiobookshelf",
|
"name": "audiobookshelf",
|
||||||
"version": "2.4.2",
|
"version": "2.4.3",
|
||||||
"description": "Self-hosted audiobook and podcast server",
|
"description": "Self-hosted audiobook and podcast server",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
+15
-3
@@ -666,7 +666,11 @@ class Database {
|
|||||||
async cleanDatabase() {
|
async cleanDatabase() {
|
||||||
// Remove invalid Podcast records
|
// Remove invalid Podcast records
|
||||||
const podcastsWithNoLibraryItem = await this.podcastModel.findAll({
|
const podcastsWithNoLibraryItem = await this.podcastModel.findAll({
|
||||||
where: Sequelize.where(Sequelize.literal(`(SELECT count(*) FROM libraryItems li WHERE li.mediaId = podcast.id)`), 0)
|
include: {
|
||||||
|
model: this.libraryItemModel,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
where: { '$libraryItem.id$': null }
|
||||||
})
|
})
|
||||||
for (const podcast of podcastsWithNoLibraryItem) {
|
for (const podcast of podcastsWithNoLibraryItem) {
|
||||||
Logger.warn(`Found podcast "${podcast.title}" with no libraryItem - removing it`)
|
Logger.warn(`Found podcast "${podcast.title}" with no libraryItem - removing it`)
|
||||||
@@ -675,7 +679,11 @@ class Database {
|
|||||||
|
|
||||||
// Remove invalid Book records
|
// Remove invalid Book records
|
||||||
const booksWithNoLibraryItem = await this.bookModel.findAll({
|
const booksWithNoLibraryItem = await this.bookModel.findAll({
|
||||||
where: Sequelize.where(Sequelize.literal(`(SELECT count(*) FROM libraryItems li WHERE li.mediaId = book.id)`), 0)
|
include: {
|
||||||
|
model: this.libraryItemModel,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
where: { '$libraryItem.id$': null }
|
||||||
})
|
})
|
||||||
for (const book of booksWithNoLibraryItem) {
|
for (const book of booksWithNoLibraryItem) {
|
||||||
Logger.warn(`Found book "${book.title}" with no libraryItem - removing it`)
|
Logger.warn(`Found book "${book.title}" with no libraryItem - removing it`)
|
||||||
@@ -684,7 +692,11 @@ class Database {
|
|||||||
|
|
||||||
// Remove empty series
|
// Remove empty series
|
||||||
const emptySeries = await this.seriesModel.findAll({
|
const emptySeries = await this.seriesModel.findAll({
|
||||||
where: Sequelize.where(Sequelize.literal(`(SELECT count(*) FROM bookSeries bs WHERE bs.seriesId = series.id)`), 0)
|
include: {
|
||||||
|
model: this.bookSeriesModel,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
where: { '$bookSeries.id$': null }
|
||||||
})
|
})
|
||||||
for (const series of emptySeries) {
|
for (const series of emptySeries) {
|
||||||
Logger.warn(`Found series "${series.name}" with no books - removing it`)
|
Logger.warn(`Found series "${series.name}" with no books - removing it`)
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ class PlaylistController {
|
|||||||
|
|
||||||
await Database.createPlaylistMediaItem(playlistMediaItem)
|
await Database.createPlaylistMediaItem(playlistMediaItem)
|
||||||
const jsonExpanded = await req.playlist.getOldJsonExpanded()
|
const jsonExpanded = await req.playlist.getOldJsonExpanded()
|
||||||
SocketAuthority.clientEmitter(playlist.userId, 'playlist_updated', jsonExpanded)
|
SocketAuthority.clientEmitter(jsonExpanded.userId, 'playlist_updated', jsonExpanded)
|
||||||
res.json(jsonExpanded)
|
res.json(jsonExpanded)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,9 +376,9 @@ class PlaylistController {
|
|||||||
if (!numMediaItems) {
|
if (!numMediaItems) {
|
||||||
Logger.info(`[PlaylistController] Playlist "${req.playlist.name}" has no more items - removing it`)
|
Logger.info(`[PlaylistController] Playlist "${req.playlist.name}" has no more items - removing it`)
|
||||||
await req.playlist.destroy()
|
await req.playlist.destroy()
|
||||||
SocketAuthority.clientEmitter(playlist.userId, 'playlist_removed', jsonExpanded)
|
SocketAuthority.clientEmitter(jsonExpanded.userId, 'playlist_removed', jsonExpanded)
|
||||||
} else {
|
} else {
|
||||||
SocketAuthority.clientEmitter(playlist.userId, 'playlist_updated', jsonExpanded)
|
SocketAuthority.clientEmitter(jsonExpanded.userId, 'playlist_updated', jsonExpanded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res.json(jsonExpanded)
|
res.json(jsonExpanded)
|
||||||
|
|||||||
@@ -229,38 +229,6 @@ class CoverManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveEmbeddedCoverArt(libraryItem) {
|
|
||||||
let audioFileWithCover = null
|
|
||||||
if (libraryItem.mediaType === 'book') {
|
|
||||||
audioFileWithCover = libraryItem.media.audioFiles.find(af => af.embeddedCoverArt)
|
|
||||||
} else if (libraryItem.mediaType == 'podcast') {
|
|
||||||
const episodeWithCover = libraryItem.media.episodes.find(ep => ep.audioFile.embeddedCoverArt)
|
|
||||||
if (episodeWithCover) audioFileWithCover = episodeWithCover.audioFile
|
|
||||||
} else if (libraryItem.mediaType === 'music') {
|
|
||||||
audioFileWithCover = libraryItem.media.audioFile
|
|
||||||
}
|
|
||||||
if (!audioFileWithCover) return false
|
|
||||||
|
|
||||||
const coverDirPath = this.getCoverDirectory(libraryItem)
|
|
||||||
await fs.ensureDir(coverDirPath)
|
|
||||||
|
|
||||||
const coverFilename = audioFileWithCover.embeddedCoverArt === 'png' ? 'cover.png' : 'cover.jpg'
|
|
||||||
const coverFilePath = Path.join(coverDirPath, coverFilename)
|
|
||||||
|
|
||||||
const coverAlreadyExists = await fs.pathExists(coverFilePath)
|
|
||||||
if (coverAlreadyExists) {
|
|
||||||
Logger.warn(`[CoverManager] Extract embedded cover art but cover already exists for "${libraryItem.media.metadata.title}" - bail`)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
const success = await extractCoverArt(audioFileWithCover.metadata.path, coverFilePath)
|
|
||||||
if (success) {
|
|
||||||
libraryItem.updateMediaCover(coverFilePath)
|
|
||||||
return coverFilePath
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract cover art from audio file and save for library item
|
* Extract cover art from audio file and save for library item
|
||||||
* @param {import('../models/Book').AudioFileObject[]} audioFiles
|
* @param {import('../models/Book').AudioFileObject[]} audioFiles
|
||||||
@@ -268,7 +236,7 @@ class CoverManager {
|
|||||||
* @param {string} [libraryItemPath] null for isFile library items
|
* @param {string} [libraryItemPath] null for isFile library items
|
||||||
* @returns {Promise<string>} returns cover path
|
* @returns {Promise<string>} returns cover path
|
||||||
*/
|
*/
|
||||||
async saveEmbeddedCoverArtNew(audioFiles, libraryItemId, libraryItemPath) {
|
async saveEmbeddedCoverArt(audioFiles, libraryItemId, libraryItemPath) {
|
||||||
let audioFileWithCover = audioFiles.find(af => af.embeddedCoverArt)
|
let audioFileWithCover = audioFiles.find(af => af.embeddedCoverArt)
|
||||||
if (!audioFileWithCover) return null
|
if (!audioFileWithCover) return null
|
||||||
|
|
||||||
@@ -291,6 +259,7 @@ class CoverManager {
|
|||||||
|
|
||||||
const success = await extractCoverArt(audioFileWithCover.metadata.path, coverFilePath)
|
const success = await extractCoverArt(audioFileWithCover.metadata.path, coverFilePath)
|
||||||
if (success) {
|
if (success) {
|
||||||
|
await CacheManager.purgeCoverCache(libraryItemId)
|
||||||
return coverFilePath
|
return coverFilePath
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const { DataTypes, Model, literal } = require('sequelize')
|
const { DataTypes, Model, where, fn, col } = require('sequelize')
|
||||||
|
|
||||||
const oldAuthor = require('../objects/entities/Author')
|
const oldAuthor = require('../objects/entities/Author')
|
||||||
|
|
||||||
@@ -114,14 +114,11 @@ class Author extends Model {
|
|||||||
static async getOldByNameAndLibrary(authorName, libraryId) {
|
static async getOldByNameAndLibrary(authorName, libraryId) {
|
||||||
const author = (await this.findOne({
|
const author = (await this.findOne({
|
||||||
where: [
|
where: [
|
||||||
literal(`name = ':authorName' COLLATE NOCASE`),
|
where(fn('lower', col('name')), authorName.toLowerCase()),
|
||||||
{
|
{
|
||||||
libraryId
|
libraryId
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
replacements: {
|
|
||||||
authorName
|
|
||||||
}
|
|
||||||
}))?.getOldAuthor()
|
}))?.getOldAuthor()
|
||||||
return author
|
return author
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -536,7 +536,7 @@ class LibraryItem extends Model {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Logger.debug(`Loaded ${itemsInProgressPayload.items.length} of ${itemsInProgressPayload.count} items for "Continue Listening/Reading" in ${((Date.now() - fullStart) / 1000).toFixed(2)}s`)
|
Logger.dev(`Loaded ${itemsInProgressPayload.items.length} of ${itemsInProgressPayload.count} items for "Continue Listening/Reading" in ${((Date.now() - fullStart) / 1000).toFixed(2)}s`)
|
||||||
|
|
||||||
let start = Date.now()
|
let start = Date.now()
|
||||||
if (library.isBook) {
|
if (library.isBook) {
|
||||||
@@ -553,7 +553,7 @@ class LibraryItem extends Model {
|
|||||||
total: continueSeriesPayload.count
|
total: continueSeriesPayload.count
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Logger.debug(`Loaded ${continueSeriesPayload.libraryItems.length} of ${continueSeriesPayload.count} items for "Continue Series" in ${((Date.now() - start) / 1000).toFixed(2)}s`)
|
Logger.dev(`Loaded ${continueSeriesPayload.libraryItems.length} of ${continueSeriesPayload.count} items for "Continue Series" in ${((Date.now() - start) / 1000).toFixed(2)}s`)
|
||||||
} else if (library.isPodcast) {
|
} else if (library.isPodcast) {
|
||||||
// "Newest Episodes" shelf
|
// "Newest Episodes" shelf
|
||||||
const newestEpisodesPayload = await libraryFilters.getNewestPodcastEpisodes(library, user, limit)
|
const newestEpisodesPayload = await libraryFilters.getNewestPodcastEpisodes(library, user, limit)
|
||||||
@@ -567,7 +567,7 @@ class LibraryItem extends Model {
|
|||||||
total: newestEpisodesPayload.count
|
total: newestEpisodesPayload.count
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Logger.debug(`Loaded ${newestEpisodesPayload.libraryItems.length} of ${newestEpisodesPayload.count} episodes for "Newest Episodes" in ${((Date.now() - start) / 1000).toFixed(2)}s`)
|
Logger.dev(`Loaded ${newestEpisodesPayload.libraryItems.length} of ${newestEpisodesPayload.count} episodes for "Newest Episodes" in ${((Date.now() - start) / 1000).toFixed(2)}s`)
|
||||||
}
|
}
|
||||||
|
|
||||||
start = Date.now()
|
start = Date.now()
|
||||||
@@ -583,7 +583,7 @@ class LibraryItem extends Model {
|
|||||||
total: mostRecentPayload.count
|
total: mostRecentPayload.count
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Logger.debug(`Loaded ${mostRecentPayload.libraryItems.length} of ${mostRecentPayload.count} items for "Recently Added" in ${((Date.now() - start) / 1000).toFixed(2)}s`)
|
Logger.dev(`Loaded ${mostRecentPayload.libraryItems.length} of ${mostRecentPayload.count} items for "Recently Added" in ${((Date.now() - start) / 1000).toFixed(2)}s`)
|
||||||
|
|
||||||
if (library.isBook) {
|
if (library.isBook) {
|
||||||
start = Date.now()
|
start = Date.now()
|
||||||
@@ -599,7 +599,7 @@ class LibraryItem extends Model {
|
|||||||
total: seriesMostRecentPayload.count
|
total: seriesMostRecentPayload.count
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Logger.debug(`Loaded ${seriesMostRecentPayload.series.length} of ${seriesMostRecentPayload.count} series for "Recent Series" in ${((Date.now() - start) / 1000).toFixed(2)}s`)
|
Logger.dev(`Loaded ${seriesMostRecentPayload.series.length} of ${seriesMostRecentPayload.count} series for "Recent Series" in ${((Date.now() - start) / 1000).toFixed(2)}s`)
|
||||||
|
|
||||||
start = Date.now()
|
start = Date.now()
|
||||||
// "Discover" shelf
|
// "Discover" shelf
|
||||||
@@ -614,7 +614,7 @@ class LibraryItem extends Model {
|
|||||||
total: discoverLibraryItemsPayload.count
|
total: discoverLibraryItemsPayload.count
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Logger.debug(`Loaded ${discoverLibraryItemsPayload.libraryItems.length} of ${discoverLibraryItemsPayload.count} items for "Discover" in ${((Date.now() - start) / 1000).toFixed(2)}s`)
|
Logger.dev(`Loaded ${discoverLibraryItemsPayload.libraryItems.length} of ${discoverLibraryItemsPayload.count} items for "Discover" in ${((Date.now() - start) / 1000).toFixed(2)}s`)
|
||||||
}
|
}
|
||||||
|
|
||||||
start = Date.now()
|
start = Date.now()
|
||||||
@@ -645,7 +645,7 @@ class LibraryItem extends Model {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Logger.debug(`Loaded ${mediaFinishedPayload.items.length} of ${mediaFinishedPayload.count} items for "Listen/Read Again" in ${((Date.now() - start) / 1000).toFixed(2)}s`)
|
Logger.dev(`Loaded ${mediaFinishedPayload.items.length} of ${mediaFinishedPayload.count} items for "Listen/Read Again" in ${((Date.now() - start) / 1000).toFixed(2)}s`)
|
||||||
|
|
||||||
if (library.isBook) {
|
if (library.isBook) {
|
||||||
start = Date.now()
|
start = Date.now()
|
||||||
@@ -661,7 +661,7 @@ class LibraryItem extends Model {
|
|||||||
total: newestAuthorsPayload.count
|
total: newestAuthorsPayload.count
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Logger.debug(`Loaded ${newestAuthorsPayload.authors.length} of ${newestAuthorsPayload.count} authors for "Newest Authors" in ${((Date.now() - start) / 1000).toFixed(2)}s`)
|
Logger.dev(`Loaded ${newestAuthorsPayload.authors.length} of ${newestAuthorsPayload.count} authors for "Newest Authors" in ${((Date.now() - start) / 1000).toFixed(2)}s`)
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.debug(`Loaded ${shelves.length} personalized shelves in ${((Date.now() - fullStart) / 1000).toFixed(2)}s`)
|
Logger.debug(`Loaded ${shelves.length} personalized shelves in ${((Date.now() - fullStart) / 1000).toFixed(2)}s`)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const { DataTypes, Model, literal } = require('sequelize')
|
const { DataTypes, Model, where, fn, col } = require('sequelize')
|
||||||
|
|
||||||
const oldSeries = require('../objects/entities/Series')
|
const oldSeries = require('../objects/entities/Series')
|
||||||
|
|
||||||
@@ -105,14 +105,11 @@ class Series extends Model {
|
|||||||
static async getOldByNameAndLibrary(seriesName, libraryId) {
|
static async getOldByNameAndLibrary(seriesName, libraryId) {
|
||||||
const series = (await this.findOne({
|
const series = (await this.findOne({
|
||||||
where: [
|
where: [
|
||||||
literal(`name = ':seriesName' COLLATE NOCASE`),
|
where(fn('lower', col('name')), seriesName.toLowerCase()),
|
||||||
{
|
{
|
||||||
libraryId
|
libraryId
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
replacements: {
|
|
||||||
seriesName
|
|
||||||
}
|
|
||||||
}))?.getOldSeries()
|
}))?.getOldSeries()
|
||||||
return series
|
return series
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -553,13 +553,17 @@ class ApiRouter {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mediaMetadata.authors[i].id?.startsWith('new')) {
|
||||||
|
mediaMetadata.authors[i].id = null
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure the ID for the author exists
|
// Ensure the ID for the author exists
|
||||||
if (mediaMetadata.authors[i].id && !(await Database.checkAuthorExists(libraryId, mediaMetadata.authors[i].id))) {
|
if (mediaMetadata.authors[i].id && !(await Database.checkAuthorExists(libraryId, mediaMetadata.authors[i].id))) {
|
||||||
Logger.warn(`[ApiRouter] Author id "${mediaMetadata.authors[i].id}" does not exist`)
|
Logger.warn(`[ApiRouter] Author id "${mediaMetadata.authors[i].id}" does not exist`)
|
||||||
mediaMetadata.authors[i].id = null
|
mediaMetadata.authors[i].id = null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mediaMetadata.authors[i].id || mediaMetadata.authors[i].id.startsWith('new')) {
|
if (!mediaMetadata.authors[i].id) {
|
||||||
let author = await Database.authorModel.getOldByNameAndLibrary(authorName, libraryId)
|
let author = await Database.authorModel.getOldByNameAndLibrary(authorName, libraryId)
|
||||||
if (!author) {
|
if (!author) {
|
||||||
author = new Author()
|
author = new Author()
|
||||||
@@ -590,13 +594,17 @@ class ApiRouter {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mediaMetadata.series[i].id?.startsWith('new')) {
|
||||||
|
mediaMetadata.series[i].id = null
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure the ID for the series exists
|
// Ensure the ID for the series exists
|
||||||
if (mediaMetadata.series[i].id && !(await Database.checkSeriesExists(libraryId, mediaMetadata.series[i].id))) {
|
if (mediaMetadata.series[i].id && !(await Database.checkSeriesExists(libraryId, mediaMetadata.series[i].id))) {
|
||||||
Logger.warn(`[ApiRouter] Series id "${mediaMetadata.series[i].id}" does not exist`)
|
Logger.warn(`[ApiRouter] Series id "${mediaMetadata.series[i].id}" does not exist`)
|
||||||
mediaMetadata.series[i].id = null
|
mediaMetadata.series[i].id = null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mediaMetadata.series[i].id || mediaMetadata.series[i].id.startsWith('new')) {
|
if (!mediaMetadata.series[i].id) {
|
||||||
let seriesItem = await Database.seriesModel.getOldByNameAndLibrary(seriesName, libraryId)
|
let seriesItem = await Database.seriesModel.getOldByNameAndLibrary(seriesName, libraryId)
|
||||||
if (!seriesItem) {
|
if (!seriesItem) {
|
||||||
seriesItem = new Series()
|
seriesItem = new Series()
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ class BookScanner {
|
|||||||
// If no cover then extract cover from audio file if available OR search for cover if enabled in server settings
|
// If no cover then extract cover from audio file if available OR search for cover if enabled in server settings
|
||||||
if (!media.coverPath) {
|
if (!media.coverPath) {
|
||||||
const libraryItemDir = existingLibraryItem.isFile ? null : existingLibraryItem.path
|
const libraryItemDir = existingLibraryItem.isFile ? null : existingLibraryItem.path
|
||||||
const extractedCoverPath = await CoverManager.saveEmbeddedCoverArtNew(media.audioFiles, existingLibraryItem.id, libraryItemDir)
|
const extractedCoverPath = await CoverManager.saveEmbeddedCoverArt(media.audioFiles, existingLibraryItem.id, libraryItemDir)
|
||||||
if (extractedCoverPath) {
|
if (extractedCoverPath) {
|
||||||
libraryScan.addLog(LogLevel.DEBUG, `Updating book "${bookMetadata.title}" extracted embedded cover art from audio file to path "${extractedCoverPath}"`)
|
libraryScan.addLog(LogLevel.DEBUG, `Updating book "${bookMetadata.title}" extracted embedded cover art from audio file to path "${extractedCoverPath}"`)
|
||||||
media.coverPath = extractedCoverPath
|
media.coverPath = extractedCoverPath
|
||||||
@@ -461,7 +461,7 @@ class BookScanner {
|
|||||||
if (!bookObject.coverPath) {
|
if (!bookObject.coverPath) {
|
||||||
const libraryItemDir = libraryItemObj.isFile ? null : libraryItemObj.path
|
const libraryItemDir = libraryItemObj.isFile ? null : libraryItemObj.path
|
||||||
// Extract and save embedded cover art
|
// Extract and save embedded cover art
|
||||||
const extractedCoverPath = await CoverManager.saveEmbeddedCoverArtNew(scannedAudioFiles, libraryItemObj.id, libraryItemDir)
|
const extractedCoverPath = await CoverManager.saveEmbeddedCoverArt(scannedAudioFiles, libraryItemObj.id, libraryItemDir)
|
||||||
if (extractedCoverPath) {
|
if (extractedCoverPath) {
|
||||||
bookObject.coverPath = extractedCoverPath
|
bookObject.coverPath = extractedCoverPath
|
||||||
} else if (Database.serverSettings.scannerFindCovers) {
|
} else if (Database.serverSettings.scannerFindCovers) {
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ class PodcastScanner {
|
|||||||
// If no cover then extract cover from audio file if available
|
// If no cover then extract cover from audio file if available
|
||||||
if (!media.coverPath && existingPodcastEpisodes.length) {
|
if (!media.coverPath && existingPodcastEpisodes.length) {
|
||||||
const audioFiles = existingPodcastEpisodes.map(ep => ep.audioFile)
|
const audioFiles = existingPodcastEpisodes.map(ep => ep.audioFile)
|
||||||
const extractedCoverPath = await CoverManager.saveEmbeddedCoverArtNew(audioFiles, existingLibraryItem.id, existingLibraryItem.path)
|
const extractedCoverPath = await CoverManager.saveEmbeddedCoverArt(audioFiles, existingLibraryItem.id, existingLibraryItem.path)
|
||||||
if (extractedCoverPath) {
|
if (extractedCoverPath) {
|
||||||
libraryScan.addLog(LogLevel.DEBUG, `Updating podcast "${podcastMetadata.title}" extracted embedded cover art from audio file to path "${extractedCoverPath}"`)
|
libraryScan.addLog(LogLevel.DEBUG, `Updating podcast "${podcastMetadata.title}" extracted embedded cover art from audio file to path "${extractedCoverPath}"`)
|
||||||
media.coverPath = extractedCoverPath
|
media.coverPath = extractedCoverPath
|
||||||
@@ -279,7 +279,7 @@ class PodcastScanner {
|
|||||||
// If cover was not found in folder then check embedded covers in audio files
|
// If cover was not found in folder then check embedded covers in audio files
|
||||||
if (!podcastObject.coverPath && scannedAudioFiles.length) {
|
if (!podcastObject.coverPath && scannedAudioFiles.length) {
|
||||||
// Extract and save embedded cover art
|
// Extract and save embedded cover art
|
||||||
podcastObject.coverPath = await CoverManager.saveEmbeddedCoverArtNew(scannedAudioFiles, libraryItemObj.id, libraryItemObj.path)
|
podcastObject.coverPath = await CoverManager.saveEmbeddedCoverArt(scannedAudioFiles, libraryItemObj.id, libraryItemObj.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
libraryItemObj.podcast = podcastObject
|
libraryItemObj.podcast = podcastObject
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ module.exports = (nameToParse, partToReturn, fixCase, stopOnError, useLongLists)
|
|||||||
namePartWords[j].slice(3).toLowerCase();
|
namePartWords[j].slice(3).toLowerCase();
|
||||||
} else if (
|
} else if (
|
||||||
namePartLabels[j] === 'suffix' &&
|
namePartLabels[j] === 'suffix' &&
|
||||||
nameParts[j].slice(-1) !== '.' &&
|
namePartWords[j].slice(-1) !== '.' &&
|
||||||
!suffixList.indexOf(nameParts[j].toLowerCase())
|
!suffixList.indexOf(namePartWords[j].toLowerCase())
|
||||||
) { // Convert suffix abbreviations to UPPER CASE
|
) { // Convert suffix abbreviations to UPPER CASE
|
||||||
if (namePartWords[j] === namePartWords[j].toLowerCase()) {
|
if (namePartWords[j] === namePartWords[j].toLowerCase()) {
|
||||||
namePartWords[j] = namePartWords[j].toUpperCase();
|
namePartWords[j] = namePartWords[j].toUpperCase();
|
||||||
@@ -343,4 +343,4 @@ module.exports = (nameToParse, partToReturn, fixCase, stopOnError, useLongLists)
|
|||||||
|
|
||||||
parsedName = fixParsedNameCase(parsedName, fixCase);
|
parsedName = fixParsedNameCase(parsedName, fixCase);
|
||||||
return partToReturn === 'all' ? parsedName : parsedName[partToReturn];
|
return partToReturn === 'all' ? parsedName : parsedName[partToReturn];
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user