kopia lustrzana https://github.com/backface/turtlestitch
commit
1601dffddc
85
src/cloud.js
85
src/cloud.js
|
@ -28,10 +28,12 @@
|
|||
*/
|
||||
|
||||
// Global settings /////////////////////////////////////////////////////
|
||||
// cloud.js should be able to exist indepent of Snap!
|
||||
// (The module date is included for simplicity, but is not needed elsewhere.)
|
||||
|
||||
/*global modules, SnapSerializer, nop, hex_sha512, DialogBoxMorph, Color,
|
||||
normalizeCanvas*/
|
||||
/*global modules, hex_sha512*/
|
||||
|
||||
modules = modules || {};
|
||||
modules.cloud = '2019-January-17';
|
||||
|
||||
// Global stuff
|
||||
|
@ -45,10 +47,14 @@ function Cloud() {
|
|||
}
|
||||
|
||||
Cloud.prototype.init = function () {
|
||||
this.url = this.determineCloudDomain();
|
||||
this.urlBasePath = '/api/v1';
|
||||
this.url = this.determineCloudDomain() + this.urlBasePath;
|
||||
this.username = null;
|
||||
};
|
||||
|
||||
// Projects larger than this are rejected.
|
||||
Cloud.MAX_FILE_SIZE = 10 * 1024 * 1024;
|
||||
|
||||
Cloud.prototype.knownDomains = {
|
||||
'Snap!Cloud' : 'https://cloud.snap.berkeley.edu',
|
||||
'Snap!Cloud (cs10)' : 'https://snap-cloud.cs10.org',
|
||||
|
@ -144,6 +150,8 @@ Cloud.prototype.genericError = function () {
|
|||
throw new Error(Cloud.genericErrorMessage);
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Low level functionality
|
||||
|
||||
Cloud.prototype.request = function (
|
||||
|
@ -249,7 +257,7 @@ Cloud.prototype.initSession = function (onSuccess) {
|
|||
'POST',
|
||||
'/init',
|
||||
function () { myself.checkCredentials(onSuccess); },
|
||||
nop,
|
||||
function () {},
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
@ -369,7 +377,6 @@ Cloud.prototype.changePassword = function (
|
|||
onError,
|
||||
'Could not change password'
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
Cloud.prototype.resetPassword = function (username, onSuccess, onError) {
|
||||
|
@ -395,79 +402,19 @@ Cloud.prototype.resendVerification = function (username, onSuccess, onError) {
|
|||
|
||||
// Projects
|
||||
|
||||
Cloud.prototype.saveProject = function (ide, onSuccess, onError) {
|
||||
Cloud.prototype.saveProject = function (projectName, body, onSuccess, onError) {
|
||||
// Expects a body object with the following paramters:
|
||||
// xml, media, thumbnail, remixID (optional), notes (optional)
|
||||
var myself = this;
|
||||
this.checkCredentials(
|
||||
function (username) {
|
||||
if (username) {
|
||||
var xml = ide.serializer.serialize(ide.stage),
|
||||
thumbnail = normalizeCanvas(
|
||||
ide.stage.thumbnail(
|
||||
SnapSerializer.prototype.thumbnailSize
|
||||
)).toDataURL(),
|
||||
body, mediaSize, size;
|
||||
|
||||
ide.serializer.isCollectingMedia = true;
|
||||
body = {
|
||||
notes: ide.projectNotes,
|
||||
xml: xml,
|
||||
media: ide.hasChangedMedia ?
|
||||
ide.serializer.mediaXML(ide.projectName) : null,
|
||||
thumbnail: thumbnail,
|
||||
remixID: ide.stage.remixID
|
||||
};
|
||||
ide.serializer.isCollectingMedia = false;
|
||||
ide.serializer.flushMedia();
|
||||
|
||||
mediaSize = body.media ? body.media.length : 0;
|
||||
size = body.xml.length + mediaSize;
|
||||
if (mediaSize > 10485760) {
|
||||
new DialogBoxMorph().inform(
|
||||
'Snap!Cloud - Cannot Save Project',
|
||||
'The media inside this project exceeds 10 MB.\n' +
|
||||
'Please reduce the size of costumes or sounds.\n',
|
||||
ide.world(),
|
||||
ide.cloudIcon(null, new Color(180, 0, 0))
|
||||
);
|
||||
throw new Error('Project media exceeds 10 MB size limit');
|
||||
}
|
||||
|
||||
// check if serialized data can be parsed back again
|
||||
try {
|
||||
ide.serializer.parse(body.xml);
|
||||
} catch (err) {
|
||||
ide.showMessage(
|
||||
'Serialization of program data failed:\n' + err
|
||||
);
|
||||
throw new Error(
|
||||
'Serialization of program data failed:\n' + err
|
||||
);
|
||||
}
|
||||
if (body.media !== null) {
|
||||
try {
|
||||
ide.serializer.parse(body.media);
|
||||
} catch (err) {
|
||||
ide.showMessage(
|
||||
'Serialization of media failed:\n' + err
|
||||
);
|
||||
throw new Error(
|
||||
'Serialization of media failed:\n' + err
|
||||
);
|
||||
}
|
||||
}
|
||||
ide.serializer.isCollectingMedia = false;
|
||||
ide.serializer.flushMedia();
|
||||
|
||||
ide.showMessage(
|
||||
'Uploading ' + Math.round(size / 1024) + ' KB...'
|
||||
);
|
||||
|
||||
myself.request(
|
||||
'POST',
|
||||
'/projects/' +
|
||||
encodeURIComponent(username) +
|
||||
'/' +
|
||||
encodeURIComponent(ide.projectName),
|
||||
encodeURIComponent(projectName),
|
||||
onSuccess,
|
||||
onError,
|
||||
'Project could not be saved',
|
||||
|
|
104
src/gui.js
104
src/gui.js
|
@ -5583,17 +5583,85 @@ IDE_Morph.prototype.logout = function () {
|
|||
);
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.saveProjectToCloud = function (name) {
|
||||
var myself = this;
|
||||
if (name) {
|
||||
this.showMessage('Saving project\nto the cloud...');
|
||||
this.setProjectName(name);
|
||||
this.cloud.saveProject(
|
||||
this,
|
||||
function () {myself.showMessage('saved.', 2); },
|
||||
this.cloudError()
|
||||
IDE_Morph.prototype.buildProjectRequest = function () {
|
||||
var xml = this.serializer.serialize(this.stage),
|
||||
thumbnail = normalizeCanvas(
|
||||
this.stage.thumbnail(
|
||||
SnapSerializer.prototype.thumbnailSize
|
||||
)).toDataURL(),
|
||||
body;
|
||||
|
||||
this.serializer.isCollectingMedia = true;
|
||||
body = {
|
||||
notes: this.projectNotes,
|
||||
xml: xml,
|
||||
media: this.hasChangedMedia ?
|
||||
this.serializer.mediaXML(this.projectName) : null,
|
||||
thumbnail: thumbnail,
|
||||
remixID: this.stage.remixID
|
||||
};
|
||||
this.serializer.isCollectingMedia = false;
|
||||
this.serializer.flushMedia();
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
IDE_Morph.prototype.verifyProject = function (body) {
|
||||
// Ensure the project is less than 10MB and serializes correctly.
|
||||
var encodedBody = JSON.stringify(body);
|
||||
if (encodedBody.length > Cloud.MAX_FILE_SIZE) {
|
||||
new DialogBoxMorph().inform(
|
||||
'Snap!Cloud - Cannot Save Project',
|
||||
'The media inside this project exceeds 10 MB.\n' +
|
||||
'Please reduce the size of costumes or sounds.\n',
|
||||
this.world(),
|
||||
this.cloudIcon(null, new Color(180, 0, 0))
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log(encodedBody.length)
|
||||
// check if serialized data can be parsed back again
|
||||
try {
|
||||
this.serializer.parse(body.xml);
|
||||
} catch (err) {
|
||||
this.showMessage('Serialization of program data failed:\n' + err);
|
||||
return false;
|
||||
}
|
||||
if (body.media !== null) {
|
||||
try {
|
||||
this.serializer.parse(body.media);
|
||||
} catch (err) {
|
||||
this.showMessage('Serialization of media failed:\n' + err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this.serializer.isCollectingMedia = false;
|
||||
this.serializer.flushMedia();
|
||||
|
||||
return encodedBody.length;
|
||||
}
|
||||
|
||||
IDE_Morph.prototype.saveProjectToCloud = function (name) {
|
||||
var myself = this, projectBody, projectSize;
|
||||
|
||||
if (name) {
|
||||
this.setProjectName(name);
|
||||
}
|
||||
|
||||
this.showMessage('Saving project\nto the cloud...');
|
||||
projectBody = this.buildProjectRequest();
|
||||
projectSize = this.verifyProject(projectBody);
|
||||
if (!projectSize) {return; } // Invalid Projects don't return anything.
|
||||
this.showMessage(
|
||||
'Uploading ' + Math.round(projectSize / 1024) + ' KB...'
|
||||
);
|
||||
this.cloud.saveProject(
|
||||
this.projectName,
|
||||
projectBody,
|
||||
function () {myself.showMessage('saved.', 2); },
|
||||
this.cloudError()
|
||||
);
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.exportProjectMedia = function (name) {
|
||||
|
@ -5804,11 +5872,11 @@ IDE_Morph.prototype.getURL = function (url, callback, responseType) {
|
|||
async = callback instanceof Function,
|
||||
myself = this,
|
||||
rsp;
|
||||
if (async) {
|
||||
request.responseType = responseType || 'text';
|
||||
if (async) {
|
||||
request.responseType = responseType || 'text';
|
||||
}
|
||||
rsp = (!async || request.responseType === 'text') ? 'responseText'
|
||||
: 'response';
|
||||
: 'response';
|
||||
try {
|
||||
request.open('GET', url, async);
|
||||
if (async) {
|
||||
|
@ -6627,16 +6695,8 @@ ProjectDialogMorph.prototype.saveProject = function () {
|
|||
};
|
||||
|
||||
ProjectDialogMorph.prototype.saveCloudProject = function () {
|
||||
var myself = this;
|
||||
this.ide.showMessage('Saving project\nto the cloud...');
|
||||
this.ide.cloud.saveProject(
|
||||
this.ide,
|
||||
function () {
|
||||
myself.ide.source = 'cloud';
|
||||
myself.ide.showMessage('saved.', 2);
|
||||
},
|
||||
this.ide.cloudError()
|
||||
);
|
||||
this.ide.source = 'cloud';
|
||||
this.ide.saveProjectToCloud();
|
||||
this.destroy();
|
||||
};
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue