Skip to content

Commit

Permalink
feat: The user can disable or enable the translation engine and save …
Browse files Browse the repository at this point in the history
…the configuration to ~/.fanyirc under user's home directory
  • Loading branch information
todoi authored and afc163 committed Nov 26, 2020
1 parent e1cd54c commit d394282
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 59 deletions.
63 changes: 51 additions & 12 deletions bin/fanyi
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,44 @@ const program = require('commander');
const chalk = require('chalk');
const updateNotifier = require('update-notifier');
const pkg = require('../package.json');
const config = require('../lib/config');

updateNotifier({ pkg }).notify();

program
.option('-C, --nocolor', 'Output without color.')
// .option('-I, --iciba', 'Just output iciba.com\'s translate result.')
// .option('-Y, --youdao', 'Just output fanyi.youdao.com\'s translate result.')
// .option('-D, --dictionaryapi', 'Just output dictionaryapi.com\'s translate result.')
.version(pkg.version);
.version(pkg.version)
.option('-s, --say', 'Turn on the pronunciation')
.option('-S, --no-say', 'Turn off the pronunciation')
.action(args => {
const {say} = args;
const options = resolveOptions({ say });
return runFY(options);
})


program
.command('config')
.description('Set the global options')
.option('-c, --color', 'Output with color')
.option('-C, --no-color', 'Output without color')
.option('-i, --iciba', 'Enable the iciba translation engine')
.option('-I, --no-iciba', 'Disable the iciba translation engine')
.option('-y, --youdao', 'Enable the youdao translation engine')
.option('-Y, --no-youdao', 'Disable the youdao translation engine')
.option('-d, --dictionaryapi', 'Enable the dictionary translation engine')
.option('-D, --no-dictionaryapi', 'Disable the dictionary translation engine')
.option('-s, --say', 'Turn on the pronunciation')
.option('-S, --no-say', 'Turn off the pronunciation')
.action(args => {
// hack
// If the input is "fanyi config", then translate the word config.
if (process.argv.length === 3) {
return runFY();
}
const {color, iciba, youdao, dictionaryapi, say} = args
const options = resolveOptions({ color, iciba, youdao, dictionaryapi, say });
return config.write(options);
});

