diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 393a82c11..9f67f0dd9 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -764,8 +764,6 @@ define([ if (bytes === 0) { return void cb(void 0, $d); } var formatted = UIElements.prettySize(bytes); - historyBytes = Math.floor(0.2*bytes); // XXX test data - if (!owned || !historyBytes || historyBytes > bytes) { $d.append(h('div.cp-app-prop', [Messages.upload_size, h('br'), h('span.cp-app-prop-content', formatted)])); return void cb(void 0, $d); diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 152b9c9f9..7f54ef6c6 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -429,10 +429,12 @@ define([ }); }; - Store.getFileSize = function (clientId, data, cb) { + Store.getFileSize = function (clientId, data, _cb) { + var cb = Util.once(Util.mkAsync(_cb)); + if (!store.anon_rpc) { return void cb({error: 'ANON_RPC_NOT_READY'}); } - var channelId = Hash.hrefToHexChannelId(data.href, data.password); + var channelId = data.channel || Hash.hrefToHexChannelId(data.href, data.password); store.anon_rpc.send("GET_FILE_SIZE", channelId, function (e, response) { if (e) { return void cb({error: e}); } if (response && response.length && typeof(response[0]) === 'number') { @@ -1761,7 +1763,9 @@ define([ // Fetch the latest version of the metadata on the server and return it. // If the pad is stored in our drive, update the local values of "owners" and "expire" - Store.getPadMetadata = function (clientId, data, cb) { + Store.getPadMetadata = function (clientId, data, _cb) { + var cb = Util.once(Util.mkAsync(_cb)); + if (!data.channel) { return void cb({ error: 'ENOTFOUND'}); } store.anon_rpc.send('GET_METADATA', data.channel, function (err, obj) { if (err) { return void cb({error: err}); } @@ -1843,7 +1847,9 @@ define([ network.sendto(hk, JSON.stringify(['GET_FULL_HISTORY', data.channel, data.validateKey])); }; - Store.getHistory = function (clientId, data, cb) { + Store.getHistory = function (clientId, data, _cb, full) { + var cb = Util.once(Util.mkAsync(_cb)); + var network = store.network; var hk = network.historyKeeper; diff --git a/www/common/outer/history.js b/www/common/outer/history.js index 5bc77cd35..43860decb 100644 --- a/www/common/outer/history.js +++ b/www/common/outer/history.js @@ -52,6 +52,12 @@ define([ return channels; }; + var getEdPublic = function (ctx, teamId) { + if (!teamId) { return Util.find(ctx.store, ['proxy', 'edPublic']); } + + var teamData = Util.find(ctx, ['store', 'proxy', 'teams', teamId]); + return Util.find(teamData, ['keys', 'drive', 'edPublic']); + }; var getRpc = function (ctx, teamId) { if (!teamId) { return ctx.store.rpc; } var teams = ctx.store.modules['team']; @@ -61,14 +67,77 @@ define([ return team.rpc; }; + var getHistoryData = function (ctx, channel, lastKnownHash, teamId, _cb) { + var cb = Util.once(Util.mkAsync(_cb)); + var edPublic = getEdPublic(ctx, teamId); + var Store = ctx.Store; + + var total = 0; + var history = 0; + var metadata = 0; + var hash; + nThen(function (waitFor) { + // Total size + Store.getFileSize(null, { + channel: channel + }, waitFor(function (obj) { + if (obj && obj.error) { + waitFor.abort(); + return void cb(obj); + } + if (typeof(obj.size) === "undefined") { + waitFor.abort(); + return void cb({error: 'ENOENT'}); + } + total = obj.size; + })); + // Pad + Store.getHistory(null, { + channel: channel, + lastKnownHash: lastKnownHash + }, waitFor(function (obj) { + if (obj && obj.error) { + waitFor.abort(); + return void cb(obj); + } + if (!Array.isArray(obj)) { + waitFor.abort(); + return void cb({error: 'EINVAL'}); + } + + hash = obj[0].hash; + var messages = obj.map(function(data) { + return data.msg; + }); + history = messages.join('\n').length; + }), true); + // Metadata + Store.getPadMetadata(null, { + channel: channel + }, waitFor(function (obj) { + if (obj && obj.error) { return; } + if (!obj || typeof(obj) !== "object") { return; } + metadata = JSON.stringify(obj).length; + if (!obj || !Array.isArray(obj.owners) || + obj.owners.indexOf(edPublic) === -1) { + waitFor.abort(); + return void cb({error: 'INSUFFICIENT_PERMISSIONS'}); + } + })); + }).nThen(function () { + cb({ + size: (total - metadata - history), + hash: hash + }); + }); + + }; + commands.GET_HISTORY_SIZE = function (ctx, data, cId, cb) { if (!ctx.store.loggedIn || !ctx.store.rpc) { return void cb({ error: 'INSUFFICIENT_PERMISSIONS' }); } var channels = data.channels; if (!Array.isArray(channels)) { return void cb({ error: 'EINVAL' }); } - var rpc = getRpc(ctx, data.teamid); - if (!rpc) { return void cb({ error: 'ENORPC'}); } - var warning = []; // If account trim history, get the correct channels here @@ -77,30 +146,26 @@ define([ } var size = 0; + var res = []; nThen(function (waitFor) { - // TODO: check if owner first? channels.forEach(function (chan) { - size += Math.floor(Math.random()*1000) * 1024; // XXX - chan = chan; // XXX - waitFor = waitFor; // XXX - /* var channel = chan; var lastKnownHash; if (typeof (chan) === "object" && chan.channel) { channel = chan.channel; lastKnownHash = chan.lastKnownHash; } - rpc.getHistorySize({ - channel: channel, - lastKnownHash: lastKnownHash - }, waitFor(function (err, value) { - if (err) { - warning.push(err); + getHistoryData(ctx, channel, lastKnownHash, data.teamId, waitFor(function (obj) { + if (obj && obj.error) { + warning.push(obj.error); return; } - size += value; + size += obj.size; + res.push({ + channel: channel, + lastKnownHash: obj.hash + }); })); - */ // XXX TODO }); }).nThen(function () { cb({ @@ -115,7 +180,7 @@ define([ var channels = data.channels; if (!Array.isArray(channels)) { return void cb({ error: 'EINVAL' }); } - var rpc = getRpc(ctx, data.teamid); + var rpc = getRpc(ctx, data.teamId); if (!rpc) { return void cb({ error: 'ENORPC'}); } var warning = []; diff --git a/www/settings/inner.js b/www/settings/inner.js index 9c352390f..8270c7c2d 100644 --- a/www/settings/inner.js +++ b/www/settings/inner.js @@ -1203,7 +1203,7 @@ define([ // XXX settings_trimHistoryTitle, settings_trimHistoryHint, trimHistory_button, trimHistory_error // XXX trimHistory_success, trimHistory_confirm - if (!privateData.isDriveOwned) { return; } // XXX + //if (!privateData.isDriveOwned) { return; } // XXX var spinner = UI.makeSpinner(); var button = h('button.btn.btn-danger-alt', {