Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MRG] Add Figshare to UI #951

Merged
merged 1 commit into from
Sep 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,5 @@ travis
helm-chart/travis-binder.yaml

# Federation data page
doc/federation/data-federation.txt
doc/federation/data-federation.txt
.vscode/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'm not wild about having editor specific ignores. Mostly because I fear we end up with many many different (poorly maintained) ignores for all the different editors people use. I think it is nicer if each of us has their own "global" gitignore a la https://help.github.com/en/articles/ignoring-files#create-a-global-gitignore

24 changes: 22 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ every day development.

* Start and stop minikube with `minikube start` and `minikube stop`.
* Install JupyterHub in minikube with helm `./testing/minikube/install-hub`
* Setup docker to use the same docker daemon as your minikube cluster `eval $(minikube docker-env)`
* Setup `docker` to use the same Docker daemon as your minikube cluster `eval $(minikube docker-env)`
* Start BinderHub `python3 -m binderhub -f testing/minikube/binderhub_config.py`
* Visit your BinderHub at[http://localhost:8585](http://localhost:8585)

Expand Down Expand Up @@ -209,7 +209,7 @@ sudo apt install socat
eval $(minikube docker-env)
```

This command sets up docker to use the same docker daemon as your minikube
This command sets up `docker` to use the same Docker daemon as your minikube
cluster does. This means images you build are directly available to the
cluster. Note: when you no longer wish to use the minikube host, you can
undo this change by running:
Expand All @@ -229,6 +229,26 @@ sudo apt install socat
All features should work, including building and launching of repositories.


### Tip: Use local repo2docker version

BinderHub runs repo2docker in a container.
For testing the combination of an unreleased repo2docker feature with BinderHub, you can use a locally build repo2docker image.
You can configure the image in the file `testing/minikube/binderhub_config.py` with the following line:

```python
c.BinderHub.build_image = 'jupyter-repo2docker:my_image_tag'
```

**Important**: the image must be build using the same Docker daemon as the minikube cluster, otherwise you get an error _"Failed to pull image [...] repository does not exist or may require 'docker login'"_.

### Tip: Enable debug logging

In the file `testing/minikube/binderhub_config.py` add the following line:

```python
c.BinderHub.debug = True
```

### Tip: Increase your GitHub API limit

By default, GitHub has a limit of 60 API requests per hour. We recommend
Expand Down
3 changes: 2 additions & 1 deletion binderhub/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
from .main import MainHandler, ParameterizedMainHandler, LegacyRedirectHandler
from .repoproviders import (GitHubRepoProvider, GitRepoProvider,
GitLabRepoProvider, GistRepoProvider,
ZenodoProvider)
ZenodoProvider, FigshareProvider)
from .metrics import MetricsHandler

from .utils import ByteSpecification, url_path_join
Expand Down Expand Up @@ -379,6 +379,7 @@ def _add_slash(self, proposal):
'git': GitRepoProvider,
'gl': GitLabRepoProvider,
'zenodo': ZenodoProvider,
'figshare': FigshareProvider,
},
config=True,
help="""
Expand Down
3 changes: 2 additions & 1 deletion binderhub/event-schemas/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"Gist",
"GitLab",
"Git",
"Zenodo"
"Zenodo",
"Figshare"
],
"description": "Provider for the repository being launched"
},
Expand Down
3 changes: 2 additions & 1 deletion binderhub/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"gist": "Gist",
"gl": "GitLab",
"git": "Git repo",
"zenodo": "Zenodo"
"zenodo": "Zenodo",
"figshare": "Figshare"
}


Expand Down
33 changes: 33 additions & 0 deletions binderhub/repoproviders.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,39 @@ def get_build_slug(self):
return "zenodo-{}".format(self.record_id)


class FigshareProvider(RepoProvider):
"""Provide contents of a Figshare article

Users must provide a spec consisting of the Figshare DOI.
"""
name = Unicode("Figshare")
url_regex = re.compile(r"(.*)/articles/([^/]+)/(\d+)(/)?(\d+)?")

@gen.coroutine
def get_resolved_ref(self):
client = AsyncHTTPClient()
req = HTTPRequest("https://doi.org/{}".format(self.spec),
user_agent="BinderHub")
r = yield client.fetch(req)

match = self.url_regex.match(r.effective_url)
article_id = match.groups()[2]
article_version = match.groups()[4]
if not article_version:
article_version = "1"
self.record_id = "{}.v{}".format(article_id, article_version)

return self.record_id

def get_repo_url(self):
# While called repo URL, the return value of this function is passed
# as argument to repo2docker, hence we return the spec as is.
return self.spec

def get_build_slug(self):
return "figshare-{}".format(self.record_id)


class GitRepoProvider(RepoProvider):
"""Bare bones git repo provider.

Expand Down
7 changes: 6 additions & 1 deletion binderhub/static/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ function updateRepoText() {
$("#ref").prop("disabled", true);
$("label[for=ref]").prop("disabled", true);
}
else if (provider === "figshare") {
text = "Figshare DOI (10.6084/m9.figshare.9782777.v1)";
$("#ref").prop("disabled", true);
$("label[for=ref]").prop("disabled", true);
}
$("#repository").attr('placeholder', text);
$("label[for=repository]").text(text);
$("#ref").attr('placeholder', tag_text);
Expand All @@ -107,7 +112,7 @@ function getBuildFormValues() {
}

var ref = $('#ref').val().trim() || 'master';
if (providerPrefix === 'zenodo') {
if (providerPrefix === 'zenodo' || providerPrefix === 'figshare') {
ref = "";
}
var path = $('#filepath').val().trim();
Expand Down
1 change: 1 addition & 0 deletions binderhub/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ <h4 id="form-header" class='row'>Build and launch a repository</h4>
<li class="dropdown-item" value="gl"><a href="#">GitLab.com</a></li>
<li class="dropdown-item" value="git"><a href="#">Git repository</a></li>
<li class="dropdown-item" value="zenodo"><a href="#">Zenodo DOI</a></li>
<li class="dropdown-item" value="figshare"><a href="#">Figshare DOI</a></li>
</ul>
</div>
</div>
Expand Down
17 changes: 16 additions & 1 deletion binderhub/tests/test_repoproviders.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from binderhub.repoproviders import (
tokenize_spec, strip_suffix, GitHubRepoProvider, GitRepoProvider,
GitLabRepoProvider, GistRepoProvider, ZenodoProvider
GitLabRepoProvider, GistRepoProvider, ZenodoProvider, FigshareProvider
)


Expand Down Expand Up @@ -52,6 +52,21 @@ async def test_zenodo():
assert repo_url == spec


async def test_figshare():
spec = '10.6084/m9.figshare.9782777.v1'

provider = FigshareProvider(spec=spec)

# have to resolve the ref first
ref = await provider.get_resolved_ref()
assert ref == '9782777.v1'

slug = provider.get_build_slug()
assert slug == 'figshare-9782777.v1'
repo_url = provider.get_repo_url()
assert repo_url == spec


@pytest.mark.github_api
def test_github_ref():
provider = GitHubRepoProvider(spec='jupyterhub/zero-to-jupyterhub-k8s/v0.4')
Expand Down