Skip to content

Commit 7e6dbe7

Browse files
authored
Allow 'multi' and 'sprite' with urls, add 'download_generated_sprite' and 'download_multi' methods (#493)
1 parent 2e5b3f4 commit 7e6dbe7

File tree

10 files changed

+544
-49
lines changed

10 files changed

+544
-49
lines changed

lib-es5/uploader.js

Lines changed: 66 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -288,36 +288,83 @@ exports.text = function text(content, callback) {
288288
});
289289
};
290290

291+
/**
292+
* Generate a sprite by merging multiple images into a single large image for reducing network overhead and bypassing
293+
* download limitations.
294+
*
295+
* The process produces 2 files as follows:
296+
* - A single image file containing all the images with the specified tag (PNG by default).
297+
* - A CSS file that includes the style class names and the location of the individual images in the sprite.
298+
*
299+
* @param {String|Object} tag A string specifying a tag that indicates which images to include or an object
300+
* which includes options and image URLs.
301+
* @param {Function} callback Callback function
302+
* @param {Object} options Configuration options. If options are passed as the first parameter, this parameter
303+
* should be empty
304+
*
305+
* @return {Object}
306+
*/
291307
exports.generate_sprite = function generate_sprite(tag, callback) {
292308
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
293309

294310
return call_api("sprite", callback, options, function () {
295-
var transformation = utils.generate_transformation_string(extend({}, options, {
296-
fetch_format: options.format
297-
}));
298-
return [{
299-
timestamp: utils.timestamp(),
300-
tag: tag,
301-
transformation: transformation,
302-
async: options.async,
303-
notification_url: options.notification_url
304-
}];
311+
return [utils.build_multi_and_sprite_params(tag, options)];
305312
});
306313
};
307314

315+
/**
316+
* Returns a signed url to download a sprite
317+
*
318+
* @param {String|Object} tag A string specifying a tag that indicates which images to include or an object
319+
* which includes options and image URLs.
320+
* @param {Object} options Configuration options. If options are passed as the first parameter, this parameter
321+
* should be empty
322+
*
323+
* @returns {string}
324+
*/
325+
exports.download_generated_sprite = function download_generated_sprite(tag) {
326+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
327+
328+
return utils.api_download_url("sprite", utils.build_multi_and_sprite_params(tag, options), options);
329+
};
330+
331+
/**
332+
* Returns a signed url to download a single animated image (GIF, PNG or WebP), video (MP4 or WebM) or a single PDF from
333+
* multiple image assets.
334+
*
335+
* @param {String|Object} tag A string specifying a tag that indicates which images to include or an object
336+
* which includes options and image URLs.
337+
* @param {Object} options Configuration options. If options are passed as the first parameter, this parameter
338+
* should be empty
339+
*
340+
* @returns {string}
341+
*/
342+
exports.download_multi = function download_multi(tag) {
343+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
344+
345+
return utils.api_download_url("multi", utils.build_multi_and_sprite_params(tag, options), options);
346+
};
347+
348+
/**
349+
* Creates either a single animated image (GIF, PNG or WebP), video (MP4 or WebM) or a single PDF from multiple image
350+
* assets.
351+
*
352+
* Each asset is included as a single frame of the resulting animated image/video, or a page of the PDF (sorted
353+
* alphabetically by their Public ID).
354+
*
355+
* @param {String|Object} tag A string specifying a tag that indicates which images to include or an object
356+
* which includes options and image URLs.
357+
* @param {Function} callback Callback function
358+
* @param {Object} options Configuration options. If options are passed as the first parameter, this parameter
359+
* should be empty
360+
*
361+
* @return {Object}
362+
*/
308363
exports.multi = function multi(tag, callback) {
309364
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
310365

311366
return call_api("multi", callback, options, function () {
312-
var transformation = utils.generate_transformation_string(extend({}, options));
313-
return [{
314-
timestamp: utils.timestamp(),
315-
tag: tag,
316-
transformation: transformation,
317-
format: options.format,
318-
async: options.async,
319-
notification_url: options.notification_url
320-
}];
367+
return [utils.build_multi_and_sprite_params(tag, options)];
321368
});
322369
};
323370

lib-es5/utils/index.js

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,38 @@ function process_radius(radius) {
313313
return radius.map(normalize_expression).join(':');
314314
}
315315

