mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Add:Abridged book detail, parse from audible, abridged book filter #1408
This commit is contained in:
		
							parent
							
								
									7181df0479
								
							
						
					
					
						commit
						fd58df4729
					
				| @ -185,6 +185,11 @@ export default { | ||||
|           value: 'tracks', | ||||
|           sublist: true | ||||
|         }, | ||||
|         { | ||||
|           text: this.$strings.LabelAbridged, | ||||
|           value: 'abridged', | ||||
|           sublist: false | ||||
|         }, | ||||
|         { | ||||
|           text: this.$strings.ButtonIssues, | ||||
|           value: 'issues', | ||||
|  | ||||
| @ -164,13 +164,20 @@ | ||||
|             <p v-if="mediaMetadata.releaseDate" class="text-xs ml-1 text-white text-opacity-60">{{ $strings.LabelCurrently }} {{ mediaMetadata.releaseDate || '' }}</p> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div v-if="selectedMatchOrig.explicit != null" class="flex items-center py-2"> | ||||
|         <div v-if="selectedMatchOrig.explicit != null" class="flex items-center pb-2" :class="{ 'pt-2': mediaMetadata.explicit == null }"> | ||||
|           <ui-checkbox v-model="selectedMatchUsage.explicit" checkbox-bg="bg" @input="checkboxToggled" /> | ||||
|           <div class="flex-grow ml-4"> | ||||
|             <ui-checkbox v-model="selectedMatch.explicit" :label="$strings.LabelExplicit" checkbox-bg="primary" border-color="gray-600" label-class="pl-2 text-base font-semibold" /> | ||||
|           <div class="flex-grow ml-4" :class="{ 'pt-4': mediaMetadata.explicit != null }"> | ||||
|             <ui-checkbox v-model="selectedMatch.explicit" :label="$strings.LabelExplicit" :disabled="!selectedMatchUsage.explicit" :checkbox-bg="!selectedMatchUsage.explicit ? 'bg' : 'primary'" border-color="gray-600" label-class="pl-2 text-base font-semibold" /> | ||||
|             <p v-if="mediaMetadata.explicit != null" class="text-xs ml-1 text-white text-opacity-60">{{ $strings.LabelCurrently }} {{ mediaMetadata.explicit ? 'Explicit (checked)' : 'Not Explicit (unchecked)' }}</p> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div v-if="selectedMatchOrig.abridged != null" class="flex items-center pb-2" :class="{ 'pt-2': mediaMetadata.abridged == null }"> | ||||
|           <ui-checkbox v-model="selectedMatchUsage.abridged" checkbox-bg="bg" @input="checkboxToggled" /> | ||||
|           <div class="flex-grow ml-4" :class="{ 'pt-4': mediaMetadata.abridged != null }"> | ||||
|             <ui-checkbox v-model="selectedMatch.abridged" :label="$strings.LabelAbridged" :disabled="!selectedMatchUsage.abridged" :checkbox-bg="!selectedMatchUsage.abridged ? 'bg' : 'primary'" border-color="gray-600" label-class="pl-2 text-base font-semibold" /> | ||||
|             <p v-if="mediaMetadata.abridged != null" class="text-xs ml-1 text-white text-opacity-60">{{ $strings.LabelCurrently }} {{ mediaMetadata.abridged ? 'Abridged (checked)' : 'Unabridged (unchecked)' }}</p> | ||||
|           </div> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="flex items-center justify-end py-2"> | ||||
|           <ui-btn color="success" type="submit">{{ $strings.ButtonSubmit }}</ui-btn> | ||||
| @ -216,6 +223,7 @@ export default { | ||||
|         explicit: true, | ||||
|         asin: true, | ||||
|         isbn: true, | ||||
|         abridged: true, | ||||
|         // Podcast specific | ||||
|         itunesPageUrl: true, | ||||
|         itunesId: true, | ||||
| @ -360,6 +368,7 @@ export default { | ||||
|         explicit: true, | ||||
|         asin: true, | ||||
|         isbn: true, | ||||
|         abridged: true, | ||||
|         // Podcast specific | ||||
|         itunesPageUrl: true, | ||||
|         itunesId: true, | ||||
| @ -476,7 +485,6 @@ export default { | ||||
|           } else if (key === 'narrator') { | ||||
|             updatePayload.metadata.narrators = this.selectedMatch[key].split(',').map((v) => v.trim()) | ||||
|           } else if (key === 'genres') { | ||||
|             // updatePayload.metadata.genres = this.selectedMatch[key].split(',').map((v) => v.trim()) | ||||
|             updatePayload.metadata.genres = [...this.selectedMatch[key]] | ||||
|           } else if (key === 'tags') { | ||||
|             updatePayload.tags = this.selectedMatch[key].split(',').map((v) => v.trim()) | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
|       <input v-model="selected" :disabled="disabled" type="checkbox" class="opacity-0 absolute" :class="!disabled ? 'cursor-pointer' : ''" /> | ||||
|       <svg v-if="selected" class="fill-current pointer-events-none" :class="svgClass" viewBox="0 0 20 20"><path d="M0 11l2-2 5 5L18 3l2 2L7 18z" /></svg> | ||||
|     </div> | ||||
|     <div v-if="label" class="select-none text-gray-100" :class="labelClassname">{{ label }}</div> | ||||
|     <div v-if="label" class="select-none" :class="[labelClassname, disabled ? 'text-gray-400' : 'text-gray-100']">{{ label }}</div> | ||||
|   </label> | ||||
| </template> | ||||
| 
 | ||||
|  | ||||
| @ -50,7 +50,7 @@ | ||||
|       </div> | ||||
| 
 | ||||
|       <div class="flex flex-wrap mt-2 -mx-1"> | ||||
|         <div class="w-full md:w-1/2 px-1"> | ||||
|         <div class="w-full md:w-1/4 px-1"> | ||||
|           <ui-text-input-with-label ref="publisherInput" v-model="details.publisher" :label="$strings.LabelPublisher" /> | ||||
|         </div> | ||||
|         <div class="w-1/2 md:w-1/4 px-1 mt-2 md:mt-0"> | ||||
| @ -61,6 +61,11 @@ | ||||
|             <ui-checkbox v-model="details.explicit" :label="$strings.LabelExplicit" checkbox-bg="primary" border-color="gray-600" label-class="pl-2 text-base font-semibold" /> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="flex-grow px-1 pt-6 mt-2 md:mt-0"> | ||||
|           <div class="flex justify-center"> | ||||
|             <ui-checkbox v-model="details.abridged" :label="$strings.LabelAbridged" checkbox-bg="primary" border-color="gray-600" label-class="pl-2 text-base font-semibold" /> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </form> | ||||
|   </div> | ||||
| @ -89,7 +94,8 @@ export default { | ||||
|         isbn: null, | ||||
|         asin: null, | ||||
|         genres: [], | ||||
|         explicit: false | ||||
|         explicit: false, | ||||
|         abridged: false | ||||
|       }, | ||||
|       newTags: [] | ||||
|     } | ||||
| @ -271,6 +277,7 @@ export default { | ||||
|       this.details.isbn = this.mediaMetadata.isbn || null | ||||
|       this.details.asin = this.mediaMetadata.asin || null | ||||
|       this.details.explicit = !!this.mediaMetadata.explicit | ||||
|       this.details.abridged = !!this.mediaMetadata.abridged | ||||
|       this.newTags = [...(this.media.tags || [])] | ||||
|     }, | ||||
|     submitForm() { | ||||
|  | ||||
| @ -124,6 +124,14 @@ | ||||
|                   {{ sizePretty }} | ||||
|                 </div> | ||||
|               </div> | ||||
|               <div v-if="isBook" class="flex py-0.5"> | ||||
|                 <div class="w-32"> | ||||
|                   <span class="text-white text-opacity-60 uppercase text-sm">{{ $strings.LabelAbridged }}</span> | ||||
|                 </div> | ||||
|                 <div> | ||||
|                   {{ isAbridged ? 'Yes' : 'No' }} | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|             <div class="hidden md:block flex-grow" /> | ||||
|           </div> | ||||
| @ -319,7 +327,10 @@ export default { | ||||
|       return this.libraryItem.isInvalid | ||||
|     }, | ||||
|     isExplicit() { | ||||
|       return this.mediaMetadata.explicit || false | ||||
|       return !!this.mediaMetadata.explicit | ||||
|     }, | ||||
|     isAbridged() { | ||||
|       return !!this.mediaMetadata.abridged | ||||
|     }, | ||||
|     invalidAudioFiles() { | ||||
|       if (!this.isBook) return [] | ||||
|  | ||||
| @ -155,6 +155,7 @@ | ||||
|   "HeaderUpdateLibrary": "Bibliothek aktualisieren", | ||||
|   "HeaderUsers": "Benutzer", | ||||
|   "HeaderYourStats": "Eigene Statistiken", | ||||
|   "LabelAbridged": "Abridged", | ||||
|   "LabelAccountType": "Kontoart", | ||||
|   "LabelAccountTypeAdmin": "Admin", | ||||
|   "LabelAccountTypeGuest": "Gast", | ||||
| @ -420,6 +421,7 @@ | ||||
|   "LabelTracksMultiTrack": "Mehrfachdatei", | ||||
|   "LabelTracksSingleTrack": "Einzeldatei", | ||||
|   "LabelType": "Typ", | ||||
|   "LabelUnabridged": "Unabridged", | ||||
|   "LabelUnknown": "Unbekannt", | ||||
|   "LabelUpdateCover": "Titelbild aktualisieren", | ||||
|   "LabelUpdateCoverHelp": "Erlaube das Überschreiben bestehender Titelbilder für die ausgewählten Hörbücher wenn eine Übereinstimmung gefunden wird", | ||||
|  | ||||
| @ -155,6 +155,7 @@ | ||||
|   "HeaderUpdateLibrary": "Update Library", | ||||
|   "HeaderUsers": "Users", | ||||
|   "HeaderYourStats": "Your Stats", | ||||
|   "LabelAbridged": "Abridged", | ||||
|   "LabelAccountType": "Account Type", | ||||
|   "LabelAccountTypeAdmin": "Admin", | ||||
|   "LabelAccountTypeGuest": "Guest", | ||||
| @ -420,6 +421,7 @@ | ||||
|   "LabelTracksMultiTrack": "Multi-track", | ||||
|   "LabelTracksSingleTrack": "Single-track", | ||||
|   "LabelType": "Type", | ||||
|   "LabelUnabridged": "Unabridged", | ||||
|   "LabelUnknown": "Unknown", | ||||
|   "LabelUpdateCover": "Update Cover", | ||||
|   "LabelUpdateCoverHelp": "Allow overwriting of existing covers for the selected books when a match is located", | ||||
| @ -636,4 +638,4 @@ | ||||
|   "ToastSocketFailedToConnect": "Socket failed to connect", | ||||
|   "ToastUserDeleteFailed": "Failed to delete user", | ||||
|   "ToastUserDeleteSuccess": "User deleted" | ||||
| } | ||||
| } | ||||
| @ -155,6 +155,7 @@ | ||||
|   "HeaderUpdateLibrary": "Actualizar Biblioteca", | ||||
|   "HeaderUsers": "Usuarios", | ||||
|   "HeaderYourStats": "Tus Estáticas", | ||||
|   "LabelAbridged": "Abridged", | ||||
|   "LabelAccountType": "Tipo de Cuenta", | ||||
|   "LabelAccountTypeAdmin": "Administrador", | ||||
|   "LabelAccountTypeGuest": "Invitado", | ||||
| @ -420,6 +421,7 @@ | ||||
|   "LabelTracksMultiTrack": "Multi-track", | ||||
|   "LabelTracksSingleTrack": "Single-track", | ||||
|   "LabelType": "Tipo", | ||||
|   "LabelUnabridged": "Unabridged", | ||||
|   "LabelUnknown": "Desconocido", | ||||
|   "LabelUpdateCover": "Actualizar Portada", | ||||
|   "LabelUpdateCoverHelp": "Permitir sobrescribir portadas existentes de los libros seleccionados cuando sean encontrados.", | ||||
|  | ||||
| @ -155,6 +155,7 @@ | ||||
|   "HeaderUpdateLibrary": "Mettre à jour la bibliothèque", | ||||
|   "HeaderUsers": "Utilisateurs", | ||||
|   "HeaderYourStats": "Vos statistiques", | ||||
|   "LabelAbridged": "Abridged", | ||||
|   "LabelAccountType": "Type de compte", | ||||
|   "LabelAccountTypeAdmin": "Admin", | ||||
|   "LabelAccountTypeGuest": "Invité", | ||||
| @ -420,6 +421,7 @@ | ||||
|   "LabelTracksMultiTrack": "Piste multiple", | ||||
|   "LabelTracksSingleTrack": "Piste simple", | ||||
|   "LabelType": "Type", | ||||
|   "LabelUnabridged": "Unabridged", | ||||
|   "LabelUnknown": "Inconnu", | ||||
|   "LabelUpdateCover": "Mettre à jour la couverture", | ||||
|   "LabelUpdateCoverHelp": "Autoriser la mise à jour de la couverture existante lorsqu’une correspondance est trouvée", | ||||
|  | ||||
| @ -155,6 +155,7 @@ | ||||
|   "HeaderUpdateLibrary": "Aktualiziraj biblioteku", | ||||
|   "HeaderUsers": "Korinici", | ||||
|   "HeaderYourStats": "Tvoja statistika", | ||||
|   "LabelAbridged": "Abridged", | ||||
|   "LabelAccountType": "Vrsta korisničkog računa", | ||||
|   "LabelAccountTypeAdmin": "Administrator", | ||||
|   "LabelAccountTypeGuest": "Gost", | ||||
| @ -420,6 +421,7 @@ | ||||
|   "LabelTracksMultiTrack": "Multi-track", | ||||
|   "LabelTracksSingleTrack": "Single-track", | ||||
|   "LabelType": "Tip", | ||||
|   "LabelUnabridged": "Unabridged", | ||||
|   "LabelUnknown": "Nepoznato", | ||||
|   "LabelUpdateCover": "Aktualiziraj Cover", | ||||
|   "LabelUpdateCoverHelp": "Dozvoli postavljanje novog covera za odabrane knjige nakon što je match pronađen.", | ||||
|  | ||||
| @ -155,6 +155,7 @@ | ||||
|   "HeaderUpdateLibrary": "Aggiorna Libreria", | ||||
|   "HeaderUsers": "Utenti", | ||||
|   "HeaderYourStats": "Statistiche Personali", | ||||
|   "LabelAbridged": "Abridged", | ||||
|   "LabelAccountType": "Tipo di Account", | ||||
|   "LabelAccountTypeAdmin": "Admin", | ||||
|   "LabelAccountTypeGuest": "Ospite", | ||||
| @ -420,6 +421,7 @@ | ||||
|   "LabelTracksMultiTrack": "Multi-traccia", | ||||
|   "LabelTracksSingleTrack": "Traccia-singola", | ||||
|   "LabelType": "Tipo", | ||||
|   "LabelUnabridged": "Unabridged", | ||||
|   "LabelUnknown": "Sconosciuto", | ||||
|   "LabelUpdateCover": "Aggiornamento Cover", | ||||
|   "LabelUpdateCoverHelp": "Consenti la sovrascrittura delle copertine esistenti per i libri selezionati quando viene trovata una corrispondenza", | ||||
| @ -636,4 +638,4 @@ | ||||
|   "ToastSocketFailedToConnect": "Socket non riesce a connettersi", | ||||
|   "ToastUserDeleteFailed": "Errore eliminazione utente", | ||||
|   "ToastUserDeleteSuccess": "Utente eliminato" | ||||
| } | ||||
| } | ||||
| @ -155,6 +155,7 @@ | ||||
|   "HeaderUpdateLibrary": "Zaktualizuj bibliotekę", | ||||
|   "HeaderUsers": "Użytkownicy", | ||||
|   "HeaderYourStats": "Twoje statystyki", | ||||
|   "LabelAbridged": "Abridged", | ||||
|   "LabelAccountType": "Typ konta", | ||||
|   "LabelAccountTypeAdmin": "Administrator", | ||||
|   "LabelAccountTypeGuest": "Gość", | ||||
| @ -420,6 +421,7 @@ | ||||
|   "LabelTracksMultiTrack": "Multi-track", | ||||
|   "LabelTracksSingleTrack": "Single-track", | ||||
|   "LabelType": "Typ", | ||||
|   "LabelUnabridged": "Unabridged", | ||||
|   "LabelUnknown": "Nieznany", | ||||
|   "LabelUpdateCover": "Zaktalizuj odkładkę", | ||||
|   "LabelUpdateCoverHelp": "Umożliwienie nadpisania istniejących okładek dla wybranych książek w przypadku znalezienia dopasowania", | ||||
|  | ||||
| @ -155,6 +155,7 @@ | ||||
|   "HeaderUpdateLibrary": "Обновить библиотеку", | ||||
|   "HeaderUsers": "Пользователи", | ||||
|   "HeaderYourStats": "Ваша статистика", | ||||
|   "LabelAbridged": "Abridged", | ||||
|   "LabelAccountType": "Тип учетной записи", | ||||
|   "LabelAccountTypeAdmin": "Администратор", | ||||
|   "LabelAccountTypeGuest": "Гость", | ||||
| @ -420,6 +421,7 @@ | ||||
|   "LabelTracksMultiTrack": "Мультитрек", | ||||
|   "LabelTracksSingleTrack": "Один трек", | ||||
|   "LabelType": "Тип", | ||||
|   "LabelUnabridged": "Unabridged", | ||||
|   "LabelUnknown": "Неизвестно", | ||||
|   "LabelUpdateCover": "Обновить обложку", | ||||
|   "LabelUpdateCoverHelp": "Позволяет перезаписывать существующие обложки для выбранных книг если будут найдены", | ||||
|  | ||||
| @ -155,6 +155,7 @@ | ||||
|   "HeaderUpdateLibrary": "更新媒体库", | ||||
|   "HeaderUsers": "用户", | ||||
|   "HeaderYourStats": "你的统计数据", | ||||
|   "LabelAbridged": "Abridged", | ||||
|   "LabelAccountType": "帐户类型", | ||||
|   "LabelAccountTypeAdmin": "管理员", | ||||
|   "LabelAccountTypeGuest": "来宾", | ||||
| @ -420,6 +421,7 @@ | ||||
|   "LabelTracksMultiTrack": "多轨", | ||||
|   "LabelTracksSingleTrack": "单轨", | ||||
|   "LabelType": "类型", | ||||
|   "LabelUnabridged": "Unabridged", | ||||
|   "LabelUnknown": "未知", | ||||
|   "LabelUpdateCover": "更新封面", | ||||
|   "LabelUpdateCoverHelp": "找到匹配项时允许覆盖所选书籍存在的封面", | ||||
|  | ||||
| @ -17,6 +17,7 @@ class BookMetadata { | ||||
|     this.asin = null | ||||
|     this.language = null | ||||
|     this.explicit = false | ||||
|     this.abridged = false | ||||
| 
 | ||||
|     if (metadata) { | ||||
|       this.construct(metadata) | ||||
| @ -38,6 +39,7 @@ class BookMetadata { | ||||
|     this.asin = metadata.asin | ||||
|     this.language = metadata.language | ||||
|     this.explicit = !!metadata.explicit | ||||
|     this.abridged = !!metadata.abridged | ||||
|   } | ||||
| 
 | ||||
|   toJSON() { | ||||
| @ -55,7 +57,8 @@ class BookMetadata { | ||||
|       isbn: this.isbn, | ||||
|       asin: this.asin, | ||||
|       language: this.language, | ||||
|       explicit: this.explicit | ||||
|       explicit: this.explicit, | ||||
|       abridged: this.abridged | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| @ -76,7 +79,8 @@ class BookMetadata { | ||||
|       isbn: this.isbn, | ||||
|       asin: this.asin, | ||||
|       language: this.language, | ||||
|       explicit: this.explicit | ||||
|       explicit: this.explicit, | ||||
|       abridged: this.abridged | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| @ -100,7 +104,8 @@ class BookMetadata { | ||||
|       authorName: this.authorName, | ||||
|       authorNameLF: this.authorNameLF, | ||||
|       narratorName: this.narratorName, | ||||
|       seriesName: this.seriesName | ||||
|       seriesName: this.seriesName, | ||||
|       abridged: this.abridged | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|  | ||||
| @ -19,7 +19,7 @@ class Audible { | ||||
|     } | ||||
| 
 | ||||
|     cleanResult(item) { | ||||
|         const { title, subtitle, asin, authors, narrators, publisherName, summary, releaseDate, image, genres, seriesPrimary, seriesSecondary, language, runtimeLengthMin } = item | ||||
|         const { title, subtitle, asin, authors, narrators, publisherName, summary, releaseDate, image, genres, seriesPrimary, seriesSecondary, language, runtimeLengthMin, formatType } = item | ||||
| 
 | ||||
|         const series = [] | ||||
|         if (seriesPrimary) { | ||||
| @ -54,7 +54,8 @@ class Audible { | ||||
|             language: language ? language.charAt(0).toUpperCase() + language.slice(1) : null, | ||||
|             duration: runtimeLengthMin && !isNaN(runtimeLengthMin) ? Number(runtimeLengthMin) : 0, | ||||
|             region: item.region || null, | ||||
|             rating: item.rating || null | ||||
|             rating: item.rating || null, | ||||
|             abridged: formatType === 'abridged' | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -793,7 +793,7 @@ class Scanner { | ||||
| 
 | ||||
|   async quickMatchBookBuildUpdatePayload(libraryItem, matchData, options) { | ||||
|     // Update media metadata if not set OR overrideDetails flag
 | ||||
|     const detailKeysToUpdate = ['title', 'subtitle', 'description', 'narrator', 'publisher', 'publishedYear', 'genres', 'tags', 'language', 'explicit', 'asin', 'isbn'] | ||||
|     const detailKeysToUpdate = ['title', 'subtitle', 'description', 'narrator', 'publisher', 'publishedYear', 'genres', 'tags', 'language', 'explicit', 'abridged', 'asin', 'isbn'] | ||||
|     const updatePayload = {} | ||||
|     updatePayload.metadata = {} | ||||
| 
 | ||||
|  | ||||
| @ -121,6 +121,10 @@ const bookMetadataMapper = { | ||||
|   explicit: { | ||||
|     to: (m) => m.explicit ? 'Y' : 'N', | ||||
|     from: (v) => v && v.toLowerCase() == 'y' | ||||
|   }, | ||||
|   abridged: { | ||||
|     to: (m) => m.abridged ? 'Y' : 'N', | ||||
|     from: (v) => v && v.toLowerCase() == 'y' | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -108,7 +108,7 @@ module.exports.reqSupportsWebp = (req) => { | ||||
| module.exports.areEquivalent = areEquivalent | ||||
| 
 | ||||
| module.exports.copyValue = (val) => { | ||||
|   if (!val) return null | ||||
|   if (!val) return val === false ? false : null | ||||
|   if (!this.isObject(val)) return val | ||||
| 
 | ||||
|   if (Array.isArray(val)) { | ||||
|  | ||||
| @ -67,6 +67,8 @@ module.exports = { | ||||
|       filtered = filtered.filter(li => li.hasIssues) | ||||
|     } else if (filterBy === 'feed-open') { | ||||
|       filtered = filtered.filter(li => feedsArray.some(feed => feed.entityId === li.id)) | ||||
|     } else if (filterBy === 'abridged') { | ||||
|       filtered = filtered.filter(li => !!li.media.metadata?.abridged) | ||||
|     } | ||||
| 
 | ||||
|     return filtered | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user