]> git.r.bdr.sh - rbdr/generador-de-insultos/blobdiff - lib/InsultGenerator.js
Update code for 2020
[rbdr/generador-de-insultos] / lib / InsultGenerator.js
index 5c40651a7493921e5dd5c118102d39b8d8ae4903..af9408b8a2c1e6b791ba258ca2880bdc4b59ec92 100644 (file)
 '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();
+  }
+};