diff --git a/nbrmd/contentsmanager.py b/nbrmd/contentsmanager.py index 5895be16c..df410e15a 100644 --- a/nbrmd/contentsmanager.py +++ b/nbrmd/contentsmanager.py @@ -1,6 +1,8 @@ import notebook.transutils from notebook.services.contents.filemanager import FileContentsManager from tornado.web import HTTPError +from traitlets import Unicode +from traitlets.config import Configurable import os import nbrmd @@ -25,14 +27,21 @@ def _reads(s, as_version, **kwargs): def check_formats(formats): + if isinstance(formats, str): + formats = formats.split(',') + + formats = [fmt if fmt.startswith('.') else '.' + fmt + for fmt in formats if fmt != ''] + allowed = nbrmd.notebook_extensions if not isinstance(formats, list) or not set(formats).issubset(allowed): - raise TypeError(u"Notebook metadata 'nbrmd_formats' " - u"should be subset of {}".format(str(allowed))) + raise TypeError("Notebook metadata 'nbrmd_formats' " + "should be subset of {}, but was {}" + "".format(str(allowed), str(formats))) return formats -class RmdFileContentsManager(FileContentsManager): +class RmdFileContentsManager(FileContentsManager, Configurable): """ A FileContentsManager Class that reads and stores notebooks to classical Jupyter notebooks (.ipynb), R Markdown notebooks (.Rmd), @@ -45,8 +54,11 @@ class RmdFileContentsManager(FileContentsManager): def all_nb_extensions(self): return ['.ipynb'] + self.nb_extensions - default_nbrmd_formats = ['.ipynb'] - default_nbrmd_sourceonly_format = None + default_nbrmd_formats = Unicode( + u'ipynb', + help='Save notebooks to these file extensions. ' + 'Can be any of ipynb,Rmd,py,R, comma separated', + config=True) def _read_notebook(self, os_path, as_version=4, load_alternative_format=True): @@ -67,24 +79,23 @@ def _read_notebook(self, os_path, as_version=4, nbrmd_formats = (nb.metadata.get('nbrmd_formats') or self.default_nbrmd_formats) + nbrmd_formats = check_formats(nbrmd_formats) + if ext not in nbrmd_formats: nbrmd_formats.append(ext) nbrmd_formats = check_formats(nbrmd_formats) - # Source format is taken in metadata, contentsmanager, or is current - # ext, or is first non .ipynb format that is found on disk - source_format = (nb.metadata.get('nbrmd_sourceonly_format') or - self.default_nbrmd_sourceonly_format) - - if source_format is None: - if ext != '.ipynb': - source_format = ext - else: - for fmt in nbrmd_formats: - if fmt != '.ipynb' and os.path.isfile(file + fmt): - source_format = fmt - break + # Source format is current ext, or is first non .ipynb format + # that is found on disk + source_format = None + if ext != '.ipynb': + source_format = ext + else: + for fmt in nbrmd_formats: + if fmt != '.ipynb' and os.path.isfile(file + fmt): + source_format = fmt + break nb_outputs = None if source_format is not None and ext != source_format: @@ -120,6 +131,8 @@ def _save_notebook(self, os_path, nb): formats = (nb.get('metadata', {}).get('nbrmd_formats') or self.default_nbrmd_formats) + formats = check_formats(formats) + if org_ext not in formats: formats.append(org_ext) diff --git a/tests/test_save_multiple.py b/tests/test_save_multiple.py index 00a6077b2..9cda436e2 100644 --- a/tests/test_save_multiple.py +++ b/tests/test_save_multiple.py @@ -76,7 +76,7 @@ def test_no_files_created_on_no_format(tmpdir): cm = RmdFileContentsManager() cm.root_dir = str(tmpdir) - cm.default_nbrmd_formats = [] + cm.default_nbrmd_formats = '' cm.save( model=dict(type='notebook', @@ -109,7 +109,7 @@ def test_no_rmd_on_not_notebook(tmpdir): cm = RmdFileContentsManager() cm.root_dir = str(tmpdir) - cm.default_nbrmd_formats = ['.Rmd'] + cm.default_nbrmd_formats = '.Rmd' with pytest.raises(HTTPError): cm.save(model=dict(type='not notebook', @@ -124,7 +124,7 @@ def test_no_rmd_on_not_v4(tmpdir): cm = RmdFileContentsManager() cm.root_dir = str(tmpdir) - cm.default_nbrmd_formats = ['.Rmd'] + cm.default_nbrmd_formats = '.Rmd' with pytest.raises(NotebookValidationError): cm.save(model=dict(type='notebook', diff --git a/tests/utils.py b/tests/utils.py index 409a11dc3..eb61d9c8e 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -31,10 +31,6 @@ def remove_outputs(nb): if k in nb: del nb[k] - for k in ['nbrmd_formats', 'nbrmd_sourceonly_format']: - if k in nb.metadata: - del nb.metadata[k] - return nb