Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: lib/filterHits.js

Issue 6337686776315904: Issue 394 - hit statistics tool data collection (Closed)
Patch Set: Created March 6, 2015, 4:50 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2015 Eyeo GmbH
4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 let {Services} = Cu.import("resource://gre/modules/Services.jsm", null);
19 let {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", null);
20
21 let {Prefs} = require("prefs");
22 let {Utils} = require("utils");
23 let {MILLIS_IN_DAY} = require("downloader");
24 let {FilterNotifier} = require("filterNotifier");
25 let {DownloadableSubscription} = require("subscriptionClasses");
26
27 /**
28 * This class reads filter hits statistics from SQLite database,
29 * manages them in memory and writes them back.
30 * @class
31 */
32 let FilterHits = exports.FilterHits =
33 {
34 /**
35 * Data that shoud be sent to the server
36 * @type Object
37 */
38 filters: Object.create(null),
39
kzar 2015/03/23 13:11:05 Nit: Trailing whitespace
saroyanm 2015/04/07 15:23:09 Done.
40 /**
41 * Time since last push
42 * @type Number
43 */
44 _lastPush: 0,
45
46 /**
47 * Indicates the timeframe between pushes
48 * @type Number
49 */
50 _pushInterval: MILLIS_IN_DAY * 7,
kzar 2015/03/23 13:11:05 I set this to 60000 (number of milliseconds in one
saroyanm 2015/03/24 10:42:40 Yes because we are saving the data to database and
kzar 2015/03/24 10:51:14 If the data submission interval is too variable it
51
52 /**
53 * Indicates whether the data are being loaded from storage
kzar 2015/03/23 13:11:05 Nit: These three comments should start with "Indic
saroyanm 2015/04/07 15:23:09 Done.
54 * @type Boolean
55 */
56 _loading: false,
57
58 /**
59 * Indicates whether the data are being saved to storage
60 * @type Boolean
61 */
62 _saving: false,
63
64 /**
65 * Indicates whether the data are being sent to the server
66 * @type Boolean
67 */
68 _sending: false,
69
70 /**
71 * Increases the filter hit count
72 * @param {Filter} filter
73 * @param {Window} window Window that the match originated in (required to ge t host)
74 */
75 increaseFilterHits: function(filter, wnd)
76 {
77 let subscriptions = filter.subscriptions;
78 let inDownloadableSubscription = false;
79 for (let i = 0; i < subscriptions.length; i++)
80 {
81 if (subscriptions[i] instanceof DownloadableSubscription)
82 {
83 inDownloadableSubscription = true;
84 break;
85 }
86 }
87
88 if (!inDownloadableSubscription)
89 return;
90
91 if (!(filter.text in this.filters))
92 this.filters[filter.text] = Object.create(null);
93
94 let statFilter = this.filters[filter.text];
95 let filterType = filter.thirdParty ? "thirdParty" : "firstParty";
96
97 if (!(filterType in statFilter))
98 statFilter[filterType] = Object.create(null);
99
100 if (!("subscriptions" in statFilter))
101 statFilter.subscriptions = [];
102
103 for (let i = 0; i < subscriptions.length; i++)
104 {
105 if (subscriptions[i] instanceof DownloadableSubscription
106 && statFilter.subscriptions.indexOf(subscriptions[i].url) == -1)
107 statFilter.subscriptions.push(subscriptions[i].url);
108 }
109
110 let wndLocation = Utils.getOriginWindow(wnd).location.href;
111 let host = Utils.unwrapURL(wndLocation).host;
112
kzar 2015/03/23 13:11:05 Nit: Trailing whitespace
113 if (!(host in statFilter[filterType]))
114 statFilter[filterType][host] = {hits: 1, latest: filter.lastHit};
115 else
116 {
117 statFilter[filterType][host].hits++;
118 statFilter[filterType][host].latest = filter.lastHit;
119 }
120 },
121
kzar 2015/03/23 13:11:05 Nit: Trailing whitespace
122 resetFilterHits: function()
123 {
124 this.filters = Object.create(null);
125 this.saveFilterHitsToDatabase();
126 },
127
kzar 2015/03/23 13:11:05 Nit: Trailing whitespace
128 sendFilterHitsToServer: function()
129 {
130 if (!Prefs.sendstats)
131 return;
132
133 let request = new XMLHttpRequest();
134 request.open("POST", Prefs.sendstats_url);
135 request.setRequestHeader("Content-Type", "application/json");
136 request.addEventListener("load", function(event)
137 {
138 FilterHits._sending = false;
139 if (request.status == 200)
140 {
141 FilterHits._lastPush = new Date().getTime();
142 FilterHits.resetFilterHits();
143 }
144 else
145 Cu.reportError("Could not send filter hit statistics to Adblock Plus ser ver.");
146 }, false);
147
148 let {addonName, addonVersion, application, applicationVersion, platform, pla tformVersion} = require("info");
149 let data = {
150 version: 1,
151 timeSincePush: this._lastPush,
152 addonName: addonName,
153 addonVersion: addonVersion,
154 application: application,
155 applicationVersion: applicationVersion,
156 platform: platform,
157 platformVersion: platformVersion,
158 filters: this.filters
159 };
160
161 this._sending = true;
162 request.send(JSON.stringify(data));
163 },
164
kzar 2015/03/23 13:11:05 Nit: Trailing whitespace
165 getStorageFile: function()
166 {
167 return FileUtils.getFile("ProfD", ["adblockplus.sqlite"]);
168 },
169
kzar 2015/03/23 13:11:05 Nit: Trailing whitespace
170 checkCreateTable: function(connection)
171 {
172 if (!connection.tableExists("filterhits"))
173 connection.executeSimpleSQL("CREATE TABLE filterhits (id INTEGER PRIMARY K EY, filters TEXT, date INTEGER)");
174 },
175
kzar 2015/03/23 13:11:05 Nit: Trailing whitespace
176 /**
177 * Load Filter hits from database
178 */
179 loadFilterHitsFromDatabase: function()
180 {
181 let storageFile = this.getStorageFile();
182 if (!storageFile)
183 return;
184
185 let connection = Services.storage.openDatabase(storageFile);
186 this.checkCreateTable(connection);
187
kzar 2015/03/23 13:11:05 Nit: Trailing whitespace
188 let statement = connection.createStatement("SELECT * FROM filterhits");
189 if (!this._loading)
190 {
191 this._loading = true;
192 statement.executeAsync(
193 {
194 handleResult: function(results)
195 {
196 let row = results.getNextRow();
197 if (row)
198 {
199 let filters = row.getResultByName("filters");
200 let lastDate = row.getResultByName("date");
201 FilterHits.filters = JSON.parse(filters);
202 FilterHits._lastPush = lastDate;
203 }
204 },
205
kzar 2015/03/23 13:11:05 Nit: Trailing whitespace
206 handleError: function(error)
207 {
208 Cu.reportError(error.message);
209 },
210
kzar 2015/03/23 13:11:05 Nit: Trailing whitespace
211 handleCompletion: function(reason)
212 {
213 if (reason != Ci.mozIStorageStatementCallback.REASON_FINISHED)
214 Cu.reportError("Loading of filter hits canceled or aborted.");
215 FilterHits._loading = false;
216 }
217 });
218 }
219
kzar 2015/03/23 13:11:05 Nit: Trailing whitespace
220 connection.asyncClose();
221 },
222
kzar 2015/03/23 13:11:05 Nit: Trailing whitespace
223 /**
224 * Save Filter hits to database
225 */
226 saveFilterHitsToDatabase: function()
227 {
228 let now = new Date().getTime();
229 if (!this._lastPush)
230 this._lastPush = now;
231
kzar 2015/03/23 13:11:05 Nit: Trailing whitespace
232 if (!this._sending && now - this._lastPush > this._pushInterval)
233 {
234 this.sendFilterHitsToServer();
235 return;
236 }
237
238 let storageFile = this.getStorageFile();
239 if (!storageFile)
240 return;
241
242 let connection = Services.storage.openDatabase(storageFile);
243 this.checkCreateTable(connection);
244
kzar 2015/03/23 13:11:05 Nit: Trailing whitespace
245 let statement = connection.createStatement("INSERT OR REPLACE INTO filterhit s (id, filters, date) VALUES(0, :filters, :date)");
246 statement.params.filters = JSON.stringify(this.filters);
247 statement.params.date = this._lastPush;
248 if (!this._saving)
249 {
250 this._saving = true;
251 statement.executeAsync(
252 {
253 handleError: function(aError)
254 {
255 Cu.reportError(aError.message);
256 },
257
kzar 2015/03/23 13:11:05 Nit: Trailing whitespace
258 handleCompletion: function(aReason)
kzar 2015/03/23 13:11:05 Nit: Trailing whitespace
259 {
260 if (aReason != Components.interfaces.mozIStorageStatementCallback.REAS ON_FINISHED)
261 Cu.reportError("Writing of filter hits canceled or aborted.");
262 FilterHits._saving = false;
263 }
264 });
265 }
266
kzar 2015/03/23 13:11:05 Nit: Trailing whitespace
267 connection.asyncClose();
268 }
269 };
270
271 FilterNotifier.addListener(function(action)
272 {
273 if (action == "load" && Prefs.sendstats)
274 FilterHits.loadFilterHitsFromDatabase();
275 });
OLDNEW

Powered by Google App Engine
This is Rietveld