more progress (still broken)

This commit is contained in:
2023-11-06 09:03:01 +01:00
parent 210f9d62eb
commit 4b0b31471b
4 changed files with 112 additions and 71 deletions

View File

@@ -6,6 +6,7 @@ const fs = require( 'fs' );
const bodyParser = require( 'body-parser' ); const bodyParser = require( 'body-parser' );
const dialog = require( 'electron' ).dialog; const dialog = require( 'electron' ).dialog;
const session = require( 'express-session' ); const session = require( 'express-session' );
const indexer = require( './indexer.js' );
app.use( bodyParser.urlencoded( { extended: false } ) ); app.use( bodyParser.urlencoded( { extended: false } ) );
@@ -121,11 +122,15 @@ app.get( '/openSongs', ( req, res ) => {
app.get( '/indexDirs', ( req, res ) => { app.get( '/indexDirs', ( req, res ) => {
if ( req.query.dir ) { if ( req.query.dir ) {
// TODO: Load from json file // TODO: Load from json file
if ( indexedData[ req.query.dir ] ) { indexer.index( req ).then( dirIndex => {
res.send( indexedData[ req.query.dir ] ); res.send( dirIndex );
} else { } ).catch( err => {
res.send( files ); if ( err === 'ERR_DIR_NOT_FOUND' ) {
} res.status( 404 ).send( 'ERR_DIR_NOT_FOUND' );
} else {
res.status( 500 ).send( 'unable to process' );
}
} );
} else { } else {
res.status( 400 ).send( 'ERR_REQ_INCOMPLETE' ); res.status( 400 ).send( 'ERR_REQ_INCOMPLETE' );
} }

View File

@@ -206,6 +206,7 @@
repeat: false, repeat: false,
isShowingFancyView: false, isShowingFancyView: false,
errorOccurredLoading: false, errorOccurredLoading: false,
coverArtSetting: 'api'
} }
}, },
methods: { methods: {
@@ -291,7 +292,7 @@
}, },
indexFiles () { indexFiles () {
for ( let dir in this.loadedDirs ) { for ( let dir in this.loadedDirs ) {
fetch( 'http://localhost:8081/indexDirs?dir=' + this.loadedDirs[ dir ] + ( this.loadCoverArtPreview ? '&coverart=true' : '' ) ).then( res => { fetch( 'http://localhost:8081/indexDirs?dir=' + this.loadedDirs[ dir ] + ( this.loadCoverArtPreview ? '&coverart=' + this.coverArtSetting : '' ) ).then( res => {
if ( res.status === 200 ) { if ( res.status === 200 ) {
this.errorOccurredLoading = false; this.errorOccurredLoading = false;
res.json().then( json => { res.json().then( json => {

View File

@@ -16,8 +16,8 @@ const settings = JSON.parse( fs.readFileSync( path.join( __dirname + '/config/ap
const music = new MusicKit( { const music = new MusicKit( {
key: fs.readFileSync( path.join( __dirname + '/config/apple_private_key.p8' ) ).toString(), key: fs.readFileSync( path.join( __dirname + '/config/apple_private_key.p8' ) ).toString(),
teamId: settings.teamID, // This is your developer account's team ID teamId: settings.teamID,
keyId: settings.keyID // This is the keys ID keyId: settings.keyID
} ); } );
module.exports.fetch = ( type, searchQuery, callback ) => { module.exports.fetch = ( type, searchQuery, callback ) => {

View File

@@ -21,7 +21,7 @@ module.exports.index = ( req ) => {
return new Promise( ( resolve, reject ) => { return new Promise( ( resolve, reject ) => {
fs.readdir( req.query.dir, { encoding: 'utf-8' }, ( err, dat ) => { fs.readdir( req.query.dir, { encoding: 'utf-8' }, ( err, dat ) => {
if ( err ) { if ( err ) {
res.status( 404 ).send( 'ERR_DIR_NOT_FOUND' ); reject( 'ERR_DIR_NOT_FOUND' );
return; return;
}; };
( async() => { ( async() => {
@@ -29,9 +29,17 @@ module.exports.index = ( req ) => {
// what was found automatically. If no song title was found in songlist or metadata, use filename // what was found automatically. If no song title was found in songlist or metadata, use filename
// TODO: Also save found information to those files and don't rerun checks if data is present // TODO: Also save found information to those files and don't rerun checks if data is present
if ( dat.includes( 'songlist.csv' ) || dat.includes( 'songlist.json' ) ) { if ( dat.includes( 'songlist.csv' ) || dat.includes( 'songlist.json' ) ) {
parseExistingData( dat, req.query.dir ).then( data => {
parseDir( dat, req, data );
} );
} else if ( dat.includes( 'songs.json' ) ) {
parseExistingData( dat, req.query.dir ).then( data => {
resolve( data );
} ).catch( err => {
reject( err );
} );
} else { } else {
resolve( await parseDir( dat, req ) );
} }
} )(); } )();
} ); } );
@@ -40,11 +48,20 @@ module.exports.index = ( req ) => {
const parseExistingData = ( dat, dir ) => { const parseExistingData = ( dat, dir ) => {
return new Promise( ( resolve, reject ) => { return new Promise( ( resolve, reject ) => {
if ( dat.includes( 'songlist.csv' ) ) { if ( dat.includes( 'songs.json' ) ) {
resolve( JSON.parse( fs.readFileSync( path.join( dir + '/songs.json' ) ) ) );
} else if ( dat.includes( 'songlist.csv' ) ) {
// This will assume that line #1 will be song #1 in the file list
// (when sorted by name)
let results = {}; let results = {};
fs.createReadStream( path.join( dir + '/songlist.csv' ) ).pipe( csv( [ 'name', 'artist', 'dancingStyle', 'tempo' ] ) ).on( 'data', ( data ) => { let pos = 0;
results[ req.query.dir + '/' + dat[ file ] ] = data; fs.createReadStream( path.join( dir + '/songlist.csv' ) )
.pipe( csv( [ 'name', 'artist', 'dancingStyle', 'tempo' ] ) )
.on( 'data', ( data ) => {
results[ dir + '/' + dat[ pos ] ] = data;
pos += 1;
} ).on( 'end', () => { } ).on( 'end', () => {
console.log( results );
resolve( results ); resolve( results );
} ); } );
} else if ( dat.includes( 'songlist.json' ) ) { } else if ( dat.includes( 'songlist.json' ) ) {
@@ -53,69 +70,87 @@ const parseExistingData = ( dat, dir ) => {
} ); } );
} }
const parseDir = async ( dat, req ) => { hasCompletedFetching = {};
let files = {};
for ( let file in dat ) { const parseDir = ( dat, req, existingData ) => {
if ( allowedFileTypes.includes( dat[ file ].slice( dat[ file ].indexOf( '.' ), dat[ file ].length ) ) ) { console.log( existingData );
try { return new Promise( ( resolve, reject ) => {
let metadata = await musicMetadata.parseFile( req.query.dir + '/' + dat[ file ] ); ( async() => {
files[ req.query.dir + '/' + dat[ file ] ] = { let files = {};
'artist': metadata[ 'common' ][ 'artist' ], for ( let file in dat ) {
'title': metadata[ 'common' ][ 'title' ], if ( allowedFileTypes.includes( dat[ file ].slice( dat[ file ].indexOf( '.' ), dat[ file ].length ) ) ) {
'year': metadata[ 'common' ][ 'year' ], try {
'bpm': metadata[ 'common' ][ 'bpm' ], let metadata = await musicMetadata.parseFile( req.query.dir + '/' + dat[ file ] );
'genre': metadata[ 'common' ][ 'genre' ], files[ req.query.dir + '/' + dat[ file ] ] = {
'duration': Math.round( metadata[ 'format' ][ 'duration' ] ), 'artist': metadata[ 'common' ][ 'artist' ],
'isLossless': metadata[ 'format' ][ 'lossless' ], 'title': metadata[ 'common' ][ 'title' ],
'sampleRate': metadata[ 'format' ][ 'sampleRate' ], 'year': metadata[ 'common' ][ 'year' ],
'bitrate': metadata[ 'format' ][ 'bitrate' ], 'bpm': metadata[ 'common' ][ 'bpm' ],
'numberOfChannels': metadata[ 'format' ][ 'numberOfChannels' ], 'genre': metadata[ 'common' ][ 'genre' ],
'container': metadata[ 'format' ][ 'container' ], 'duration': Math.round( metadata[ 'format' ][ 'duration' ] ),
'filename': req.query.dir + '/' + dat[ file ], 'isLossless': metadata[ 'format' ][ 'lossless' ],
} 'sampleRate': metadata[ 'format' ][ 'sampleRate' ],
if ( metadata[ 'common' ][ 'picture' ] ) { 'bitrate': metadata[ 'format' ][ 'bitrate' ],
files[ req.query.dir + '/' + dat[ file ] ][ 'hasCoverArt' ] = true; 'numberOfChannels': metadata[ 'format' ][ 'numberOfChannels' ],
if ( req.query.coverart == 'true' ) { 'container': metadata[ 'format' ][ 'container' ],
coverArtIndex[ req.query.dir + '/' + dat[ file ] ] = metadata[ 'common' ][ 'picture' ] ? metadata[ 'common' ][ 'picture' ][ 0 ][ 'data' ] : undefined; 'filename': req.query.dir + '/' + dat[ file ],
} }
} else { if ( req.query.coverart == 'meta' ) {
if ( req.query.coverart == 'true' ) { if ( metadata[ 'common' ][ 'picture' ] ) {
imageFetcher.fetch( 'songs', metadata[ 'common' ][ 'artist' ] + ' ' + metadata[ 'common' ][ 'title' ], ( err, data ) => { files[ req.query.dir + '/' + dat[ file ] ][ 'hasCoverArt' ] = true;
if ( err ) { coverArtIndex[ req.query.dir + '/' + dat[ file ] ] = metadata[ 'common' ][ 'picture' ] ? metadata[ 'common' ][ 'picture' ][ 0 ][ 'data' ] : undefined;
indexedData[ req.query.dir ][ req.query.dir + '/' + dat[ file ] ][ 'hasCoverArt' ] = false; } else {
files[ req.query.dir + '/' + dat[ file ] ][ 'hasCoverArt' ] = false; files[ req.query.dir + '/' + dat[ file ] ][ 'hasCoverArt' ] = false;
return;
} }
if ( data.results.songs ) { } else if ( req.query.coverart == 'api' ) {
if ( data.results.songs.data ) { hasCompletedFetching[ req.query.dir + '/' + dat[ file ] ] = false;
let url = data.results.songs.data[ 0 ].attributes.artwork.url; imageFetcher.fetch( 'songs', metadata[ 'common' ][ 'artist' ] + ' ' + metadata[ 'common' ][ 'title' ], ( err, data ) => {
url = url.replace( '{w}', data.results.songs.data[ 0 ].attributes.artwork.width ); if ( err ) {
url = url.replace( '{h}', data.results.songs.data[ 0 ].attributes.artwork.height ); files[ req.query.dir + '/' + dat[ file ] ][ 'hasCoverArt' ] = false;
console.log( url ); return;
}
if ( data.results.songs ) {
if ( data.results.songs.data ) {
let url = data.results.songs.data[ 0 ].attributes.artwork.url;
url = url.replace( '{w}', data.results.songs.data[ 0 ].attributes.artwork.width );
url = url.replace( '{h}', data.results.songs.data[ 0 ].attributes.artwork.height );
console.log( url );
} else {
files[ req.query.dir + '/' + dat[ file ] ][ 'hasCoverArt' ] = false;
}
} else { } else {
indexedData[ req.query.dir ][ req.query.dir + '/' + dat[ file ] ][ 'hasCoverArt' ] = false;
files[ req.query.dir + '/' + dat[ file ] ][ 'hasCoverArt' ] = false; files[ req.query.dir + '/' + dat[ file ] ][ 'hasCoverArt' ] = false;
} }
} else { hasCompletedFetching[ req.query.dir + '/' + dat[ file ] ] = true;
indexedData[ req.query.dir ][ req.query.dir + '/' + dat[ file ] ][ 'hasCoverArt' ] = false; } );
files[ req.query.dir + '/' + dat[ file ] ][ 'hasCoverArt' ] = false; files[ req.query.dir + '/' + dat[ file ] ][ 'hasCoverArt' ] = true;
} } else {
} ); files[ req.query.dir + '/' + dat[ file ] ][ 'hasCoverArt' ] = false;
files[ req.query.dir + '/' + dat[ file ] ][ 'hasCoverArt' ] = true; }
} else { } catch ( err ) {
files[ req.query.dir + '/' + dat[ file ] ][ 'hasCoverArt' ] = false; console.error( err );
files[ req.query.dir + '/' + dat[ file ] ] = 'ERROR';
} }
} }
} catch ( err ) {
console.error( err );
files[ req.query.dir + '/' + dat[ file ] ] = 'ERROR';
} }
} else if ( dat[ file ].slice( dat[ file ].indexOf( '.' ), dat[ file ].length ) === '.csv' ) { let ok = false;
setInterval( () => {
for ( let song in hasCompletedFetching ) {
if ( !hasCompletedFetching[ song ] ) {
ok = false;
}
}
if ( ok ) {
indexedData[ req.query.dir ] = files;
resolve( files );
}
ok = true;
}, 250 );
} )();
} )
};
} else if ( dat[ file ].slice( dat[ file ].indexOf( '.' ), dat[ file ].length ) === '.json' ) {
const saveToDisk = () => {
}
} };
indexedData[ req.query.dir ] = files;
return files;
}