Commit a0194082 authored by Romain Courteaud's avatar Romain Courteaud

Release Version 3.24.0

Migrate to Dropbox API v2
parent 3e002090
...@@ -10297,27 +10297,18 @@ return new Parser; ...@@ -10297,27 +10297,18 @@ return new Parser;
* JIO Dropbox Storage. Type = "dropbox". * JIO Dropbox Storage. Type = "dropbox".
* Dropbox "database" storage. * Dropbox "database" storage.
*/ */
/*global Blob, jIO, RSVP, UriTemplate*/ /*global Blob, jIO, RSVP*/
/*jslint nomen: true*/ /*jslint nomen: true*/
(function (jIO, RSVP, Blob, UriTemplate) { (function (jIO, RSVP, Blob, JSON) {
"use strict"; "use strict";
var UPLOAD_URL = "https://content.dropboxapi.com/1/files_put/" + var GET_URL = "https://content.dropboxapi.com/2/files/download",
"{+root}{+id}{+name}{?access_token}", UPLOAD_URL = "https://content.dropboxapi.com/2/files/upload",
upload_template = UriTemplate.parse(UPLOAD_URL), REMOVE_URL = "https://api.dropboxapi.com/2/files/delete_v2",
CREATE_DIR_URL = "https://api.dropboxapi.com/1/fileops/create_folder" + CREATE_DIR_URL = "https://api.dropboxapi.com/2/files/create_folder_v2",
"{?access_token,root,path}", METADATA_URL = "https://api.dropboxapi.com/2/files/get_metadata",
create_dir_template = UriTemplate.parse(CREATE_DIR_URL), LIST_FOLDER_URL = "https://api.dropboxapi.com/2/files/list_folder",
REMOVE_URL = "https://api.dropboxapi.com/1/fileops/delete/" + LIST_MORE_URL = "https://api.dropboxapi.com/2/files/list_folder/continue";
"{?access_token,root,path}",
remote_template = UriTemplate.parse(REMOVE_URL),
GET_URL = "https://content.dropboxapi.com/1/files" +
"{/root,id}{+name}{?access_token}",
get_template = UriTemplate.parse(GET_URL),
//LIST_URL = 'https://api.dropboxapi.com/1/metadata/sandbox/';
METADATA_URL = "https://api.dropboxapi.com/1/metadata" +
"{/root}{+id}{?access_token}",
metadata_template = UriTemplate.parse(METADATA_URL);
function restrictDocumentId(id) { function restrictDocumentId(id) {
if (id.indexOf("/") !== 0) { if (id.indexOf("/") !== 0) {
...@@ -10328,7 +10319,7 @@ return new Parser; ...@@ -10328,7 +10319,7 @@ return new Parser;
throw new jIO.util.jIOError("id " + id + " is forbidden (no end /)", throw new jIO.util.jIOError("id " + id + " is forbidden (no end /)",
400); 400);
} }
return id; return id.slice(0, -1);
} }
function restrictAttachmentId(id) { function restrictAttachmentId(id) {
...@@ -10338,6 +10329,66 @@ return new Parser; ...@@ -10338,6 +10329,66 @@ return new Parser;
} }
} }
function recursiveAllAttachments(result, token, id, cursor) {
var data,
url;
if (cursor === undefined) {
data = {
"path": id,
"recursive": false,
"include_media_info": false,
"include_deleted": false,
"include_has_explicit_shared_members": false,
"include_mounted_folders": true
};
url = LIST_FOLDER_URL;
} else {
data = {"cursor": cursor};
url = LIST_MORE_URL;
}
return new RSVP.Queue()
.push(function () {
return jIO.util.ajax({
type: "POST",
url: url,
headers: {
"Authorization": "Bearer " + token,
"Content-Type": "application/json"
},
data: JSON.stringify(data)
});
})
.push(function (evt) {
var obj = JSON.parse(evt.target.response || evt.target.responseText),
i;
for (i = 0; i < obj.entries.length; i += 1) {
if (obj.entries[i][".tag"] === "file") {
result[obj.entries[i].name] = {};
}
}
if (obj.has_more) {
return recursiveAllAttachments(result, token, id, obj.cursor);
}
return result;
}, function (error) {
if (error.target !== undefined && error.target.status === 409) {
var err_content = JSON.parse(error.target.response ||
error.target.responseText);
if ((err_content.error['.tag'] === 'path') &&
(err_content.error.path['.tag'] === 'not_folder')) {
throw new jIO.util.jIOError("Not a directory: " + id + "/",
404);
}
if ((err_content.error['.tag'] === 'path') &&
(err_content.error.path['.tag'] === 'not_found')) {
throw new jIO.util.jIOError("Cannot find document: " + id + "/",
404);
}
}
throw error;
});
}
/** /**
* The JIO Dropbox Storage extension * The JIO Dropbox Storage extension
* *
...@@ -10349,12 +10400,7 @@ return new Parser; ...@@ -10349,12 +10400,7 @@ return new Parser;
throw new TypeError("Access Token' must be a string " + throw new TypeError("Access Token' must be a string " +
"which contains more than one character."); "which contains more than one character.");
} }
if (typeof spec.root !== 'string' || !spec.root ||
(spec.root !== "dropbox" && spec.root !== "sandbox")) {
throw new TypeError("root must be 'dropbox' or 'sandbox'");
}
this._access_token = spec.access_token; this._access_token = spec.access_token;
this._root = spec.root;
} }
DropboxStorage.prototype.put = function (id, param) { DropboxStorage.prototype.put = function (id, param) {
...@@ -10369,18 +10415,24 @@ return new Parser; ...@@ -10369,18 +10415,24 @@ return new Parser;
.push(function () { .push(function () {
return jIO.util.ajax({ return jIO.util.ajax({
type: "POST", type: "POST",
url: create_dir_template.expand({ url: CREATE_DIR_URL,
access_token: that._access_token, headers: {
root: that._root, "Authorization": "Bearer " + that._access_token,
path: id "Content-Type": "application/json"
}) },
data: JSON.stringify({"path": id, "autorename": false})
}); });
}) })
.push(undefined, function (err) { .push(undefined, function (err) {
if ((err.target !== undefined) && if ((err.target !== undefined) &&
(err.target.status === 405)) { (err.target.status === 409)) {
// Directory already exists, no need to fail var err_content = JSON.parse(err.target.response ||
return; err.target.responseText);
if ((err_content.error['.tag'] === 'path') &&
(err_content.error.path['.tag'] === 'conflict')) {
// Directory already exists, no need to fail
return;
}
} }
throw err; throw err;
}); });
...@@ -10390,11 +10442,12 @@ return new Parser; ...@@ -10390,11 +10442,12 @@ return new Parser;
id = restrictDocumentId(id); id = restrictDocumentId(id);
return jIO.util.ajax({ return jIO.util.ajax({
type: "POST", type: "POST",
url: remote_template.expand({ url: REMOVE_URL,
access_token: this._access_token, headers: {
root: this._root, "Authorization": "Bearer " + this._access_token,
path: id "Content-Type": "application/json"
}) },
data: JSON.stringify({"path": id})
}); });
}; };
...@@ -10409,64 +10462,39 @@ return new Parser; ...@@ -10409,64 +10462,39 @@ return new Parser;
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
return jIO.util.ajax({ return jIO.util.ajax({
type: "GET", type: "POST",
url: metadata_template.expand({ url: METADATA_URL,
access_token: that._access_token, headers: {
root: that._root, "Authorization": "Bearer " + that._access_token,
id: id "Content-Type": "application/json"
}) },
data: JSON.stringify({"path": id})
}); });
}) })
.push(function (evt) { .push(function (evt) {
var obj = JSON.parse(evt.target.response || var obj = JSON.parse(evt.target.response ||
evt.target.responseText); evt.target.responseText);
if (obj.is_dir) { if (obj[".tag"] === "folder") {
return {}; return {};
} }
throw new jIO.util.jIOError("Not a directory: " + id, 404); throw new jIO.util.jIOError("Not a directory: " + id + "/", 404);
}, function (error) { }, function (error) {
if (error.target !== undefined && error.target.status === 404) { if (error.target !== undefined && error.target.status === 409) {
throw new jIO.util.jIOError("Cannot find document: " + id, 404); var err_content = JSON.parse(error.target.response ||
error.target.responseText);
if ((err_content.error['.tag'] === 'path') &&
(err_content.error.path['.tag'] === 'not_found')) {
throw new jIO.util.jIOError("Cannot find document: " + id + "/",
404);
}
} }
throw error; throw error;
}); });
}; };
DropboxStorage.prototype.allAttachments = function (id) { DropboxStorage.prototype.allAttachments = function (id) {
var that = this;
id = restrictDocumentId(id); id = restrictDocumentId(id);
return recursiveAllAttachments({}, this._access_token, id);
return new RSVP.Queue()
.push(function () {
return jIO.util.ajax({
type: "GET",
url: metadata_template.expand({
access_token: that._access_token,
root: that._root,
id: id
})
});
})
.push(function (evt) {
var obj = JSON.parse(evt.target.response || evt.target.responseText),
i,
result = {};
if (!obj.is_dir) {
throw new jIO.util.jIOError("Not a directory: " + id, 404);
}
for (i = 0; i < obj.contents.length; i += 1) {
if (!obj.contents[i].is_dir) {
result[obj.contents[i].path.split("/").pop()] = {};
}
}
return result;
}, function (error) {
if (error.target !== undefined && error.target.status === 404) {
throw new jIO.util.jIOError("Cannot find document: " + id, 404);
}
throw error;
});
}; };
//currently, putAttachment will fail with files larger than 150MB, //currently, putAttachment will fail with files larger than 150MB,
...@@ -10481,20 +10509,24 @@ return new Parser; ...@@ -10481,20 +10509,24 @@ return new Parser;
restrictAttachmentId(name); restrictAttachmentId(name);
return jIO.util.ajax({ return jIO.util.ajax({
type: "PUT", type: "POST",
url: upload_template.expand({ url: UPLOAD_URL,
root: this._root, headers: {
id: id, "Authorization": "Bearer " + this._access_token,
name: name, "Content-Type": "application/octet-stream",
access_token: this._access_token "Dropbox-API-Arg": JSON.stringify({
}), "path": id + "/" + name,
dataType: blob.type, "mode": "overwrite",
"autorename": false,
"mute": false
})
},
data: blob data: blob
}); });
}; };
DropboxStorage.prototype.getAttachment = function (id, name) { DropboxStorage.prototype.getAttachment = function (id, name) {
var that = this; var context = this;
id = restrictDocumentId(id); id = restrictDocumentId(id);
restrictAttachmentId(name); restrictAttachmentId(name);
...@@ -10502,26 +10534,48 @@ return new Parser; ...@@ -10502,26 +10534,48 @@ return new Parser;
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
return jIO.util.ajax({ return jIO.util.ajax({
type: "GET", url: GET_URL,
type: "POST",
dataType: "blob", dataType: "blob",
url: get_template.expand({ headers: {
root: that._root, "Authorization": "Bearer " + context._access_token,
id: id, "Dropbox-API-Arg": JSON.stringify({"path": id + "/" + name})
name: name, }
access_token: that._access_token
})
}); });
}) })
.push(function (evt) { .push(function (evt) {
if (evt.target.response instanceof Blob) {
return evt.target.response;
}
return new Blob( return new Blob(
[evt.target.response || evt.target.responseText], [evt.target.responseText],
{"type": evt.target.getResponseHeader('Content-Type') || {"type": evt.target.getResponseHeader('Content-Type') ||
"application/octet-stream"} "application/octet-stream"}
); );
}, function (error) { }, function (error) {
if (error.target !== undefined && error.target.status === 404) { if (error.target !== undefined && error.target.status === 409) {
throw new jIO.util.jIOError("Cannot find attachment: " + if (!(error.target.response instanceof Blob)) {
id + ", " + name, 404); var err_content = JSON.parse(error.target.responseText);
if ((err_content.error['.tag'] === 'path') &&
(err_content.error.path['.tag'] === 'not_found')) {
throw new jIO.util.jIOError("Cannot find attachment: " +
id + "/, " + name, 404);
}
throw error;
}
return new RSVP.Queue()
.push(function () {
return jIO.util.readBlobAsText(error.target.response);
})
.push(function (evt) {
var err_content = JSON.parse(evt.target.result);
if ((err_content.error['.tag'] === 'path') &&
(err_content.error.path['.tag'] === 'not_found')) {
throw new jIO.util.jIOError("Cannot find attachment: " +
id + "/, " + name, 404);
}
throw error;
});
} }
throw error; throw error;
}); });
...@@ -10538,16 +10592,22 @@ return new Parser; ...@@ -10538,16 +10592,22 @@ return new Parser;
.push(function () { .push(function () {
return jIO.util.ajax({ return jIO.util.ajax({
type: "POST", type: "POST",
url: remote_template.expand({ url: REMOVE_URL,
access_token: that._access_token, headers: {
root: that._root, "Authorization": "Bearer " + that._access_token,
path: id + name "Content-Type": "application/json"
}) },
data: JSON.stringify({"path": id + "/" + name})
}); });
}).push(undefined, function (error) { }).push(undefined, function (error) {
if (error.target !== undefined && error.target.status === 404) { if (error.target !== undefined && error.target.status === 409) {
throw new jIO.util.jIOError("Cannot find attachment: " + var err_content = JSON.parse(error.target.response ||
id + ", " + name, 404); error.target.responseText);
if ((err_content.error['.tag'] === 'path_lookup') &&
(err_content.error.path_lookup['.tag'] === 'not_found')) {
throw new jIO.util.jIOError("Cannot find attachment: " +
id + "/, " + name, 404);
}
} }
throw error; throw error;
}); });
...@@ -10555,7 +10615,7 @@ return new Parser; ...@@ -10555,7 +10615,7 @@ return new Parser;
jIO.addStorage('dropbox', DropboxStorage); jIO.addStorage('dropbox', DropboxStorage);
}(jIO, RSVP, Blob, UriTemplate)); }(jIO, RSVP, Blob, JSON));
;/* ;/*
* Copyright 2013, Nexedi SA * Copyright 2013, Nexedi SA
* Released under the LGPL license. * Released under the LGPL license.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
{ {
"name": "jio", "name": "jio",
"version": "v3.23.1", "version": "v3.24.0",
"license": "LGPLv3", "license": "LGPLv3",
"author": "Nexedi SA", "author": "Nexedi SA",
"contributors": [ "contributors": [
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment