def share_notebook(request, course, student, notebook):
"""
the URL to create static snapshots; it is intended to be fetched through ajax
* computes a hash for storing the output
* runs nbconvert in the student's container
* stores the result in /nbhosting/snapshots/<course>/<hash>.html
* returns a JSON-encoded dict that is either
* { url: "/snapshots/flotpython/5465789765789.html" }
* or { error: "the error message" }
"""
# the ipynb extension is removed from the notebook name in urls.py
notebook_withext = notebook + ".ipynb"
# compute hash from the input, so that a second run on the same notebook
# will override any previsouly published static snapshot
hasher = hashlib.sha1(bytes('{}-{}-{}'.format(course, student, notebook),
encoding='utf-8'))
hash = hasher.hexdigest()
subcommand = 'docker-share-student-course-notebook-in-hash'
command = ['nbh', '-d', sitesettings.root]
if DEBUG:
command.append('-x')
command.append(subcommand)
command += [ student, course, notebook_withext, hash]
logger.info("In {}\n-> Running command {}".format(Path.cwd(), " ".join(command)))
completed_process = subprocess.run(
command, universal_newlines=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
log_completed_process(completed_process, subcommand)
if completed_process.returncode != 0:
message = "command {} returned {}\nstderr:{}"\
.format(" ".join(command),
completed_process.returncode,
completed_process.stderr)
return JsonResponse(dict(error=message))
# expect docker-share-student-course-notebook to write a url_path on its stdout
url_path = completed_process.stdout.strip()
logger.info("reading url_path={}".format(url_path))
# rebuild a full URL with proto and hostname,
url = "{scheme}://{hostname}{path}"\
.format(scheme=request.scheme, hostname=request.get_host(), path=url_path)
return JsonResponse(dict(url_path=url_path, url=url))
评论列表
文章目录