|
| 1 | +var express = require('express') |
| 2 | + , cors = require('cors') |
| 3 | + , app = express() |
| 4 | + , irc = require('irc') |
| 5 | + , ircDataProvider = require('./ircDataProvider').ircDataProvider |
| 6 | + , opengraphParser = require('./opengraphParser.js').opengraphParser; |
| 7 | + |
| 8 | +/* PREPARE OPENGRAPH DATA PARSER AND HELPERS*/ |
| 9 | +var ogParser = new opengraphParser(); |
| 10 | + |
| 11 | +var getOGPmongoUpdate = function(url, callback) { |
| 12 | + var ret = {}; |
| 13 | + ogParser.getHybridGraph(url, function(error, graph) { |
| 14 | + if(error) {callback(error, ret);} |
| 15 | + else { |
| 16 | + ret.title = graph.title; |
| 17 | + ret.description = graph.description; |
| 18 | + ret.image = graph.image; |
| 19 | + callback(null, ret); |
| 20 | + } |
| 21 | + }); |
| 22 | +}; |
| 23 | + |
| 24 | +/* CORS ROUTING CONFIGURATION */ |
| 25 | +var whitelist = ['http://thecact.us', 'http://thewalr.us', 'http://www.thecact.us', 'http://www.thewalr.us']; |
| 26 | + |
| 27 | +var corsOptions = { |
| 28 | + origin: function(origin, callback){ |
| 29 | + var originIsWhitelisted = whitelist.indexOf(origin) !== -1; |
| 30 | + callback(null, originIsWhitelisted); |
| 31 | + }, |
| 32 | + maxAge: 1728000, |
| 33 | + exposedHeaders: 'Location', |
| 34 | + methods: 'GET,POST,OPTIONS', |
| 35 | + allowedHeaders: 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since' |
| 36 | +}; |
| 37 | + |
| 38 | +/* MONGODB IRCDATAPROVIDER CONNECTION AND HELPERS */ |
| 39 | +var dbReady = false; |
| 40 | +var ready = function(error) { |
| 41 | + if(error) console.log(error); |
| 42 | + else dbReady = true; |
| 43 | +} |
| 44 | +var ircData = new ircDataProvider('localhost', 27017,'laticus',ready); |
| 45 | + |
| 46 | +var genericUserUpdate = function(nick, mongoUpdate) { |
| 47 | + if(dbReady) { |
| 48 | + ircData.getCollection(function (error, collection) { |
| 49 | + if(error) console.log(error); |
| 50 | + else { |
| 51 | + collection.update({"user": nick},mongoUpdate,{"upsert" : true}, function(error, modified, result) { |
| 52 | + if(error) console.log(error); |
| 53 | + }); |
| 54 | + } |
| 55 | + }, 'users'); |
| 56 | + } |
| 57 | +}; |
| 58 | + |
| 59 | +var genericLinkUpdate = function(linkURL, nick, mongoUpdate) { |
| 60 | + if(dbReady) { |
| 61 | + ircData.getCollection(function (error, collection) { |
| 62 | + if(error) console.log(error); |
| 63 | + else { |
| 64 | + collection.update({"url": linkURL, "user": nick},mongoUpdate,{"upsert" : true}, function(error, modified, result) { |
| 65 | + if(error) console.log(error); |
| 66 | + }); |
| 67 | + } |
| 68 | + }, 'links'); |
| 69 | + } |
| 70 | +}; |
| 71 | + |
| 72 | +var genericActivityUpdate = function(mongoUpdate) { |
| 73 | + if(dbReady) { |
| 74 | + ircData.getCollection(function (error, collection) { |
| 75 | + if(error) console.log(error); |
| 76 | + else { |
| 77 | + collection.insert(mongoUpdate, function(error, modified, result) { |
| 78 | + if(error) console.log(error); |
| 79 | + }); |
| 80 | + } |
| 81 | + }, 'activity'); |
| 82 | + } |
| 83 | +}; |
| 84 | + |
| 85 | +var genericTubeUpdate = function(tubeID, nick, mongoUpdate) { |
| 86 | + if(dbReady) { |
| 87 | + ircData.getCollection(function (error, collection) { |
| 88 | + if(error) console.log(error); |
| 89 | + else { |
| 90 | + var criteria = {}; |
| 91 | + if(nick == "BetterBot") { |
| 92 | + criteria = {"id": tubeID}; |
| 93 | + } |
| 94 | + else { |
| 95 | + criteria = {"id": tubeID, "user": nick}; |
| 96 | + } |
| 97 | + collection.update(criteria,mongoUpdate,{"upsert" : true}, function(error, modified, result) { |
| 98 | + if(error) console.log(error); |
| 99 | + }); |
| 100 | + } |
| 101 | + }, 'tubes'); |
| 102 | + } |
| 103 | +}; |
| 104 | + |
| 105 | +/* YOUTUBE LINK PARSER */ |
| 106 | +var youtubeLink = function(url) { |
| 107 | + var regExp = /^.*(?:(?:youtu\.be\/([^#\&\?]*))|(?:youtube.com\/(?:v\/|.*\/u\/\w\/|embed\/|watch\??v?=?)([^#\&\?]*))).*$/; |
| 108 | + var match = url.match(regExp); |
| 109 | + if (match) { |
| 110 | + if(match[1]) { |
| 111 | + return {"result" : true, "id" : match[1]}; |
| 112 | + } |
| 113 | + else if(match[2]) { |
| 114 | + return {"result" : true, "id" : match[2]}; |
| 115 | + } |
| 116 | + else { |
| 117 | + return {"result" : false, "id" : null}; |
| 118 | + } |
| 119 | + } |
| 120 | + else { |
| 121 | + return {"result" : false, "id" : null}; |
| 122 | + } |
| 123 | +} |
| 124 | + |
| 125 | +/* IRC CLIENT CONNECTION AND LISTENERS */ |
| 126 | +var client = new irc.Client('morgan.freenode.net', 'Laticus-Prime', {channels: ['#laticus']}); |
| 127 | + |
| 128 | +client.addListener('message#laticus', function (from, message) { |
| 129 | + var usersUpdate = {"$inc" : {"posts" : 1, "links" : 0}, "$setOnInsert" : {"lastLogin" : "unknown", "online" : true}}; |
| 130 | + var linksUpdate = {"$setOnInsert" : {}}; |
| 131 | + var tubesUpdate = {"$setOnInsert" : {}}; |
| 132 | + |
| 133 | + URLlist = message.match(/http[s]?:\/\/[\S]*/ig); |
| 134 | + if(URLlist != null) { |
| 135 | + for (var i = 0; i < URLlist.length; i++) { |
| 136 | + var tube = youtubeLink(URLlist[i]); |
| 137 | + if(tube.result) { |
| 138 | + tubesUpdate.$setOnInsert.user = from; |
| 139 | + tubesUpdate.$setOnInsert.id = tube.id; |
| 140 | + tubesUpdate.$setOnInsert.time = new Date().toISOString(); |
| 141 | + usersUpdate.$inc.links = usersUpdate.$inc.links + 1; |
| 142 | + |
| 143 | + genericTubeUpdate(tube.id, from, tubesUpdate); |
| 144 | + } |
| 145 | + else { |
| 146 | + linksUpdate.$setOnInsert.user = from; |
| 147 | + linksUpdate.$setOnInsert.url = URLlist[i]; |
| 148 | + linksUpdate.$setOnInsert.time = new Date().toISOString(); |
| 149 | + usersUpdate.$inc.links = usersUpdate.$inc.links + 1; |
| 150 | + |
| 151 | + getOGPmongoUpdate(linksUpdate.$setOnInsert.url, function(error, update) { |
| 152 | + if(error) {console.log(error);} |
| 153 | + linksUpdate.$setOnInsert.og = update; |
| 154 | + genericLinkUpdate(linksUpdate.$setOnInsert.url, from, linksUpdate); |
| 155 | + }); |
| 156 | + } |
| 157 | + } |
| 158 | + } |
| 159 | + genericUserUpdate(from, usersUpdate); |
| 160 | +}); |
| 161 | + |
| 162 | +client.addListener('names#laticus', function(nicks) { |
| 163 | + if(dbReady) { |
| 164 | + ircData.find(function(error, dbOnline) { |
| 165 | + var dbOffline = {}; |
| 166 | + for(var i = 0; i < dbOnline.length; i++) { |
| 167 | + if(nicks.hasOwnProperty(dbOnline[i].user)) { |
| 168 | + delete nicks[dbOnline[i].user]; |
| 169 | + } |
| 170 | + else { |
| 171 | + dbOffline[dbOnline[i].user] = ""; |
| 172 | + } |
| 173 | + } |
| 174 | + var usersUpdate = {"$set" : {"online" : true}, "$setOnInsert" : {"posts" : 0, "links" : 0, "lastLogin" : "unknown"}}; |
| 175 | + for(var nick in nicks) { |
| 176 | + if(!nicks.hasOwnProperty(nick)) { continue; } |
| 177 | + genericUserUpdate(nick, usersUpdate); |
| 178 | + } |
| 179 | + usersUpdate = {"$set" : {"online" : false}, "$setOnInsert" : {"posts" : 0, "links" : 0, "lastLogin" : "unknown"}}; |
| 180 | + for(var nick in dbOffline) { |
| 181 | + if(!dbOffline.hasOwnProperty(nick)) { continue; } |
| 182 | + genericUserUpdate(nick, usersUpdate); |
| 183 | + } |
| 184 | + },'users', {"online" : true}); |
| 185 | + } |
| 186 | +}); |
| 187 | + |
| 188 | +client.addListener('join#laticus', function(nick) { |
| 189 | + var timeStamp = new Date().toISOString(); |
| 190 | + var usersUpdate = {"$set" : {"online" : true, "lastLogin" : timeStamp}, "$setOnInsert" : {"posts" : 0, "links" : 0}}; |
| 191 | + var activityUpdate = {"user" : nick, "event" : "joined", "time" : timeStamp}; |
| 192 | + genericUserUpdate(nick, usersUpdate); |
| 193 | + genericActivityUpdate(activityUpdate); |
| 194 | +}); |
| 195 | + |
| 196 | +client.addListener('part#laticus', function(nick, reason) { |
| 197 | + var timeStamp = new Date().toISOString(); |
| 198 | + var usersUpdate = {"$set" : {"online" : false}, "$setOnInsert" : {"posts" : 0, "links" : 0, "lastLogin" : "unknown"}}; |
| 199 | + var activityUpdate = {"user" : nick, "event" : "parted", "reason" : reason, "time" : timeStamp}; |
| 200 | + genericUserUpdate(nick, usersUpdate); |
| 201 | + genericActivityUpdate(activityUpdate); |
| 202 | +}); |
| 203 | + |
| 204 | +client.addListener('kick#laticus', function(nick, by, reason) { |
| 205 | + var timeStamp = new Date().toISOString(); |
| 206 | + var usersUpdate = {"$set" : {"online" : false}, "$setOnInsert" : {"posts" : 0, "links" : 0, "lastLogin" : "unknown"}}; |
| 207 | + var activityUpdate = {"user" : nick, "event" : "kicked", "by" : by, "reason" : reason, "time" : timeStamp}; |
| 208 | + genericUserUpdate(nick, usersUpdate); |
| 209 | + genericActivityUpdate(activityUpdate); |
| 210 | +}); |
| 211 | + |
| 212 | +client.addListener('quit', function(nick, reason) { |
| 213 | + var timeStamp = new Date().toISOString(); |
| 214 | + var usersUpdate = {"$set" : {"online" : false}, "$setOnInsert" : {"posts" : 0, "links" : 0, "lastLogin" : "unknown"}}; |
| 215 | + var activityUpdate = {"user" : nick, "event" : "quit", "reason" : reason, "time" : timeStamp}; |
| 216 | + genericUserUpdate(nick, usersUpdate); |
| 217 | + genericActivityUpdate(activityUpdate); |
| 218 | +}); |
| 219 | + |
| 220 | +client.addListener('kill', function(nick, reason) { |
| 221 | + var timeStamp = new Date().toISOString(); |
| 222 | + var usersUpdate = {"$set" : {"online" : false}, "$setOnInsert" : {"posts" : 0, "links" : 0, "lastLogin" : "unknown"}}; |
| 223 | + var activityUpdate = {"user" : nick, "event" : "killed", "reason" : reason, "time" : timeStamp}; |
| 224 | + genericUserUpdate(nick, usersUpdate); |
| 225 | + genericActivityUpdate(activityUpdate); |
| 226 | +}); |
| 227 | + |
| 228 | +client.addListener('nick', function(oldnick, newnick) { |
| 229 | + var timeStamp = new Date().toISOString(); |
| 230 | + var usersUpdate = {"$set" : {"online" : false}, "$setOnInsert" : {"posts" : 0, "links" : 0, "lastLogin" : "unknown"}}; |
| 231 | + var activityUpdate = {"user" : oldnick, "event" : "nick", "oldnick" : oldnick, "newnick" : newnick, "time" : timeStamp}; |
| 232 | + genericUserUpdate(oldnick, usersUpdate); |
| 233 | + genericActivityUpdate(activityUpdate); |
| 234 | + |
| 235 | + usersUpdate = {"$set" : {"online" : true, "lastLogin" : timeStamp}, "$setOnInsert" : {"posts" : 0, "links" : 0}}; |
| 236 | + genericUserUpdate(newnick, usersUpdate); |
| 237 | +}); |
| 238 | + |
| 239 | +client.addListener('error', function(message) { |
| 240 | + console.log('error: ', message); |
| 241 | +}); |
| 242 | + |
| 243 | +/* SERVER ENDPOINTS FOR RETURNING JSON DATA */ |
| 244 | +app.get('/users/', cors(corsOptions), function(req, res, next){ |
| 245 | + res.set('Cache-Control', 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'); |
| 246 | + if(dbReady) { |
| 247 | + ircData.find(function(error, data) { |
| 248 | + res.json(data); |
| 249 | + },'users'); |
| 250 | + } |
| 251 | +}); |
| 252 | + |
| 253 | +app.get('/links/', cors(corsOptions), function(req, res, next){ |
| 254 | + res.set('Cache-Control', 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'); |
| 255 | + if(dbReady) { |
| 256 | + ircData.find(function(error, data) { |
| 257 | + res.json(data); |
| 258 | + },'links'); |
| 259 | + } |
| 260 | +}); |
| 261 | + |
| 262 | +app.get('/activity/', cors(corsOptions), function(req, res, next){ |
| 263 | + res.set('Cache-Control', 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'); |
| 264 | + if(dbReady) { |
| 265 | + ircData.find(function(error, data) { |
| 266 | + res.json(data); |
| 267 | + },'activity'); |
| 268 | + } |
| 269 | +}); |
| 270 | + |
| 271 | +app.get('/tubes/', cors(corsOptions), function(req, res, next){ |
| 272 | + res.set('Cache-Control', 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'); |
| 273 | + if(dbReady) { |
| 274 | + ircData.find(function(error, data) { |
| 275 | + res.json(data); |
| 276 | + },'tubes'); |
| 277 | + } |
| 278 | +}); |
| 279 | + |
| 280 | +/* DATA GATHERING HELPER FUNCTIONS */ |
| 281 | +var getMessages = function() { |
| 282 | + ret = ""; |
| 283 | + |
| 284 | + for (var i = 0; i < data.messages.length; i++) { |
| 285 | + ret = ret + data.messages[i] + '\n'; |
| 286 | + } |
| 287 | + |
| 288 | + return ret; |
| 289 | +}; |
| 290 | + |
| 291 | +var getURLs = function() { |
| 292 | + ret = ""; |
| 293 | + |
| 294 | + for (var i = 0; i < data.URLs.length; i++) { |
| 295 | + ret = ret + data.URLs[i] + '\n'; |
| 296 | + } |
| 297 | + |
| 298 | + return ret; |
| 299 | +}; |
| 300 | + |
| 301 | +/* START SERVER */ |
| 302 | +app.listen(26969); |
0 commit comments