mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-11-02 18:37:01 -05:00 
			
		
		
		
	Scan for covers now saves covers, server settings to save covers in audiobook folder
This commit is contained in:
		
							parent
							
								
									28cbe0a95c
								
							
						
					
					
						commit
						a4bf3a759f
					
				@ -30,7 +30,7 @@ export default {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    className() {
 | 
					    className() {
 | 
				
			||||||
      if (this.disabled) return 'bg-bg cursor-not-allowed'
 | 
					      if (this.disabled) return this.toggleValue ? `bg-${this.onColor} cursor-not-allowed` : `bg-${this.offColor} cursor-not-allowed`
 | 
				
			||||||
      return this.toggleValue ? `bg-${this.onColor}` : `bg-${this.offColor}`
 | 
					      return this.toggleValue ? `bg-${this.onColor}` : `bg-${this.offColor}`
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    switchClassName() {
 | 
					    switchClassName() {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "audiobookshelf-client",
 | 
					  "name": "audiobookshelf-client",
 | 
				
			||||||
  "version": "1.3.3",
 | 
					  "version": "1.3.4",
 | 
				
			||||||
  "description": "Audiobook manager and player",
 | 
					  "description": "Audiobook manager and player",
 | 
				
			||||||
  "main": "index.js",
 | 
					  "main": "index.js",
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
 | 
				
			|||||||
@ -42,9 +42,9 @@
 | 
				
			|||||||
        <div class="flex items-start py-2">
 | 
					        <div class="flex items-start py-2">
 | 
				
			||||||
          <div class="py-2">
 | 
					          <div class="py-2">
 | 
				
			||||||
            <div class="flex items-center">
 | 
					            <div class="flex items-center">
 | 
				
			||||||
              <ui-toggle-switch v-model="newServerSettings.scannerParseSubtitle" @input="updateScannerParseSubtitle" />
 | 
					              <ui-toggle-switch v-model="newServerSettings.scannerParseSubtitle" :disabled="updatingServerSettings" @input="updateScannerParseSubtitle" />
 | 
				
			||||||
              <ui-tooltip :text="parseSubtitleTooltip">
 | 
					              <ui-tooltip :text="parseSubtitleTooltip">
 | 
				
			||||||
                <p class="pl-4 text-lg">Parse Subtitles <span class="material-icons icon-text">info_outlined</span></p>
 | 
					                <p class="pl-4 text-lg">Parse subtitles <span class="material-icons icon-text">info_outlined</span></p>
 | 
				
			||||||
              </ui-tooltip>
 | 
					              </ui-tooltip>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
@ -53,12 +53,30 @@
 | 
				
			|||||||
            <ui-btn color="success" class="mb-4" :loading="isScanning" :disabled="isScanningCovers" @click="scan">Scan</ui-btn>
 | 
					            <ui-btn color="success" class="mb-4" :loading="isScanning" :disabled="isScanningCovers" @click="scan">Scan</ui-btn>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <div class="w-full mb-4">
 | 
					            <div class="w-full mb-4">
 | 
				
			||||||
              <ui-tooltip direction="bottom" text="Only scans audiobooks without a cover. Covers will be applied if a close match is found." class="w-full">
 | 
					              <ui-tooltip direction="bottom" text="(Warning: Long running task!) Attempts to lookup and match a cover with all audiobooks that don't have one." class="w-full">
 | 
				
			||||||
                <ui-btn color="primary" class="w-full" small :padding-x="2" :loading="isScanningCovers" :disabled="isScanning" @click="scanCovers">Scan for Covers</ui-btn>
 | 
					                <ui-btn color="primary" class="w-full" small :padding-x="2" :loading="isScanningCovers" :disabled="isScanning" @click="scanCovers">Scan for Covers</ui-btn>
 | 
				
			||||||
              </ui-tooltip>
 | 
					              </ui-tooltip>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <!-- <ui-btn color="primary" small @click="saveMetadataFiles">Save Metadata</ui-btn> -->
 | 
					      <div class="py-4 mb-4">
 | 
				
			||||||
 | 
					        <p class="text-2xl">Metadata</p>
 | 
				
			||||||
 | 
					        <div class="flex items-start py-2">
 | 
				
			||||||
 | 
					          <div class="py-2">
 | 
				
			||||||
 | 
					            <div class="flex items-center">
 | 
				
			||||||
 | 
					              <ui-toggle-switch v-model="storeCoversInAudiobookDir" :disabled="updatingServerSettings" @input="updateCoverStorageDestination" />
 | 
				
			||||||
 | 
					              <ui-tooltip :text="coverDestinationTooltip">
 | 
				
			||||||
 | 
					                <p class="pl-4 text-lg">Store covers with audiobook <span class="material-icons icon-text">info_outlined</span></p>
 | 
				
			||||||
 | 
					              </ui-tooltip>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          <div class="flex-grow" />
 | 
				
			||||||
 | 
					          <div class="w-40 flex flex-col">
 | 
				
			||||||
 | 
					            <ui-tooltip :text="saveMetadataTooltip" direction="bottom" class="w-full">
 | 
				
			||||||
 | 
					              <ui-btn color="primary" small class="w-full" @click="saveMetadataFiles">Save Metadata</ui-btn>
 | 
				
			||||||
 | 
					            </ui-tooltip>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
@ -101,18 +119,21 @@ export default {
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  data() {
 | 
					  data() {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
 | 
					      storeCoversInAudiobookDir: false,
 | 
				
			||||||
      isResettingAudiobooks: false,
 | 
					      isResettingAudiobooks: false,
 | 
				
			||||||
      users: [],
 | 
					      users: [],
 | 
				
			||||||
      selectedAccount: null,
 | 
					      selectedAccount: null,
 | 
				
			||||||
      showAccountModal: false,
 | 
					      showAccountModal: false,
 | 
				
			||||||
      isDeletingUser: false,
 | 
					      isDeletingUser: false,
 | 
				
			||||||
      newServerSettings: {}
 | 
					      newServerSettings: {},
 | 
				
			||||||
 | 
					      updatingServerSettings: false
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  watch: {
 | 
					  watch: {
 | 
				
			||||||
    serverSettings(newVal, oldVal) {
 | 
					    serverSettings(newVal, oldVal) {
 | 
				
			||||||
      if (newVal && !oldVal) {
 | 
					      if (newVal && !oldVal) {
 | 
				
			||||||
        this.newServerSettings = { ...this.serverSettings }
 | 
					        this.newServerSettings = { ...this.serverSettings }
 | 
				
			||||||
 | 
					        this.storeCoversInAudiobookDir = this.newServerSettings.coverDestination === this.$constants.CoverDestination.AUDIOBOOK
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
@ -120,6 +141,12 @@ export default {
 | 
				
			|||||||
    parseSubtitleTooltip() {
 | 
					    parseSubtitleTooltip() {
 | 
				
			||||||
      return 'Extract subtitles from audiobook directory names.<br>Subtitle must be seperated by " - "<br>i.e. "Book Title - A Subtitle Here" has the subtitle "A Subtitle Here"'
 | 
					      return 'Extract subtitles from audiobook directory names.<br>Subtitle must be seperated by " - "<br>i.e. "Book Title - A Subtitle Here" has the subtitle "A Subtitle Here"'
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    coverDestinationTooltip() {
 | 
				
			||||||
 | 
					      return 'By default covers are stored in /metadata/books, enabling this setting will store covers inside your audiobooks directory. Only one file named "cover" will be kept.'
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    saveMetadataTooltip() {
 | 
				
			||||||
 | 
					      return 'This will write a "metadata.nfo" file in all of your audiobook directories.'
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    serverSettings() {
 | 
					    serverSettings() {
 | 
				
			||||||
      return this.$store.state.serverSettings
 | 
					      return this.$store.state.serverSettings
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@ -134,6 +161,12 @@ export default {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  methods: {
 | 
					  methods: {
 | 
				
			||||||
 | 
					    updateCoverStorageDestination(val) {
 | 
				
			||||||
 | 
					      this.newServerSettings.coverDestination = val ? this.$constants.CoverDestination.AUDIOBOOK : this.$constants.CoverDestination.METADATA
 | 
				
			||||||
 | 
					      this.updateServerSettings({
 | 
				
			||||||
 | 
					        coverDestination: this.newServerSettings.coverDestination
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    updateScannerParseSubtitle(val) {
 | 
					    updateScannerParseSubtitle(val) {
 | 
				
			||||||
      var payload = {
 | 
					      var payload = {
 | 
				
			||||||
        scannerParseSubtitle: val
 | 
					        scannerParseSubtitle: val
 | 
				
			||||||
@ -141,13 +174,16 @@ export default {
 | 
				
			|||||||
      this.updateServerSettings(payload)
 | 
					      this.updateServerSettings(payload)
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    updateServerSettings(payload) {
 | 
					    updateServerSettings(payload) {
 | 
				
			||||||
 | 
					      this.updatingServerSettings = true
 | 
				
			||||||
      this.$store
 | 
					      this.$store
 | 
				
			||||||
        .dispatch('updateServerSettings', payload)
 | 
					        .dispatch('updateServerSettings', payload)
 | 
				
			||||||
        .then((success) => {
 | 
					        .then((success) => {
 | 
				
			||||||
          console.log('Updated Server Settings', success)
 | 
					          console.log('Updated Server Settings', success)
 | 
				
			||||||
 | 
					          this.updatingServerSettings = false
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        .catch((error) => {
 | 
					        .catch((error) => {
 | 
				
			||||||
          console.error('Failed to update server settings', error)
 | 
					          console.error('Failed to update server settings', error)
 | 
				
			||||||
 | 
					          this.updatingServerSettings = false
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    setDeveloperMode() {
 | 
					    setDeveloperMode() {
 | 
				
			||||||
@ -161,7 +197,14 @@ export default {
 | 
				
			|||||||
    scanCovers() {
 | 
					    scanCovers() {
 | 
				
			||||||
      this.$root.socket.emit('scan_covers')
 | 
					      this.$root.socket.emit('scan_covers')
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    saveMetadataComplete(result) {
 | 
				
			||||||
 | 
					      this.savingMetadata = false
 | 
				
			||||||
 | 
					      if (!result) return
 | 
				
			||||||
 | 
					      this.$toast.success(`Metadata saved for ${result.success} audiobooks`)
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    saveMetadataFiles() {
 | 
					    saveMetadataFiles() {
 | 
				
			||||||
 | 
					      this.savingMetadata = true
 | 
				
			||||||
 | 
					      this.$root.socket.once('save_metadata_complete', this.saveMetadataComplete)
 | 
				
			||||||
      this.$root.socket.emit('save_metadata')
 | 
					      this.$root.socket.emit('save_metadata')
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    loadUsers() {
 | 
					    loadUsers() {
 | 
				
			||||||
@ -247,6 +290,7 @@ export default {
 | 
				
			|||||||
      this.$root.socket.on('user_removed', this.userRemoved)
 | 
					      this.$root.socket.on('user_removed', this.userRemoved)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      this.newServerSettings = this.serverSettings ? { ...this.serverSettings } : {}
 | 
					      this.newServerSettings = this.serverSettings ? { ...this.serverSettings } : {}
 | 
				
			||||||
 | 
					      this.storeCoversInAudiobookDir = this.newServerSettings.coverDestination === this.$constants.CoverDestination.AUDIOBOOK
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  mounted() {
 | 
					  mounted() {
 | 
				
			||||||
 | 
				
			|||||||
@ -5,8 +5,14 @@ const DownloadStatus = {
 | 
				
			|||||||
  FAILED: 3
 | 
					  FAILED: 3
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const CoverDestination = {
 | 
				
			||||||
 | 
					  METADATA: 0,
 | 
				
			||||||
 | 
					  AUDIOBOOK: 1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Constants = {
 | 
					const Constants = {
 | 
				
			||||||
  DownloadStatus
 | 
					  DownloadStatus,
 | 
				
			||||||
 | 
					  CoverDestination
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default ({ app }, inject) => {
 | 
					export default ({ app }, inject) => {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "audiobookshelf",
 | 
					  "name": "audiobookshelf",
 | 
				
			||||||
  "version": "1.3.3",
 | 
					  "version": "1.3.4",
 | 
				
			||||||
  "description": "Self-hosted audiobook server for managing and playing audiobooks",
 | 
					  "description": "Self-hosted audiobook server for managing and playing audiobooks",
 | 
				
			||||||
  "main": "index.js",
 | 
					  "main": "index.js",
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,6 @@ const imageType = require('image-type')
 | 
				
			|||||||
const globals = require('./utils/globals')
 | 
					const globals = require('./utils/globals')
 | 
				
			||||||
const { CoverDestination } = require('./utils/constants')
 | 
					const { CoverDestination } = require('./utils/constants')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class CoverController {
 | 
					class CoverController {
 | 
				
			||||||
  constructor(db, MetadataPath, AudiobookPath) {
 | 
					  constructor(db, MetadataPath, AudiobookPath) {
 | 
				
			||||||
    this.db = db
 | 
					    this.db = db
 | 
				
			||||||
@ -52,8 +51,8 @@ class CoverController {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Remove covers in metadata/books/{ID} that dont have the same filename as the new cover
 | 
					  // Remove covers that dont have the same filename as the new cover
 | 
				
			||||||
  async checkBookMetadataCovers(dirpath, newCoverExt) {
 | 
					  async removeOldCovers(dirpath, newCoverExt) {
 | 
				
			||||||
    var filesInDir = await this.getFilesInDirectory(dirpath)
 | 
					    var filesInDir = await this.getFilesInDirectory(dirpath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (let i = 0; i < filesInDir.length; i++) {
 | 
					    for (let i = 0; i < filesInDir.length; i++) {
 | 
				
			||||||
@ -97,17 +96,11 @@ class CoverController {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    var { fullPath, relPath } = this.getCoverDirectory(audiobook)
 | 
					    var { fullPath, relPath } = this.getCoverDirectory(audiobook)
 | 
				
			||||||
    await fs.ensureDir(fullPath)
 | 
					    await fs.ensureDir(fullPath)
 | 
				
			||||||
    var isStoringInMetadata = relPath.slice(1).startsWith('metadata')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var coverFilename = `cover${extname}`
 | 
					    var coverFilename = `cover${extname}`
 | 
				
			||||||
    var coverFullPath = Path.join(fullPath, coverFilename)
 | 
					    var coverFullPath = Path.join(fullPath, coverFilename)
 | 
				
			||||||
    var coverPath = Path.join(relPath, coverFilename)
 | 
					    var coverPath = Path.join(relPath, coverFilename)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (isStoringInMetadata) {
 | 
					 | 
				
			||||||
      await this.checkBookMetadataCovers(fullPath, extname)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Move cover from temp upload dir to destination
 | 
					    // Move cover from temp upload dir to destination
 | 
				
			||||||
    var success = await coverFile.mv(coverFullPath).then(() => true).catch((error) => {
 | 
					    var success = await coverFile.mv(coverFullPath).then(() => true).catch((error) => {
 | 
				
			||||||
      Logger.error('[CoverController] Failed to move cover file', path, error)
 | 
					      Logger.error('[CoverController] Failed to move cover file', path, error)
 | 
				
			||||||
@ -115,12 +108,13 @@ class CoverController {
 | 
				
			|||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!success) {
 | 
					    if (!success) {
 | 
				
			||||||
      // return res.status(500).send('Failed to move cover into destination')
 | 
					 | 
				
			||||||
      return {
 | 
					      return {
 | 
				
			||||||
        error: 'Failed to move cover into destination'
 | 
					        error: 'Failed to move cover into destination'
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await this.removeOldCovers(fullPath, extname)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Logger.info(`[CoverController] Uploaded audiobook cover "${coverPath}" for "${audiobook.title}"`)
 | 
					    Logger.info(`[CoverController] Uploaded audiobook cover "${coverPath}" for "${audiobook.title}"`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    audiobook.updateBookCover(coverPath)
 | 
					    audiobook.updateBookCover(coverPath)
 | 
				
			||||||
@ -171,10 +165,7 @@ class CoverController {
 | 
				
			|||||||
      var coverFullPath = Path.join(fullPath, coverFilename)
 | 
					      var coverFullPath = Path.join(fullPath, coverFilename)
 | 
				
			||||||
      await fs.rename(temppath, coverFullPath)
 | 
					      await fs.rename(temppath, coverFullPath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      var isStoringInMetadata = relPath.slice(1).startsWith('metadata')
 | 
					      await this.removeOldCovers(fullPath, '.' + imgtype.ext)
 | 
				
			||||||
      if (isStoringInMetadata) {
 | 
					 | 
				
			||||||
        await this.checkBookMetadataCovers(fullPath, '.' + imgtype.ext)
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      Logger.info(`[CoverController] Downloaded audiobook cover "${coverPath}" from url "${url}" for "${audiobook.title}"`)
 | 
					      Logger.info(`[CoverController] Downloaded audiobook cover "${coverPath}" from url "${url}" for "${audiobook.title}"`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -10,12 +10,13 @@ const { secondsToTimestamp } = require('./utils/fileUtils')
 | 
				
			|||||||
const { ScanResult, CoverDestination } = require('./utils/constants')
 | 
					const { ScanResult, CoverDestination } = require('./utils/constants')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Scanner {
 | 
					class Scanner {
 | 
				
			||||||
  constructor(AUDIOBOOK_PATH, METADATA_PATH, db, emitter) {
 | 
					  constructor(AUDIOBOOK_PATH, METADATA_PATH, db, coverController, emitter) {
 | 
				
			||||||
    this.AudiobookPath = AUDIOBOOK_PATH
 | 
					    this.AudiobookPath = AUDIOBOOK_PATH
 | 
				
			||||||
    this.MetadataPath = METADATA_PATH
 | 
					    this.MetadataPath = METADATA_PATH
 | 
				
			||||||
    this.BookMetadataPath = Path.join(this.MetadataPath, 'books')
 | 
					    this.BookMetadataPath = Path.join(this.MetadataPath, 'books')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.db = db
 | 
					    this.db = db
 | 
				
			||||||
 | 
					    this.coverController = coverController
 | 
				
			||||||
    this.emitter = emitter
 | 
					    this.emitter = emitter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.cancelScan = false
 | 
					    this.cancelScan = false
 | 
				
			||||||
@ -453,6 +454,8 @@ class Scanner {
 | 
				
			|||||||
    var audiobooksNeedingCover = this.audiobooks.filter(ab => !ab.cover && ab.author)
 | 
					    var audiobooksNeedingCover = this.audiobooks.filter(ab => !ab.cover && ab.author)
 | 
				
			||||||
    var found = 0
 | 
					    var found = 0
 | 
				
			||||||
    var notFound = 0
 | 
					    var notFound = 0
 | 
				
			||||||
 | 
					    var failed = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (let i = 0; i < audiobooksNeedingCover.length; i++) {
 | 
					    for (let i = 0; i < audiobooksNeedingCover.length; i++) {
 | 
				
			||||||
      var audiobook = audiobooksNeedingCover[i]
 | 
					      var audiobook = audiobooksNeedingCover[i]
 | 
				
			||||||
      var options = {
 | 
					      var options = {
 | 
				
			||||||
@ -462,10 +465,15 @@ class Scanner {
 | 
				
			|||||||
      var results = await this.bookFinder.findCovers('openlibrary', audiobook.title, audiobook.author, options)
 | 
					      var results = await this.bookFinder.findCovers('openlibrary', audiobook.title, audiobook.author, options)
 | 
				
			||||||
      if (results.length) {
 | 
					      if (results.length) {
 | 
				
			||||||
        Logger.debug(`[Scanner] Found best cover for "${audiobook.title}"`)
 | 
					        Logger.debug(`[Scanner] Found best cover for "${audiobook.title}"`)
 | 
				
			||||||
        audiobook.book.cover = results[0]
 | 
					        var coverUrl = results[0]
 | 
				
			||||||
        await this.db.updateAudiobook(audiobook)
 | 
					        var result = await this.coverController.downloadCoverFromUrl(audiobook, coverUrl)
 | 
				
			||||||
 | 
					        if (result.error) {
 | 
				
			||||||
 | 
					          failed++
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
          found++
 | 
					          found++
 | 
				
			||||||
 | 
					          await this.db.updateAudiobook(audiobook)
 | 
				
			||||||
          this.emitter('audiobook_updated', audiobook.toJSONMinified())
 | 
					          this.emitter('audiobook_updated', audiobook.toJSONMinified())
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        notFound++
 | 
					        notFound++
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
				
			|||||||
@ -36,10 +36,10 @@ class Server {
 | 
				
			|||||||
    this.db = new Db(this.ConfigPath)
 | 
					    this.db = new Db(this.ConfigPath)
 | 
				
			||||||
    this.auth = new Auth(this.db)
 | 
					    this.auth = new Auth(this.db)
 | 
				
			||||||
    this.watcher = new Watcher(this.AudiobookPath)
 | 
					    this.watcher = new Watcher(this.AudiobookPath)
 | 
				
			||||||
    this.scanner = new Scanner(this.AudiobookPath, this.MetadataPath, this.db, this.emitter.bind(this))
 | 
					    this.coverController = new CoverController(this.db, this.MetadataPath, this.AudiobookPath)
 | 
				
			||||||
 | 
					    this.scanner = new Scanner(this.AudiobookPath, this.MetadataPath, this.db, this.coverController, this.emitter.bind(this))
 | 
				
			||||||
    this.streamManager = new StreamManager(this.db, this.MetadataPath)
 | 
					    this.streamManager = new StreamManager(this.db, this.MetadataPath)
 | 
				
			||||||
    this.rssFeeds = new RssFeeds(this.Port, this.db)
 | 
					    this.rssFeeds = new RssFeeds(this.Port, this.db)
 | 
				
			||||||
    this.coverController = new CoverController(this.db, this.MetadataPath, this.AudiobookPath)
 | 
					 | 
				
			||||||
    this.downloadManager = new DownloadManager(this.db, this.MetadataPath, this.AudiobookPath, this.emitter.bind(this))
 | 
					    this.downloadManager = new DownloadManager(this.db, this.MetadataPath, this.AudiobookPath, this.emitter.bind(this))
 | 
				
			||||||
    this.apiController = new ApiController(this.MetadataPath, this.db, this.scanner, this.auth, this.streamManager, this.rssFeeds, this.downloadManager, this.coverController, this.emitter.bind(this), this.clientEmitter.bind(this))
 | 
					    this.apiController = new ApiController(this.MetadataPath, this.db, this.scanner, this.auth, this.streamManager, this.rssFeeds, this.downloadManager, this.coverController, this.emitter.bind(this), this.clientEmitter.bind(this))
 | 
				
			||||||
    this.hlsController = new HlsController(this.db, this.scanner, this.auth, this.streamManager, this.emitter.bind(this), this.streamManager.StreamsPath)
 | 
					    this.hlsController = new HlsController(this.db, this.scanner, this.auth, this.streamManager, this.emitter.bind(this), this.streamManager.StreamsPath)
 | 
				
			||||||
 | 
				
			|||||||
@ -437,7 +437,10 @@ class Audiobook {
 | 
				
			|||||||
    this.otherFiles = this.otherFiles.filter(f => newOtherFilePaths.includes(f.path))
 | 
					    this.otherFiles = this.otherFiles.filter(f => newOtherFilePaths.includes(f.path))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Some files are not there anymore and filtered out
 | 
					    // Some files are not there anymore and filtered out
 | 
				
			||||||
    if (currOtherFileNum !== this.otherFiles.length) hasUpdates = true
 | 
					    if (currOtherFileNum !== this.otherFiles.length) {
 | 
				
			||||||
 | 
					      Logger.debug(`[Audiobook] ${currOtherFileNum - this.otherFiles.length} other files were removed for "${this.title}"`)
 | 
				
			||||||
 | 
					      hasUpdates = true
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // If desc.txt is new or forcing rescan then read it and update description if empty
 | 
					    // If desc.txt is new or forcing rescan then read it and update description if empty
 | 
				
			||||||
    var descriptionTxt = newOtherFiles.find(file => file.filename === 'desc.txt')
 | 
					    var descriptionTxt = newOtherFiles.find(file => file.filename === 'desc.txt')
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user