Improved error handling when upgrading content.
parent
a38a0f1253
commit
2011e856c0
|
@ -2,18 +2,18 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
|
||||
(function ($) {
|
||||
var info, $container, librariesCache = {};
|
||||
|
||||
|
||||
// Initialize
|
||||
$(document).ready(function () {
|
||||
// Get library info
|
||||
info = H5PIntegration.getLibraryInfo();
|
||||
|
||||
|
||||
// Get and reset container
|
||||
$container = $('#h5p-admin-container').html('<p>' + info.message + '</p>');
|
||||
|
||||
|
||||
// Make it possible to select version
|
||||
var $version = $(getVersionSelect(info.versions)).appendTo($container);
|
||||
|
||||
|
||||
// Add "go" button
|
||||
$('<button/>', {
|
||||
class: 'h5p-admin-upgrade-button',
|
||||
|
@ -23,11 +23,11 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
new ContentUpgrade($version.val());
|
||||
}
|
||||
}).appendTo($container);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Generate html for version select.
|
||||
*
|
||||
*
|
||||
* @param {Object} versions
|
||||
* @returns {String}
|
||||
*/
|
||||
|
@ -41,18 +41,18 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
return html;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Private. Helps process each property on the given object asynchronously in serial order.
|
||||
*
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @param {Function} process
|
||||
* @param {Function} finished
|
||||
*/
|
||||
var asyncSerial = function (obj, process, finished) {
|
||||
var id, isArray = obj instanceof Array;
|
||||
|
||||
// Keep track of each property that belongs to this object.
|
||||
|
||||
// Keep track of each property that belongs to this object.
|
||||
if (!isArray) {
|
||||
var ids = [];
|
||||
for (id in obj) {
|
||||
|
@ -61,9 +61,9 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var i = -1; // Keeps track of the current property
|
||||
|
||||
|
||||
/**
|
||||
* Private. Process the next property
|
||||
*/
|
||||
|
@ -71,10 +71,10 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
id = isArray ? i : ids[i];
|
||||
process(id, obj[id], check);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Private. Check if we're done or have an error.
|
||||
*
|
||||
*
|
||||
* @param {String} err
|
||||
*/
|
||||
var check = function (err) {
|
||||
|
@ -89,13 +89,13 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
}
|
||||
}, 0);
|
||||
};
|
||||
|
||||
|
||||
check(); // Start
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Make it easy to keep track of version details.
|
||||
*
|
||||
*
|
||||
* @param {String} version
|
||||
* @param {Number} libraryId
|
||||
* @returns {_L1.Version}
|
||||
|
@ -103,19 +103,19 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
function Version(version, libraryId) {
|
||||
if (libraryId !== undefined) {
|
||||
version = info.versions[libraryId];
|
||||
|
||||
|
||||
// Public
|
||||
this.libraryId = libraryId;
|
||||
}
|
||||
var versionSplit = version.split('.', 3);
|
||||
|
||||
|
||||
// Public
|
||||
this.major = versionSplit[0];
|
||||
this.minor = versionSplit[1];
|
||||
|
||||
|
||||
/**
|
||||
* Public. Custom string for this object.
|
||||
*
|
||||
*
|
||||
* @returns {String}
|
||||
*/
|
||||
this.toString = function () {
|
||||
|
@ -125,17 +125,17 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
|
||||
/**
|
||||
* Displays a throbber in the status field.
|
||||
*
|
||||
*
|
||||
* @param {String} msg
|
||||
* @returns {_L1.Throbber}
|
||||
*/
|
||||
function Throbber(msg) {
|
||||
var $throbber = H5PUtils.throbber(msg);
|
||||
$container.html('').append($throbber);
|
||||
|
||||
|
||||
/**
|
||||
* Makes it possible to set the progress.
|
||||
*
|
||||
*
|
||||
* @param {String} progress
|
||||
*/
|
||||
this.setProgress = function (progress) {
|
||||
|
@ -145,16 +145,16 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
|
||||
/**
|
||||
* Start a new content upgrade.
|
||||
*
|
||||
*
|
||||
* @param {Number} libraryId
|
||||
* @returns {_L1.ContentUpgrade}
|
||||
*/
|
||||
function ContentUpgrade(libraryId) {
|
||||
var self = this;
|
||||
|
||||
|
||||
// Get selected version
|
||||
self.version = new Version(null, libraryId);
|
||||
|
||||
|
||||
// Create throbber with loading text and progress
|
||||
self.throbber = new Throbber(info.inProgress.replace('%ver', self.version));
|
||||
|
||||
|
@ -164,36 +164,36 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
token: info.token
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the next batch and start processing it.
|
||||
*
|
||||
*
|
||||
* @param {Object} outData
|
||||
*/
|
||||
ContentUpgrade.prototype.nextBatch = function (outData) {
|
||||
var self = this;
|
||||
|
||||
|
||||
$.post(info.infoUrl, outData, function (inData) {
|
||||
if (!(inData instanceof Object)) {
|
||||
// Print errors from backend
|
||||
return self.setStatus(inData);
|
||||
}
|
||||
}
|
||||
if (inData.left === 0) {
|
||||
// Nothing left to process
|
||||
return self.setStatus(info.done);
|
||||
}
|
||||
|
||||
|
||||
self.left = inData.left;
|
||||
self.token = inData.token;
|
||||
|
||||
|
||||
// Start processing
|
||||
self.processBatch(inData.params);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set current status message.
|
||||
*
|
||||
*
|
||||
* @param {String} msg
|
||||
*/
|
||||
ContentUpgrade.prototype.setStatus = function (msg) {
|
||||
|
@ -202,28 +202,37 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
|
||||
/**
|
||||
* Process the given parameters.
|
||||
*
|
||||
*
|
||||
* @param {Object} parameters
|
||||
*/
|
||||
ContentUpgrade.prototype.processBatch = function (parameters) {
|
||||
var self = this;
|
||||
var upgraded = {}; // Track upgraded params
|
||||
|
||||
|
||||
var current = 0; // Track progress
|
||||
asyncSerial(parameters, function (id, params, next) {
|
||||
|
||||
// Make params possible to work with
|
||||
params = JSON.parse(params);
|
||||
|
||||
try {
|
||||
// Make params possible to work with
|
||||
params = JSON.parse(params);
|
||||
if (!(params instanceof Object)) {
|
||||
throw true;
|
||||
}
|
||||
}
|
||||
catch (event) {
|
||||
return next(info.errorContent.replace('%id', id) + ' ' + info.errorParamsBroken);
|
||||
}
|
||||
|
||||
// Upgrade this content.
|
||||
self.upgrade(info.library.name, new Version(info.library.version), self.version, params, function (err, params) {
|
||||
if (!err) {
|
||||
upgraded[id] = JSON.stringify(params);
|
||||
|
||||
current++;
|
||||
self.throbber.setProgress(Math.round((info.total - self.left + current) / (info.total / 100)) + ' %');
|
||||
if (err) {
|
||||
return next(info.errorContent.replace('%id', id) + ' ' + err);
|
||||
}
|
||||
next(err);
|
||||
|
||||
upgraded[id] = JSON.stringify(params);
|
||||
|
||||
current++;
|
||||
self.throbber.setProgress(Math.round((info.total - self.left + current) / (info.total / 100)) + ' %');
|
||||
next();
|
||||
});
|
||||
|
||||
}, function (err) {
|
||||
|
@ -240,10 +249,10 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Upgade the given content.
|
||||
*
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Version} oldVersion
|
||||
* @param {Version} newVersion
|
||||
|
@ -253,19 +262,19 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
*/
|
||||
ContentUpgrade.prototype.upgrade = function (name, oldVersion, newVersion, params, next) {
|
||||
var self = this;
|
||||
|
||||
|
||||
// Load library details and upgrade routines
|
||||
self.loadLibrary(name, newVersion, function (err, library) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
|
||||
// Run upgrade routines on params
|
||||
self.processParams(library, oldVersion, newVersion, params, function (err, params) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
|
||||
// Check if any of the sub-libraries need upgrading
|
||||
asyncSerial(library.semantics, function (index, field, next) {
|
||||
self.processField(field, params[field.name], function (err, upgradedParams) {
|
||||
|
@ -280,24 +289,24 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Load library data needed for content upgrade.
|
||||
*
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Version} version
|
||||
* @param {Function} next
|
||||
*/
|
||||
ContentUpgrade.prototype.loadLibrary = function (name, version, next) {
|
||||
var self = this;
|
||||
|
||||
|
||||
var key = name + '/' + version.major + '/' + version.minor;
|
||||
if (librariesCache[key] !== undefined) {
|
||||
// Library has been loaded before. Return cache.
|
||||
next(null, librariesCache[key]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$.ajax({
|
||||
dataType: 'json',
|
||||
cache: true,
|
||||
|
@ -306,7 +315,7 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
next(info.errorData.replace('%lib', name + ' ' + version));
|
||||
}).done(function (library) {
|
||||
librariesCache[key] = library;
|
||||
|
||||
|
||||
if (library.upgradesScript) {
|
||||
self.loadScript(library.upgradesScript, function (err) {
|
||||
if (err) {
|
||||
|
@ -320,10 +329,10 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Load script with upgrade hooks.
|
||||
*
|
||||
*
|
||||
* @param {String} url
|
||||
* @param {Function} next
|
||||
*/
|
||||
|
@ -338,10 +347,10 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
next();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Run upgrade hooks on params.
|
||||
*
|
||||
*
|
||||
* @param {Object} library
|
||||
* @param {Version} oldVersion
|
||||
* @param {Version} newVersion
|
||||
|
@ -354,7 +363,7 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
// Upgrades script should be loaded so the upgrades should be here.
|
||||
return next(info.errorScript.replace('%lib', library.name + ' ' + newVersion));
|
||||
}
|
||||
|
||||
|
||||
// No upgrades script. Move on
|
||||
return next(null, params);
|
||||
}
|
||||
|
@ -362,7 +371,7 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
// Run upgrade hooks. Start by going through major versions
|
||||
asyncSerial(H5PUpgrades[library.name], function (major, minors, nextMajor) {
|
||||
if (major < oldVersion.major || major > newVersion.major) {
|
||||
// Older than the current version or newer than the selected
|
||||
// Older than the current version or newer than the selected
|
||||
nextMajor();
|
||||
}
|
||||
else {
|
||||
|
@ -374,14 +383,16 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
}
|
||||
else {
|
||||
// We found an upgrade hook, run it
|
||||
if (upgrade.contentUpgrade !== undefined && typeof upgrade.contentUpgrade === 'function') {
|
||||
upgrade.contentUpgrade(params, function (err, upgradedParams) {
|
||||
var unnecessaryWrapper = (upgrade.contentUpgrade !== undefined ? upgrade.contentUpgrade : upgrade);
|
||||
|
||||
try {
|
||||
unnecessaryWrapper(params, function (err, upgradedParams) {
|
||||
params = upgradedParams;
|
||||
nextMinor(err);
|
||||
});
|
||||
}
|
||||
else {
|
||||
nextMinor(info.errorScript.replace('%lib', library.name + ' ' + newVersion));
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
}
|
||||
}, nextMajor);
|
||||
|
@ -390,27 +401,27 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
next(err, params);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Process parameter fields to find and upgrade sub-libraries.
|
||||
*
|
||||
*
|
||||
* @param {Object} field
|
||||
* @param {Object} params
|
||||
* @param {Function} next
|
||||
*/
|
||||
ContentUpgrade.prototype.processField = function (field, params, next) {
|
||||
var self = this;
|
||||
|
||||
|
||||
if (params === undefined) {
|
||||
return next();
|
||||
}
|
||||
|
||||
|
||||
switch (field.type) {
|
||||
case 'library':
|
||||
if (params.library === undefined || params.params === undefined) {
|
||||
return next();
|
||||
}
|
||||
|
||||
|
||||
// Look for available upgrades
|
||||
var usedLib = params.library.split(' ', 2);
|
||||
for (var i = 0; i < field.options.length; i++) {
|
||||
|
@ -419,14 +430,14 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
if (availableLib[1] === usedLib[1]) {
|
||||
return next(); // Same version
|
||||
}
|
||||
|
||||
|
||||
// We have different versions
|
||||
var usedVer = new Version(usedLib[1]);
|
||||
var availableVer = new Version(availableLib[1]);
|
||||
if (usedVer.major > availableVer.major || (usedVer.major === availableVer.major && usedVer.minor >= availableVer.minor)) {
|
||||
return next(); // Larger or same version that's available
|
||||
}
|
||||
|
||||
|
||||
// A newer version is available, upgrade params
|
||||
return self.upgrade(availableLib[0], usedVer, availableVer, params.params, function (err, upgraded) {
|
||||
if (!err) {
|
||||
|
@ -484,4 +495,4 @@ var H5PUpgrades = H5PUpgrades || {};
|
|||
}
|
||||
};
|
||||
|
||||
})(H5P.jQuery);
|
||||
})(H5P.jQuery);
|
||||
|
|
Loading…
Reference in New Issue