sanitize filenames and update function
This commit is contained in:
parent
710f1a5e48
commit
2abf4506b3
@ -25,6 +25,7 @@
|
|||||||
"redis": "^3.0.2",
|
"redis": "^3.0.2",
|
||||||
"request": "^2.88.2",
|
"request": "^2.88.2",
|
||||||
"request-promise-native": "^1.0.8",
|
"request-promise-native": "^1.0.8",
|
||||||
|
"sanitize-filename": "^1.6.3",
|
||||||
"socket.io": "^2.3.0",
|
"socket.io": "^2.3.0",
|
||||||
"sqlite": "^4.0.9",
|
"sqlite": "^4.0.9",
|
||||||
"sqlite3": "^4.2.0",
|
"sqlite3": "^4.2.0",
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import {exec} from 'child_process'
|
import { exec } from 'child_process'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import fs from 'fs-extra'
|
import fs from 'fs-extra'
|
||||||
import url from 'url'
|
|
||||||
import os from 'os'
|
import os from 'os'
|
||||||
import qs from 'querystring'
|
|
||||||
|
|
||||||
const supportedMetadata = ['album', 'genre', 'title', 'artist', 'year', 'track']
|
const supportedMetadata = ['album', 'genre', 'title', 'artist', 'year', 'track']
|
||||||
|
|
||||||
@ -41,7 +39,7 @@ function filewalker (dir, done) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function insertDB (db, track) {
|
async function insertDB (db, track) {
|
||||||
let ensure = await db.get('SELECT * FROM Track WHERE title=? AND artist=? AND album=?', track.title, track.artist, track.album || '')
|
const ensure = await db.get('SELECT * FROM Track WHERE title=? AND artist=? AND album=?', track.title, track.artist, track.album || '')
|
||||||
if (ensure) {
|
if (ensure) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -54,13 +52,15 @@ async function insertDB (db, track) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function updateDB (db, id, meta) {
|
async function updateDB (db, id, meta) {
|
||||||
let sanit = []
|
const ref = []
|
||||||
for (let key in meta) {
|
const vals = []
|
||||||
|
for (const key in meta) {
|
||||||
if (supportedMetadata.indexOf(key) === -1) continue
|
if (supportedMetadata.indexOf(key) === -1) continue
|
||||||
let val = meta[key]
|
const val = meta[key]
|
||||||
sanit.push(key + '="' + val + '"')
|
ref.push(key + ' = ?')
|
||||||
|
vals.push(val)
|
||||||
}
|
}
|
||||||
await db.run('UPDATE Track SET ' + sanit.join(',') + ' WHERE id = ?', id)
|
await db.run('UPDATE Track SET ' + ref.join(',') + ' WHERE id = ?', [...vals, id])
|
||||||
return meta
|
return meta
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ function promiseExec (cmd, opts) {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
exec(cmd, opts, function (err, stdout, stderr) {
|
exec(cmd, opts, function (err, stdout, stderr) {
|
||||||
if (err) return reject(err)
|
if (err) return reject(err)
|
||||||
resolve({stdout, stderr})
|
resolve({ stdout, stderr })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -90,8 +90,8 @@ function askAsync (rl, q) {
|
|||||||
|
|
||||||
function copyAsync (fsrc, fdst) {
|
function copyAsync (fsrc, fdst) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let source = fs.createReadStream(path.resolve(fsrc))
|
const source = fs.createReadStream(path.resolve(fsrc))
|
||||||
let dest = fs.createWriteStream(path.resolve(fdst))
|
const dest = fs.createWriteStream(path.resolve(fdst))
|
||||||
|
|
||||||
source.pipe(dest)
|
source.pipe(dest)
|
||||||
source.on('end', resolve)
|
source.on('end', resolve)
|
||||||
@ -100,13 +100,13 @@ function copyAsync (fsrc, fdst) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getInfos (file) {
|
async function getInfos (file) {
|
||||||
let formatData = await promiseExec(`ffprobe -i "${file}" -show_entries format -v quiet -of json`)
|
const formatData = await promiseExec(`ffprobe -i "${file}" -show_entries format -v quiet -of json`)
|
||||||
|
|
||||||
let parsed = JSON.parse(formatData.stdout)
|
let parsed = JSON.parse(formatData.stdout)
|
||||||
if (!parsed || !parsed.format || !parsed.format.duration) throw new Error('Failed to parse metadata!')
|
if (!parsed || !parsed.format || !parsed.format.duration) throw new Error('Failed to parse metadata!')
|
||||||
parsed = parsed.format
|
parsed = parsed.format
|
||||||
|
|
||||||
let data = {
|
const data = {
|
||||||
file,
|
file,
|
||||||
duration: parseFloat(parsed.duration)
|
duration: parseFloat(parsed.duration)
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ async function getInfos (file) {
|
|||||||
if (Math.floor(data.duration) === 0) throw new Error('Invalid file type!')
|
if (Math.floor(data.duration) === 0) throw new Error('Invalid file type!')
|
||||||
|
|
||||||
if (parsed.tags) {
|
if (parsed.tags) {
|
||||||
for (let k in parsed.tags) {
|
for (const k in parsed.tags) {
|
||||||
let tagtype = k.toLowerCase()
|
let tagtype = k.toLowerCase()
|
||||||
let value = parsed.tags[k]
|
let value = parsed.tags[k]
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ async function getInfos (file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!data.title) {
|
if (!data.title) {
|
||||||
let parsed = path.parse(file)
|
const parsed = path.parse(file)
|
||||||
data.title = parsed.name
|
data.title = parsed.name
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,12 +140,12 @@ async function getInfos (file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function setMetadata (file, meta, source, cleanup = false) {
|
async function setMetadata (file, meta, source, cleanup = false) {
|
||||||
if (!meta || !meta['title'] || meta.title === '') throw new Error('Invalid metadata provided')
|
if (!meta || !meta.title || meta.title === '') throw new Error('Invalid metadata provided')
|
||||||
let sanit = []
|
const sanit = []
|
||||||
let dbq = {}
|
const dbq = {}
|
||||||
for (let key in meta) {
|
for (let key in meta) {
|
||||||
if (supportedMetadata.indexOf(key) === -1) continue
|
if (supportedMetadata.indexOf(key) === -1) continue
|
||||||
let val = meta[key]
|
const val = meta[key]
|
||||||
if ((key === 'artist' || key === 'title') && (!val || val === '')) continue
|
if ((key === 'artist' || key === 'title') && (!val || val === '')) continue
|
||||||
dbq[key] = val
|
dbq[key] = val
|
||||||
if (key === 'year') key = 'date'
|
if (key === 'year') key = 'date'
|
||||||
@ -155,7 +155,7 @@ async function setMetadata (file, meta, source, cleanup = false) {
|
|||||||
if (!sanit.length) throw new Error('Invalid metadata provided')
|
if (!sanit.length) throw new Error('Invalid metadata provided')
|
||||||
|
|
||||||
if (!source) {
|
if (!source) {
|
||||||
let p = path.parse(file)
|
const p = path.parse(file)
|
||||||
source = path.join(os.tmpdir(), '.retmp' + p.ext)
|
source = path.join(os.tmpdir(), '.retmp' + p.ext)
|
||||||
cleanup = true
|
cleanup = true
|
||||||
await copyAsync(file, source)
|
await copyAsync(file, source)
|
||||||
@ -171,5 +171,14 @@ async function setMetadata (file, meta, source, cleanup = false) {
|
|||||||
return { file, dbq }
|
return { file, dbq }
|
||||||
}
|
}
|
||||||
|
|
||||||
export default { getFiles, promiseExec, askAsync, insertDB, updateDB,
|
export default {
|
||||||
copyAsync, getInfos, setMetadata, supportedMetadata }
|
getFiles,
|
||||||
|
promiseExec,
|
||||||
|
askAsync,
|
||||||
|
insertDB,
|
||||||
|
updateDB,
|
||||||
|
copyAsync,
|
||||||
|
getInfos,
|
||||||
|
setMetadata,
|
||||||
|
supportedMetadata
|
||||||
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import readline from 'readline'
|
import readline from 'readline'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
import sanitize from 'sanitize-filename'
|
||||||
|
|
||||||
import asn from './common/async'
|
import asn from './common/async'
|
||||||
import dl from './common/download'
|
import dl from './common/download'
|
||||||
@ -47,6 +48,7 @@ async function download (furl) {
|
|||||||
filename = fileAnsw
|
filename = fileAnsw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filename = sanitize(filename)
|
||||||
const fn = path.join(musicdir, filename)
|
const fn = path.join(musicdir, filename)
|
||||||
await asn.setMetadata(fn, clean, file.source, true)
|
await asn.setMetadata(fn, clean, file.source, true)
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
import sanitize from 'sanitize-filename'
|
||||||
import asn from './common/async'
|
import asn from './common/async'
|
||||||
import dl from './common/download'
|
import dl from './common/download'
|
||||||
import { dbPromise } from './database'
|
import { dbPromise } from './database'
|
||||||
@ -16,7 +17,8 @@ async function downloadLocally (id) {
|
|||||||
const info = await getTrackMetaReal(id)
|
const info = await getTrackMetaReal(id)
|
||||||
if (!info) throw new Error('No track with this ID in external list.')
|
if (!info) throw new Error('No track with this ID in external list.')
|
||||||
const file = await dl.fetchVideo(info)
|
const file = await dl.fetchVideo(info)
|
||||||
const filename = info.artist + ' - ' + info.title + '.mp3'
|
let filename = info.artist + ' - ' + info.title + '.mp3'
|
||||||
|
filename = sanitize(filename)
|
||||||
info.file = path.join(values.directory, filename)
|
info.file = path.join(values.directory, filename)
|
||||||
await asn.promiseExec(`ffmpeg -i "${file.source}" -metadata artist="${info.artist}" -metadata title="${info.title}" -codec copy "${info.file}"`)
|
await asn.promiseExec(`ffmpeg -i "${file.source}" -metadata artist="${info.artist}" -metadata title="${info.title}" -codec copy "${info.file}"`)
|
||||||
await fs.unlink(file.source)
|
await fs.unlink(file.source)
|
||||||
|
Loading…
Reference in New Issue
Block a user