Replies: 3 comments
-
Крепкий среднячокfunction updateStrongMiddle() {
const PLAYED_COUNT = { min: 3, max: 15 }
const FULL_DIFF = { min: 90, max: 111 }
const SKIP_DIFF = { min: 0, max: 60 }
const SKIP_THRESHOLD = 5
const SKIP_DAYS_REL = 14
let tracks = getRecentTracks()
calcDiff()
skipRecentDays()
reduceDiff()
filter()
Playlist.saveWithReplace({
name: 'Крепкий среднячок',
tracks: Selector.sliceRandom(tracks, 15)
})
function getRecentTracks() {
let recentTracks = Combiner.push([], Cache.read('SpotifyRecentTracks'), Cache.read('LastfmRecentTracks'))
let grouped = Object.values(recentTracks.reduce((acc, track) => {
acc[track.id] = acc[track.id] || []
acc[track.id].push(track)
return acc
}, {}))
let deduped = grouped.map(tracks => {
Order.sort(tracks, 'meta.played_at', 'desc')
for (let i = 1; i < tracks.length; i++) {
let xTime = new Date(tracks[i - 1])
let yTime = new Date(tracks[i])
if (xTime - yTime <= 10000) {
i--
tracks.splice(i, 1)
}
}
return tracks
}).flat(1)
Order.sort(deduped, 'meta.played_at', 'asc')
return deduped
}
function calcDiff() {
for (let i = 1; i < tracks.length; i++) {
let aEnd = new Date(tracks[i - 1].played_at).getTime()
let bEnd = new Date(tracks[i].played_at).getTime()
let delta = bEnd - aEnd
tracks[i].diffProcent = 100 * delta / tracks[i].duration_ms
}
}
function skipRecentDays() {
let recentTracks = RecentTracks.get()
Filter.rangeDateRel(recentTracks, SKIP_DAYS_REL, 0)
Filter.removeTracks(tracks, recentTracks)
}
function reduceDiff() {
tracks = Object.values(tracks.reduce((acc, track) => {
acc[track.id] = acc[track.id] || track
acc[track.id].diffGroup = acc[track.id].diffGroup || []
acc[track.id].diffGroup.push(track.diffProcent)
return acc
}, {}))
}
function filter() {
tracks = tracks.filter(t => {
t.fullPlayedCount = reduce(t, FULL_DIFF.min, FULL_DIFF.max)
t.skipCount = reduce(t, SKIP_DIFF.min, SKIP_DIFF.max)
return t.skipCount <= SKIP_THRESHOLD && (t.fullPlayedCount >= PLAYED_COUNT.min && t.fullPlayedCount <= PLAYED_COUNT.max)
})
function reduce(track, min, max) {
return track.diffGroup.reduce((acc, value) => {
let int = Math.round(value)
return int >= min && int <= max ? ++acc : acc
}, 0)
}
}
} |
Beta Was this translation helpful? Give feedback.
-
|
Соединил некоторые части алгоритмов Крепкого середнячка и Лучшего времени суток. Добавил константу пересечения - то есть сколько раз трек играл в определенное время суток. В моем случае получилось забавно, среди найденных треков постоянно много лайков, но не все. Если также будет у вас, то похоже на паттерн вылавливания претендентов на лайки) Предполагается триггер на каждый час. Clerk обновит плейлист 4 раза за день. Чтобы подобрать оптимальные значения констант, можно запустить функцию несколько раз не дожидаясь триггера. let targetPeriod = 'morning';
// Clerk.runOnceAfter('00:00', function nightStrongPls() { onSetDayPeriod() });
// Clerk.runOnceAfter('06:00', function morningStrongPls() { onSetDayPeriod() });
// Clerk.runOnceAfter('12:00', function dayStrongPls() { onSetDayPeriod() });
// Clerk.runOnceAfter('18:00', function eveningStrongPls() { onSetDayPeriod() });
// if (targetPeriod.length == 0) {
// return;
// }Претенденты на лайкиfunction updateStrongMiddleWithPeriods() {
const PLAYED_COUNT = { min: 9, max: 90 }
const FULL_DIFF = { min: 60, max: 112 }
const SKIP_DIFF = { min: 0, max: 51 }
const SKIP_THRESHOLD = 20
const SKIP_DAYS_REL = 8
const MIN_CROSS_COUNT = 5
const PERIODS = [
{ period: 'night', from: 0, to: 5 },
{ period: 'morning', from: 6, to: 11 },
{ period: 'day', from: 12, to: 17 },
{ period: 'evening', from: 18, to: 23 },
];
let targetPeriod = '';
Clerk.runOnceAfter('00:00', function nightStrongPls() { onSetDayPeriod() });
Clerk.runOnceAfter('06:00', function morningStrongPls() { onSetDayPeriod() });
Clerk.runOnceAfter('12:00', function dayStrongPls() { onSetDayPeriod() });
Clerk.runOnceAfter('18:00', function eveningStrongPls() { onSetDayPeriod() });
if (targetPeriod.length == 0) {
return;
}
let tracks = getRecentTracks()
calcDiff()
skipRecentDays()
reduceDiff()
filter()
Playlist.saveWithReplace({
name: 'Претенденты на лайки',
tracks: Selector.sliceRandom(tracks, 30)
})
function getRecentTracks() {
let recentTracks = Combiner.push([], Cache.read('SpotifyRecentTracks'), Cache.read('LastfmRecentTracks'))
let grouped = Object.values(recentTracks.reduce((acc, track) => {
acc[track.id] = acc[track.id] || []
acc[track.id].push(track)
return acc
}, {}))
let deduped = grouped.map(tracks => {
Order.sort(tracks, 'meta.played_at', 'desc')
for (let i = 1; i < tracks.length; i++) {
let xTime = new Date(tracks[i - 1])
let yTime = new Date(tracks[i])
if (xTime - yTime <= 10000) {
i--
tracks.splice(i, 1)
}
}
return tracks
}).flat(1)
Order.sort(deduped, 'meta.played_at', 'asc')
return deduped
}
function calcDiff() {
for (let i = 1; i < tracks.length; i++) {
let aEnd = new Date(tracks[i - 1].played_at).getTime()
let bEnd = new Date(tracks[i].played_at).getTime()
let delta = bEnd - aEnd
tracks[i].diffProcent = 100 * delta / tracks[i].duration_ms
}
}
function skipRecentDays() {
let recentTracks = RecentTracks.get()
Filter.rangeDateRel(recentTracks, SKIP_DAYS_REL, 0)
Filter.removeTracks(tracks, recentTracks)
}
function reduceDiff() {
tracks = Object.values(tracks.reduce((acc, track) => {
acc[track.id] = acc[track.id] || track
acc[track.id].diffGroup = acc[track.id].diffGroup || []
acc[track.id].diffGroup.push(track.diffProcent)
acc[track.id].periods = acc[track.id].periods || []
acc[track.id].periods.push(track.played_at || track.added_at)
return acc
}, {})).map((t, i) => {
t.crossPeriodCount = t.periods.filter(p => isDayPeriod(new Date(p), targetPeriod)).length
return t
})
}
function filter() {
tracks = tracks.filter(t => {
t.fullPlayedCount = reduce(t, FULL_DIFF.min, FULL_DIFF.max)
t.skipCount = reduce(t, SKIP_DIFF.min, SKIP_DIFF.max)
return t.skipCount <= SKIP_THRESHOLD && t.crossPeriodCount >= MIN_CROSS_COUNT
&& (t.fullPlayedCount >= PLAYED_COUNT.min && t.fullPlayedCount <= PLAYED_COUNT.max)
})
function reduce(track, min, max) {
return track.diffGroup.reduce((acc, value) => {
let int = Math.round(value)
return int >= min && int <= max ? ++acc : acc
}, 0)
}
}
function onSetDayPeriod() {
let nowHours = new Date().getHours();
targetPeriod = PERIODS.find(item => nowHours >= item.from && nowHours <= item.to).period;
}
function isDayPeriod(date, period) {
let hours = date.getHours();
return PERIODS.some(item => period == item.period && hours >= item.from && hours <= item.to);
}
} |
Beta Was this translation helpful? Give feedback.
-
|
при выполнении создаётся пустой плейлист |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Наверное не ошибусь, если скажу, что большинство скриптов преследует цель убирать историю прослушиваний. Пойдя от обратного, попробовал ответить на вопрос: как найти крепкий среднячок, который не успел надоесть, редко пропускается, не попадает в топы? Меня результат приятно удивил. Интересно услышать ваши результаты.
Плейлисты
Описание констант
Beta Was this translation helpful? Give feedback.
All reactions