New data model fix library stats

This commit is contained in:
advplyr 2022-03-18 12:37:47 -05:00
parent 57399bb79e
commit eea3e2583c
8 changed files with 69 additions and 33 deletions

View File

@ -44,7 +44,7 @@ class LibraryController {
if (req.query.include && req.query.include === 'filterdata') { if (req.query.include && req.query.include === 'filterdata') {
return res.json({ return res.json({
filterdata: libraryHelpers.getDistinctFilterDataNew(req.libraryItems), filterdata: libraryHelpers.getDistinctFilterDataNew(req.libraryItems),
issues: libraryHelpers.getNumIssues(req.libraryItems), issues: req.libraryItems.filter(li => li.hasIssues).length,
library: req.library library: req.library
}) })
} }
@ -439,7 +439,6 @@ class LibraryController {
async stats(req, res) { async stats(req, res) {
var libraryItems = req.libraryItems var libraryItems = req.libraryItems
var authorsWithCount = libraryHelpers.getAuthorsWithCount(libraryItems) var authorsWithCount = libraryHelpers.getAuthorsWithCount(libraryItems)
var genresWithCount = libraryHelpers.getGenresWithCount(libraryItems) var genresWithCount = libraryHelpers.getGenresWithCount(libraryItems)
var durationStats = libraryHelpers.getItemDurationStats(libraryItems) var durationStats = libraryHelpers.getItemDurationStats(libraryItems)

View File

@ -152,6 +152,10 @@ class LibraryItem {
get hasMediaEntities() { get hasMediaEntities() {
return this.media.hasMediaEntities return this.media.hasMediaEntities
} }
get hasIssues() {
if (this.isMissing || this.isInvalid) return true
return this.media.hasIssues
}
// Data comes from scandir library item data // Data comes from scandir library item data
setData(libraryMediaType, payload) { setData(libraryMediaType, payload) {

View File

@ -43,6 +43,10 @@ class PodcastEpisode {
get tracks() { get tracks() {
return [this.audioFile] return [this.audioFile]
} }
get duration() {
return this.audioFile.duration
}
get size() { return this.audioFile.metadata.size }
// Only checks container format // Only checks container format
checkCanDirectPlay(payload) { checkCanDirectPlay(payload) {

View File

@ -15,7 +15,7 @@ class EBookFile {
construct(file) { construct(file) {
this.ino = file.ino this.ino = file.ino
this.metadata = new FileMetadata(file) this.metadata = new FileMetadata(file.metadata)
this.ebookFormat = file.ebookFormat this.ebookFormat = file.ebookFormat
this.addedAt = file.addedAt this.addedAt = file.addedAt
this.updatedAt = file.updatedAt this.updatedAt = file.updatedAt

View File

@ -72,8 +72,12 @@ class Book {
get size() { get size() {
var total = 0 var total = 0
this.audiobooks.forEach((ab) => total += ab.size) this.audiobooks.forEach((ab) => {
this.ebooks.forEach((eb) => total += eb.size) total += ab.size
})
this.ebooks.forEach((eb) => {
total += eb.size
})
return total return total
} }
get hasMediaEntities() { get hasMediaEntities() {
@ -87,6 +91,9 @@ class Book {
get hasEmbeddedCoverArt() { get hasEmbeddedCoverArt() {
return this.audiobooks.some(ab => ab.hasEmbeddedCoverArt) return this.audiobooks.some(ab => ab.hasEmbeddedCoverArt)
} }
get hasIssues() {
return this.audiobooks.some(ab => ab.missingParts.length)
}
update(payload) { update(payload) {
var json = this.toJSON() var json = this.toJSON()
@ -293,5 +300,24 @@ class Book {
var audiobook = this.getCreateAudiobookVariant(variant) var audiobook = this.getCreateAudiobookVariant(variant)
audiobook.audioFiles.push(audioFile) audiobook.audioFiles.push(audioFile)
} }
getLongestDuration() {
if (!this.audiobooks.length) return 0
var longest = 0
this.audiobooks.forEach((ab) => {
if (ab.duration > longest) longest = ab.duration
})
return longest
}
getTotalAudioTracks() {
var total = 0
this.audiobooks.forEach((ab) => total += ab.tracks.length)
return total
}
getTotalDuration() {
var total = 0
this.audiobooks.forEach((ab) => total += ab.duration)
return total
}
} }
module.exports = Book module.exports = Book

View File

@ -43,8 +43,7 @@ class Podcast {
metadata: this.metadata.toJSON(), metadata: this.metadata.toJSON(),
coverPath: this.coverPath, coverPath: this.coverPath,
tags: [...this.tags], tags: [...this.tags],
episodes: this.episodes.map(e => e.toJSON()), episodes: this.episodes.map(e => e.toJSON())
} }
} }
@ -54,19 +53,14 @@ class Podcast {
metadata: this.metadata.toJSONExpanded(), metadata: this.metadata.toJSONExpanded(),
coverPath: this.coverPath, coverPath: this.coverPath,
tags: [...this.tags], tags: [...this.tags],
episodes: this.episodes.map(e => e.toJSON()), episodes: this.episodes.map(e => e.toJSON())
} }
} }
get tracks() {
return []
}
get duration() {
return 0
}
get size() { get size() {
return 0 var total = 0
this.episodes.forEach((ep) => total += ep.size)
return total
} }
get hasMediaEntities() { get hasMediaEntities() {
return !!this.episodes.length return !!this.episodes.length
@ -77,6 +71,9 @@ class Podcast {
get hasEmbeddedCoverArt() { get hasEmbeddedCoverArt() {
return false return false
} }
get hasIssues() {
return false
}
update(payload) { update(payload) {
var json = this.toJSON() var json = this.toJSON()
@ -105,10 +102,6 @@ class Podcast {
return true return true
} }
checkUpdateMissingTracks() {
return false
}
removeFileWithInode(inode) { removeFileWithInode(inode) {
return false return false
} }
@ -138,5 +131,23 @@ class Podcast {
var payload = this.metadata.searchQuery(query) var payload = this.metadata.searchQuery(query)
return payload || {} return payload || {}
} }
getLongestDuration() {
if (!this.episodes.length) return 0
var longest = 0
this.episodes.forEach((ab) => {
if (ab.duration > longest) longest = ab.duration
})
return longest
}
getTotalAudioTracks() {
return this.episodes.length
}
getTotalDuration() {
var total = 0
this.episodes.forEach((ep) => total += ep.duration)
return total
}
} }
module.exports = Podcast module.exports = Podcast

View File

@ -286,7 +286,7 @@ async function migrateLibraryItems(db) {
sessions = sessions.map(se => { sessions = sessions.map(se => {
var libraryItemWithAudiobook = libraryItems.find(li => li.media.getAudiobookById && !!li.media.getAudiobookById(se.mediaEntityId)) var libraryItemWithAudiobook = libraryItems.find(li => li.media.getAudiobookById && !!li.media.getAudiobookById(se.mediaEntityId))
if (!libraryItemWithAudiobook) { if (!libraryItemWithAudiobook) {
Logger.error('[dbMigration] Failed to find library item with audiobook id', audiobookId) Logger.error('[dbMigration] Failed to find library item with audiobook id', se.mediaEntityId)
return null return null
} }
se.libraryItemId = libraryItemWithAudiobook.id se.libraryItemId = libraryItemWithAudiobook.id

View File

@ -241,13 +241,13 @@ module.exports = {
}, },
getItemDurationStats(libraryItems) { getItemDurationStats(libraryItems) {
var sorted = sort(libraryItems).desc(li => li.media.duration) var sorted = sort(libraryItems).desc(li => li.media.getLongestDuration())
var top10 = sorted.slice(0, 10).map(li => ({ title: li.media.metadata.title, duration: li.media.duration })).filter(i => i.duration > 0) var top10 = sorted.slice(0, 10).map(li => ({ title: li.media.metadata.title, duration: li.media.getLongestDuration() })).filter(i => i.duration > 0)
var totalDuration = 0 var totalDuration = 0
var numAudioTracks = 0 var numAudioTracks = 0
libraryItems.forEach((li) => { libraryItems.forEach((li) => {
totalDuration += li.media.duration totalDuration += li.media.getTotalDuration()
numAudioTracks += (li.media.tracks || []).length numAudioTracks += li.media.getTotalAudioTracks()
}) })
return { return {
totalDuration, totalDuration,
@ -263,12 +263,4 @@ module.exports = {
}) })
return totalSize return totalSize
}, },
getNumIssues(libraryItems) {
// TODO: Implement issues
return libraryItems.filter(li => li.isMissing).length
// return books.filter(ab => {
// return ab.numMissingParts || ab.numInvalidParts || ab.isMissing || ab.isInvalid
// }).length
}
} }