Skip to content

Commit

Permalink
#6594 allow to publish personal gists (#6637)
Browse files Browse the repository at this point in the history
* #6586 show error dialog on gist publishing error

* #6586 move gistPublish to extension dir

* #66586 show the network error in gist publishing dialog

* #6594 allow to publish personal gists

* #6594 use html file for modal template

* #6594 store personal access token in beakerx.json

* #6594 add oauth scope information to modal

* adjust text

* can press enter

* #6594 allow publish on enter click

* #6594 set publish as default button
  • Loading branch information
Mariusz Jurowicz authored and scottdraves committed Jan 19, 2018
1 parent a5f7165 commit 7987165
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 25 deletions.
2 changes: 1 addition & 1 deletion js/notebook/src/Plot.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ var PlotView = widgets.DOMWidgetView.extend({
scope.destroy();
});
}
that._currentScope.destroy();
that._currentScope && that._currentScope.destroy();

setTimeout(function() { that._currentScope = null; });
});
Expand Down
2 changes: 1 addition & 1 deletion js/notebook/src/extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ define([
'./plot/plotApi',
'./shared/bkCoreManager',
'big.js',
'./extension/GistPublish'
'./extension/gistPublish/index'
], function(
configmod,
comm,
Expand Down
103 changes: 103 additions & 0 deletions js/notebook/src/extension/gistPublish/gistPublishModal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright 2017 TWO SIGMA OPEN SOURCE, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import * as _ from 'underscore';

const dialog = require('base/js/dialog');
const utils = require('base/js/utils');

export default class GistPublishModal {
static template = _.template(require('./modalTemplate.html'))();
static settingsUrl = `${(Jupyter.notebook_list || Jupyter.notebook).base_url}beakerx/settings`;

static show(submitCallback: Function): void {
GistPublishModal.getGithubPersonalAccessToken()
.then(personalAccessToken => {
GistPublishModal.create(submitCallback, personalAccessToken);
});
}

static create(submitCallback, personalAccessToken = '') {
const modalContent = GistPublishModal.createModalContent();
const personalAccessTokenInput = modalContent.querySelector('input');
const form = modalContent.querySelector('form');

const submitHandler = (event) => {
const personalAccessToken = personalAccessTokenInput ? personalAccessTokenInput.value : '';

event.preventDefault();
submitCallback(personalAccessToken);
GistPublishModal.storePersonalAccessToken(personalAccessToken);
};

if (personalAccessTokenInput && form) {
personalAccessTokenInput.value = personalAccessToken;
}

const modal = dialog.modal({
keyboard_manager: Jupyter.notebook.keyboard_manager,
title : 'Publish to a GitHub Gist',
body : modalContent,
default_button: 'Publish',
buttons: {
'Publish': {
'class' : 'btn-primary',
'click': submitHandler
},
'Cancel': {}
}
});

if (form) {
form.onsubmit = (event) => {
modal.modal('hide');
submitHandler(event);
}
}
}

static createModalContent(): HTMLElement {
const modalContent = document.createElement('div');

modalContent.innerHTML = GistPublishModal.template;

return modalContent;
}

static storePersonalAccessToken(githubPersonalAccessToken = ''): Promise<any> {
return GistPublishModal.getStoredSettings()
.then(storedSettings =>
utils.ajax(GistPublishModal.settingsUrl, {
type: 'POST',
data: JSON.stringify({
...storedSettings,
githubPersonalAccessToken
})
}).fail(reason => { console.log(reason); })
);
}

static getGithubPersonalAccessToken(): Promise<any> {
return GistPublishModal.getStoredSettings()
.then(settings => settings.githubPersonalAccessToken || '');
}

static getStoredSettings(): Promise<any> {
return utils.ajax(GistPublishModal.settingsUrl, {
method: 'GET'
}).fail(reason => { console.log(reason); });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
* limitations under the License.
*/

import $ from 'jquery';
import * as $ from 'jquery';
import GistPublishModal from './gistPublishModal';

const dialog = require('base/js/dialog');
const CONFIG = {
Expand Down Expand Up @@ -44,19 +45,9 @@ export function registerFeature(): void {
}

function beforePublish(): void {
dialog.modal({
title : 'Publish',
body : 'Publish to an anonymous Github Gist, and open in nbviewer?',
buttons: {
'OK': {
'class' : 'btn-primary',
'click': function() {
saveWidgetsState().then(doPublish);
}
},
'Cancel': {}
}
});
GistPublishModal.show(personalAccessToken => saveWidgetsState().then(
() => doPublish(personalAccessToken)
));
}

function showErrorDialog(errorMsg) {
Expand Down Expand Up @@ -84,14 +75,19 @@ function saveWidgetsState(): Promise<any> {
});
}

function doPublish(): void {
function doPublish(personalAccessToken): void {
const nbjson = Jupyter.notebook.toJSON();
const filedata = {};

filedata[Jupyter.notebook.notebook_name] = {
content : JSON.stringify(nbjson, undefined, 1)
};

let gistsUrl = CONFIG.gistsUrl;
if (personalAccessToken) {
gistsUrl = `${gistsUrl}?oauth_token=${personalAccessToken}`;
}

const settings = {
type : 'POST',
headers : {},
Expand All @@ -102,14 +98,17 @@ function doPublish(): void {
success : (data, status) => {
console.log("gist successfully published: " + data.id);
window.open(CONFIG.nbviewerBaseUrl + data.id);
},
error : (jqXHR, status, err) => {
const errorMsg = jqXHR.readyState === 0 && !err ? 'NETWORK ERROR!' : err;

console.log(errorMsg);
showErrorDialog(errorMsg);
}
};

$.ajax(CONFIG.gistsUrl, settings);
return $.ajax(gistsUrl, settings).catch((jqXHR, status, err) => {
let errorMsg = jqXHR.readyState === 0 && !err ? 'NETWORK ERROR!' : err;

if (jqXHR.responseJSON && jqXHR.responseJSON.message) {
errorMsg = jqXHR.responseJSON.message;
}

console.log(errorMsg);
showErrorDialog(errorMsg);
});
}
36 changes: 36 additions & 0 deletions js/notebook/src/extension/gistPublish/modalTemplate.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!--
Copyright 2017 TWO SIGMA OPEN SOURCE, LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<div>
<p class="alert alert-primary bg-info">
<strong>Leave the Personal Access Token field empty to publish as an anonymous gist.</strong>
<br>
<strong>Press enter or click the "Publish" button below. A
window will open with the results, which you can share like
any URL.</strong>
</p>
<form>
<div class="form-group">
<label>Personal Access Token</label>
<input type="password" class="form-control">
</div>
</form>
<p class="help-block">
<span>Enter a <a target="_blank" href="https://github.com/settings/tokens">Personal Access Token</a> to publish the notebook as a gist in your GitHub account.</span><br>
<span>We recommend your Personal Access Token have only the <strong><i>gists</i></strong> scope.</span><br>
<span>You can read about scopes <a href="https://developer.github.com/apps/building-oauth-apps/scopes-for-oauth-apps/">here</a></span>
</p>
</div>
2 changes: 1 addition & 1 deletion js/notebook/src/plot/plotScope.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ define([
moment
) {

var CONTEXT_MENU_DEBOUNCE_TIME = 250;
var CONTEXT_MENU_DEBOUNCE_TIME = 350;

function PlotScope(wrapperId) {
this.wrapperId = wrapperId;
Expand Down

0 comments on commit 7987165

Please sign in to comment.