mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-11-03 19:07:00 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			94 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			94 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
const Logger = require('./Logger')
 | 
						|
const BookFinder = require('./BookFinder')
 | 
						|
const Audiobook = require('./Audiobook')
 | 
						|
const audioFileScanner = require('./utils/audioFileScanner')
 | 
						|
const { getAllAudiobookFiles } = require('./utils/scandir')
 | 
						|
const { secondsToTimestamp } = require('./utils/fileUtils')
 | 
						|
 | 
						|
class Scanner {
 | 
						|
  constructor(AUDIOBOOK_PATH, METADATA_PATH, db, emitter) {
 | 
						|
    this.AudiobookPath = AUDIOBOOK_PATH
 | 
						|
    this.MetadataPath = METADATA_PATH
 | 
						|
    this.db = db
 | 
						|
    this.emitter = emitter
 | 
						|
 | 
						|
    this.bookFinder = new BookFinder()
 | 
						|
  }
 | 
						|
 | 
						|
  get audiobooks() {
 | 
						|
    return this.db.audiobooks
 | 
						|
  }
 | 
						|
 | 
						|
  async scan() {
 | 
						|
    // console.log('Start scan audiobooks', this.audiobooks.map(a => a.fullPath).join(', '))
 | 
						|
    const scanStart = Date.now()
 | 
						|
    var audiobookDataFound = await getAllAudiobookFiles(this.AudiobookPath)
 | 
						|
    for (let i = 0; i < audiobookDataFound.length; i++) {
 | 
						|
      var audiobookData = audiobookDataFound[i]
 | 
						|
      if (!audiobookData.parts.length) {
 | 
						|
        Logger.error('No Valid Parts for Audiobook', audiobookData)
 | 
						|
      } else {
 | 
						|
        var existingAudiobook = this.audiobooks.find(a => a.fullPath === audiobookData.fullPath)
 | 
						|
        if (existingAudiobook) {
 | 
						|
          Logger.info('Audiobook already added', audiobookData.title)
 | 
						|
          // Todo: Update Audiobook here
 | 
						|
        } else {
 | 
						|
          // console.log('Audiobook not already there... add new audiobook', audiobookData.fullPath)
 | 
						|
          var audiobook = new Audiobook()
 | 
						|
          audiobook.setData(audiobookData)
 | 
						|
          await audioFileScanner.scanParts(audiobook, audiobookData.parts)
 | 
						|
          if (!audiobook.tracks.length) {
 | 
						|
            Logger.warn('Invalid audiobook, no valid tracks', audiobook.title)
 | 
						|
          } else {
 | 
						|
            Logger.info('Audiobook Scanned', audiobook.title, `(${audiobook.sizePretty}) [${audiobook.durationPretty}]`)
 | 
						|
            await this.db.insertAudiobook(audiobook)
 | 
						|
            this.emitter('audiobook_added', audiobook.toJSONMinified())
 | 
						|
          }
 | 
						|
        }
 | 
						|
        var progress = Math.round(100 * (i + 1) / audiobookDataFound.length)
 | 
						|
        this.emitter('scan_progress', {
 | 
						|
          total: audiobookDataFound.length,
 | 
						|
          done: i + 1,
 | 
						|
          progress
 | 
						|
        })
 | 
						|
      }
 | 
						|
    }
 | 
						|
    const scanElapsed = Math.floor((Date.now() - scanStart) / 1000)
 | 
						|
    Logger.info(`[SCANNER] Finished ${secondsToTimestamp(scanElapsed)}`)
 | 
						|
  }
 | 
						|
 | 
						|
  async fetchMetadata(id, trackIndex = 0) {
 | 
						|
    var audiobook = this.audiobooks.find(a => a.id === id)
 | 
						|
    if (!audiobook) {
 | 
						|
      return false
 | 
						|
    }
 | 
						|
    var tracks = audiobook.tracks
 | 
						|
    var index = isNaN(trackIndex) ? 0 : Number(trackIndex)
 | 
						|
    var firstTrack = tracks[index]
 | 
						|
    var firstTrackFullPath = firstTrack.fullPath
 | 
						|
    var scanResult = await audioFileScanner.scan(firstTrackFullPath)
 | 
						|
    return scanResult
 | 
						|
  }
 | 
						|
 | 
						|
  async find(req, res) {
 | 
						|
    var method = req.params.method
 | 
						|
    var query = req.query
 | 
						|
 | 
						|
    var result = null
 | 
						|
 | 
						|
    if (method === 'isbn') {
 | 
						|
      result = await this.bookFinder.findByISBN(query)
 | 
						|
    } else if (method === 'search') {
 | 
						|
      result = await this.bookFinder.search(query.provider, query.title, query.author || null)
 | 
						|
    }
 | 
						|
 | 
						|
    res.json(result)
 | 
						|
  }
 | 
						|
 | 
						|
  async findCovers(req, res) {
 | 
						|
    var query = req.query
 | 
						|
    var result = await this.bookFinder.findCovers(query.provider, query.title, query.author || null)
 | 
						|
    res.json(result)
 | 
						|
  }
 | 
						|
}
 | 
						|
module.exports = Scanner |