Files
2025-02-26 14:49:25 +07:00

332 lines
9.1 KiB
JavaScript

/**
* Google related utils.
* Depends upon:
* - https://apis.google.com/js/api.js: auth and picker
* - https://apis.google.com/js/client.js: drive and request
*/
var dwv = dwv || {};
/** @namespace */
dwv.google = dwv.google || {};
// external
var gapi = gapi || {};
var google = google || {};
/**
* Google Authentification class.
* Allows to authentificate to google services.
*/
dwv.google.Auth = function ()
{
// closure to self
var self = this;
// immediate mode: behind the scenes token refresh
var immediate = false;
// The Client ID obtained from the Google Developers Console. Replace with your own Client ID.
this.clientId = "544445548355-7pli7rbg578hslnngnkj7ledcg6g5ejo.apps.googleusercontent.com";
// The scope to use to access user's Drive items.
this.scope = ['https://www.googleapis.com/auth/drive.readonly'];
/**
* Load the API and authentify.
*/
this.load = function () {
immediate = false;
gapi.load('auth', {'callback': onApiLoad});
};
/**
* Load the API and authentify silently.
*/
this.loadSilent = function () {
immediate = true;
gapi.load('auth', {'callback': onApiLoad});
};
/**
* Called if the authentification is successful.
* Default does nothing. No input parameters.
*/
this.onload = function () {};
/**
* Callback to be overloaded.
* Default does nothing. No input parameters.
*/
this.onfail = function () {};
/**
* Authentificate.
*/
function onApiLoad() {
// see https://developers.google.com/api-client-library/...
// ...javascript/reference/referencedocs#gapiauthauthorizeparams
gapi.auth.authorize({
'client_id': self.clientId,
'scope': self.scope,
'immediate': immediate
},
handleResult
);
}
/**
* Launch callback if all good.
* @param {Object} authResult An OAuth 2.0 Token Object.
* See https://developers.google.com/api-client-library/...
* ...javascript/reference/referencedocs#OAuth20TokenObject
*/
function handleResult(authResult) {
if (authResult && !authResult.error) {
self.onload();
}
else {
self.onfail();
}
}
};
/**
* Google Picker class.
* Allows to create a picker and handle its result.
*/
dwv.google.Picker = function ()
{
// closure to self
var self = this;
/**
* Load API and create picker.
*/
this.load = function () {
gapi.load('picker', {'callback': onApiLoad});
};
/**
* Called after user picked files.
* @param {Array} ids The list of picked files ids.
*/
this.onload = null;
/**
* Create the picker.
*/
function onApiLoad() {
var view = new google.picker.View(google.picker.ViewId.DOCS);
view.setMimeTypes("application/dicom");
// see https://developers.google.com/picker/docs/reference#PickerBuilder
var picker = new google.picker.PickerBuilder()
.enableFeature(google.picker.Feature.NAV_HIDDEN)
.enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
.setOAuthToken(gapi.auth.getToken().access_token)
.addView(view)
.setCallback(handleResult)
.build();
picker.setVisible(true);
}
/**
* Launch callback if all good.
* @param {Object} data The data returned by the picker.
* See https://developers.google.com/picker/docs/results
*/
function handleResult(data) {
if (data.action === google.picker.Action.PICKED &&
data.docs.length !== 0 ) {
var ids = [];
for (var i = 0; i < data.docs.length; ++i) {
ids[ids.length] = data.docs[i].id;
}
self.onload(ids);
}
}
};
/**
* Google Drive class.
* Allows to request google drive for file download links from a list of file ids.
*/
dwv.google.Drive = function ()
{
// closure to self
var self = this;
// list of ids
var idList = null;
// The Browser API key obtained from the Google Developers Console.
this.apiKey = 'AIzaSyA5YAedAwoQsBZ-TzVEEVkv2ezD5hqe4s0';
/**
* Set the ids to ask for download link.
* @param {Array} ids The list of file ids to ask for download link.
*/
this.setIds = function (ids) {
idList = ids;
};
/**
* Get the ids to ask for download link.
*/
this.getIds = function () {
return idList;
};
/**
* Load API and query drive for download links.
* @param {Array} ids The list of file ids to ask for download link.
*/
this.loadIds = function (ids) {
self.setIds(ids);
self.load();
};
/**
* Load API and query drive for download links.
* The ids to ask for have been provided via the setIds.
*/
this.load = function () {
// set the api key
gapi.client.setApiKey(self.apiKey);
var func = createApiLoad(self.getIds());
gapi.client.load('drive', 'v3', func);
};
/**
* Called after drive response with the file urls.
* @param {Array} urls The list of files urls corresponding to the input ids.
*/
this.onload = null;
/**
* Create an API load handler.
* @param {Array} ids The list of file ids to ask for download link.
*/
function createApiLoad(ids) {
var f = function () { onApiLoad(ids); };
return f;
}
/**
* Run the drive request.
* @param {Array} ids The list of file ids to ask for download link.
*/
function onApiLoad(ids) {
// group requests in batch (ans stay bellow quotas)
var batch = gapi.client.newBatch();
for (var i = 0; i < ids.length; ++i) {
// Can't make it work, HTTPRequest sends CORS error...
// see https://developers.google.com/drive/v3/reference/files/get
//var request = gapi.client.drive.files.get({
// 'fileId': fileId, 'fields': 'webViewLink'
//});
// File path with v2??
// see https://developers.google.com/api-client-library/...
// ...javascript/reference/referencedocs#gapiclientrequestargs
var request = gapi.client.request({
'path': '/drive/v2/files/' + ids[i],
'method': 'GET'
});
// add to batch
batch.add(request);
}
// execute the batch
batch.execute( handleDriveLoad );
}
/**
* Launch callback when all queries have returned.
* @param {Object} resp The batch request response.
* See https://developers.google.com/api-client-library/...
* ...javascript/reference/referencedocs#gapiclientRequestexecute
*/
function handleDriveLoad(resp) {
// link list
var urls = [];
// ID-response map of each requests response
var respKeys = Object.keys(resp);
for ( var i = 0; i < respKeys.length; ++i ) {
urls[urls.length] = resp[respKeys[i]].result.downloadUrl;
}
// call onload
self.onload(urls);
}
};
/**
* Append authorized header to the input callback arguments.
* @param {Function} callback The callback to append headers to.
*/
dwv.google.getAuthorizedCallback = function (callback) {
var func = function (urls) {
//see https://developers.google.com/api-client-library/javascript/features/cors
var header = {
"name": "Authorization",
"value": "Bearer " + gapi.auth.getToken().access_token
};
callback(urls, [header]);
};
return func;
};
/**
* GoogleDriveLoad gui.
* @constructor
*/
dwv.gui.GoogleDriveLoad = function (app)
{
/**
* Setup the gdrive load HTML to the page.
*/
this.setup = function()
{
// behind the scenes authentification to avoid popup blocker
var gAuth = new dwv.google.Auth();
gAuth.loadSilent();
// associated div
var gdriveLoadDiv = document.createElement("div");
gdriveLoadDiv.className = "gdrivediv";
gdriveLoadDiv.style.display = "none";
// node
var node = app.getElement("loaderlist");
// append
node.appendChild(gdriveLoadDiv);
// refresh
dwv.gui.refreshElement(node);
};
/**
* Display the file load HTML.
* @param {Boolean} bool True to display, false to hide.
*/
this.display = function (bool)
{
// gdrive div element
var node = app.getElement("loaderlist");
var filediv = node.getElementsByClassName("gdrivediv")[0];
filediv.style.display = bool ? "" : "none";
if (bool) {
// jquery mobile dependent
$("#popupOpen").popup("close");
app.resetLoadbox();
var gAuth = new dwv.google.Auth();
var gPicker = new dwv.google.Picker();
var gDrive = new dwv.google.Drive();
// pipeline
gAuth.onload = gPicker.load;
gPicker.onload = gDrive.loadIds;
gDrive.onload = dwv.google.getAuthorizedCallback(app.loadURLs);
// launch
gAuth.load();
}
};
};