blob: 862313ab1ca50dad6a4ee55c4779c277c32b0112 [file] [log] [blame]
/*
*Licensed to the Apache Software Foundation (ASF) under one
*or more contributor license agreements. See the NOTICE file
*distributed with this work for additional information
*regarding copyright ownership. The ASF licenses this file
*to you under the Apache License, Version 2.0 (the
*"License"); you may not use this file except in compliance
*with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*Unless required by applicable law or agreed to in writing,
*software distributed under the License is distributed on an
*"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
*KIND, either express or implied. See the License for the
*specific language governing permissions and limitations
*under the License.
*/
/*
* XMLHttpRequest.prototype.sendAsBinary polyfill
* from: https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#sendAsBinary()
*
* @method sendAsBinary
* @param {string} sData
*/
if (!XMLHttpRequest.prototype.sendAsBinary) {
XMLHttpRequest.prototype.sendAsBinary = function(sData) {
var nBytes = sData.length,
ui8Data = new Uint8Array(nBytes);
for (var nIdx = 0; nIdx < nBytes; nIdx++) {
ui8Data[nIdx] = sData.charCodeAt(nIdx) & 0xff;
}
this.send(ui8Data);
};
}
/*
* A class to model a Usergrid asset.
*
* @constructor
* @param {object} options {name:"photo.jpg", path:"/user/uploads", "content-type":"image/jpeg", owner:"F01DE600-0000-0000-0000-000000000000" }
* @returns {callback} callback(err, asset)
*/
Usergrid.Asset = function(options, callback) {
var self = this,
messages = [];
self._client = options.client;
self._data = options.data || {};
self._data.type = "assets";
var missingData = ["name", "owner", "path"].some(function(required) {
return !(required in self._data);
});
if (missingData) {
doCallback(callback, [new UsergridError("Invalid asset data: 'name', 'owner', and 'path' are required properties."), null, self], self);
} else {
self.save(function(err, data) {
if (err) {
doCallback(callback, [new UsergridError(data), data, self], self);
} else {
if (data && data.entities && data.entities.length) {
self.set(data.entities[0]);
}
doCallback(callback, [null, data, self], self);
}
});
}
};
/*
* Inherit from Usergrid.Entity.
*/
Usergrid.Asset.prototype = new Usergrid.Entity();
/*
* Add an asset to a folder.
*
* @method connect
* @public
* @param {object} options {folder:"F01DE600-0000-0000-0000-000000000000"}
* @returns {callback} callback(err, asset)
*/
Usergrid.Asset.prototype.addToFolder = function(options, callback) {
var self = this,
error = null;
if (('folder' in options) && isUUID(options.folder)) {
//we got a valid UUID
var folder = Usergrid.Folder({
uuid: options.folder
}, function(err, folder) {
if (err) {
doCallback(callback, [UsergridError.fromResponse(folder), folder, self], self);
} else {
var endpoint = ["folders", folder.get("uuid"), "assets", self.get("uuid")].join('/');
var options = {
method: 'POST',
endpoint: endpoint
};
this._client.request(options, function(err, response) {
if (err) {
doCallback(callback, [UsergridError.fromResponse(folder), response, self], self);
} else {
doCallback(callback, [null, folder, self], self);
}
});
}
});
} else {
doCallback(callback, [new UsergridError('folder not specified'), null, self], self);
}
};
Usergrid.Entity.prototype.attachAsset = function (file, callback) {
if (!(window.File && window.FileReader && window.FileList && window.Blob)) {
doCallback(callback, [ new UsergridError("The File APIs are not fully supported by your browser."), null, this ], this);
return;
}
var self = this;
var args = arguments;
var type = this._data.type;
var attempts = self.get("attempts");
if (isNaN(attempts)) {
attempts = 3;
}
if(type != 'assets' && type != 'asset') {
var endpoint = [ this._client.URI, this._client.orgName, this._client.appName, type, self.get("uuid") ].join("/");
} else {
self.set("content-type", file.type);
self.set("size", file.size);
var endpoint = [ this._client.URI, this._client.orgName, this._client.appName, "assets", self.get("uuid"), "data" ].join("/");
}
var xhr = new XMLHttpRequest();
xhr.open("POST", endpoint, true);
xhr.onerror = function(err) {
doCallback(callback, [ new UsergridError("The File APIs are not fully supported by your browser.") ], xhr, self);
};
xhr.onload = function(ev) {
if (xhr.status >= 500 && attempts > 0) {
self.set("attempts", --attempts);
setTimeout(function() {
self.attachAsset.apply(self, args);
}, 100);
} else if (xhr.status >= 300) {
self.set("attempts");
doCallback(callback, [ new UsergridError(JSON.parse(xhr.responseText)), xhr, self ], self);
} else {
self.set("attempts");
self.fetch();
doCallback(callback, [ null, xhr, self ], self);
}
};
var fr = new FileReader();
fr.onload = function() {
var binary = fr.result;
if (type === 'assets' || type === 'asset') {
xhr.overrideMimeType("application/octet-stream");
xhr.setRequestHeader("Content-Type", "application/octet-stream");
}
xhr.sendAsBinary(binary);
};
fr.readAsBinaryString(file);
};
/*
* Upload Asset data
*
* @method upload
* @public
* @param {object} data Can be a javascript Blob or File object
* @returns {callback} callback(err, asset)
*/
Usergrid.Asset.prototype.upload = function(data, callback) {
this.attachAsset(data, function(err, response) {
if(!err){
doCallback(callback, [ null, response, self ], self);
} else {
doCallback(callback, [ new UsergridError(err), response, self ], self);
}
});
};
/*
* Download Asset data
*
* @method download
* @public
* @returns {callback} callback(err, blob) blob is a javascript Blob object.
*/
Usergrid.Entity.prototype.downloadAsset = function(callback) {
var self = this;
var endpoint;
var type = this._data.type;
var xhr = new XMLHttpRequest();
if(type != "assets" && type != 'asset') {
endpoint = [ this._client.URI, this._client.orgName, this._client.appName, type, self.get("uuid") ].join("/");
} else {
endpoint = [ this._client.URI, this._client.orgName, this._client.appName, "assets", self.get("uuid"), "data" ].join("/");
}
xhr.open("GET", endpoint, true);
xhr.responseType = "blob";
xhr.onload = function(ev) {
var blob = xhr.response;
if(type != "assets" && type != 'asset') {
doCallback(callback, [ null, blob, xhr ], self);
} else {
doCallback(callback, [ null, xhr, self ], self);
}
};
xhr.onerror = function(err) {
callback(true, err);
doCallback(callback, [ new UsergridError(err), xhr, self ], self);
};
if(type != "assets" && type != 'asset') {
xhr.setRequestHeader("Accept", self._data["file-metadata"]["content-type"]);
} else {
xhr.overrideMimeType(self.get("content-type"));
}
xhr.send();
};
/*
* Download Asset data
*
* @method download
* @public
* @returns {callback} callback(err, blob) blob is a javascript Blob object.
*/
Usergrid.Asset.prototype.download = function(callback) {
this.downloadAsset(function(err, response) {
if(!err){
doCallback(callback, [ null, response, self ], self);
} else {
doCallback(callback, [ new UsergridError(err), response, self ], self);
}
});
};