Merge pull request #825 from SISheogorath/remove/GoogleDrive

Removing google drive integration
This commit is contained in:
Christoph (Sheogorath) Kern 2018-05-16 01:59:35 +02:00 committed by GitHub
commit 42b0965550
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 3 additions and 516 deletions

View file

@ -272,7 +272,7 @@ There are some config settings you need to change in the files below.
| ------- | --------- | ----------- |
| facebook, twitter, github, gitlab, mattermost, dropbox, google, ldap, saml | environment variables or `config.json` | for signin |
| imgur, s3, minio | environment variables or `config.json` | for image upload |
| google drive(`google/apiKey`, `google/clientID`), dropbox(`dropbox/appKey`) | `config.json` | for export and import |
| dropbox(`dropbox/appKey`) | `config.json` | for export and import |
## Third-party integration OAuth callback URLs

2
app.js
View file

@ -33,8 +33,6 @@ var data = {
urlpath: config.urlPath,
debug: config.debug,
version: config.version,
GOOGLE_API_KEY: config.google.clientSecret,
GOOGLE_CLIENT_ID: config.google.clientID,
DROPBOX_APP_KEY: config.dropbox.appKey,
allowedUploadMimeTypes: config.allowedUploadMimeTypes
}

View file

@ -136,10 +136,6 @@
"description": "Google API client secret",
"required": false
},
"HMD_GOOGLE_API_KEY": {
"description": "Google API key (for import/export)",
"required": false
},
"HMD_IMGUR_CLIENTID": {
"description": "Imgur API client id",
"required": false

View file

@ -1,118 +0,0 @@
/** !
* Google Drive File Picker Example
* By Daniel Lo Nigro (http://dan.cx/)
*/
(function () {
/**
* Initialise a Google Driver file picker
*/
var FilePicker = window.FilePicker = function (options) {
// Config
this.apiKey = options.apiKey
this.clientId = options.clientId
// Elements
this.buttonEl = options.buttonEl
// Events
this.onSelect = options.onSelect
this.buttonEl.on('click', this.open.bind(this))
// Disable the button until the API loads, as it won't work properly until then.
this.buttonEl.prop('disabled', true)
// Load the drive API
window.gapi.client.setApiKey(this.apiKey)
window.gapi.client.load('drive', 'v2', this._driveApiLoaded.bind(this))
window.google.load('picker', '1', { callback: this._pickerApiLoaded.bind(this) })
}
FilePicker.prototype = {
/**
* Open the file picker.
*/
open: function () {
// Check if the user has already authenticated
var token = window.gapi.auth.getToken()
if (token) {
this._showPicker()
} else {
// The user has not yet authenticated with Google
// We need to do the authentication before displaying the Drive picker.
this._doAuth(false, function () { this._showPicker() }.bind(this))
}
},
/**
* Show the file picker once authentication has been done.
* @private
*/
_showPicker: function () {
var accessToken = window.gapi.auth.getToken().access_token
var view = new window.google.picker.DocsView()
view.setMimeTypes('text/markdown,text/html')
view.setIncludeFolders(true)
view.setOwnedByMe(true)
this.picker = new window.google.picker.PickerBuilder()
.enableFeature(window.google.picker.Feature.NAV_HIDDEN)
.addView(view)
.setAppId(this.clientId)
.setOAuthToken(accessToken)
.setCallback(this._pickerCallback.bind(this))
.build()
.setVisible(true)
},
/**
* Called when a file has been selected in the Google Drive file picker.
* @private
*/
_pickerCallback: function (data) {
if (data[window.google.picker.Response.ACTION] === window.google.picker.Action.PICKED) {
var file = data[window.google.picker.Response.DOCUMENTS][0]
var id = file[window.google.picker.Document.ID]
var request = window.gapi.client.drive.files.get({
fileId: id
})
request.execute(this._fileGetCallback.bind(this))
}
},
/**
* Called when file details have been retrieved from Google Drive.
* @private
*/
_fileGetCallback: function (file) {
if (this.onSelect) {
this.onSelect(file)
}
},
/**
* Called when the Google Drive file picker API has finished loading.
* @private
*/
_pickerApiLoaded: function () {
this.buttonEl.prop('disabled', false)
},
/**
* Called when the Google Drive API has finished loading.
* @private
*/
_driveApiLoaded: function () {
this._doAuth(true)
},
/**
* Authenticate with Google Drive via the Google JavaScript API.
* @private
*/
_doAuth: function (immediate, callback) {
window.gapi.auth.authorize({
client_id: this.clientId,
scope: 'https://www.googleapis.com/auth/drive.readonly',
immediate: immediate
}, callback || function () {})
}
}
}())

View file

@ -1,267 +0,0 @@
/* eslint-env browser, jquery */
/**
* Helper for implementing retries with backoff. Initial retry
* delay is 1 second, increasing by 2x (+jitter) for subsequent retries
*
* @constructor
*/
var RetryHandler = function () {
this.interval = 1000 // Start at one second
this.maxInterval = 60 * 1000 // Don't wait longer than a minute
}
/**
* Invoke the function after waiting
*
* @param {function} fn Function to invoke
*/
RetryHandler.prototype.retry = function (fn) {
setTimeout(fn, this.interval)
this.interval = this.nextInterval_()
}
/**
* Reset the counter (e.g. after successful request.)
*/
RetryHandler.prototype.reset = function () {
this.interval = 1000
}
/**
* Calculate the next wait time.
* @return {number} Next wait interval, in milliseconds
*
* @private
*/
RetryHandler.prototype.nextInterval_ = function () {
var interval = this.interval * 2 + this.getRandomInt_(0, 1000)
return Math.min(interval, this.maxInterval)
}
/**
* Get a random int in the range of min to max. Used to add jitter to wait times.
*
* @param {number} min Lower bounds
* @param {number} max Upper bounds
* @private
*/
RetryHandler.prototype.getRandomInt_ = function (min, max) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
/**
* Helper class for resumable uploads using XHR/CORS. Can upload any Blob-like item, whether
* files or in-memory constructs.
*
* @example
* var content = new Blob(["Hello world"], {"type": "text/plain"});
* var uploader = new MediaUploader({
* file: content,
* token: accessToken,
* onComplete: function(data) { ... }
* onError: function(data) { ... }
* });
* uploader.upload();
*
* @constructor
* @param {object} options Hash of options
* @param {string} options.token Access token
* @param {blob} options.file Blob-like item to upload
* @param {string} [options.fileId] ID of file if replacing
* @param {object} [options.params] Additional query parameters
* @param {string} [options.contentType] Content-type, if overriding the type of the blob.
* @param {object} [options.metadata] File metadata
* @param {function} [options.onComplete] Callback for when upload is complete
* @param {function} [options.onProgress] Callback for status for the in-progress upload
* @param {function} [options.onError] Callback if upload fails
*/
var MediaUploader = function (options) {
var noop = function () {}
this.file = options.file
this.contentType = options.contentType || this.file.type || 'application/octet-stream'
this.metadata = options.metadata || {
'title': this.file.name,
'mimeType': this.contentType
}
this.token = options.token
this.onComplete = options.onComplete || noop
this.onProgress = options.onProgress || noop
this.onError = options.onError || noop
this.offset = options.offset || 0
this.chunkSize = options.chunkSize || 0
this.retryHandler = new RetryHandler()
this.url = options.url
if (!this.url) {
var params = options.params || {}
params.uploadType = 'resumable'
this.url = this.buildUrl_(options.fileId, params, options.baseUrl)
}
this.httpMethod = options.fileId ? 'PUT' : 'POST'
}
/**
* Initiate the upload.
*/
MediaUploader.prototype.upload = function () {
var xhr = new XMLHttpRequest()
xhr.open(this.httpMethod, this.url, true)
xhr.setRequestHeader('Authorization', 'Bearer ' + this.token)
xhr.setRequestHeader('Content-Type', 'application/json')
xhr.setRequestHeader('X-Upload-Content-Length', this.file.size)
xhr.setRequestHeader('X-Upload-Content-Type', this.contentType)
xhr.onload = function (e) {
if (e.target.status < 400) {
var location = e.target.getResponseHeader('Location')
this.url = location
this.sendFile_()
} else {
this.onUploadError_(e)
}
}.bind(this)
xhr.onerror = this.onUploadError_.bind(this)
xhr.send(JSON.stringify(this.metadata))
}
/**
* Send the actual file content.
*
* @private
*/
MediaUploader.prototype.sendFile_ = function () {
var content = this.file
var end = this.file.size
if (this.offset || this.chunkSize) {
// Only bother to slice the file if we're either resuming or uploading in chunks
if (this.chunkSize) {
end = Math.min(this.offset + this.chunkSize, this.file.size)
}
content = content.slice(this.offset, end)
}
var xhr = new XMLHttpRequest()
xhr.open('PUT', this.url, true)
xhr.setRequestHeader('Content-Type', this.contentType)
xhr.setRequestHeader('Content-Range', 'bytes ' + this.offset + '-' + (end - 1) + '/' + this.file.size)
xhr.setRequestHeader('X-Upload-Content-Type', this.file.type)
if (xhr.upload) {
xhr.upload.addEventListener('progress', this.onProgress)
}
xhr.onload = this.onContentUploadSuccess_.bind(this)
xhr.onerror = this.onContentUploadError_.bind(this)
xhr.send(content)
}
/**
* Query for the state of the file for resumption.
*
* @private
*/
MediaUploader.prototype.resume_ = function () {
var xhr = new XMLHttpRequest()
xhr.open('PUT', this.url, true)
xhr.setRequestHeader('Content-Range', 'bytes */' + this.file.size)
xhr.setRequestHeader('X-Upload-Content-Type', this.file.type)
if (xhr.upload) {
xhr.upload.addEventListener('progress', this.onProgress)
}
xhr.onload = this.onContentUploadSuccess_.bind(this)
xhr.onerror = this.onContentUploadError_.bind(this)
xhr.send()
}
/**
* Extract the last saved range if available in the request.
*
* @param {XMLHttpRequest} xhr Request object
*/
MediaUploader.prototype.extractRange_ = function (xhr) {
var range = xhr.getResponseHeader('Range')
if (range) {
this.offset = parseInt(range.match(/\d+/g).pop(), 10) + 1
}
}
/**
* Handle successful responses for uploads. Depending on the context,
* may continue with uploading the next chunk of the file or, if complete,
* invokes the caller's callback.
*
* @private
* @param {object} e XHR event
*/
MediaUploader.prototype.onContentUploadSuccess_ = function (e) {
if (e.target.status === 200 || e.target.status === 201) {
this.onComplete(e.target.response)
} else if (e.target.status === 308) {
this.extractRange_(e.target)
this.retryHandler.reset()
this.sendFile_()
} else {
this.onContentUploadError_(e)
}
}
/**
* Handles errors for uploads. Either retries or aborts depending
* on the error.
*
* @private
* @param {object} e XHR event
*/
MediaUploader.prototype.onContentUploadError_ = function (e) {
if (e.target.status && e.target.status < 500) {
this.onError(e.target.response)
} else {
this.retryHandler.retry(this.resume_.bind(this))
}
}
/**
* Handles errors for the initial request.
*
* @private
* @param {object} e XHR event
*/
MediaUploader.prototype.onUploadError_ = function (e) {
this.onError(e.target.response) // TODO - Retries for initial upload
}
/**
* Construct a query string from a hash/object
*
* @private
* @param {object} [params] Key/value pairs for query string
* @return {string} query string
*/
MediaUploader.prototype.buildQuery_ = function (params) {
params = params || {}
return Object.keys(params).map(function (key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(params[key])
}).join('&')
}
/**
* Build the drive upload URL
*
* @private
* @param {string} [id] File ID if replacing
* @param {object} [params] Query parameters
* @return {string} URL
*/
MediaUploader.prototype.buildUrl_ = function (id, params, baseUrl) {
var url = baseUrl || 'https://www.googleapis.com/upload/drive/v2/files/'
if (id) {
url += id
}
var query = this.buildQuery_(params)
if (query) {
url += '?' + query
}
return url
}
window.MediaUploader = MediaUploader

View file

@ -30,8 +30,6 @@ import {
import {
debug,
DROPBOX_APP_KEY,
GOOGLE_API_KEY,
GOOGLE_CLIENT_ID,
noteid,
noteurl,
urlpath,
@ -908,29 +906,6 @@ if (DROPBOX_APP_KEY) {
ui.toolbar.export.dropbox.hide()
}
// check if google api key and client id are set and load scripts
if (GOOGLE_API_KEY && GOOGLE_CLIENT_ID) {
$('<script>')
.attr('type', 'text/javascript')
.attr('src', 'https://www.google.com/jsapi?callback=onGoogleAPILoaded')
.prop('async', true)
.prop('defer', true)
.appendTo('body')
} else {
ui.toolbar.import.googleDrive.hide()
ui.toolbar.export.googleDrive.hide()
}
function onGoogleAPILoaded () {
$('<script>')
.attr('type', 'text/javascript')
.attr('src', 'https://apis.google.com/js/client:plusone.js?onload=onGoogleClientLoaded')
.prop('async', true)
.prop('defer', true)
.appendTo('body')
}
window.onGoogleAPILoaded = onGoogleAPILoaded
// button actions
// share
ui.toolbar.publish.attr('href', noteurl + '/publish')
@ -979,53 +954,6 @@ ui.toolbar.export.dropbox.click(function () {
}
Dropbox.save(options)
})
function uploadToGoogleDrive (accessToken) {
ui.spinner.show()
var filename = renderFilename(ui.area.markdown) + '.md'
var markdown = editor.getValue()
var blob = new Blob([markdown], {
type: 'text/markdown;charset=utf-8'
})
blob.name = filename
var uploader = new MediaUploader({
file: blob,
token: accessToken,
onComplete: function (data) {
data = JSON.parse(data)
showMessageModal('<i class="fa fa-cloud-upload"></i> Export to Google Drive', 'Export Complete!', data.alternateLink, 'Click here to view your file', true)
ui.spinner.hide()
},
onError: function (data) {
showMessageModal('<i class="fa fa-cloud-upload"></i> Export to Google Drive', 'Export Error :(', '', data, false)
ui.spinner.hide()
}
})
uploader.upload()
}
function googleApiAuth (immediate, callback) {
gapi.auth.authorize(
{
'client_id': GOOGLE_CLIENT_ID,
'scope': 'https://www.googleapis.com/auth/drive.file',
'immediate': immediate
}, callback || function () { })
}
function onGoogleClientLoaded () {
googleApiAuth(true)
buildImportFromGoogleDrive()
}
window.onGoogleClientLoaded = onGoogleClientLoaded
// export to google drive
ui.toolbar.export.googleDrive.click(function (e) {
var token = gapi.auth.getToken()
if (token) {
uploadToGoogleDrive(token.access_token)
} else {
googleApiAuth(false, function (result) {
uploadToGoogleDrive(result.access_token)
})
}
})
// export to gist
ui.toolbar.export.gist.attr('href', noteurl + '/gist')
// export to snippet
@ -1075,38 +1003,6 @@ ui.toolbar.import.dropbox.click(function () {
}
Dropbox.choose(options)
})
// import from google drive
function buildImportFromGoogleDrive () {
/* eslint-disable no-unused-vars */
let picker = new FilePicker({
apiKey: GOOGLE_API_KEY,
clientId: GOOGLE_CLIENT_ID,
buttonEl: ui.toolbar.import.googleDrive,
onSelect: function (file) {
if (file.downloadUrl) {
ui.spinner.show()
var accessToken = gapi.auth.getToken().access_token
$.ajax({
type: 'GET',
beforeSend: function (request) {
request.setRequestHeader('Authorization', 'Bearer ' + accessToken)
},
url: file.downloadUrl,
success: function (data) {
if (file.fileExtension === 'html') { parseToEditor(data) } else { replaceAll(data) }
},
error: function (data) {
showMessageModal('<i class="fa fa-cloud-download"></i> Import from Google Drive', 'Import failed :(', '', data, false)
},
complete: function () {
ui.spinner.hide()
}
})
}
}
})
/* eslint-enable no-unused-vars */
}
// import from gist
ui.toolbar.import.gist.click(function () {
// na

View file

@ -5,6 +5,4 @@ window.version = '<%- version %>'
window.allowedUploadMimeTypes = <%- JSON.stringify(allowedUploadMimeTypes) %>
window.GOOGLE_API_KEY = '<%- GOOGLE_API_KEY %>'
window.GOOGLE_CLIENT_ID = '<%- GOOGLE_CLIENT_ID %>'
window.DROPBOX_APP_KEY = '<%- DROPBOX_APP_KEY %>'

View file

@ -1,5 +1,3 @@
export const GOOGLE_API_KEY = window.GOOGLE_API_KEY || ''
export const GOOGLE_CLIENT_ID = window.GOOGLE_CLIENT_ID || ''
export const DROPBOX_APP_KEY = window.DROPBOX_APP_KEY || ''
export const domain = window.domain || '' // domain name

View file

@ -22,13 +22,11 @@ export const getUIElements = () => ({
},
export: {
dropbox: $('.ui-save-dropbox'),
googleDrive: $('.ui-save-google-drive'),
gist: $('.ui-save-gist'),
snippet: $('.ui-save-snippet')
},
import: {
dropbox: $('.ui-import-dropbox'),
googleDrive: $('.ui-import-google-drive'),
gist: $('.ui-import-gist'),
snippet: $('.ui-import-snippet'),
clipboard: $('.ui-import-clipboard')

View file

@ -32,13 +32,11 @@
</li>
<li role="presentation"><a role="menuitem" class="ui-extra-slide" tabindex="-1" href="#" target="_blank"><i class="fa fa-tv fa-fw"></i> <%= __('Slide Mode') %></a>
</li>
<% if((typeof github !== 'undefined' && github) || (typeof dropbox !== 'undefined' && dropbox) || (typeof google !== 'undefined' && google) || (typeof gitlab !== 'undefined' && gitlab && (!gitlab.scope || gitlab.scope === 'api'))) { %>
<% if((typeof github !== 'undefined' && github) || (typeof dropbox !== 'undefined' && dropbox) || (typeof gitlab !== 'undefined' && gitlab && (!gitlab.scope || gitlab.scope === 'api'))) { %>
<li class="divider"></li>
<li class="dropdown-header"><%= __('Export') %></li>
<li role="presentation"><a role="menuitem" class="ui-save-dropbox" tabindex="-1" href="#" target="_self"><i class="fa fa-dropbox fa-fw"></i> Dropbox</a>
</li>
<li role="presentation"><a role="menuitem" class="ui-save-google-drive" tabindex="-1" href="#" target="_self"><i class="fa fa-cloud-upload fa-fw"></i> Google Drive</a>
</li>
<% if(typeof github !== 'undefined' && github) { %>
<li role="presentation"><a role="menuitem" class="ui-save-gist" tabindex="-1" href="#" target="_blank"><i class="fa fa-github fa-fw"></i> Gist</a>
</li>
@ -52,8 +50,6 @@
<li class="dropdown-header"><%= __('Import') %></li>
<li role="presentation"><a role="menuitem" class="ui-import-dropbox" tabindex="-1" href="#" target="_self"><i class="fa fa-dropbox fa-fw"></i> Dropbox</a>
</li>
<li role="presentation"><a role="menuitem" class="ui-import-google-drive" tabindex="-1" href="#" target="_self"><i class="fa fa-cloud-download fa-fw"></i> Google Drive</a>
</li>
<li role="presentation"><a role="menuitem" class="ui-import-gist" href="#" data-toggle="modal" data-target="#gistImportModal"><i class="fa fa-github fa-fw"></i> Gist</a>
</li>
<% if(typeof gitlab !== 'undefined' && gitlab && (!gitlab.scope || gitlab.scope === 'api')) { %>
@ -138,13 +134,11 @@
</li>
<li role="presentation"><a role="menuitem" class="ui-extra-slide" tabindex="-1" href="#" target="_blank"><i class="fa fa-tv fa-fw"></i> <%= __('Slide Mode') %></a>
</li>
<% if((typeof github !== 'undefined' && github) || (typeof dropbox !== 'undefined' && dropbox) || (typeof google !== 'undefined' && google) || (typeof gitlab !== 'undefined' && gitlab && (!gitlab.scope || gitlab.scope === 'api'))) { %>
<% if((typeof github !== 'undefined' && github) || (typeof dropbox !== 'undefined' && dropbox) || (typeof gitlab !== 'undefined' && gitlab && (!gitlab.scope || gitlab.scope === 'api'))) { %>
<li class="divider"></li>
<li class="dropdown-header"><%= __('Export') %></li>
<li role="presentation"><a role="menuitem" class="ui-save-dropbox" tabindex="-1" href="#" target="_self"><i class="fa fa-dropbox fa-fw"></i> Dropbox</a>
</li>
<li role="presentation"><a role="menuitem" class="ui-save-google-drive" tabindex="-1" href="#" target="_self"><i class="fa fa-cloud-upload fa-fw"></i> Google Drive</a>
</li>
<% if(typeof github !== 'undefined' && github) { %>
<li role="presentation"><a role="menuitem" class="ui-save-gist" tabindex="-1" href="#" target="_blank"><i class="fa fa-github fa-fw"></i> Gist</a>
</li>
@ -158,8 +152,6 @@
<li class="dropdown-header"><%= __('Import') %></li>
<li role="presentation"><a role="menuitem" class="ui-import-dropbox" tabindex="-1" href="#" target="_self"><i class="fa fa-dropbox fa-fw"></i> Dropbox</a>
</li>
<li role="presentation"><a role="menuitem" class="ui-import-google-drive" tabindex="-1" href="#" target="_self"><i class="fa fa-cloud-download fa-fw"></i> Google Drive</a>
</li>
<li role="presentation"><a role="menuitem" class="ui-import-gist" href="#" data-toggle="modal" data-target="#gistImportModal"><i class="fa fa-github fa-fw"></i> Gist</a>
</li>
<% if(typeof gitlab !== 'undefined' && gitlab && (!gitlab.scope || gitlab.scope === 'api')) { %>

View file

@ -208,8 +208,6 @@ module.exports = {
'flowchart.js',
'js-sequence-diagrams',
'expose?RevealMarkdown!reveal-markdown',
path.join(__dirname, 'public/js/google-drive-upload.js'),
path.join(__dirname, 'public/js/google-drive-picker.js'),
path.join(__dirname, 'public/js/index.js')
],
'index-styles': [
@ -266,8 +264,6 @@ module.exports = {
'script!abcjs',
'expose?io!socket.io-client',
'expose?RevealMarkdown!reveal-markdown',
path.join(__dirname, 'public/js/google-drive-upload.js'),
path.join(__dirname, 'public/js/google-drive-picker.js'),
path.join(__dirname, 'public/js/index.js')
],
pretty: [