mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Adds fetching book data on upload
This commit is contained in:
		
							parent
							
								
									aa933df525
								
							
						
					
					
						commit
						3cc900ffbf
					
				| @ -8,6 +8,12 @@ | |||||||
|       <span class="text-base text-white text-opacity-80 font-mono material-icons">close</span> |       <span class="text-base text-white text-opacity-80 font-mono material-icons">close</span> | ||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|  |     <div v-if="!isPodcast" | ||||||
|  |       class="w-8 h-8 bg-bg border border-white border-opacity-10 flex items-center justify-center rounded-full hover:bg-primary cursor-pointer" | ||||||
|  |       @click="fetchMetadata"> | ||||||
|  |       <span class="text-base text-white text-opacity-80 font-mono material-icons">refresh</span> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|     <template v-if="!uploadSuccess && !uploadFailed"> |     <template v-if="!uploadSuccess && !uploadFailed"> | ||||||
|       <widgets-alert v-if="error" type="error"> |       <widgets-alert v-if="error" type="error"> | ||||||
|         <p class="text-base">{{ error }}</p> |         <p class="text-base">{{ error }}</p> | ||||||
| @ -48,8 +54,8 @@ | |||||||
|       <p class="text-base">{{ $strings.MessageUploaderItemFailed }}</p> |       <p class="text-base">{{ $strings.MessageUploaderItemFailed }}</p> | ||||||
|     </widgets-alert> |     </widgets-alert> | ||||||
| 
 | 
 | ||||||
