diff --git a/client/components/app/BookShelfCategorized.vue b/client/components/app/BookShelfCategorized.vue index 4f198844..32d3d085 100644 --- a/client/components/app/BookShelfCategorized.vue +++ b/client/components/app/BookShelfCategorized.vue @@ -155,7 +155,7 @@ export default { }, settingsUpdated(settings) {}, scan() { - this.$root.socket.emit('scan', this.$store.state.libraries.currentLibraryId) + this.$store.dispatch('libraries/requestLibraryScan', { libraryId: this.$store.state.libraries.currentLibraryId }) }, libraryItemAdded(libraryItem) { console.log('libraryItem added', libraryItem) diff --git a/client/components/app/LazyBookshelf.vue b/client/components/app/LazyBookshelf.vue index 920758f0..46ef22d3 100644 --- a/client/components/app/LazyBookshelf.vue +++ b/client/components/app/LazyBookshelf.vue @@ -563,7 +563,7 @@ export default { } }, scan() { - this.$root.socket.emit('scan', this.currentLibraryId) + this.$store.dispatch('libraries/requestLibraryScan', { libraryId: this.currentLibraryId }) } }, mounted() { diff --git a/client/components/cards/LazyBookCard.vue b/client/components/cards/LazyBookCard.vue index 0b4a3565..cd12d0ff 100644 --- a/client/components/cards/LazyBookCard.vue +++ b/client/components/cards/LazyBookCard.vue @@ -419,23 +419,28 @@ export default { toast.error(`Failed to mark as ${updatePayload.isFinished ? 'Finished' : 'Not Finished'}`) }) }, - itemScanComplete(result) { - this.rescanning = false - var toast = this.$toast || this.$nuxt.$toast - if (!result) { - toast.error(`Re-Scan Failed for "${this.title}"`) - } else if (result === 'UPDATED') { - toast.success(`Re-Scan complete audiobook was updated`) - } else if (result === 'UPTODATE') { - toast.success(`Re-Scan complete audiobook was up to date`) - } else if (result === 'REMOVED') { - toast.error(`Re-Scan complete audiobook was removed`) - } - }, rescan() { this.rescanning = true - this._socket.once('item_scan_complete', this.itemScanComplete) - this._socket.emit('scan_item', this.libraryItemId) + this.$axios + .$get(`/api/items/${this.libraryItemId}/scan`) + .then((data) => { + this.rescanning = false + var result = data.result + if (!result) { + this.$toast.error(`Re-Scan Failed for "${this.title}"`) + } else if (result === 'UPDATED') { + this.$toast.success(`Re-Scan complete item was updated`) + } else if (result === 'UPTODATE') { + this.$toast.success(`Re-Scan complete item was up to date`) + } else if (result === 'REMOVED') { + this.$toast.error(`Re-Scan complete item was removed`) + } + }) + .catch((error) => { + console.error('Failed to scan library item', error) + this.$toast.error('Failed to scan library item') + this.rescanning = false + }) }, showEditModalTracks() { // More menu func diff --git a/client/components/modals/item/tabs/Details.vue b/client/components/modals/item/tabs/Details.vue index 5e149457..15597520 100644 --- a/client/components/modals/item/tabs/Details.vue +++ b/client/components/modals/item/tabs/Details.vue @@ -117,22 +117,28 @@ export default { this.quickMatching = false }) }, - libraryScanComplete(result) { - this.rescanning = false - if (!result) { - this.$toast.error(`Re-Scan Failed for "${this.title}"`) - } else if (result === 'UPDATED') { - this.$toast.success(`Re-Scan complete item was updated`) - } else if (result === 'UPTODATE') { - this.$toast.success(`Re-Scan complete item was up to date`) - } else if (result === 'REMOVED') { - this.$toast.error(`Re-Scan complete item was removed`) - } - }, rescan() { this.rescanning = true - this.$root.socket.once('item_scan_complete', this.libraryScanComplete) - this.$root.socket.emit('scan_item', this.libraryItemId) + this.$axios + .$get(`/api/items/${this.libraryItemId}/scan`) + .then((data) => { + this.rescanning = false + var result = data.result + if (!result) { + this.$toast.error(`Re-Scan Failed for "${this.title}"`) + } else if (result === 'UPDATED') { + this.$toast.success(`Re-Scan complete item was updated`) + } else if (result === 'UPTODATE') { + this.$toast.success(`Re-Scan complete item was up to date`) + } else if (result === 'REMOVED') { + this.$toast.error(`Re-Scan complete item was removed`) + } + }) + .catch((error) => { + console.error('Failed to scan library item', error) + this.$toast.error('Failed to scan library item') + this.rescanning = false + }) }, saveMetadataComplete(result) { this.savingMetadata = false diff --git a/client/components/tables/library/LibraryItem.vue b/client/components/tables/library/LibraryItem.vue index d6ce9a04..ba490a43 100644 --- a/client/components/tables/library/LibraryItem.vue +++ b/client/components/tables/library/LibraryItem.vue @@ -76,10 +76,10 @@ export default { this.$emit('edit', this.library) }, scan() { - this.$root.socket.emit('scan', this.library.id) + this.$store.dispatch('libraries/requestLibraryScan', { libraryId: this.library.id }) }, forceScan() { - this.$root.socket.emit('scan', this.library.id, { forceRescan: true }) + this.$store.dispatch('libraries/requestLibraryScan', { libraryId: this.library.id, force: 1 }) }, deleteClick() { if (this.isMain) return diff --git a/client/pages/upload/index.vue b/client/pages/upload/index.vue index 53303231..cc9a0b09 100644 --- a/client/pages/upload/index.vue +++ b/client/pages/upload/index.vue @@ -232,7 +232,7 @@ export default { }) return this.$axios - .$post('/upload', form) + .$post('/api/upload', form) .then(() => true) .catch((error) => { console.error('Failed', error) diff --git a/client/store/index.js b/client/store/index.js index 7a3fcfd7..3933c1ea 100644 --- a/client/store/index.js +++ b/client/store/index.js @@ -46,7 +46,7 @@ export const actions = { var updatePayload = { ...payload } - return this.$axios.$patch('/api/serverSettings', updatePayload).then((result) => { + return this.$axios.$patch('/api/settings', updatePayload).then((result) => { if (result.success) { commit('setServerSettings', result.serverSettings) return true diff --git a/client/store/libraries.js b/client/store/libraries.js index 7b02045f..6cce6d5d 100644 --- a/client/store/libraries.js +++ b/client/store/libraries.js @@ -33,6 +33,14 @@ export const getters = { } export const actions = { + requestLibraryScan({ state, commit }, { libraryId, force }) { + this.$axios.$get(`/api/libraries/${libraryId}/scan`, { params: { force } }).then(() => { + this.$toast.success('Library scan started') + }).catch((error) => { + console.error('Failed to start scan', error) + this.$toast.error('Failed to start scan') + }) + }, loadFolders({ state, commit }) { if (state.folders.length) { var lastCheck = Date.now() - state.folderLastUpdate diff --git a/server/Server.js b/server/Server.js index a51b512c..25304e51 100644 --- a/server/Server.js +++ b/server/Server.js @@ -9,8 +9,6 @@ const rateLimit = require('express-rate-limit') const { version } = require('../package.json') // Utils -const { ScanResult } = require('./utils/constants') -const filePerms = require('./utils/filePerms') const dbMigration = require('./utils/dbMigration') const Logger = require('./Logger') @@ -160,12 +158,11 @@ class Server { const distPath = Path.join(global.appRoot, '/client/dist') app.use(express.static(distPath)) + // TODO: Are these necessary? // Metadata folder static path - app.use('/metadata', this.authMiddleware.bind(this), express.static(global.MetadataPath)) - + // app.use('/metadata', this.authMiddleware.bind(this), express.static(global.MetadataPath)) // Downloads folder static path - app.use('/downloads', this.authMiddleware.bind(this), express.static(this.downloadManager.downloadDirPath)) - + // app.use('/downloads', this.authMiddleware.bind(this), express.static(this.downloadManager.downloadDirPath)) // Static folder app.use(express.static(Path.join(global.appRoot, 'static'))) @@ -197,7 +194,6 @@ class Server { app.get('/collection/:id', (req, res) => res.sendFile(Path.join(distPath, 'index.html'))) app.post('/login', this.getLoginRateLimiter(), (req, res) => this.auth.login(req, res)) - app.post('/upload', this.authMiddleware.bind(this), this.handleUpload.bind(this)) app.post('/logout', this.authMiddleware.bind(this), this.logout.bind(this)) app.get('/ping', (req, res) => { Logger.info('Recieved ping') @@ -230,9 +226,7 @@ class Server { // with the goal of the web socket connection being a nice-to-have not need-to-have // Scanning - socket.on('scan', this.scan.bind(this)) socket.on('cancel_scan', this.cancelScan.bind(this)) - socket.on('scan_item', (libraryItemId) => this.scanLibraryItem(socket, libraryItemId)) socket.on('save_metadata', (libraryItemId) => this.saveMetadata(socket, libraryItemId)) // Downloading @@ -273,24 +267,6 @@ class Server { await this.scanner.scanFilesChanged(fileUpdates) } - async scan(libraryId, options = {}) { - Logger.info('[Server] Starting Scan') - await this.scanner.scan(libraryId, options) - // await this.scanner.scan(libraryId) - Logger.info('[Server] Scan complete') - } - - async scanLibraryItem(socket, libraryItemId) { - var result = await this.scanner.scanLibraryItemById(libraryItemId) - var scanResultName = '' - for (const key in ScanResult) { - if (ScanResult[key] === result) { - scanResultName = key - } - } - socket.emit('item_scan_complete', scanResultName) - } - cancelScan(id) { Logger.debug('[Server] Cancel scan', id) this.scanner.setCancelLibraryScan(id) @@ -351,70 +327,6 @@ class Server { } } - async handleUpload(req, res) { - if (!req.user.canUpload) { - Logger.warn('User attempted to upload without permission', req.user) - return res.sendStatus(403) - } - var files = Object.values(req.files) - var title = req.body.title - var author = req.body.author - var series = req.body.series - var libraryId = req.body.library - var folderId = req.body.folder - - var library = this.db.libraries.find(lib => lib.id === libraryId) - if (!library) { - return res.status(500).send(`Library not found with id ${libraryId}`) - } - var folder = library.folders.find(fold => fold.id === folderId) - if (!folder) { - return res.status(500).send(`Folder not found with id ${folderId} in library ${library.name}`) - } - - if (!files.length || !title) { - return res.status(500).send(`Invalid post data`) - } - - // For setting permissions recursively - var firstDirPath = Path.join(folder.fullPath, author) - - var outputDirectory = '' - if (series && author) { - outputDirectory = Path.join(folder.fullPath, author, series, title) - } else if (author) { - outputDirectory = Path.join(folder.fullPath, author, title) - } else { - outputDirectory = Path.join(folder.fullPath, title) - } - - var exists = await fs.pathExists(outputDirectory) - if (exists) { - Logger.error(`[Server] Upload directory "${outputDirectory}" already exists`) - return res.status(500).send(`Directory "${outputDirectory}" already exists`) - } - - await fs.ensureDir(outputDirectory) - - Logger.info(`Uploading ${files.length} files to`, outputDirectory) - - for (let i = 0; i < files.length; i++) { - var file = files[i] - - var path = Path.join(outputDirectory, file.name) - await file.mv(path).then(() => { - return true - }).catch((error) => { - Logger.error('Failed to move file', path, error) - return false - }) - } - - await filePerms.setDefault(firstDirPath) - - res.sendStatus(200) - } - // First time login rate limit is hit loginLimitReached(req, res, options) { Logger.error(`[Server] Login rate limit (${options.max}) was hit for ip ${req.ip}`) diff --git a/server/controllers/LibraryController.js b/server/controllers/LibraryController.js index 3aafc8d1..263e93b0 100644 --- a/server/controllers/LibraryController.js +++ b/server/controllers/LibraryController.js @@ -487,6 +487,20 @@ class LibraryController { res.sendStatus(200) } + // GET: api/scan (Root) + async scan(req, res) { + if (!req.user.isRoot) { + Logger.error(`[LibraryController] Non-root user attempted to scan library`, req.user) + return res.sendStatus(403) + } + var options = { + forceRescan: req.query.force == 1 + } + res.sendStatus(200) + await this.scanner.scan(req.library, options) + Logger.info('[LibraryController] Scan complete') + } + middleware(req, res, next) { var librariesAccessible = req.user.librariesAccessible || [] if (librariesAccessible && librariesAccessible.length && !librariesAccessible.includes(req.params.id)) { diff --git a/server/controllers/LibraryItemController.js b/server/controllers/LibraryItemController.js index bc403f77..d5ef371b 100644 --- a/server/controllers/LibraryItemController.js +++ b/server/controllers/LibraryItemController.js @@ -1,5 +1,6 @@ const Logger = require('../Logger') const { reqSupportsWebp } = require('../utils/index') +const { ScanResult } = require('../utils/constants') class LibraryItemController { constructor() { } @@ -239,6 +240,18 @@ class LibraryItemController { else res.sendStatus(500) } + // GET: api/items/:id/scan (Root) + async scan(req, res) { + if (!req.user.isRoot) { + Logger.error(`[LibraryItemController] Non-root user attempted to scan library item`, req.user) + return res.sendStatus(403) + } + var result = await this.scanner.scanLibraryItemById(req.libraryItem.id) + res.json({ + result: Object.keys(ScanResult).find(key => ScanResult[key] == result) + }) + } + middleware(req, res, next) { var item = this.db.libraryItems.find(li => li.id === req.params.id) diff --git a/server/controllers/MiscController.js b/server/controllers/MiscController.js new file mode 100644 index 00000000..ae8fe3c9 --- /dev/null +++ b/server/controllers/MiscController.js @@ -0,0 +1,198 @@ +const Path = require('path') +const fs = require('fs-extra') +const axios = require('axios') + +const Logger = require('../Logger') +const { parsePodcastRssFeedXml } = require('../utils/podcastUtils') +const { isObject } = require('../utils/index') + +// +// This is a controller for routes that don't have a home yet :( +// +class MiscController { + constructor() { } + + // POST: api/upload + async handleUpload(req, res) { + if (!req.user.canUpload) { + Logger.warn('User attempted to upload without permission', req.user) + return res.sendStatus(403) + } + var files = Object.values(req.files) + var title = req.body.title + var author = req.body.author + var series = req.body.series + var libraryId = req.body.library + var folderId = req.body.folder + + var library = this.db.libraries.find(lib => lib.id === libraryId) + if (!library) { + return res.status(500).send(`Library not found with id ${libraryId}`) + } + var folder = library.folders.find(fold => fold.id === folderId) + if (!folder) { + return res.status(500).send(`Folder not found with id ${folderId} in library ${library.name}`) + } + + if (!files.length || !title) { + return res.status(500).send(`Invalid post data`) + } + + // For setting permissions recursively + var firstDirPath = Path.join(folder.fullPath, author) + + var outputDirectory = '' + if (series && author) { + outputDirectory = Path.join(folder.fullPath, author, series, title) + } else if (author) { + outputDirectory = Path.join(folder.fullPath, author, title) + } else { + outputDirectory = Path.join(folder.fullPath, title) + } + + var exists = await fs.pathExists(outputDirectory) + if (exists) { + Logger.error(`[Server] Upload directory "${outputDirectory}" already exists`) + return res.status(500).send(`Directory "${outputDirectory}" already exists`) + } + + await fs.ensureDir(outputDirectory) + + Logger.info(`Uploading ${files.length} files to`, outputDirectory) + + for (let i = 0; i < files.length; i++) { + var file = files[i] + + var path = Path.join(outputDirectory, file.name) + await file.mv(path).then(() => { + return true + }).catch((error) => { + Logger.error('Failed to move file', path, error) + return false + }) + } + + await filePerms.setDefault(firstDirPath) + + res.sendStatus(200) + } + + // GET: api/download/:id + async download(req, res) { + if (!req.user.canDownload) { + Logger.error('User attempting to download without permission', req.user) + return res.sendStatus(403) + } + var downloadId = req.params.id + Logger.info('Download Request', downloadId) + var download = this.downloadManager.getDownload(downloadId) + if (!download) { + Logger.error('Download request not found', downloadId) + return res.sendStatus(404) + } + + var options = { + headers: { + 'Content-Type': download.mimeType + } + } + res.download(download.fullPath, download.filename, options, (err) => { + if (err) { + Logger.error('Download Error', err) + } + }) + } + + // PATCH: api/settings (Root) + async updateServerSettings(req, res) { + if (!req.user.isRoot) { + Logger.error('User other than root attempting to update server settings', req.user) + return res.sendStatus(403) + } + var settingsUpdate = req.body + if (!settingsUpdate || !isObject(settingsUpdate)) { + return res.status(500).send('Invalid settings update object') + } + + var madeUpdates = this.db.serverSettings.update(settingsUpdate) + if (madeUpdates) { + // If backup schedule is updated - update backup manager + if (settingsUpdate.backupSchedule !== undefined) { + this.backupManager.updateCronSchedule() + } + + await this.db.updateServerSettings() + } + return res.json({ + success: true, + serverSettings: this.db.serverSettings + }) + } + + // POST: api/purgecache (Root) + async purgeCache(req, res) { + if (!req.user.isRoot) { + return res.sendStatus(403) + } + Logger.info(`[ApiRouter] Purging all cache`) + await this.cacheManager.purgeAll() + res.sendStatus(200) + } + + getPodcastFeed(req, res) { + var url = req.body.rssFeed + if (!url) { + return res.status(400).send('Bad request') + } + + axios.get(url).then(async (data) => { + if (!data || !data.data) { + Logger.error('Invalid podcast feed request response') + return res.status(500).send('Bad response from feed request') + } + var podcast = await parsePodcastRssFeedXml(data.data) + if (!podcast) { + return res.status(500).send('Invalid podcast RSS feed') + } + res.json(podcast) + }).catch((error) => { + console.error('Failed', error) + res.status(500).send(error) + }) + } + + async findBooks(req, res) { + var provider = req.query.provider || 'google' + var title = req.query.title || '' + var author = req.query.author || '' + var results = await this.bookFinder.search(provider, title, author) + res.json(results) + } + + async findCovers(req, res) { + var query = req.query + var result = await this.bookFinder.findCovers(query.provider, query.title, query.author || null) + res.json(result) + } + + async findPodcasts(req, res) { + var term = req.query.term + var results = await this.podcastFinder.search(term) + res.json(results) + } + + async findAuthor(req, res) { + var query = req.query.q + var author = await this.authorFinder.findAuthorByName(query) + res.json(author) + } + + authorize(req, res) { + if (!req.user) { + Logger.error('Invalid user in authorize') + return res.sendStatus(401) + } + res.json({ user: req.user }) + } +} +module.exports = new MiscController() \ No newline at end of file diff --git a/server/routers/ApiRouter.js b/server/routers/ApiRouter.js index db1d325d..d758f4bf 100644 --- a/server/routers/ApiRouter.js +++ b/server/routers/ApiRouter.js @@ -2,11 +2,7 @@ const express = require('express') const Path = require('path') const fs = require('fs-extra') const date = require('date-and-time') -const axios = require('axios') - const Logger = require('../Logger') -const { isObject } = require('../utils/index') -const { parsePodcastRssFeedXml } = require('../utils/podcastUtils') const LibraryController = require('../controllers/LibraryController') const UserController = require('../controllers/UserController') @@ -18,6 +14,7 @@ const SeriesController = require('../controllers/SeriesController') const AuthorController = require('../controllers/AuthorController') const MediaEntityController = require('../controllers/MediaEntityController') const SessionController = require('../controllers/SessionController') +const MiscController = require('../controllers/MiscController') const BookFinder = require('../finders/BookFinder') const AuthorFinder = require('../finders/AuthorFinder') @@ -69,6 +66,7 @@ class ApiRouter { this.router.get('/libraries/:id/stats', LibraryController.middleware.bind(this), LibraryController.stats.bind(this)) this.router.get('/libraries/:id/authors', LibraryController.middleware.bind(this), LibraryController.getAuthors.bind(this)) this.router.post('/libraries/:id/matchbooks', LibraryController.middleware.bind(this), LibraryController.matchBooks.bind(this)) + this.router.get('/libraries/:id/scan', LibraryController.middleware.bind(this), LibraryController.scan.bind(this)) // Root only this.router.post('/libraries/order', LibraryController.reorder.bind(this)) @@ -95,6 +93,7 @@ class ApiRouter { this.router.delete('/items/:id/cover', LibraryItemController.middleware.bind(this), LibraryItemController.removeCover.bind(this)) this.router.post('/items/:id/match', LibraryItemController.middleware.bind(this), LibraryItemController.match.bind(this)) this.router.post('/items/:id/play', LibraryItemController.middleware.bind(this), LibraryItemController.startPlaybackSession.bind(this)) + this.router.get('/items/:id/scan', LibraryItemController.middleware.bind(this), LibraryItemController.scan.bind(this)) // Root only this.router.post('/items/batch/delete', LibraryItemController.batchDelete.bind(this)) this.router.post('/items/batch/update', LibraryItemController.batchUpdate.bind(this)) @@ -146,14 +145,6 @@ class ApiRouter { this.router.delete('/backup/:id', BackupController.delete.bind(this)) this.router.post('/backup/upload', BackupController.upload.bind(this)) - // - // Search Routes - // - this.router.get('/search/covers', this.findCovers.bind(this)) - this.router.get('/search/books', this.findBooks.bind(this)) - this.router.get('/search/podcast', this.findPodcasts.bind(this)) - this.router.get('/search/authors', this.findAuthor.bind(this)) - // // File System Routes // @@ -183,102 +174,19 @@ class ApiRouter { // // Misc Routes // - this.router.patch('/serverSettings', this.updateServerSettings.bind(this)) - - this.router.post('/authorize', this.authorize.bind(this)) - - this.router.get('/download/:id', this.download.bind(this)) - - this.router.post('/purgecache', this.purgeCache.bind(this)) + this.router.post('/upload', MiscController.handleUpload.bind(this)) + this.router.get('/download/:id', MiscController.download.bind(this)) + this.router.patch('/settings', MiscController.updateServerSettings.bind(this)) // Root only + this.router.post('/purgecache', MiscController.purgeCache.bind(this)) // Root only + this.router.post('/getPodcastFeed', MiscController.getPodcastFeed.bind(this)) + this.router.post('/authorize', MiscController.authorize.bind(this)) + this.router.get('/search/covers', MiscController.findCovers.bind(this)) + this.router.get('/search/books', MiscController.findBooks.bind(this)) + this.router.get('/search/podcast', MiscController.findPodcasts.bind(this)) + this.router.get('/search/authors', MiscController.findAuthor.bind(this)) // OLD // this.router.post('/syncUserAudiobookData', this.syncUserAudiobookData.bind(this)) - - this.router.post('/getPodcastFeed', this.getPodcastFeed.bind(this)) - } - - async findBooks(req, res) { - var provider = req.query.provider || 'google' - var title = req.query.title || '' - var author = req.query.author || '' - var results = await this.bookFinder.search(provider, title, author) - res.json(results) - } - - async findCovers(req, res) { - var query = req.query - var result = await this.bookFinder.findCovers(query.provider, query.title, query.author || null) - res.json(result) - } - - async findPodcasts(req, res) { - var term = req.query.term - var results = await this.podcastFinder.search(term) - res.json(results) - } - - async findAuthor(req, res) { - var query = req.query.q - var author = await this.authorFinder.findAuthorByName(query) - res.json(author) - } - - authorize(req, res) { - if (!req.user) { - Logger.error('Invalid user in authorize') - return res.sendStatus(401) - } - res.json({ user: req.user }) - } - - async updateServerSettings(req, res) { - if (!req.user.isRoot) { - Logger.error('User other than root attempting to update server settings', req.user) - return res.sendStatus(403) - } - var settingsUpdate = req.body - if (!settingsUpdate || !isObject(settingsUpdate)) { - return res.status(500).send('Invalid settings update object') - } - - var madeUpdates = this.db.serverSettings.update(settingsUpdate) - if (madeUpdates) { - // If backup schedule is updated - update backup manager - if (settingsUpdate.backupSchedule !== undefined) { - this.backupManager.updateCronSchedule() - } - - await this.db.updateServerSettings() - } - return res.json({ - success: true, - serverSettings: this.db.serverSettings - }) - } - - async download(req, res) { - if (!req.user.canDownload) { - Logger.error('User attempting to download without permission', req.user) - return res.sendStatus(403) - } - var downloadId = req.params.id - Logger.info('Download Request', downloadId) - var download = this.downloadManager.getDownload(downloadId) - if (!download) { - Logger.error('Download request not found', downloadId) - return res.sendStatus(404) - } - - var options = { - headers: { - 'Content-Type': download.mimeType - } - } - res.download(download.fullPath, download.filename, options, (err) => { - if (err) { - Logger.error('Download Error', err) - } - }) } async getDirectories(dir, relpath, excludedDirs, level = 0) { @@ -450,15 +358,6 @@ class ApiRouter { return listeningStats } - async purgeCache(req, res) { - if (!req.user.isRoot) { - return res.sendStatus(403) - } - Logger.info(`[ApiRouter] Purging all cache`) - await this.cacheManager.purgeAll() - res.sendStatus(200) - } - async createAuthorsAndSeriesForItemUpdate(mediaPayload) { if (mediaPayload.metadata) { var mediaMetadata = mediaPayload.metadata @@ -512,27 +411,5 @@ class ApiRouter { } } } - - getPodcastFeed(req, res) { - var url = req.body.rssFeed - if (!url) { - return res.status(400).send('Bad request') - } - - axios.get(url).then(async (data) => { - if (!data || !data.data) { - Logger.error('Invalid podcast feed request response') - return res.status(500).send('Bad response from feed request') - } - var podcast = await parsePodcastRssFeedXml(data.data) - if (!podcast) { - return res.status(500).send('Invalid podcast RSS feed') - } - res.json(podcast) - }).catch((error) => { - console.error('Failed', error) - res.status(500).send(error) - }) - } } module.exports = ApiRouter \ No newline at end of file diff --git a/server/scanner/Scanner.js b/server/scanner/Scanner.js index 5be5deaa..c172feb8 100644 --- a/server/scanner/Scanner.js +++ b/server/scanner/Scanner.js @@ -109,17 +109,13 @@ class Scanner { return ScanResult.UPTODATE } - async scan(libraryId, options = {}) { - if (this.isLibraryScanning(libraryId)) { - Logger.error(`[Scanner] Already scanning ${libraryId}`) + async scan(library, options = {}) { + if (this.isLibraryScanning(library.id)) { + Logger.error(`[Scanner] Already scanning ${library.id}`) return } - var library = this.db.libraries.find(lib => lib.id === libraryId) - if (!library) { - Logger.error(`[Scanner] Library not found for scan ${libraryId}`) - return - } else if (!library.folders.length) { + if (!library.folders.length) { Logger.warn(`[Scanner] Library has no folders to scan "${library.name}"`) return }