diff --git a/coffee/components-manager.coffee b/coffee/components-manager.coffee index a82d63f..3a023a8 100644 --- a/coffee/components-manager.coffee +++ b/coffee/components-manager.coffee @@ -445,40 +445,38 @@ commandFunctions = message: 'OK!' +# WEBHOOKS create_webhook: ( user, oBody, callback ) -> answ = hasRequiredParams [ 'hookname' ], oBody if answ.code isnt 200 callback answ else - db.getWebhooks ( err, hooks ) => - if hooks.indexOf oBody.hookname > -1 + db.getUserWebhooks user.username, ( err, hooks ) => + if hooks.indexOf( oBody.hookname ) > -1 answ.code = 409 answ.message = 'Webhook already existing: ' + oBody.hookname callback answ else - db.storeWebhook user.username, oBody.hookname - callback - code: 200 - message: 'OK!' + db.getAllWebhookIDs ( arrHooks ) -> + genHookID = ( arrHooks ) -> + hookid = '' + for i in [0..1] + hookid += Math.random().toString( 36 ).substring 2 + if arrHooks and arrHooks.indexOf( hookid ) > -1 + genHookID arrHooks + else + hookid + hookid = genHookID arrHooks + db.createWebhook user.username, oBody.hookname, hookid + callback + code: 200 + message: JSON.stringify + hookid: hookid - delete_webhook: ( user, oBody, callback ) -> - answ = hasRequiredParams [ 'hookname' ], oBody - if answ.code isnt 200 - callback answ - else - db.getWebhooks ( err, hooks ) => - if hooks.indexOf oBody.hookname is -1 - answ.code = 409 - answ.message = 'Webhook does not exist: ' + oBody.hookname - callback answ - else - db.deleteWebhook user.username, oBody.hookname - callback - code: 200 - message: 'OK!' - - get_webhooks: ( user, oBody, callback ) -> - db.getWebhooks user.username, ( err, data ) -> + + + get_all_webhooks: ( user, oBody, callback ) -> + db.getUserWebhooks user.username, ( err, data ) -> if err callback code: 400 @@ -488,3 +486,24 @@ commandFunctions = code: 200 message: JSON.stringify data + + + + + + delete_webhook: ( user, oBody, callback ) -> + answ = hasRequiredParams [ 'hookname' ], oBody + if answ.code isnt 200 + callback answ + else + db.getUserWebhooks user.username, ( err, hooks ) => + if hooks.indexOf( oBody.hookname ) is -1 + answ.code = 409 + answ.message = 'Webhook does not exist: ' + oBody.hookname + callback answ + else + db.deleteUserWebhook user.username, oBody.hookname + callback + code: 200 + message: 'OK!' + \ No newline at end of file diff --git a/coffee/event-poller.coffee b/coffee/event-poller.coffee index c3294f5..8e266ed 100644 --- a/coffee/event-poller.coffee +++ b/coffee/event-poller.coffee @@ -31,6 +31,10 @@ logconf[ 'file-path' ] = process.argv[ 5 ] log = logger.getLogger logconf log.info 'EP | Event Poller starts up' +process.on 'uncaughtException', ( err ) -> + log.error 'Probably one of the event pollers created an error in a callback function!' + log.error err + # Initialize required modules (should be in cache already) db logger: log dynmod diff --git a/coffee/http-listener.coffee b/coffee/http-listener.coffee index 15a999b..74292b0 100644 --- a/coffee/http-listener.coffee +++ b/coffee/http-listener.coffee @@ -19,8 +19,6 @@ db = require './persistence' # [querystring](http://nodejs.org/api/querystring.html) path = require 'path' qs = require 'querystring' -fs = require 'fs' -path = require 'path' # - External Modules: [express](http://expressjs.com/api.html) express = require 'express' @@ -44,41 +42,6 @@ exports = module.exports = ( args ) => initRouting args[ 'http-port' ] module.exports -indexEvent = ( event, body, resp ) -> - if typeof body is 'string' - try - obj = qs.parse body - catch err - try - obj = JSON.parse body - catch err - resp.send 400, 'Badly formed event!' - return - else - obj = body - timestamp = ( new Date() ).toISOString() - rand = ( Math.floor Math.random() * 10e9 ).toString( 16 ).toUpperCase() - obj.event = event - obj.eventid = "#{ obj.event }_UTC|#{ timestamp }_#{ rand }" - db.pushEvent obj - resp.send 200, "Thank you for the event: #{ obj.eventid }" - -# Activate a webhook. the body will be JSON parsed, the name of the webhook will -# be the event name given to the event object, a timestamp will be added -activateWebHook = ( app, name ) => - @log.info "HL | Webhook activated for #{ name }" - app.post "/webhooks/#{ name }", ( req, resp ) -> - body = '' - req.on 'data', ( data ) -> - body += data - - req.on 'end', -> - indexEvent name, body, resp - # This is a hack to quickly allow storing of public accessible data - if name is 'uptimestatistics' - fPath = path.resolve __dirname, '..', 'webpages', 'public', 'data', 'histochart.json' - fs.writeFile fPath, JSON.stringify( JSON.parse( body ), undefined, 2 ), 'utf8' - ### Initializes the request routing and starts listening on the given port. @@ -118,8 +81,10 @@ initRouting = ( port ) => app.post '/usercommand', requestHandler.handleUserCommand # - **`POST` to _"/admincommand"_:** Admin requests are only possible for admins app.post '/admincommand', requestHandler.handleAdminCommand - # - **`POST` to _"/webhooks/*"_:** Webhooks can be added in the config file - activateWebHook app, hookName for hookName in @arrWebhooks + # - **`POST` to _"/webhooks/*"_:** Webhooks retrieve remote events + app.post '/webhooks', requestHandler.handleWebhooks + # - **`POST` to _"/measurements/*"_:** We also want to record measurements + app.post '/measurements', requestHandler.handleMeasurements server = app.listen parseInt( port ) || 8111 # inbound event channel diff --git a/coffee/persistence.coffee b/coffee/persistence.coffee index db8ba38..fae26d2 100644 --- a/coffee/persistence.coffee +++ b/coffee/persistence.coffee @@ -801,9 +801,28 @@ Creates and stores a webhook. @param {String} userId @param {String} hookname ### -exports.createWebhook = ( userId, hookname ) => +exports.createWebhook = ( userId, hookname, hookid ) => @db.sadd "user:#{ userId }:webhooks", hookname, replyHandler "sadd 'user:#{ userId }:webhooks' -> '#{ hookname }'" + @db.sadd "webhooks", hookid, replyHandler "sadd 'webhooks' -> '#{ hookid }'" + +### +Gets all the users webhooks. + +@public getWebhooks( *userId* ) +@param {String} userId +### +exports.getUserWebhooks = ( userId, cb ) => + @db.smembers "user:#{ userId }:webhooks", cb + +### +Gets all the users webhooks. + +@public getWebhooks( *userId* ) +@param {String} userId +### +exports.getAllWebhookIDs = ( cb ) => + @db.smembers "webhooks", cb ### Deletes a webhook. @@ -812,19 +831,10 @@ Deletes a webhook. @param {String} userId @param {String} hookname ### -exports.deleteWebhook = ( userId, hookname ) => +exports.deleteUserWebhook = ( userId, hookname ) => @db.srem "user:#{ userId }:webhooks", hookname, replyHandler "srem 'user:#{ userId }:webhooks' -> '#{ hookname }'" -### -Gets all the users webhooks. - -@public getWebhooks( *userId* ) -@param {String} userId -### -exports.getWebhooks = ( userId, cb ) => - @db.smembers "user:#{ userId }:webhooks", cb - ### Shuts down the db link. diff --git a/coffee/request-handler.coffee b/coffee/request-handler.coffee index df49536..52343f6 100644 --- a/coffee/request-handler.coffee +++ b/coffee/request-handler.coffee @@ -110,11 +110,14 @@ exports.handleEvent = ( req, resp ) -> req.on 'end', -> #if req.session and req.session.user + console.log typeof body + console.log body try obj = JSON.parse body catch err resp.send 400, 'Badly formed event!' # If required event properties are present we process the event # + console.log obj if obj and obj.event and not err timestamp = ( new Date() ).toISOString() rand = ( Math.floor Math.random() * 10e9 ).toString( 16 ).toUpperCase() @@ -360,4 +363,66 @@ exports.handleAdminCommand = ( req, resp ) => resp.send obj.code, obj else resp.send 401, 'You need to be logged in as admin!' - + + +indexEvent = ( event, body, resp ) -> + if typeof body is 'string' + try + obj = qs.parse body + catch err + try + obj = JSON.parse body + catch err + resp.send 400, 'Badly formed event!' + return + else + obj = body + timestamp = ( new Date() ).toISOString() + rand = ( Math.floor Math.random() * 10e9 ).toString( 16 ).toUpperCase() + obj.event = event + obj.eventid = "#{ obj.event }_UTC|#{ timestamp }_#{ rand }" + db.pushEvent obj + resp.send 200, "Thank you for the event: #{ obj.eventid }" + obj + +### +Handles webhook posts +### +exports.handleWebhooks = ( req, resp ) => + console.log 'RH | IMPLEMENT WEBHOOKS' + +### +Handles measurement posts +### +exports.handleMeasurements = ( req, resp ) => + body = '' + req.on 'data', ( data ) -> + body += data + + req.on 'end', -> + obj = indexEvent name, body, resp + if obj.eventname is 'uptimestatistics' + # This is a hack to quickly allow storing of public accessible data + fPath = path.resolve __dirname, '..', 'webpages', 'public', 'data', 'histochart.json' + fs.writeFile fPath, JSON.stringify( JSON.parse( body ), undefined, 2 ), 'utf8' + +# Activate a webhook. the body will be JSON parsed, the name of the webhook will +# be the event name given to the event object, a timestamp will be added +activateWebHook = ( app, name ) => + @log.info "HL | Webhook activated for #{ name }" + app.post "/webhooks/#{ name }", ( req, resp ) -> + body = '' + req.on 'data', ( data ) -> + body += data + + req.on 'end', -> + indexEvent name, body, resp + +# Remove a webhook +removeWebHook = ( app, hookid ) => + @log.info "HL | Removing Webhook for #{ hookid }" + isFound = false + for oRoute, i in app.routes.post + if oRoute.path is "/webhooks/#{ name }" + app.routes.post.splice i, 1 + isFound = true diff --git a/examples/action-invokers/system.coffee b/examples/action-invokers/converter.coffee similarity index 67% rename from examples/action-invokers/system.coffee rename to examples/action-invokers/converter.coffee index d01b740..16f73b4 100644 --- a/examples/action-invokers/system.coffee +++ b/examples/action-invokers/converter.coffee @@ -86,4 +86,33 @@ fConvertTimeStringToDate = ( text ) -> start.setMilliseconds 0 if start < new Date() start.setDate start.getDate() + 1 - start \ No newline at end of file + start + +degToRad = ( deg ) -> + deg * Math.PI / 180 + +exports.LongLatToMeterDistance = ( latOne, longOne, latTwo, longTwo, eventname ) -> + earthRadius = 3958.75 + latOne = parseFloat latOne + longOne = parseFloat longOne + latTwo = parseFloat latTwo + longTwo = parseFloat longTwo + if isNaN latOne or isNaN longOne or isNaN latTwo or isNaN longTwo + log "Illegal values detected in yur given parameters: + #{ latOne }, #{ longOne }, #{ latTwo }, #{ longTwo }" + return + dLat = degToRad latTwo - latOne + dLng = degToRad longTwo - longOne + a = Math.sin( dLat / 2 ) * Math.sin( dLat / 2 ) + + Math.cos( degToRad latOne ) * Math.cos( degToRad latTwo ) * + Math.sin( dLng / 2 ) * Math.sin( dLng / 2 ) + c = 2 * Math.atan2 Math.sqrt( a ), Math.sqrt 1 - a + + pushEvent + event: eventname + body: + latOne: latOne + longOne: longOne + latTwo: latTwo + longTwo: longTwo + distance: earthRadius * c * 1609 # meter conversion diff --git a/examples/arguments.json b/examples/arguments.json new file mode 100644 index 0000000..45a80fa --- /dev/null +++ b/examples/arguments.json @@ -0,0 +1,6 @@ +[ + "47.563176999999996", + "7.581330899999998", + "47.563186999999996", + "7.587331899999998" +] \ No newline at end of file diff --git a/examples/eventproducers/hoststatistics.coffee b/examples/eventproducers/hoststatistics.coffee index 42ceb7e..436736c 100644 --- a/examples/eventproducers/hoststatistics.coffee +++ b/examples/eventproducers/hoststatistics.coffee @@ -1,70 +1,72 @@ fs = require 'fs' -# libnmap = require 'node-libnmap' ping = require 'net-ping' -# request = require 'request' needle = require 'needle' # remoteUrl = "localhost:8125" remoteUrl = "http://ec2-54-226-188-9.compute-1.amazonaws.com:8126" fPushEvent = ( evt ) -> - needle.post remoteUrl + '/webhooks/uptimestatistics', JSON.stringify( evt ), ( err, resp, body ) -> + needle.post remoteUrl + '/measurements', evt, ( err, resp, body ) -> if err or resp.statusCode isnt 200 console.log 'Error in pushing event!' else console.log 'Successfully posted an event' try - # arrHosts = JSON.parse fs.readFileSync 'hostlist.json', 'utf8' - histData = JSON.parse fs.readFileSync 'histochart.json', 'utf8' + histData = fs.readFileSync 'histoappend.json', 'utf8' catch err console.error err console.error "Error reading historical data file" process.exit() - -# console.log arrHosts -# libnmap.nmap 'scan', -# range: arrHosts, -# callback: ( err, report ) -> -# if err -# console.log err -# else -# report.forEach ( item ) -> -# console.log item[ 0 ] - session = ping.createSession retries: 2 -everyMins = 10 -oHosts = {} -oPings = {} -i = -1 +oSum = {} if histData - oHosts = histData.hosts - oPings = histData.pingtimes + arrPings = histData.split "\n" + try + for strObj, i in arrPings + if strObj isnt '' + oTmp = JSON.parse strObj + oSum[ oTmp.timestamp ] = + sum: oTmp.sum + if oTmp + fPushEvent + currentlyon: oSum[ oTmp.timestamp ].sum + pingtimes: oSum + + catch err + console.log 'Error parsing histo data' + console.log err + +i = -1 +ips = [] pingTime = (new Date()).toISOString() -oPings[ pingTime ] = ips: [] fPollHosts = () -> i++ console.log "Pinging 131.152.85.#{ i }" session.pingHost "131.152.85.#{ i }", ( err, target, sent, rcvd ) -> if not err - if not oHosts[ target ] - oHosts[ target ] = {} - oHosts[ target ][ pingTime ] = (new Date( rcvd - sent )).getTime() - oPings[ pingTime ].ips.push target + ips.push target if i is 255 i = -1 - console.log 'All ping requests returned, pushing event into the system and starting again at 0' - oPings[ pingTime ].sum = oPings[ pingTime ].ips.length - evt = - currentlyon: oPings[ pingTime ].ips.length - pingtimes: oPings - hosts: oHosts - fPushEvent evt - fs.writeFile 'histochart.json', JSON.stringify( evt, undefined, 2 ), 'utf8' + console.log "All ping requests returned (#{ips.length} answered), pushing event into the system and starting again at 0" + + oSum[ pingTime ] = sum: ips.length + fPushEvent + eventname: 'uptimestatistics' + payload: + currentlyon: ips.length + pingtimes: oSum + + oPing = + timestamp: pingTime + ips: ips + sum: ips.length + + fs.appendFile 'histoappend.json', JSON.stringify( oPing ) + "\n", 'utf8' pingTime = (new Date()).toISOString() - oPings[ pingTime ] = ips: [] + ips = [] setTimeout fPollHosts, 7000 @@ -72,29 +74,3 @@ fPollHosts = () -> fPollHosts() -# Some pings eventually get blocked if you ping 255 IPs within one second... -# -# fPollHosts = () -> -# semaphore = arrHosts.length -# pingTime = (new Date()).toISOString() -# oPings[ pingTime ] = ips: [] -# for host in arrHosts -# session.pingHost host, ( err, target, sent, rcvd ) -> -# if not err -# if not oHosts[ target ] -# oHosts[ target ] = {} -# oHosts[ target ][ pingTime ] = (new Date( rcvd - sent )).getTime() -# oPings[ pingTime ].ips.push target - -# if --semaphore is 0 -# console.log 'All ping requests returned, pushing event into the system' -# oPings[ pingTime ].sum = oPings[ pingTime ].ips.length -# evt = -# currentlyon: oPings[ pingTime ].ips.length -# pingtimes: oPings -# hosts: oHosts -# fPushEvent evt -# fs.writeFile 'histochart.json', JSON.stringify( evt, undefined, 2 ), 'utf8' - -# console.log "Pinging again in #{ everyMins } minutes" -# setTimeout fPollHosts, everyMins * 60 * 1000 diff --git a/examples/runscript.coffee b/examples/runscript.coffee index 61d8e2e..d61f031 100644 --- a/examples/runscript.coffee +++ b/examples/runscript.coffee @@ -21,6 +21,8 @@ request = require 'request' importio = require( 'import-io' ).client params = JSON.parse fs.readFileSync 'params.json', 'utf8' +arrArgs = JSON.parse fs.readFileSync 'arguments.json', 'utf8' + code = fs.readFileSync process.argv[ 2 ], 'utf8' src = cs.compile code @@ -40,13 +42,7 @@ sandbox = vm.runInNewContext src, sandbox, sandbox.id -# sandbox.exports[ process.argv[ 3 ] ].apply null, [ "FS14", "FS14 - CS108", "param3", "param4" ] -sandbox.exports[ process.argv[ 3 ] ].apply null, [ - useraccount: "10595" - semester: "FS14" - studies: "BSC4" - major: "BL" -] +console.log sandbox.exports[ process.argv[ 3 ] ].apply null, arrArgs console.log "If no error happened until here it seems the script compiled and ran correctly! Congrats!" \ No newline at end of file diff --git a/examples/runscript.js b/examples/runscript.js index f6ae015..b178a02 100644 --- a/examples/runscript.js +++ b/examples/runscript.js @@ -9,7 +9,7 @@ compilation and running of module code */ (function() { - var code, crypto, cs, fs, importio, needle, params, request, sandbox, src, vm; + var arrArgs, code, crypto, cs, fs, importio, needle, params, request, sandbox, src, vm; if (!process.argv[2]) { console.log('Please provide a path to a coffee file'); @@ -32,6 +32,8 @@ compilation and running of module code params = JSON.parse(fs.readFileSync('params.json', 'utf8')); + arrArgs = JSON.parse(fs.readFileSync('arguments.json', 'utf8')); + code = fs.readFileSync(process.argv[2], 'utf8'); src = cs.compile(code); @@ -54,14 +56,7 @@ compilation and running of module code vm.runInNewContext(src, sandbox, sandbox.id); - sandbox.exports[process.argv[3]].apply(null, [ - { - useraccount: "10595", - semester: "FS14", - studies: "BSC4", - major: "BL" - } - ]); + console.log(sandbox.exports[process.argv[3]].apply(null, arrArgs)); console.log("If no error happened until here it seems the script compiled and ran correctly! Congrats!"); diff --git a/js/components-manager.js b/js/components-manager.js index c179b22..06b48d0 100644 --- a/js/components-manager.js +++ b/js/components-manager.js @@ -568,48 +568,43 @@ Components Manager if (answ.code !== 200) { return callback(answ); } else { - return db.getWebhooks((function(_this) { + return db.getUserWebhooks(user.username, (function(_this) { return function(err, hooks) { - if (hooks.indexOf(oBody.hookname > -1)) { + if (hooks.indexOf(oBody.hookname) > -1) { answ.code = 409; answ.message = 'Webhook already existing: ' + oBody.hookname; return callback(answ); } else { - db.storeWebhook(user.username, oBody.hookname); - return callback({ - code: 200, - message: 'OK!' + return db.getAllWebhookIDs(function(arrHooks) { + var genHookID, hookid; + genHookID = function(arrHooks) { + var hookid, i, _i; + hookid = ''; + for (i = _i = 0; _i <= 1; i = ++_i) { + hookid += Math.random().toString(36).substring(2); + } + if (arrHooks && arrHooks.indexOf(hookid) > -1) { + return genHookID(arrHooks); + } else { + return hookid; + } + }; + hookid = genHookID(arrHooks); + db.createWebhook(user.username, oBody.hookname, hookid); + return callback({ + code: 200, + message: JSON.stringify({ + hookid: hookid + }) + }); }); } }; })(this)); } }, - delete_webhook: function(user, oBody, callback) { - var answ; - answ = hasRequiredParams(['hookname'], oBody); - if (answ.code !== 200) { - return callback(answ); - } else { - return db.getWebhooks((function(_this) { - return function(err, hooks) { - if (hooks.indexOf(oBody.hookname === -1)) { - answ.code = 409; - answ.message = 'Webhook does not exist: ' + oBody.hookname; - return callback(answ); - } else { - db.deleteWebhook(user.username, oBody.hookname); - return callback({ - code: 200, - message: 'OK!' - }); - } - }; - })(this)); - } - }, - get_webhooks: function(user, oBody, callback) { - return db.getWebhooks(user.username, function(err, data) { + get_all_webhooks: function(user, oBody, callback) { + return db.getUserWebhooks(user.username, function(err, data) { if (err) { return callback({ code: 400, @@ -622,6 +617,29 @@ Components Manager }); } }); + }, + delete_webhook: function(user, oBody, callback) { + var answ; + answ = hasRequiredParams(['hookname'], oBody); + if (answ.code !== 200) { + return callback(answ); + } else { + return db.getUserWebhooks(user.username, (function(_this) { + return function(err, hooks) { + if (hooks.indexOf(oBody.hookname) === -1) { + answ.code = 409; + answ.message = 'Webhook does not exist: ' + oBody.hookname; + return callback(answ); + } else { + db.deleteUserWebhook(user.username, oBody.hookname); + return callback({ + code: 200, + message: 'OK!' + }); + } + }; + })(this)); + } } }; diff --git a/js/event-poller.js b/js/event-poller.js index e089b9e..48db09c 100644 --- a/js/event-poller.js +++ b/js/event-poller.js @@ -39,6 +39,11 @@ Dynamic Modules log.info('EP | Event Poller starts up'); + process.on('uncaughtException', function(err) { + log.error('Probably one of the event pollers created an error in a callback function!'); + return log.error(err); + }); + db({ logger: log }); diff --git a/js/http-listener.js b/js/http-listener.js index 4fce30f..d7c8816 100644 --- a/js/http-listener.js +++ b/js/http-listener.js @@ -10,7 +10,7 @@ HTTP Listener */ (function() { - var activateWebHook, app, db, exports, express, fs, indexEvent, initRouting, path, qs, requestHandler; + var app, db, exports, express, initRouting, path, qs, requestHandler; requestHandler = require('./request-handler'); @@ -20,10 +20,6 @@ HTTP Listener qs = require('querystring'); - fs = require('fs'); - - path = require('path'); - express = require('express'); app = express(); @@ -48,53 +44,6 @@ HTTP Listener }; })(this); - indexEvent = function(event, body, resp) { - var err, obj, rand, timestamp; - if (typeof body === 'string') { - try { - obj = qs.parse(body); - } catch (_error) { - err = _error; - try { - obj = JSON.parse(body); - } catch (_error) { - err = _error; - resp.send(400, 'Badly formed event!'); - return; - } - } - } else { - obj = body; - } - timestamp = (new Date()).toISOString(); - rand = (Math.floor(Math.random() * 10e9)).toString(16).toUpperCase(); - obj.event = event; - obj.eventid = "" + obj.event + "_UTC|" + timestamp + "_" + rand; - db.pushEvent(obj); - return resp.send(200, "Thank you for the event: " + obj.eventid); - }; - - activateWebHook = (function(_this) { - return function(app, name) { - _this.log.info("HL | Webhook activated for " + name); - return app.post("/webhooks/" + name, function(req, resp) { - var body; - body = ''; - req.on('data', function(data) { - return body += data; - }); - return req.on('end', function() { - var fPath; - indexEvent(name, body, resp); - if (name === 'uptimestatistics') { - fPath = path.resolve(__dirname, '..', 'webpages', 'public', 'data', 'histochart.json'); - return fs.writeFile(fPath, JSON.stringify(JSON.parse(body), void 0, 2), 'utf8'); - } - }); - }); - }; - })(this); - /* Initializes the request routing and starts listening on the given port. @@ -105,7 +54,7 @@ HTTP Listener initRouting = (function(_this) { return function(port) { - var hookName, server, sess_sec, _i, _len, _ref; + var server, sess_sec; app.use(express.cookieParser()); sess_sec = "149u*y8C:@kmN/520Gt\\v'+KFBnQ!\\r<>5X/xRI`sT '" + hookname + "'")); + return function(userId, hookname, hookid) { + _this.db.sadd("user:" + userId + ":webhooks", hookname, replyHandler("sadd 'user:" + userId + ":webhooks' -> '" + hookname + "'")); + return _this.db.sadd("webhooks", hookid, replyHandler("sadd 'webhooks' -> '" + hookid + "'")); + }; + })(this); + + + /* + Gets all the users webhooks. + + @public getWebhooks( *userId* ) + @param {String} userId + */ + + exports.getUserWebhooks = (function(_this) { + return function(userId, cb) { + return _this.db.smembers("user:" + userId + ":webhooks", cb); + }; + })(this); + + + /* + Gets all the users webhooks. + + @public getWebhooks( *userId* ) + @param {String} userId + */ + + exports.getAllWebhookIDs = (function(_this) { + return function(cb) { + return _this.db.smembers("webhooks", cb); }; })(this); @@ -1058,27 +1087,13 @@ Persistence @param {String} hookname */ - exports.deleteWebhook = (function(_this) { + exports.deleteUserWebhook = (function(_this) { return function(userId, hookname) { return _this.db.srem("user:" + userId + ":webhooks", hookname, replyHandler("srem 'user:" + userId + ":webhooks' -> '" + hookname + "'")); }; })(this); - /* - Gets all the users webhooks. - - @public getWebhooks( *userId* ) - @param {String} userId - */ - - exports.getWebhooks = (function(_this) { - return function(userId, cb) { - return _this.db.smembers("user:" + userId + ":webhooks", cb); - }; - })(this); - - /* Shuts down the db link. diff --git a/js/request-handler.js b/js/request-handler.js index cac23d3..6a452cc 100644 --- a/js/request-handler.js +++ b/js/request-handler.js @@ -11,7 +11,7 @@ Request Handler */ (function() { - var crypto, db, dirHandlers, exports, fs, getHandlerPath, getRemoteScripts, getScript, getTemplate, mustache, path, pathUsers, qs, renderPage; + var activateWebHook, crypto, db, dirHandlers, exports, fs, getHandlerPath, getRemoteScripts, getScript, getTemplate, indexEvent, mustache, path, pathUsers, qs, removeWebHook, renderPage; db = require('./persistence'); @@ -127,12 +127,15 @@ Request Handler }); return req.on('end', function() { var answ, err, obj, rand, timestamp; + console.log(typeof body); + console.log(body); try { obj = JSON.parse(body); } catch (_error) { err = _error; resp.send(400, 'Badly formed event!'); } + console.log(obj); if (obj && obj.event && !err) { timestamp = (new Date()).toISOString(); rand = (Math.floor(Math.random() * 10e9)).toString(16).toUpperCase(); @@ -435,4 +438,101 @@ Request Handler }; })(this); + indexEvent = function(event, body, resp) { + var err, obj, rand, timestamp; + if (typeof body === 'string') { + try { + obj = qs.parse(body); + } catch (_error) { + err = _error; + try { + obj = JSON.parse(body); + } catch (_error) { + err = _error; + resp.send(400, 'Badly formed event!'); + return; + } + } + } else { + obj = body; + } + timestamp = (new Date()).toISOString(); + rand = (Math.floor(Math.random() * 10e9)).toString(16).toUpperCase(); + obj.event = event; + obj.eventid = "" + obj.event + "_UTC|" + timestamp + "_" + rand; + db.pushEvent(obj); + resp.send(200, "Thank you for the event: " + obj.eventid); + return obj; + }; + + + /* + Handles webhook posts + */ + + exports.handleWebhooks = (function(_this) { + return function(req, resp) { + return console.log('RH | IMPLEMENT WEBHOOKS'); + }; + })(this); + + + /* + Handles measurement posts + */ + + exports.handleMeasurements = (function(_this) { + return function(req, resp) { + var body; + body = ''; + req.on('data', function(data) { + return body += data; + }); + return req.on('end', function() { + var fPath, obj; + obj = indexEvent(name, body, resp); + if (obj.eventname === 'uptimestatistics') { + fPath = path.resolve(__dirname, '..', 'webpages', 'public', 'data', 'histochart.json'); + return fs.writeFile(fPath, JSON.stringify(JSON.parse(body), void 0, 2), 'utf8'); + } + }); + }; + })(this); + + activateWebHook = (function(_this) { + return function(app, name) { + _this.log.info("HL | Webhook activated for " + name); + return app.post("/webhooks/" + name, function(req, resp) { + var body; + body = ''; + req.on('data', function(data) { + return body += data; + }); + return req.on('end', function() { + return indexEvent(name, body, resp); + }); + }); + }; + })(this); + + removeWebHook = (function(_this) { + return function(app, hookid) { + var i, isFound, oRoute, _i, _len, _ref, _results; + _this.log.info("HL | Removing Webhook for " + hookid); + isFound = false; + _ref = app.routes.post; + _results = []; + for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { + oRoute = _ref[i]; + if (oRoute.path === ("/webhooks/" + name)) { + app.routes.post.splice(i, 1); + _results.push(isFound = true); + } else { + _results.push(void 0); + } + } + return _results; + }; + })(this); + }).call(this); diff --git a/webpages/handlers/coffee/forge_event.coffee b/webpages/handlers/coffee/forge_event.coffee index 436abeb..4de1754 100644 --- a/webpages/handlers/coffee/forge_event.coffee +++ b/webpages/handlers/coffee/forge_event.coffee @@ -54,7 +54,7 @@ fOnLoad = () -> oSelector = fFindKeyStringPair obj.body if oSelector sel = "&selkey=#{ oSelector.key }&selval=#{ oSelector.val }" - url = 'forge?page=forge_rule&eventname=' + obj.event + sel + url = 'forge?page=forge_rule&eventtype=custom&eventname=' + obj.event + sel window.open url, '_blank' else $( '#info' ).text 'Please provide a valid eventname' diff --git a/webpages/handlers/coffee/forge_rule.coffee b/webpages/handlers/coffee/forge_rule.coffee index 1ccb839..ca37726 100644 --- a/webpages/handlers/coffee/forge_rule.coffee +++ b/webpages/handlers/coffee/forge_rule.coffee @@ -62,11 +62,18 @@ fOnLoad = () -> # EVENT # If the user is coming from an event he wants a rule to be setup for him - if oParams.eventname - $( '#select_event_type' ).val 'Custom Event' - inpEvt = $( '' ).attr( 'type', 'text').attr 'id', 'input_eventname' - inpEvt.val oParams.eventname - $( '#event_parameters' ).append inpEvt + switch oParams.eventtype + when 'custom' + $( '#select_event_type' ).val 'Custom Event' + inpEvt = $( '' ).attr( 'type', 'text').attr 'id', 'input_eventname' + inpEvt.val oParams.eventname + $( '#event_parameters' ).append inpEvt + + when 'webhook' + console.log 'webhook' + + when 'poller' + console.log 'poller' # Event type is changed, changes the whole event section $( '#select_event_type' ).change () -> diff --git a/webpages/handlers/coffee/forge_webhook.coffee b/webpages/handlers/coffee/forge_webhook.coffee index e69de29..e5a1670 100644 --- a/webpages/handlers/coffee/forge_webhook.coffee +++ b/webpages/handlers/coffee/forge_webhook.coffee @@ -0,0 +1,89 @@ +# Fetch the search string and transform it into an object for easy access +arrParams = window.location.search.substring(1).split '&' +oParams = {} +for param in arrParams + arrKV = param.split '=' + oParams[ arrKV[ 0 ] ] = arrKV[ 1 ] + +if oParams.id + oParams.id = decodeURIComponent oParams.id + +fDisplayError = ( msg ) -> + window.scrollTo 0, 0 + $( '#info' ).text "Error: #{ msg }" + $( '#info' ).attr 'class', 'error' + +fIssueRequest = ( args ) -> + $( '#info' ).text '' + $.post( '/usercommand', args.body ) + .done args.done + .fail args.fail + +fFailedRequest = ( msg ) -> + ( err ) -> + if err.status is 401 + window.location.href = 'forge?page=forge_rule' + else + fDisplayError msg + +fUpdateWebhookList = ( data ) -> + $( '#table_webhooks tr' ).remove() + oHooks = JSON.parse data.message + console.log oHooks + for modName of oHooks + tr = $ '' + inp = $( '
' ).text modName + img = $( '' ).attr( 'class', 'del' ) + .attr( 'title', 'Delete Module' ).attr 'src', 'red_cross_small.png' + tr.append( $( '' ).append img ) + tr.append( $( '' ).append inp ) + $( '#table_webhooks' ).append tr + +fOnLoad = () -> + + document.title = 'Create Webhooks!' + # Load existing rules + + fIssueRequest + body: + command: 'get_all_webhooks' + done: fUpdateWebhookList + fail: fFailedRequest 'Unable to post get_all_webhooks request' + + # Register button action + $( '#but_submit' ).click -> + $( '#info' ).text '' + + hookname = $( '#inp_hookname' ).val() + if hookname is '' + fDisplayError 'Please provide a hookname!' + + else + $( '#display_hookurl *' ).remove() + fIssueRequest + body: + command: 'create_webhook' + body: JSON.stringify + hookname: hookname + done: ( data ) -> + oAnsw = JSON.parse data.message + url = [ location.protocol, '//', location.host ].join '' + + h3 = $( '

