X-Git-Url: https://git.r.bdr.sh/rbdr/generador-de-insultos/blobdiff_plain/e865f21be5685ef2fbc57e36460f8d6819e0fe34..da393520c4a1b33bffdfe26974e817f2c65267d3:/lib/InsultGenerator.js diff --git a/lib/InsultGenerator.js b/lib/InsultGenerator.js index 5c40651..af9408b 100644 --- a/lib/InsultGenerator.js +++ b/lib/InsultGenerator.js @@ -1,180 +1,113 @@ 'use strict'; +const Fs = require('fs'); +const Path = require('path'); -var fs = require('fs'); - -var Promise = require('bluebird'); -require('neon'); - -var Conjugator = require('./Conjugator'); - -var InsultGenerator = Class({}, "InsultGenerator")({ - prototype : { - file : null, - verbs: null, - nouns: null, - - _maxTries: 10, - _loaded: false, - _verbRe: /^[0-9]+\-v\s+?lemma\s+?([^ ]+)/, - _nounRe: /^[0-9]+\-n\s+?lemma\s+?([^ ]+)/, - _conjugator: null, - - init : function init(config) { - config = config || {}; - - Object.keys(config).forEach(function (property) { - this[property] = config[property]; - }, this); - - this._conjugator = new Conjugator(); - }, - - generate : function generate(config) { - var selectedVerb; - return this._load() - .then(function () { - return this._getVerb(); - }.bind(this)).then(function (verb) { - return this._conjugateVerb(verb); - }.bind(this)).then(function (conjugatedVerb) { - selectedVerb = conjugatedVerb; - return this._getNoun(); - }.bind(this)).then(function (noun) { - return this._generateInsult(selectedVerb, noun); - }.bind(this)); - }, - - _load : function _load() { - return this._loadFile() - .then(function () { - return this._loadVerbs(); - }.bind(this)).then(function () { - return this._loadNouns(); - }.bind(this)); - }, - - _loadFile : function _loadFile() { - return new Promise(function (resolve, reject) { - if (this._loaded) { - return resolve(); - } +const Conjugator = require('./Conjugator'); - fs.readFile(this.file, {encoding: 'utf8'}, function (err, contents) { - if (err) { - return reject(err); - } +const internals = { + kMaxAttempts: 10, + kVowels: ['a', 'e', 'i', 'o', 'u'], + kWordFile: Path.resolve(__dirname, '../ext/words.tab'), + kWordRe: /^[0-9]+\-(n|v)\s+?lemma\s+?([^ ]+)/, - this._contents = contents; - this._loaded = true; - resolve(); - }.bind(this)); - }.bind(this)); - }, - - _loadVerbs : function _loadVerbs() { - return new Promise(function (resolve, reject) { - if (this.verbs) { - return resolve(); - } + wordList: null, - this.verbs = []; - this._contents.split('\n').forEach(function (line) { - var matches; - matches = line.match(this._verbRe); + // Gets the list of words, key can be either nouns or verbs - if (matches) { - if (this.verbs.indexOf(matches[1]) === -1) { - this.verbs.push(matches[1]) - } - } - }, this); + async getWordList(key) { + + internals.wordList = internals.wordList || await internals.readWordFile(); + return internals.wordList[key]; + }, + + // Read the list of words and returns it + + readWordFile() { - resolve(); - }.bind(this)); - }, + return new Promise(function (resolve, reject) { - _loadNouns : function _loadNouns() { - return new Promise(function (resolve, reject) { - if (this.nouns) { - return resolve(); + console.debug('Reading word file'); + Fs.readFile(internals.kWordFile, {encoding: 'utf8'}, function (err, contents) { + + if (err) { + return reject(err); } - this.nouns = []; - this._contents.split('\n').forEach(function (line) { - var matches; - matches = line.match(this._nounRe); + const verbs = new Set(); + const nouns = new Set(); + const words = contents.split('\n'); + + console.debug(`Found ${words.length} words, categorizing`); + + words.forEach(function (line) { + + const matches = line.match(internals.kWordRe); if (matches) { - if (this.nouns.indexOf(matches[1]) === -1) { - this.nouns.push(matches[1]) + if (matches[1] === 'v') { + return verbs.add(matches[2]); } + + nouns.add(matches[2]); } - }, this); - - resolve(); - }.bind(this)); - }, - - _getVerb : function _getVerb() { - var index; - index = Math.floor(Math.random()*this.verbs.length); - return Promise.resolve(this.verbs[index]); - }, - - _conjugateVerb : function _conjugateVerb(verb) { - return new Promise(function (resolve, reject) { - var tries; - - tries = 0; - - var attemptConjugation = function attemptConjugation(verb, tries) { - if (tries > this._maxTries) { - return reject(new Error("Couldn't find a proper verb")); - }; - - this._conjugator.conjugate(verb) - .then(function (conjugatedVerb) { - resolve(conjugatedVerb); - }) - .catch(function (err) { - this._getVerb().then(function (verb) { - attemptConjugation.bind(this)(verb, tries + 1); - }.bind(this)) - }.bind(this)); - }; - - setTimeout(attemptConjugation.bind(this, verb, 0), 0); - }.bind(this)); - }, - - _getNoun : function _getNoun() { - var index, noun; - index = Math.floor(Math.random()*this.nouns.length); - return Promise.resolve(this.nouns[index].toLowerCase()); - }, - - _generateInsult : function _generateInsult(verb, noun) { - return Promise.resolve(verb + this._pluralize(noun)); - }, - - // Super dumb pluralizer - _pluralize : function _pluralize(noun) { - var lastLetter; - - lastLetter = noun[noun.length - 1]; - - if (lastLetter === "s") { - return noun; - } - - if (["a","e","i","o","u"].indexOf(lastLetter) >= 0) { - return noun + "s" - } - - return noun + "es"; + }); + + console.debug(`Nouns: ${nouns.size}, Verbs: ${verbs.size}`); + + resolve({ + verbs: [...verbs], + nouns: [...nouns] + }); + }); + }); + }, + + // Gets a conjugated verb + + async getVerb() { + + const verbs = await internals.getWordList('verbs'); + const verb = verbs[Math.floor(Math.random()*verbs.length)]; + return await Conjugator.conjugate(verb); + }, + + // Gets a pluralized noun + + async getNoun() { + + const nouns = await internals.getWordList('nouns'); + const noun = nouns[Math.floor(Math.random()*nouns.length)]; + return internals.pluralize(noun); + }, + + // Pluralizes a word + + pluralize(noun) { + + const lastLetter = noun[noun.length - 1]; + + if (lastLetter === 's') { + return noun; } + + if (internals.kVowels.indexOf(lastLetter) >= 0) { + return noun + 's' + } + + return noun + 'es'; } -}); +}; + +module.exports = { -module.exports = InsultGenerator; + // Generates an insult. + + async generate() { + + const verb = await internals.getVerb(); + const noun = await internals.getNoun(); + + return (verb + noun).toLowerCase(); + } +};