padDiff.js: convert to Promises/async

pull/3559/head
Ray Bellis 2019-01-31 14:38:56 +00:00
parent 4622309dc2
commit ccb49dcdc1
1 changed files with 93 additions and 175 deletions

View File

@ -1,7 +1,5 @@
var Changeset = require("../../static/js/Changeset"); var Changeset = require("../../static/js/Changeset");
var async = require("async");
var exportHtml = require('./ExportHtml'); var exportHtml = require('./ExportHtml');
const thenify = require("thenify").withCallback;
function PadDiff (pad, fromRev, toRev) { function PadDiff (pad, fromRev, toRev) {
// check parameters // check parameters
@ -79,79 +77,52 @@ PadDiff.prototype._isClearAuthorship = function(changeset) {
return true; return true;
}; };
PadDiff.prototype._createClearAuthorship = thenify(function(rev, callback) { PadDiff.prototype._createClearAuthorship = async function(rev) {
var self = this;
this._pad.getInternalRevisionAText(rev, function(err, atext) {
if (err) {
return callback(err);
}
// build clearAuthorship changeset let atext = await this._pad.getInternalRevisionAText(rev);
var builder = Changeset.builder(atext.text.length);
builder.keepText(atext.text, [['author','']], self._pad.pool);
var changeset = builder.toString();
callback(null, changeset); // build clearAuthorship changeset
}); var builder = Changeset.builder(atext.text.length);
}); builder.keepText(atext.text, [['author','']], this._pad.pool);
var changeset = builder.toString();
PadDiff.prototype._createClearStartAtext = thenify(function(rev, callback) { return changeset;
var self = this; }
PadDiff.prototype._createClearStartAtext = async function(rev) {
// get the atext of this revision // get the atext of this revision
this._pad.getInternalRevisionAText(rev, function(err, atext) { let atext = this._pad.getInternalRevisionAText(rev);
if (err) {
return callback(err);
}
// create the clearAuthorship changeset // create the clearAuthorship changeset
self._createClearAuthorship(rev, function(err, changeset) { let changeset = await this._createClearAuthorship(rev);
if (err) {
return callback(err);
}
try { // apply the clearAuthorship changeset
// apply the clearAuthorship changeset let newAText = Changeset.applyToAText(changeset, atext, this._pad.pool);
var newAText = Changeset.applyToAText(changeset, atext, self._pad.pool);
} catch(err) {
return callback(err)
}
callback(null, newAText); return newAText;
}); }
});
});
PadDiff.prototype._getChangesetsInBulk = thenify(function(startRev, count, callback) { PadDiff.prototype._getChangesetsInBulk = async function(startRev, count) {
var self = this;
// find out which revisions we need // find out which revisions we need
var revisions = []; let revisions = [];
for (var i = startRev; i < (startRev + count) && i <= this._pad.head; i++) { for (let i = startRev; i < (startRev + count) && i <= this._pad.head; i++) {
revisions.push(i); revisions.push(i);
} }
var changesets = [], authors = []; // get all needed revisions (in parallel)
let changesets = [], authors = [];
// get all needed revisions await Promise.all(revisions.map(rev => {
async.forEach(revisions, function(rev, callback) { return this._pad.getRevision(rev).then(revision => {
self._pad.getRevision(rev, function(err, revision) { let arrayNum = rev - startRev;
if (err) {
return callback(err);
}
var arrayNum = rev-startRev;
changesets[arrayNum] = revision.changeset; changesets[arrayNum] = revision.changeset;
authors[arrayNum] = revision.meta.author; authors[arrayNum] = revision.meta.author;
callback();
}); });
}, }));
function(err) {
callback(err, changesets, authors); return { changesets, authors };
}); }
});
PadDiff.prototype._addAuthors = function(authors) { PadDiff.prototype._addAuthors = function(authors) {
var self = this; var self = this;
@ -164,144 +135,91 @@ PadDiff.prototype._addAuthors = function(authors) {
}); });
}; };
PadDiff.prototype._createDiffAtext = thenify(function(callback) { PadDiff.prototype._createDiffAtext = async function() {
var self = this;
var bulkSize = 100; let bulkSize = 100;
// get the cleaned startAText // get the cleaned startAText
self._createClearStartAtext(self._fromRev, function(err, atext) { let atext = await this._createClearStartAtext(this._fromRev);
if (err) { return callback(err); }
var superChangeset = null; let superChangeset = null;
let rev = this._fromRev + 1;
var rev = self._fromRev + 1; for (let rev = this._fromRev + 1; rev <= this._toRev; rev += bulkSize) {
// async while loop // get the bulk
async.whilst( let { changesets, authors } = await this._getChangesetsInBulk(rev, bulkSize);
// loop condition
function () { return rev <= self._toRev; },
// loop body let addedAuthors = [];
function (callback) {
// get the bulk
self._getChangesetsInBulk(rev,bulkSize,function(err, changesets, authors) {
var addedAuthors = [];
// run trough all changesets // run through all changesets
for (var i = 0; i < changesets.length && (rev + i) <= self._toRev; i++) { for (let i = 0; i < changesets.length && (rev + i) <= this._toRev; ++i) {
var changeset = changesets[i]; let changeset = changesets[i];
// skip clearAuthorship Changesets // skip clearAuthorship Changesets
if (self._isClearAuthorship(changeset)) { if (this._isClearAuthorship(changeset)) {
continue; continue;
}
changeset = self._extendChangesetWithAuthor(changeset, authors[i], self._pad.pool);
// add this author to the authorarray
addedAuthors.push(authors[i]);
// compose it with the superChangset
if (superChangeset === null) {
superChangeset = changeset;
} else {
superChangeset = Changeset.composeWithDeletions(superChangeset, changeset, self._pad.pool);
}
}
// add the authors to the PadDiff authorArray
self._addAuthors(addedAuthors);
// lets continue with the next bulk
rev += bulkSize;
callback();
});
},
// after the loop has ended
function (err) {
// if there are only clearAuthorship changesets, we don't get a superChangeset, so we can skip this step
if (superChangeset) {
var deletionChangeset = self._createDeletionChangeset(superChangeset,atext,self._pad.pool);
try {
// apply the superChangeset, which includes all addings
atext = Changeset.applyToAText(superChangeset, atext, self._pad.pool);
// apply the deletionChangeset, which adds a deletions
atext = Changeset.applyToAText(deletionChangeset, atext, self._pad.pool);
} catch(err) {
return callback(err)
}
}
callback(err, atext);
} }
);
});
});
PadDiff.prototype.getHtml = thenify(function(callback) { changeset = this._extendChangesetWithAuthor(changeset, authors[i], this._pad.pool);
// add this author to the authorarray
addedAuthors.push(authors[i]);
// compose it with the superChangset
if (superChangeset === null) {
superChangeset = changeset;
} else {
superChangeset = Changeset.composeWithDeletions(superChangeset, changeset, this._pad.pool);
}
}
// add the authors to the PadDiff authorArray
this._addAuthors(addedAuthors);
}
// if there are only clearAuthorship changesets, we don't get a superChangeset, so we can skip this step
if (superChangeset) {
let deletionChangeset = this._createDeletionChangeset(superChangeset, atext, this._pad.pool);
// apply the superChangeset, which includes all addings
atext = Changeset.applyToAText(superChangeset, atext, this._pad.pool);
// apply the deletionChangeset, which adds a deletions
atext = Changeset.applyToAText(deletionChangeset, atext, this._pad.pool);
}
return atext;
}
PadDiff.prototype.getHtml = async function() {
// cache the html // cache the html
if (this._html != null) { if (this._html != null) {
return callback(null, this._html); return this._html;
} }
var self = this; // get the diff atext
var atext, html, authorColors; let atext = await this._createDiffAtext();
async.series([ // get the authorColor table
// get the diff atext let authorColors = await this._pad.getAllAuthorColors();
function(callback) {
self._createDiffAtext(function(err, _atext) {
if (err) {
return callback(err);
}
atext = _atext; // convert the atext to html
callback(); this._html = exportHtml.getHTMLFromAtext(this._pad, atext, authorColors);
});
},
// get the authorColor table return this._html;
function(callback) { }
self._pad.getAllAuthorColors(function(err, _authorColors) {
if (err) {
return callback(err);
}
authorColors = _authorColors; PadDiff.prototype.getAuthors = async function() {
callback();
});
},
// convert the atext to html
function(callback) {
html = exportHtml.getHTMLFromAtext(self._pad, atext, authorColors);
self._html = html;
callback();
}
],
function(err) {
callback(err, html);
});
});
PadDiff.prototype.getAuthors = thenify(function(callback) {
var self = this;
// check if html was already produced, if not produce it, this generates the author array at the same time // check if html was already produced, if not produce it, this generates the author array at the same time
if (self._html == null) { if (this._html == null) {
self.getHtml(function(err) { await this.getHtml();
if (err) {
return callback(err);
}
callback(null, self._authors);
});
} else {
callback(null, self._authors);
} }
});
return self._authors;
}
PadDiff.prototype._extendChangesetWithAuthor = function(changeset, author, apool) { PadDiff.prototype._extendChangesetWithAuthor = function(changeset, author, apool) {
// unpack // unpack