From da393520c4a1b33bffdfe26974e817f2c65267d3 Mon Sep 17 00:00:00 2001 From: Ben Beltran Date: Sat, 18 Apr 2020 14:20:53 +0200 Subject: Update code for 2020 --- lib/Conjugator.js | 110 ++++++++++----------- lib/InsultGenerator.js | 257 ++++++++++++++++++------------------------------- 2 files changed, 144 insertions(+), 223 deletions(-) (limited to 'lib') diff --git a/lib/Conjugator.js b/lib/Conjugator.js index 78dd713..c4e74f7 100644 --- a/lib/Conjugator.js +++ b/lib/Conjugator.js @@ -1,66 +1,54 @@ 'use strict'; +const Cheerio = require('cheerio'); +const Fetch = require('node-fetch'); -var Promise = require('bluebird'); -var cheerio = require('cheerio'); -require('neon'); -var request = require('request'); - - -var Conjugator = Class({}, "Conjugator")({ - prototype : { - _baseUrl: "http://www.spanishdict.com/conjugate/", - _selector: "table .ex-tip", - - init : function init(config) { - config = config || {}; - - Object.keys(config).forEach(function (property) { - this[property] = config[property]; - }, this); - }, - - conjugate : function conjugate(verb) { - return new Promise(function (resolve, reject) { - request(this._baseUrl + verb, function (err, res, body) { - var $, result, finalVerb ; - if (err) { - return reject(err); - } - $ = cheerio.load(body); - result = $(this._selector)[10]; - - if (!result) { - console.log("Verb not found: ", verb); - return reject(new Error("Not a valid verb")); - } - - finalVerb = this._extractWord(result); - - console.log(verb, finalVerb); - resolve(finalVerb); - }.bind(this)); - }.bind(this)); - }, - - _extractWord : function _extractWord(node) { - var word = "", components; - - node.children.forEach(function (child) { - if (child.type === "text") { - word += child.data; - } else { - word += this._extractWord(child); - } - }, this); - - word = word.split(",")[0]; // multiple conjugations, take 1 - components = word.split(" "); // some special cases have two words - // use the last, why not - - return components[components.length - 1]; - } +const internals = { + kBaseUrl: 'http://www.spanishdict.com/conjugate/', + kSelector: 'table .ex-tip', + kThirdPersonPresentPosition: 10, + + extractWord(node) { + + let word = ''; + + node.children.forEach(function (child) { + + if (child.type === 'text') { + word += child.data; + } else { + word += internals.extractWord(child); + } + }); + + word = word.split(',')[0]; // multiple conjugations, take 1 + + const components = word.split(' '); // some special cases have two words + // use the last, why not + + return components[components.length - 1]; } -}); +}; -module.exports = Conjugator; +module.exports = { + async conjugate(verb) { + + console.debug(`Conjugating ${verb}`); + + const response = await Fetch(internals.kBaseUrl + verb); + const body = await response.text(); + + const $ = Cheerio.load(body); + const result = $(internals.kSelector)[internals.kThirdPersonPresentPosition]; + + if (!result) { + console.error('Verb not found: ', verb); + throw new Error('Not a valid verb'); + } + + const plainTextVerb = internals.extractWord(result); + console.debug(verb, plainTextVerb); + + return plainTextVerb; + } +}; 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(); + } +}; -- cgit