|     <div v-if="isUploading" class="absolute top-0 left-0 w-full h-full bg-black bg-opacity-50 flex items-center justify-center z-20"> |     <div v-if="isNonInteractable" class="absolute top-0 left-0 w-full h-full bg-black bg-opacity-50 flex items-center justify-center z-20"> | ||||||
|       <ui-loading-indicator :text="$strings.MessageUploading" /> |       <ui-loading-indicator :text="nonInteractionLabel" /> | ||||||
|     </div> |     </div> | ||||||
|   </div> |   </div> | ||||||
| </template> | </template> | ||||||
| @ -64,7 +70,8 @@ export default { | |||||||
|       default: () => { } |       default: () => { } | ||||||
|     }, |     }, | ||||||
|     mediaType: String, |     mediaType: String, | ||||||
|     processing: Boolean |     processing: Boolean, | ||||||
|  |     provider: String | ||||||
|   }, |   }, | ||||||
|   data() { |   data() { | ||||||
|     return { |     return { | ||||||
| @ -76,7 +83,8 @@ export default { | |||||||
|       error: '', |       error: '', | ||||||
|       isUploading: false, |       isUploading: false, | ||||||
|       uploadFailed: false, |       uploadFailed: false, | ||||||
|       uploadSuccess: false |       uploadSuccess: false, | ||||||
|  |       isFetchingMetadata: false | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   computed: { |   computed: { | ||||||
| @ -94,6 +102,16 @@ export default { | |||||||
|       } else { |       } else { | ||||||
|         return this.itemData.title |         return this.itemData.title | ||||||
|       } |       } | ||||||
|  |     }, | ||||||
|  |     isNonInteractable() { | ||||||
|  |       return this.isUploading || this.isFetchingMetadata | ||||||
|  |     }, | ||||||
|  |     nonInteractionLabel() { | ||||||
|  |       if (this.isUploading) { | ||||||
|  |         return this.$strings.MessageUploading | ||||||
|  |       } else if (this.isFetchingMetadata) { | ||||||
|  |         return this.$strings.LabelFetchingMetadata | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   methods: { |   methods: { | ||||||
| @ -105,6 +123,30 @@ export default { | |||||||
|     titleUpdated() { |     titleUpdated() { | ||||||
|       this.error = '' |       this.error = '' | ||||||
|     }, |     }, | ||||||
|  |     async fetchMetadata() { | ||||||
|  |       if (!this.itemData.title.trim().length) { | ||||||
|  |         return | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       this.isFetchingMetadata = true | ||||||
|  | 
 | ||||||
|  |       try { | ||||||
|  |         const searchQueryString = `title=${this.itemData.title}&author=${this.itemData.author}&provider=${this.provider}` | ||||||
|  |         const [bestCandidate, ..._rest] = await this.$axios.$get(`/api/search/books?${searchQueryString}`) | ||||||
|  | 
 | ||||||
|  |         this.itemData = { | ||||||
|  |           ...this.itemData, | ||||||
|  |           title: bestCandidate?.title, | ||||||
|  |           author: bestCandidate?.author, | ||||||
|  |           series: (bestCandidate?.series || [])[0]?.series | ||||||
|  |         } | ||||||
|  |       } catch (e) { | ||||||
|  |         console.error('Failed', e) | ||||||
|  |         // TODO: do something with the error? | ||||||
|  |       } finally { | ||||||
|  |         this.isFetchingMetadata = false | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     getData() { |     getData() { | ||||||
|       if (!this.itemData.title) { |       if (!this.itemData.title) { | ||||||
|         this.error = 'Must have a title' |         this.error = 'Must have a title' | ||||||
|  | |||||||
| @ -14,6 +14,14 @@ | |||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
| 
 | 
 | ||||||
|  |       <div v-if="!selectedLibraryIsPodcast" class="flex items-center py-2"> | ||||||
|  |         <ui-toggle-switch v-model="fetchMetadata.enabled" /> | ||||||
|  |         <p class="pl-4 text-base">{{ $strings.LabelAutoFetchMetadata }}</p> | ||||||
|  |         <div class="flex-grow ml-4"> | ||||||
|  |           <ui-dropdown v-model="fetchMetadata.provider" :items="providers" :label="$strings.LabelProvider" :disabled="!fetchMetadata.enabled" /> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  | 
 | ||||||
|       <widgets-alert v-if="error" type="error"> |       <widgets-alert v-if="error" type="error"> | ||||||
|         <p class="text-lg">{{ error }}</p> |         <p class="text-lg">{{ error }}</p> | ||||||
|       </widgets-alert> |       </widgets-alert> | ||||||
| @ -61,9 +69,16 @@ | |||||||
|       </widgets-alert> |       </widgets-alert> | ||||||
| 
 | 
 | ||||||
|       <!-- Item Upload cards --> |       <!-- Item Upload cards --> | ||||||
|       <template v-for="item in items"> |       <cards-item-upload-card  | ||||||
|         <cards-item-upload-card :ref="`itemCard-${item.index}`" :key="item.index" :media-type="selectedLibraryMediaType" :item="item" :processing="processing" @remove="removeItem(item)" /> |         v-for="item in items" | ||||||
|       </template> |         :key="item.index" | ||||||
|  |         :ref="`itemCard-${item.index}`" | ||||||
|  |         :media-type="selectedLibraryMediaType" | ||||||
|  |         :item="item" | ||||||
|  |         :provider="fetchMetadata.provider" | ||||||
|  |         :processing="processing" | ||||||
|  |         @remove="removeItem(item)" | ||||||
|  |       /> | ||||||
| 
 | 
 | ||||||
|       <!-- Upload/Reset btns --> |       <!-- Upload/Reset btns --> | ||||||
|       <div v-show="items.length" class="flex justify-end pb-8 pt-4"> |       <div v-show="items.length" class="flex justify-end pb-8 pt-4"> | ||||||
| @ -92,13 +107,18 @@ export default { | |||||||
|       selectedLibraryId: null, |       selectedLibraryId: null, | ||||||
|       selectedFolderId: null, |       selectedFolderId: null, | ||||||
|       processing: false, |       processing: false, | ||||||
|       uploadFinished: false |       uploadFinished: false, | ||||||
|  |       fetchMetadata: { | ||||||
|  |         enabled: false, | ||||||
|  |         provider: 'google' | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   watch: { |   watch: { | ||||||
|     selectedLibrary(newVal) { |     selectedLibrary(newVal) { | ||||||
|       if (newVal && !this.selectedFolderId) { |       if (newVal && !this.selectedFolderId) { | ||||||
|         this.setDefaultFolder() |         this.setDefaultFolder() | ||||||
|  |         this.setMetadataProvider() | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
| @ -133,6 +153,13 @@ export default { | |||||||
|     selectedLibraryIsPodcast() { |     selectedLibraryIsPodcast() { | ||||||
|       return this.selectedLibraryMediaType === 'podcast' |       return this.selectedLibraryMediaType === 'podcast' | ||||||
|     }, |     }, | ||||||
|  |     providers() { | ||||||
|  |       if (this.selectedLibraryIsPodcast) return this.$store.state.scanners.podcastProviders | ||||||
|  |       return this.$store.state.scanners.providers | ||||||
|  |     }, | ||||||
|  |     canFetchMetadata() { | ||||||
|  |       return !this.selectedLibraryIsPodcast && this.fetchMetadata.enabled | ||||||
|  |     }, | ||||||
|     selectedFolder() { |     selectedFolder() { | ||||||
|       if (!this.selectedLibrary) return null |       if (!this.selectedLibrary) return null | ||||||
|       return this.selectedLibrary.folders.find((fold) => fold.id === this.selectedFolderId) |       return this.selectedLibrary.folders.find((fold) => fold.id === this.selectedFolderId) | ||||||
| @ -160,12 +187,16 @@ export default { | |||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       this.setDefaultFolder() |       this.setDefaultFolder() | ||||||
|  |       this.setMetadataProvider() | ||||||
|     }, |     }, | ||||||
|     setDefaultFolder() { |     setDefaultFolder() { | ||||||
|       if (!this.selectedFolderId && this.selectedLibrary && this.selectedLibrary.folders.length) { |       if (!this.selectedFolderId && this.selectedLibrary && this.selectedLibrary.folders.length) { | ||||||
|         this.selectedFolderId = this.selectedLibrary.folders[0].id |         this.selectedFolderId = this.selectedLibrary.folders[0].id | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     setMetadataProvider() { | ||||||
|  |       this.fetchMetadata.provider = this.$store.getters['libraries/getLibraryProvider'](this.selectedLibraryId) | ||||||
|  |     }, | ||||||
|     removeItem(item) { |     removeItem(item) { | ||||||
|       this.items = this.items.filter((b) => b.index !== item.index) |       this.items = this.items.filter((b) => b.index !== item.index) | ||||||
|       if (!this.items.length) { |       if (!this.items.length) { | ||||||
| @ -213,27 +244,49 @@ export default { | |||||||
|       var items = e.dataTransfer.items || [] |       var items = e.dataTransfer.items || [] | ||||||
| 
 | 
 | ||||||
|       var itemResults = await this.uploadHelpers.getItemsFromDrop(items, this.selectedLibraryMediaType) |       var itemResults = await this.uploadHelpers.getItemsFromDrop(items, this.selectedLibraryMediaType) | ||||||
|       this.setResults(itemResults) |       this.onItemsSelected(itemResults) | ||||||
|     }, |     }, | ||||||
|     inputChanged(e) { |     inputChanged(e) { | ||||||
|       if (!e.target || !e.target.files) return |       if (!e.target || !e.target.files) return | ||||||
|       var _files = Array.from(e.target.files) |       var _files = Array.from(e.target.files) | ||||||
|       if (_files && _files.length) { |       if (_files && _files.length) { | ||||||
|         var itemResults = this.uploadHelpers.getItemsFromPicker(_files, this.selectedLibraryMediaType) |         var itemResults = this.uploadHelpers.getItemsFromPicker(_files, this.selectedLibraryMediaType) | ||||||
|         this.setResults(itemResults) |         this.onItemsSelected(itemResults) | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     setResults(itemResults) { |     onItemsSelected(itemResults) { | ||||||
|  |       if (this.itemSelectionSuccessful(itemResults)) { | ||||||
|  |         // setTimeout ensures the new item ref is attached before this method is called | ||||||
|  |         setTimeout(this.attemptMetadataFetch, 0) | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     itemSelectionSuccessful(itemResults) { | ||||||
|  |       console.log('Upload results', itemResults) | ||||||
|  | 
 | ||||||
|       if (itemResults.error) { |       if (itemResults.error) { | ||||||
|         this.error = itemResults.error |         this.error = itemResults.error | ||||||
|         this.items = [] |         this.items = [] | ||||||
|         this.ignoredFiles = [] |         this.ignoredFiles = [] | ||||||
|       } else { |         return false | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|       this.error = '' |       this.error = '' | ||||||
|       this.items = itemResults.items |       this.items = itemResults.items | ||||||
|       this.ignoredFiles = itemResults.ignoredFiles |       this.ignoredFiles = itemResults.ignoredFiles | ||||||
|  |       return true | ||||||
|  |     }, | ||||||
|  |     attemptMetadataFetch() { | ||||||
|  |       if (!this.canFetchMetadata) { | ||||||
|  |         return false | ||||||
|       } |       } | ||||||
|       console.log('Upload results', itemResults) | 
 | ||||||
|  |       this.items.forEach((item) => { | ||||||
|  |         let itemRef = this.$refs[`itemCard-${item.index}`] | ||||||
|  | 
 | ||||||
|  |         if (itemRef?.length) { | ||||||
|  |           itemRef[0].fetchMetadata(this.fetchMetadata.provider) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|     }, |     }, | ||||||
|     updateItemCardStatus(index, status) { |     updateItemCardStatus(index, status) { | ||||||
|       var ref = this.$refs[`itemCard-${index}`] |       var ref = this.$refs[`itemCard-${index}`] | ||||||
| @ -346,6 +399,8 @@ export default { | |||||||
|   }, |   }, | ||||||
|   mounted() { |   mounted() { | ||||||
|     this.selectedLibraryId = this.$store.state.libraries.currentLibraryId |     this.selectedLibraryId = this.$store.state.libraries.currentLibraryId | ||||||
|  |     this.setMetadataProvider() | ||||||
|  | 
 | ||||||
|     this.setDefaultFolder() |     this.setDefaultFolder() | ||||||
|     window.addEventListener('dragenter', this.dragenter) |     window.addEventListener('dragenter', this.dragenter) | ||||||
|     window.addEventListener('dragleave', this.dragleave) |     window.addEventListener('dragleave', this.dragleave) | ||||||
|  | |||||||
| @ -194,6 +194,7 @@ | |||||||
|   "LabelAuthorLastFirst": "Author (Last, First)", |   "LabelAuthorLastFirst": "Author (Last, First)", | ||||||
|   "LabelAuthors": "Authors", |   "LabelAuthors": "Authors", | ||||||
|   "LabelAutoDownloadEpisodes": "Auto Download Episodes", |   "LabelAutoDownloadEpisodes": "Auto Download Episodes", | ||||||
|  |   "LabelAutoFetchMetadata": "Auto Fetch Metadata", | ||||||
|   "LabelBackToUser": "Back to User", |   "LabelBackToUser": "Back to User", | ||||||
|   "LabelBackupLocation": "Backup Location", |   "LabelBackupLocation": "Backup Location", | ||||||
|   "LabelBackupsEnableAutomaticBackups": "Enable automatic backups", |   "LabelBackupsEnableAutomaticBackups": "Enable automatic backups", | ||||||
| @ -259,6 +260,7 @@ | |||||||
|   "LabelExample": "Example", |   "LabelExample": "Example", | ||||||
|   "LabelExplicit": "Explicit", |   "LabelExplicit": "Explicit", | ||||||
|   "LabelFeedURL": "Feed URL", |   "LabelFeedURL": "Feed URL", | ||||||
|  |   "LabelFetchingMetadata": "Fetching Metadata", | ||||||
|   "LabelFile": "File", |   "LabelFile": "File", | ||||||
|   "LabelFileBirthtime": "File Birthtime", |   "LabelFileBirthtime": "File Birthtime", | ||||||
|   "LabelFileModified": "File Modified", |   "LabelFileModified": "File Modified", | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user