161 lines
3.7 KiB
JavaScript
161 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}</td>`
|
|
).join('') +
|
|
'</tr>'
|
|
).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);
|