mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 941685 - Ping metrics server with snippets impression data. r=bnicholson
This commit is contained in:
parent
eb6892a43b
commit
73928f1858
@ -800,5 +800,8 @@ pref("browser.snippets.updateInterval", 86400);
|
||||
// URL used to check for user's country code
|
||||
pref("browser.snippets.geoUrl", "https://geo.mozilla.org/country.json");
|
||||
|
||||
// URL used to ping metrics with stats about which snippets have been shown
|
||||
pref("browser.snippets.statsUrl", "https://snippets-stats.mozilla.org/mobile");
|
||||
|
||||
// This pref requires a restart to take effect.
|
||||
pref("browser.snippets.enabled", false);
|
||||
|
@ -9,6 +9,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Home", "resource://gre/modules/Home.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gEncoder", function() { return new gChromeWin.TextEncoder(); });
|
||||
XPCOMUtils.defineLazyGetter(this, "gDecoder", function() { return new gChromeWin.TextDecoder(); });
|
||||
@ -18,6 +19,9 @@ const SNIPPETS_ENABLED = Services.prefs.getBoolPref("browser.snippets.enabled");
|
||||
// URL to fetch snippets, in the urlFormatter service format.
|
||||
const SNIPPETS_UPDATE_URL_PREF = "browser.snippets.updateUrl";
|
||||
|
||||
// URL to send stats data to metrics.
|
||||
const SNIPPETS_STATS_URL_PREF = "browser.snippets.statsUrl";
|
||||
|
||||
// URL to fetch country code, a value that's cached and refreshed once per month.
|
||||
const SNIPPETS_GEO_URL_PREF = "browser.snippets.geoUrl";
|
||||
|
||||
@ -38,6 +42,20 @@ XPCOMUtils.defineLazyGetter(this, "gSnippetsURL", function() {
|
||||
return Services.urlFormatter.formatURL(updateURL);
|
||||
});
|
||||
|
||||
// Where we cache snippets data
|
||||
XPCOMUtils.defineLazyGetter(this, "gSnippetsPath", function() {
|
||||
return OS.Path.join(OS.Constants.Path.profileDir, "snippets.json");
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gStatsURL", function() {
|
||||
return Services.prefs.getCharPref(SNIPPETS_STATS_URL_PREF);
|
||||
});
|
||||
|
||||
// Where we store stats about which snippets have been shown
|
||||
XPCOMUtils.defineLazyGetter(this, "gStatsPath", function() {
|
||||
return OS.Path.join(OS.Constants.Path.profileDir, "snippets-stats.txt");
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gGeoURL", function() {
|
||||
return Services.prefs.getCharPref(SNIPPETS_GEO_URL_PREF);
|
||||
});
|
||||
@ -109,9 +127,8 @@ function updateSnippets() {
|
||||
* @param response responseText returned from snippets server
|
||||
*/
|
||||
function cacheSnippets(response) {
|
||||
let path = OS.Path.join(OS.Constants.Path.profileDir, "snippets.json");
|
||||
let data = gEncoder.encode(response);
|
||||
let promise = OS.File.writeAtomic(path, data, { tmpPath: path + ".tmp" });
|
||||
let promise = OS.File.writeAtomic(gSnippetsPath, data, { tmpPath: gSnippetsPath + ".tmp" });
|
||||
promise.then(null, e => Cu.reportError("Error caching snippets: " + e));
|
||||
}
|
||||
|
||||
@ -119,8 +136,7 @@ function cacheSnippets(response) {
|
||||
* Loads snippets from cached `snippets.json`.
|
||||
*/
|
||||
function loadSnippetsFromCache() {
|
||||
let path = OS.Path.join(OS.Constants.Path.profileDir, "snippets.json");
|
||||
let promise = OS.File.read(path);
|
||||
let promise = OS.File.read(gSnippetsPath);
|
||||
promise.then(array => updateBanner(gDecoder.decode(array)), e => {
|
||||
// If snippets.json doesn't exist, update data from the server.
|
||||
if (e instanceof OS.File.Error && e.becauseNoSuchFile) {
|
||||
@ -167,7 +183,10 @@ function updateBanner(response) {
|
||||
gChromeWin.BrowserApp.addTab(message.url);
|
||||
},
|
||||
onshown: function() {
|
||||
// XXX: 10% of the time, let the metrics server know which message was shown (bug 937373)
|
||||
// 10% of the time, record the snippet id and a timestamp
|
||||
if (Math.random() < .1) {
|
||||
writeStat(message.id, new Date().toISOString());
|
||||
}
|
||||
}
|
||||
});
|
||||
// Keep track of the message we added so that we can remove it later.
|
||||
@ -175,6 +194,76 @@ function updateBanner(response) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends snippet id and timestamp to the end of `snippets-stats.txt`.
|
||||
*
|
||||
* @param snippetId unique id for snippet, sent from snippets server
|
||||
* @param timestamp in ISO8601
|
||||
*/
|
||||
function writeStat(snippetId, timestamp) {
|
||||
let data = gEncoder.encode(snippetId + "," + timestamp + ";");
|
||||
|
||||
Task.spawn(function() {
|
||||
try {
|
||||
let file = yield OS.File.open(gStatsPath, { append: true, write: true });
|
||||
try {
|
||||
yield file.write(data);
|
||||
} finally {
|
||||
yield file.close();
|
||||
}
|
||||
} catch (ex if ex instanceof OS.File.Error && ex.becauseNoSuchFile) {
|
||||
// If the file doesn't exist yet, create it.
|
||||
yield OS.File.writeAtomic(gStatsPath, data, { tmpPath: gStatsPath + ".tmp" });
|
||||
}
|
||||
}).then(null, e => Cu.reportError("Error writing snippets stats: " + e));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads snippets stats data from `snippets-stats.txt` and sends the data to metrics.
|
||||
*/
|
||||
function sendStats() {
|
||||
let promise = OS.File.read(gStatsPath);
|
||||
promise.then(array => sendStatsRequest(gDecoder.decode(array)), e => {
|
||||
if (e instanceof OS.File.Error && e.becauseNoSuchFile) {
|
||||
// If the file doesn't exist, there aren't any stats to send.
|
||||
} else {
|
||||
Cu.reportError("Error eading snippets stats: " + e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends stats to metrics about which snippets have been shown.
|
||||
* Appends snippet ids and timestamps as parameters to a GET request.
|
||||
* e.g. https://snippets-stats.mozilla.org/mobile?s1=3825&t1=2013-11-17T18:27Z&s2=6326&t2=2013-11-18T18:27Z
|
||||
*
|
||||
* @param data contents of stats data file
|
||||
*/
|
||||
function sendStatsRequest(data) {
|
||||
let params = [];
|
||||
let stats = data.split(";");
|
||||
|
||||
// The last item in the array will be an empty string, so stop before then.
|
||||
for (let i = 0; i < stats.length - 1; i++) {
|
||||
let stat = stats[i].split(",");
|
||||
params.push("s" + i + "=" + encodeURIComponent(stat[0]));
|
||||
params.push("t" + i + "=" + encodeURIComponent(stat[1]));
|
||||
}
|
||||
|
||||
let url = gStatsURL + "?" + params.join("&");
|
||||
|
||||
// Remove the file after succesfully sending the data.
|
||||
_httpGetRequest(url, removeStats);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes text file where we store snippets stats.
|
||||
*/
|
||||
function removeStats() {
|
||||
let promise = OS.File.remove(gStatsPath);
|
||||
promise.then(null, e => Cu.reportError("Error removing snippets stats: " + e));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to make HTTP GET requests.
|
||||
*
|
||||
@ -227,6 +316,7 @@ Snippets.prototype = {
|
||||
return;
|
||||
}
|
||||
update();
|
||||
sendStats();
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user