mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-30 18:12:25 -04:00 
			
		
		
		
	Merge pull request #2491 from liaochuan/liaocl
Add Podcast Search Region
This commit is contained in:
		
						commit
						fdc1fc1b2a
					
				| @ -49,6 +49,9 @@ | |||||||
|         </ui-tooltip> |         </ui-tooltip> | ||||||
|       </div> |       </div> | ||||||
|     </div> |     </div> | ||||||
|  |     <div v-if="isPodcastLibrary" class="py-3"> | ||||||
|  |       <ui-dropdown :label="$strings.LabelPodcastSearchRegion" v-model="podcastSearchRegion" :items="$podcastSearchRegionOptions" small class="max-w-52" @input="formUpdated" /> | ||||||
|  |     </div> | ||||||
|   </div> |   </div> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| @ -69,7 +72,8 @@ export default { | |||||||
|       skipMatchingMediaWithAsin: false, |       skipMatchingMediaWithAsin: false, | ||||||
|       skipMatchingMediaWithIsbn: false, |       skipMatchingMediaWithIsbn: false, | ||||||
|       audiobooksOnly: false, |       audiobooksOnly: false, | ||||||
|       hideSingleBookSeries: false |       hideSingleBookSeries: false, | ||||||
|  |       podcastSearchRegion: 'us' | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   computed: { |   computed: { | ||||||
| @ -85,6 +89,9 @@ export default { | |||||||
|     isBookLibrary() { |     isBookLibrary() { | ||||||
|       return this.mediaType === 'book' |       return this.mediaType === 'book' | ||||||
|     }, |     }, | ||||||
|  |     isPodcastLibrary() { | ||||||
|  |       return this.mediaType === 'podcast' | ||||||
|  |     }, | ||||||
|     providers() { |     providers() { | ||||||
|       if (this.mediaType === 'podcast') return this.$store.state.scanners.podcastProviders |       if (this.mediaType === 'podcast') return this.$store.state.scanners.podcastProviders | ||||||
|       return this.$store.state.scanners.providers |       return this.$store.state.scanners.providers | ||||||
| @ -99,7 +106,8 @@ export default { | |||||||
|           skipMatchingMediaWithAsin: !!this.skipMatchingMediaWithAsin, |           skipMatchingMediaWithAsin: !!this.skipMatchingMediaWithAsin, | ||||||
|           skipMatchingMediaWithIsbn: !!this.skipMatchingMediaWithIsbn, |           skipMatchingMediaWithIsbn: !!this.skipMatchingMediaWithIsbn, | ||||||
|           audiobooksOnly: !!this.audiobooksOnly, |           audiobooksOnly: !!this.audiobooksOnly, | ||||||
|           hideSingleBookSeries: !!this.hideSingleBookSeries |           hideSingleBookSeries: !!this.hideSingleBookSeries, | ||||||
|  |           podcastSearchRegion: this.podcastSearchRegion | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
| @ -113,6 +121,7 @@ export default { | |||||||
|       this.skipMatchingMediaWithIsbn = !!this.librarySettings.skipMatchingMediaWithIsbn |       this.skipMatchingMediaWithIsbn = !!this.librarySettings.skipMatchingMediaWithIsbn | ||||||
|       this.audiobooksOnly = !!this.librarySettings.audiobooksOnly |       this.audiobooksOnly = !!this.librarySettings.audiobooksOnly | ||||||
|       this.hideSingleBookSeries = !!this.librarySettings.hideSingleBookSeries |       this.hideSingleBookSeries = !!this.librarySettings.hideSingleBookSeries | ||||||
|  |       this.podcastSearchRegion = this.librarySettings.podcastSearchRegion || 'us' | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   mounted() { |   mounted() { | ||||||
|  | |||||||
| @ -86,6 +86,9 @@ export default { | |||||||
|     }, |     }, | ||||||
|     streamLibraryItem() { |     streamLibraryItem() { | ||||||
|       return this.$store.state.streamLibraryItem |       return this.$store.state.streamLibraryItem | ||||||
|  |     }, | ||||||
|  |     librarySettings() { | ||||||
|  |       return this.$store.getters['libraries/getCurrentLibrarySettings'] | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   methods: { |   methods: { | ||||||
| @ -151,7 +154,12 @@ export default { | |||||||
|     async submitSearch(term) { |     async submitSearch(term) { | ||||||
|       this.processing = true |       this.processing = true | ||||||
|       this.termSearched = '' |       this.termSearched = '' | ||||||
|       let results = await this.$axios.$get(`/api/search/podcast?term=${encodeURIComponent(term)}`).catch((error) => { | 
 | ||||||
|  |       const searchParams = new URLSearchParams({ | ||||||
|  |         term, | ||||||
|  |         country: this.librarySettings?.podcastSearchRegion || 'us' | ||||||
|  |       }) | ||||||
|  |       let results = await this.$axios.$get(`/api/search/podcast?${searchParams.toString()}`).catch((error) => { | ||||||
|         console.error('Search request failed', error) |         console.error('Search request failed', error) | ||||||
|         return [] |         return [] | ||||||
|       }) |       }) | ||||||
|  | |||||||
| @ -29,6 +29,18 @@ Vue.prototype.$languageCodeOptions = Object.keys(languageCodeMap).map(code => { | |||||||
|   } |   } | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
|  | // iTunes search API uses ISO 3166 country codes: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
 | ||||||
|  | const podcastSearchRegionMap = { | ||||||
|  |   'us': { label: 'United States' }, | ||||||
|  |   'cn': { label: '中国' } | ||||||
|  | } | ||||||
|  | Vue.prototype.$podcastSearchRegionOptions = Object.keys(podcastSearchRegionMap).map(code => { | ||||||
|  |   return { | ||||||
|  |     text: podcastSearchRegionMap[code].label, | ||||||
|  |     value: code | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | 
 | ||||||
| Vue.prototype.$languageCodes = { | Vue.prototype.$languageCodes = { | ||||||
|   default: defaultCode, |   default: defaultCode, | ||||||
|   current: defaultCode, |   current: defaultCode, | ||||||
|  | |||||||
| @ -396,6 +396,7 @@ | |||||||
|   "LabelPlayMethod": "Metoda přehrávání", |   "LabelPlayMethod": "Metoda přehrávání", | ||||||
|   "LabelPodcast": "Podcast", |   "LabelPodcast": "Podcast", | ||||||
|   "LabelPodcasts": "Podcasty", |   "LabelPodcasts": "Podcasty", | ||||||
|  |   "LabelPodcastSearchRegion": "Oblast vyhledávání podcastu", | ||||||
|   "LabelPodcastType": "Typ podcastu", |   "LabelPodcastType": "Typ podcastu", | ||||||
|   "LabelPort": "Port", |   "LabelPort": "Port", | ||||||
|   "LabelPrefixesToIgnore": "Předpony, které se mají ignorovat (nerozlišují se malá a velká písmena)", |   "LabelPrefixesToIgnore": "Předpony, které se mají ignorovat (nerozlišují se malá a velká písmena)", | ||||||
|  | |||||||
| @ -396,6 +396,7 @@ | |||||||
|   "LabelPlayMethod": "Afspilningsmetode", |   "LabelPlayMethod": "Afspilningsmetode", | ||||||
|   "LabelPodcast": "Podcast", |   "LabelPodcast": "Podcast", | ||||||
|   "LabelPodcasts": "Podcasts", |   "LabelPodcasts": "Podcasts", | ||||||
|  |   "LabelPodcastSearchRegion": "Podcast søgeområde", | ||||||
|   "LabelPodcastType": "Podcast type", |   "LabelPodcastType": "Podcast type", | ||||||
|   "LabelPort": "Port", |   "LabelPort": "Port", | ||||||
|   "LabelPrefixesToIgnore": "Præfikser der skal ignoreres (skal ikke skelne mellem store og små bogstaver)", |   "LabelPrefixesToIgnore": "Præfikser der skal ignoreres (skal ikke skelne mellem store og små bogstaver)", | ||||||
|  | |||||||
| @ -396,6 +396,7 @@ | |||||||
|   "LabelPlayMethod": "Abspielmethode", |   "LabelPlayMethod": "Abspielmethode", | ||||||
|   "LabelPodcast": "Podcast", |   "LabelPodcast": "Podcast", | ||||||
|   "LabelPodcasts": "Podcasts", |   "LabelPodcasts": "Podcasts", | ||||||
|  |   "LabelPodcastSearchRegion": "Podcast-Suchregion", | ||||||
|   "LabelPodcastType": "Podcast Typ", |   "LabelPodcastType": "Podcast Typ", | ||||||
|   "LabelPort": "Port", |   "LabelPort": "Port", | ||||||
|   "LabelPrefixesToIgnore": "Zu ignorierende(s) Vorwort(e) (Groß- und Kleinschreibung wird nicht berücksichtigt)", |   "LabelPrefixesToIgnore": "Zu ignorierende(s) Vorwort(e) (Groß- und Kleinschreibung wird nicht berücksichtigt)", | ||||||
|  | |||||||
| @ -396,6 +396,7 @@ | |||||||
|   "LabelPlayMethod": "Play Method", |   "LabelPlayMethod": "Play Method", | ||||||
|   "LabelPodcast": "Podcast", |   "LabelPodcast": "Podcast", | ||||||
|   "LabelPodcasts": "Podcasts", |   "LabelPodcasts": "Podcasts", | ||||||
|  |   "LabelPodcastSearchRegion": "Podcast search region", | ||||||
|   "LabelPodcastType": "Podcast Type", |   "LabelPodcastType": "Podcast Type", | ||||||
|   "LabelPort": "Port", |   "LabelPort": "Port", | ||||||
|   "LabelPrefixesToIgnore": "Prefixes to Ignore (case insensitive)", |   "LabelPrefixesToIgnore": "Prefixes to Ignore (case insensitive)", | ||||||
|  | |||||||
| @ -396,6 +396,7 @@ | |||||||
|   "LabelPlayMethod": "Método de Reproducción", |   "LabelPlayMethod": "Método de Reproducción", | ||||||
|   "LabelPodcast": "Podcast", |   "LabelPodcast": "Podcast", | ||||||
|   "LabelPodcasts": "Podcasts", |   "LabelPodcasts": "Podcasts", | ||||||
|  |   "LabelPodcastSearchRegion": "Región de búsqueda de podcasts", | ||||||
|   "LabelPodcastType": "Tipo Podcast", |   "LabelPodcastType": "Tipo Podcast", | ||||||
|   "LabelPort": "Puerto", |   "LabelPort": "Puerto", | ||||||
|   "LabelPrefixesToIgnore": "Prefijos para Ignorar (no distingue entre mayúsculas y minúsculas.)", |   "LabelPrefixesToIgnore": "Prefijos para Ignorar (no distingue entre mayúsculas y minúsculas.)", | ||||||
|  | |||||||
| @ -396,6 +396,7 @@ | |||||||
|   "LabelPlayMethod": "Méthode d’écoute", |   "LabelPlayMethod": "Méthode d’écoute", | ||||||
|   "LabelPodcast": "Podcast", |   "LabelPodcast": "Podcast", | ||||||
|   "LabelPodcasts": "Podcasts", |   "LabelPodcasts": "Podcasts", | ||||||
|  |   "LabelPodcastSearchRegion": "Région de recherche de podcasts", | ||||||
|   "LabelPodcastType": "Type de Podcast", |   "LabelPodcastType": "Type de Podcast", | ||||||
|   "LabelPort": "Port", |   "LabelPort": "Port", | ||||||
|   "LabelPrefixesToIgnore": "Préfixes à Ignorer (Insensible à la Casse)", |   "LabelPrefixesToIgnore": "Préfixes à Ignorer (Insensible à la Casse)", | ||||||
|  | |||||||
| @ -396,6 +396,7 @@ | |||||||
|   "LabelPlayMethod": "Play Method", |   "LabelPlayMethod": "Play Method", | ||||||
|   "LabelPodcast": "Podcast", |   "LabelPodcast": "Podcast", | ||||||
|   "LabelPodcasts": "Podcasts", |   "LabelPodcasts": "Podcasts", | ||||||
|  |   "LabelPodcastSearchRegion": "પોડકાસ્ટ શોધ પ્રદેશ", | ||||||
|   "LabelPodcastType": "Podcast Type", |   "LabelPodcastType": "Podcast Type", | ||||||
|   "LabelPort": "Port", |   "LabelPort": "Port", | ||||||
|   "LabelPrefixesToIgnore": "Prefixes to Ignore (case insensitive)", |   "LabelPrefixesToIgnore": "Prefixes to Ignore (case insensitive)", | ||||||
|  | |||||||
| @ -396,6 +396,7 @@ | |||||||
|   "LabelPlayMethod": "Play Method", |   "LabelPlayMethod": "Play Method", | ||||||
|   "LabelPodcast": "Podcast", |   "LabelPodcast": "Podcast", | ||||||
|   "LabelPodcasts": "Podcasts", |   "LabelPodcasts": "Podcasts", | ||||||
|  |   "LabelPodcastSearchRegion": "पॉडकास्ट खोज क्षेत्र", | ||||||
|   "LabelPodcastType": "Podcast Type", |   "LabelPodcastType": "Podcast Type", | ||||||
|   "LabelPort": "Port", |   "LabelPort": "Port", | ||||||
|   "LabelPrefixesToIgnore": "Prefixes to Ignore (case insensitive)", |   "LabelPrefixesToIgnore": "Prefixes to Ignore (case insensitive)", | ||||||
|  | |||||||
| @ -396,6 +396,7 @@ | |||||||
|   "LabelPlayMethod": "Vrsta reprodukcije", |   "LabelPlayMethod": "Vrsta reprodukcije", | ||||||
|   "LabelPodcast": "Podcast", |   "LabelPodcast": "Podcast", | ||||||
|   "LabelPodcasts": "Podcasts", |   "LabelPodcasts": "Podcasts", | ||||||
|  |   "LabelPodcastSearchRegion": "Područje pretrage podcasta", | ||||||
|   "LabelPodcastType": "Podcast Type", |   "LabelPodcastType": "Podcast Type", | ||||||
|   "LabelPort": "Port", |   "LabelPort": "Port", | ||||||
|   "LabelPrefixesToIgnore": "Prefiksi za ignorirati (mala i velika slova nisu bitna)", |   "LabelPrefixesToIgnore": "Prefiksi za ignorirati (mala i velika slova nisu bitna)", | ||||||
|  | |||||||
| @ -396,6 +396,7 @@ | |||||||
|   "LabelPlayMethod": "Metodo di riproduzione", |   "LabelPlayMethod": "Metodo di riproduzione", | ||||||
|   "LabelPodcast": "Podcast", |   "LabelPodcast": "Podcast", | ||||||
|   "LabelPodcasts": "Podcasts", |   "LabelPodcasts": "Podcasts", | ||||||
|  |   "LabelPodcastSearchRegion": "Area di ricerca podcast", | ||||||
|   "LabelPodcastType": "Tipo di Podcast", |   "LabelPodcastType": "Tipo di Podcast", | ||||||
|   "LabelPort": "Port", |   "LabelPort": "Port", | ||||||
|   "LabelPrefixesToIgnore": "Suffissi da ignorare (specificando maiuscole e minuscole)", |   "LabelPrefixesToIgnore": "Suffissi da ignorare (specificando maiuscole e minuscole)", | ||||||
|  | |||||||
| @ -396,6 +396,7 @@ | |||||||
|   "LabelPlayMethod": "Grojimo metodas", |   "LabelPlayMethod": "Grojimo metodas", | ||||||
|   "LabelPodcast": "Tinklalaidė", |   "LabelPodcast": "Tinklalaidė", | ||||||
|   "LabelPodcasts": "Tinklalaidės", |   "LabelPodcasts": "Tinklalaidės", | ||||||
|  |   "LabelPodcastSearchRegion": "Podcast paieškos regionas", | ||||||
|   "LabelPodcastType": "Tinklalaidės tipas", |   "LabelPodcastType": "Tinklalaidės tipas", | ||||||
|   "LabelPort": "Prievadas", |   "LabelPort": "Prievadas", | ||||||
|   "LabelPrefixesToIgnore": "Ignoruojami priešdėliai (didžiosios/mažosios nesvarbu)", |   "LabelPrefixesToIgnore": "Ignoruojami priešdėliai (didžiosios/mažosios nesvarbu)", | ||||||
|  | |||||||
| @ -396,6 +396,7 @@ | |||||||
|   "LabelPlayMethod": "Afspeelwijze", |   "LabelPlayMethod": "Afspeelwijze", | ||||||
|   "LabelPodcast": "Podcast", |   "LabelPodcast": "Podcast", | ||||||
|   "LabelPodcasts": "Podcasts", |   "LabelPodcasts": "Podcasts", | ||||||
|  |   "LabelPodcastSearchRegion": "Podcast zoekregio", | ||||||
|   "LabelPodcastType": "Podcasttype", |   "LabelPodcastType": "Podcasttype", | ||||||
|   "LabelPort": "Poort", |   "LabelPort": "Poort", | ||||||
|   "LabelPrefixesToIgnore": "Te negeren voorzetsels (ongeacht hoofdlettergebruik)", |   "LabelPrefixesToIgnore": "Te negeren voorzetsels (ongeacht hoofdlettergebruik)", | ||||||
|  | |||||||
| @ -396,6 +396,7 @@ | |||||||
|   "LabelPlayMethod": "Avspillingsmetode", |   "LabelPlayMethod": "Avspillingsmetode", | ||||||
|   "LabelPodcast": "Podcast", |   "LabelPodcast": "Podcast", | ||||||
|   "LabelPodcasts": "Podcaster", |   "LabelPodcasts": "Podcaster", | ||||||
|  |   "LabelPodcastSearchRegion": "Podcast-søkeområde", | ||||||
|   "LabelPodcastType": "Podcast type", |   "LabelPodcastType": "Podcast type", | ||||||
|   "LabelPort": "Port", |   "LabelPort": "Port", | ||||||
|   "LabelPrefixesToIgnore": "Prefiks som skal ignoreres (skiller ikke mellom store og små bokstaver)", |   "LabelPrefixesToIgnore": "Prefiks som skal ignoreres (skiller ikke mellom store og små bokstaver)", | ||||||
|  | |||||||
| @ -396,6 +396,7 @@ | |||||||
|   "LabelPlayMethod": "Metoda odtwarzania", |   "LabelPlayMethod": "Metoda odtwarzania", | ||||||
|   "LabelPodcast": "Podcast", |   "LabelPodcast": "Podcast", | ||||||
|   "LabelPodcasts": "Podcasty", |   "LabelPodcasts": "Podcasty", | ||||||
|  |   "LabelPodcastSearchRegion": "Obszar wyszukiwania podcastów", | ||||||
|   "LabelPodcastType": "Podcast Type", |   "LabelPodcastType": "Podcast Type", | ||||||
|   "LabelPort": "Port", |   "LabelPort": "Port", | ||||||
|   "LabelPrefixesToIgnore": "Ignorowane prefiksy (wielkość liter nie ma znaczenia)", |   "LabelPrefixesToIgnore": "Ignorowane prefiksy (wielkość liter nie ma znaczenia)", | ||||||
|  | |||||||
| @ -40,8 +40,8 @@ | |||||||
|   "ButtonLookup": "Procurar", |   "ButtonLookup": "Procurar", | ||||||
|   "ButtonManageTracks": "Gerenciar Faixas", |   "ButtonManageTracks": "Gerenciar Faixas", | ||||||
|   "ButtonMapChapterTitles": "Designar Títulos de Capítulos", |   "ButtonMapChapterTitles": "Designar Títulos de Capítulos", | ||||||
|   "ButtonitensAllAuthors": "Consultar Todos os Autores", |   "ButtonMatchAllAuthors": "Consultar Todos os Autores", | ||||||
|   "ButtonitensBooks": "Consultar Livros", |   "ButtonMatchBooks": "Consultar Livros", | ||||||
|   "ButtonNevermind": "Cancelar", |   "ButtonNevermind": "Cancelar", | ||||||
|   "ButtonNextChapter": "Próximo Capítulo", |   "ButtonNextChapter": "Próximo Capítulo", | ||||||
|   "ButtonOk": "Ok", |   "ButtonOk": "Ok", | ||||||
| @ -57,7 +57,7 @@ | |||||||
|   "ButtonPurgeMediaProgress": "Apagar o Progresso nas Mídias", |   "ButtonPurgeMediaProgress": "Apagar o Progresso nas Mídias", | ||||||
|   "ButtonQueueAddItem": "Adicionar à Lista", |   "ButtonQueueAddItem": "Adicionar à Lista", | ||||||
|   "ButtonQueueRemoveItem": "Remover da Lista", |   "ButtonQueueRemoveItem": "Remover da Lista", | ||||||
|   "ButtonQuickitens": "Consulta rápida", |   "ButtonQuickMatch": "Consulta rápida", | ||||||
|   "ButtonRead": "Ler", |   "ButtonRead": "Ler", | ||||||
|   "ButtonRemove": "Remover", |   "ButtonRemove": "Remover", | ||||||
|   "ButtonRemoveAll": "Remover Todos", |   "ButtonRemoveAll": "Remover Todos", | ||||||
| @ -133,9 +133,9 @@ | |||||||
|   "HeaderLogin": "Login", |   "HeaderLogin": "Login", | ||||||
|   "HeaderLogs": "Logs", |   "HeaderLogs": "Logs", | ||||||
|   "HeaderManageGenres": "Gerenciar Gêneros", |   "HeaderManageGenres": "Gerenciar Gêneros", | ||||||
|   "HeaderManageetiquetas": "Gerenciar Etiquetas", |   "HeaderManageTags": "Gerenciar Etiquetas", | ||||||
|   "HeaderMapDetails": "Designar Detalhes", |   "HeaderMapDetails": "Designar Detalhes", | ||||||
|   "Headeritens": "Consultar", |   "HeaderMatch": "Consultar", | ||||||
|   "HeaderMetadataOrderOfPrecedence": "Ordem de Prioridade dos Metadados", |   "HeaderMetadataOrderOfPrecedence": "Ordem de Prioridade dos Metadados", | ||||||
|   "HeaderMetadataToEmbed": "Metadados a Serem Incluídos", |   "HeaderMetadataToEmbed": "Metadados a Serem Incluídos", | ||||||
|   "HeaderNewAccount": "Nova Conta", |   "HeaderNewAccount": "Nova Conta", | ||||||
| @ -396,6 +396,7 @@ | |||||||
|   "LabelPlayMethod": "Método de Reprodução", |   "LabelPlayMethod": "Método de Reprodução", | ||||||
|   "LabelPodcast": "Podcast", |   "LabelPodcast": "Podcast", | ||||||
|   "LabelPodcasts": "Podcasts", |   "LabelPodcasts": "Podcasts", | ||||||
|  |   "LabelPodcastSearchRegion": "Podcast search region", | ||||||
|   "LabelPodcastType": "Tipo de Podcast", |   "LabelPodcastType": "Tipo de Podcast", | ||||||
|   "LabelPort": "Porta", |   "LabelPort": "Porta", | ||||||
|   "LabelPrefixesToIgnore": "Prefixos para Ignorar (sem distinção entre maiúsculas e minúsculas)", |   "LabelPrefixesToIgnore": "Prefixos para Ignorar (sem distinção entre maiúsculas e minúsculas)", | ||||||
|  | |||||||
| @ -396,6 +396,7 @@ | |||||||
|   "LabelPlayMethod": "Метод воспроизведения", |   "LabelPlayMethod": "Метод воспроизведения", | ||||||
|   "LabelPodcast": "Подкаст", |   "LabelPodcast": "Подкаст", | ||||||
|   "LabelPodcasts": "Подкасты", |   "LabelPodcasts": "Подкасты", | ||||||
|  |   "LabelPodcastSearchRegion": "Регион поиска подкастов", | ||||||
|   "LabelPodcastType": "Тип подкаста", |   "LabelPodcastType": "Тип подкаста", | ||||||
|   "LabelPort": "Порт", |   "LabelPort": "Порт", | ||||||
|   "LabelPrefixesToIgnore": "Игнорируемые префиксы (без учета регистра)", |   "LabelPrefixesToIgnore": "Игнорируемые префиксы (без учета регистра)", | ||||||
|  | |||||||
| @ -396,6 +396,7 @@ | |||||||
|   "LabelPlayMethod": "Spelläge", |   "LabelPlayMethod": "Spelläge", | ||||||
|   "LabelPodcast": "Podcast", |   "LabelPodcast": "Podcast", | ||||||
|   "LabelPodcasts": "Podcasts", |   "LabelPodcasts": "Podcasts", | ||||||
|  |   "LabelPodcastSearchRegion": "Podcast-sökområde", | ||||||
|   "LabelPodcastType": "Podcasttyp", |   "LabelPodcastType": "Podcasttyp", | ||||||
|   "LabelPort": "Port", |   "LabelPort": "Port", | ||||||
|   "LabelPrefixesToIgnore": "Prefix att ignorera (skiftlägesokänsligt)", |   "LabelPrefixesToIgnore": "Prefix att ignorera (skiftlägesokänsligt)", | ||||||
|  | |||||||
| @ -396,6 +396,7 @@ | |||||||
|   "LabelPlayMethod": "播放方法", |   "LabelPlayMethod": "播放方法", | ||||||
|   "LabelPodcast": "播客", |   "LabelPodcast": "播客", | ||||||
|   "LabelPodcasts": "播客", |   "LabelPodcasts": "播客", | ||||||
|  |   "LabelPodcastSearchRegion": "播客搜索地区", | ||||||
|   "LabelPodcastType": "播客类型", |   "LabelPodcastType": "播客类型", | ||||||
|   "LabelPort": "端口", |   "LabelPort": "端口", | ||||||
|   "LabelPrefixesToIgnore": "忽略的前缀 (不区分大小写)", |   "LabelPrefixesToIgnore": "忽略的前缀 (不区分大小写)", | ||||||
|  | |||||||
| @ -43,12 +43,15 @@ class SearchController { | |||||||
|    */ |    */ | ||||||
|   async findPodcasts(req, res) { |   async findPodcasts(req, res) { | ||||||
|     const term = req.query.term |     const term = req.query.term | ||||||
|  |     const country = req.query.country || 'us' | ||||||
|     if (!term) { |     if (!term) { | ||||||
|       Logger.error('[SearchController] Invalid request query param "term" is required') |       Logger.error('[SearchController] Invalid request query param "term" is required') | ||||||
|       return res.status(400).send('Invalid request query param "term" is required') |       return res.status(400).send('Invalid request query param "term" is required') | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const results = await PodcastFinder.search(term) |     const results = await PodcastFinder.search(term, { | ||||||
|  |       country | ||||||
|  |     }) | ||||||
|     res.json(results) |     res.json(results) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -6,10 +6,16 @@ class PodcastFinder { | |||||||
|     this.iTunesApi = new iTunes() |     this.iTunesApi = new iTunes() | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   /** | ||||||
|  |    *  | ||||||
|  |    * @param {string} term  | ||||||
|  |    * @param {{country:string}} options  | ||||||
|  |    * @returns {Promise<import('../providers/iTunes').iTunesPodcastSearchResult[]>} | ||||||
|  |    */ | ||||||
|   async search(term, options = {}) { |   async search(term, options = {}) { | ||||||
|     if (!term) return null |     if (!term) return null | ||||||
|     Logger.debug(`[iTunes] Searching for podcast with term "${term}"`) |     Logger.debug(`[iTunes] Searching for podcast with term "${term}"`) | ||||||
|     var results = await this.iTunesApi.searchPodcasts(term, options) |     const results = await this.iTunesApi.searchPodcasts(term, options) | ||||||
|     Logger.debug(`[iTunes] Podcast search for "${term}" returned ${results.length} results`) |     Logger.debug(`[iTunes] Podcast search for "${term}" returned ${results.length} results`) | ||||||
|     return results |     return results | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ class LibrarySettings { | |||||||
|     this.audiobooksOnly = false |     this.audiobooksOnly = false | ||||||
|     this.hideSingleBookSeries = false // Do not show series that only have 1 book 
 |     this.hideSingleBookSeries = false // Do not show series that only have 1 book 
 | ||||||
|     this.metadataPrecedence = ['folderStructure', 'audioMetatags', 'nfoFile', 'txtFiles', 'opfFile', 'absMetadata'] |     this.metadataPrecedence = ['folderStructure', 'audioMetatags', 'nfoFile', 'txtFiles', 'opfFile', 'absMetadata'] | ||||||
|  |     this.podcastSearchRegion = 'us' | ||||||
| 
 | 
 | ||||||
|     if (settings) { |     if (settings) { | ||||||
|       this.construct(settings) |       this.construct(settings) | ||||||
| @ -30,6 +31,7 @@ class LibrarySettings { | |||||||
|       // Added in v2.4.5
 |       // Added in v2.4.5
 | ||||||
|       this.metadataPrecedence = ['folderStructure', 'audioMetatags', 'nfoFile', 'txtFiles', 'opfFile', 'absMetadata'] |       this.metadataPrecedence = ['folderStructure', 'audioMetatags', 'nfoFile', 'txtFiles', 'opfFile', 'absMetadata'] | ||||||
|     } |     } | ||||||
|  |     this.podcastSearchRegion = settings.podcastSearchRegion || 'us' | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   toJSON() { |   toJSON() { | ||||||
| @ -41,7 +43,8 @@ class LibrarySettings { | |||||||
|       autoScanCronExpression: this.autoScanCronExpression, |       autoScanCronExpression: this.autoScanCronExpression, | ||||||
|       audiobooksOnly: this.audiobooksOnly, |       audiobooksOnly: this.audiobooksOnly, | ||||||
|       hideSingleBookSeries: this.hideSingleBookSeries, |       hideSingleBookSeries: this.hideSingleBookSeries, | ||||||
|       metadataPrecedence: [...this.metadataPrecedence] |       metadataPrecedence: [...this.metadataPrecedence], | ||||||
|  |       podcastSearchRegion: this.podcastSearchRegion | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,16 +2,46 @@ const axios = require('axios') | |||||||
| const Logger = require('../Logger') | const Logger = require('../Logger') | ||||||
| const htmlSanitizer = require('../utils/htmlSanitizer') | const htmlSanitizer = require('../utils/htmlSanitizer') | ||||||
| 
 | 
 | ||||||
|  | /** | ||||||
|  |  * @typedef iTunesSearchParams | ||||||
|  |  * @property {string} term | ||||||
|  |  * @property {string} country | ||||||
|  |  * @property {string} media | ||||||
|  |  * @property {string} entity | ||||||
|  |  * @property {number} limit | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * @typedef iTunesPodcastSearchResult | ||||||
|  |  * @property {string} id | ||||||
|  |  * @property {string} artistId | ||||||
|  |  * @property {string} title | ||||||
|  |  * @property {string} artistName | ||||||
|  |  * @property {string} description | ||||||
|  |  * @property {string} descriptionPlain | ||||||
|  |  * @property {string} releaseDate | ||||||
|  |  * @property {string[]} genres | ||||||
|  |  * @property {string} cover | ||||||
|  |  * @property {string} feedUrl | ||||||
|  |  * @property {string} pageUrl | ||||||
|  |  * @property {boolean} explicit | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
| class iTunes { | class iTunes { | ||||||
|   constructor() { } |   constructor() { } | ||||||
| 
 | 
 | ||||||
|   // https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/iTuneSearchAPI/Searching.html
 |   /** | ||||||
|  |    * @see https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/iTuneSearchAPI/Searching.html
 | ||||||
|  |    *  | ||||||
|  |    * @param {iTunesSearchParams} options  | ||||||
|  |    * @returns {Promise<Object[]>} | ||||||
|  |    */ | ||||||
|   search(options) { |   search(options) { | ||||||
|     if (!options.term) { |     if (!options.term) { | ||||||
|       Logger.error('[iTunes] Invalid search options - no term') |       Logger.error('[iTunes] Invalid search options - no term') | ||||||
|       return [] |       return [] | ||||||
|     } |     } | ||||||
|     var query = { |     const query = { | ||||||
|       term: options.term, |       term: options.term, | ||||||
|       media: options.media, |       media: options.media, | ||||||
|       entity: options.entity, |       entity: options.entity, | ||||||
| @ -82,6 +112,11 @@ class iTunes { | |||||||
|     }) |     }) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   /** | ||||||
|  |    *  | ||||||
|  |    * @param {Object} data  | ||||||
|  |    * @returns {iTunesPodcastSearchResult} | ||||||
|  |    */ | ||||||
|   cleanPodcast(data) { |   cleanPodcast(data) { | ||||||
|     return { |     return { | ||||||
|       id: data.collectionId, |       id: data.collectionId, | ||||||
| @ -100,6 +135,12 @@ class iTunes { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   /** | ||||||
|  |    *  | ||||||
|  |    * @param {string} term  | ||||||
|  |    * @param {{country:string}} options  | ||||||
|  |    * @returns {Promise<iTunesPodcastSearchResult[]>} | ||||||
|  |    */ | ||||||
|   searchPodcasts(term, options = {}) { |   searchPodcasts(term, options = {}) { | ||||||
|     return this.search({ term, entity: 'podcast', media: 'podcast', ...options }).then((results) => { |     return this.search({ term, entity: 'podcast', media: 'podcast', ...options }).then((results) => { | ||||||
|       return results.map(this.cleanPodcast.bind(this)) |       return results.map(this.cleanPodcast.bind(this)) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user