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 Oct. 14, 2014, 4:48 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
« no previous file with comments | « defaults/prefs.js ('k') | lib/filterListener.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * This file is part of Adblock Plus <http://adblockplus.org/>,
3 * Copyright (C) 2006-2014 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 {Utils} = require("utils");
22 let {MILLIS_IN_DAY} = require("downloader");
23
24 /**
25 * This class reads filter hits statistics from SQLite database,
26 * manages them in memory and writes them back.
27 * @class
28 */
29 let FilterHits = exports.FilterHits =
30 {
31 filters: {},
32
33 _serviceURL: "",
saroyanm 2014/10/14 16:53:48 Here should go the URL for backend service.
34 _lastPush: 0,
35 _pushInterval: MILLIS_IN_DAY * 7,
36 _loading: false,
37 _saving: false,
38 _sending: false,
39
40 /**
41 * Increases the filter hit count
42 * @param {Filter} filter
43 * @param {Window} window Window that the match originated in (required to ge t host)
44 */
45 increaseFilterHits: function(filter, wnd)
46 {
47 if (!filter.text || (filter.subscriptions[0] && filter.subscriptions[0].url. indexOf("~user~") == 0))
48 return;
49
50 if (!(filter.text in this.filters))
51 this.filters[filter.text] = {};
52
53 let filterType = filter.thirdParty ? "thirdParty" : "firstParty";
54
55 if (!(filterType in this.filters[filter.text]))
56 this.filters[filter.text][filterType] = {};
57
58 if (!("subscriptions" in this.filters[filter.text]))
59 this.filters[filter.text].subscriptions = [];
60
61 if (filter.subscriptions)
62 {
63 for (let i = 0; i < filter.subscriptions.length; i++)
64 {
65 if (this.filters[filter.text].subscriptions.indexOf(filter.subscriptions [i]._title) == -1)
66 this.filters[filter.text].subscriptions.push(filter.subscriptions[i]._ title);
67 }
68 }
69
70 let wndLocation = Utils.getOriginWindow(wnd).location.href;
71 let host = Utils.unwrapURL(wndLocation).host;
72
73 if (!(host in this.filters[filter.text][filterType]))
74 this.filters[filter.text][filterType][host] = {hits: 1, latest: filter.lat est};
75 else
76 {
77 this.filters[filter.text][filterType][host].hits++;
78 this.filters[filter.text][filterType][host].latest = filter.latest;
79 }
80 },
81
82 resetFilterHits: function()
83 {
84 this.filters = {};
85 this.saveFilterHitsToDatabase();
86 },
87
88 sendFilterHitsToServer: function()
89 {
90 let prepareData = function()
91 {
92 let {addonName, addonVersion, application, applicationVersion, platform, p latformVersion} = require("info");
93 return {
94 version: 1,
95 timeSincePush: this._lastPush,
96 addonName: addonName,
97 addonVersion: addonVersion,
98 application: application,
99 applicationVersion: applicationVersion,
100 platform: platform,
101 platformVersion: platformVersion,
102 filters: this.filters
103 }
104 }.bind(this);
105
106 let request = new XMLHttpRequest();
107 request.open("POST", this._serviceURL);
108 request.setRequestHeader("Content-Type", "application/json");
109 request.addEventListener("load", function(event)
110 {
111 let request = event.target;
112 FilterHits._sending = false;
113 if (request.status == 200)
114 {
115 FilterHits._lastPush = new Date().getTime();
116 FilterHits.resetFilterHits();
117 }
118 else
119 Cu.reportError("could not send filter hit statistics to AdBlock Plus ser ver");
120 }, false);
121 this._sending = true;
122 request.send(JSON.stringify(prepareData()));
123 },
124
125 getStorageFile: function()
126 {
127 return FileUtils.getFile("ProfD", ["adblockplus.sqlite"]);
128 },
129
130 checkCreateTable: function(connection)
131 {
132 if (!connection.tableExists("filterhits"))
133 connection.executeSimpleSQL("CREATE TABLE filterhits (id INTEGER PRIMARY K EY, filters TEXT, date INTEGER)");
134 },
135
136 /**
137 * Load Filter hits from database
138 */
139 loadFilterHitsFromDatabase: function()
140 {
141 let storageFile = this.getStorageFile();
142 if (!storageFile)
143 return;
144
145 let connection = Services.storage.openDatabase(storageFile);
146 this.checkCreateTable(connection);
147
148 let statement = connection.createStatement("SELECT * FROM filterhits");
149 if (!this._loading)
150 {
151 this._loading = true;
152 statement.executeAsync(
153 {
154 handleResult: function(aResultSet)
155 {
156 let row = aResultSet.getNextRow();
157 if (row)
158 {
159 let filters = row.getResultByName("filters");
160 let lastDate = row.getResultByName("date");
161 FilterHits.filters = JSON.parse(filters);
162 FilterHits._lastPush = lastDate;
163 }
164 FilterHits._loading = false;
165 },
166
167 handleError: function(aError)
168 {
169 Cu.reportError(aError.message);
170 },
171
172 handleCompletion: function(aReason)
173 {
174 if (aReason != Components.interfaces.mozIStorageStatementCallback.REAS ON_FINISHED)
175 {
176 Cu.reportError("Loading of filter hits canceled or aborted.");
177 FilterHits._loading = false;
178 }
179 }
180 });
181 }
182
183 connection.asyncClose();
184 },
185
186 /**
187 * Save Filter hits to database
188 */
189 saveFilterHitsToDatabase: function()
190 {
191 if (!this._lastPush)
192 this._lastPush = new Date().getTime();
193
194 if (!this._sending && new Date().getTime() - this._lastPush > this._pushInte rval)
195 {
196 this.sendFilterHitsToServer();
197 return;
198 }
199
200 let storageFile = this.getStorageFile();
201 if (!storageFile)
202 return;
203
204 let connection = Services.storage.openDatabase(storageFile);
205 this.checkCreateTable(connection);
206
207 let statement = connection.createStatement("INSERT OR REPLACE INTO filterhit s (id, filters, date) VALUES(0, :filters, :date)");
208 statement.params.filters = JSON.stringify(this.filters);
209 statement.params.date = this._lastPush;
210 if (!this._saving)
211 {
212 this._saving = true;
213 statement.executeAsync(
214 {
215 handleError: function(aError)
216 {
217 Cu.reportError(aError.message);
218 },
219
220 handleCompletion: function(aReason)
221 {
222 if (aReason != Components.interfaces.mozIStorageStatementCallback.REAS ON_FINISHED)
223 Cu.reportError("Writing of filter hits canceled or aborted.");
224 FilterHits._saving = false;
225 }
226 });
227 }
228
229 connection.asyncClose();
230 }
231 };
OLDNEW
« no previous file with comments | « defaults/prefs.js ('k') | lib/filterListener.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld