feat(cli): load local file
This commit is contained in:
parent
7a9b4910b4
commit
397326ce13
3 changed files with 54 additions and 32 deletions
79
src/cli.ts
79
src/cli.ts
|
@ -4,9 +4,9 @@
|
||||||
|
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { fetchMscz, MSCZ_URL_SYM } from './mscz'
|
import { fetchMscz, setMscz, MSCZ_URL_SYM } from './mscz'
|
||||||
import { loadMscore, INDV_DOWNLOADS, WebMscore } from './mscore'
|
import { loadMscore, INDV_DOWNLOADS, WebMscore } from './mscore'
|
||||||
import { ScoreInfoHtml } from './scoreinfo'
|
import { ScoreInfo, ScoreInfoHtml, ScoreInfoObj } from './scoreinfo'
|
||||||
import { escapeFilename } from './utils'
|
import { escapeFilename } from './utils'
|
||||||
import i18n from './i18n'
|
import i18n from './i18n'
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ const ora: typeof import('ora') = require('ora')
|
||||||
const chalk: typeof import('chalk') = require('chalk')
|
const chalk: typeof import('chalk') = require('chalk')
|
||||||
|
|
||||||
const SCORE_URL_PREFIX = 'https://musescore.com/'
|
const SCORE_URL_PREFIX = 'https://musescore.com/'
|
||||||
|
const EXT = '.mscz'
|
||||||
|
|
||||||
interface Params {
|
interface Params {
|
||||||
url: string;
|
url: string;
|
||||||
|
@ -25,35 +26,42 @@ interface Params {
|
||||||
}
|
}
|
||||||
|
|
||||||
void (async () => {
|
void (async () => {
|
||||||
// ask for the page url
|
const fileInit: string | undefined = process.argv[2]
|
||||||
const { url } = await inquirer.prompt<Params>({
|
const isLocalFile = fileInit?.endsWith(EXT) && fs.existsSync(fileInit)
|
||||||
type: 'input',
|
|
||||||
name: 'url',
|
|
||||||
message: 'Score URL:',
|
|
||||||
suffix: ` (starts with "${SCORE_URL_PREFIX}")\n `,
|
|
||||||
validate (input: string) {
|
|
||||||
return input && input.startsWith(SCORE_URL_PREFIX)
|
|
||||||
},
|
|
||||||
default: process.argv[2],
|
|
||||||
})
|
|
||||||
|
|
||||||
// request scoreinfo
|
let scoreinfo: ScoreInfo
|
||||||
const scoreinfo = await ScoreInfoHtml.request(url)
|
if (!isLocalFile) {
|
||||||
const fileName = scoreinfo.fileName
|
// ask for the page url
|
||||||
|
const { url } = await inquirer.prompt<Params>({
|
||||||
|
type: 'input',
|
||||||
|
name: 'url',
|
||||||
|
message: 'Score URL:',
|
||||||
|
suffix: ` (starts with "${SCORE_URL_PREFIX}")\n `,
|
||||||
|
validate (input: string) {
|
||||||
|
return input && input.startsWith(SCORE_URL_PREFIX)
|
||||||
|
},
|
||||||
|
default: fileInit,
|
||||||
|
})
|
||||||
|
|
||||||
// confirmation
|
// request scoreinfo
|
||||||
const { confirmed } = await inquirer.prompt<Params>({
|
scoreinfo = await ScoreInfoHtml.request(url)
|
||||||
type: 'confirm',
|
|
||||||
name: 'confirmed',
|
// confirmation
|
||||||
message: 'Continue?',
|
const { confirmed } = await inquirer.prompt<Params>({
|
||||||
prefix: `${chalk.yellow('!')} ` +
|
type: 'confirm',
|
||||||
`ID: ${scoreinfo.id}\n ` +
|
name: 'confirmed',
|
||||||
`Title: ${scoreinfo.title}\n `,
|
message: 'Continue?',
|
||||||
default: true,
|
prefix: `${chalk.yellow('!')} ` +
|
||||||
})
|
`ID: ${scoreinfo.id}\n ` +
|
||||||
if (!confirmed) return
|
`Title: ${scoreinfo.title}\n `,
|
||||||
|
default: true,
|
||||||
|
})
|
||||||
|
if (!confirmed) return
|
||||||
|
console.log() // print a blank line to the terminal
|
||||||
|
} else {
|
||||||
|
scoreinfo = new ScoreInfoObj(0, path.basename(fileInit, EXT))
|
||||||
|
}
|
||||||
|
|
||||||
console.log()
|
|
||||||
const spinner = ora({
|
const spinner = ora({
|
||||||
text: i18n('PROCESSING')(),
|
text: i18n('PROCESSING')(),
|
||||||
color: 'blue',
|
color: 'blue',
|
||||||
|
@ -64,11 +72,19 @@ void (async () => {
|
||||||
let score: WebMscore
|
let score: WebMscore
|
||||||
let metadata: import('webmscore/schemas').ScoreMetadata
|
let metadata: import('webmscore/schemas').ScoreMetadata
|
||||||
try {
|
try {
|
||||||
// fetch mscz file from the dataset, and cache it for side effect
|
if (!isLocalFile) {
|
||||||
await fetchMscz(scoreinfo)
|
// fetch mscz file from the dataset, and cache it for side effect
|
||||||
|
await fetchMscz(scoreinfo)
|
||||||
|
} else {
|
||||||
|
// load local file
|
||||||
|
const data = await fs.promises.readFile(fileInit)
|
||||||
|
await setMscz(scoreinfo, data.buffer)
|
||||||
|
}
|
||||||
|
|
||||||
spinner.info('MSCZ file loaded')
|
spinner.info('MSCZ file loaded')
|
||||||
spinner.info(`File URL: ${scoreinfo.store.get(MSCZ_URL_SYM) as string}`)
|
if (!isLocalFile) {
|
||||||
|
spinner.info(`File URL: ${scoreinfo.store.get(MSCZ_URL_SYM) as string}`)
|
||||||
|
}
|
||||||
spinner.start()
|
spinner.start()
|
||||||
|
|
||||||
// load score using webmscore
|
// load score using webmscore
|
||||||
|
@ -123,6 +139,7 @@ void (async () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
// export files
|
// export files
|
||||||
|
const fileName = scoreinfo.fileName || await score.titleFilenameSafe()
|
||||||
spinner.start()
|
spinner.start()
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
filetypes.map(async (d) => {
|
filetypes.map(async (d) => {
|
||||||
|
|
|
@ -76,6 +76,11 @@ export const fetchMscz = async (scoreinfo: ScoreInfo, _fetch = getFetch()): Prom
|
||||||
return msczBufferP
|
return msczBufferP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/require-await
|
||||||
|
export const setMscz = async (scoreinfo: ScoreInfo, buffer: ArrayBuffer): Promise<void> => {
|
||||||
|
scoreinfo.store.set(MSCZ_BUF_SYM, Promise.resolve(buffer))
|
||||||
|
}
|
||||||
|
|
||||||
export const downloadMscz = async (scoreinfo: ScoreInfo, saveAs: typeof import('file-saver').saveAs): Promise<void> => {
|
export const downloadMscz = async (scoreinfo: ScoreInfo, saveAs: typeof import('file-saver').saveAs): Promise<void> => {
|
||||||
const data = new Blob([await fetchMscz(scoreinfo)])
|
const data = new Blob([await fetchMscz(scoreinfo)])
|
||||||
const filename = scoreinfo.fileName
|
const filename = scoreinfo.fileName
|
||||||
|
|
|
@ -27,7 +27,7 @@ export abstract class ScoreInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ScoreInfoObj extends ScoreInfo {
|
export class ScoreInfoObj extends ScoreInfo {
|
||||||
constructor (public id: number, public title: string) { super() }
|
constructor (public id: number = 0, public title: string = '') { super() }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ScoreInfoInPage extends ScoreInfo {
|
export class ScoreInfoInPage extends ScoreInfo {
|
||||||
|
|
Loading…
Reference in a new issue