Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions nbviewer/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class NBViewer(Application):
github_tree_handler = Unicode(default_value="nbviewer.providers.github.handlers.GitHubTreeHandler", help="The Tornado handler to use for viewing directory trees on GitHub").tag(config=True)
gist_handler = Unicode(default_value="nbviewer.providers.gist.handlers.GistHandler", help="The Tornado handler to use for viewing notebooks stored as GitHub Gists").tag(config=True)
user_gists_handler = Unicode(default_value="nbviewer.providers.gist.handlers.UserGistsHandler", help="The Tornado handler to use for viewing directory containing all of a user's Gists").tag(config=True)
gitlab_handler = Unicode(default_value="nbviewer.providers.gitlab.handlers.GitlabHandler", help="The Tornado handler to use for viewing notebooks in a GitLab instance").tag(config=True)

client = Any().tag(config=True)
@default('client')
Expand Down Expand Up @@ -245,6 +246,7 @@ def init_tornado_application(self):
local_handler=self.local_handler,
gist_handler=self.gist_handler,
user_gists_handler=self.user_gists_handler,
gitlab_handler=self.gitlab_handler,
)
handler_kwargs = {'handler_names' : handler_names, 'handler_settings' : self.handler_settings}
handlers = init_handlers(self.formats, options.providers, self.base_url, options.localfiles, **handler_kwargs)
Expand Down
4 changes: 2 additions & 2 deletions nbviewer/providers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
#-----------------------------------------------------------------------------

default_providers = ['nbviewer.providers.{}'.format(prov)
for prov in ['url', 'github', 'gist']]
for prov in ['url', 'github', 'gist', 'gitlab']]

default_rewrites = ['nbviewer.providers.{}'.format(prov)
for prov in ['gist', 'github', 'dropbox', 'url']]
for prov in ['gitlab', 'gist', 'github', 'dropbox', 'url']]


def provider_handlers(providers, **handler_kwargs):
Expand Down
1 change: 1 addition & 0 deletions nbviewer/providers/gitlab/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .handlers import default_handlers, uri_rewrites
107 changes: 107 additions & 0 deletions nbviewer/providers/gitlab/handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import json
import os
from tornado import web
from tornado.log import app_log
from ..base import RenderingHandler, cached
from ...utils import response_text
from .. import _load_handler_from_location


class GitlabHandler(RenderingHandler):

async def get_notebook_data(self, host, group, repo, blob, branch, path):

token = os.environ.get("GITLAB_TOKEN")

base_url = "https://{host}/api/v4".format(host=host)

projects_url = ("{base_url}/projects?private_token={token}"
.format(base_url=base_url, token=token))

app_log.info("Fetching " + projects_url)

try:
projects_response = await self.fetch(projects_url)
projects_text = response_text(projects_response)
projects = json.loads(projects_text)

path_with_namespace = "{group}/{repo}".format(group=group, repo=repo)

project = None
for p in projects:
if p["path_with_namespace"] == path_with_namespace:
project = p
break
else:
raise Exception("Project path not found: " + path_with_namespace)

prj = project["id"]
tree_url = ("{base_url}/projects/{prj}/repository/tree?recursive=true&ref={branch}&per_page=1000&private_token={token}"
.format(base_url=base_url,
prj=prj,
branch=branch,
token=token))

app_log.info("Fetching " + tree_url)

tree_response = await self.fetch(tree_url)
tree_text = response_text(tree_response)
tree = json.loads(tree_text)

blob = None
for item in tree:
if item["path"] == path:
blob = item
break
else:
raise Exception("Blob not found: " + path)

sha = blob["id"]

raw_url = "{base_url}/projects/{prj}/repository/blobs/{sha}/raw?private_token={token}"
return raw_url.format(base_url=base_url,
prj=prj,
sha=sha,
token=token)

except Exception as e:
app_log.error(e)


async def deliver_notebook(self, remote_url):
app_log.info("Fetching notebook: " + remote_url)

response = await self.fetch(remote_url)

try:
nbjson = response_text(response, encoding='utf-8')
except UnicodeDecodeError:
app_log.error("Notebook is not utf8: %s", remote_url, exc_info=True)
raise web.HTTPError(400)

await self.finish_notebook(nbjson,
download_url=remote_url,
msg="file from url: " + remote_url,
public=False,
request=self.request)



@cached
async def get(self, host, group, repo, blob, branch, path):
raw_url = await self.get_notebook_data(host, group, repo, blob, branch, path)
await self.deliver_notebook(raw_url)

def uri_rewrites(rewrites=[]):
gitlab_rewrites = [
(r'^https?://(gitlab\..*)$', r'/gitlab/{0}'),
(r'^/url[s]?/(gitlab\..*)$', r'/gitlab/{0}'),
(r'^/url[s]?/https?://(gitlab\..*)$', r'/gitlab/{0}'),
]
return rewrites + gitlab_rewrites

def default_handlers(handlers=[], **handler_names):
gitlab_handler = _load_handler_from_location(handler_names['gitlab_handler'])
return handlers + [
(r'/gitlab/(?P<host>[\w_\-.]+)/(?P<group>[\w_\-.]+)/(?P<repo>[\w_\-]+)/(?P<blob>blob)/(?P<branch>[\w_\-()]+)/(?P<path>.*)', gitlab_handler, {}),
]