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
|
// URL used to check for user's country code
|
||||||
pref("browser.snippets.geoUrl", "https://geo.mozilla.org/country.json");
|
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.
|
// This pref requires a restart to take effect.
|
||||||
pref("browser.snippets.enabled", false);
|
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, "Home", "resource://gre/modules/Home.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.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, "gEncoder", function() { return new gChromeWin.TextEncoder(); });
|
||||||
XPCOMUtils.defineLazyGetter(this, "gDecoder", function() { return new gChromeWin.TextDecoder(); });
|
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.
|
// URL to fetch snippets, in the urlFormatter service format.
|
||||||
const SNIPPETS_UPDATE_URL_PREF = "browser.snippets.updateUrl";
|
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.
|
// URL to fetch country code, a value that's cached and refreshed once per month.
|
||||||
const SNIPPETS_GEO_URL_PREF = "browser.snippets.geoUrl";
|
const SNIPPETS_GEO_URL_PREF = "browser.snippets.geoUrl";
|
||||||
|
|
||||||
@ -38,6 +42,20 @@ XPCOMUtils.defineLazyGetter(this, "gSnippetsURL", function() {
|
|||||||
return Services.urlFormatter.formatURL(updateURL);
|
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() {
|
XPCOMUtils.defineLazyGetter(this, "gGeoURL", function() {
|
||||||
return Services.prefs.getCharPref(SNIPPETS_GEO_URL_PREF);
|
return Services.prefs.getCharPref(SNIPPETS_GEO_URL_PREF);
|
||||||
});
|
});
|
||||||
@ -109,9 +127,8 @@ function updateSnippets() {
|
|||||||
* @param response responseText returned from snippets server
|
* @param response responseText returned from snippets server
|
||||||
*/
|
*/
|
||||||
function cacheSnippets(response) {
|
function cacheSnippets(response) {
|
||||||
let path = OS.Path.join(OS.Constants.Path.profileDir, "snippets.json");
|
|
||||||
let data = gEncoder.encode(response);
|
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));
|
promise.then(null, e => Cu.reportError("Error caching snippets: " + e));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,8 +136,7 @@ function cacheSnippets(response) {
|
|||||||
* Loads snippets from cached `snippets.json`.
|
* Loads snippets from cached `snippets.json`.
|
||||||
*/
|
*/
|
||||||
function loadSnippetsFromCache() {
|
function loadSnippetsFromCache() {
|
||||||
let path = OS.Path.join(OS.Constants.Path.profileDir, "snippets.json");
|
let promise = OS.File.read(gSnippetsPath);
|
||||||
let promise = OS.File.read(path);
|
|
||||||
promise.then(array => updateBanner(gDecoder.decode(array)), e => {
|
promise.then(array => updateBanner(gDecoder.decode(array)), e => {
|
||||||
// If snippets.json doesn't exist, update data from the server.
|
// If snippets.json doesn't exist, update data from the server.
|
||||||
if (e instanceof OS.File.Error && e.becauseNoSuchFile) {
|
if (e instanceof OS.File.Error && e.becauseNoSuchFile) {
|
||||||
@ -167,7 +183,10 @@ function updateBanner(response) {
|
|||||||
gChromeWin.BrowserApp.addTab(message.url);
|
gChromeWin.BrowserApp.addTab(message.url);
|
||||||
},
|
},
|
||||||
onshown: function() {
|
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.
|
// 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.
|
* Helper function to make HTTP GET requests.
|
||||||
*
|
*
|
||||||
@ -227,6 +316,7 @@ Snippets.prototype = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
|
sendStats();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user