spotifylookup/resultvisualizer.js

159 lines
3.7 KiB
JavaScript

const fs = require('fs/promises');
const path = require('path');
const { createDocument, $ } = require(path.join(__dirname, 'bits', 'psuedoframework'));
const fescriptpath = path.join(__dirname, 'bits', 'frontend.js');
const stylesheet = `
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
*, *::before, *::after {
box-sizing: border-box;
}
body {
background-color: #000922;
font-family: sans;
color: white;
}
.wrapper, .wrapper table {
width: 100%;
border-collapse: collapse;
}
table tr:nth-child(odd) {
background-color: #030a38;
}
tr {
cursor: pointer;
}
.meta .file {
font-weight: bold;
}
.meta .title, .meta .artist {
font-size: .6rem;
}
input[type=checkbox] {
width: 1.2rem;
height: 1.2rem;
border-radius: 8px;
}
button {
font-size: 2rem;
padding: 1.6rem 6rem;
margin: 1rem;
background-color: #1DB954;
text-transform: uppercase;
color: white;
font-weight: bold;
border: none;
border-radius: 4rem;
cursor: pointer;
transition: background-color .15s linear;
}
button:hover {
background-color: #25df67;
}
`;
async function getPreviousSelection() {
let selection;
try {
selection = JSON.parse(await fs.readFile(path.join(__dirname, 'track-selection.json')));
} catch (e) {
selection = [];
}
return selection;
}
const checkCache = [];
function selectionContainsURI(list, uri) {
if (list.length === 0) {
return false;
}
// Only check a single one with the same spotify uri
if (checkCache.includes(uri)) {
return false;
}
const result = list.some((item) => item[1] === uri);
if (result) {
checkCache.push(uri);
}
return result;
}
async function generate() {
const fescript = await fs.readFile(fescriptpath);
const selection = await getPreviousSelection();
const wrapper = $('div', null, ['wrapper']);
const table = $('table');
const header = $('thead', `
<thead>
<tr>
<th>Choose</th>
<th>Original File</th>
<th>Type</th>
<th>Album</th>
<th>Title</th>
<th>Artist</th>
<th>Preview</th>
<th>Meta</th>
</tr>
</thead>
`);
const tbody = $('tbody');
const spotify = JSON.parse(await fs.readFile('spotify.json'));
let rows = [];
for (const entry of spotify) {
let row = [];
for (const sfItem of entry.spotify) {
row.push([
'<input type="checkbox" ' +
`data-spotify="${sfItem.uri}" ` +
`data-file="${entry.file}" ` +
(selectionContainsURI(selection, sfItem.uri) ? 'checked' : '') +
'>',
'',
sfItem.album.album_type,
sfItem.album.name,
sfItem.name,
sfItem.artists.map((item) => item.name).join(', '),
sfItem.preview_url ? `<audio preload="none" controls src="${sfItem.preview_url}"></audio>` : '',
`<a href="${sfItem.uri}" target="_blank">` +
`<img src="${sfItem.album.images[sfItem.album.images.length - 1].url}">` +
'</a>'
]);
}
row[0][1] = $('div',
$('span', path.basename(entry.file), ['file']) +
'<br>' +
$('span', `Title: ${entry.title}`, ['title']) +
`<br>` +
$('span', `Artist: ${entry.artist}`, ['artist']),
['meta']
);
rows.push(
row.map(
(rowItem) => $('tr',
rowItem.map(
(colItem) => $('td', colItem)
).join(''))
).join('')
);
}
rows.forEach((item) => tbody.append(item));
wrapper.append(table.append(header).append(tbody))
.append(`<button id="export">Export selection</button>`)
.append(`<script defer>${fescript}</script>`);
await fs.writeFile('search-results.html', createDocument(stylesheet, wrapper));
}
generate().catch(console.error);