├── logo.png ├── util ├── textapi.js ├── tag.js ├── nicknamer.js ├── synonyms.js └── trump.js ├── index.js ├── .gitignore ├── package.json ├── LICENSE └── README.md /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nerdsupremacist/trumpify/HEAD/logo.png -------------------------------------------------------------------------------- /util/textapi.js: -------------------------------------------------------------------------------- 1 | var AYLIENTextAPI = require('aylien_textapi'); 2 | 3 | // I know I should put this somewhere secure. 4 | // MEH... I just don't care ;) 5 | 6 | var textapi = new AYLIENTextAPI({ 7 | application_id: "c751188f", 8 | application_key: "75e92817bce96eb1e0cb1474771036d6" 9 | }); 10 | 11 | module.exports = textapi; 12 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var tagger = require('./util/tag.js'); 2 | var nicknamer = require('./util/nicknamer.js'); 3 | var words = require('./util/synonyms.js'); 4 | 5 | function process(text, callback) { 6 | tagger(text, function(text, sentiment) { 7 | nicknamer(text, sentiment, function(text, keywords) { 8 | words(text, keywords, callback); 9 | }); 10 | }); 11 | } 12 | module.exports = process; 13 | -------------------------------------------------------------------------------- /util/tag.js: -------------------------------------------------------------------------------- 1 | var api = require('./textapi.js'); 2 | 3 | var dict = require('./trump.js'); 4 | 5 | function tagger(text, callback) { 6 | api.sentiment({ "text": text }, function(error, response) { 7 | if (error === null) { 8 | var feeling = response.polarity; 9 | var words = dict[feeling]; 10 | var next = words[Math.floor((Math.random() * words.length))]; 11 | if (next && Math.random() > 0.2) { 12 | text = text + " " + next.toUpperCase() + "!"; 13 | } 14 | callback(text, response.polarity); 15 | } 16 | }); 17 | } 18 | 19 | module.exports = tagger; 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "trumpify-node", 3 | "version": "0.1.1", 4 | "description": "Make your words be the best Words - Instant text trumpifier", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/mathiasquintero/trumpify.git" 12 | }, 13 | "keywords": [ 14 | "trump", 15 | "text", 16 | "process", 17 | "replacement" 18 | ], 19 | "author": "mathiasquintero", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/mathiasquintero/trumpify/issues" 23 | }, 24 | "homepage": "https://github.com/mathiasquintero/trumpify#readme", 25 | "dependencies": { 26 | "aylien_textapi": "^0.6.0", 27 | "request": "^2.79.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Mathias Quintero 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /util/nicknamer.js: -------------------------------------------------------------------------------- 1 | var api = require('./textapi.js'); 2 | 3 | var replace = ["organization", "person", "location"]; 4 | 5 | var dict = require('./trump.js'); 6 | 7 | function nicknamer(text, feeling, callback) { 8 | api.entities({ 9 | text: text 10 | }, function(error, response) { 11 | if (error === null) { 12 | var items = replace.reduce(function(r, i) { 13 | return r.concat(response.entities[i] || []); 14 | }, []); 15 | var offset = -0.4; 16 | for (var i = 0; i < items.length; i++) { 17 | if (Math.random() >= 0.5 + offset) { 18 | offset += 0.3; 19 | var words = dict[feeling]; 20 | var next = words[Math.floor((Math.random() * words.length))]; 21 | if (next) { 22 | text = text.replace(items[i], next + " " + items[i]); 23 | } 24 | } 25 | } 26 | var keywords = (response.entities.keyword || []).filter(function(x) { 27 | return items.reduce(function(r, i) { 28 | return r && i.indexOf(x) <= -1; 29 | }, true) && x.toUpperCase() !== x; 30 | }); 31 | callback(text, keywords); 32 | } 33 | }); 34 | } 35 | 36 | module.exports = nicknamer; 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | # Trumpify 4 | 5 | ### Make your words be the BEST WORDS. 6 | 7 | The President usually set the standard in fashion for the next few years. And no fashion statement of the Trump presidency has been more present than the way he talks (and most importantly tweets). For a demo go [Here](http://quintero.io/trumpify/) 8 | 9 |
10 | 11 | Trumpify is here to help you imitate his style. (WIP) 12 | 13 | Using NLP Trumpify notices the intent and different entities in your sentences and adds insults or praise as it needs. It also finds any words that may be too complicated and makes them, well... More Trumpy. 14 | 15 | For example: 16 | 17 | ``` 18 | The New York Times keeps spreading inaccurate information. 19 | The media truly is the adversary of my administration. 20 | ``` 21 | 22 | Turns into: 23 | 24 | ``` 25 | The failing New York Times keeps spreading wrong information. 26 | The media truly is the opponent of my presidential term. 27 | SO NOT GOOD! 28 | ``` 29 | 30 | So what happened here? 31 | 32 | * Trumpify checked the intent of our message and notice a negative position. 33 | * It added a TrumpStyle finishing sentence using this sentiment. 34 | * Then it identified that we're talking about the New York Times and added a TrumpStyle insult. 35 | * Finally it identified the complex words such as "inaccurate" and "administration", and looked for any synonyms that are often used by Trump. 36 | 37 | As you can imagine this is perfect for tweeting! ;) 38 | 39 | It's still pretty buggy, but I think with a bit more work, we can make Tweeting Great Again 40 | 41 | ## Possible Uses 42 | 43 | * Trump Slack Command 44 | * Trumpify Chrome Extension 45 | 46 | -------------------------------------------------------------------------------- /util/synonyms.js: -------------------------------------------------------------------------------- 1 | var request = require('request'); 2 | 3 | var ignore = ["similar term", "related term"]; 4 | 5 | var dict = require('./trump.js'); 6 | var words = ["positive", "negative", "other"].reduce(function(r, i) { 7 | return r.concat(dict[i] || []); 8 | }, []); 9 | 10 | function synonymsIn(object) { 11 | return object.reduce(function(r, i) { 12 | var items = i.list.synonyms.split("|").filter(function(x) { 13 | return x.indexOf("(antonym)") < 0; 14 | }).map(function(x) { 15 | return ignore.reduce(function (r, i) { 16 | return r.replace(" (" + i + ")", ""); 17 | }, x); 18 | }); 19 | return r.concat(items); 20 | }, []).filter(function(x) { 21 | return words.reduce(function(r, i) { 22 | return r || x.toLowerCase().indexOf(i.toLowerCase()) > -1; 23 | }, false); 24 | }); 25 | } 26 | 27 | function getSynonyms(text, keywords, callback) { 28 | var count = 0; 29 | var handleItem = function(item) { 30 | request("http://thesaurus.altervista.org/thesaurus/v1?language=en_US&output=json&key=4K5aSIJqqOsgMmT3xxje&word=" + item, function(err, response, body) { 31 | if (response.statusCode == 200) { 32 | var info = JSON.parse(body); 33 | var others = synonymsIn(info.response).concat([item]); 34 | var next = others[Math.floor((Math.random() * others.length))]; 35 | if (next && Math.random() > 0.3) { 36 | text = text.replace(item, next); 37 | } 38 | } 39 | count += 1; 40 | if (count == keywords.length) { 41 | callback(text); 42 | } 43 | }); 44 | }; 45 | if (keywords.length > 0) { 46 | for (var i = 0; i < keywords.length; i++) { 47 | handleItem(keywords[i]); 48 | } 49 | } else { 50 | callback(text); 51 | } 52 | } 53 | 54 | module.exports = getSynonyms; 55 | -------------------------------------------------------------------------------- /util/trump.js: -------------------------------------------------------------------------------- 1 | var words = { 2 | "positive": [ 3 | "good", 4 | "great", 5 | "great, great", 6 | "better", 7 | "greatest", 8 | "important", 9 | "very important", 10 | "very good", 11 | "tremendous", 12 | "fantastic", 13 | "amazing", 14 | "terrific", 15 | "best", 16 | "winning", 17 | "huge", 18 | "classy", 19 | "nice", 20 | "beautiful", 21 | "smart", 22 | "very highly educated", 23 | "underrated", 24 | "strong", 25 | "very strong", 26 | "strongman", 27 | "fighter", 28 | "big", 29 | "huuuge", 30 | "enormous", 31 | ], 32 | "negative": [ 33 | "tiny", 34 | "worst", 35 | "boring", 36 | "sad", 37 | "outragious", 38 | "stupid", 39 | "not good", 40 | "bad", 41 | "very bad", 42 | "so not good", 43 | "dangerous", 44 | "lying", 45 | "failing", 46 | "stupid", 47 | "so called", 48 | "dishonest", 49 | "fake", 50 | "ridiculous", 51 | "low energy", 52 | "tough", 53 | "weak", 54 | "zero", 55 | "joke", 56 | "very weak", 57 | "scam", 58 | "hater", 59 | "loser", 60 | "total loser", 61 | "lightweight", 62 | "moron", 63 | "wrong", 64 | "nasty", 65 | "so nasty", 66 | "disgrace", 67 | "mean", 68 | "very mean", 69 | "crooked", 70 | "so crooked", 71 | "racist", 72 | "sexist", 73 | "ugly", 74 | "very ugly", 75 | "hidious", 76 | "unfair", 77 | "very unfair", 78 | "disastrous", 79 | "disaster", 80 | "tanked", 81 | "underachieving", 82 | "lie", 83 | "total lie", 84 | "problem", 85 | "terrible", 86 | "failure", 87 | "total failure", 88 | "crazy", 89 | "super crazy", 90 | "gross", 91 | "very gross", 92 | "scumbag", 93 | "total scumbag", 94 | "dumb", 95 | "very dumb", 96 | "so dumb", 97 | "total mess", 98 | "pathetic", 99 | "very pathetic", 100 | "snowflake", 101 | "overrated", 102 | "hypocrite", 103 | "sleazy", 104 | "baby", 105 | "little", 106 | "little baby", 107 | ], 108 | "neutral": [], 109 | "other": [ 110 | "jobs", 111 | "job", 112 | "everyone", 113 | "handful", 114 | "utterly", 115 | "wall", 116 | "apocalyptic", 117 | "nuclear", 118 | "words", 119 | "hell", 120 | "spreading", 121 | "obviously", 122 | "businessman", 123 | "going", 124 | "know", 125 | "people", 126 | "want", 127 | "think", 128 | "brain", 129 | "right", 130 | "country", 131 | "lot", 132 | "money", 133 | "look", 134 | "mean", 135 | "way", 136 | "make", 137 | "really", 138 | "love", 139 | "time", 140 | "doing", 141 | "trump", 142 | "tell", 143 | "win", 144 | "court", 145 | "sue", 146 | "thing", 147 | "things", 148 | "believe", 149 | "world", 150 | "everybody", 151 | "guy", 152 | "years", 153 | "okay", 154 | "big", 155 | "bigly", 156 | "million", 157 | "billion", 158 | "talk", 159 | "deal", 160 | "thank", 161 | "president", 162 | "wall", 163 | "number", 164 | "happen", 165 | "happened", 166 | "actually", 167 | "talking", 168 | "little", 169 | "saying", 170 | "states", 171 | "better", 172 | "incredible", 173 | "remember", 174 | "problem", 175 | "person", 176 | "somebody", 177 | "probably", 178 | "opposition", 179 | "opposer", 180 | "rival", 181 | "total", 182 | "throw", 183 | "rating", 184 | "immigration", 185 | "muslims", 186 | "mexicans", 187 | "true", 188 | "false", 189 | "liberal", 190 | "absolutely", 191 | "again", 192 | ] 193 | }; 194 | 195 | module.exports = words; 196 | --------------------------------------------------------------------------------