// $ npm init // $ npm i read-chunk image-type tmp // $ node outguess const { spawn } = require('child_process'); const readChunk = require('read-chunk'); const imageType = require('image-type'); const tmp = require('tmp'); const fs = require('fs'); const VERBOSE = true; const OUTGUESS_APP = '/Applications/Outguess.app/Contents/outguess'; const WORK_DIR = '/Users/claus/Downloads/'; const SOURCE = WORK_DIR + 'Syphon-Signal-Registered-VIVIVICIVICIIVIII.jpg'; const keys = [ 'cyma', 'berlin', 'geneva, switzerland', 'Le Locle, Neuchatel, Switzerland', 'Jura, Mountains', 'La Chaux de Fonds', 'Watch Valley', 'gorham, retro, railroad, museum', 'Cascade, Alpine, Brook', 'Moose, Brook', 'Presidential rail trail', 'Mt washington valley', 'Mount washington, gorham', 'Mount washington, new hampshire', 'zurich, switzerland', 'gorham, new hampshire', ]; keys.map(key => permutations(key)) .flat() .filter((item, i, arr) => arr.indexOf(item) == i) .reduce( (acc, key) => acc.then(() => { return outguess(key); }), Promise.resolve() ); function outguess(key) { const promise = new Promise((resolve, reject) => { const out = tmp.fileSync(); const child = spawn(OUTGUESS_APP, ['-k', key, '-r', SOURCE, out.name]); child.on('close', code => { const buffer = readChunk.sync(out.name, 0, 12); const type = imageType(buffer); if (type != null && typeof type === 'object') { const file = `${WORK_DIR}${key}.${type.ext}`; fs.renameSync(out.name, file); resolve({ ...type, file, key, }); return; } reject({ key, code }); }); }); return promise .then(result => { console.log(`### ${result.key}: ${result.file}`); return result; }) .catch(e => { VERBOSE && console.log(` ${e.key}: FAIL`); return e; }); } function permutations(input) { const rawKeys = input .split(',') .map(rawKey => rawKey.replace(/\s+/g, '').toLowerCase()); const keys = permutator(rawKeys).map(key => key.join('')); return keys; } function permutator(inputArr) { const result = []; const permute = (arr, m = []) => { if (arr.length === 0) { result.push(m); } else { for (let i = 0; i < arr.length; i++) { let curr = arr.slice(); let next = curr.splice(i, 1); permute(curr.slice(), m.concat(next)); } } }; for (let i = inputArr.length; i > 0; i--) { for (let j = 0; j <= inputArr.length - i; j++) { const arr = inputArr.slice(j, j + i); permute(arr); } } return result; }