btrtracks/dbpopulate.js

126 lines
3.6 KiB
JavaScript
Executable File

#!/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 <file> -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()