mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-04-28 17:28:30 +02:00
Update:Only load libraries from db when needed
This commit is contained in:
parent
1c40af3eef
commit
1d974375a0
@ -104,10 +104,16 @@ class Auth {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserLoginResponsePayload(user) {
|
/**
|
||||||
|
* Payload returned to a user after successful login
|
||||||
|
* @param {oldUser} user
|
||||||
|
* @returns {object}
|
||||||
|
*/
|
||||||
|
async getUserLoginResponsePayload(user) {
|
||||||
|
const libraryIds = await Database.models.library.getAllLibraryIds()
|
||||||
return {
|
return {
|
||||||
user: user.toJSONForBrowser(),
|
user: user.toJSONForBrowser(),
|
||||||
userDefaultLibraryId: user.getDefaultLibraryId(Database.libraries),
|
userDefaultLibraryId: user.getDefaultLibraryId(libraryIds),
|
||||||
serverSettings: Database.serverSettings.toJSONForBrowser(),
|
serverSettings: Database.serverSettings.toJSONForBrowser(),
|
||||||
ereaderDevices: Database.emailSettings.getEReaderDevices(user),
|
ereaderDevices: Database.emailSettings.getEReaderDevices(user),
|
||||||
Source: global.Source
|
Source: global.Source
|
||||||
@ -136,7 +142,8 @@ class Auth {
|
|||||||
return res.status(401).send('Invalid root password (hint: there is none)')
|
return res.status(401).send('Invalid root password (hint: there is none)')
|
||||||
} else {
|
} else {
|
||||||
Logger.info(`[Auth] ${user.username} logged in from ${ipAddress}`)
|
Logger.info(`[Auth] ${user.username} logged in from ${ipAddress}`)
|
||||||
return res.json(this.getUserLoginResponsePayload(user))
|
const userLoginResponsePayload = await this.getUserLoginResponsePayload(user)
|
||||||
|
return res.json(userLoginResponsePayload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +151,8 @@ class Auth {
|
|||||||
const compare = await bcrypt.compare(password, user.pash)
|
const compare = await bcrypt.compare(password, user.pash)
|
||||||
if (compare) {
|
if (compare) {
|
||||||
Logger.info(`[Auth] ${user.username} logged in from ${ipAddress}`)
|
Logger.info(`[Auth] ${user.username} logged in from ${ipAddress}`)
|
||||||
res.json(this.getUserLoginResponsePayload(user))
|
const userLoginResponsePayload = await this.getUserLoginResponsePayload(user)
|
||||||
|
res.json(userLoginResponsePayload)
|
||||||
} else {
|
} else {
|
||||||
Logger.warn(`[Auth] Failed login attempt ${req.rateLimit.current} of ${req.rateLimit.limit} from ${ipAddress}`)
|
Logger.warn(`[Auth] Failed login attempt ${req.rateLimit.current} of ${req.rateLimit.limit} from ${ipAddress}`)
|
||||||
if (req.rateLimit.remaining <= 2) {
|
if (req.rateLimit.remaining <= 2) {
|
||||||
|
@ -17,7 +17,6 @@ class Database {
|
|||||||
// TODO: below data should be loaded from the DB as needed
|
// TODO: below data should be loaded from the DB as needed
|
||||||
this.libraryItems = []
|
this.libraryItems = []
|
||||||
this.users = []
|
this.users = []
|
||||||
this.libraries = []
|
|
||||||
this.settings = []
|
this.settings = []
|
||||||
this.collections = []
|
this.collections = []
|
||||||
this.playlists = []
|
this.playlists = []
|
||||||
@ -168,9 +167,6 @@ class Database {
|
|||||||
this.users = await this.models.user.getOldUsers()
|
this.users = await this.models.user.getOldUsers()
|
||||||
Logger.info(`[Database] Loaded ${this.users.length} users`)
|
Logger.info(`[Database] Loaded ${this.users.length} users`)
|
||||||
|
|
||||||
this.libraries = await this.models.library.getAllOldLibraries()
|
|
||||||
Logger.info(`[Database] Loaded ${this.libraries.length} libraries`)
|
|
||||||
|
|
||||||
this.collections = await this.models.collection.getOldCollections()
|
this.collections = await this.models.collection.getOldCollections()
|
||||||
Logger.info(`[Database] Loaded ${this.collections.length} collections`)
|
Logger.info(`[Database] Loaded ${this.collections.length} collections`)
|
||||||
|
|
||||||
@ -190,6 +186,8 @@ class Database {
|
|||||||
this.serverSettings.version = packageJson.version
|
this.serverSettings.version = packageJson.version
|
||||||
await this.updateServerSettings()
|
await this.updateServerSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.models.library.getMaxDisplayOrder()
|
||||||
}
|
}
|
||||||
|
|
||||||
async createRootUser(username, pash, token) {
|
async createRootUser(username, pash, token) {
|
||||||
@ -254,7 +252,6 @@ class Database {
|
|||||||
async createLibrary(oldLibrary) {
|
async createLibrary(oldLibrary) {
|
||||||
if (!this.sequelize) return false
|
if (!this.sequelize) return false
|
||||||
await this.models.library.createFromOld(oldLibrary)
|
await this.models.library.createFromOld(oldLibrary)
|
||||||
this.libraries.push(oldLibrary)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateLibrary(oldLibrary) {
|
updateLibrary(oldLibrary) {
|
||||||
@ -265,7 +262,6 @@ class Database {
|
|||||||
async removeLibrary(libraryId) {
|
async removeLibrary(libraryId) {
|
||||||
if (!this.sequelize) return false
|
if (!this.sequelize) return false
|
||||||
await this.models.library.removeById(libraryId)
|
await this.models.library.removeById(libraryId)
|
||||||
this.libraries = this.libraries.filter(lib => lib.id !== libraryId)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async createCollection(oldCollection) {
|
async createCollection(oldCollection) {
|
||||||
|
@ -93,6 +93,10 @@ class Server {
|
|||||||
this.auth.authMiddleware(req, res, next)
|
this.auth.authMiddleware(req, res, next)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize database, backups, logs, rss feeds, cron jobs & watcher
|
||||||
|
* Cleanup stale/invalid data
|
||||||
|
*/
|
||||||
async init() {
|
async init() {
|
||||||
Logger.info('[Server] Init v' + version)
|
Logger.info('[Server] Init v' + version)
|
||||||
await this.playbackSessionManager.removeOrphanStreams()
|
await this.playbackSessionManager.removeOrphanStreams()
|
||||||
@ -111,13 +115,15 @@ class Server {
|
|||||||
await this.logManager.init()
|
await this.logManager.init()
|
||||||
await this.apiRouter.checkRemoveEmptySeries(Database.series) // Remove empty series
|
await this.apiRouter.checkRemoveEmptySeries(Database.series) // Remove empty series
|
||||||
await this.rssFeedManager.init()
|
await this.rssFeedManager.init()
|
||||||
this.cronManager.init()
|
|
||||||
|
const libraries = await Database.models.library.getAllOldLibraries()
|
||||||
|
this.cronManager.init(libraries)
|
||||||
|
|
||||||
if (Database.serverSettings.scannerDisableWatcher) {
|
if (Database.serverSettings.scannerDisableWatcher) {
|
||||||
Logger.info(`[Server] Watcher is disabled`)
|
Logger.info(`[Server] Watcher is disabled`)
|
||||||
this.watcher.disabled = true
|
this.watcher.disabled = true
|
||||||
} else {
|
} else {
|
||||||
this.watcher.initWatcher(Database.libraries)
|
this.watcher.initWatcher(libraries)
|
||||||
this.watcher.on('files', this.filesChanged.bind(this))
|
this.watcher.on('files', this.filesChanged.bind(this))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,13 +17,12 @@ class FileSystemController {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Do not include existing mapped library paths in response
|
// Do not include existing mapped library paths in response
|
||||||
Database.libraries.forEach(lib => {
|
const libraryFoldersPaths = await Database.models.libraryFolder.getAllLibraryFolderPaths()
|
||||||
lib.folders.forEach((folder) => {
|
libraryFoldersPaths.forEach((path) => {
|
||||||
let dir = folder.fullPath
|
let dir = path || ''
|
||||||
if (dir.includes(global.appRoot)) dir = dir.replace(global.appRoot, '')
|
if (dir.includes(global.appRoot)) dir = dir.replace(global.appRoot, '')
|
||||||
excludedDirs.push(dir)
|
excludedDirs.push(dir)
|
||||||
})
|
})
|
||||||
})
|
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
directories: await this.getDirectories(global.appRoot, '/', excludedDirs)
|
directories: await this.getDirectories(global.appRoot, '/', excludedDirs)
|
||||||
|
@ -44,7 +44,9 @@ class LibraryController {
|
|||||||
|
|
||||||
const library = new Library()
|
const library = new Library()
|
||||||
|
|
||||||
newLibraryPayload.displayOrder = Database.libraries.map(li => li.displayOrder).sort((a, b) => a - b).pop() + 1
|
let currentLargestDisplayOrder = await Database.models.library.getMaxDisplayOrder()
|
||||||
|
if (isNaN(currentLargestDisplayOrder)) currentLargestDisplayOrder = 0
|
||||||
|
newLibraryPayload.displayOrder = currentLargestDisplayOrder + 1
|
||||||
library.setData(newLibraryPayload)
|
library.setData(newLibraryPayload)
|
||||||
await Database.createLibrary(library)
|
await Database.createLibrary(library)
|
||||||
|
|
||||||
@ -60,17 +62,18 @@ class LibraryController {
|
|||||||
res.json(library)
|
res.json(library)
|
||||||
}
|
}
|
||||||
|
|
||||||
findAll(req, res) {
|
async findAll(req, res) {
|
||||||
|
const libraries = await Database.models.library.getAllOldLibraries()
|
||||||
|
|
||||||
const librariesAccessible = req.user.librariesAccessible || []
|
const librariesAccessible = req.user.librariesAccessible || []
|
||||||
if (librariesAccessible.length) {
|
if (librariesAccessible.length) {
|
||||||
return res.json({
|
return res.json({
|
||||||
libraries: Database.libraries.filter(lib => librariesAccessible.includes(lib.id)).map(lib => lib.toJSON())
|
libraries: libraries.filter(lib => librariesAccessible.includes(lib.id)).map(lib => lib.toJSON())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
libraries: Database.libraries.map(lib => lib.toJSON())
|
libraries: libraries.map(lib => lib.toJSON())
|
||||||
// libraries: Database.libraries.map(lib => lib.toJSON())
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,6 +154,12 @@ class LibraryController {
|
|||||||
return res.json(library.toJSON())
|
return res.json(library.toJSON())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DELETE: /api/libraries/:id
|
||||||
|
* Delete a library
|
||||||
|
* @param {*} req
|
||||||
|
* @param {*} res
|
||||||
|
*/
|
||||||
async delete(req, res) {
|
async delete(req, res) {
|
||||||
const library = req.library
|
const library = req.library
|
||||||
|
|
||||||
@ -173,6 +182,10 @@ class LibraryController {
|
|||||||
|
|
||||||
const libraryJson = library.toJSON()
|
const libraryJson = library.toJSON()
|
||||||
await Database.removeLibrary(library.id)
|
await Database.removeLibrary(library.id)
|
||||||
|
|
||||||
|
// Re-order libraries
|
||||||
|
await Database.models.library.resetDisplayOrder()
|
||||||
|
|
||||||
SocketAuthority.emitter('library_removed', libraryJson)
|
SocketAuthority.emitter('library_removed', libraryJson)
|
||||||
return res.json(libraryJson)
|
return res.json(libraryJson)
|
||||||
}
|
}
|
||||||
@ -601,17 +614,23 @@ class LibraryController {
|
|||||||
res.json(categories)
|
res.json(categories)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PATCH: Change the order of libraries
|
/**
|
||||||
|
* POST: /api/libraries/order
|
||||||
|
* Change the display order of libraries
|
||||||
|
* @param {*} req
|
||||||
|
* @param {*} res
|
||||||
|
*/
|
||||||
async reorder(req, res) {
|
async reorder(req, res) {
|
||||||
if (!req.user.isAdminOrUp) {
|
if (!req.user.isAdminOrUp) {
|
||||||
Logger.error('[LibraryController] ReorderLibraries invalid user', req.user)
|
Logger.error('[LibraryController] ReorderLibraries invalid user', req.user)
|
||||||
return res.sendStatus(403)
|
return res.sendStatus(403)
|
||||||
}
|
}
|
||||||
|
const libraries = await Database.models.library.getAllOldLibraries()
|
||||||
|
|
||||||
var orderdata = req.body
|
const orderdata = req.body
|
||||||
var hasUpdates = false
|
let hasUpdates = false
|
||||||
for (let i = 0; i < orderdata.length; i++) {
|
for (let i = 0; i < orderdata.length; i++) {
|
||||||
var library = Database.libraries.find(lib => lib.id === orderdata[i].id)
|
const library = libraries.find(lib => lib.id === orderdata[i].id)
|
||||||
if (!library) {
|
if (!library) {
|
||||||
Logger.error(`[LibraryController] Invalid library not found in reorder ${orderdata[i].id}`)
|
Logger.error(`[LibraryController] Invalid library not found in reorder ${orderdata[i].id}`)
|
||||||
return res.sendStatus(500)
|
return res.sendStatus(500)
|
||||||
@ -623,14 +642,14 @@ class LibraryController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasUpdates) {
|
if (hasUpdates) {
|
||||||
Database.libraries.sort((a, b) => a.displayOrder - b.displayOrder)
|
libraries.sort((a, b) => a.displayOrder - b.displayOrder)
|
||||||
Logger.debug(`[LibraryController] Updated library display orders`)
|
Logger.debug(`[LibraryController] Updated library display orders`)
|
||||||
} else {
|
} else {
|
||||||
Logger.debug(`[LibraryController] Library orders were up to date`)
|
Logger.debug(`[LibraryController] Library orders were up to date`)
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
libraries: Database.libraries.map(lib => lib.toJSON())
|
libraries: libraries.map(lib => lib.toJSON())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -902,13 +921,13 @@ class LibraryController {
|
|||||||
res.send(opmlText)
|
res.send(opmlText)
|
||||||
}
|
}
|
||||||
|
|
||||||
middleware(req, res, next) {
|
async middleware(req, res, next) {
|
||||||
if (!req.user.checkCanAccessLibrary(req.params.id)) {
|
if (!req.user.checkCanAccessLibrary(req.params.id)) {
|
||||||
Logger.warn(`[LibraryController] Library ${req.params.id} not accessible to user ${req.user.username}`)
|
Logger.warn(`[LibraryController] Library ${req.params.id} not accessible to user ${req.user.username}`)
|
||||||
return res.sendStatus(403)
|
return res.sendStatus(403)
|
||||||
}
|
}
|
||||||
|
|
||||||
const library = Database.libraries.find(lib => lib.id === req.params.id)
|
const library = await Database.models.library.getOldById(req.params.id)
|
||||||
if (!library) {
|
if (!library) {
|
||||||
return res.status(404).send('Library not found')
|
return res.status(404).send('Library not found')
|
||||||
}
|
}
|
||||||
|
@ -24,18 +24,18 @@ class MiscController {
|
|||||||
Logger.error('Invalid request, no files')
|
Logger.error('Invalid request, no files')
|
||||||
return res.sendStatus(400)
|
return res.sendStatus(400)
|
||||||
}
|
}
|
||||||
var files = Object.values(req.files)
|
const files = Object.values(req.files)
|
||||||
var title = req.body.title
|
const title = req.body.title
|
||||||
var author = req.body.author
|
const author = req.body.author
|
||||||
var series = req.body.series
|
const series = req.body.series
|
||||||
var libraryId = req.body.library
|
const libraryId = req.body.library
|
||||||
var folderId = req.body.folder
|
const folderId = req.body.folder
|
||||||
|
|
||||||
var library = Database.libraries.find(lib => lib.id === libraryId)
|
const library = await Database.models.library.getOldById(libraryId)
|
||||||
if (!library) {
|
if (!library) {
|
||||||
return res.status(404).send(`Library not found with id ${libraryId}`)
|
return res.status(404).send(`Library not found with id ${libraryId}`)
|
||||||
}
|
}
|
||||||
var folder = library.folders.find(fold => fold.id === folderId)
|
const folder = library.folders.find(fold => fold.id === folderId)
|
||||||
if (!folder) {
|
if (!folder) {
|
||||||
return res.status(404).send(`Folder not found with id ${folderId} in library ${library.name}`)
|
return res.status(404).send(`Folder not found with id ${folderId} in library ${library.name}`)
|
||||||
}
|
}
|
||||||
@ -45,8 +45,8 @@ class MiscController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For setting permissions recursively
|
// For setting permissions recursively
|
||||||
var outputDirectory = ''
|
let outputDirectory = ''
|
||||||
var firstDirPath = ''
|
let firstDirPath = ''
|
||||||
|
|
||||||
if (library.isPodcast) { // Podcasts only in 1 folder
|
if (library.isPodcast) { // Podcasts only in 1 folder
|
||||||
outputDirectory = Path.join(folder.fullPath, title)
|
outputDirectory = Path.join(folder.fullPath, title)
|
||||||
@ -62,8 +62,7 @@ class MiscController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var exists = await fs.pathExists(outputDirectory)
|
if (await fs.pathExists(outputDirectory)) {
|
||||||
if (exists) {
|
|
||||||
Logger.error(`[Server] Upload directory "${outputDirectory}" already exists`)
|
Logger.error(`[Server] Upload directory "${outputDirectory}" already exists`)
|
||||||
return res.status(500).send(`Directory "${outputDirectory}" already exists`)
|
return res.status(500).send(`Directory "${outputDirectory}" already exists`)
|
||||||
}
|
}
|
||||||
@ -132,12 +131,19 @@ class MiscController {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
authorize(req, res) {
|
/**
|
||||||
|
* POST: /api/authorize
|
||||||
|
* Used to authorize an API token
|
||||||
|
*
|
||||||
|
* @param {*} req
|
||||||
|
* @param {*} res
|
||||||
|
*/
|
||||||
|
async authorize(req, res) {
|
||||||
if (!req.user) {
|
if (!req.user) {
|
||||||
Logger.error('Invalid user in authorize')
|
Logger.error('Invalid user in authorize')
|
||||||
return res.sendStatus(401)
|
return res.sendStatus(401)
|
||||||
}
|
}
|
||||||
const userResponse = this.auth.getUserLoginResponsePayload(req.user)
|
const userResponse = await this.auth.getUserLoginResponsePayload(req.user)
|
||||||
res.json(userResponse)
|
res.json(userResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ class PodcastController {
|
|||||||
}
|
}
|
||||||
const payload = req.body
|
const payload = req.body
|
||||||
|
|
||||||
const library = Database.libraries.find(lib => lib.id === payload.libraryId)
|
const library = await Database.models.library.getOldById(payload.libraryId)
|
||||||
if (!library) {
|
if (!library) {
|
||||||
Logger.error(`[PodcastController] Create: Library not found "${payload.libraryId}"`)
|
Logger.error(`[PodcastController] Create: Library not found "${payload.libraryId}"`)
|
||||||
return res.status(404).send('Library not found')
|
return res.status(404).send('Library not found')
|
||||||
|
@ -13,13 +13,21 @@ class CronManager {
|
|||||||
this.podcastCronExpressionsExecuting = []
|
this.podcastCronExpressionsExecuting = []
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
/**
|
||||||
this.initLibraryScanCrons()
|
* Initialize library scan crons & podcast download crons
|
||||||
|
* @param {oldLibrary[]} libraries
|
||||||
|
*/
|
||||||
|
init(libraries) {
|
||||||
|
this.initLibraryScanCrons(libraries)
|
||||||
this.initPodcastCrons()
|
this.initPodcastCrons()
|
||||||
}
|
}
|
||||||
|
|
||||||
initLibraryScanCrons() {
|
/**
|
||||||
for (const library of Database.libraries) {
|
* Initialize library scan crons
|
||||||
|
* @param {oldLibrary[]} libraries
|
||||||
|
*/
|
||||||
|
initLibraryScanCrons(libraries) {
|
||||||
|
for (const library of libraries) {
|
||||||
if (library.settings.autoScanCronExpression) {
|
if (library.settings.autoScanCronExpression) {
|
||||||
this.startCronForLibrary(library)
|
this.startCronForLibrary(library)
|
||||||
}
|
}
|
||||||
|
@ -14,15 +14,15 @@ class NotificationManager {
|
|||||||
return notificationData
|
return notificationData
|
||||||
}
|
}
|
||||||
|
|
||||||
onPodcastEpisodeDownloaded(libraryItem, episode) {
|
async onPodcastEpisodeDownloaded(libraryItem, episode) {
|
||||||
if (!Database.notificationSettings.isUseable) return
|
if (!Database.notificationSettings.isUseable) return
|
||||||
|
|
||||||
Logger.debug(`[NotificationManager] onPodcastEpisodeDownloaded: Episode "${episode.title}" for podcast ${libraryItem.media.metadata.title}`)
|
Logger.debug(`[NotificationManager] onPodcastEpisodeDownloaded: Episode "${episode.title}" for podcast ${libraryItem.media.metadata.title}`)
|
||||||
const library = Database.libraries.find(lib => lib.id === libraryItem.libraryId)
|
const library = await Database.models.library.getOldById(libraryItem.libraryId)
|
||||||
const eventData = {
|
const eventData = {
|
||||||
libraryItemId: libraryItem.id,
|
libraryItemId: libraryItem.id,
|
||||||
libraryId: libraryItem.libraryId,
|
libraryId: libraryItem.libraryId,
|
||||||
libraryName: library ? library.name : 'Unknown',
|
libraryName: library?.name || 'Unknown',
|
||||||
mediaTags: (libraryItem.media.tags || []).join(', '),
|
mediaTags: (libraryItem.media.tags || []).join(', '),
|
||||||
podcastTitle: libraryItem.media.metadata.title,
|
podcastTitle: libraryItem.media.metadata.title,
|
||||||
podcastAuthor: libraryItem.media.metadata.author || '',
|
podcastAuthor: libraryItem.media.metadata.author || '',
|
||||||
|
@ -4,6 +4,10 @@ const oldLibrary = require('../objects/Library')
|
|||||||
|
|
||||||
module.exports = (sequelize) => {
|
module.exports = (sequelize) => {
|
||||||
class Library extends Model {
|
class Library extends Model {
|
||||||
|
/**
|
||||||
|
* Get all old libraries
|
||||||
|
* @returns {Promise<oldLibrary[]>}
|
||||||
|
*/
|
||||||
static async getAllOldLibraries() {
|
static async getAllOldLibraries() {
|
||||||
const libraries = await this.findAll({
|
const libraries = await this.findAll({
|
||||||
include: sequelize.models.libraryFolder,
|
include: sequelize.models.libraryFolder,
|
||||||
@ -12,6 +16,11 @@ module.exports = (sequelize) => {
|
|||||||
return libraries.map(lib => this.getOldLibrary(lib))
|
return libraries.map(lib => this.getOldLibrary(lib))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert expanded Library to oldLibrary
|
||||||
|
* @param {Library} libraryExpanded
|
||||||
|
* @returns {Promise<oldLibrary>}
|
||||||
|
*/
|
||||||
static getOldLibrary(libraryExpanded) {
|
static getOldLibrary(libraryExpanded) {
|
||||||
const folders = libraryExpanded.libraryFolders.map(folder => {
|
const folders = libraryExpanded.libraryFolders.map(folder => {
|
||||||
return {
|
return {
|
||||||
@ -58,6 +67,11 @@ module.exports = (sequelize) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update library and library folders
|
||||||
|
* @param {object} oldLibrary
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
static async updateFromOld(oldLibrary) {
|
static async updateFromOld(oldLibrary) {
|
||||||
const existingLibrary = await this.findByPk(oldLibrary.id, {
|
const existingLibrary = await this.findByPk(oldLibrary.id, {
|
||||||
include: sequelize.models.libraryFolder
|
include: sequelize.models.libraryFolder
|
||||||
@ -112,6 +126,11 @@ module.exports = (sequelize) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy library by id
|
||||||
|
* @param {string} libraryId
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
static removeById(libraryId) {
|
static removeById(libraryId) {
|
||||||
return this.destroy({
|
return this.destroy({
|
||||||
where: {
|
where: {
|
||||||
@ -119,6 +138,59 @@ module.exports = (sequelize) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all library ids
|
||||||
|
* @returns {Promise<string[]>} array of library ids
|
||||||
|
*/
|
||||||
|
static async getAllLibraryIds() {
|
||||||
|
const libraries = await this.findAll({
|
||||||
|
attributes: ['id']
|
||||||
|
})
|
||||||
|
return libraries.map(l => l.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find Library by primary key & return oldLibrary
|
||||||
|
* @param {string} libraryId
|
||||||
|
* @returns {Promise<oldLibrary|null>} Returns null if not found
|
||||||
|
*/
|
||||||
|
static async getOldById(libraryId) {
|
||||||
|
if (!libraryId) return null
|
||||||
|
const library = await this.findByPk(libraryId, {
|
||||||
|
include: sequelize.models.libraryFolder
|
||||||
|
})
|
||||||
|
if (!library) return null
|
||||||
|
return this.getOldLibrary(library)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the largest value in the displayOrder column
|
||||||
|
* Used for setting a new libraries display order
|
||||||
|
* @returns {Promise<number>}
|
||||||
|
*/
|
||||||
|
static getMaxDisplayOrder() {
|
||||||
|
return this.max('displayOrder') || 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates displayOrder to be sequential
|
||||||
|
* Used after removing a library
|
||||||
|
*/
|
||||||
|
static async resetDisplayOrder() {
|
||||||
|
const libraries = await this.findAll({
|
||||||
|
order: [['displayOrder', 'ASC']]
|
||||||
|
})
|
||||||
|
for (let i = 0; i < libraries.length; i++) {
|
||||||
|
const library = libraries[i]
|
||||||
|
if (library.displayOrder !== i + 1) {
|
||||||
|
Logger.dev(`[Library] Updating display order of library from ${library.displayOrder} to ${i + 1}`)
|
||||||
|
await library.update({ displayOrder: i + 1 }).catch((error) => {
|
||||||
|
Logger.error(`[Library] Failed to update library display order to ${i + 1}`, error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Library.init({
|
Library.init({
|
||||||
|
@ -1,7 +1,18 @@
|
|||||||
const { DataTypes, Model } = require('sequelize')
|
const { DataTypes, Model } = require('sequelize')
|
||||||
|
|
||||||
module.exports = (sequelize) => {
|
module.exports = (sequelize) => {
|
||||||
class LibraryFolder extends Model { }
|
class LibraryFolder extends Model {
|
||||||
|
/**
|
||||||
|
* Gets all library folder path strings
|
||||||
|
* @returns {Promise<string[]>} array of library folder paths
|
||||||
|
*/
|
||||||
|
static async getAllLibraryFolderPaths() {
|
||||||
|
const libraryFolders = await this.findAll({
|
||||||
|
attributes: ['path']
|
||||||
|
})
|
||||||
|
return libraryFolders.map(l => l.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LibraryFolder.init({
|
LibraryFolder.init({
|
||||||
id: {
|
id: {
|
||||||
|
@ -258,11 +258,15 @@ class User {
|
|||||||
return hasUpdates
|
return hasUpdates
|
||||||
}
|
}
|
||||||
|
|
||||||
getDefaultLibraryId(libraries) {
|
/**
|
||||||
|
* Get first available library id for user
|
||||||
|
*
|
||||||
|
* @param {string[]} libraryIds
|
||||||
|
* @returns {string|null}
|
||||||
|
*/
|
||||||
|
getDefaultLibraryId(libraryIds) {
|
||||||
// Libraries should already be in ascending display order, find first accessible
|
// Libraries should already be in ascending display order, find first accessible
|
||||||
var firstAccessibleLibrary = libraries.find(lib => this.checkCanAccessLibrary(lib.id))
|
return libraryIds.find(lid => this.checkCanAccessLibrary(lid)) || null
|
||||||
if (!firstAccessibleLibrary) return null
|
|
||||||
return firstAccessibleLibrary.id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns most recent media progress w/ `media` object and optionally an `episode` object
|
// Returns most recent media progress w/ `media` object and optionally an `episode` object
|
||||||
|
@ -66,7 +66,7 @@ class Scanner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async scanLibraryItemByRequest(libraryItem) {
|
async scanLibraryItemByRequest(libraryItem) {
|
||||||
const library = Database.libraries.find(lib => lib.id === libraryItem.libraryId)
|
const library = await Database.models.library.getOldById(libraryItem.libraryId)
|
||||||
if (!library) {
|
if (!library) {
|
||||||
Logger.error(`[Scanner] Scan libraryItem by id library not found "${libraryItem.libraryId}"`)
|
Logger.error(`[Scanner] Scan libraryItem by id library not found "${libraryItem.libraryId}"`)
|
||||||
return ScanResult.NOTHING
|
return ScanResult.NOTHING
|
||||||
@ -552,7 +552,7 @@ class Scanner {
|
|||||||
|
|
||||||
for (const folderId in folderGroups) {
|
for (const folderId in folderGroups) {
|
||||||
const libraryId = folderGroups[folderId].libraryId
|
const libraryId = folderGroups[folderId].libraryId
|
||||||
const library = Database.libraries.find(lib => lib.id === libraryId)
|
const library = await Database.models.library.getOldById(libraryId)
|
||||||
if (!library) {
|
if (!library) {
|
||||||
Logger.error(`[Scanner] Library not found in files changed ${libraryId}`)
|
Logger.error(`[Scanner] Library not found in files changed ${libraryId}`)
|
||||||
continue;
|
continue;
|
||||||
|
Loading…
Reference in New Issue
Block a user