program.on('--help', function () {
console.log('');
Expand All @@ -29,12 +58,22 @@ if (!process.argv.slice(2).length) {
program.outputHelp();
}

const fanyi = require('..');
const nocolor = program.nocolor;
if (nocolor) {
chalk = new chalk.constructor({ enabled: false });
async function runFY(options = {}) {
const defaultOptions = await config.load();
const mergedOptions = {...defaultOptions, ...options}
const fanyi = require('..');
fanyi(program.args.join(' '), mergedOptions)
}

fanyi(program.args.join(' '), {
nocolor,
});
function resolveOptions(options) {
const opts = {}
Object.keys(options)
.filter(key => isBoolean(options[key]))
.map(key => opts[key] = options[key]);

return opts;
}

function isBoolean(val) {
return typeof val === 'boolean';
}
88 changes: 49 additions & 39 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ const ora = require('ora');

module.exports = function (word, options, callback) {
console.log('');
const { say, iciba, youdao, dictionaryapi } = options;
const requestCounts = [iciba, youdao, dictionaryapi].filter(isTrueOrUndefined).length;
const spinner = ora().start();

// say it
try {
if (!process.env.CI) {
if (!process.env.CI && isTrueOrUndefined(say)) {
require('say').speak(word, isChinese(word) ? 'Ting-Ting' : null);
}
} catch (e) {
Expand All @@ -22,7 +25,7 @@ module.exports = function (word, options, callback) {
let count = 0;
const callbackAll = () => {
count += 1;
if (count >= 3) {
if (count >= requestCounts) {
spinner.stop();
callback && callback();
}
Expand All @@ -31,47 +34,54 @@ module.exports = function (word, options, callback) {
word = encodeURIComponent(word);

// iciba
request.get(SOURCE.iciba.replace('${word}', word), function (error, response, body) {
if (!error && response.statusCode == 200) {
parseString(body, function (err, result) {
if (err) {
return;
}
print.iciba(result.dict, options);
});
}
callbackAll();
});
isTrueOrUndefined(iciba) &&
request.get(SOURCE.iciba.replace('${word}', word), function (error, response, body) {
if (!error && response.statusCode == 200) {
parseString(body, function (err, result) {
if (err) {
return;
}
print.iciba(result.dict, options);
});
}
callbackAll();
});

// youdao
request.get(SOURCE.youdao.replace('${word}', word), function (error, response, body) {
if (!error && response.statusCode == 200) {
try {
const data = JSON.parse(entities.decode(body));
print.youdao(data, options);
} catch (e) {
// 来自您key的翻译API请求异常频繁,为保护其他用户的正常访问,只能暂时禁止您目前key的访问
isTrueOrUndefined(youdao) &&
request.get(SOURCE.youdao.replace('${word}', word), function (error, response, body) {
if (!error && response.statusCode == 200) {
try {
const data = JSON.parse(entities.decode(body));
print.youdao(data, options);
} catch (e) {
// 来自您key的翻译API请求异常频繁,为保护其他用户的正常访问,只能暂时禁止您目前key的访问
}
}
}
callbackAll();
});
callbackAll();
});

// dictionaryapi
request.get(SOURCE.dictionaryapi.replace('${word}', word), { timeout: 6000 }, function (
error,
response,
body,
) {
if (error) {
return callbackAll();
}
if (response.statusCode == 200) {
parseString(body, function (err, result) {
if (!err) {
print.dictionaryapi(result.entry_list.entry, word, options);
isTrueOrUndefined(dictionaryapi) &&
request.get(
SOURCE.dictionaryapi.replace('${word}', word),
{ timeout: 6000 },
function (error, response, body) {
if (error) {
return callbackAll();
}
});
}
callbackAll();
});
if (response.statusCode == 200) {
parseString(body, function (err, result) {
if (!err) {
print.dictionaryapi(result.entry_list.entry, word, options);
}
});
}
callbackAll();
},
);
};

function isTrueOrUndefined(val) {
return val === true || val === undefined;
}
28 changes: 28 additions & 0 deletions lib/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const homedir = process.env.HOME || require('os').homedir();
const path = require('path');
const fs = require('fs');
const configPath = path.resolve(homedir, '.fanyirc');

const config = {
async load(path = configPath) {
const emptyObj = {};
if (fs.existsSync(path) && fs.statSync(path).isFile()) {
const content = fs.readFileSync(path, 'utf-8');
try {
return JSON.parse(content.toString());
} catch (e) {
return emptyObj;
}
} else {
return emptyObj;
}
},
async write(options = {}, path = configPath) {
const defaultOptions = await config.load(path);
const mergedOptions = { ...defaultOptions, ...options };
const content = JSON.stringify(mergedOptions);
return fs.writeFileSync(path, content);
},
};

module.exports = config;
24 changes: 16 additions & 8 deletions lib/print.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const chalk = require('chalk');
let chalk = require('chalk');

exports.iciba = function (data, options) {
if (options && options.nocolor) {
chalk = new chalk.constructor({ enabled: false });
exports.iciba = function (data, options = {}) {
if (options.color === false) {
chalk = initChalkWithNoColor();
}

let firstLine = '';
Expand Down Expand Up @@ -62,8 +62,8 @@ exports.iciba = function (data, options) {
};

exports.youdao = function (data, options) {
if (options && options.nocolor) {
chalk = new chalk.constructor({ enabled: false });
if (options.color === false) {
chalk = initChalkWithNoColor();
}

let firstLine = '';
Expand Down Expand Up @@ -101,8 +101,8 @@ exports.youdao = function (data, options) {
};

exports.dictionaryapi = function (data, word, options) {
if (options && options.nocolor) {
chalk = new chalk.constructor({ enabled: false });
if (options.color === false) {
chalk = initChalkWithNoColor();
}

if (word.indexOf('%') >= 0) {
Expand Down Expand Up @@ -171,3 +171,11 @@ function highlight(string, key, defaultColor) {
chalk[defaultColor]('$1') + chalk.yellow('$2'),
);
}

function initChalkWithNoColor() {
try {
return new chalk.constructor({ enabled: false });
} catch (e) {
return new chalk.Instance({ level: 0 });
}
}

0 comments on commit d394282

Please sign in to comment.