316+
function build_multi_and_sprite_params(tagOrOptions, options) {
317+
var tag = null;
318+
if (typeof tagOrOptions === 'string') {
319+
tag = tagOrOptions;
320+
} else {
321+
if (isEmpty(options)) {
322+
options = tagOrOptions;
323+
} else {
324+
throw new Error('First argument must be a tag when additional options are passed');
325+
}
326+
tag = null;
327+
}
328+
if (!options && !tag) {
329+
throw new Error('Either tag or urls are required');
330+
}
331+
if (!options) {
332+
options = {};
333+
}
334+
var urls = options.urls;
335+
var transformation = generate_transformation_string(extend({}, options, {
336+
fetch_format: options.format
337+
}));
338+
return {
339+
tag,
340+
transformation,
341+
urls,
342+
timestamp: utils.timestamp(),
343+
async: options.async,
344+
notification_url: options.notification_url
345+
};
346+
}
347+
316348
function build_upload_params(options) {
317349
var params = {
318350
access_mode: options.access_mode,
@@ -1178,6 +1210,18 @@ function download_backedup_asset(asset_id, version_id) {
11781210
return exports.base_api_url(['download_backup'], options) + "?" + hashToQuery(params);
11791211
}
11801212

1213+
/**
1214+
* Utility method to create a signed URL for specified resources.
1215+
* @param action
1216+
* @param params
1217+
* @param options
1218+
*/
1219+
function api_download_url(action, params, options) {
1220+
var download_params = _extends({}, params, { mode: "download" });
1221+
var cloudinary_params = exports.sign_request(download_params, options);
1222+
return exports.api_url(action, options) + "?" + hashToQuery(cloudinary_params);
1223+
}
1224+
11811225
/**
11821226
* Returns a URL that when invokes creates an archive and returns it.
11831227
* @param {object} options
@@ -1215,10 +1259,10 @@ function download_backedup_asset(asset_id, version_id) {
12151259
function download_archive_url() {
12161260
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
12171261

1218-
var cloudinary_params = exports.sign_request(exports.archive_params(merge(options, {
1262+
var params = exports.archive_params(merge(options, {
12191263
mode: "download"
1220-
})), options);
1221-
return exports.api_url("generate_archive", options) + "?" + hashToQuery(cloudinary_params);
1264+
}));
1265+
return api_download_url("generate_archive", params, options);
12221266
}
12231267

12241268
/**
@@ -1597,6 +1641,8 @@ exports.NOP = function () {};
15971641
exports.generate_auth_token = generate_auth_token;
15981642
exports.getUserAgent = getUserAgent;
15991643
exports.build_upload_params = build_upload_params;
1644+
exports.build_multi_and_sprite_params = build_multi_and_sprite_params;
1645+
exports.api_download_url = api_download_url;
16001646
exports.timestamp = function () {
16011647
return Math.floor(new Date().getTime() / 1000);
16021648
};

lib-es5/v2/uploader.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,6 @@ exports.upload_tag_params = uploader.upload_tag_params;
3535
exports.upload_url = uploader.upload_url;
3636
exports.image_upload_tag = uploader.image_upload_tag;
3737
exports.unsigned_image_upload_tag = uploader.unsigned_image_upload_tag;
38-
exports.create_slideshow = uploader.create_slideshow;
38+
exports.create_slideshow = uploader.create_slideshow;
39+
exports.download_generated_sprite = uploader.download_generated_sprite;
40+
exports.download_multi = uploader.download_multi;

lib/uploader.js

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -239,36 +239,76 @@ exports.text = function text(content, callback, options = {}) {
239239
});
240240
};
241241

242+
/**
243+
* Generate a sprite by merging multiple images into a single large image for reducing network overhead and bypassing
244+
* download limitations.
245+
*
246+
* The process produces 2 files as follows:
247+
* - A single image file containing all the images with the specified tag (PNG by default).
248+
* - A CSS file that includes the style class names and the location of the individual images in the sprite.
249+
*
250+
* @param {String|Object} tag A string specifying a tag that indicates which images to include or an object
251+
* which includes options and image URLs.
252+
* @param {Function} callback Callback function
253+
* @param {Object} options Configuration options. If options are passed as the first parameter, this parameter
254+
* should be empty
255+
*
256+
* @return {Object}
257+
*/
242258
exports.generate_sprite = function generate_sprite(tag, callback, options = {}) {
243259
return call_api("sprite", callback, options, function () {
244-
const transformation = utils.generate_transformation_string(extend({}, options, {
245-
fetch_format: options.format
246-
}));
247-
return [
248-
{
249-
timestamp: utils.timestamp(),
250-
tag: tag,
251-
transformation: transformation,
252-
async: options.async,
253-
notification_url: options.notification_url
254-
}
255-
];
260+
return [utils.build_multi_and_sprite_params(tag, options)];
256261
});
257262
};
258263

264+
265+
/**
266+
* Returns a signed url to download a sprite
267+
*
268+
* @param {String|Object} tag A string specifying a tag that indicates which images to include or an object
269+
* which includes options and image URLs.
270+
* @param {Object} options Configuration options. If options are passed as the first parameter, this parameter
271+
* should be empty
272+
*
273+
* @returns {string}
274+
*/
275+
exports.download_generated_sprite = function download_generated_sprite(tag, options = {}) {
276+
return utils.api_download_url("sprite", utils.build_multi_and_sprite_params(tag, options), options);
277+
}
278+
279+
/**
280+
* Returns a signed url to download a single animated image (GIF, PNG or WebP), video (MP4 or WebM) or a single PDF from
281+
* multiple image assets.
282+
*
283+
* @param {String|Object} tag A string specifying a tag that indicates which images to include or an object
284+
* which includes options and image URLs.
285+
* @param {Object} options Configuration options. If options are passed as the first parameter, this parameter
286+
* should be empty
287+
*
288+
* @returns {string}
289+
*/
290+
exports.download_multi = function download_multi(tag, options = {}) {
291+
return utils.api_download_url("multi", utils.build_multi_and_sprite_params(tag, options), options);
292+
}
293+
294+
/**
295+
* Creates either a single animated image (GIF, PNG or WebP), video (MP4 or WebM) or a single PDF from multiple image
296+
* assets.
297+
*
298+
* Each asset is included as a single frame of the resulting animated image/video, or a page of the PDF (sorted
299+
* alphabetically by their Public ID).
300+
*
301+
* @param {String|Object} tag A string specifying a tag that indicates which images to include or an object
302+
* which includes options and image URLs.
303+
* @param {Function} callback Callback function
304+
* @param {Object} options Configuration options. If options are passed as the first parameter, this parameter
305+
* should be empty
306+
*
307+
* @return {Object}
308+
*/
259309
exports.multi = function multi(tag, callback, options = {}) {
260310
return call_api("multi", callback, options, function () {
261-
const transformation = utils.generate_transformation_string(extend({}, options));
262-
return [
263-
{
264-
timestamp: utils.timestamp(),
265-
tag: tag,
266-
transformation: transformation,
267-
format: options.format,
268-
async: options.async,
269-
notification_url: options.notification_url
270-
}
271-
];
311+
return [utils.build_multi_and_sprite_params(tag, options)];
272312
});
273313
};
274314

lib/utils/index.js

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,38 @@ function process_radius(radius) {
292292
return radius.map(normalize_expression).join(':');
293293
}
294294

295+
function build_multi_and_sprite_params(tagOrOptions, options) {
296+
let tag = null;
297+
if (typeof tagOrOptions === 'string') {
298+
tag = tagOrOptions;
299+
} else {
300+
if (isEmpty(options)) {
301+
options = tagOrOptions;
302+
} else {
303+
throw new Error('First argument must be a tag when additional options are passed');
304+
}
305+
tag = null;
306+
}
307+
if (!options && !tag) {
308+
throw new Error('Either tag or urls are required')
309+
}
310+
if (!options) {
311+
options = {}
312+
}
313+
const urls = options.urls
314+
const transformation = generate_transformation_string(extend({}, options, {
315+
fetch_format: options.format
316+
}));
317+
return {
318+
tag,
319+
transformation,
320+
urls,
321+
timestamp: utils.timestamp(),
322+
async: options.async,
323+
notification_url: options.notification_url
324+
};
325+
}
326+
295327
function build_upload_params(options) {
296328
let params = {
297329
access_mode: options.access_mode,
@@ -1081,6 +1113,18 @@ function download_backedup_asset(asset_id, version_id, options = {}) {
10811113
return exports.base_api_url(['download_backup'], options) + "?" + hashToQuery(params);
10821114
}
10831115

1116+
/**
1117+
* Utility method to create a signed URL for specified resources.
1118+
* @param action
1119+
* @param params
1120+
* @param options
1121+
*/
1122+
function api_download_url(action, params, options) {
1123+
const download_params = {...params, mode: "download"}
1124+
let cloudinary_params = exports.sign_request(download_params, options);
1125+
return exports.api_url(action, options) + "?" + hashToQuery(cloudinary_params);
1126+
}
1127+
10841128
/**
10851129
* Returns a URL that when invokes creates an archive and returns it.
10861130
* @param {object} options
@@ -1116,10 +1160,10 @@ function download_backedup_asset(asset_id, version_id, options = {}) {
11161160
* @return {String} archive url
11171161
*/
11181162
function download_archive_url(options = {}) {
1119-
let cloudinary_params = exports.sign_request(exports.archive_params(merge(options, {
1163+
const params = exports.archive_params(merge(options, {
11201164
mode: "download"
1121-
})), options);
1122-
return exports.api_url("generate_archive", options) + "?" + hashToQuery(cloudinary_params);
1165+
}))
1166+
return api_download_url("generate_archive", params, options)
11231167
}
11241168

11251169
/**
@@ -1463,6 +1507,8 @@ exports.NOP = function () {};
14631507
exports.generate_auth_token = generate_auth_token;
14641508
exports.getUserAgent = getUserAgent;
14651509
exports.build_upload_params = build_upload_params;
1510+
exports.build_multi_and_sprite_params = build_multi_and_sprite_params;
1511+
exports.api_download_url = api_download_url;
14661512
exports.timestamp = () => Math.floor(new Date().getTime() / 1000);
14671513
exports.option_consume = consumeOption; // for backwards compatibility
14681514
exports.build_array = toArray; // for backwards compatibility

lib/v2/uploader.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,5 @@ exports.upload_url = uploader.upload_url;
3434
exports.image_upload_tag = uploader.image_upload_tag;
3535
exports.unsigned_image_upload_tag = uploader.unsigned_image_upload_tag;
3636
exports.create_slideshow = uploader.create_slideshow;
37+
exports.download_generated_sprite = uploader.download_generated_sprite;
38+
exports.download_multi = uploader.download_multi;

0 commit comments

Comments
 (0)