113 lines
3.1 KiB
JavaScript
113 lines
3.1 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) {
|
|
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
|
|
// console.log("Skipping search for", albumQuery, trackQuery, duration)
|
|
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()
|
|
}
|