diff --git a/app/sockets/analytics_service.js b/app/sockets/analytics_service.js index 477363f3..589858ea 100644 --- a/app/sockets/analytics_service.js +++ b/app/sockets/analytics_service.js @@ -12,7 +12,7 @@ var mongoose = require('mongoose'), module.exports = function (io, socket) { var visitorsData = {}; - var saveVisitorData = function (data, cb){ + var saveVisitorData = function (data, socket, cb){ Form.findById(data.formId, function(err, form) { if (err) { console.error(err); @@ -32,15 +32,22 @@ module.exports = function (io, socket) { form.analytics.visitors.push(newVisitor); - form.save(function (formSaveErr) { - if (err) { - console.error(err); - throw new Error(errorHandler.getErrorMessage(formSaveErr)); + request('https://freegeoip.net/json/'+socket.conn.transport.socket._socket.remoteAddress, (error, response, body)=> { + var geoData = body; + data.geoLocation = { + city: geoData.city, + country: geoData.country_name } + form.save(function (formSaveErr) { + if (err) { + console.error(err); + throw new Error(errorHandler.getErrorMessage(formSaveErr)); + } - if(cb){ - return cb(); - } + if(cb){ + return cb(); + } + }); }); }); }; @@ -54,22 +61,12 @@ module.exports = function (io, socket) { visitorsData[current_socket.id].ipAddr = current_socket.conn.transport.socket._socket.remoteAddress; - console.log(current_socket); - request('https://freegeoip.net/json/'+current_socket.conn.transport.socket._socket.remoteAddress, (error, response, body)=> { - console.log(body); - var geoData = body; - visitorsData[current_socket.id].geoLocation = { - city: geoData.city, - country: geoData.country_name - } - - if (data.isSubmitted && !data.isSaved) { - visitorsData[current_socket.id].isSaved = true; - saveVisitorData(data, function() { - current_socket.disconnect(true); - }); - } - }); + if (data.isSubmitted && !data.isSaved) { + visitorsData[current_socket.id].isSaved = true; + saveVisitorData(data, function() { + current_socket.disconnect(true); + }); + } }); current_socket.on('disconnect', function() { @@ -85,3 +82,4 @@ module.exports = function (io, socket) { }); }); }; + diff --git a/public/dist/application.js b/public/dist/application.js index bda39348..407518a2 100644 --- a/public/dist/application.js +++ b/public/dist/application.js @@ -84,11 +84,11 @@ angular.module('TellForm.templates', []).run(['$templateCache', function($templa " \n" + - "
| # | {{value.title}} | {{ 'PERCENTAGE_COMPLETE' | translate }} | {{ 'TIME_ELAPSED' | translate }} | {{ 'DEVICE' | translate }} | {{ 'LOCATION' | translate }} | {{ 'IP_ADDRESS' | translate }} | {{ 'DATE_SUBMITTED' | translate }} (UTC) | |
|---|---|---|---|---|---|---|---|---|
| {{$index+1}} | {{field.fieldValue}} | {{row.percentageComplete}}% | {{row.timeElapsed | secondsToDateTime | date:'mm:ss'}} | {{row.device.name}}, {{row.device.type}} | {{row.geoLocation.City}}, {{row.geoLocation.Country}} | {{row.ipAddr}} | {{row.created | date:'yyyy-MM-dd HH:mm:ss'}} |
{{ \'BEFORE_YOU_CONTINUE\' | translate }} polydaic@gmail.com
{{ \'CHECK_YOUR_EMAIL\' | translate }} polydaic@gmail.com
{{pageData.introParagraph}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{myform.startPage.introParagraph}}
{{myform.endPage.paragraph}}
| # | {{value.title}} | {{ 'PERCENTAGE_COMPLETE' | translate }} | {{ 'TIME_ELAPSED' | translate }} | {{ 'DEVICE' | translate }} | {{ 'LOCATION' | translate }} | {{ 'IP_ADDRESS' | translate }} | {{ 'DATE_SUBMITTED' | translate }} (UTC) | |
|---|---|---|---|---|---|---|---|---|
| {{$index+1}} | {{field.fieldValue}} | {{row.percentageComplete}}% | {{row.timeElapsed | secondsToDateTime | date:'mm:ss'}} | {{row.device.name}}, {{row.device.type}} | {{row.geoLocation.City}}, {{row.geoLocation.Country}} | {{row.ipAddr}} | {{row.created | date:'yyyy-MM-dd HH:mm:ss'}} |
{{ \'BEFORE_YOU_CONTINUE\' | translate }} polydaic@gmail.com
{{ \'CHECK_YOUR_EMAIL\' | translate }} polydaic@gmail.com
{{pageData.introParagraph}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{myform.startPage.introParagraph}}
{{myform.endPage.paragraph}}
{{pageData.introParagraph}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
{{field.description}}
p&&a>v},a.noIncrementMinutes=function(){var a=n(p,t);return a>v||a
p&&a>v},a.noToggleMeridian=function(){return p.getHours()<13?n(p,720)>v:n(p,-720)0};b.bind("mousewheel wheel",function(b){a.$apply(d(b)?a.incrementHours():a.decrementHours()),b.preventDefault()}),c.bind("mousewheel wheel",function(b){a.$apply(d(b)?a.incrementMinutes():a.decrementMinutes()),b.preventDefault()})},this.setupArrowkeyEvents=function(b,c){b.bind("keydown",function(b){38===b.which?(b.preventDefault(),a.incrementHours(),a.$apply()):40===b.which&&(b.preventDefault(),a.decrementHours(),a.$apply())}),c.bind("keydown",function(b){38===b.which?(b.preventDefault(),a.incrementMinutes(),a.$apply()):40===b.which&&(b.preventDefault(),a.decrementMinutes(),a.$apply())})},this.setupInputEvents=function(b,c){if(a.readonlyInput)return a.updateHours=angular.noop,void(a.updateMinutes=angular.noop);var d=function(b,c){q.$setViewValue(null),q.$setValidity("time",!1),angular.isDefined(b)&&(a.invalidHours=b),angular.isDefined(c)&&(a.invalidMinutes=c)};a.updateHours=function(){var a=h(),b=i();angular.isDefined(a)&&angular.isDefined(b)?(p.setHours(a),pv?d(!0):k("h")):d(!0)},b.bind("blur",function(b){!a.invalidHours&&a.hours<10&&a.$apply(function(){a.hours=j(a.hours)})}),a.updateMinutes=function(){var a=i(),b=h();angular.isDefined(a)&&angular.isDefined(b)?(p.setMinutes(a),pv?d(void 0,!0):k("m")):d(void 0,!0)},c.bind("blur",function(b){!a.invalidMinutes&&a.minutes<10&&a.$apply(function(){a.minutes=j(a.minutes)})})},this.render=function(){var b=q.$viewValue;isNaN(b)?(q.$setValidity("time",!1),e.error('Timepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.')):(b&&(p=b),pv?(q.$setValidity("time",!1),a.invalidHours=!0,a.invalidMinutes=!0):l(),m())},a.showSpinners=angular.isDefined(c.showSpinners)?a.$parent.$eval(c.showSpinners):g.showSpinners,a.incrementHours=function(){a.noIncrementHours()||o(60*s)},a.decrementHours=function(){a.noDecrementHours()||o(60*-s)},a.incrementMinutes=function(){a.noIncrementMinutes()||o(t)},a.decrementMinutes=function(){a.noDecrementMinutes()||o(-t)},a.toggleMeridian=function(){a.noToggleMeridian()||o(720*(p.getHours()<12?1:-1))}}]).directive("uibTimepicker",function(){return{restrict:"EA",require:["uibTimepicker","?^ngModel"],controller:"UibTimepickerController",controllerAs:"timepicker",replace:!0,scope:{},templateUrl:function(a,b){return b.templateUrl||"template/timepicker/timepicker.html"},link:function(a,b,c,d){var e=d[0],f=d[1];f&&e.init(f,b.find("input"))}}}),angular.module("ui.bootstrap.timepicker").value("$timepickerSuppressWarning",!1).controller("TimepickerController",["$scope","$element","$attrs","$controller","$log","$timepickerSuppressWarning",function(a,b,c,d,e,f){f||e.warn("TimepickerController is now deprecated. Use UibTimepickerController instead."),angular.extend(this,d("UibTimepickerController",{$scope:a,$element:b,$attrs:c}))}]).directive("timepicker",["$log","$timepickerSuppressWarning",function(a,b){return{restrict:"EA",require:["timepicker","?^ngModel"],controller:"TimepickerController",controllerAs:"timepicker",replace:!0,scope:{},templateUrl:function(a,b){return b.templateUrl||"template/timepicker/timepicker.html"},link:function(c,d,e,f){b||a.warn("timepicker is now deprecated. Use uib-timepicker instead.");var g=f[0],h=f[1];h&&g.init(h,d.find("input"))}}}]),angular.module("ui.bootstrap.typeahead",["ui.bootstrap.position"]).factory("uibTypeaheadParser",["$parse",function(a){var b=/^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+([\s\S]+?)$/;return{parse:function(c){var d=c.match(b);if(!d)throw new Error('Expected typeahead specification in form of "_modelValue_ (as _label_)? for _item_ in _collection_" but got "'+c+'".');return{itemName:d[3],source:a(d[4]),viewMapper:a(d[2]||d[1]),modelMapper:a(d[1])}}}}]).controller("UibTypeaheadController",["$scope","$element","$attrs","$compile","$parse","$q","$timeout","$document","$window","$rootScope","$uibPosition","uibTypeaheadParser",function(a,b,c,d,e,f,g,h,i,j,k,l){function m(){K.moveInProgress||(K.moveInProgress=!0,K.$digest()),S&&g.cancel(S),S=g(function(){K.matches.length&&n(),K.moveInProgress=!1},r)}function n(){K.position=C?k.offset(b):k.position(b),K.position.top+=b.prop("offsetHeight")}var o,p,q=[9,13,27,38,40],r=200,s=a.$eval(c.typeaheadMinLength);s||0===s||(s=1);var t,u,v=a.$eval(c.typeaheadWaitMs)||0,w=a.$eval(c.typeaheadEditable)!==!1,x=e(c.typeaheadLoading).assign||angular.noop,y=e(c.typeaheadOnSelect),z=!!angular.isDefined(c.typeaheadSelectOnBlur)&&a.$eval(c.typeaheadSelectOnBlur),A=e(c.typeaheadNoResults).assign||angular.noop,B=c.typeaheadInputFormatter?e(c.typeaheadInputFormatter):void 0,C=!!c.typeaheadAppendToBody&&a.$eval(c.typeaheadAppendToBody),D=c.typeaheadAppendToElementId||!1,E=a.$eval(c.typeaheadFocusFirst)!==!1,F=!!c.typeaheadSelectOnExact&&a.$eval(c.typeaheadSelectOnExact),G=e(c.ngModel),H=e(c.ngModel+"($$$p)"),I=function(b,c){return angular.isFunction(G(a))&&p&&p.$options&&p.$options.getterSetter?H(b,{$$$p:c}):G.assign(b,c)},J=l.parse(c.uibTypeahead),K=a.$new(),L=a.$on("$destroy",function(){K.$destroy()});K.$on("$destroy",L);var M="typeahead-"+K.$id+"-"+Math.floor(1e4*Math.random());b.attr({"aria-autocomplete":"list","aria-expanded":!1,"aria-owns":M});var N=angular.element("");N.attr({id:M,matches:"matches",active:"activeIdx",select:"select(activeIdx)","move-in-progress":"moveInProgress",query:"query",position:"position"}),angular.isDefined(c.typeaheadTemplateUrl)&&N.attr("template-url",c.typeaheadTemplateUrl),angular.isDefined(c.typeaheadPopupTemplateUrl)&&N.attr("popup-template-url",c.typeaheadPopupTemplateUrl);var O=function(){K.matches=[],K.activeIdx=-1,b.attr("aria-expanded",!1)},P=function(a){return M+"-option-"+a};K.$watch("activeIdx",function(a){a<0?b.removeAttr("aria-activedescendant"):b.attr("aria-activedescendant",P(a))});var Q=function(a,b){return!!(K.matches.length>b&&a)&&a.toUpperCase()===K.matches[b].label.toUpperCase()},R=function(c){var d={$viewValue:c};x(a,!0),A(a,!1),f.when(J.source(a,d)).then(function(e){var f=c===o.$viewValue;if(f&&t)if(e&&e.length>0){K.activeIdx=E?0:-1,A(a,!1),K.matches.length=0;for(var g=0;g\n {{heading}}\n
\n \n
\n\n \n
\n')}]),angular.module("template/datepicker/month.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/month.html",'\n \n \n \n \n \n \n \n \n \n {{::label.abbr}} \n \n \n \n{{ weekNumbers[$index] }} \n \n \n \n \n \n
\n')}]),angular.module("template/datepicker/popup.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/popup.html",'\n')}]),angular.module("template/datepicker/year.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/year.html",'\n \n \n \n \n \n \n \n \n \n\n \n \n \n \n
\n')}]),angular.module("template/modal/backdrop.html",[]).run(["$templateCache",function(a){a.put("template/modal/backdrop.html",'\n')}]),angular.module("template/modal/window.html",[]).run(["$templateCache",function(a){a.put("template/modal/window.html",'\n \n \n \n \n \n \n \n \n \n\n \n \n \n
\n')}]),angular.module("template/tooltip/tooltip-html-popup.html",[]).run(["$templateCache",function(a){a.put("template/tooltip/tooltip-html-popup.html",'\n \n
\n')}]),angular.module("template/typeahead/typeahead-match.html",[]).run(["$templateCache",function(a){a.put("template/typeahead/typeahead-match.html",'\n')}]),angular.module("template/typeahead/typeahead-popup.html",[]).run(["$templateCache",function(a){a.put("template/typeahead/typeahead-popup.html",'\n')}]),!angular.$$csp()&&angular.element(document).find("head").prepend(''),!function(a,b){"function"==typeof define&&define.amd?define([],function(){return b()}):"object"==typeof exports?module.exports=b():b()}(this,function(){function a(a){var b=a.storageKey(),c=a.storage(),d=function(){var d=a.preferredLanguage();angular.isString(d)?a.use(d):c.put(b,a.use())};d.displayName="fallbackFromIncorrectStorageValue",c?c.get(b)?a.use(c.get(b))["catch"](d):d():angular.isString(a.preferredLanguage())&&a.use(a.preferredLanguage())}function b(){var a,b,c=null,d=!1,e=!1;b={sanitize:function(a,b){return"text"===b&&(a=g(a)),a},escape:function(a,b){return"text"===b&&(a=f(a)),a},sanitizeParameters:function(a,b){return"params"===b&&(a=h(a,g)),a},escapeParameters:function(a,b){return"params"===b&&(a=h(a,f)),a}},b.escaped=b.escapeParameters,this.addStrategy=function(a,c){return b[a]=c,this},this.removeStrategy=function(a){return delete b[a],this},this.useStrategy=function(a){return d=!0,c=a,this},this.$get=["$injector","$log",function(f,g){var h={},i=function(a,c,d){return angular.forEach(d,function(d){if(angular.isFunction(d))a=d(a,c);else if(angular.isFunction(b[d]))a=b[d](a,c);else{if(!angular.isString(b[d]))throw new Error("pascalprecht.translate.$translateSanitization: Unknown sanitization strategy: '"+d+"'");if(!h[b[d]])try{h[b[d]]=f.get(b[d])}catch(e){throw h[b[d]]=function(){},new Error("pascalprecht.translate.$translateSanitization: Unknown sanitization strategy: '"+d+"'")}a=h[b[d]](a,c)}}),a},j=function(){d||e||(g.warn("pascalprecht.translate.$translateSanitization: No sanitization strategy has been configured. This can have serious security implications. See http://angular-translate.github.io/docs/#/guide/19_security for details."),e=!0)};return f.has("$sanitize")&&(a=f.get("$sanitize")),{useStrategy:function(a){return function(b){a.useStrategy(b)}}(this),sanitize:function(a,b,d){if(c||j(),arguments.length<3&&(d=c),!d)return a;var e=angular.isArray(d)?d:[d];return i(a,b,e)}}}];var f=function(a){var b=angular.element("");return b.text(a),b.html()},g=function(b){if(!a)throw new Error("pascalprecht.translate.$translateSanitization: Error cannot find $sanitize service. Either include the ngSanitize module (https://docs.angularjs.org/api/ngSanitize) or use a sanitization strategy which does not depend on $sanitize, such as 'escape'.");return a(b)},h=function(a,b,c){if(angular.isObject(a)){var d=angular.isArray(a)?[]:{};if(c){if(c.indexOf(a)>-1)throw new Error("pascalprecht.translate.$translateSanitization: Error cannot interpolate parameter due recursive object")}else c=[];return c.push(a),angular.forEach(a,function(a,e){angular.isFunction(a)||(d[e]=h(a,b,c))}),c.splice(-1,1),d}return angular.isNumber(a)?a:b(a)}}function c(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u={},v=[],w=a,x=[],y="translate-cloak",z=!1,A=!1,B=".",C=!1,D=!1,E=0,F=!0,G="default",H={"default":function(a){return(a||"").split("-").join("_")},java:function(a){var b=(a||"").split("-").join("_"),c=b.split("_");return c.length>1?c[0].toLowerCase()+"_"+c[1].toUpperCase():b},bcp47:function(a){var b=(a||"").split("_").join("-"),c=b.split("-");return c.length>1?c[0].toLowerCase()+"-"+c[1].toUpperCase():b},"iso639-1":function(a){var b=(a||"").split("_").join("-"),c=b.split("-");return c[0].toLowerCase()}},I="2.11.1",J=function(){if(angular.isFunction(d.getLocale))return d.getLocale();var a,c,e=b.$get().navigator,f=["language","browserLanguage","systemLanguage","userLanguage"];if(angular.isArray(e.languages))for(a=0;a\n \n \n \n \n \n \n \n \n \n \n : \n \n \n \n \n \n \n \n\n \n \n \n ").attr("src",b).css("visibility","hidden").css("position","fixed").css("max-width","none !important").css("max-height","none !important");h.on("load",d),h.on("error",f);var i=0;g(),angular.element(document.getElementsByTagName("body")[0]).append(h)},function(){e.reject("load error")})}),a.$ngfDimensionPromise=e.promise,a.$ngfDimensionPromise["finally"](function(){delete a.$ngfDimensionPromise}),a.$ngfDimensionPromise},f.mediaDuration=function(a){if(a.$ngfDuration){var d=b.defer();return c(function(){d.resolve(a.$ngfDuration)}),d.promise}if(a.$ngfDurationPromise)return a.$ngfDurationPromise;var e=b.defer();return c(function(){return 0!==a.type.indexOf("audio")&&0!==a.type.indexOf("video")?void e.reject("not media"):void f.dataUrl(a).then(function(b){function d(){var b=h[0].duration;a.$ngfDuration=b,h.remove(),e.resolve(b)}function f(){h.remove(),e.reject("load error")}function g(){c(function(){h[0].parentNode&&(h[0].duration?d():i>10?f():g())},1e3)}var h=angular.element(0===a.type.indexOf("audio")?"