Skip to content
This repository has been archived by the owner on Apr 12, 2023. It is now read-only.

0.3.5 #8

Merged
merged 9 commits into from Mar 27, 2013
6 changes: 3 additions & 3 deletions README.md
@@ -1,7 +1,7 @@
# Node.js client for imbo
A [node.js](http://nodejs.org/) client for [imbo](https://github.com/imbo/imbo).
# Javascript client for imbo
A javascript (browser/[node.js](http://nodejs.org/)) client for [imbo](https://github.com/imbo/imbo).

## Basic usage
## Basic usage (node.js)
```javascript
var Imbo = require('imbo');

Expand Down
1 change: 1 addition & 0 deletions build-browser.js
Expand Up @@ -10,6 +10,7 @@ var files = [
'lib/browser.js',
'lib/compat.js',
'lib/url.js',
'lib/query.js',
'lib/client.js'
];

Expand Down
226 changes: 197 additions & 29 deletions dist/imbo.browser.js
@@ -1,5 +1,5 @@
// Set up a global Imbo-namespace and signify that we're not in Node
Imbo = { Node: false, Version: '0.3.1' };
Imbo = { Node: false, Version: '0.3.5' };

(function(Imbo, undef) {

Expand Down Expand Up @@ -108,6 +108,18 @@ Imbo = { Node: false, Version: '0.3.1' };
xhr.send(null);
};

Imbo.Browser.EtagCache = {
cache: {},

get: function(url) {
return Imbo.Browser.EtagCache[url];
},

put: function(url, etag) {
Imbo.Browser.EtagCache[url] = etag;
}
};

})(Imbo);
// Compatability layer for browsers

Expand Down Expand Up @@ -161,19 +173,26 @@ Imbo = { Node: false, Version: '0.3.1' };
data = JSON.stringify(data);
}

if (Imbo.Node) {

}


// Browser environment
var xhr = new XMLHttpRequest();
var xhr = new XMLHttpRequest(), etag;
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status !== 0 && onComplete) {
etag = xhr.getResponseHeader('etag');
etag && Imbo.Browser.EtagCache.put(uri, etag);

onComplete(undef, Imbo.Compat.requestDone(xhr, jsonRequest));
}
};
xhr.open(method, uri, true);
xhr.setRequestHeader('Accept', headers.Accept);

var etag = Imbo.Browser.EtagCache.get(uri);
if (method == 'GET' && etag) {
xhr.setRequestHeader('If-None-Match', etag);
}

xhr.onerror = function() {
onComplete('XMLHttpRequest failed - CORS disabled?');
};
Expand Down Expand Up @@ -262,14 +281,15 @@ Imbo = { Node: false, Version: '0.3.1' };
/**
* Imbo URL helper
*/
function ImboUrl(baseUrl, publicKey, privateKey, imageIdentifier, path) {
var ImboUrl = function(baseUrl, publicKey, privateKey, imageIdentifier, path, queryString) {
this.transformations = [];
this.baseUrl = baseUrl;
this.publicKey = publicKey;
this.imageIdentifier = imageIdentifier;
this.privateKey = privateKey;
this.imageIdentifier = imageIdentifier || '';
this.path = path || '';
}
this.queryString = queryString;
};

ImboUrl.prototype.border = function(color, width, height) {
color = (color || '000000').replace(/^#/, '');
Expand Down Expand Up @@ -386,11 +406,12 @@ Imbo = { Node: false, Version: '0.3.1' };
};

ImboUrl.prototype.getQueryString = function() {
var query = '';
var query = this.queryString || '';
if (this.transformations.length) {
// We have some transformations. Generate a transformation key that will be sent to the
// server so the server can verify if the transformations are valid or not.
query = 't[]=' + this.transformations.reduce(function(query, element) {
query += query.length ? '&' : '';
query += 't[]=' + this.transformations.reduce(function(query, element) {
return query + '&t[]=' + element;
});
}
Expand All @@ -399,15 +420,21 @@ Imbo = { Node: false, Version: '0.3.1' };
};

ImboUrl.prototype.getUrl = function() {
var url = this.baseUrl + '/users/' + this.publicKey + '/images/' + this.imageIdentifier + this.path;
var qs = this.getQueryString();
var url = this.baseUrl + '/users/' + this.publicKey;
if (this.imageIdentifier || this.path) {
url = url + '/images/' + this.imageIdentifier + this.path;
}

url = url.replace(/\/+$/, '');

var qs = this.getQueryString();
if (qs.length) {
url += '?' + qs;
}

var token = this.getAccessToken(url, this.privateKey);

return url + (qs.length ? '&' : '?') + 'accessToken=' + token;
return url + (url.indexOf('?') > -1 ? '&' : '?') + 'accessToken=' + token;
};

ImboUrl.prototype.toString = function() {
Expand All @@ -421,6 +448,96 @@ Imbo = { Node: false, Version: '0.3.1' };
Imbo.Url = ImboUrl;
return ImboUrl;
})(typeof Imbo !== 'undefined' ? Imbo : {});
(function(Imbo, undef) {

var ImboQuery = function() {
this.values = {
page: 1,
num: 20,
metadata: false,
query: null,
from: null,
to: null
};
};

ImboQuery.prototype.page = function(val) {
if (!val) { return this.values.page; }
this.values.page = val;
return this;
};

ImboQuery.prototype.num = function(val) {
if (!val) { return this.values.num; }
this.values.num = val;
return this;
};

ImboQuery.prototype.limit = ImboQuery.prototype.num;

ImboQuery.prototype.metadata = function(val) {
if (typeof val === 'undefined') { return this.values.metadata; }
this.values.metadata = !!val;
return this;
};

ImboQuery.prototype.query = function(val) {
if (!val) { return this.values.query; }
this.values.query = val;
return this;
};

ImboQuery.prototype.from = function(val) {
if (!val) { return this.values.from; }
this.values.from = val;
return this;
};

ImboQuery.prototype.to = function(val) {
if (!val) { return this.values.to; }
this.values.to = val;
return this;
};

ImboQuery.prototype.toQueryString = function() {
// Retrieve query parameters, reduce params down to non-empty values
var params = {}, keys = ['page', 'num', 'metadata', 'query', 'from', 'to'];
for (var i = 0; i < keys.length; i++) {
if (!!this.values[keys[i]]) {
params[keys[i]] = this.values[keys[i]];
}
}

// JSON-encode metadata query, if present
if (params.query) {
params.query = JSON.stringify(params.query);
}

// Get timestamps from dates
if (params.from) {
params.from = Math.floor(params.from.getTime() / 1000);
}
if (params.to) {
params.to = Math.floor(params.to.getTime() / 1000);
}

// Build query string
var parts = [], key;
for (key in params) {
parts.push(key + '=' + encodeURIComponent(params[key]));
}
return parts.join('&');
};

ImboQuery.prototype.toString = ImboQuery.prototype.toQueryString;

if (typeof module !== 'undefined') {
module.exports = ImboQuery;
}

Imbo.Query = ImboQuery;
return ImboQuery;
})(typeof Imbo !== 'undefined' ? Imbo : {});


(function(Imbo, undef) {
Expand Down Expand Up @@ -461,8 +578,23 @@ Imbo = { Node: false, Version: '0.3.1' };
return new Imbo.Url(host, this.options.publicKey, this.options.privateKey, imageIdentifier);
};

ImboClient.prototype.getResourceUrl = function(resourceIdentifier, path) {
return new Imbo.Url(this.options.hosts[0], this.options.publicKey, this.options.privateKey, resourceIdentifier, path);
ImboClient.prototype.getImagesUrl = function(query) {
return this.getResourceUrl('', '/', query ? query.toString() : null);
};

ImboClient.prototype.getUserUrl = function() {
return this.getResourceUrl();
};

ImboClient.prototype.getResourceUrl = function(resourceIdentifier, path, query) {
return new Imbo.Url(
this.options.hosts[0],
this.options.publicKey,
this.options.privateKey,
resourceIdentifier,
path,
query
);
};

ImboClient.prototype.getSignedResourceUrl = function(method, url, date) {
Expand Down Expand Up @@ -511,7 +643,8 @@ Imbo = { Node: false, Version: '0.3.1' };
/**
* Image operations
*/
ImboClient.prototype.headImage = function(imageIdentifier, callback) {
ImboClient.prototype.headImage = function(imageIdentifier, cb) {
var callback = cb || function() {};
var url = this.getResourceUrl(imageIdentifier), undef;

Imbo.Compat.request('HEAD', url.toString(), function(err, res) {
Expand All @@ -524,8 +657,8 @@ Imbo = { Node: false, Version: '0.3.1' };
});
};

ImboClient.prototype.deleteImage = function(imgPath, callback) {
var self = this;
ImboClient.prototype.deleteImage = function(imgPath, cb) {
var self = this, callback = cb || function() {};
self.getImageIdentifier(imgPath, function(err, imageIdentifier) {
if (err) {
return callback(err);
Expand All @@ -535,7 +668,8 @@ Imbo = { Node: false, Version: '0.3.1' };
});
};

ImboClient.prototype.deleteImageByIdentifier = function(imageIdentifier, callback) {
ImboClient.prototype.deleteImageByIdentifier = function(imageIdentifier, cb) {
var callback = cb || function() {};
var url = this.getSignedResourceUrl('DELETE', this.getResourceUrl(imageIdentifier));

Imbo.Compat.request('DELETE', url, function(err, res) {
Expand Down Expand Up @@ -572,7 +706,8 @@ Imbo = { Node: false, Version: '0.3.1' };
});
};

ImboClient.prototype.addImageFromBlob = function(blob, callback) {
ImboClient.prototype.addImageFromBlob = function(blob, cb) {
var callback = cb || function() {};
var self = this, onComplete = callback.complete || callback;
var start = Date.now();
self.getImageIdentifierFromString(blob, function(err, imageIdentifier) {
Expand Down Expand Up @@ -603,11 +738,11 @@ Imbo = { Node: false, Version: '0.3.1' };
/**
* Add a new image to the server (from filesystem)
*
* @param {string|File} path Path to the local image, or an instance of File
* @param {Function} callback Function to call when image has been uploaded
* @param {string|File} path Path to the local image, or an instance of File
* @param {Function} cb Function to call when image has been uploaded
*/
ImboClient.prototype.addImage = function(path, callback) {
var self = this;
ImboClient.prototype.addImage = function(path, cb) {
var self = this, callback = cb || function() {};
Imbo.Compat.getContents(path, function(err, data) {
if (err) {
return callback(err);
Expand All @@ -617,8 +752,8 @@ Imbo = { Node: false, Version: '0.3.1' };
});
};

ImboClient.prototype.addImageFromUrl = function(url, callback) {
var self = this;
ImboClient.prototype.addImageFromUrl = function(url, cb) {
var self = this, callback = cb || function() {};
Imbo.Compat.getContentsFromUrl(url, function(err, data) {
if (err) {
return callback(err);
Expand All @@ -628,11 +763,42 @@ Imbo = { Node: false, Version: '0.3.1' };
});
};

/**
* Fetch information for a given user/public key
*/
ImboClient.prototype.getUserInfo = function(callback) {
Imbo.Compat.request('GET', this.getUserUrl().toString(), function(err, res) {
if (err || (res && res.statusCode != 200)) {
return callback(err || getErrorMessage(res), null, res);
}

callback(undef, res.body, res);
});
};

/**
* Fetch images
*/
ImboClient.prototype.getImages = function(callback, query) {
// Build the complete URL
var url = this.getImagesUrl(query);

// Fetch the response
Imbo.Compat.request('GET', url.toString(), function(err, res) {
if (err || (res && res.statusCode != 200)) {
return callback(err || getErrorMessage(res), null, res);
}

callback(undef, res.body, res);
});
};

/**
* Metadata methods
*/
ImboClient.prototype.getMetadata = function(imageIdentifier, callback) {
ImboClient.prototype.getMetadata = function(imageIdentifier, cb) {
var url = this.getResourceUrl(imageIdentifier, '/meta');
var callback = cb || function() {};
Imbo.Compat.request('GET', url.toString(), function(err, res) {
if (err || (res && res.statusCode != 200)) {
return callback(err || getErrorMessage(res), null, res);
Expand All @@ -642,8 +808,9 @@ Imbo = { Node: false, Version: '0.3.1' };
});
};

ImboClient.prototype.deleteMetadata = function(imageIdentifier, callback) {
ImboClient.prototype.deleteMetadata = function(imageIdentifier, cb) {
var url = this.getSignedResourceUrl('DELETE', this.getResourceUrl(imageIdentifier, '/meta'));
var callback = cb || function() {};
Imbo.Compat.request('DELETE', url, function(err, res) {
if (err || (res && res.statusCode != 200)) {
return callback(err || getErrorMessage(res), res);
Expand All @@ -653,8 +820,9 @@ Imbo = { Node: false, Version: '0.3.1' };
});
};

ImboClient.prototype.editMetadata = function(imageIdentifier, data, callback) {
ImboClient.prototype.editMetadata = function(imageIdentifier, data, cb) {
var url = this.getSignedResourceUrl('POST', this.getResourceUrl(imageIdentifier, '/meta'));
var callback = cb || function() {};
Imbo.Compat.request('POST', url, data, function(err, res) {
if (err || (res && res.statusCode != 200 && res.statusCode != 201)) {
return callback(err || getErrorMessage(res), res);
Expand Down
2 changes: 1 addition & 1 deletion dist/imbo.browser.min.js

Large diffs are not rendered by default.