Skip to content

Commit 74acab7

Browse files
committed
Link generator handles non-git sources
The link generator creates gitpuller links for non-git sources including archives from google drive, dropbox and any publicly accessible web url.
1 parent a1ea521 commit 74acab7

File tree

3 files changed

+189
-17
lines changed

3 files changed

+189
-17
lines changed

.circleci/config.yml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
version: 2.1
2+
jobs:
3+
build:
4+
docker:
5+
- image: circleci/python:3.6
6+
steps:
7+
- checkout
8+
- run: echo "no operation build"
9+
10+
workflows:
11+
build:
12+
jobs:
13+
- build

_static/link_gen/link.js

+100-12
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
// Pure function that generates an nbgitpuller URL
2-
function generateRegularUrl(hubUrl, urlPath, repoUrl, branch) {
2+
function generateRegularUrl(hubUrl, urlPath, repoUrl, branch, compressed) {
33

44
// assume hubUrl is a valid URL
55
var url = new URL(hubUrl);
66

77
url.searchParams.set('repo', repoUrl);
8-
8+
9+
if(compressed) {
10+
url.searchParams.set('compressed', "true");
11+
}
12+
913
if (urlPath) {
1014
url.searchParams.set('urlpath', urlPath);
1115
}
@@ -100,6 +104,13 @@ var apps = {
100104
}
101105
}
102106

107+
function clearLinks(){
108+
document.getElementById('default-link').value = "";
109+
document.getElementById('binder-link').value = "";
110+
document.getElementById('canvas-link').value = "";
111+
}
112+
113+
var stateSource = null;
103114
function changeTab(div) {
104115
var hub = document.getElementById("hub");
105116
var hub_help_text = document.getElementById("hub-help-text");
@@ -109,8 +120,11 @@ function changeTab(div) {
109120
var content_repo = document.getElementById("content-repo-group");
110121
var content_branch = document.getElementById("content-branch-group");
111122
var id = div.id;
112-
123+
var form = document.getElementById('linkgenerator');
124+
125+
clearLinks();
113126
if (id.includes("binder")) {
127+
document.getElementById("app-source").hidden = true;
114128
hub.placeholder = "https://mybinder.org";
115129
hub.value = "https://mybinder.org";
116130
hub_help_text.hidden = true;
@@ -121,15 +135,27 @@ function changeTab(div) {
121135
env_repo_branch.pattern = ".+";
122136
content_repo.hidden = false;
123137
content_branch.hidden = false;
138+
// if binder but in correct state
139+
stateSource = form.querySelector('input[name="source"]:checked');
140+
document.getElementById("source-git").checked = true;
141+
displaySource();
124142
} else {
143+
document.getElementById("app-source").hidden = false;
125144
hub.placeholder = "https://hub.example.com";
145+
hub.value = "";
126146
hub_help_text.hidden = false;
127147
hub.labels[0].innerHTML = "JupyterHub URL";
128148
env_repo.labels[0].innerHTML = "Git Repository URL";
129149
env_repo_help_text.hidden = true;
130150
env_repo_branch.required = false;
131151
content_repo.hidden = true;
132152
content_branch.hidden = true;
153+
154+
//if coming from binder tab restore state
155+
if(stateSource)
156+
stateSource.checked = true;
157+
stateSource = null
158+
displaySource();
133159
}
134160
}
135161

@@ -145,24 +171,32 @@ function generateCloneDirectoryName(gitCloneUrl) {
145171
return lastPart.split(':').slice(-1)[0].replace(/(\.git|\.bundle)?/, '');
146172
}
147173

174+
148175
function displayLink() {
149176
var form = document.getElementById('linkgenerator');
150-
177+
151178
form.classList.add('was-validated');
152179
if (form.checkValidity()) {
153180
var hubUrl = document.getElementById('hub').value;
154181
var repoUrl = document.getElementById('repo').value;
155-
var branch = document.getElementById('branch').value;
182+
var driveUrl = document.getElementById('drive-url').value;
183+
var dropUrl = document.getElementById('drop-url').value;
184+
var webUrl = document.getElementById('web-url').value;
185+
var gitBranch = document.getElementById('branch').value;
156186
var contentRepoUrl = document.getElementById('content-repo').value;
157187
var contentRepoBranch = document.getElementById('content-branch').value;
158188
var filePath = document.getElementById('filepath').value;
159189
var appName = form.querySelector('input[name="app"]:checked').value;
160190
var activeTab = document.querySelector(".nav-link.active").id;
161-
191+
var source = form.querySelector('input[name="source"]:checked').value;
192+
162193
if (appName === 'custom') {
163194
var urlPath = document.getElementById('urlpath').value;
164195
} else {
165196
var repoName = generateCloneDirectoryName(repoUrl);
197+
if(source !== "git"){
198+
repoName = ""
199+
}
166200
var urlPath;
167201
if (activeTab === "tab-auth-binder") {
168202
var contentRepoName = new URL(contentRepoUrl).pathname.split('/').pop().replace(/\.git$/, '');
@@ -171,26 +205,41 @@ function displayLink() {
171205
urlPath = apps[appName].generateUrlPath(repoName + '/' + filePath);
172206
}
173207
}
174-
175208
if (activeTab === "tab-auth-default") {
209+
branch = "";
210+
compressed = true;
211+
if(source == "git"){
212+
sourceUrl = repoUrl;
213+
branch = gitBranch;
214+
compressed = false;
215+
} else if(source == "googledrive"){
216+
sourceUrl = driveUrl;
217+
} else if(source == "dropbox"){
218+
sourceUrl = dropUrl;
219+
} else if(source == "web"){
220+
sourceUrl = webUrl;
221+
}
176222
document.getElementById('default-link').value = generateRegularUrl(
177-
hubUrl, urlPath, repoUrl, branch
223+
hubUrl, urlPath, sourceUrl, branch, compressed
178224
);
179225
} else if (activeTab === "tab-auth-canvas"){
180226
document.getElementById('canvas-link').value = generateCanvasUrl(
181-
hubUrl, urlPath, repoUrl, branch
227+
hubUrl, urlPath, repoUrl, gitBranch
182228
);
183229
} else if (activeTab === "tab-auth-binder"){
184230
// FIXME: userName parsing using new URL(...) assumes a
185231
// HTTP based repoUrl. Does it make sense to create a
186232
// BinderHub link for SSH URLs? Then let's fix this parsing.
187233
var userName = new URL(repoUrl).pathname.split('/')[1];
188234
document.getElementById('binder-link').value = generateBinderUrl(
189-
hubUrl, userName, repoName, branch, urlPath, contentRepoUrl, contentRepoBranch
235+
hubUrl, userName, repoName, gitBranch, urlPath, contentRepoUrl, contentRepoBranch
190236
);
191237
}
238+
} else {
239+
clearLinks();
192240
}
193241
}
242+
194243
function populateFromQueryString() {
195244
// preseed values if specified in the url
196245
var params = new URLSearchParams(window.location.search);
@@ -213,6 +262,31 @@ function populateFromQueryString() {
213262
}
214263
}
215264

265+
function hideShowByClassName(cls, hideShow){
266+
[].forEach.call(document.querySelectorAll(cls), function (el) {
267+
el.style.display = hideShow;
268+
setDisabled = (hideShow == 'none')
269+
$(el).find("input").each(function(){
270+
$(this).prop("disabled", setDisabled);
271+
});
272+
});
273+
}
274+
275+
function displaySource(){
276+
var form = document.getElementById('linkgenerator');
277+
var source = form.querySelector('input[name="source"]:checked').value;
278+
hideShowByClassName(".source", 'none');
279+
if(source == 'git'){
280+
hideShowByClassName(".source-git", '');
281+
} else if(source == 'googledrive'){
282+
hideShowByClassName(".source-googledrive", '');
283+
} else if(source == 'dropbox'){
284+
hideShowByClassName(".source-dropbox", '');
285+
} else if(source == 'web'){
286+
hideShowByClassName(".source-web", '');
287+
}
288+
}
289+
216290
/**
217291
* Main loop of the program.
218292
*
@@ -224,7 +298,7 @@ function populateFromQueryString() {
224298
function render() {
225299
var form = document.getElementById('linkgenerator');
226300
var appName = form.querySelector('input[name="app"]:checked').value;
227-
301+
228302
if (appName == 'custom') {
229303
document.getElementById('urlpath').disabled = false;
230304
document.getElementById('filepath').disabled = true;
@@ -238,6 +312,8 @@ function render() {
238312
document.getElementById('filepath').disabled = false;
239313
}
240314
}
315+
316+
241317
displayLink();
242318
}
243319

@@ -246,11 +322,21 @@ function render() {
246322
*/
247323
function main() {
248324
// Hook up any changes in form elements to call render()
249-
document.querySelectorAll('#linkgenerator input[type="radio"]').forEach(
325+
document.querySelectorAll('#linkgenerator input[name="app"]').forEach(
250326
function (element) {
251327
element.addEventListener('change', render);
252328
}
253329
)
330+
document.querySelectorAll('#linkgenerator input[name="source"]').forEach(
331+
function (element) {
332+
element.addEventListener('change', function(){
333+
displaySource();
334+
render();
335+
}
336+
);
337+
}
338+
)
339+
254340
document.querySelectorAll('#linkgenerator input[type="text"], #linkgenerator input[type="url"]').forEach(
255341
function (element) {
256342
element.addEventListener('input', render);
@@ -269,7 +355,9 @@ function main() {
269355
}
270356
}
271357

358+
272359
// Do an initial render, to make sure our disabled / enabled properties are correctly set
360+
displaySource();
273361
render();
274362
}
275363

link.html

+76-5
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,41 @@ <h1>nbgitpuller link generator<a class="headerlink" href="#nbgitpuller-link-gene
221221
</small>
222222
</div>
223223
</div>
224-
225-
<div class="form-group row">
224+
225+
<div class="form-group row" id="app-source">
226+
<div class="col-sm-2 col-form-label">
227+
<label for="app" class=>Notebook Source</label>
228+
<small class="form-text text-muted">
229+
</small>
230+
</div>
231+
<div class="col-sm-10">
232+
<div class="form-check">
233+
<input class="form-check-input" type="radio" name="source" id="source-git" value="git" checked>
234+
<label class="form-check-label text-dark" for="source-git">
235+
Git Repository(eg. github)
236+
</label>
237+
</div>
238+
<div class="form-check">
239+
<input class="form-check-input" type="radio" name="source" id="source-googledrive" value="googledrive">
240+
<label class="form-check-label text-dark" for="source-googledrive">
241+
Google Drive
242+
</label>
243+
</div>
244+
<div class="form-check">
245+
<input class="form-check-input" type="radio" name="source" id="source-dropbox" value="dropbox">
246+
<label class="form-check-label text-dark" for="source-dropbox">
247+
Dropbox
248+
</label>
249+
</div>
250+
<div class="form-check">
251+
<input class="form-check-input" type="radio" name="source" id="source-web" value="web">
252+
<label class="form-check-label text-dark" for="source-web">
253+
Web(Public URL to archive)
254+
</label>
255+
</div>
256+
</div>
257+
</div>
258+
<div class="form-group row source source-git">
226259
<label for="repo" class="col-sm-2 col-form-label">Git Repository URL</label>
227260
<div class="col-sm-6">
228261
<input class="form-control" type="text" id="repo" placeholder="https://github.com/example/test"
@@ -250,7 +283,7 @@ <h1>nbgitpuller link generator<a class="headerlink" href="#nbgitpuller-link-gene
250283
</div>
251284
</div>
252285

253-
<div class="form-group row" id="content-repo-group" hidden="true">
286+
<div class="form-group row source source-git" id="content-repo-group" hidden="true">
254287
<label for="content-repo" class="col-sm-2 col-form-label">Git Content Repository URL</label>
255288
<div class="col-sm-6">
256289
<input class="form-control" type="text" id="content-repo" placeholder="https://github.com/example/test"
@@ -264,12 +297,17 @@ <h1>nbgitpuller link generator<a class="headerlink" href="#nbgitpuller-link-gene
264297
<div class="input-group-prepend">
265298
<span class="input-group-text" id="content-branch-prepend-label">branch</span>
266299
</div>
267-
<input name="content-branch" id="content-branch" type="text" class="form-control" value="master" aria-label="Branch Name" aria-describedby="content-branch-prepend-label">
300+
<input name="content-branch" id="content-branch" type="text" aria-label="Branch Name" aria-describedby="content-branch-prepend-label">
301+
<small id="default-content-message" class="form-text text-muted">
302+
If left blank, the default branch of your repository is used. Also note, Github now names the default branch <code>main</code> instead of <code>master</code> on
303+
<a href="https://github.blog/changelog/2020-10-01-the-default-branch-for-newly-created-repositories-is-now-main/">
304+
new GitHub repositories</a>
305+
</small>
268306
</div>
269307
</div>
270308
</div>
271309

272-
<div class="form-group row" id="filepath-container">
310+
<div class="form-group row source source-git" id="filepath-container">
273311
<label for="filepath" class="col-sm-2 col-form-label">File to open</label>
274312
<div class="col-sm-10">
275313
<input class="form-control" type="text" id="filepath" placeholder="index.ipynb"
@@ -280,6 +318,39 @@ <h1>nbgitpuller link generator<a class="headerlink" href="#nbgitpuller-link-gene
280318
</div>
281319
</div>
282320

321+
<div class="form-group row source source-googledrive">
322+
<label for="repo" class="col-sm-2 col-form-label">Google Drive Shared Link</label>
323+
<div class="col-sm-10">
324+
<input class="form-control" type="text" id="drive-url" placeholder="https://drive.google.com/file/d/1p3m0h5UGWdLkVVP0S1HpG2yeDlU/view?usp=sharing"
325+
oninput="displayLink()" required pattern="((https?)://.+|(drive.google).+:.+)">
326+
<div class="invalid-feedback">
327+
Must be a valid Google Drive URL
328+
</div>
329+
</div>
330+
</div>
331+
332+
<div class="form-group row source source-dropbox">
333+
<label for="repo" class="col-sm-2 col-form-label">Dropbox Shared Link</label>
334+
<div class="col-sm-10">
335+
<input class="form-control" type="text" id="drop-url" placeholder="https://www.dropbox.com/s/w0q4eirtuht/example.tgz?dl=0"
336+
oninput="displayLink()" required pattern="((https?)://.+|(drive.google).+:.+)">
337+
<div class="invalid-feedback">
338+
Must be a valid Dropbox URL (Note: all the common compression formats work(e.g. zip, tar, tgz, etc))
339+
</div>
340+
</div>
341+
</div>
342+
343+
<div class="form-group row source source-web">
344+
<label for="repo" class="col-sm-2 col-form-label">Public URL to archive</label>
345+
<div class="col-sm-10">
346+
<input class="form-control" type="text" id="web-url" placeholder="https://example.com/materials-sp20-external.zip"
347+
oninput="displayLink()" required pattern="((https?)://.+|(drive.google).+:.+)">
348+
<div class="invalid-feedback">
349+
Must be a valid public URL (Note: all the common compression formats work(e.g. zip, tar, tgz, etc))
350+
</div>
351+
</div>
352+
</div>
353+
283354
<div class="form-group row" id="app-container">
284355
<div class="col-sm-2 col-form-label">
285356
<label for="app" class=>Application to Open</label>

0 commit comments

Comments
 (0)