-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8 from ilicmarko/v2
V2
- Loading branch information
Showing
7 changed files
with
719 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
const fs = require('fs-extra'); | ||
const chalk = require('chalk'); | ||
const path = require('path'); | ||
const utils = require('../utils'); | ||
const inquirer = require('inquirer'); | ||
|
||
exports.command = 'images <input>'; | ||
exports.aliases = ['i']; | ||
exports.desc = 'Generate sequence of images.'; | ||
exports.builder = { | ||
output: { | ||
type: 'string', | ||
aliases: ['o'], | ||
describe: 'Path to JSON file generated by Chrome.', | ||
demand: true, | ||
normalize: true, | ||
} | ||
}; | ||
exports.handler = async (argv) => { | ||
const { input, output } = argv; | ||
|
||
if (!fs.existsSync(input)) { | ||
console.error(chalk.red(`Provided file '${input}' doesn't exist`)); | ||
process.exit(1); | ||
} | ||
|
||
if (!fs.existsSync(output)) { | ||
try { | ||
fs.mkdirSync(output); | ||
console.log(chalk.blue(`Directory ${output} created!`)); | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
throw new Error(`EACCES: permission denied, mkdir '${output}'`); | ||
} | ||
|
||
throw err; | ||
} | ||
} else { | ||
const { overwrite } = await inquirer | ||
.prompt([{ | ||
name: 'overwrite', | ||
type: 'confirm', | ||
message: `Directory \`${output}\` already exists. Do you want to overwrite it?` | ||
}]); | ||
|
||
if (overwrite) fs.emptyDirSync(output); | ||
} | ||
|
||
const fileData = fs.readFileSync(input, 'utf8'); | ||
let jsonData; | ||
|
||
try { | ||
jsonData = JSON.parse(fileData); | ||
} catch (e) { | ||
console.error(chalk.red(e)); | ||
process.exit(1) | ||
} | ||
|
||
if (!Array.isArray(jsonData)) { | ||
console.log('This doesn\'t look like Chrome Timeline JSON. Please provide valid data.'); | ||
process.exit(1); | ||
} | ||
|
||
const snapshots = jsonData.filter(item => item.name === 'Screenshot').map(item => item.args.snapshot); | ||
|
||
if (!snapshots.length) { | ||
console.error(chalk.red('There are no captured frames inside the provided input.')); | ||
process.exit(1); | ||
} | ||
|
||
let imageStream; | ||
let ext; | ||
|
||
snapshots.forEach((snapshot, i) => { | ||
imageStream = Buffer.from(snapshot, 'base64'); | ||
ext = utils.getFileTypeFromStream(imageStream); | ||
if (ext) { | ||
fs.writeFileSync(path.resolve(output, `${i}.${ext}`), imageStream); | ||
} else { | ||
console.log(chalk.yellow(`Frame ${i} couldn't be saved.`)) | ||
} | ||
}); | ||
|
||
console.log(chalk.green.bold(`${snapshots.length} frames exported to ${output}`)); | ||
process.exit(); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#!/usr/bin/env node | ||
const path = require('path'); | ||
const yargs = require('yargs'); | ||
|
||
// noinspection BadExpressionStatementJS | ||
yargs | ||
.scriptName('dte') | ||
.usage('$0 <cmd> [args]') | ||
.commandDir(path.join(__dirname, 'commands')) | ||
.demandCommand() | ||
.option('output', { | ||
alias: 'o', | ||
describe: 'Output folder where the images will be exported.' | ||
}) | ||
.demandOption(['output'], 'Please provide output argument.') | ||
.help('h') | ||
.alias('h', 'help') | ||
.argv; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/** | ||
* Check Buffer for file signature. | ||
* @param {Array} header | ||
* @param {ArrayBuffer} stream | ||
* @param {Object} [settings] | ||
* @returns {boolean} | ||
*/ | ||
function checkHeader(header, stream, settings) { | ||
// Basic early checks if the stream is a Buffer | ||
if (!(stream instanceof Uint8Array || stream instanceof ArrayBuffer || Buffer.isBuffer(stream))) throw new Error('Buffer not valid'); | ||
const buffer = stream instanceof Uint8Array ? stream : new Uint8Array(input); | ||
if (!(buffer && buffer.length > 1)) throw new Error('Buffer not valid'); | ||
|
||
const defaultSettings = { offset: 0 }; | ||
const mergedSettings = { ...defaultSettings, ...settings }; | ||
|
||
for (let i = 0; i < header.length; i++) { | ||
if (header[i] !== buffer[i + mergedSettings.offset]) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
function getFileTypeFromStream(stream) { | ||
if (checkHeader([0xFF, 0xD8, 0xFF], stream)) return 'jpg'; | ||
if (checkHeader([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A], stream)) return 'png'; | ||
if (checkHeader([0x57, 0x45, 0x42, 0x50], stream, {offset: 8})) return 'webp'; | ||
return false; | ||
} | ||
|
||
module.exports = { | ||
getFileTypeFromStream, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.