More voting stuff, start moving to typescript
This commit is contained in:
126
playlist-search.ts
Normal file
126
playlist-search.ts
Normal file
@@ -0,0 +1,126 @@
|
||||
import Fuse from 'fuse.js';
|
||||
import FuseResult = Fuse.FuseResult;
|
||||
|
||||
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: Track[] = 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): FuseResult<Track>[] {
|
||||
return fuseByAlbum.search(query)
|
||||
}
|
||||
|
||||
function searchTracks(query): FuseResult<Track>[] {
|
||||
return fuseByTrack.search(query)
|
||||
}
|
||||
|
||||
function fullSearch(album, track, duration): FuseResult<Track> {
|
||||
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): FuseResult<Track> {
|
||||
const albumResults = searchAlbums(album)
|
||||
return filterResultsByDuration(albumResults, duration, true)
|
||||
}
|
||||
|
||||
function trackDurationSearch(track, duration): FuseResult<Track> {
|
||||
const trackResults = searchTracks(track)
|
||||
return filterResultsByDuration(trackResults, duration)
|
||||
}
|
||||
|
||||
function filterResultsByDuration(results, duration, failSearch = false): FuseResult<Track> {
|
||||
const durationResults = results.filter(result => result.item.duration === duration)
|
||||
if (durationResults.length > 0) {
|
||||
return durationResults[0]
|
||||
} else {
|
||||
return failSearch ? null : results[0]
|
||||
}
|
||||
}
|
||||
|
||||
export function search(albumQuery, trackQuery, duration): FuseResult<Track> {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
export function getAt(index): Track {
|
||||
return playlist[index]
|
||||
}
|
||||
|
||||
function trySearch() {
|
||||
console.log(JSON.stringify(search("Final Fantasy VI", "Dancing Mad", "\f")))
|
||||
}
|
||||
|
||||
class Track {
|
||||
public album: string
|
||||
public track: string
|
||||
public duration: string
|
||||
}
|
||||
|
||||
// These shouldn't be called asynchronously, manually call it ourselves
|
||||
buildTrackValidCharacters()
|
||||
buildAlbumValidCharacters()
|
||||
|
||||
module.exports = {
|
||||
search,
|
||||
getAt,
|
||||
getValidAlbumCharacters,
|
||||
getValidTrackCharacters
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
trySearch()
|
||||
}
|
||||
Reference in New Issue
Block a user