Update jsdocs for search podcasts

This commit is contained in:
advplyr 2024-02-17 13:24:49 -06:00
parent 2ec52a7a45
commit 180c328ed1
5 changed files with 62 additions and 8 deletions

View File

@ -87,7 +87,7 @@ export default {
streamLibraryItem() {
return this.$store.state.streamLibraryItem
},
librarySetting() {
librarySettings() {
return this.$store.getters['libraries/getCurrentLibrarySettings']
}
},
@ -154,7 +154,12 @@ export default {
async submitSearch(term) {
this.processing = true
this.termSearched = ''
let results = await this.$axios.$get(`/api/search/podcast?term=${encodeURIComponent(term)}&country=${encodeURIComponent(this.librarySetting?.podcastSearchRegion)}`).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)
return []
})

View File

@ -28,9 +28,11 @@ Vue.prototype.$languageCodeOptions = Object.keys(languageCodeMap).map(code => {
value: 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: '中国' },
'cn': { label: '中国' }
}
Vue.prototype.$podcastSearchRegionOptions = Object.keys(podcastSearchRegionMap).map(code => {
return {

View File

@ -43,14 +43,14 @@ class SearchController {
*/
async findPodcasts(req, res) {
const term = req.query.term
const country = req.query.country
const country = req.query.country || 'us'
if (!term) {
Logger.error('[SearchController] 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, {
country: country
country
})
res.json(results)
}

View File

@ -6,10 +6,16 @@ class PodcastFinder {
this.iTunesApi = new iTunes()
}
/**
*
* @param {string} term
* @param {{country:string}} options
* @returns {Promise<import('../providers/iTunes').iTunesPodcastSearchResult[]>}
*/
async search(term, options = {}) {
if (!term) return null
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`)
return results
}

View File

@ -2,16 +2,46 @@ const axios = require('axios')
const Logger = require('../Logger')
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 {
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) {
if (!options.term) {
Logger.error('[iTunes] Invalid search options - no term')
return []
}
var query = {
const query = {
term: options.term,
media: options.media,
entity: options.entity,
@ -82,6 +112,11 @@ class iTunes {
})
}
/**
*
* @param {Object} data
* @returns {iTunesPodcastSearchResult}
*/
cleanPodcast(data) {
return {
id: data.collectionId,
@ -100,6 +135,12 @@ class iTunes {
}
}
/**
*
* @param {string} term
* @param {{country:string}} options
* @returns {Promise<iTunesPodcastSearchResult[]>}
*/
searchPodcasts(term, options = {}) {
return this.search({ term, entity: 'podcast', media: 'podcast', ...options }).then((results) => {
return results.map(this.cleanPodcast.bind(this))