feat: view queries in; media updated
This commit is contained in:
parent
08e2c2ff3f
commit
057d75f863
49 changed files with 578 additions and 353 deletions
|
@ -13,7 +13,6 @@ const fetchDataFromView = async (viewName) => {
|
|||
const { data, error } = await supabase
|
||||
.from(viewName)
|
||||
.select('*')
|
||||
.order('listened_at', { ascending: false })
|
||||
.range(rangeStart, rangeStart + PAGE_SIZE - 1)
|
||||
|
||||
if (error) {
|
||||
|
@ -23,7 +22,7 @@ const fetchDataFromView = async (viewName) => {
|
|||
|
||||
if (data.length === 0) break
|
||||
|
||||
rows = rows.concat(data)
|
||||
rows = [...rows, ...data]
|
||||
|
||||
if (data.length < PAGE_SIZE) break
|
||||
rangeStart += PAGE_SIZE
|
||||
|
@ -32,113 +31,70 @@ const fetchDataFromView = async (viewName) => {
|
|||
return rows
|
||||
}
|
||||
|
||||
const aggregateData = (data, groupByField, groupByType) => {
|
||||
const aggregation = {}
|
||||
|
||||
data.forEach(item => {
|
||||
const key = item[groupByField]
|
||||
if (!aggregation[key]) {
|
||||
let imageField = ''
|
||||
|
||||
switch (groupByType) {
|
||||
case 'artist':
|
||||
imageField = item['artist_art']
|
||||
break
|
||||
case 'album':
|
||||
imageField = item['album_art']
|
||||
break
|
||||
case 'track':
|
||||
imageField = item['album_art']
|
||||
break
|
||||
default:
|
||||
imageField = ''
|
||||
}
|
||||
|
||||
aggregation[key] = {
|
||||
title: item[groupByField],
|
||||
plays: 0,
|
||||
url: item['artist_url'],
|
||||
image: imageField,
|
||||
genre: item['artist_genres'],
|
||||
type: groupByType
|
||||
}
|
||||
|
||||
if (groupByType === 'track' || groupByType === 'album') aggregation[key]['artist'] = item['artist_name']
|
||||
}
|
||||
|
||||
aggregation[key].plays++
|
||||
})
|
||||
|
||||
return Object.values(aggregation).sort((a, b) => b['plays'] - a['plays']).map((item, index) => ({ ...item, rank: index + 1 }))
|
||||
}
|
||||
|
||||
const buildRecents = (data) => {
|
||||
return data.map(listen => ({
|
||||
title: listen['track_name'],
|
||||
artist: listen['artist_name'],
|
||||
url: listen['artist_url'],
|
||||
timestamp: listen['listened_at'],
|
||||
image: listen['album_art'],
|
||||
type: 'track'
|
||||
})).sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp))
|
||||
}
|
||||
|
||||
const aggregateGenres = (data) => {
|
||||
const genreAggregation = {}
|
||||
|
||||
data.forEach(item => {
|
||||
const genre = item['genre_name'] || ''
|
||||
const genreUrl = item['genre_url'] || ''
|
||||
|
||||
if (!genreAggregation[genre]) {
|
||||
genreAggregation[genre] = {
|
||||
name: genre,
|
||||
url: genreUrl,
|
||||
plays: 0,
|
||||
type: 'genre'
|
||||
}
|
||||
}
|
||||
|
||||
genreAggregation[genre]['plays']++
|
||||
})
|
||||
|
||||
return Object.values(genreAggregation).sort((a, b) => b['plays'] - a['plays'])
|
||||
}
|
||||
|
||||
export default async function () {
|
||||
export default async function fetchMusicData() {
|
||||
try {
|
||||
const [recentTracks, monthTracks, threeMonthTracks] = await Promise.all([
|
||||
const [
|
||||
recentTracks,
|
||||
weekTracks,
|
||||
weekArtists,
|
||||
weekAlbums,
|
||||
weekGenres,
|
||||
monthTracks,
|
||||
monthArtists,
|
||||
monthAlbums,
|
||||
monthGenres,
|
||||
threeMonthTracks,
|
||||
threeMonthArtists,
|
||||
threeMonthAlbums,
|
||||
threeMonthGenres,
|
||||
] = await Promise.all([
|
||||
fetchDataFromView('recent_tracks'),
|
||||
fetchDataFromView('week_tracks'),
|
||||
fetchDataFromView('week_artists'),
|
||||
fetchDataFromView('week_albums'),
|
||||
fetchDataFromView('week_genres'),
|
||||
fetchDataFromView('month_tracks'),
|
||||
fetchDataFromView('three_month_tracks')
|
||||
fetchDataFromView('month_artists'),
|
||||
fetchDataFromView('month_albums'),
|
||||
fetchDataFromView('month_genres'),
|
||||
fetchDataFromView('three_month_tracks'),
|
||||
fetchDataFromView('three_month_artists'),
|
||||
fetchDataFromView('three_month_albums'),
|
||||
fetchDataFromView('three_month_genres'),
|
||||
])
|
||||
|
||||
return {
|
||||
recent: buildRecents(recentTracks),
|
||||
recent: recentTracks,
|
||||
week: {
|
||||
artists: aggregateData(recentTracks, 'artist_name', 'artist'),
|
||||
albums: aggregateData(recentTracks, 'album_name', 'album'),
|
||||
tracks: aggregateData(recentTracks, 'track_name', 'track'),
|
||||
genres: aggregateGenres(recentTracks),
|
||||
totalTracks: recentTracks.length.toLocaleString('en-US')
|
||||
tracks: weekTracks,
|
||||
artists: weekArtists,
|
||||
albums: weekAlbums,
|
||||
genres: weekGenres,
|
||||
totalTracks: weekTracks
|
||||
.reduce((acc, track) => acc + track.plays, 0)
|
||||
.toLocaleString('en-US'),
|
||||
},
|
||||
month: {
|
||||
artists: aggregateData(monthTracks, 'artist_name', 'artist'),
|
||||
albums: aggregateData(monthTracks, 'album_name', 'album'),
|
||||
tracks: aggregateData(monthTracks, 'track_name', 'track'),
|
||||
genres: aggregateGenres(monthTracks),
|
||||
totalTracks: monthTracks.length.toLocaleString('en-US')
|
||||
tracks: monthTracks,
|
||||
artists: monthArtists,
|
||||
albums: monthAlbums,
|
||||
genres: monthGenres,
|
||||
totalTracks: monthTracks
|
||||
.reduce((acc, track) => acc + track.plays, 0)
|
||||
.toLocaleString('en-US'),
|
||||
},
|
||||
threeMonth: {
|
||||
artists: aggregateData(threeMonthTracks, 'artist_name', 'artist'),
|
||||
albums: aggregateData(threeMonthTracks, 'album_name', 'album'),
|
||||
tracks: aggregateData(threeMonthTracks, 'track_name', 'track'),
|
||||
genres: aggregateGenres(threeMonthTracks),
|
||||
totalTracks: threeMonthTracks.length.toLocaleString('en-US')
|
||||
}
|
||||
tracks: threeMonthTracks,
|
||||
artists: threeMonthArtists,
|
||||
albums: threeMonthAlbums,
|
||||
genres: threeMonthGenres,
|
||||
totalTracks: threeMonthTracks
|
||||
.reduce((acc, track) => acc + track.plays, 0)
|
||||
.toLocaleString('en-US'),
|
||||
},
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error in fetching and processing music data:', error)
|
||||
console.error('Error fetching and processing music data:', error)
|
||||
return {}
|
||||
}
|
||||
}
|
|
@ -40,6 +40,7 @@ export default async function () {
|
|||
image: show['episode']['image'],
|
||||
backdrop: show['episode']['backdrop'],
|
||||
last_watched_at: show['episode']['last_watched_at'],
|
||||
grid: show['grid'],
|
||||
type: 'tv'
|
||||
}))
|
||||
|
||||
|
|
Reference in a new issue