Files
radio-scraper/playlist-search.js
2021-03-02 18:44:06 -07:00

112 lines
3.0 KiB
JavaScript

const Fuse = require('fuse.js')
const fs = require('fs')
const scraper = require('./playlist-scrape')
const PLAYLIST_URL = 'https://nintendoradioplaylist2.000webhostapp.com/Livestream%20Playlist.html'
const playlist = require('./playlist.json')
const albumValidCharacters = new Set()
const trackValidCharacters = new Set()
function buildAlbumValidCharacters() {
albumValidCharacters.clear()
new Set(playlist.map(entry => entry.album)) // Get set of albums
.forEach(album => album.split('').forEach(letter => albumValidCharacters.add(letter)))
}
function buildTrackValidCharacters() {
trackValidCharacters.clear()
new Set(playlist.map(entry => entry.track))
.forEach(track => track.split('').forEach(letter => trackValidCharacters.add(letter)))
}
function getValidAlbumCharacters() {
if (albumValidCharacters.size === 0) {
buildAlbumValidCharacters()
}
return albumValidCharacters
}
function getValidTrackCharacters() {
if (trackValidCharacters.size === 0) {
console.log("Building index of valid track characters, this may take some time...")
buildTrackValidCharacters()
}
return trackValidCharacters
}
const fuseByAlbum = new Fuse(playlist, {
keys: ['album']
})
const fuseByTrack = new Fuse(playlist, {
keys: ['track']
})
function searchAlbums(query) {
return fuseByAlbum.search(query)
}
function searchTracks(query) {
return fuseByTrack.search(query)
}
function fullSearch(album, track, duration) {
const inAlbumSearch = new Fuse(searchAlbums(album), {keys: ['item.track']})
const trackResults = inAlbumSearch.search(track).map(result => result.item)
if (duration) {
return filterResultsByDuration(trackResults, duration)
} else {
// No duration present, treat as album+track lookup
return trackResults[0]
}
}
function albumDurationSearch(album, duration) {
const albumResults = searchAlbums(album)
return filterResultsByDuration(albumResults, duration, true)
}
function trackDurationSearch(track, duration) {
const trackResults = searchTracks(track)
return filterResultsByDuration(trackResults, duration)
}
function filterResultsByDuration(results, duration, failSearch = false) {
const durationResults = results.filter(result => result.item.duration === duration)
if (durationResults.length > 0) {
return durationResults[0]
} else {
return failSearch ? null : results[0]
}
}
function search(albumQuery, trackQuery, duration) {
if (albumQuery && trackQuery && duration) {
return fullSearch(albumQuery, trackQuery, duration)
} else if (albumQuery && duration) {
return albumDurationSearch(albumQuery, duration)
} else if (trackQuery && duration) {
return trackDurationSearch(trackQuery, duration)
} else {
// Not enough info to perform a decent search
return null
}
}
function trySearch() {
console.log(JSON.stringify(search("Final Fantasy VI", "Dancing Mad", "\f")))
}
// These shouldn't be called asynchronously, manually call it ourselves
buildTrackValidCharacters()
buildAlbumValidCharacters()
module.exports = {
search,
getValidAlbumCharacters,
getValidTrackCharacters
}
if (require.main === module) {
trySearch()
}