' ).text "This is the Webhook Url you should use:" + inp = $('').attr( 'type', 'text' ).attr( 'style', 'font-size:1em' ) + .val "#{ url }/webhooks/#{ oAnsw.hookid }" + h3.append inp + $( '#display_hookurl' ).append h3 + + div = $('
').html "Push your location via this page" + $( '#display_hookurl' ).append div + + fail: ( err ) -> + if err.status is 409 + fFailedRequest( 'Webhook Event Name already existing!' ) err + else + fFailedRequest( 'Unable to create Webhook! ' + err.message ) err + +#

This is the Webhook Url you should use:

+# push your location via this page: mobile?hookid= +window.addEventListener 'load', fOnLoad, true diff --git a/webpages/handlers/js/forge_event.js b/webpages/handlers/js/forge_event.js index 7d95206..9bbf1e6 100644 --- a/webpages/handlers/js/forge_event.js +++ b/webpages/handlers/js/forge_event.js @@ -73,7 +73,7 @@ sel = "&selkey=" + oSelector.key + "&selval=" + oSelector.val; } } - url = 'forge?page=forge_rule&eventname=' + obj.event + sel; + url = 'forge?page=forge_rule&eventtype=custom&eventname=' + obj.event + sel; return window.open(url, '_blank'); } else { $('#info').text('Please provide a valid eventname'); diff --git a/webpages/handlers/js/forge_rule.js b/webpages/handlers/js/forge_rule.js index 3225afb..3913b9f 100644 --- a/webpages/handlers/js/forge_rule.js +++ b/webpages/handlers/js/forge_rule.js @@ -68,11 +68,18 @@ editor.setTheme("ace/theme/monokai"); editor.getSession().setMode("ace/mode/json"); editor.setShowPrintMargin(false); - if (oParams.eventname) { - $('#select_event_type').val('Custom Event'); - inpEvt = $('').attr('type', 'text').attr('id', 'input_eventname'); - inpEvt.val(oParams.eventname); - $('#event_parameters').append(inpEvt); + switch (oParams.eventtype) { + case 'custom': + $('#select_event_type').val('Custom Event'); + inpEvt = $('').attr('type', 'text').attr('id', 'input_eventname'); + inpEvt.val(oParams.eventname); + $('#event_parameters').append(inpEvt); + break; + case 'webhook': + console.log('webhook'); + break; + case 'poller': + console.log('poller'); } $('#select_event_type').change(function() { $('#event_parameters *').remove(); diff --git a/webpages/handlers/js/forge_webhook.js b/webpages/handlers/js/forge_webhook.js index c15577d..249ee39 100644 --- a/webpages/handlers/js/forge_webhook.js +++ b/webpages/handlers/js/forge_webhook.js @@ -1,5 +1,106 @@ // Generated by CoffeeScript 1.7.1 (function() { + var arrKV, arrParams, fDisplayError, fFailedRequest, fIssueRequest, fOnLoad, fUpdateWebhookList, oParams, param, _i, _len; + arrParams = window.location.search.substring(1).split('&'); + + oParams = {}; + + for (_i = 0, _len = arrParams.length; _i < _len; _i++) { + param = arrParams[_i]; + arrKV = param.split('='); + oParams[arrKV[0]] = arrKV[1]; + } + + if (oParams.id) { + oParams.id = decodeURIComponent(oParams.id); + } + + fDisplayError = function(msg) { + window.scrollTo(0, 0); + $('#info').text("Error: " + msg); + return $('#info').attr('class', 'error'); + }; + + fIssueRequest = function(args) { + $('#info').text(''); + return $.post('/usercommand', args.body).done(args.done).fail(args.fail); + }; + + fFailedRequest = function(msg) { + return function(err) { + if (err.status === 401) { + return window.location.href = 'forge?page=forge_rule'; + } else { + return fDisplayError(msg); + } + }; + }; + + fUpdateWebhookList = function(data) { + var img, inp, modName, oHooks, tr, _results; + $('#table_webhooks tr').remove(); + oHooks = JSON.parse(data.message); + console.log(oHooks); + _results = []; + for (modName in oHooks) { + tr = $(''); + inp = $('
').text(modName); + img = $('').attr('class', 'del').attr('title', 'Delete Module').attr('src', 'red_cross_small.png'); + tr.append($('').append(img)); + tr.append($('').append(inp)); + _results.push($('#table_webhooks').append(tr)); + } + return _results; + }; + + fOnLoad = function() { + document.title = 'Create Webhooks!'; + fIssueRequest({ + body: { + command: 'get_all_webhooks' + }, + done: fUpdateWebhookList, + fail: fFailedRequest('Unable to post get_all_webhooks request') + }); + return $('#but_submit').click(function() { + var hookname; + $('#info').text(''); + hookname = $('#inp_hookname').val(); + if (hookname === '') { + return fDisplayError('Please provide a hookname!'); + } else { + $('#display_hookurl *').remove(); + return fIssueRequest({ + body: { + command: 'create_webhook', + body: JSON.stringify({ + hookname: hookname + }) + }, + done: function(data) { + var div, h3, inp, oAnsw, url; + oAnsw = JSON.parse(data.message); + url = [location.protocol, '//', location.host].join(''); + h3 = $('

