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: reset filterhits Created April 28, 2014, 5:33 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 {IO} = require("io");
19 let {Utils} = require("utils");
20 let {Prefs} = require("prefs");
21 let {TimeLine} = require("timeline");
22 let {Filter} = require("filterClasses");
23
24 /**
25 * This class reads filter hits statistics from disk, manages them in memory and writes them back.W
26 * @class
27 */
28 let FilterHits = exports.FilterHits =
29 {
30 statistics: {},
31
32 _loading: false,
33 _saving: false,
34 _needsSave: false,
35
36 /**
37 * File that the filter hits statistics has been loaded from and should be sav ed to
38 * @type nsIFile
39 */
40 get filterHitsFile()
41 {
42 let file = null;
43 if (!file)
44 {
45 // Place the file in the data dir
46 file = IO.resolveFilePath(Prefs.data_directory);
47 if (file)
48 file.append("filter-hits.ini");
49 }
50 if (!file)
51 {
52 // Data directory pref misconfigured? Try the default value
53 try
54 {
55 file = IO.resolveFilePath(Services.prefs.getDefaultBranch("extensions.ad blockplus.").getCharPref("data_directory"));
56 if (file)
57 file.append("filter-hits.ini");
58 } catch(e) {}
59 }
60
61 if (!file)
62 Cu.reportError("Adblock Plus: Failed to resolve filter-hits file");
63
64 this.__defineGetter__("filterHitsFile", function() file);
65 return this.filterHitsFile;
66 },
67
68 /**
69 * Increases the filter hit count by one
70 * @param {Filter} filter
71 * @param {Window} window Window that the match originated in (required to ge t host name)
72 */
73 increaseFilterHits: function(filter, wnd)
74 {
75 if (!filter.text)
76 return;
77
78 if (filter.text in this.statistics)
79 this.statistics[filter.text].statsHitCount++;
80 else
81 this.statistics[filter.text] = {statsHitCount:1, lastHit: 0, domainsCount: {},
82 thirdParty: false, subscriptions: []};
83
84 let increaseHits = function(filterStats)
85 {
86 if (filter.lastHit)
87 filterStats.lastHit = filter.lastHit;
88
89 if (filter.subscriptions)
90 {
91 for (let i = 0; i < filter.subscriptions.length; i++)
92 {
93 if (filterStats.subscriptions.indexOf(filter.subscriptions[i]._title) == -1)
94 filterStats.subscriptions.push(filter.subscriptions[i]._title);
95 }
96 }
97
98 if (filter.thirdParty)
99 filterStats.thirdParty = true;
100
101 // Get hostname from window object
102 let wndLocation = Utils.getOriginWindow(wnd).location.href;
103 let host = Utils.unwrapURL(wndLocation).host;
104
105 if (host in filterStats.domainsCount)
106 filterStats.domainsCount[host]++;
107 else
108 filterStats.domainsCount[host] = 1;
109 };
110
111 increaseHits(this.statistics[filter.text]);
112 },
113
114 resetFilterHits: function()
115 {
116 this.statistics = {};
117 },
118
119 /**
120 * send filter hits statistics to ABP sever and reset filter hits count
121 */
122 sendFilterHitsToServer: function()
123 {
124 //TODO implement ajax request to server sending this.statistics
125 //clear statics on 200 response
126 this.resetFilterHits();
127 this.saveFilterHitsToDisk();
128 },
129
130 /**
131 * Loads Filter hit statistics from the disk
132 */
133 loadFilterHitsFromDisk: function()
134 {
135 if (this._loading)
136 return;
137
138 let sourceFile = FilterHits.filterHitsFile;
139 if (!sourceFile)
140 return;
141
142 TimeLine.enter("Entered FilterHits.loadFilterHitsFromDisk()");
143 this._loading = true;
144
145 let readFile = function()
146 {
147 TimeLine.enter("FilterHits.loadFilterHitsFromDisk() -> readFile()");
148 let parser = new FilterHitsParser();
149 IO.readFromFile(sourceFile, true, parser, function(e)
150 {
151 TimeLine.enter("FilterHits.loadFilterHitsFromDisk() read callback");
152 if (e)
153 Cu.reportError(e);
154
155 doneReading(parser);
156 }.bind(this), "FilterHitsRead");
157
158 TimeLine.leave("FilterHits.loadFilterHitsFromDisk() <- readFile()", "Filte rHitsRead");
159 }.bind(this);
160
161 var doneReading = function(parser)
162 {
163 FilterHits.statistics = parser.statistics;
164 this._loading = false;
165 TimeLine.leave("FilterHits.loadFilterHitsFromDisk() read callback done");
166 }.bind(this);
167
168 IO.statFile(sourceFile, function(e, statData)
169 {
170 if (!e && statData.exists)
171 readFile(sourceFile);
172 });
173 TimeLine.leave("FilterHits.loadFilterHitsFromDisk() done");
174 },
175
176 /**
177 * Stringify filter hits statistics object
178 */
179 _generateFilterHitData: function()
180 {
181 yield JSON.stringify(FilterHits.statistics);
182 },
183
184 /**
185 * Save Filters hit statistics to the disk
186 */
187 saveFilterHitsToDisk: function()
188 {
189 let targetFile = FilterHits.filterHitsFile;
190 if (!targetFile)
191 return;
192
193 if (this._saving)
194 {
195 this._needsSave = true;
196 return;
197 }
198 TimeLine.enter("Entered FilterHits.saveFilterHitsToDisk()");
199 // Make sure the file's parent directory exists
200 try {
201 targetFile.parent.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECT ORY);
202 } catch (e) {}
203
204 let writeStats = function()
205 {
206 TimeLine.enter("FilterHits.saveFilterHitsToDisk() -> writeStats()");
207 IO.writeToFile(targetFile, true, this._generateFilterHitData(), function(e )
208 {
209 TimeLine.enter("FilterHits.saveFilterHitsToDisk() write callback");
210 this._saving = false;
211
212 if (e)
213 Cu.reportError(e);
214
215 if (this._needsSave)
216 {
217 this._needsSave = false;
218 this.saveFilterHitsToDisk();
219 }
220 TimeLine.leave("FilterHits.saveFilterHitsToDisk() write callback done");
221 }.bind(this), "FilterHitsWriteStats");
222 TimeLine.leave("FilterHits.saveFilterHitsToDisk() -> writeStats()", "Filte rStorageWriteStats");
223 }.bind(this);
224
225 this._saving = true;
226 writeStats();
227 TimeLine.leave("FilterHits.saveFilterHitsToDisk() done");
228 }
229 };
230
231 /**
232 * IO.readFromFile() listener to parse filter-hits data.
233 * @constructor
234 */
235 function FilterHitsParser()
236 {
237 this.statistics = {__proto__: null};
238 }
239 FilterHitsParser.prototype =
240 {
241 process: function(val)
242 {
243 if (val === null)
244 return;
245 this.statistics = JSON.parse(val);
246 }
247 };
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