Skip to content

Commit

Permalink
Добавлена функция Lastfm.rangeTags
Browse files Browse the repository at this point in the history
  • Loading branch information
Chimildic committed Dec 6, 2021
1 parent 0ecfca4 commit f3db62f
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 6 deletions.
1 change: 1 addition & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

## Версия 1.5.4
- Добавлена попытка повторного чтения/записи при неизвестной ошибки службы Google Диска.
- Добавлена функция: [Lastfm.rangeTags](/func?id=rangetags).
- [addToQueue](/func?id=addtoqueue) может добавлять массив треков в очередь.
- К [mineTracks](/func?id=minetracks) добавлен параметр для пропуска элементов.
- К [removeUnavailable](/func?id=removeunavailable) добавлен аргумент отключения сообщений с логами.
Expand Down
37 changes: 37 additions & 0 deletions docs/func.md
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,43 @@ let tracks = Lastfm.getTopTracks({
});
```

### rangeTags

Оставляет только треки, которые содержат указанные теги Lastfm. Треки непрошедшие проверку удаляются из оригинального массива `spotifyTracks`. К каждому треку добавляется ключ `tags`, содержащий массив тегов.

!> На каждый трек тратится по одному запросу. Используйте функцию только после максимального сокращения массива другими фильтрами.

Аргументы
- (массив) `spotifyTracks` - проверяемые Spotify-треки.
- (объект) `args` - условия проверки.
- (массив) `include` - массив с объектами тегов. Если есть у трека (хотя бы один), он сохраняется.
- (массив) `exclude` - массив с объектами тегов. Если есть у трека (хотя бы один), он удаляется.
- (бул) `isRemoveUnknown` - при `true` треки без тегов удаляются. При `false` остаются. По умолчанию `false`.
- (бул) `isLogging` - при `true` выводятся сообщения о треках, для которых нет тегов. При `false` не выводит. По умолчанию `false`.

Пример 1 - Оставить из недавних любимых треков только рок, исключая инди. Так как теги проставляются пользователями, у них есть показатель популярности (до 100). `minCount` - минимальное значение показателя включительно. Если будет меньше, трек удаляется не смотря на наличие тега.
```js
let tracks = Source.getSavedTracks(20);
Lastfm.rangeTags(tracks, {
isLogging: true,
isRemoveUnknown: true,
include: [
{ name: 'rock', minCount: 10 },
],
exclude: [
{ name: 'indie', minCount: 10 },
]
});
```

Пример 2 - Добавить к трекам теги, удалить неизвестные.
```js
let tracks = Source.getSavedTracks(20);
Lastfm.rangeTags(tracks, {
isRemoveUnknown: true,
});
```

### removeRecentArtists
Удаляет из массива треков `original` историю недавно прослушанных `limit` треков пользователя `lastfmUser`. Совпадение определяется только по имени исполнителя. Требуется [дополнительная настройка](/install?id=Настройка-lastfm). Из-за разного написания имен в Lastfm и Spotify удалятся не все треки.

Expand Down
55 changes: 49 additions & 6 deletions library.js
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ const Player = (function () {
addItem(tracks.id);
}

function addItem(id){
function addItem(id) {
let queryObj = { uri: `spotify:track:${id}` };
let url = createUrl('/me/player/queue', deviceId, queryObj);
return SpotifyRequest.post(url);
Expand Down Expand Up @@ -2073,6 +2073,7 @@ const Lastfm = (function () {
const LASTFM_API_BASE_URL = 'http://ws.audioscrobbler.com/2.0/?';
const LASTFM_STATION = 'https://www.last.fm/player/station/user';
return {
rangeTags: rangeTags,
removeRecentTracks: removeRecentTracks,
removeRecentArtists: removeRecentArtists,
getLovedTracks: getLovedTracks,
Expand Down Expand Up @@ -2398,16 +2399,58 @@ const Lastfm = (function () {
return CustomUrlFetchApp.fetch(url) || [];
}

function isNowPlayling(track) {
return track['@attr'] && track['@attr'].nowplaying === 'true';
}

function rangeTags(spotifyTracks, args) {
spotifyTracks.forEach(t => {
let queryObj = {
method: 'track.gettoptags',
user: args.user || KeyValue.LASTFM_LOGIN,
artist: t.artists[0].name.formatName(),
track: t.name.formatName(),
autocorrect: 1,
};
let response = CustomUrlFetchApp.fetch(createUrl(queryObj));
let trackname = `${t.artists[0].name} - ${t.name}`;
if (response.toptags && response.toptags.tag) {
if (response.toptags.tag.length > 0) {
t.tags = response.toptags.tag
} else if (response.toptags.tag.length == 0 && args.isLogging) {
console.info('У трека нет тегов', trackname);
}
} else if (response.error && args.isLogging) {
console.info(`${response.message}. Трек: ${trackname}`);
}
});

Combiner.replace(spotifyTracks, spotifyTracks.filter(t => {
if (!t.hasOwnProperty('tags') || t.tags.length == 0) {
return !args.isRemoveUnknown;
}
return isSomeBelong(t, args.include, true) && !isSomeBelong(t, args.exclude, false);
}));

function isSomeBelong(track, inputTags, defaultResult) {
if (!track || !Array.isArray(inputTags)) {
return defaultResult;
}
return inputTags.some(inputTag => {
return track.tags.some(trackTag =>
trackTag.name == inputTag.name
&& trackTag.count >= (inputTag.minCount || 0)
);
});
}
}

function createUrl(queryObj) {
queryObj.api_key = KeyValue.LASTFM_API_KEY;
queryObj.format = 'json';
return LASTFM_API_BASE_URL + CustomUrlFetchApp.parseQuery(queryObj);
}

function isNowPlayling(track) {
return track['@attr'] && track['@attr'].nowplaying === 'true';
}

function formatLastfmTrackKey(item) {
let artist = item.artist.name ? item.artist.name : item.artist['#text'];
return `${artist} ${item.name}`.formatName();
Expand Down Expand Up @@ -3254,7 +3297,7 @@ const Admin = (function () {

String.prototype.formatName = function () {
return this.toLowerCase()
.replace(/[',?!@#$%^&*()+-./\\]/g, ' ')
.replace(/['`,?!@#$%^&*()+-./\\]/g, ' ')
.replace(/\s{2,}/g, ' ')
.replace(/ё/g, 'е')
.trim();
Expand Down

0 comments on commit f3db62f

Please sign in to comment.