diff --git a/backend/config/constants.js b/backend/config/constants.js index f2d2ec5..16a5705 100644 --- a/backend/config/constants.js +++ b/backend/config/constants.js @@ -74,4 +74,11 @@ constants.answerType = { EXTERNAL_SOURCE_WP_NEWS: 2, }; +constants.contentType = { + TITLES: 0, + NEWS: 1, +}; + +constants.FIXED_SUMMARY_LENGTH = 3; + module.exports = constants; diff --git a/backend/helpers/externalSource.js b/backend/helpers/externalSource.js index edee01d..4713672 100644 --- a/backend/helpers/externalSource.js +++ b/backend/helpers/externalSource.js @@ -35,73 +35,85 @@ getDataFromWPJSON = function (sourceUrl, page = 1, maxPosts = 10) { }); }; -summarizeText = function (text, length, clearText=true){ - - if (clearText){ - text = htmlToText.fromString(post.content.rendered,{ - wordwrap:false, - ignoreHref:true, - ignoreImage:true +summarizeText = function (text, length, clearText = true) { + if (clearText) { + text = htmlToText.fromString (text, { + wordwrap: false, + ignoreHref: true, + ignoreImage: true, }); } - return summarizer(text,{n:length}); -} + return summarizer (text, {n: length}); +}; + +getTitlesFromWP = function (sourceUrl) { + return new Promise ((resolve, reject) => { + getDataFromWPJSON (sourceUrl) + .then (rawData => { + let result = ''; + rawData.forEach (post => { + result += + post.title.rendered + + ` `; + }); + resolve (result); + }) + .catch (err => { + reject (constants.voiceResponseStrings.ERROR_FETCHING_CONTENT); + }); + }); +}; + +getLatestNewsFromWP = function ( + sourceUrl, + postCount = 10, + includeTitle = false +) { + return new Promise ((resolve, reject) => { + getDataFromWPJSON (sourceUrl, 1, postCount) + .then (rawData => { + let result = ''; + let htmlToTextOptions = { + wordwrap: false, + ignoreHref: true, + ignoreImage: true, + }; + + try { + rawData.forEach (post => { + result += includeTitle ? post.title.rendered : ''; + result += includeTitle + ? `` + : ''; + result += summarizeText ( + post.content.rendered, + constants.FIXED_SUMMARY_LENGTH + ); + result += ``; + }); + + resolve (result); + } catch (err) { + reject (constants.voiceResponseStrings.ERROR_SUMMARIZING_CONTENT); + } + }) + .catch (err => { + reject (constants.voiceResponseStrings.ERROR_FETCHING_CONTENT); + }); + }); +}; module.exports = { - getAnswerFromWP: function (sourceUrl) { + getAnswerFromWP: function (sourceUrl, contentType) { //This function will extract needed data from JSON, which we got from getDataFromWPJSON - //At the moment, it's taking titles and creates answer - return new Promise ((resolve, reject) => { - getDataFromWPJSON (sourceUrl) - .then (rawData => { - let result = ''; - rawData.forEach (post => { - result += - post.title.rendered + - ` `; - }); - resolve (result); - }) - .catch (err => { - reject (constants.voiceResponseString.ERROR_FETCHING_CONTENT); - }); - }); - }, - - getLatestNewsFromWP: function ( - sourceUrl, - postCount = 10, - includeTitle = false - ) { - return new Promise ((resolve, reject) => { - getDataFromWPJSON (sourceUrl, 1, postCount) - .then (rawData => { - let result = ''; - let htmlToTextOptions = { - wordwrap: false, - ignoreHref: true, - ignoreImage: true, - } - - try { - rawData.forEach (post => { - result += includeTitle ? post.title.rendered : ''; - result += includeTitle - ? `` - : ''; - result += summarizeText(post.content.rendered,3); - result += ``; - }); - - resolve (result); - } catch (err) { - reject (constants.voiceResponseString.ERROR_SUMMARIZING_CONTENT); - } - }) - .catch (err => { - reject (constants.voiceResponseString.ERROR_FETCHING_CONTENT); - }); - }); + switch (contentType) { + case constants.contentType.TITLES: + return getTitlesFromWP (sourceUrl); + break; + case constants.contentType.NEWS: + return getLatestNewsFromWP (sourceUrl); + break; + } }, }; diff --git a/backend/models/alexa.js b/backend/models/alexa.js index c912984..e7a251d 100644 --- a/backend/models/alexa.js +++ b/backend/models/alexa.js @@ -74,47 +74,61 @@ module.exports = { let answerPromiseProps = { resolve: null, - reject: null - } + reject: null, + }; - let answer = new Promise((resolve,reject)=>{ + let answer = new Promise ((resolve, reject) => { answerPromiseProps = { - resolve:resolve, - reject:reject - } + resolve: resolve, + reject: reject, + }; }); - - switch (intent.answerType){ + + switch (intent.answerType) { case constants.answerType.PREDEFINED: - answerPromiseProps.resolve(intent.answer); + answerPromiseProps.resolve (intent.answer); break; case constants.answerType.EXTERNAL_SOURCE_WP_TITLES: - predefinedSourceHelper.getAnswerFromWP(intent.externalAnswerSource).then(answer=>{ - answerPromiseProps.resolve(answer); - }).catch(error=>{ - answerPromiseProps.reject(error); - }); + predefinedSourceHelper + .getAnswerFromWP ( + intent.externalAnswerSource, + constants.contentType.TITLES + ) + .then (answer => { + answerPromiseProps.resolve (answer); + }) + .catch (error => { + answerPromiseProps.reject (error); + }); break; case constants.answerType.EXTERNAL_SOURCE_WP_NEWS: - predefinedSourceHelper.getLatestNewsFromWP(intent.externalAnswerSource).then(answer=>{ - answerPromiseProps.resolve(answer); - }).catch(error=>{ - answerPromiseProps.reject(error); - }); + predefinedSourceHelper + .getAnswerFromWP ( + intent.externalAnswerSource, + constants.contentType.NEWS + ) + .then (answer => { + answerPromiseProps.resolve (answer); + }) + .catch (error => { + answerPromiseProps.reject (error); + }); break; } - answer.then(answer=>{ - this.response - .speak (answer) - .listen (constants.voiceResponseStrings.GENERIC_CONTINUE); //Phrase from listen doesn't work !!! - this.emit (':responseReady'); - }).catch(error=>{ - this.response - .speak (error) - .listen (constants.voiceResponseStrings.GENERIC_CONTINUE); //Phrase from listen doesn't work !!! - this.emit (':responseReady'); - }); + answer + .then (answer => { + this.response + .speak (answer) + .listen (constants.voiceResponseStrings.GENERIC_CONTINUE); //Phrase from listen doesn't work !!! + this.emit (':responseReady'); + }) + .catch (error => { + this.response + .speak (error) + .listen (constants.voiceResponseStrings.GENERIC_CONTINUE); //Phrase from listen doesn't work !!! + this.emit (':responseReady'); + }); }; }); diff --git a/backend/package-lock.json b/backend/package-lock.json index d29f472..5e90d35 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -34,6 +34,14 @@ "i18next-sprintf-postprocessor": "0.2.2" } }, + "apparatus": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/apparatus/-/apparatus-0.0.9.tgz", + "integrity": "sha1-N9zSWDStC2UQdllikduCPusZCL0=", + "requires": { + "sylvester": "0.0.21" + } + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -95,6 +103,12 @@ "tweetnacl": "0.14.5" } }, + "bindings": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", + "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==", + "optional": true + }, "body-parser": { "version": "1.18.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", @@ -163,6 +177,11 @@ "delayed-stream": "1.0.0" } }, + "complex.js": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.0.4.tgz", + "integrity": "sha512-Syl95HpxUTS0QjwNxencZsKukgh1zdS9uXeXX2Us0pHaqBR6kiZZi0AkZ9VpZFwHJyVIUVzI4EumjWdXP3fy6w==" + }, "content-disposition": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", @@ -222,6 +241,11 @@ "ms": "2.0.0" } }, + "decimal.js": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-9.0.1.tgz", + "integrity": "sha512-2h0iKbJwnImBk4TGk7CG1xadoA0g3LDPlQhQzbZ221zvG0p2YVUedbKIPsOZXKZGx6YmZMJKYOalpCMxSdDqTQ==" + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -322,6 +346,11 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, + "escape-latex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.0.0.tgz", + "integrity": "sha512-oogO9Cg3n/4nspF34CTfXFymgI79skca66DebIIQgxVy6qRVqczl/ji2YGAqhFCzpD/oAt/fCWF4qlhMAfda+g==" + }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -442,6 +471,11 @@ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" }, + "fraction.js": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.4.tgz", + "integrity": "sha512-aK/oGatyYLTtXRHjfEsytX5fieeR5H4s8sLorzcT12taFS+dbMZejnvm9gRa8mZAPwci24ucjq9epDyaq5u8Iw==" + }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -594,6 +628,11 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k=" + }, "jmespath": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", @@ -636,6 +675,21 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==" }, + "mathjs": { + "version": "3.20.2", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-3.20.2.tgz", + "integrity": "sha512-3f6/+uf1cUtIz1rYFz775wekl/UEDSQ3mU6xdxW7qzpvvhc2v28i3UtLsGTRB+u8OqDWoSX6Dz8gehaGFs6tCA==", + "requires": { + "complex.js": "2.0.4", + "decimal.js": "9.0.1", + "escape-latex": "1.0.0", + "fraction.js": "4.0.4", + "javascript-natural-sort": "0.7.1", + "seed-random": "2.2.0", + "tiny-emitter": "2.0.2", + "typed-function": "0.10.7" + } + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -698,6 +752,38 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "nalapa": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/nalapa/-/nalapa-1.11.0.tgz", + "integrity": "sha1-YJZywk1fNZ73PQpmLyf11Kp8tj8=", + "requires": { + "lodash": "4.6.1" + }, + "dependencies": { + "lodash": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.6.1.tgz", + "integrity": "sha1-3wDBFkrSNrGDz8OIel6NOMxjy7w=" + } + } + }, + "nan": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "optional": true + }, + "natural": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/natural/-/natural-0.5.6.tgz", + "integrity": "sha1-8hUrYfNr78b+Dta8gR+0mebp3M0=", + "requires": { + "apparatus": "0.0.9", + "sylvester": "0.0.21", + "underscore": "1.8.3", + "webworker-threads": "0.7.13" + } + }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", @@ -712,6 +798,16 @@ "is-stream": "1.1.0" } }, + "nodejs-text-summarizer": { + "version": "github:GotPPay/nodejs-text-summarizer#9be60ffe387560b97f05c178be7db220012a52c1", + "requires": { + "lodash": "4.17.5", + "mathjs": "3.20.2", + "nalapa": "1.11.0", + "natural": "0.5.6", + "underscore.string": "3.3.4" + } + }, "nodemailer": { "version": "4.6.3", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-4.6.3.tgz", @@ -875,6 +971,11 @@ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" }, + "seed-random": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/seed-random/-/seed-random-2.2.0.tgz", + "integrity": "sha1-KpsZ4lCoFwmSMaW5mk2vgLf77VQ=" + }, "semver": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", @@ -931,6 +1032,11 @@ "hoek": "4.2.0" } }, + "sprintf-js": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.1.tgz", + "integrity": "sha1-Nr54Mgr+WAH2zqPueLblqrlA6gw=" + }, "sshpk": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", @@ -964,6 +1070,16 @@ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" }, + "sylvester": { + "version": "0.0.21", + "resolved": "https://registry.npmjs.org/sylvester/-/sylvester-0.0.21.tgz", + "integrity": "sha1-KYexzivS84sNzio0OIiEv6RADqc=" + }, + "tiny-emitter": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.0.2.tgz", + "integrity": "sha512-2NM0auVBGft5tee/OxP4PI3d8WItkDM+fPnaRAVo6xTDI2knbz9eC5ArWGqtGlYqiH3RU5yMpdyTTO7MguC4ow==" + }, "tough-cookie": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", @@ -995,6 +1111,25 @@ "mime-types": "2.1.17" } }, + "typed-function": { + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-0.10.7.tgz", + "integrity": "sha512-3mlZ5AwRMbLvUKkc8a1TI4RUJUS2H27pmD5q0lHRObgsoWzhDAX01yg82kwSP1FUw922/4Y9ZliIEh0qJZcz+g==" + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + }, + "underscore.string": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.4.tgz", + "integrity": "sha1-LCo/n4PmR2L9xF5s6sZRQoZCE9s=", + "requires": { + "sprintf-js": "1.1.1", + "util-deprecate": "1.0.2" + } + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -1046,6 +1181,16 @@ "extsprintf": "1.3.0" } }, + "webworker-threads": { + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/webworker-threads/-/webworker-threads-0.7.13.tgz", + "integrity": "sha1-yEsYtrokElu503NC5E3rgVFi+4M=", + "optional": true, + "requires": { + "bindings": "1.3.0", + "nan": "2.10.0" + } + }, "whatwg-fetch": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz",