fixed analytics geolocation

This commit is contained in:
David Baldwynn 2017-03-06 13:45:11 -08:00
parent 00054c9440
commit 8a12f4d65c
No known key found for this signature in database
GPG key ID: 15D1C13202224A9B
14 changed files with 194 additions and 322 deletions

View file

@ -54,26 +54,19 @@ exports.createSubmission = function(req, res) {
timeElapsed = req.body.timeElapsed;
}
var submission = new FormSubmission({
admin: req.form.admin._id,
form: req.form._id,
title: req.form.title,
admin: form.admin._id,
form: form._id,
title: form.title,
form_fields: req.body.form_fields,
timeElapsed: timeElapsed,
percentageComplete: req.body.percentageComplete
percentageComplete: req.body.percentageComplete,
ipAddr: req.body.ipAddr,
geoLocation: req.body.geoLocation,
device: req.body.device
});
//Save submitter's IP Address
if(req.headers['x-forwarded-for'] || req.connection.remoteAddress){
var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
if(ip && process.env.NODE_ENV !== 'development') submission.ipAddr = ip;
}
if (req.device) {
submission.device = req.device;
}
submission.save(function(err, submission){
if (err) {
console.error(err.message);
return res.status(500).send({
@ -185,6 +178,7 @@ exports.readForRender = function(req, res) {
delete newForm.submissions;
delete newForm.analytics;
delete newForm.isLive;
delete newForm.admin;
return res.json(newForm);
};
@ -234,7 +228,6 @@ exports.update = function(req, res) {
*/
exports.delete = function(req, res) {
var form = req.form;
// console.log('deleting form');
Form.remove({_id: form._id}, function(err) {
if (err) {
res.status(400).send({

View file

@ -234,8 +234,8 @@ FormSchema.virtual('analytics.fields').get(function () {
var totalViews = dropoffViews+continueViews;
var responses = continueViews;
var continueRate = continueViews/totalViews*100;
var dropoffRate = dropoffViews/totalViews*100;
var continueRate = (continueViews/totalViews*100).toFixed(0);
var dropoffRate = (dropoffViews/totalViews*100).toFixed(0);
fieldDropoffs[i] = {
dropoffViews: dropoffViews,

View file

@ -5,7 +5,6 @@
*/
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
freegeoip = require('node-freegeoip'),
_ = require('lodash'),
config = require('../../config/config'),
path = require('path'),
@ -53,9 +52,6 @@ var FormSubmissionSchema = new Schema({
Country: {
type: String
},
Region: {
type: String
},
City: {
type: String
}
@ -69,29 +65,11 @@ var FormSubmissionSchema = new Schema({
}
},
pdfFilePath: {
type: Schema.Types.Mixed
},
pdf: {
type: Schema.Types.Mixed
},
fdfData: {
type: Schema.Types.Mixed
},
timeElapsed: {
type: Number
},
percentageComplete: {
type: Number
},
hasPlugins: {
oscarhost: {
type: Boolean,
default: false
}
}
});
@ -112,19 +90,4 @@ FormSubmissionSchema.plugin(mUtilities.timestamp, {
useVirtual: false
});
//Check for IP Address of submitting person
FormSubmissionSchema.pre('save', function (next) {
var self = this;
if (this.ipAddr) {
if (this.isModified('ipAddr') || !this.geoLocation) {
freegeoip.getLocation(this.ipAddr, function (err, location) {
if (err) return next(err);
self.geoLocation = location;
return next();
});
}
}
return next();
});
module.exports = FormSubmissionSchema;

10
config/env/test.js vendored
View file

@ -56,15 +56,5 @@ module.exports = {
pass: process.env.MAILER_PASSWORD || ''
}
}
},
oscarhost: {
baseUrl: process.env.OSCARHOST_BASEURL || 'OSCARHOST_BASEURL',
settings: {
updateType: process.env.OSCARHOST_UPDATETYPE || 'OSCARHOST_UPDATETYPE',
},
auth:{
user: process.env.OSCARHOST_USER || 'process.env.OSCARHOST_USER',
pass: process.env.OSCARHOST_PASS || 'process.env.OSCARHOST_PASS',
}
}
};

View file

@ -74,7 +74,6 @@
"mongoose-utilities": "~0.1.1",
"morgan": "~1.6.1",
"multer": "~1.1.0",
"node-freegeoip": "0.0.1",
"nodemailer": "~1.10.0",
"nodemailer-sendgrid-transport": "^0.2.0",
"nodemailer-sparkpost-transport": "^1.0.0",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -260,8 +260,6 @@ angular.module('view-form').directive('submitFormDirective', ['$http', 'TimeCoun
});
}
console.log("time elapsed: ");
console.log(TimeCounter.getTimeElapsed());
SendVisitorData.send($scope.myform, getActiveField(), TimeCounter.getTimeElapsed());
};
@ -310,6 +308,39 @@ angular.module('view-form').directive('submitFormDirective', ['$http', 'TimeCoun
document.querySelectorAll('.ng-invalid.focusOn')[0].focus();
};
var getDeviceData = function(){
var md = new MobileDetect(window.navigator.userAgent);
var deviceType = 'other';
if (md.tablet()){
deviceType = 'tablet';
} else if (md.mobile()) {
deviceType = 'mobile';
} else if (!md.is('bot')) {
deviceType = 'desktop';
}
return {
type: deviceType,
name: window.navigator.platform
}
};
var getIpAndGeo = function(){
//Get Ip Address and GeoLocation Data
$.ajaxSetup( { "async": false } );
var geoData = $.getJSON('//freegeoip.net/json/').responseJSON;
$.ajaxSetup( { "async": true } );
return {
ipAddr: geoData.ip,
geoLocation: {
City: geoData.city,
Country: geoData.country_name
}
}
};
$rootScope.submitForm = $scope.submitForm = function() {
var _timeElapsed = TimeCounter.stopClock();
@ -317,8 +348,15 @@ angular.module('view-form').directive('submitFormDirective', ['$http', 'TimeCoun
var form = _.cloneDeep($scope.myform);
form.timeElapsed = _timeElapsed;
var deviceData = getDeviceData();
form.device = deviceData;
var geoData = getIpAndGeo();
form.ipAddr = geoData.ipAddr;
form.geoLocation = geoData.geoLocation;
console.log(geoData);
form.timeElapsed = _timeElapsed;
form.percentageComplete = $filter('formValidity')($scope.myform) / $scope.myform.visible_form_fields.length * 100;
delete form.visible_form_fields;
@ -331,7 +369,6 @@ angular.module('view-form').directive('submitFormDirective', ['$http', 'TimeCoun
setTimeout(function () {
$scope.submitPromise = $http.post('/forms/' + $scope.myform._id, form)
.success(function (data, status, headers) {
console.log($scope.myform.form_fields[0]);
$scope.myform.submitted = true;
$scope.loading = false;
SendVisitorData.send($scope.myform, getActiveField(), _timeElapsed);

View file

@ -41,7 +41,11 @@
timeElapsed: timeElapsed,
language: lang,
deviceType: deviceType,
ipAddr: geoData.ip
ipAddr: geoData.ip,
geoLocation: {
city: geoData.city,
country: geoData.country_name
}
};
Socket.emit('form-visitor-data', visitorData);
}

View file

@ -12,82 +12,12 @@ angular.module('forms').directive('configureFormDirective', ['$rootScope', '$htt
formFields:'@'
},
controller: function($scope){
console.log($scope.myform);
if( CurrentForm.getForm().plugins){
if(CurrentForm.getForm().plugins.oscarhost.baseUrl) $scope.oscarhostAPI = true;
}else{
$scope.oscarhostAPI = false;
}
$scope.log = '';
$scope.pdfLoading = false;
$scope.languages = $rootScope.languages;
this._current_upload = null;
$scope.resetForm = $rootScope.resetForm;
$scope.update = $rootScope.update;
this._unbindedPdfFields = $scope.pdfFields;
//DAVID: TODO: finish this so we can create a Form.pdfFieldMap
// $scope.getUnbindedPdfFields = function(fieldType){
// this._unbindedPdfFields = $scope.pdfFields
// }
//PDF Functions
$scope.cancelUpload = function(){
this._current_upload.abort();
$scope.pdfLoading = false;
$scope.removePDF();
};
$scope.removePDF = function(){
$scope.myform.pdf = null;
$scope.myform.isGenerated = false;
$scope.myform.autofillPDFs = false;
console.log('form.pdf: '+$scope.myform.pdf+' REMOVED');
};
$scope.uploadPDF = function(file) {
if (file) {
console.log(file);
Upload.upload({
url: '/upload/pdf',
data: {
'user': $scope.user,
file: file
}
}).then(function (resp) {
var data = resp.data;
$scope.log = 'file ' + data.originalname + ' uploaded as ' + data.filename + '. JSON: ' + JSON.stringify(data) + '\n' + $scope.log;
$scope.myform.pdf = angular.fromJson(angular.toJson(data));
//console.log($scope.myform.pdf);
$scope.pdfLoading = false;
console.log($scope.log);
if (!$scope.$$phase && !$scope.$digest) {
$scope.$apply();
}
}, function(resp){
$scope.pdfLoading = false;
console.log('Error occured during upload.\n');
console.log(resp.status);
}, function (evt) {
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total, 10);
$scope.log = 'progress: ' + progressPercentage + '% ' +
evt.config.data.file.name + '\n' + $scope.log;
console.log($scope.log);
$scope.pdfLoading = true;
});
}
};
}
};
}

View file

@ -39,7 +39,7 @@ angular.module('forms').directive('editSubmissionsFormDirective', ['$rootScope',
}
$scope.table.rows = submissions;
console.log(submissions);
/*
** Analytics Functions
@ -55,7 +55,7 @@ angular.module('forms').directive('editSubmissionsFormDirective', ['$rootScope',
if(numSubmissions == 0) return 0;
return totalTime/numSubmissions;
return (totalTime/numSubmissions).toFixed(0);
})();
$scope.DeviceStatistics = (function(){
@ -86,12 +86,12 @@ angular.module('forms').directive('editSubmissionsFormDirective', ['$rootScope',
stats[deviceType].total_time = stats[deviceType].total_time + visitor.timeElapsed;
stats[deviceType].average_time = stats[deviceType].total_time / stats[deviceType].visits;
stats[deviceType].average_time = (stats[deviceType].total_time / stats[deviceType].visits).toFixed(0);
if(!stats[deviceType].average_time) stats[deviceType].average_time = 0;
if (visitor.isSubmitted) stats[deviceType].responses++;
stats[deviceType].completion = stats[deviceType].responses / stats[deviceType].visits;
stats[deviceType].completion = (stats[deviceType].responses / stats[deviceType].visits).toFixed(0);
if(!stats[deviceType].completion) stats[deviceType].completion = 0;
}
console.log("stats");
@ -139,7 +139,7 @@ angular.module('forms').directive('editSubmissionsFormDirective', ['$rootScope',
/*
* Form Submission Methods
*/
//Delete selected submissions of Form
$scope.deleteSelectedSubmissions = function(){

View file

@ -134,7 +134,7 @@
{{ 'COMPLETION_RATE' | translate }}
</div>
<div class="row">
{{DeviceStatistics.desktop.completion}}
{{DeviceStatistics.desktop.completion}}%
</div>
</div>
@ -143,7 +143,7 @@
{{ 'COMPLETION_RATE' | translate }}
</div>
<div class="row">
{{DeviceStatistics.tablet.completion}}
{{DeviceStatistics.tablet.completion}}%
</div>
</div>
@ -152,7 +152,7 @@
{{ 'COMPLETION_RATE' | translate }}
</div>
<div class="row">
{{DeviceStatistics.phone.completion}}
{{DeviceStatistics.phone.completion}}%
</div>
</div>
@ -161,7 +161,7 @@
{{ 'COMPLETION_RATE' | translate }}
</div>
<div class="row">
{{DeviceStatistics.other.completion}}
{{DeviceStatistics.other.completion}}%
</div>
</div>
</div>
@ -245,17 +245,17 @@
</button>
</div>
<div class="col-xs-2 col-xs-offset-4 text-right">
<button class="btn btn-default" ng-click="exportSubmissions('xml')">
<button class="btn btn-gray" ng-click="exportSubmissions('xml')">
<small>{{ 'EXPORT_TO_EXCEL' | translate }}</small>
</button>
</div>
<div class="col-md-2 text-right">
<button class="btn btn-default" ng-click="exportSubmissions('csv')">
<button class="btn btn-gray" ng-click="exportSubmissions('csv')">
<small>{{ 'EXPORT_TO_CSV' | translate }}</small>
</button>
</div>
<div class="col-md-2 text-right">
<button class="btn btn-default" ng-click="exportSubmissions('json')">
<button class="btn btn-gray" ng-click="exportSubmissions('json')">
<small>{{ 'EXPORT_TO_JSON' | translate }}</small>
</button>
</div>
@ -290,9 +290,6 @@
<th>
{{ 'DATE_SUBMITTED' | translate }} (UTC)
</th>
<th ng-if="myform.autofillPDFs">
{{ 'GENERATED_PDF' | translate }}
</th>
</tr>
</thead>
@ -318,7 +315,7 @@
{{row.device.name}}, {{row.device.type}}
</td>
<td>
{{row.geoLocation.city}}, {{row.geoLocation.country_name}}
{{row.geoLocation.City}}, {{row.geoLocation.Country}}
</td>
<td>
{{row.ipAddr}}
@ -326,9 +323,6 @@
<td>
{{row.created | date:'yyyy-MM-dd HH:mm:ss'}}
</td>
<td ng-if="row.pdf">
<a href="{{row.pdfFilePath}}" download="{{row.pdf.name}}" target="_self">{{ 'GENERATED_PDF' | translate }}</a>
</td>
</tr>
</tbody>
</table>