diff --git a/package.json b/package.json index 19173a6..bed3a6c 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "cross-spawn": "^5.0.1", "fs-extra": "^2.0.0", "glob": "^7.0.5", + "google-translate-api": "^2.2.2", "gulp-refresh": "^1.1.0", "imagemin": "^5.2.1", "imagemin-mozjpeg": "^6.0.0", diff --git a/src/commands/new.js b/src/commands/new.js index 00721e3..01e36cc 100644 --- a/src/commands/new.js +++ b/src/commands/new.js @@ -42,7 +42,7 @@ const setupAssets = async function setupAssets () { }; const setupOthers = async function setupOthers () { await utils.mkdir(Project('controllers')); - await utils.mkdir(Project('locals')); + await utils.mkdir(Project('locales')); await utils.mkdir(Project('seeds')); await utils.mkdir(Project('models')); await utils.mkdir(Project('public')); diff --git a/src/commands/translate.js b/src/commands/translate.js new file mode 100644 index 0000000..0d4c0d0 --- /dev/null +++ b/src/commands/translate.js @@ -0,0 +1,58 @@ +import 'colors'; +import Command from 'cmd-line/lib/Command'; +import * as fs from 'fs-extra'; +import lang from '../support/languages'; + +export default (new Command(__filename, 'Translate your localization files')) + .Args('?to', '?from') + .Options( + ['-l', '--list', 'Show a list of languages'], + ['-g', '--generate', 'indicate to genereate the translation file.'] +) + .Action(async function (to, from, options) { + from = from || configuration.server.localization.locales[0]; + if (options.list) { + for (const key of Object.keys(lang)) { + console.log(key + ' ' + lang[key]); + } + return 0; + } + if (!from) { + console.log('No source locale, please check your configuration'); + return 1; + } + if (!lang[to]) { + console.log('No target locale, please check your configuration'); + return 1; + } + if (from === to) { + console.log('cannot translate to the same language'); + return 0; + } + const GET = require('../functions/get').default; + async function translate (text, from, to) { + let r; + r = JSON.parse(await GET(`http://api.mymemory.translated.net/get?q=${encodeURI(text)}&langpair=${from}|${to}`, null, null)); + if (r.responseData.translatedText.indexOf('YOU USED ALL AVAILABLE FREE TRANSLATIONS') > -1) { + r = await GET(`http://translate.google.com/translate_a/single?client=ctx&sl=${from}&tl=${to}&hl=es&dt=t&q=${encodeURI(text)}`); + return r[0][0][0]; + } else if (r.responseStatus === 200) { + return r.responseData.translatedText.replace(new RegExp(`\b${from}$`, 'g'), to); + } else if (r.responseStatus === 403) { + return null; + } else { + console.log(lang[to], r.responseData); + return text; + } + } + let translation = fs.readJSONSync(ProyPath(configuration.server.localization.directory, `${from}.js`)); + let newLang = {}; + for (const key of Object.keys(translation)) { + try { + newLang[key] = await translate(translation[key], from, to); + } catch (ex) { + console.log(ex); + } + } + fs.writeFileSync(ProyPath(configuration.server.localization.directory, `${to}.js`), JSON.stringify(newLang, 4, 4)); + }); diff --git a/src/deamon.js b/src/deamon.js index 8e09e5f..03fb4fa 100644 --- a/src/deamon.js +++ b/src/deamon.js @@ -64,6 +64,7 @@ export default function StartKoatonServer (resolve, reject, EmberPids, nginx = f 'commands', 'koaton_modules', 'views', + 'downloads', 'config/bundles.js', '*.tmp', '*.json', diff --git a/src/functions/get.js b/src/functions/get.js new file mode 100644 index 0000000..4695feb --- /dev/null +++ b/src/functions/get.js @@ -0,0 +1,31 @@ +const http = require('http'); +function GET (hostname) { + return new Promise(function (resolve, reject) { + let [protocol, host] = hostname.split('//'); + let url = host.split('/'); + host = url[0]; + url = url.splice(1, host.length).join('/'); + let request = http.request({ + protocol: protocol, + hostname: host, + port: 80, + path: `/${url}`, + agent: false // create a new agent just for this one request + }); + request.on('response', (response) => { + let result = ''; + response.on('data', (chunk) => { + result += chunk.toString(); + }); + response.on('error', (err) => { + reject(err); + }); + response.on('end', () => { + resolve(result); + }); + }); + request.end(); + }); +} + +export default GET; diff --git a/src/support/Languages.js b/src/support/Languages.js new file mode 100644 index 0000000..7501d0a --- /dev/null +++ b/src/support/Languages.js @@ -0,0 +1,106 @@ +export default { + 'af': 'Afrikaans', + 'sq': 'Albanian', + 'am': 'Amharic', + 'ar': 'Arabic', + 'hy': 'Armenian', + 'az': 'Azerbaijani', + 'eu': 'Basque', + 'be': 'Belarusian', + 'bn': 'Bengali', + 'bo': 'Tibetan', + 'bs': 'Bosnian', + 'br': 'Breton', + 'bg': 'Bulgarian', + 'my': 'Burmese', + 'ca': 'Catalan; Valencian', + 'cs': 'Czech', + 'ch': 'Chamorro', + 'zh': 'Chinese', + 'cy': 'Welsh', + 'da': 'Danish', + 'de': 'German', + 'nl': 'Dutch; Flemish', + 'dz': 'Dzongkha', + 'el': 'Greek, Modern (1453-)', + 'en': 'English', + 'eo': 'Esperanto', + 'et': 'Estonian', + 'fo': 'Faroese', + 'fa': 'Persian', + 'fi': 'Finnish', + 'fr': 'French', + 'ka': 'Georgian', + 'ga': 'Irish', + 'gl': 'Galician', + 'gu': 'Gujarati', + 'ht': 'Haitian; Haitian Creole', + 'he': 'Hebrew', + 'hi': 'Hindi', + 'hr': 'Croatian', + 'hu': 'Hungarian', + 'is': 'Icelandic', + 'id': 'Indonesian', + 'it': 'Italian', + 'ja': 'Japanese', + 'kl': 'Kalaallisut; Greenlandic', + 'kn': 'Kannada', + 'kk': 'Kazakh', + 'km': 'Central Khmer', + 'rw': 'Kinyarwanda', + 'ko': 'Korean', + 'ku': 'Kurdish', + 'lo': 'Lao', + 'la': 'Latin', + 'lv': 'Latvian', + 'lt': 'Lithuanian', + 'lb': 'Luxembourgish; Letzeburgesch', + 'mk': 'Macedonian', + 'ml': 'Malayalam', + 'mi': 'Maori', + 'mr': 'Marathi', + 'mg': 'Malagasy', + 'mn': 'Mongolian', + 'ne': 'Nepali', + 'nn': 'Norwegian Nynorsk; Nynorsk, Norwegian', + 'nb': 'Bokmål, Norwegian; Norwegian Bokmål', + 'no': 'Norwegian', + 'ny': 'Chichewa; Chewa; Nyanja', + 'pa': 'Panjabi; Punjabi', + 'pl': 'Polish', + 'pt': 'Portuguese', + 'ps': 'Pushto; Pashto', + 'qu': 'Quechua', + 'rm': 'Romansh', + 'ro': 'Romanian; Moldavian; Moldovan', + 'rn': 'Rundi', + 'ru': 'Russian', + 'si': 'Sinhala; Sinhalese', + 'sk': 'Slovak', + 'sl': 'Slovenian', + 'sm': 'Samoan', + 'sn': 'Shona', + 'so': 'Somali', + 'st': 'Sotho, Southern', + 'es': 'Spanish; Castilian', + 'sr': 'Serbian', + 'sw': 'Swahili', + 'sv': 'Swedish', + 'ta': 'Tamil', + 'te': 'Telugu', + 'tl': 'Tagalog', + 'th': 'Thai', + 'ti': 'Tigrinya', + 'to': 'Tonga (Tonga Islands)', + 'tk': 'Turkmen', + 'tr': 'Turkish', + 'uk': 'Ukrainian', + 'ur': 'Urdu', + 'uz': 'Uzbek', + 'vi': 'Vietnamese', + 'wo': 'Wolof', + 'xh': 'Xhosa', + 'yi': 'Yiddish', + 'yo': 'Yoruba', + 'zu': 'Zulu' +}; diff --git a/templates/gitignore b/templates/gitignore index d1beeeb..c538d42 100644 --- a/templates/gitignore +++ b/templates/gitignore @@ -1,4 +1,5 @@ node_modules/ +koaton_modules/ bower_components/ /ember/ .DS_Store diff --git a/templates/package.json b/templates/package.json index 5733fb6..f3daff2 100644 --- a/templates/package.json +++ b/templates/package.json @@ -4,6 +4,7 @@ "description": "", "main": "app.js", "scripts": { + "commit": "git add -A & git-cz", "convert": "koaton-exporter **/*.es6 ./ -e js", "assets":"node ./node_modules/koaton/scripts/build.js", "prestart": "npm run assets", @@ -19,6 +20,11 @@ "dependencies": { "koaton":"^1.3.0" }, + "config": { + "commitizen": { + "path": "cz-conventional-changelog" + } + }, "devDependencies": { "commitizen": "^2.8.6", "cz-conventional-changelog": "^1.2.0", diff --git a/test/configuration/translate.js b/test/configuration/translate.js new file mode 100644 index 0000000..0c17d10 --- /dev/null +++ b/test/configuration/translate.js @@ -0,0 +1,37 @@ +import * as fs from 'fs-extra'; +import TestNode from '../support/TestNode'; +import ServerConfiguaration from '../../src/support/Server'; +import '../support/array'; +import langs from '../../src/support/languages'; + +let tests = []; +let cmdname = 'koaton translate'; + +tests.push(new TestNode(cmdname, [undefined, undefined, { + list: true +}], true, true)) + .SetUp(() => { + process.chdir('testingapp'); + process.env.isproyect = 'true'; + require(ProyPath('node_modules', 'koaton/lib/support', 'globals')); + global.scfg = new ServerConfiguaration(); + scfg.port = 62626; + global.skipshell = true; + fs.writeFileSync(ProyPath('locales', 'en.js'), JSON.stringify({t001: 'Hello'}, 4, 4)); + }); +for (const lang of Object.keys(langs)) { + tests.push(new TestNode(cmdname, [lang, undefined, {}], true, true)) + .Expect(`translates to ${langs[lang]}`, true, (log) => { + if (lang === 'en') { + return log.indexOf('cannot translate to the same language') > -1; + } else { + let translation = fs.readJSONSync(ProyPath('locales', `${lang}.js`)); + return translation.t001 && translation.t001 !== 'Hello'; + } + }); +} + +tests.last.CleanUp(() => { + process.chdir('..'); +}); +export { cmdname as testname, tests as config }; diff --git a/test/integration.js b/test/integration.js index 29194ad..175c417 100644 --- a/test/integration.js +++ b/test/integration.js @@ -6,8 +6,9 @@ import configuration from './configuration'; const commands = importindex(ProyPath('/src/commands')).default; const CommandOrder = [].concat([ // 'new', 'adapter', 'ember', - 'model', - 'relation' + // 'model', + // 'relation' + 'translate', // 'nginx', // 'install', 'build', 'seed', 'modulify' // 'serve' diff --git a/test/mocha.opts b/test/mocha.opts index 426af39..e739dfd 100644 --- a/test/mocha.opts +++ b/test/mocha.opts @@ -1,3 +1,3 @@ --require src/globals.js ---bail + --slow 0