mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-01-03 00:06:46 +01:00
Update Series and Author model to be library specific
This commit is contained in:
parent
1d13d0a553
commit
0ac63b2678
@ -271,12 +271,16 @@ export default {
|
||||
let filterValue = null
|
||||
if (parts.length > 1) {
|
||||
const decoded = this.$decode(parts[1])
|
||||
if (decoded.startsWith('aut_')) {
|
||||
if (parts[0] === 'authors') {
|
||||
const author = this.authors.find((au) => au.id == decoded)
|
||||
if (author) filterValue = author.name
|
||||
} else if (decoded.startsWith('ser_')) {
|
||||
const series = this.series.find((se) => se.id == decoded)
|
||||
if (series) filterValue = series.name
|
||||
} else if (parts[0] === 'series') {
|
||||
if (decoded === 'no-series') {
|
||||
filterValue = this.$strings.MessageNoSeries
|
||||
} else {
|
||||
const series = this.series.find((se) => se.id == decoded)
|
||||
if (series) filterValue = series.name
|
||||
}
|
||||
} else {
|
||||
filterValue = decoded
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ class LibraryItemController {
|
||||
|
||||
// Book specific
|
||||
if (libraryItem.isBook) {
|
||||
await this.createAuthorsAndSeriesForItemUpdate(mediaPayload)
|
||||
await this.createAuthorsAndSeriesForItemUpdate(mediaPayload, libraryItem.libraryId)
|
||||
}
|
||||
|
||||
// Podcast specific
|
||||
@ -342,7 +342,7 @@ class LibraryItemController {
|
||||
var libraryItem = Database.libraryItems.find(_li => _li.id === updatePayloads[i].id)
|
||||
if (!libraryItem) return null
|
||||
|
||||
await this.createAuthorsAndSeriesForItemUpdate(mediaPayload)
|
||||
await this.createAuthorsAndSeriesForItemUpdate(mediaPayload, libraryItem.libraryId)
|
||||
|
||||
var hasUpdates = libraryItem.media.update(mediaPayload)
|
||||
if (hasUpdates) {
|
||||
|
@ -10,7 +10,7 @@ class SeriesController {
|
||||
* /api/series/:id
|
||||
*
|
||||
* TODO: Update mobile app to use /api/libraries/:id/series/:seriesId API route instead
|
||||
* Series are not library specific so we need to know what the library id is
|
||||
* Series are not library specific so we need to know what the library id is
|
||||
*
|
||||
* @param {*} req
|
||||
* @param {*} res
|
||||
|
@ -74,5 +74,9 @@ module.exports = (sequelize) => {
|
||||
modelName: 'author'
|
||||
})
|
||||
|
||||
const { library } = sequelize.models
|
||||
library.hasMany(Author)
|
||||
Author.belongsTo(library)
|
||||
|
||||
return Author
|
||||
}
|
@ -68,5 +68,9 @@ module.exports = (sequelize) => {
|
||||
modelName: 'series'
|
||||
})
|
||||
|
||||
const { library } = sequelize.models
|
||||
library.hasMany(Series)
|
||||
Series.belongsTo(library)
|
||||
|
||||
return Series
|
||||
}
|
@ -11,6 +11,7 @@ class Author {
|
||||
this.imagePath = null
|
||||
this.addedAt = null
|
||||
this.updatedAt = null
|
||||
this.libraryId = null
|
||||
|
||||
if (author) {
|
||||
this.construct(author)
|
||||
@ -25,6 +26,7 @@ class Author {
|
||||
this.imagePath = author.imagePath
|
||||
this.addedAt = author.addedAt
|
||||
this.updatedAt = author.updatedAt
|
||||
this.libraryId = author.libraryId
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
@ -35,7 +37,8 @@ class Author {
|
||||
description: this.description,
|
||||
imagePath: this.imagePath,
|
||||
addedAt: this.addedAt,
|
||||
updatedAt: this.updatedAt
|
||||
updatedAt: this.updatedAt,
|
||||
libraryId: this.libraryId
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,7 +55,7 @@ class Author {
|
||||
}
|
||||
}
|
||||
|
||||
setData(data) {
|
||||
setData(data, libraryId) {
|
||||
this.id = uuidv4()
|
||||
this.name = data.name
|
||||
this.description = data.description || null
|
||||
@ -60,6 +63,7 @@ class Author {
|
||||
this.imagePath = data.imagePath || null
|
||||
this.addedAt = Date.now()
|
||||
this.updatedAt = Date.now()
|
||||
this.libraryId = libraryId
|
||||
}
|
||||
|
||||
update(payload) {
|
||||
|
@ -7,6 +7,7 @@ class Series {
|
||||
this.description = null
|
||||
this.addedAt = null
|
||||
this.updatedAt = null
|
||||
this.libraryId = null
|
||||
|
||||
if (series) {
|
||||
this.construct(series)
|
||||
@ -19,6 +20,7 @@ class Series {
|
||||
this.description = series.description || null
|
||||
this.addedAt = series.addedAt
|
||||
this.updatedAt = series.updatedAt
|
||||
this.libraryId = series.libraryId
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
@ -27,7 +29,8 @@ class Series {
|
||||
name: this.name,
|
||||
description: this.description,
|
||||
addedAt: this.addedAt,
|
||||
updatedAt: this.updatedAt
|
||||
updatedAt: this.updatedAt,
|
||||
libraryId: this.libraryId
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,12 +42,13 @@ class Series {
|
||||
}
|
||||
}
|
||||
|
||||
setData(data) {
|
||||
setData(data, libraryId) {
|
||||
this.id = uuidv4()
|
||||
this.name = data.name
|
||||
this.description = data.description || null
|
||||
this.addedAt = Date.now()
|
||||
this.updatedAt = Date.now()
|
||||
this.libraryId = libraryId
|
||||
}
|
||||
|
||||
update(series) {
|
||||
|
@ -519,7 +519,7 @@ class ApiRouter {
|
||||
return listeningStats
|
||||
}
|
||||
|
||||
async createAuthorsAndSeriesForItemUpdate(mediaPayload) {
|
||||
async createAuthorsAndSeriesForItemUpdate(mediaPayload, libraryId) {
|
||||
if (mediaPayload.metadata) {
|
||||
const mediaMetadata = mediaPayload.metadata
|
||||
|
||||
@ -534,10 +534,10 @@ class ApiRouter {
|
||||
}
|
||||
|
||||
if (!mediaMetadata.authors[i].id || mediaMetadata.authors[i].id.startsWith('new')) {
|
||||
let author = Database.authors.find(au => au.checkNameEquals(authorName))
|
||||
let author = Database.authors.find(au => au.libraryId === libraryId && au.checkNameEquals(authorName))
|
||||
if (!author) {
|
||||
author = new Author()
|
||||
author.setData(mediaMetadata.authors[i])
|
||||
author.setData(mediaMetadata.authors[i], libraryId)
|
||||
Logger.debug(`[ApiRouter] Created new author "${author.name}"`)
|
||||
newAuthors.push(author)
|
||||
}
|
||||
@ -563,10 +563,10 @@ class ApiRouter {
|
||||
}
|
||||
|
||||
if (!mediaMetadata.series[i].id || mediaMetadata.series[i].id.startsWith('new')) {
|
||||
let seriesItem = Database.series.find(se => se.checkNameEquals(seriesName))
|
||||
let seriesItem = Database.series.find(se => se.libraryId === libraryId && se.checkNameEquals(seriesName))
|
||||
if (!seriesItem) {
|
||||
seriesItem = new Series()
|
||||
seriesItem.setData(mediaMetadata.series[i])
|
||||
seriesItem.setData(mediaMetadata.series[i], libraryId)
|
||||
Logger.debug(`[ApiRouter] Created new series "${seriesItem.name}"`)
|
||||
newSeries.push(seriesItem)
|
||||
}
|
||||
|
@ -477,13 +477,13 @@ class Scanner {
|
||||
|
||||
// Create or match all new authors and series
|
||||
if (libraryItem.media.metadata.authors.some(au => au.id.startsWith('new'))) {
|
||||
var newAuthors = []
|
||||
const newAuthors = []
|
||||
libraryItem.media.metadata.authors = libraryItem.media.metadata.authors.map((tempMinAuthor) => {
|
||||
var _author = Database.authors.find(au => au.checkNameEquals(tempMinAuthor.name))
|
||||
if (!_author) _author = newAuthors.find(au => au.checkNameEquals(tempMinAuthor.name)) // Check new unsaved authors
|
||||
let _author = Database.authors.find(au => au.libraryId === libraryItem.libraryId && au.checkNameEquals(tempMinAuthor.name))
|
||||
if (!_author) _author = newAuthors.find(au => au.libraryId === libraryItem.libraryId && au.checkNameEquals(tempMinAuthor.name)) // Check new unsaved authors
|
||||
if (!_author) { // Must create new author
|
||||
_author = new Author()
|
||||
_author.setData(tempMinAuthor)
|
||||
_author.setData(tempMinAuthor, libraryItem.libraryId)
|
||||
newAuthors.push(_author)
|
||||
}
|
||||
|
||||
@ -498,13 +498,13 @@ class Scanner {
|
||||
}
|
||||
}
|
||||
if (libraryItem.media.metadata.series.some(se => se.id.startsWith('new'))) {
|
||||
var newSeries = []
|
||||
const newSeries = []
|
||||
libraryItem.media.metadata.series = libraryItem.media.metadata.series.map((tempMinSeries) => {
|
||||
var _series = Database.series.find(se => se.checkNameEquals(tempMinSeries.name))
|
||||
if (!_series) _series = newSeries.find(se => se.checkNameEquals(tempMinSeries.name)) // Check new unsaved series
|
||||
let _series = Database.series.find(se => se.libraryId === libraryItem.libraryId && se.checkNameEquals(tempMinSeries.name))
|
||||
if (!_series) _series = newSeries.find(se => se.libraryId === libraryItem.libraryId && se.checkNameEquals(tempMinSeries.name)) // Check new unsaved series
|
||||
if (!_series) { // Must create new series
|
||||
_series = new Series()
|
||||
_series.setData(tempMinSeries)
|
||||
_series.setData(tempMinSeries, libraryItem.libraryId)
|
||||
newSeries.push(_series)
|
||||
}
|
||||
return {
|
||||
@ -877,12 +877,11 @@ class Scanner {
|
||||
matchData.author = matchData.author.split(',').map(au => au.trim()).filter(au => !!au)
|
||||
}
|
||||
const authorPayload = []
|
||||
for (let index = 0; index < matchData.author.length; index++) {
|
||||
const authorName = matchData.author[index]
|
||||
var author = Database.authors.find(au => au.checkNameEquals(authorName))
|
||||
for (const authorName of matchData.author) {
|
||||
let author = Database.authors.find(au => au.libraryId === libraryItem.libraryId && au.checkNameEquals(authorName))
|
||||
if (!author) {
|
||||
author = new Author()
|
||||
author.setData({ name: authorName })
|
||||
author.setData({ name: authorName }, libraryItem.libraryId)
|
||||
await Database.createAuthor(author)
|
||||
SocketAuthority.emitter('author_added', author.toJSON())
|
||||
}
|
||||
@ -895,12 +894,11 @@ class Scanner {
|
||||
if (matchData.series && (!libraryItem.media.metadata.seriesName || options.overrideDetails)) {
|
||||
if (!Array.isArray(matchData.series)) matchData.series = [{ series: matchData.series, sequence: matchData.sequence }]
|
||||
const seriesPayload = []
|
||||
for (let index = 0; index < matchData.series.length; index++) {
|
||||
const seriesMatchItem = matchData.series[index]
|
||||
var seriesItem = Database.series.find(au => au.checkNameEquals(seriesMatchItem.series))
|
||||
for (const seriesMatchItem of matchData.series) {
|
||||
let seriesItem = Database.series.find(se => se.libraryId === libraryItem.libraryId && se.checkNameEquals(seriesMatchItem.series))
|
||||
if (!seriesItem) {
|
||||
seriesItem = new Series()
|
||||
seriesItem.setData({ name: seriesMatchItem.series })
|
||||
seriesItem.setData({ name: seriesMatchItem.series }, libraryItem.libraryId)
|
||||
await Database.createSeries(seriesItem)
|
||||
SocketAuthority.emitter('series_added', seriesItem.toJSON())
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ const oldDbIdMap = {
|
||||
libraries: {},
|
||||
libraryFolders: {},
|
||||
libraryItems: {},
|
||||
authors: {},
|
||||
series: {},
|
||||
authors: {}, // key is (new) library id with another map of author ids
|
||||
series: {}, // key is (new) library id with another map of series ids
|
||||
collections: {},
|
||||
podcastEpisodes: {},
|
||||
books: {}, // key is library item id
|
||||
@ -98,10 +98,10 @@ function migrateBook(oldLibraryItem, LibraryItem) {
|
||||
// Migrate BookAuthors
|
||||
//
|
||||
for (const oldBookAuthor of oldBook.metadata.authors) {
|
||||
if (oldDbIdMap.authors[oldBookAuthor.id]) {
|
||||
if (oldDbIdMap.authors[LibraryItem.libraryId][oldBookAuthor.id]) {
|
||||
newRecords.bookAuthor.push({
|
||||
id: uuidv4(),
|
||||
authorId: oldDbIdMap.authors[oldBookAuthor.id],
|
||||
authorId: oldDbIdMap.authors[LibraryItem.libraryId][oldBookAuthor.id],
|
||||
bookId: Book.id
|
||||
})
|
||||
} else {
|
||||
@ -113,11 +113,11 @@ function migrateBook(oldLibraryItem, LibraryItem) {
|
||||
// Migrate BookSeries
|
||||
//
|
||||
for (const oldBookSeries of oldBook.metadata.series) {
|
||||
if (oldDbIdMap.series[oldBookSeries.id]) {
|
||||
if (oldDbIdMap.series[LibraryItem.libraryId][oldBookSeries.id]) {
|
||||
const BookSeries = {
|
||||
id: uuidv4(),
|
||||
sequence: oldBookSeries.sequence,
|
||||
seriesId: oldDbIdMap.series[oldBookSeries.id],
|
||||
seriesId: oldDbIdMap.series[LibraryItem.libraryId][oldBookSeries.id],
|
||||
bookId: Book.id
|
||||
}
|
||||
newRecords.bookSeries.push(BookSeries)
|
||||
@ -297,33 +297,66 @@ function migrateLibraries(oldLibraries) {
|
||||
}
|
||||
}
|
||||
|
||||
function migrateAuthors(oldAuthors) {
|
||||
function migrateAuthors(oldAuthors, oldLibraryItems) {
|
||||
for (const oldAuthor of oldAuthors) {
|
||||
const Author = {
|
||||
id: uuidv4(),
|
||||
name: oldAuthor.name,
|
||||
asin: oldAuthor.asin || null,
|
||||
description: oldAuthor.description,
|
||||
imagePath: oldAuthor.imagePath,
|
||||
createdAt: oldAuthor.addedAt || Date.now(),
|
||||
updatedAt: oldAuthor.updatedAt || Date.now()
|
||||
// Get an array of NEW library ids that have this author
|
||||
const librariesWithThisAuthor = [...new Set(oldLibraryItems.map(li => {
|
||||
if (!li.media.metadata.authors?.some(au => au.id === oldAuthor.id)) return null
|
||||
if (!oldDbIdMap.libraries[li.libraryId]) {
|
||||
Logger.warn(`[dbMigration] Authors library id ${li.libraryId} was not migrated`)
|
||||
}
|
||||
return oldDbIdMap.libraries[li.libraryId]
|
||||
}).filter(lid => lid))]
|
||||
|
||||
if (!librariesWithThisAuthor.length) {
|
||||
Logger.error(`[dbMigration] Author ${oldAuthor.name} was not found in any libraries`)
|
||||
}
|
||||
|
||||
for (const libraryId of librariesWithThisAuthor) {
|
||||
const Author = {
|
||||
id: uuidv4(),
|
||||
name: oldAuthor.name,
|
||||
asin: oldAuthor.asin || null,
|
||||
description: oldAuthor.description,
|
||||
imagePath: oldAuthor.imagePath,
|
||||
createdAt: oldAuthor.addedAt || Date.now(),
|
||||
updatedAt: oldAuthor.updatedAt || Date.now(),
|
||||
libraryId
|
||||
}
|
||||
if (!oldDbIdMap.authors[libraryId]) oldDbIdMap.authors[libraryId] = {}
|
||||
oldDbIdMap.authors[libraryId][oldAuthor.id] = Author.id
|
||||
newRecords.author.push(Author)
|
||||
}
|
||||
oldDbIdMap.authors[oldAuthor.id] = Author.id
|
||||
newRecords.author.push(Author)
|
||||
}
|
||||
}
|
||||
|
||||
function migrateSeries(oldSerieses) {
|
||||
function migrateSeries(oldSerieses, oldLibraryItems) {
|
||||
// Originaly series were shared between libraries if they had the same name
|
||||
// Series will be separate between libraries
|
||||
for (const oldSeries of oldSerieses) {
|
||||
const Series = {
|
||||
id: uuidv4(),
|
||||
name: oldSeries.name,
|
||||
description: oldSeries.description || null,
|
||||
createdAt: oldSeries.addedAt || Date.now(),
|
||||
updatedAt: oldSeries.updatedAt || Date.now()
|
||||
// Get an array of NEW library ids that have this series
|
||||
const librariesWithThisSeries = [...new Set(oldLibraryItems.map(li => {
|
||||
if (!li.media.metadata.series?.some(se => se.id === oldSeries.id)) return null
|
||||
return oldDbIdMap.libraries[li.libraryId]
|
||||
}).filter(lid => lid))]
|
||||
|
||||
if (!librariesWithThisSeries.length) {
|
||||
Logger.error(`[dbMigration] Series ${oldSeries.name} was not found in any libraries`)
|
||||
}
|
||||
|
||||
for (const libraryId of librariesWithThisSeries) {
|
||||
const Series = {
|
||||
id: uuidv4(),
|
||||
name: oldSeries.name,
|
||||
description: oldSeries.description || null,
|
||||
createdAt: oldSeries.addedAt || Date.now(),
|
||||
updatedAt: oldSeries.updatedAt || Date.now(),
|
||||
libraryId
|
||||
}
|
||||
if (!oldDbIdMap.series[libraryId]) oldDbIdMap.series[libraryId] = {}
|
||||
oldDbIdMap.series[libraryId][oldSeries.id] = Series.id
|
||||
newRecords.series.push(Series)
|
||||
}
|
||||
oldDbIdMap.series[oldSeries.id] = Series.id
|
||||
newRecords.series.push(Series)
|
||||
}
|
||||
}
|
||||
|
||||
@ -615,7 +648,14 @@ function migrateFeeds(oldFeeds) {
|
||||
} else if (oldFeed.entityType === 'libraryItem') {
|
||||
entityId = oldDbIdMap.libraryItems[oldFeed.entityId]
|
||||
} else if (oldFeed.entityType === 'series') {
|
||||
entityId = oldDbIdMap.series[oldFeed.entityId]
|
||||
// Series were split to be per library
|
||||
// This will use the first series it finds
|
||||
for (const libraryId in oldDbIdMap.series) {
|
||||
if (oldDbIdMap.series[libraryId][oldFeed.entityId]) {
|
||||
entityId = oldDbIdMap.series[libraryId][oldFeed.entityId]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!entityId) {
|
||||
@ -719,9 +759,9 @@ module.exports.migrate = async (DatabaseModels) => {
|
||||
|
||||
const start = Date.now()
|
||||
migrateSettings(data.settings)
|
||||
migrateAuthors(data.authors)
|
||||
migrateSeries(data.series)
|
||||
migrateLibraries(data.libraries)
|
||||
migrateAuthors(data.authors, data.libraryItems)
|
||||
migrateSeries(data.series, data.libraryItems)
|
||||
migrateLibraryItems(data.libraryItems)
|
||||
migrateUsers(data.users)
|
||||
migrateSessions(data.sessions)
|
||||
|
Loading…
Reference in New Issue
Block a user