116 lines
3.6 KiB
JavaScript
116 lines
3.6 KiB
JavaScript
const fs = require('fs');
|
|
|
|
// We can either use a process-wide object regularly saved to a JSON file,
|
|
// or a Redis equivalent (for multi-process / when the filesystem is unreliable.
|
|
var redis;
|
|
var useRedis = false;
|
|
if (process.env.REDISTOGO_URL) {
|
|
var redisToGo = require('url').parse(process.env.REDISTOGO_URL);
|
|
redis = require('redis').createClient(redisToGo.port, redisToGo.hostname);
|
|
redis.auth(redisToGo.auth.split(':')[1]);
|
|
useRedis = true;
|
|
}
|
|
|
|
var analytics = {};
|
|
|
|
var analyticsAutoSaveFileName = process.env.SHIELDS_ANALYTICS_FILE || './analytics.json';
|
|
var analyticsAutoSavePeriod = 10000;
|
|
setInterval(function analyticsAutoSave() {
|
|
if (useRedis) {
|
|
redis.set(analyticsAutoSaveFileName, JSON.stringify(analytics));
|
|
} else {
|
|
fs.writeFileSync(analyticsAutoSaveFileName, JSON.stringify(analytics));
|
|
}
|
|
}, analyticsAutoSavePeriod);
|
|
|
|
function defaultAnalytics() {
|
|
var analytics = Object.create(null);
|
|
// In case something happens on the 36th.
|
|
analytics.vendorMonthly = new Array(36);
|
|
resetMonthlyAnalytics(analytics.vendorMonthly);
|
|
analytics.rawMonthly = new Array(36);
|
|
resetMonthlyAnalytics(analytics.rawMonthly);
|
|
analytics.vendorFlatMonthly = new Array(36);
|
|
resetMonthlyAnalytics(analytics.vendorFlatMonthly);
|
|
analytics.rawFlatMonthly = new Array(36);
|
|
resetMonthlyAnalytics(analytics.rawFlatMonthly);
|
|
analytics.vendorFlatSquareMonthly = new Array(36);
|
|
resetMonthlyAnalytics(analytics.vendorFlatSquareMonthly);
|
|
analytics.rawFlatSquareMonthly = new Array(36);
|
|
resetMonthlyAnalytics(analytics.rawFlatSquareMonthly);
|
|
return analytics;
|
|
}
|
|
|
|
// Auto-load analytics.
|
|
function analyticsAutoLoad() {
|
|
var defaultAnalyticsObject = defaultAnalytics();
|
|
if (useRedis) {
|
|
redis.get(analyticsAutoSaveFileName, function(err, value) {
|
|
if (err == null && value != null) {
|
|
// if/try/return trick:
|
|
// if error, then the rest of the function is run.
|
|
try {
|
|
analytics = JSON.parse(value);
|
|
// Extend analytics with a new value.
|
|
for (var key in defaultAnalyticsObject) {
|
|
if (!(key in analytics)) {
|
|
analytics[key] = defaultAnalyticsObject[key];
|
|
}
|
|
}
|
|
return;
|
|
} catch(e) {
|
|
console.error('Invalid Redis analytics, resetting.');
|
|
console.error(e);
|
|
}
|
|
}
|
|
analytics = defaultAnalyticsObject;
|
|
});
|
|
} else {
|
|
// Not using Redis.
|
|
try {
|
|
analytics = JSON.parse(fs.readFileSync(analyticsAutoSaveFileName));
|
|
// Extend analytics with a new value.
|
|
for (var key in defaultAnalyticsObject) {
|
|
if (!(key in analytics)) {
|
|
analytics[key] = defaultAnalyticsObject[key];
|
|
}
|
|
}
|
|
} catch(e) {
|
|
if (e.code !== 'ENOENT') {
|
|
console.error('Invalid JSON file for analytics, resetting.');
|
|
console.error(e);
|
|
}
|
|
analytics = defaultAnalyticsObject;
|
|
}
|
|
}
|
|
}
|
|
|
|
var lastDay = (new Date()).getDate();
|
|
function resetMonthlyAnalytics(monthlyAnalytics) {
|
|
for (var i = 0; i < monthlyAnalytics.length; i++) {
|
|
monthlyAnalytics[i] = 0;
|
|
}
|
|
}
|
|
function incrMonthlyAnalytics(monthlyAnalytics) {
|
|
try {
|
|
var currentDay = (new Date()).getDate();
|
|
// If we changed month, reset empty days.
|
|
while (lastDay !== currentDay) {
|
|
// Assumption: at least a hit a month.
|
|
lastDay = (lastDay + 1) % monthlyAnalytics.length;
|
|
monthlyAnalytics[lastDay] = 0;
|
|
}
|
|
monthlyAnalytics[currentDay]++;
|
|
} catch(e) { console.error(e.stack); }
|
|
}
|
|
|
|
function getAnalytics() {
|
|
return analytics;
|
|
}
|
|
|
|
module.exports = {
|
|
analyticsAutoLoad,
|
|
incrMonthlyAnalytics,
|
|
getAnalytics
|
|
};
|