#!/usr/bin/env babel-node import fs from 'fs-extra' import path from 'path' import sqlite from 'sqlite' import Promise from 'bluebird' import readline from 'readline' import asn from './common/async' import dl from './common/download' const values = require(path.join(__dirname, 'values.json')) const musicdir = path.resolve(values.directory) const dbPromise = Promise.resolve() .then(() => sqlite.open(path.join(__dirname, values.database), { Promise, cache: true })) .then(db => db.migrate()) // ffprobe -i -show_entries format=duration -v quiet -of csv="p=0" async function interactive (fpath, db) { let rl = readline.createInterface({ input: process.stdin, output: process.stdout }) console.log('=> No metadata found for specified file! Interactive mode enabled.\n') let pt = path.parse(fpath) let track = { file: fpath, title: pt.name } let clean = dl.parseTitle(track) console.log('== Determined Title: ' + clean.title) console.log('== Determined Artist: ' + clean.artist) let newTitle = await asn.askAsync(rl, `Title [${clean.title}] ? `) let newArtist = await asn.askAsync(rl, `Artist [${clean.artist}] ? `) if (newTitle.trim() !== '') track.title = newTitle if (newArtist.trim() !== '') track.artist = newArtist let len = await asn.promiseExec(`ffprobe -i "${track.file}" -show_entries format=duration -v quiet -of csv="p=0"`) track.duration = parseFloat(len) rl.close() return track } async function run () { let db = await dbPromise if (process.argv[2] != null) { let filePath = path.resolve(process.argv[2]) let trackinf try { trackinf = await dl.getInfos(filePath) } catch (e) { trackinf = await interactive(filePath, db) } if (!trackinf) { console.error('Nothing to do.') return } let ensure = await db.get('SELECT * FROM Track WHERE title=? AND artist=?', trackinf.title, trackinf.artist) if (ensure) { console.error('A track of this description already exists in the database.') return } await db.run('INSERT INTO Track VALUES (NULL,?,?,?,?,?,?,?,?)', [trackinf.title, trackinf.artist, trackinf.file, trackinf.album || null, trackinf.genre || null, trackinf.track || null, trackinf.year || null, Math.floor(trackinf.duration)]) console.log('=> Done.') return } let files = await getFiles(musicdir) let cleanTrackData = [] let skips = 0 for (let i in files) { let file = files[i] // if (cleanTrackData.length > 10) break // debug purposes process.stdout.write(`\rProcessing file ${parseInt(i) + 1} of ${files.length}.. (${skips} skipped)`) try { let fd = await dl.getInfos(file) cleanTrackData.push(fd) } catch (e) { skips++ continue } } process.stdout.write(`\r${cleanTrackData.length} files indexed, ${skips} files were skipped. \n`) let entries = 0 for (let i in cleanTrackData) { let track = cleanTrackData[i] process.stdout.write(`\rPopulating database.. (Track ${parseInt(i) + 1} of ${cleanTrackData.length})`) try { let ensure = await db.get('SELECT * FROM Track WHERE title=? AND artist=?', track.title, track.artist) if (ensure) continue await db.run('INSERT INTO Track VALUES (NULL,?,?,?,?,?,?,?,?)', [track.title, track.artist, track.file, track.album || null, track.genre || null, track.track || null, track.year || null, Math.floor(track.duration)]) entries++ } catch (e) { console.warn(e.message) continue } } console.log(`=> \n${entries} tracks were successfully added to the cache!`) } run()