const logger = require('winston'); const ua = require('universal-analytics'); const config = require('config'); const db = require('../models'); const googleApiKey = config.get('AnalyticsConfig.GoogleId'); module.exports = { postToStats (action, url, ipAddress, name, claimId, fileName, fileType, nsfw, result) { logger.silly(`creating ${action} record for statistics db`); // make sure the result is a string if (result && (typeof result !== 'string')) { result = result.toString(); } // // make sure the ip address(es) are a string if (ipAddress && (typeof ipAddress !== 'string')) { ipAddress = ipAddress.toString(); } // create record in the db db.Stats.create({ action, url, ipAddress, name, claimId, fileName, fileType, nsfw, result, }) .then() .catch(error => { logger.error('sequelize error', error); }); }, sendGoogleAnalytics (action, headers, ip, originalUrl) { const visitorId = ip.replace(/\./g, '-'); const visitor = ua(googleApiKey, visitorId, { strictCidFormat: false, https: true }); let params; switch (action) { case 'serve': params = { ec : 'serve', ea : originalUrl, uip: ip, ua : headers['user-agent'], ul : headers['accept-language'], }; break; case 'publish': params = { ec : 'publish', ea : originalUrl, uip: ip, ua : headers['user-agent'], ul : headers['accept-language'], }; break; default: break; } visitor.event(params, (err) => { if (err) { logger.error('Google Analytics Event Error >>', err); } }); }, getStatsSummary (startDate) { logger.debug('retrieving statistics'); const deferred = new Promise((resolve, reject) => { // get the raw statistics data db.Stats .findAll({ where: { createdAt: { gt: startDate, }, }, }) .then(data => { let resultHashTable = {}; let totalServe = 0; let totalPublish = 0; let totalShow = 0; let totalCount = 0; let totalSuccess = 0; let totalFailure = 0; let percentSuccess; // sumarise the data for (let i = 0; i < data.length; i++) { let key = data[i].action + data[i].url; totalCount += 1; switch (data[i].action) { case 'serve': totalServe += 1; break; case 'publish': totalPublish += 1; break; case 'show': totalShow += 1; break; default: break; } if (resultHashTable[key]) { resultHashTable[key]['count'] += 1; if (data[i].result === 'success') { resultHashTable[key]['success'] += 1; totalSuccess += 1; } else { resultHashTable[key]['failure'] += 1; totalFailure += 1; } } else { resultHashTable[key] = { action : data[i].action, url : data[i].url, count : 1, success: 0, failure: 0, }; if (data[i].result === 'success') { resultHashTable[key]['success'] += 1; totalSuccess += 1; } else { resultHashTable[key]['failure'] += 1; totalFailure += 1; } } } percentSuccess = Math.round(totalSuccess / totalCount * 100); // return results resolve({ records: resultHashTable, totals: { totalServe, totalPublish, totalShow, totalCount, totalSuccess, totalFailure }, percentSuccess }); }) .catch(error => { logger.error('sequelize error', error); reject(error); }); }); return deferred; }, getTrendingClaims (startDate) { logger.debug('retrieving trending statistics'); const deferred = new Promise((resolve, reject) => { // get the raw statistics data db.Stats .findAll({ where: { createdAt: { gt: startDate, }, name: { not: null, }, claimId: { not: null, }, }, }) .then(data => { let resultHashTable = {}; let sortableArray = []; let sortedArray; // summarise the data for (let i = 0; i < data.length; i++) { let key = `${data[i].name}#${data[i].claimId}`; if (resultHashTable[key] === undefined) { resultHashTable[key] = { count : 0, details: { name : data[i].name, claimId : data[i].claimId, fileName: data[i].fileName, fileType: data[i].fileType, nsfw : data[i].nsfw, }, }; } else { resultHashTable[key]['count'] += 1; } } for (let objKey in resultHashTable) { if (resultHashTable.hasOwnProperty(objKey)) { sortableArray.push([ resultHashTable[objKey]['count'], resultHashTable[objKey]['details'], ]); } } sortableArray.sort((a, b) => { return b[0] - a[0]; }); sortedArray = sortableArray.map((a) => { return a[1]; }); // return results resolve(sortedArray); }) .catch(error => { logger.error('sequelize error', error); reject(error); }); }); return deferred; }, };