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 |
|
20 | var 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 |
|
31 | var AWS = require("aws-sdk");
|
32 |
|
33 | var 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 |
|
48 | var 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 |
|
129 | run(require('minimist')(process.argv.slice(2)));
|