Last active
August 29, 2015 13:57
-
-
Save CapyTheBeara/9539722 to your computer and use it in GitHub Desktop.
An Ember object to send Google Drive API requests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Created this object to facilitate an Ember Data Adapter | |
// Usage: | |
g = Gapi.create(); | |
// create a file with just meta data (no content) | |
g.insert({ title: 'first' }); | |
// create a file with content | |
g.insert({ title: 'second', content: 'second content'}); | |
// search for a file | |
g.findQuery({ q: "title contains 'fir'" }); | |
g.findQuery({ q: "fullText contains 'content'" }); | |
// find all and get file ids | |
var ids; | |
g.findAll().then(function(res) { ids = res.items.getEach('id'); }); | |
// update a file's meta data | |
g.update(ids[0], { title: 'third' }); | |
// get a file an then its content | |
var url; | |
g.fetch(ids[0]).then(function(res){ url = res.downloadUrl; }); | |
g.getFileContent(url).then(function(res) { console.log(res); }); | |
// update a file's content | |
g.update(ids[0], { content: 'new content here'} ); | |
g.getFileContent(url).then(function(res) { console.log(res); }); | |
// destroy a file | |
ids.forEach(function(id) { g.destroy(id); }); | |
//////////////////////////////////////// | |
var gapiScriptUrl = 'https://apis.google.com/js/client.js?onload=gapiReady', | |
scopes = 'https://www.googleapis.com/auth/drive.appdata', | |
apiKey = 'YOUR_KEY', | |
clientId = 'YOUR_CLIENT_ID', | |
Promise = Em.RSVP.Promise; | |
function log() { | |
if (!window.config.DEBUG) { return; } | |
console.log.apply(console, Array.prototype.slice.call(arguments, 0)); | |
} | |
function handleResponse(resolve, reject) { | |
return function(res) { | |
if (res.error) { | |
log(res); | |
Em.run(null, reject, res); | |
} else { | |
log(res); | |
Em.run(null, resolve, res); | |
} | |
}; | |
} | |
var boundary = '-------314159265358979323846'; | |
var delimiter = "\r\n--" + boundary + "\r\n"; | |
var close_delim = "\r\n--" + boundary + "--"; | |
function createRequestBody(fileResource, content) { | |
return delimiter + | |
'Content-Type: application/json\r\n\r\n' + | |
JSON.stringify(fileResource) + | |
delimiter + | |
'Content-Type: ' + fileResource.mimeType + '\r\n\r\n' + | |
content + | |
close_delim; | |
} | |
var driveUploadPath = '/upload/drive/v2/files'; | |
// allows adding content to a file (either insert or update) | |
function clientRequest(opts) { | |
var fileResource = opts.fileResource, | |
content = fileResource.content, | |
path = opts.id ? driveUploadPath + '/' + opts.id : driveUploadPath; | |
if (!fileResource.mimeType) { | |
fileResource.mimeType = 'text/plain'; | |
} | |
if (!content) { | |
return opts.simpleRequest(); | |
} else { | |
delete fileResource.content; | |
} | |
log('==sending client request== ', opts); | |
return new Promise(function(resolve, reject) { | |
gapi.client.request({ | |
path: path, | |
method: opts.method, | |
params: { uploadType: 'multipart' }, | |
headers: { | |
'Content-Type': 'multipart/mixed; boundary="' + boundary + '"' | |
}, | |
body: createRequestBody(fileResource, content) | |
}).execute(handleResponse(resolve, reject)); | |
}); | |
} | |
function ajax(url, method, token) { | |
return new Promise(function(resolve, reject) { | |
$.ajax({ | |
url: url, | |
type: method, | |
headers: { | |
'Authorization': 'Bearer ' + token | |
}, | |
success: function(res) { | |
Em.run(null, resolve, res); | |
}, | |
error: function(jqXHR, status, error) { | |
Em.run(null, reject, error); | |
} | |
}); | |
}); | |
} | |
var Gapi = Em.Object.extend(Em.PromiseProxyMixin, { | |
promise: null, | |
authorized: null, | |
reqMethod: null, | |
reqArgs: null, | |
requestedAt: null, | |
accessToken: null, | |
gapiReady: false, | |
driveReady: false, | |
init: function() { | |
this._super(); | |
if (!window.gapi) { | |
window.gapiReady = this.setGapiReady.bind(this); | |
$.getScript(gapiScriptUrl); | |
} else { | |
this.set('gapiReady', true); | |
} | |
}, | |
setGapiReady: function() { | |
this.set('gapiReady', true); | |
}, | |
gapiReadyChanged: function() { | |
if (!this.get('gapiReady')) { return; } | |
gapi.client.setApiKey(apiKey); | |
gapi.client.load('drive', 'v2', function(res) { | |
this.set('driveReady', true); | |
}.bind(this)); | |
Em.run.next(this, function() { this.authorize(true); }); | |
}.observes('gapiReady').on('init'), | |
authorize: function(immediate) { | |
gapi.auth.authorize({ | |
client_id: clientId, | |
scope: scopes, | |
immediate: immediate | |
}, this.handleAuthResult.bind(this)); | |
}, | |
handleAuthResult: function(authResult) { | |
if (authResult && !authResult.error) { | |
this.set('authorized', true); | |
this.set('accessToken', gapi.auth.getToken().access_token); | |
} else { | |
this.set('authorized', false); | |
} | |
}, | |
fetch: function(id) { | |
return this.request('get', { fileId: id }); | |
}, | |
findQuery: function(query) { | |
return this.request('list', query); | |
}, | |
findAll: function() { | |
return this.request('list'); | |
}, | |
// creates new file w/ metadata or file w/ metadata and content | |
insert: function(fileResource) { | |
if (!fileResource.parents) { | |
fileResource.parents = [{ id: 'appdata' }]; | |
} | |
return clientRequest({ | |
fileResource: fileResource, | |
method: 'POST', | |
simpleRequest: function() { | |
return this.request('_insert', { resource: fileResource }); | |
}.bind(this) | |
}); | |
}, | |
// only updates file metadata | |
patch: function(id, fileResource) { | |
return this.request('patch', { | |
fileId: id, | |
resource: fileResource | |
}); | |
}, | |
// updates file metadata or content | |
update: function(id, fileResource) { | |
return clientRequest({ | |
id: id, | |
fileResource: fileResource, | |
method: 'PUT', | |
simpleRequest: function() { | |
return this.patch(id, fileResource); | |
}.bind(this) | |
}); | |
}, | |
// This sends a POST request which sends back a response. | |
// Ember Data throws an error because of this. | |
// destroy: function(id) { | |
// return this.request('delete', { fileId: id }); | |
// }, | |
destroy: function(id) { | |
var url = 'https://www.googleapis.com/drive/v2/files/' + id; | |
return ajax(url, 'DELETE', this.get('accessToken')); | |
}, | |
request: function() { | |
var args = Array.prototype.slice.call(arguments, 0); | |
this.setProperties({ | |
reqMethod: args[0], | |
reqArgs: args.slice(1), | |
requestedAt: new Date().getTime() | |
}); | |
return this; | |
}, | |
sendRequest: function() { | |
var method = this.get('reqMethod'), | |
args = this.get('reqArgs'); | |
if (!this.get('driveReady') || !method) { return; } | |
log('==sending request== ', method, args); | |
if (method === 'insert') { | |
return this.insert.apply(this, args); | |
} | |
if (method === '_insert') { | |
method = 'insert'; | |
} | |
var promise = new Promise(function(resolve, reject) { | |
gapi.client.drive | |
.files[method].apply(null, args) | |
.execute(handleResponse(resolve, reject)); | |
}); | |
this.set('promise', promise); | |
}.observes('driveReady', 'requestedAt'), | |
getFileContent: function(downloadUrl) { | |
var token = this.get('accessToken'); | |
return ajax(downloadUrl, 'GET', token); | |
} | |
}); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment