Create podcast manager and re-organize managers

This commit is contained in:
advplyr 2022-03-20 16:41:06 -05:00
parent 122f2a2556
commit e1e6b46456
12 changed files with 86 additions and 65 deletions

View File

@ -17,15 +17,18 @@ const Auth = require('./Auth')
const Watcher = require('./Watcher')
const Scanner = require('./scanner/Scanner')
const Db = require('./Db')
const BackupManager = require('./BackupManager')
const LogManager = require('./LogManager')
const ApiRouter = require('./routers/ApiRouter')
const HlsRouter = require('./routers/HlsRouter')
const StaticRouter = require('./routers/StaticRouter')
const PlaybackSessionManager = require('./PlaybackSessionManager')
const DownloadManager = require('./DownloadManager')
const CoverController = require('./CoverController')
const CacheManager = require('./CacheManager')
const CoverManager = require('./managers/CoverManager')
const DownloadManager = require('./managers/DownloadManager')
const CacheManager = require('./managers/CacheManager')
const LogManager = require('./managers/LogManager')
const BackupManager = require('./managers/BackupManager')
const PlaybackSessionManager = require('./managers/PlaybackSessionManager')
const PodcastManager = require('./managers/PodcastManager')
class Server {
constructor(PORT, HOST, UID, GID, CONFIG_PATH, METADATA_PATH, AUDIOBOOK_PATH) {
@ -48,18 +51,22 @@ class Server {
fs.ensureDirSync(global.AudiobookPath, 0o774)
this.db = new Db()
this.watcher = new Watcher()
this.auth = new Auth(this.db)
// Managers
this.backupManager = new BackupManager(this.db, this.emitter.bind(this))
this.logManager = new LogManager(this.db)
this.cacheManager = new CacheManager()
this.watcher = new Watcher()
this.coverController = new CoverController(this.db, this.cacheManager)
this.scanner = new Scanner(this.db, this.coverController, this.emitter.bind(this))
this.playbackSessionManager = new PlaybackSessionManager(this.db, this.emitter.bind(this), this.clientEmitter.bind(this))
this.downloadManager = new DownloadManager(this.db)
this.playbackSessionManager = new PlaybackSessionManager(this.db, this.emitter.bind(this), this.clientEmitter.bind(this))
this.coverManager = new CoverManager(this.db, this.cacheManager)
this.podcastManager = new PodcastManager(this.db)
this.scanner = new Scanner(this.db, this.coverManager, this.emitter.bind(this))
// Routers
this.apiRouter = new ApiRouter(this.db, this.auth, this.scanner, this.playbackSessionManager, this.downloadManager, this.coverController, this.backupManager, this.watcher, this.cacheManager, this.emitter.bind(this), this.clientEmitter.bind(this))
this.apiRouter = new ApiRouter(this.db, this.auth, this.scanner, this.playbackSessionManager, this.downloadManager, this.coverManager, this.backupManager, this.watcher, this.cacheManager, this.podcastManager, this.emitter.bind(this), this.clientEmitter.bind(this))
this.hlsRouter = new HlsRouter(this.db, this.auth, this.playbackSessionManager, this.emitter.bind(this))
this.staticRouter = new StaticRouter(this.db)

View File

@ -16,7 +16,7 @@ class AuthorController {
this.cacheManager.purgeImageCache(req.author.id)
if (!payload.imagePath) { // If removing image then remove file
var currentImagePath = req.author.imagePath
await this.coverController.removeFile(currentImagePath)
await this.coverManager.removeFile(currentImagePath)
}
}

View File

@ -68,10 +68,10 @@ class LibraryItemController {
var result = null
if (req.body && req.body.url) {
Logger.debug(`[LibraryItemController] Requesting download cover from url "${req.body.url}"`)
result = await this.coverController.downloadCoverFromUrl(libraryItem, req.body.url)
result = await this.coverManager.downloadCoverFromUrl(libraryItem, req.body.url)
} else if (req.files && req.files.cover) {
Logger.debug(`[LibraryItemController] Handling uploaded cover`)
result = await this.coverController.uploadCover(libraryItem, req.files.cover)
result = await this.coverManager.uploadCover(libraryItem, req.files.cover)
} else {
return res.status(400).send('Invalid request no file or url')
}
@ -97,7 +97,7 @@ class LibraryItemController {
return res.status(400).error('Invalid request no cover path')
}
var validationResult = await this.coverController.validateCoverPath(req.body.cover, libraryItem)
var validationResult = await this.coverManager.validateCoverPath(req.body.cover, libraryItem)
if (validationResult.error) {
return res.status(500).send(validationResult.error)
}

View File

@ -6,11 +6,11 @@ const archiver = require('archiver')
const StreamZip = require('node-stream-zip')
// Utils
const { getFileSize } = require('./utils/fileUtils')
const filePerms = require('./utils/filePerms')
const Logger = require('./Logger')
const { getFileSize } = require('../utils/fileUtils')
const filePerms = require('../utils/filePerms')
const Logger = require('../Logger')
const Backup = require('./objects/Backup')
const Backup = require('../objects/Backup')
class BackupManager {
constructor(db, emitter) {

View File

@ -1,8 +1,8 @@
const Path = require('path')
const fs = require('fs-extra')
const stream = require('stream')
const Logger = require('./Logger')
const { resizeImage } = require('./utils/ffmpegHelpers')
const Logger = require('../Logger')
const { resizeImage } = require('../utils/ffmpegHelpers')
class CacheManager {
constructor() {

View File

@ -1,16 +1,16 @@
const fs = require('fs-extra')
const Path = require('path')
const axios = require('axios')
const Logger = require('./Logger')
const Logger = require('../Logger')
const readChunk = require('read-chunk')
const imageType = require('image-type')
const filePerms = require('./utils/filePerms')
const filePerms = require('../utils/filePerms')
const globals = require('./utils/globals')
const { downloadFile } = require('./utils/fileUtils')
const { extractCoverArt } = require('./utils/ffmpegHelpers')
const globals = require('../utils/globals')
const { downloadFile } = require('../utils/fileUtils')
const { extractCoverArt } = require('../utils/ffmpegHelpers')
class CoverController {
class CoverManager {
constructor(db, cacheManager) {
this.db = db
this.cacheManager = cacheManager
@ -30,7 +30,7 @@ class CoverController {
try {
return fs.readdir(dir)
} catch (error) {
Logger.error(`[CoverController] Failed to get files in dir ${dir}`, error)
Logger.error(`[CoverManager] Failed to get files in dir ${dir}`, error)
return []
}
}
@ -38,11 +38,11 @@ class CoverController {
removeFile(filepath) {
try {
return fs.pathExists(filepath).then((exists) => {
if (!exists) Logger.warn(`[CoverController] Attempting to remove file that does not exist ${filepath}`)
if (!exists) Logger.warn(`[CoverManager] Attempting to remove file that does not exist ${filepath}`)
return exists ? fs.unlink(filepath) : false
})
} catch (error) {
Logger.error(`[CoverController] Failed to remove file "${filepath}"`, error)
Logger.error(`[CoverManager] Failed to remove file "${filepath}"`, error)
return false
}
}
@ -57,7 +57,7 @@ class CoverController {
var _filename = Path.basename(file, _extname)
if (_filename === 'cover' && _extname !== newCoverExt) {
var filepath = Path.join(dirpath, file)
Logger.debug(`[CoverController] Removing old cover from metadata "${filepath}"`)
Logger.debug(`[CoverManager] Removing old cover from metadata "${filepath}"`)
await this.removeFile(filepath)
}
}
@ -97,7 +97,7 @@ class CoverController {
// Move cover from temp upload dir to destination
var success = await coverFile.mv(coverFullPath).then(() => true).catch((error) => {
Logger.error('[CoverController] Failed to move cover file', path, error)
Logger.error('[CoverManager] Failed to move cover file', path, error)
return false
})
@ -110,7 +110,7 @@ class CoverController {
await this.removeOldCovers(coverDirPath, extname)
await this.cacheManager.purgeCoverCache(libraryItem.id)
Logger.info(`[CoverController] Uploaded libraryItem cover "${coverFullPath}" for "${libraryItem.media.metadata.title}"`)
Logger.info(`[CoverManager] Uploaded libraryItem cover "${coverFullPath}" for "${libraryItem.media.metadata.title}"`)
libraryItem.updateMediaCover(coverFullPath)
return {
@ -125,7 +125,7 @@ class CoverController {
var temppath = Path.posix.join(coverDirPath, 'cover')
var success = await downloadFile(url, temppath).then(() => true).catch((err) => {
Logger.error(`[CoverController] Download image file failed for "${url}"`, err)
Logger.error(`[CoverManager] Download image file failed for "${url}"`, err)
return false
})
if (!success) {
@ -147,14 +147,14 @@ class CoverController {
await this.removeOldCovers(coverDirPath, '.' + imgtype.ext)
await this.cacheManager.purgeCoverCache(libraryItem.id)
Logger.info(`[CoverController] Downloaded libraryItem cover "${coverFullPath}" from url "${url}" for "${libraryItem.media.metadata.title}"`)
Logger.info(`[CoverManager] Downloaded libraryItem cover "${coverFullPath}" from url "${url}" for "${libraryItem.media.metadata.title}"`)
libraryItem.updateMediaCover(coverFullPath)
return {
cover: coverFullPath
}
} catch (error) {
Logger.error(`[CoverController] Fetch cover image from url "${url}" failed`, error)
Logger.error(`[CoverManager] Fetch cover image from url "${url}" failed`, error)
return {
error: 'Failed to fetch image from url'
}
@ -164,7 +164,7 @@ class CoverController {
async validateCoverPath(coverPath, libraryItem) {
// Invalid cover path
if (!coverPath || coverPath.startsWith('http:') || coverPath.startsWith('https:')) {
Logger.error(`[CoverController] validate cover path invalid http url "${coverPath}"`)
Logger.error(`[CoverManager] validate cover path invalid http url "${coverPath}"`)
return {
error: 'Invalid cover path'
}
@ -172,7 +172,7 @@ class CoverController {
coverPath = coverPath.replace(/\\/g, '/')
// Cover path already set on media
if (libraryItem.media.coverPath == coverPath) {
Logger.debug(`[CoverController] validate cover path already set "${coverPath}"`)
Logger.debug(`[CoverManager] validate cover path already set "${coverPath}"`)
return {
cover: coverPath,
updated: false
@ -180,7 +180,7 @@ class CoverController {
}
// Cover path does not exist
if (!await fs.pathExists(coverPath)) {
Logger.error(`[CoverController] validate cover path does not exist "${coverPath}"`)
Logger.error(`[CoverManager] validate cover path does not exist "${coverPath}"`)
return {
error: 'Cover path does not exist'
}
@ -199,10 +199,10 @@ class CoverController {
var coverFilename = `cover.${imgtype.ext}`
var newCoverPath = Path.posix.join(coverDirPath, coverFilename)
Logger.debug(`[CoverController] validate cover path copy cover from "${coverPath}" to "${newCoverPath}"`)
Logger.debug(`[CoverManager] validate cover path copy cover from "${coverPath}" to "${newCoverPath}"`)
var copySuccess = await fs.copy(coverPath, newCoverPath, { overwrite: true }).then(() => true).catch((error) => {
Logger.error(`[CoverController] validate cover path failed to copy cover`, error)
Logger.error(`[CoverManager] validate cover path failed to copy cover`, error)
return false
})
if (!copySuccess) {
@ -212,7 +212,7 @@ class CoverController {
}
await filePerms.setDefault(newCoverPath)
await this.removeOldCovers(coverDirPath, '.' + imgtype.ext)
Logger.debug(`[CoverController] cover copy success`)
Logger.debug(`[CoverManager] cover copy success`)
coverPath = newCoverPath
}
@ -237,7 +237,7 @@ class CoverController {
var coverAlreadyExists = await fs.pathExists(coverFilePath)
if (coverAlreadyExists) {
Logger.warn(`[CoverController] Extract embedded cover art but cover already exists for "${libraryItem.media.metadata.title}" - bail`)
Logger.warn(`[CoverManager] Extract embedded cover art but cover already exists for "${libraryItem.media.metadata.title}" - bail`)
return false
}
@ -249,4 +249,4 @@ class CoverController {
return false
}
}
module.exports = CoverController
module.exports = CoverManager

View File

@ -3,13 +3,14 @@ const fs = require('fs-extra')
const archiver = require('archiver')
const workerThreads = require('worker_threads')
const Logger = require('./Logger')
const Download = require('./objects/Download')
const filePerms = require('./utils/filePerms')
const { getId } = require('./utils/index')
const { writeConcatFile, writeMetadataFile } = require('./utils/ffmpegHelpers')
const { getFileSize } = require('./utils/fileUtils')
const Logger = require('../Logger')
const Download = require('../objects/Download')
const filePerms = require('../utils/filePerms')
const { getId } = require('../utils/index')
const { writeConcatFile, writeMetadataFile } = require('../utils/ffmpegHelpers')
const { getFileSize } = require('../utils/fileUtils')
const TAG = 'DownloadManager'
class DownloadManager {
constructor(db) {
this.db = db

View File

@ -1,9 +1,9 @@
const Path = require('path')
const fs = require('fs-extra')
const DailyLog = require('./objects/DailyLog')
const DailyLog = require('../objects/DailyLog')
const Logger = require('./Logger')
const Logger = require('../Logger')
const TAG = '[LogManager]'

View File

@ -1,8 +1,8 @@
const Path = require('path')
const { PlayMethod } = require('./utils/constants')
const PlaybackSession = require('./objects/PlaybackSession')
const Stream = require('./objects/Stream')
const Logger = require('./Logger')
const { PlayMethod } = require('../utils/constants')
const PlaybackSession = require('../objects/PlaybackSession')
const Stream = require('../objects/Stream')
const Logger = require('../Logger')
class PlaybackSessionManager {
constructor(db, emitter, clientEmitter) {

View File

@ -0,0 +1,12 @@
class PodcastManager {
constructor(db) {
this.db = db
this.downloadQueue = []
}
async downloadPodcasts(podcasts, targetDir) {
}
}
module.exports = PodcastManager

View File

@ -26,16 +26,17 @@ const Series = require('../objects/entities/Series')
const FileSystemController = require('../controllers/FileSystemController')
class ApiRouter {
constructor(db, auth, scanner, playbackSessionManager, downloadManager, coverController, backupManager, watcher, cacheManager, emitter, clientEmitter) {
constructor(db, auth, scanner, playbackSessionManager, downloadManager, coverManager, backupManager, watcher, cacheManager, podcastManager, emitter, clientEmitter) {
this.db = db
this.auth = auth
this.scanner = scanner
this.playbackSessionManager = playbackSessionManager
this.downloadManager = downloadManager
this.backupManager = backupManager
this.coverController = coverController
this.coverManager = coverManager
this.watcher = watcher
this.cacheManager = cacheManager
this.podcastManager = podcastManager
this.emitter = emitter
this.clientEmitter = clientEmitter

View File

@ -17,11 +17,11 @@ const Author = require('../objects/entities/Author')
const Series = require('../objects/entities/Series')
class Scanner {
constructor(db, coverController, emitter) {
constructor(db, coverManager, emitter) {
this.ScanLogPath = Path.posix.join(global.MetadataPath, 'logs', 'scans')
this.db = db
this.coverController = coverController
this.coverManager = coverManager
this.emitter = emitter
this.cancelLibraryScan = {}
@ -84,7 +84,7 @@ class Scanner {
// Extract embedded cover art if cover is not already in directory
if (libraryItem.media.hasEmbeddedCoverArt && !libraryItem.media.coverPath) {
var coverPath = await this.coverController.saveEmbeddedCoverArt(libraryItem)
var coverPath = await this.coverManager.saveEmbeddedCoverArt(libraryItem)
if (coverPath) {
Logger.debug(`[Scanner] Saved embedded cover art "${coverPath}"`)
hasUpdated = true
@ -348,7 +348,7 @@ class Scanner {
// If an audio file has embedded cover art and no cover is set yet, extract & use it
if (newAudioFiles.length || libraryScan.scanOptions.forceRescan) {
if (libraryItem.media.hasEmbeddedCoverArt && !libraryItem.media.coverPath) {
var savedCoverPath = await this.coverController.saveEmbeddedCoverArt(libraryItem)
var savedCoverPath = await this.coverManager.saveEmbeddedCoverArt(libraryItem)
if (savedCoverPath) {
hasUpdated = true
libraryScan.addLog(LogLevel.DEBUG, `Saved embedded cover art "${savedCoverPath}"`)
@ -395,7 +395,7 @@ class Scanner {
// Extract embedded cover art if cover is not already in directory
if (libraryItem.media.hasEmbeddedCoverArt && !libraryItem.media.coverPath) {
var coverPath = await this.coverController.saveEmbeddedCoverArt(libraryItem)
var coverPath = await this.coverManager.saveEmbeddedCoverArt(libraryItem)
if (coverPath) {
if (libraryScan) libraryScan.addLog(LogLevel.DEBUG, `Saved embedded cover art "${coverPath}"`)
else Logger.debug(`[Scanner] Saved embedded cover art "${coverPath}"`)
@ -600,7 +600,7 @@ class Scanner {
for (let i = 0; i < results.length && i < 2; i++) {
// Downloads and updates the book cover
var result = await this.coverController.downloadCoverFromUrl(libraryItem, results[i])
var result = await this.coverManager.downloadCoverFromUrl(libraryItem, results[i])
if (result.error) {
Logger.error(`[Scanner] Failed to download cover from url "${results[i]}" | Attempt ${i + 1}`, result.error)
@ -662,7 +662,7 @@ class Scanner {
var hasUpdated = false
if (matchData.cover && (!libraryItem.media.coverPath || options.overrideCover)) {
Logger.debug(`[Scanner] Updating cover "${matchData.cover}"`)
var coverResult = await this.coverController.downloadCoverFromUrl(libraryItem, matchData.cover)
var coverResult = await this.coverManager.downloadCoverFromUrl(libraryItem, matchData.cover)
if (!coverResult || coverResult.error || !coverResult.cover) {
Logger.warn(`[Scanner] Match cover "${matchData.cover}" failed to use: ${coverResult ? coverResult.error : 'Unknown Error'}`)
} else {