').text("This is the Webhook Url you should use:"); + inp = $('').attr('type', 'text').attr('style', 'font-size:1em').val("" + url + "/webhooks/" + oAnsw.hookid); + h3.append(inp); + $('#display_hookurl').append(h3); + div = $('
').html("Push your location via this page"); + return $('#display_hookurl').append(div); + }, + fail: function(err) { + if (err.status === 409) { + return fFailedRequest('Webhook Event Name already existing!')(err); + } else { + return fFailedRequest('Unable to create Webhook! ' + err.message)(err); + } + } + }); + } + }); + }; + + window.addEventListener('load', fOnLoad, true); }).call(this); diff --git a/webpages/handlers/templates/forge_event.html b/webpages/handlers/templates/forge_event.html index a3c1057..d1160c1 100644 --- a/webpages/handlers/templates/forge_event.html +++ b/webpages/handlers/templates/forge_event.html @@ -9,5 +9,6 @@ }

- - + +
+ diff --git a/webpages/handlers/templates/forge_webhook.html b/webpages/handlers/templates/forge_webhook.html index 9b90ccd..379d393 100644 --- a/webpages/handlers/templates/forge_webhook.html +++ b/webpages/handlers/templates/forge_webhook.html @@ -1,5 +1,7 @@ - +

Create your own Webhooks

+

Provide your desired Event Name : +



-

This is the Webhook Url you should use:

+
diff --git a/webpages/handlers/templates/menubar.html b/webpages/handlers/templates/menubar.html index b882ee1..8203ec9 100644 --- a/webpages/handlers/templates/menubar.html +++ b/webpages/handlers/templates/menubar.html @@ -20,6 +20,9 @@ fCreateLink( 'Create Rule', fRedirect( 'forge?page=forge_rule' ) ); + fCreateLink( 'Create Webhooks', + fRedirect( 'forge?page=forge_webhook' ) + ); fCreateLink( 'Edit Rules', fRedirect( 'forge?page=edit_rules' ) ); @@ -32,9 +35,6 @@ fCreateLink( 'Edit EPs & AIs', fRedirect( 'forge?page=edit_modules' ) ); - fCreateLink( 'Webhooks', - fRedirect( 'forge?page=forge_webhook' ) - ); // fCreateLink( 'admin', fRedirect( 'admin' ) ); fCreateLink( 'Logout', function() { diff --git a/webpages/public/histogram.html b/webpages/public/histogram.html index 1ad0d47..593a222 100644 --- a/webpages/public/histogram.html +++ b/webpages/public/histogram.html @@ -10,6 +10,7 @@