forked from bbc/newslabs-datastringer
/
crime-stringer.js
114 lines (94 loc) · 3.38 KB
/
crime-stringer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//todo: mettre le mois dans le triggerResult
var sync = require('synchronize');
var utils = require('./utils.js');
function stringer(lat, lng, numberOfMonths, threshold, callback) {
sync.fiber(function() {
// get last update date, so that we know where to start from.
var dateJson = sync.await(utils.getTheJSON(
"http://data.police.uk/api/crime-last-updated", sync.defer()));
var currentDate = new Date(JSON.parse(dateJson).date);
var lastUpdateTimeRef = new Date(0);
try {
var refJSON = sync.await(utils.readAsset('crime-stringer-reference/lastUpdate ' +
lat + '-' + lng + '.json', sync.defer()));
lastUpdateTimeRef = new Date(JSON.parse(refJSON));
}
catch(except) {
}
if (currentDate <= lastUpdateTimeRef) {
return;
}
utils.writeAsset('crime-stringer-reference/lastUpdate.json', JSON.stringify(currentDate),
function(err) {
console.log(err);
});
var baseQuery = "http://data.police.uk/api/crimes-street/all-crime?lat=" +
lat + "&lng=" + lng;
// query crime stats for each month
var crimeArray = [];
while (numberOfMonths) {
// build query for current month
var currMonth = currentDate.getMonth() + 1; // months start at 0 ¬_¬
currMonth = currMonth > 9 ? String(currMonth) : '0' + String(currMonth);
var timeQuery = "&date=" + currentDate.getFullYear() + "-" + currMonth;
console.log('police-uk: fetching data for ' + timeQuery);
try {
var data = sync.await(crimeQuery(baseQuery + timeQuery, sync.defer()));
crimeArray.push(data);
} catch (e) {
console.log('caught exception while fetching data for ' + currentDate +
', skipping to next month');
}
currentDate.setMonth(currentDate.getMonth() - 1);
numberOfMonths--;
}
// compute average for each category, over the time range
var categories = Object.keys(crimeArray[0]);
numberOfMonths = crimeArray.length;
var categoryAverages = {};
for (var c = 0; c < categories.length; c++) {
var cat = categories[c];
categoryAverages[cat] = 0;
for (var i = 0; i < crimeArray.length; i++) {
if (cat in crimeArray[i]) {
categoryAverages[cat] += crimeArray[i][cat];
}
}
categoryAverages[cat] /= numberOfMonths;
}
// for each category, compute the diff btw crime amount for last month and
// average.
// callback if > threshold
for (var c = 0; c < categories.length; c++) {
var cat = categories[c];
var categoryDiff = (crimeArray[0][cat] / categoryAverages[cat] * 100) -
100;
if (Math.abs(categoryDiff) > Math.abs(threshold)) {
callback('crime-stringer', cat + ', diff: ' + categoryDiff);
}
}
});
} //stringer
function crimeQuery(path_json, callback) {
utils.getTheJSON(path_json, process);
function process(err, json) {
if (err) {
callback(err);
return;
}
if (!json) {
callback('No JSON could be fetched for ' + path_json);
return;
}
var data = JSON.parse(json);
var monthCrimeStat = {};
for (var i = 0; i < data.length; i++) {
if (!(data[i].category in monthCrimeStat)) {
monthCrimeStat[data[i].category] = 0; // 1st crime seen for this category
}
monthCrimeStat[data[i].category] += 1;
}
callback(undefined, monthCrimeStat);
}
}
module.exports = stringer;