зеркало из https://github.com/mozilla/lightbeam.git
Fixes for #208 (Store connections as arrays)
This commit is contained in:
Родитель
c509739bf5
Коммит
409191f5d4
|
@ -46,19 +46,60 @@ aggregate.nodeForKey = function(key){
|
|||
return result;
|
||||
};
|
||||
|
||||
aggregate.connectionAsObject = function(conn){
|
||||
if (Array.isArray(conn)){
|
||||
return{
|
||||
source: conn[SOURCE],
|
||||
target: conn[TARGET],
|
||||
timestamp: new Date(conn[TIMESTAMP]),
|
||||
contentType: conn[CONTENT_TYPE],
|
||||
cookie: conn[COOKIE],
|
||||
sourceVisited: conn[SOURCE_VISITED],
|
||||
secure: conn[SECURE],
|
||||
sourcePathDepth: conn[SOURCE_PATH_DEPTH],
|
||||
sourceQueryDepth: conn[SOURCE_QUERY_DEPTH],
|
||||
sourceSub: conn[SOURCE_SUB],
|
||||
targetSub: conn[TARGET_SUB],
|
||||
method: conn[METHOD],
|
||||
status: conn[STATUS],
|
||||
cacheable: conn[CACHEABLE]
|
||||
};
|
||||
}
|
||||
return conn;
|
||||
|
||||
}
|
||||
|
||||
function onLoad(connections){
|
||||
connections.forEach(onConnection);
|
||||
}
|
||||
|
||||
aggregate.on('load', onLoad);
|
||||
|
||||
function onConnection(connection){
|
||||
// Constants for indexes of properties in array format
|
||||
const SOURCE = 0;
|
||||
const TARGET = 1;
|
||||
const TIMESTAMP = 2;
|
||||
const CONTENT_TYPE = 3;
|
||||
const COOKIE = 4;
|
||||
const SOURCE_VISITED = 5;
|
||||
const SECURE = 6;
|
||||
const SOURCE_PATH_DEPTH = 7;
|
||||
const SOURCE_QUERY_DEPTH = 8;
|
||||
const SOURCE_SUB = 9;
|
||||
const TARGET_SUB = 10;
|
||||
const METHOD = 11;
|
||||
const STATUS = 12;
|
||||
const CACHEABLE = 13;
|
||||
|
||||
|
||||
function onConnection(conn){
|
||||
// A connection has the following keys:
|
||||
// source (url), target (url), timestamp (int), contentType (str), cookie (bool), sourceVisited (bool), secure(bool), sourcePathDepth (int), sourceQueryDepth(int)
|
||||
// We want to shape the collection of connections that represent points in time into
|
||||
// aggregate data for graphing. Each connection has two endpoints represented by GraphNode objects
|
||||
// and one edge represented by a GraphEdge object, but we want to re-use these when connections
|
||||
// map to the same endpoints or edges.
|
||||
var connection = aggregate.connectionAsObject(conn);
|
||||
var sourcenode, targetnode, edge, nodelist, updated = false;
|
||||
if (nodemap[connection.source]){
|
||||
sourcenode = nodemap[connection.source];
|
||||
|
|
|
@ -26,6 +26,11 @@ clock.name = "clock";
|
|||
clock.on('init', onInit);
|
||||
clock.on('connection', onConnection);
|
||||
clock.on('remove', onRemove);
|
||||
clock.on('setFilter', setFilter);
|
||||
|
||||
function setFilter(){
|
||||
addon.emit('setFilter', 'filter24hours');
|
||||
}
|
||||
|
||||
function onInit(connections){
|
||||
// draw clock dial
|
||||
|
@ -47,9 +52,10 @@ function onInit(connections){
|
|||
fadeEarlierTrackers(timeToBucket(new Date()));
|
||||
};
|
||||
|
||||
function onConnection(connection){
|
||||
function onConnection(conn){
|
||||
// A connection has the following keys:
|
||||
// source (url), target (url), timestamp (int), contentType (str), cookie (bool), sourceVisited (bool), secure(bool), sourcePathDepth (int), sourceQueryDepth(int)
|
||||
var connection = aggregate.connectionAsObject(conn);
|
||||
aggregate.emit('connection', connection);
|
||||
var bucketIdx = timeToBucket(connection.timestamp);
|
||||
if (! clock.timeslots[bucketIdx]){
|
||||
|
@ -105,7 +111,7 @@ function onConnection(connection){
|
|||
}
|
||||
|
||||
function onRemove(){
|
||||
clearTimeout(handTimer);
|
||||
clearTimeout(clockTimer);
|
||||
clock.timeslots = new Array(96);
|
||||
resetCanvas();
|
||||
};
|
||||
|
|
|
@ -12,18 +12,20 @@ function initCap(str){
|
|||
|
||||
|
||||
function switchVisualization(name){
|
||||
if (currentVisualization === visualizations[name]) return;
|
||||
localStorage.visualization = initCap(name);
|
||||
console.log('switchVisualizations(' + name + ')');
|
||||
if (currentVisualization){
|
||||
if (currentVisualization === visualizations[name]) return;
|
||||
currentVisualization.emit('remove');
|
||||
}
|
||||
localStorage.visualization = initCap(name);
|
||||
currentVisualization = visualizations[name];
|
||||
currentVisualization.emit('setFilter');
|
||||
// toggle off info panel, settings page, help bubbles
|
||||
document.querySelector("#content").classList.remove("showinfo");
|
||||
document.querySelector(".settings-page").classList.add("hide");
|
||||
clearAllBubbles();
|
||||
// show vizcanvas again in case it is hidden
|
||||
document.querySelector(".vizcanvas").classList.remove("hide");
|
||||
|
||||
|
||||
addon.emit('uiready');
|
||||
}
|
||||
|
|
|
@ -20,6 +20,12 @@ graph.on('init', onInit);
|
|||
graph.on('connection', onConnection);
|
||||
graph.on('remove', onRemove);
|
||||
graph.on('reset', onReset);
|
||||
graph.on('setFilter', setFilter);
|
||||
|
||||
function setFilter(){
|
||||
//addon.emit('setFilter', 'filterLastXSites', 5);
|
||||
addon.emit('setFilter', 'filter24hours');
|
||||
}
|
||||
|
||||
function onInit(connections){
|
||||
console.log('initializing graph from %s connections', connections.length);
|
||||
|
@ -156,8 +162,6 @@ function updateGraph(){
|
|||
|
||||
}
|
||||
|
||||
window.updategGraph = updateGraph;
|
||||
|
||||
function addCircle(selection){
|
||||
selection
|
||||
.append('circle')
|
||||
|
|
13
data/list.js
13
data/list.js
|
@ -17,6 +17,11 @@ var columns = ["Type", "Site", "First Access", "Last Access"];
|
|||
list.on("init", OnInit);
|
||||
list.on("conneciton", onConnection);
|
||||
list.on("remove", onRemove);
|
||||
list.on('setFilter', setFilter);
|
||||
|
||||
function setFilter(){
|
||||
addon.emit('setFilter', 'filterNothing');
|
||||
}
|
||||
|
||||
|
||||
function OnInit(connections){
|
||||
|
@ -49,12 +54,12 @@ function initGraph(){
|
|||
breadcrumb = document.createElement("div");
|
||||
breadcrumb.classList.add("list-breadcrumb");
|
||||
document.querySelector(".stage").appendChild(breadcrumb);
|
||||
|
||||
|
||||
// list header
|
||||
header = document.createElement("div");
|
||||
header.classList.add("list-header");
|
||||
document.querySelector(".stage").appendChild(header);
|
||||
|
||||
|
||||
var table = document.createElement("table");
|
||||
table.classList.add("list-table");
|
||||
document.querySelector(".stage.list").appendChild(table);
|
||||
|
@ -86,7 +91,7 @@ function setFilteredBreadcrumb(filter){
|
|||
document.querySelector("#content").classList.remove("showinfo");
|
||||
showFilteredTable();
|
||||
},false);
|
||||
|
||||
|
||||
var headerText = document.createTextNode("Site that have connections linked from/to " + filter);
|
||||
header.appendChild(headerText);
|
||||
}
|
||||
|
@ -110,7 +115,7 @@ function setUnfilteredBreadcrumb(){
|
|||
var detailDiv = document.createElement("div");
|
||||
detailDiv.appendChild(detailTextNode);
|
||||
summaryDiv.appendChild(detailDiv);
|
||||
|
||||
|
||||
header.appendChild(summaryDiv);
|
||||
});
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@ const {on, once, off, emit} = require('sdk/event/core');
|
|||
|
||||
var allConnections = [];
|
||||
|
||||
var filters = {};
|
||||
|
||||
var filter24hours = function(connection){
|
||||
var now = new Date();
|
||||
var day = 24 * 60 * 60 * 1000;
|
||||
|
@ -26,17 +28,55 @@ var filter24hours = function(connection){
|
|||
return connection.timestamp > yesterday;
|
||||
}
|
||||
};
|
||||
filter24hours.filterType = 'filter';
|
||||
var connectionFilter = filter24hours; // default filter
|
||||
filters['filter24hours'] = filter24hours;
|
||||
|
||||
var filterNothing = function(connections){
|
||||
return connections;
|
||||
};
|
||||
filterNothing.filterType = 'function';
|
||||
filters['filterNothing'] = filterNothing;
|
||||
|
||||
var filterLastXSites = function(x){
|
||||
var siteFilter = function(connections){
|
||||
var siteIndices = [];
|
||||
for (var i = storage.connections.length - 1; i > -1; i--){
|
||||
var connection = storage.connections[i];
|
||||
if (connection[Connection.SOURCE_VISITED]){
|
||||
siteIndices.push(i);
|
||||
}
|
||||
if (siteIndices.length >= x){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (siteIndices.length){
|
||||
return storage.connections.slice(siteIndices.pop());
|
||||
}else{
|
||||
return storage.connections;
|
||||
}
|
||||
};
|
||||
siteFilter.filterType = 'function';
|
||||
return siteFilter;
|
||||
};
|
||||
|
||||
filters['filterLastXSites'] = filterLastXSites;
|
||||
|
||||
exports.Connection = Connection;
|
||||
exports.allConnections = [];
|
||||
exports.setConnectionFilter = setConnectionFilter;
|
||||
exports.getConnectionFilter = getConnectionFilter;
|
||||
exports.addConnection = addConnection;
|
||||
exports.exportFormat = exportFormat;
|
||||
exports.filteredConnections = filteredConnections;
|
||||
|
||||
function setConnectionFilter(filter){
|
||||
function setConnectionFilter(filter, arg){
|
||||
log('setConnectionFilter(' + filter + ', ' + arg + ')');
|
||||
if (arg){
|
||||
connectionFilter = filters[filter].call(null, arg);
|
||||
}else{
|
||||
connectionFilter = filters[filter];
|
||||
}
|
||||
log('connectionFilter is set: ' + !!connectionFilter);
|
||||
}
|
||||
|
||||
function getConnectionFilter(){
|
||||
|
@ -44,7 +84,13 @@ function getConnectionFilter(){
|
|||
}
|
||||
|
||||
function filteredConnections(){
|
||||
return allConnections.filter(connectionFilter);
|
||||
switch(connectionFilter.filterType){
|
||||
case 'function':
|
||||
return connectionFilter(storage.connections);
|
||||
case 'filter':
|
||||
default:
|
||||
return storage.connections.filter(connectionFilter);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Move persistence into a component
|
||||
|
@ -308,6 +354,7 @@ Connection.prototype.restoreFromArray = function(log){
|
|||
this.method = log[12] || 'GET';
|
||||
this.status = log[13] || 200;
|
||||
this.cacheable = log[14] || true;
|
||||
this.valid = true;
|
||||
Connection.restoredLogs += 1;
|
||||
return this;
|
||||
};
|
||||
|
@ -415,6 +462,7 @@ Connection.stopUpload = function(){
|
|||
Connection.on('startUpload', Connection.startUpload);
|
||||
Connection.on('stopUpload', Connection.stopUpload);
|
||||
Connection.on('reset', reset);
|
||||
Connection.on('setConnectionFilter', setConnectionFilter);
|
||||
if (storage.userHasOptedIntoSharing){
|
||||
Connection.startUpload();
|
||||
}
|
||||
|
@ -424,10 +472,10 @@ if (storage.userHasOptedIntoSharing){
|
|||
|
||||
function exportFormat(connections, lastSync){
|
||||
if (!connections){
|
||||
connections = storage.connections.map(Connection.fromObject);
|
||||
connections = storage.connections.map(Connection.restore);
|
||||
}
|
||||
if (!lastSync){
|
||||
lastSync = new Date(0).valueOf();
|
||||
lastSync = 0;
|
||||
}
|
||||
return JSON.stringify({
|
||||
format: 'Collusion Save File',
|
||||
|
|
10
lib/ui.js
10
lib/ui.js
|
@ -94,6 +94,10 @@ function attachToCollusionPage(worker) {
|
|||
Connection.on('restored', onRestored);
|
||||
});
|
||||
|
||||
worker.port.on('setFilter', function(filtername, filterarg){
|
||||
Connection.emit('setConnectionFilter', filtername, filterarg);
|
||||
});
|
||||
|
||||
var onConnection = function(connection){
|
||||
//console.error('connection: ' + connection);
|
||||
try{
|
||||
|
@ -123,7 +127,7 @@ function attachToCollusionPage(worker) {
|
|||
worker.port.on('stopUpload', function(){
|
||||
Connection.emit('stopUpload');
|
||||
});
|
||||
|
||||
|
||||
worker.port.on("summarize", function(){
|
||||
var firstTimestamp = new Date(allConnections[0].timestamp);
|
||||
var localTimeSince = firstTimestamp.getFullYear() + "-" +
|
||||
|
@ -132,11 +136,11 @@ function attachToCollusionPage(worker) {
|
|||
firstTimestamp.getHours() + ":" +
|
||||
firstTimestamp.getMinutes() + ":" +
|
||||
firstTimestamp.getSeconds();
|
||||
|
||||
|
||||
var summary = {};
|
||||
summary.localTimeSince = localTimeSince;
|
||||
summary.numConnections = allConnections.length;
|
||||
|
||||
|
||||
worker.port.emit("displaySummary", summary);
|
||||
});
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче