diff --git a/docs/changelog.md b/docs/changelog.md index c99a472..9f7bfcc 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -12,6 +12,7 @@ - Теперь [mineTracks](/func?id=minetracks) может искать ключевые слова в названиях альбомов и самих треках. - В `mineTracks` аргумент `playlistCount` переименован в `itemCount`. - Новая функция у Filter: [replaceWithSimilar](/func?id=replacewithsimilar). +- Новая функция у Lastfm: [getSimilarArtists](/func?id=getsimilarartists-1) ## Версия 1.4.4 - Новый фильтр [removeUnavailable](/func?id=removeunavailable). diff --git a/docs/func.md b/docs/func.md index 1d60478..8a23dfd 100644 --- a/docs/func.md +++ b/docs/func.md @@ -1732,6 +1732,22 @@ Library.deleteFavoriteTracks(savedTracks); let tracks = Lastfm.getLovedTracks('login', 200); ``` +### getSimilarArtists + +Возвращает массив исполнителей, которые похожи на входные элементы соглансо данным Lastfm. + +Аргументы +- (массив) `items` - массив треков или исполнителей. Выбирается только `name` исполнителя. +- (число) `match` - минимальное значение похожести на оригинального исполнителя в границе от `0.0` до `1.0`. +- (число) `limit` - количество запрашиваемых похожих исполнителей на одного оригинального. +- (бул) `isFlat` - если `false` результат содержит исполнителей в отдельном массиве. Если `true` все исполнители в одном массиве. По умолчанию `true`. + +Пример 1 - Получить исполнителей похожих на отслеживаемых +```js +let artists = Source.getArtists({ followed_include: true, }); +let similarArtists = Lastfm.getSimilarArtists(artists, 0.65, 20); +``` + ### getSimilarTracks Возвращает массив треков, которые похожи на входные треки согласно данным Lastfm. @@ -1740,6 +1756,7 @@ let tracks = Lastfm.getLovedTracks('login', 200); - (массив) `tracks` - треки, для которых нужно найти похожие. - (число) `match` - минимальное значение похожести на оригинальный трек в границе от `0.0` до `1.0`. - (число) `limit` - количество запрашиваемых похожих треков на один оригинальный трек. +- (бул) `isFlat` - если `false` результат содержит треки в отдельном массиве. Если `true` все треки в одном массиве. По умолчанию `true`. Пример 1 - Получить треки, похожие на плейлист ```js diff --git a/library.js b/library.js index 55e12f9..49875c6 100644 --- a/library.js +++ b/library.js @@ -1901,36 +1901,74 @@ const Lastfm = (function () { getRecomStation: getRecomStation, getNeighboursStation: getNeighboursStation, getSimilarTracks: getSimilarTracks, + getSimilarArtists: getSimilarArtists, getCustomTop: getCustomTop, }; - function getSimilarTracks(tracks, match, limit) { + function getSimilarTracks(tracks, match, limit, isFlat = true) { + return getSimilar({ + searchMethod: Search.multisearchTracks, + formatMethod: formatTrackNameLastfm, + apiMethodStr: 'track.getsimilar', + items: tracks, + limit: limit, + match: match, + parentKey: 'similartracks', + childKey: 'track', + isFlat: isFlat, + }); + } + + function getSimilarArtists(items, match, limit, isFlat = true) { + return getSimilar({ + searchMethod: Search.multisearchArtists, + formatMethod: formatArtistNameLastfm, + apiMethodStr: 'artist.getsimilar', + items: items, + limit: limit, + match: match, + parentKey: 'similarartists', + childKey: 'artist', + isFlat: isFlat, + }); + } + + function getSimilar(params) { let requests = createRequests(); - return Search.multisearchTracks(getAll(), formatTrackNameLastfm); + let items = getAll(); + if (params.isFlat) { + return params.searchMethod(items, params.formatMethod); + } + return items.reduce((result, array) => { + result.push(params.searchMethod(array, params.formatMethod)); + return result; + }, []); function createRequests() { - return tracks.reduce((requests, track) => { - let queryStr = CustomUrlFetchApp.parseQuery({ - method: 'track.getsimilar', + return params.items.reduce((requests, item) => { + let queryStr = { + method: params.apiMethodStr, autocorrect: '1', - artist: track.artists[0].name, - track: track.name, - limit: limit || 50, + artist: item.artists ? item.artists[0].name : item.name, + limit: params.limit || 50, format: 'json', api_key: KeyValue.LASTFM_API_KEY, - }); - requests.push({ url: LASTFM_API_BASE_URL + queryStr }); + }; + if (params.apiMethodStr.includes('track')) { + queryStr.track = item.name; + } + requests.push({ url: LASTFM_API_BASE_URL + CustomUrlFetchApp.parseQuery(queryStr) }); return requests; }, []); } function getAll() { - return CustomUrlFetchApp.fetchAll(requests).reduce((similarTracks, response) => { - if (response.similartracks) { - let filteredTracks = response.similartracks.track.filter((track) => track.match >= match); - return Combiner.push(similarTracks, filteredTracks); + return CustomUrlFetchApp.fetchAll(requests).reduce((similarItems, response) => { + if (response[params.parentKey]) { + let filteredItems = response[params.parentKey][params.childKey].filter((item) => item.match >= params.match); + _ = params.isFlat ? Combiner.push(similarItems, filteredItems) : similarItems.push(filteredItems); } - return similarTracks; + return similarItems; }, []); } }