UNPKG

3.77 kBPlain TextView Raw
1#!/usr/bin/env node
2
3/*
4 * Run all analytics reports output JSON to disk.
5 *
6 * Usage: analytics
7 *
8 * Defaults to printing JSON to STDOUT.
9 *
10 * --output: Output to a directory.
11 * --publish: Publish to an S3 bucket.
12 * --only: only run one report.
13 * --slim: Where supported, use totals only (omit the `data` array).
14 * Only applies to JSON, and reports where "slim": true.
15 * --csv: CSV instead of JSON.
16 * --frequency: Limit to reports with this 'frequency' value.
17 * --debug: print debug details on STDOUT
18 */
19
20var Analytics = require("../analytics"),
21 config = require("../config"),
22 fs = require("fs"),
23 path = require('path'),
24 async = require("async")
25 csv = require("fast-csv");
26
27
28// AWS credentials are looked for in env vars or in ~/.aws/config.
29// AWS bucket and path need to be set in env vars mentioned in config.js.
30
31var AWS = require("aws-sdk");
32
33var publish = function(name, data, extension, options, callback) {
34 if (options.debug) console.log("[" + name + "] Publishing to " + config.aws.bucket + "...");
35
36 var mime = {".json": "application/json", ".csv": "text/csv"};
37
38 new AWS.S3({params: {Bucket: config.aws.bucket}}).upload({
39 Key: config.aws.path + "/" + name + extension,
40 Body: data,
41 ContentType: mime[extension],
42 ACL: "public-read",
43 CacheControl: "max-age=" + (config.aws.cache || 0)
44 }, callback);
45};
46
47
48var run = function(options) {
49 if (!options) options = {};
50 if (options.debug) options.verbose = options.debug;
51 if (options.verbose) options.debug = options.verbose;
52
53 // can be overridden to only do one report
54 var names;
55 if (options.only)
56 names = [options.only];
57 else if (options.frequency) {
58 names = [];
59 var all = Object.keys(Analytics.reports);
60 for (var i=0; i<all.length; i++) {
61 if (Analytics.reports[all[i]].frequency == options.frequency)
62 names.push(all[i]);
63 }
64 }
65
66 else
67 names = Object.keys(Analytics.reports);
68
69 var eachReport = function(name, done) {
70 var report = Analytics.reports[name];
71
72 if (options.debug) console.log("\n[" + report.name + "] Fetching...");
73 Analytics.query(report, function(err, data) {
74 if (err) return console.log("ERROR AFTER QUERYING: " + err);
75
76 if (options.debug) console.log("[" + report.name + "] Saving report data...");
77
78 // CSV, see https://github.com/C2FO/fast-csv#formatting-functions
79 if (options.csv) {
80 csv.writeToString(data['data'], {headers: true}, function(err, data) {
81 if (err) return console.log("ERROR AFTER CSV: " + JSON.stringify(err));
82
83 writeReport(name, data, ".csv", done);
84 });
85 }
86
87 // JSON
88 else {
89 // some reports can be slimmed down for direct rendering
90 if (options.slim && report.slim) delete data.data;
91
92 writeReport(name, JSON.stringify(data, null, 2), ".json", done);
93 }
94 });
95 };
96
97 var writeReport = function(name, output, extension, done) {
98 var written = function(err) {
99 if (err)
100 console.error("ERROR AFTER WRITING: " + JSON.stringify(err));
101 else if (options.debug)
102 console.log("[" + name + "] Done.");
103 done();
104 };
105
106 if (options.publish)
107 publish(name, output, extension, options, written);
108
109 else if (options.output && (typeof(options.output) == "string"))
110 fs.writeFile(path.join(options.output, (name + extension)), output, written);
111
112 else {
113 // could be split on \n\n
114 console.log(output + "\n");
115 written();
116 }
117 };
118
119 async.eachSeries(names, eachReport, function(err) {
120 if (err) {
121 console.error(err);
122 process.exit(1);
123 }
124
125 if (options.debug) console.log("All done.");
126 });
127};
128
129run(require('minimist')(process.argv.slice(2)));