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

Side by Side Diff: modules/statsmaster/files/usercounts.html

Issue 29464559: #1538 - Remove class statsmaster and associated resources (Closed)
Patch Set: Created June 13, 2017, 9:43 a.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 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <title>User counter</title>
6 <style type="text/css">
7 form
8 {
9 display: inline;
10 }
11
12 .spacer
13 {
14 margin: 0 10px;
15 }
16
17 table
18 {
19 border-collapse: collapse;
20 }
21
22 td, th
23 {
24 padding: 5px;
25 border: 1px solid black;
26 }
27
28 td
29 {
30 text-align: right;
31 }
32 </style>
33 <script type="text/javascript">
34 const MILLIS_IN_DAY = 24 * 60 * 60 * 1000;
35
36 function zeroPad(number, digits)
37 {
38 var result = number.toString(10);
39 while (result.length < digits)
40 result = "0" + result;
41 return result;
42 }
43
44 function formatDate(date)
45 {
46 return zeroPad(date.getFullYear(), 4) + "-" + zeroPad(date.getMonth() + 1, 2) + "-" + zeroPad(date.getDate(), 2);
47 }
48
49 var curMonth = null;
50 var curMonthFilters = null;
51 var curMonthAntiadblock = null;
52 var curMonthNotifications = null;
53
54 function checkStats(data, fromDate, offset, callback)
55 {
56 var date = new Date(fromDate.getTime() + offset * MILLIS_IN_DAY);
57
58 function doDownload(url, descr, callback)
59 {
60 var request = new XMLHttpRequest();
61 request.open("GET", url);
62 request.addEventListener("load", function()
63 {
64 if (request.status != 200)
65 alert("Failed to download " + descr + ", got response " + request.st atus);
66 else
67 callback(JSON.parse(request.responseText));
68 }, false);
69 request.addEventListener("error", function()
70 {
71 alert("Failed to download " + descr);
72 }, false);
73 request.send(null);
74 }
75
76 function doCheckStats(source, type)
77 {
78 if (!(date.getDate() in source.day))
79 return;
80
81 var intervals = source.day[date.getDate()].previousDownload;
82 for (var interval in intervals)
83 {
84 if (!intervals.hasOwnProperty(interval))
85 continue;
86
87 var days;
88 if (/^\d+ day/.test(interval))
89 days = parseInt(interval, 10);
90 else if (/^\d+ month/.test(interval))
91 days = 31;
92 else
93 continue;
94
95 // Most requests claiming that last download was long ago are bots or broken installations
96 if (days > 30)
97 continue;
98
99 var hits = intervals[interval].hits;
100 for (var i = Math.max(offset, 0); i < data.length; i++)
101 {
102 if (i - offset < 30 && i - offset + days >= 30)
103 data[i]["30day " + type] += hits;
104 if (i - offset < 7 && i - offset + days >= 7)
105 data[i]["7day " + type] += hits;
106 if (i - offset < 1 && i - offset + days >= 1)
107 data[i]["1day " + type] += hits;
108 }
109 }
110 }
111
112 var month = zeroPad(date.getFullYear(), 4) + zeroPad(date.getMonth() + 1, 2);
113 if (month != curMonth)
114 {
115 doDownload("/raw/subscription/" + month + "/exceptionrules.txt.json", "a cceptable ads data for month " + month, function(json)
116 {
117 curMonthFilters = json;
118 doDownload("/raw/subscription/" + month + "/antiadblockfilters.txt.jso n", "anti-adblock data for month " + month, function(json)
119 {
120 curMonthAntiadblock = json;
121 doDownload("/raw/notification/" + month + "/notification.json.json", "notification data for month " + month, function(json)
122 {
123 curMonthNotifications = json;
124 curMonth = month;
125 doCheckStats(curMonthFilters, "acceptable");
126 doCheckStats(curMonthAntiadblock, "antiadblock");
127 doCheckStats(curMonthNotifications, "total");
128 callback();
129 });
130 });
131 });
132 }
133 else
134 {
135 doCheckStats(curMonthFilters, "acceptable");
136 doCheckStats(curMonthAntiadblock, "antiadblock");
137 doCheckStats(curMonthNotifications, "total");
138 callback();
139 }
140 }
141
142 function showResults(fromDate, data)
143 {
144 function createCell(row, text)
145 {
146 var cell = document.createElement("td");
147 cell.appendChild(document.createTextNode(text));
148 row.appendChild(cell);
149 }
150
151 var resultBody = document.getElementById("resultBody");
152 while (resultBody.lastChild)
153 resultBody.removeChild(resultBody.lastChild);
154
155 for (var i = 0; i < data.length; i++)
156 {
157 var date = new Date(fromDate.getTime() + i * MILLIS_IN_DAY);
158
159 var row = document.createElement("tr");
160 createCell(row, date.toLocaleDateString());
161 createCell(row, data[i]["1day total"].toLocaleString());
162 createCell(row, data[i]["1day antiadblock"].toLocaleString());
163 createCell(row, data[i]["1day acceptable"].toLocaleString());
164 createCell(row, (100 - data[i]["1day acceptable"] / data[i]["1day total" ] * 100).toFixed(2) + "%");
165 createCell(row, data[i]["7day total"].toLocaleString());
166 createCell(row, data[i]["7day antiadblock"].toLocaleString());
167 createCell(row, data[i]["7day acceptable"].toLocaleString());
168 createCell(row, (100 - data[i]["7day acceptable"] / data[i]["7day total" ] * 100).toFixed(2) + "%");
169 createCell(row, data[i]["30day total"].toLocaleString());
170 createCell(row, data[i]["30day antiadblock"].toLocaleString());
171 createCell(row, data[i]["30day acceptable"].toLocaleString());
172 createCell(row, (100 - data[i]["30day acceptable"] / data[i]["30day tota l"] * 100).toFixed(2) + "%");
173 resultBody.appendChild(row);
174 }
175
176 document.getElementById("result").removeAttribute("hidden");
177 document.getElementById("wait").setAttribute("hidden", "hidden");
178 }
179
180 function calculate()
181 {
182 document.getElementById("result").setAttribute("hidden", "hidden");
183 document.getElementById("wait").removeAttribute("hidden");
184
185 var fromDate = document.getElementById("from").value.replace(/^\s+/, "").r eplace(/\s+$/, "");
186 var match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(fromDate);
187 if (!match)
188 {
189 alert("Wrong start date format.");
190 document.getElementById("from").focus();
191 return;
192 }
193 fromDate = new Date(parseInt(match[1], 10), parseInt(match[2], 10) - 1, pa rseInt(match[3], 10), 12);
194
195 var toDate = document.getElementById("to").value.replace(/^\s+/, "").repla ce(/\s+$/, "");
196 var match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(toDate);
197 if (!match)
198 {
199 alert("Wrong end date format.");
200 document.getElementById("to").focus();
201 return;
202 }
203 toDate = new Date(parseInt(match[1], 10), parseInt(match[2], 10) - 1, pars eInt(match[3], 10), 12);
204
205 if (fromDate > toDate)
206 {
207 var tmp = fromDate;
208 fromDate = toDate;
209 toDate = tmp;
210 }
211
212 var data = [];
213 for (var d = fromDate; formatDate(d) <= formatDate(toDate); d = new Date(d .getTime() + MILLIS_IN_DAY))
214 data.push({"1day total": 0, "1day antiadblock": 0, "1day acceptable": 0, "7day total": 0, "7day antiadblock": 0, "7day acceptable": 0, "30day total": 0, "30day antiadblock": 0, "30day acceptable": 0});
215
216 var offset = -30;
217 var callback = function()
218 {
219 offset++;
220 if (offset >= data.length)
221 {
222 showResults(fromDate, data);
223 return;
224 }
225 checkStats(data, fromDate, offset, callback);
226 };
227 callback();
228 }
229
230 window.onload = function()
231 {
232 document.getElementById("from").value = formatDate(new Date(Date.now() - 7 * MILLIS_IN_DAY));
233 document.getElementById("to").value = formatDate(new Date(Date.now() - MIL LIS_IN_DAY));
234 }
235 </script>
236 </head>
237 <body>
238 <p>
239 Please enter the date range that you need user statistics for:
240 </p>
241 <p>
242 <form action="javascript://" onsubmit="calculate();">
243 Start date (yyyy-mm-dd format): <input id="from" type="text">
244 <span class="spacer"></span>
245 End date (yyyy-mm-dd format): <input id="to" type="text">
246 <span class="spacer"></span>
247 <button type="submit">Calculate</button>
248 </form>
249 </p>
250 <p id="wait" hidden>
251 Please wait, data is being fetched...
252 </p>
253 <table id="result" hidden>
254 <tr>
255 <th rowspan="2">Date</th>
256 <th colspan="4">1-day active users</th>
257 <th colspan="4">7-day active users</th>
258 <th colspan="4">30-day active users</th>
259 </tr>
260 <tr>
261 <th>Total</th>
262 <th>Anti-adblock filters</th>
263 <th>Acceptable ads</th>
264 <th>Opt-out rate</th>
265 <th>Total</th>
266 <th>Anti-adblock filters</th>
267 <th>Acceptable ads</th>
268 <th>Opt-out rate</th>
269 <th>Total</th>
270 <th>Anti-adblock filters</th>
271 <th>Acceptable ads</th>
272 <th>Opt-out rate</th>
273 </tr>
274 <tbody id="resultBody">
275 </tbody>
276 </table>
277 </body>
278 </html>
OLDNEW

Powered by Google App Engine
This is Rietveld