mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Remove NFO metadata and save metadata button
This commit is contained in:
		
							parent
							
								
									3f6ed6dbf9
								
							
						
					
					
						commit
						79a82df914
					
				| @ -9,10 +9,6 @@ | ||||
| 
 | ||||
|         <div class="flex-grow" /> | ||||
| 
 | ||||
|         <ui-tooltip v-if="!isMissing && mediaType == 'book'" text="(Root User Only) Save a NFO metadata file in your audiobooks directory" direction="bottom" class="mr-4 hidden sm:block"> | ||||
|           <ui-btn v-if="isRootUser" :loading="savingMetadata" color="bg" type="button" class="h-full" small @click.stop.prevent="saveMetadata">Save Metadata</ui-btn> | ||||
|         </ui-tooltip> | ||||
| 
 | ||||
|         <ui-tooltip v-if="mediaType == 'book'" :disabled="!!quickMatching" :text="`(Root User Only) Populate empty book details & cover with first book result from '${libraryProvider}'. Does not overwrite details.`" direction="bottom" class="mr-4"> | ||||
|           <ui-btn v-if="isRootUser" :loading="quickMatching" color="bg" type="button" class="h-full" small @click.stop.prevent="quickMatch">Quick Match</ui-btn> | ||||
|         </ui-tooltip> | ||||
| @ -40,7 +36,6 @@ export default { | ||||
|     return { | ||||
|       resettingProgress: false, | ||||
|       isScrollable: false, | ||||
|       savingMetadata: false, | ||||
|       rescanning: false, | ||||
|       quickMatching: false | ||||
|     } | ||||
| @ -144,24 +139,6 @@ export default { | ||||
|           this.rescanning = false | ||||
|         }) | ||||
|     }, | ||||
|     saveMetadataComplete(result) { | ||||
|       this.savingMetadata = false | ||||
|       if (result.error) { | ||||
|         this.$toast.error(result.error) | ||||
|       } else if (result.audiobookId) { | ||||
|         var { savedPath } = result | ||||
|         if (!savedPath) { | ||||
|           this.$toast.error(`Failed to save metadata file (${result.audiobookId})`) | ||||
|         } else { | ||||
|           this.$toast.success(`Metadata file saved "${result.audiobookTitle}"`) | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     saveMetadata() { | ||||
|       this.savingMetadata = true | ||||
|       this.$root.socket.once('save_metadata_complete', this.saveMetadataComplete) | ||||
|       this.$root.socket.emit('save_metadata', this.libraryItemId) | ||||
|     }, | ||||
|     submitForm() { | ||||
|       if (this.isProcessing) { | ||||
|         return | ||||
|  | ||||
| @ -225,11 +225,6 @@ class Server { | ||||
| 
 | ||||
|       // Scanning
 | ||||
|       socket.on('cancel_scan', this.cancelScan.bind(this)) | ||||
|       socket.on('save_metadata', (libraryItemId) => this.saveMetadata(socket, libraryItemId)) | ||||
| 
 | ||||
|       // Downloading
 | ||||
|       socket.on('download', (payload) => this.downloadManager.downloadSocketRequest(socket, payload)) | ||||
|       socket.on('remove_download', (downloadId) => this.downloadManager.removeSocketRequest(socket, downloadId)) | ||||
| 
 | ||||
|       // Logs
 | ||||
|       socket.on('set_log_listener', (level) => Logger.addSocketListener(socket, level)) | ||||
| @ -273,14 +268,6 @@ class Server { | ||||
|     this.scanner.setCancelLibraryScan(id) | ||||
|   } | ||||
| 
 | ||||
|   // Generates an NFO metadata file, if no audiobookId is passed then all audiobooks are done
 | ||||
|   async saveMetadata(socket, audiobookId = null) { | ||||
|     Logger.info('[Server] Starting save metadata files') | ||||
|     var response = await this.scanner.saveMetadata(audiobookId) | ||||
|     Logger.info(`[Server] Finished saving metadata files Successful: ${response.success}, Failed: ${response.failed}`) | ||||
|     socket.emit('save_metadata_complete', response) | ||||
|   } | ||||
| 
 | ||||
|   // Remove unused /metadata/items/{id} folders
 | ||||
|   async purgeMetadata() { | ||||
|     var itemsMetadata = Path.join(global.MetadataPath, 'items') | ||||
|  | ||||
| @ -243,8 +243,6 @@ class LibraryItem { | ||||
|     this.scanVersion = version | ||||
|   } | ||||
| 
 | ||||
|   saveMetadata() { } | ||||
| 
 | ||||
|   // Returns null if file not found, true if file was updated, false if up to date
 | ||||
|   //  updates existing LibraryFile, AudioFile, EBookFile's
 | ||||
|   checkFileFound(fileFound) { | ||||
|  | ||||
| @ -616,40 +616,6 @@ class Scanner { | ||||
|     return false | ||||
|   } | ||||
| 
 | ||||
|   // TODO: Redo metadata
 | ||||
|   async saveMetadata(audiobookId) { | ||||
|     // if (audiobookId) {
 | ||||
|     //   var audiobook = this.db.audiobooks.find(ab => ab.id === audiobookId)
 | ||||
|     //   if (!audiobook) {
 | ||||
|     //     return {
 | ||||
|     //       error: 'Audiobook not found'
 | ||||
|     //     }
 | ||||
|     //   }
 | ||||
|     //   var savedPath = await audiobook.writeNfoFile()
 | ||||
|     //   return {
 | ||||
|     //     audiobookId,
 | ||||
|     //     audiobookTitle: audiobook.title,
 | ||||
|     //     savedPath
 | ||||
|     //   }
 | ||||
|     // } else {
 | ||||
|     //   var response = {
 | ||||
|     //     success: 0,
 | ||||
|     //     failed: 0
 | ||||
|     //   }
 | ||||
|     //   for (let i = 0; i < this.db.audiobooks.length; i++) {
 | ||||
|     //     var audiobook = this.db.audiobooks[i]
 | ||||
|     //     var savedPath = await audiobook.writeNfoFile()
 | ||||
|     //     if (savedPath) {
 | ||||
|     //       Logger.info(`[Scanner] Saved metadata nfo ${savedPath}`)
 | ||||
|     //       response.success++
 | ||||
|     //     } else {
 | ||||
|     //       response.failed++
 | ||||
|     //     }
 | ||||
|     //   }
 | ||||
|     //   return response
 | ||||
|     // }
 | ||||
|   } | ||||
| 
 | ||||
|   async quickMatchBook(libraryItem, options = {}) { | ||||
|     var provider = options.provider || 'google' | ||||
|     var searchTitle = options.title || libraryItem.media.metadata.title | ||||
|  | ||||
| @ -1,91 +0,0 @@ | ||||
| const fs = require('fs-extra') | ||||
| const Path = require('path') | ||||
| const { bytesPretty } = require('./fileUtils') | ||||
| const Logger = require('../Logger') | ||||
| 
 | ||||
| const LEFT_COL_LEN = 25 | ||||
| 
 | ||||
| function sectionHeaderLines(title) { | ||||
|   return [title, ''.padEnd(10, '=')] | ||||
| } | ||||
| 
 | ||||
| function generateSection(sectionTitle, sectionData) { | ||||
|   var lines = sectionHeaderLines(sectionTitle) | ||||
|   for (const key in sectionData) { | ||||
|     var line = key.padEnd(LEFT_COL_LEN) + (sectionData[key] || '') | ||||
|     lines.push(line) | ||||
|   } | ||||
|   return lines | ||||
| } | ||||
| 
 | ||||
| async function generate(audiobook, nfoFilename = 'metadata.nfo') { | ||||
|   var jsonObj = audiobook.toJSON() | ||||
|   var book = jsonObj.book | ||||
| 
 | ||||
|   var generalSectionData = { | ||||
|     'Title': book.title, | ||||
|     'Subtitle': book.subtitle, | ||||
|     'Author': book.author, | ||||
|     'Narrator': book.narrator, | ||||
|     'Series': book.series, | ||||
|     'Volume Number': book.volumeNumber, | ||||
|     'Publish Year': book.publishedYear, | ||||
|     'Genre': book.genres ? book.genres.join(', ') : '', | ||||
|     'Duration': audiobook.durationPretty, | ||||
|     'Chapters': jsonObj.chapters.length | ||||
|   } | ||||
| 
 | ||||
|   if (!book.subtitle) { | ||||
|     delete generalSectionData['Subtitle'] | ||||
|   } | ||||
| 
 | ||||
|   if (!book.series) { | ||||
|     delete generalSectionData['Series'] | ||||
|     delete generalSectionData['Volume Number'] | ||||
|   } | ||||
| 
 | ||||
|   var tracks = audiobook.tracks | ||||
|   var audioTrack = tracks.length ? audiobook.tracks[0] : {} | ||||
| 
 | ||||
|   var totalBitrate = 0 | ||||
|   var numBitrates = 0 | ||||
|   for (let i = 0; i < tracks.length; i++) { | ||||
|     if (tracks[i].bitRate) { | ||||
|       totalBitrate += tracks[i].bitRate | ||||
|       numBitrates++ | ||||
|     } | ||||
|   } | ||||
|   var averageBitrate = numBitrates ? totalBitrate / numBitrates : 0 | ||||
| 
 | ||||
|   var mediaSectionData = { | ||||
|     'Tracks': jsonObj.tracks.length, | ||||
|     'Size': audiobook.sizePretty, | ||||
|     'Codec': audioTrack.codec, | ||||
|     'Ext': audioTrack.ext, | ||||
|     'Channels': audioTrack.channels, | ||||
|     'Channel Layout': audioTrack.channelLayout, | ||||
|     'Average Bitrate': bytesPretty(averageBitrate) | ||||
|   } | ||||
| 
 | ||||
|   var bookSection = generateSection('Book Info', generalSectionData) | ||||
| 
 | ||||
|   var descriptionSection = null | ||||
|   if (book.description) { | ||||
|     descriptionSection = sectionHeaderLines('Book Description') | ||||
|     descriptionSection.push(book.description) | ||||
|   } | ||||
| 
 | ||||
|   var mediaSection = generateSection('Media Info', mediaSectionData) | ||||
| 
 | ||||
|   var fullFile = bookSection.join('\n') + '\n\n' | ||||
|   if (descriptionSection) fullFile += descriptionSection.join('\n') + '\n\n' | ||||
|   fullFile += mediaSection.join('\n') | ||||
| 
 | ||||
|   var nfoPath = Path.join(audiobook.fullPath, nfoFilename) | ||||
|   var relativePath = Path.join(audiobook.path, nfoFilename) | ||||
|   return fs.writeFile(nfoPath, fullFile).then(() => relativePath).catch((error) => { | ||||
|     Logger.error(`Failed to write nfo file ${error}`) | ||||
|     return false | ||||
|   }) | ||||
| } | ||||
| module.exports = generate | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user