##// END OF EJS Templates
Moved nb conversion into its own method. Additional error handling.
Jonathan Frederic -
Show More
@@ -1,180 +1,196 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 """NBConvert is a utility for conversion of IPYNB files.
2 """NBConvert is a utility for conversion of IPYNB files.
3
3
4 Commandline interface for the NBConvert conversion utility. Read the
4 Commandline interface for the NBConvert conversion utility. Read the
5 readme.rst for usage information
5 readme.rst for usage information
6 """
6 """
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 #Copyright (c) 2013, the IPython Development Team.
8 #Copyright (c) 2013, the IPython Development Team.
9 #
9 #
10 #Distributed under the terms of the Modified BSD License.
10 #Distributed under the terms of the Modified BSD License.
11 #
11 #
12 #The full license is in the file COPYING.txt, distributed with this software.
12 #The full license is in the file COPYING.txt, distributed with this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 #Imports
16 #Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #Stdlib imports
19 #Stdlib imports
20 from __future__ import print_function
20 from __future__ import print_function
21 import sys
21 import sys
22 import os
22 import os
23 import glob
23 import glob
24
24
25 #From IPython
25 #From IPython
26 from IPython.core.application import BaseIPythonApplication
26 from IPython.core.application import BaseIPythonApplication
27 from IPython.config.application import catch_config_error
27 from IPython.config.application import catch_config_error
28 from IPython.utils.traitlets import Unicode, List, Instance, DottedObjectName, Type
28 from IPython.utils.traitlets import Unicode, List, Instance, DottedObjectName, Type
29 from IPython.utils.importstring import import_item
29 from IPython.utils.importstring import import_item
30
30
31 from .exporters.export import export_by_name, get_export_names, ExporterNameError
31 from .exporters.export import export_by_name, get_export_names, ExporterNameError
32 from .exporters.exporter import Exporter
32 from .exporters.exporter import Exporter
33 from .writers.base import WriterBase
33 from .writers.base import WriterBase
34 from .utils.config import GlobalConfigurable
34 from .utils.config import GlobalConfigurable
35
35
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37 #Classes and functions
37 #Classes and functions
38 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
39
39
40 class NbConvertApp(BaseIPythonApplication):
40 class NbConvertApp(BaseIPythonApplication):
41 """Application used to convert to and from notebook file type (*.ipynb)"""
41 """Application used to convert to and from notebook file type (*.ipynb)"""
42
42
43
43
44 description = Unicode(
44 description = Unicode(
45 u"""This application is used to convert notebook files (*.ipynb).
45 u"""This application is used to convert notebook files (*.ipynb).
46 An ipython config file can be used to batch convert notebooks in the
46 An ipython config file can be used to batch convert notebooks in the
47 current directory.""")
47 current directory.""")
48
48
49 examples = Unicode(u"""
49 examples = Unicode(u"""
50 Running `ipython nbconvert` will read the directory config file and then
50 Running `ipython nbconvert` will read the directory config file and then
51 apply it to one or more notebooks.
51 apply it to one or more notebooks.
52
52
53 Multiple notebooks can be given at the command line in a couple of
53 Multiple notebooks can be given at the command line in a couple of
54 different ways:
54 different ways:
55
55
56 > ipython nbconvert notebook*.ipynb
56 > ipython nbconvert notebook*.ipynb
57 > ipython nbconvert notebook1.ipynb notebook2.ipynb
57 > ipython nbconvert notebook1.ipynb notebook2.ipynb
58 > ipython nbconvert # this will use the config file to fill in the notebooks
58 > ipython nbconvert # this will use the config file to fill in the notebooks
59 """)
59 """)
60
60
61 config_file_name = Unicode(u'ipython_nbconvert_config.py')
61 config_file_name = Unicode(u'ipython_nbconvert_config.py')
62
62
63 #Writer specific variables
63 #Writer specific variables
64 writer = Instance('IPython.nbconvert.writers.base.WriterBase',
64 writer = Instance('IPython.nbconvert.writers.base.WriterBase',
65 help="""Instance of the writer class used to write the
65 help="""Instance of the writer class used to write the
66 results of the conversion.""")
66 results of the conversion.""")
67 writer_class = DottedObjectName('FilesWriter', config=True,
67 writer_class = DottedObjectName('FilesWriter', config=True,
68 help="""Writer class used to write the
68 help="""Writer class used to write the
69 results of the conversion""")
69 results of the conversion""")
70 writer_aliases = {'FilesWriter': 'IPython.nbconvert.writers.files.FilesWriter',
70 writer_aliases = {'FilesWriter': 'IPython.nbconvert.writers.files.FilesWriter',
71 'DebugWriter': 'IPython.nbconvert.writers.debug.DebugWriter',
71 'DebugWriter': 'IPython.nbconvert.writers.debug.DebugWriter',
72 'StdoutWriter': 'IPython.nbconvert.writers.stdout.StdoutWriter'}
72 'StdoutWriter': 'IPython.nbconvert.writers.stdout.StdoutWriter'}
73 writer_factory = Type()
73 writer_factory = Type()
74
74
75 def _writer_class_changed(self, name, old, new):
75 def _writer_class_changed(self, name, old, new):
76 if new in self.writer_aliases:
76 if new in self.writer_aliases:
77 new = self.writer_aliases[new]
77 new = self.writer_aliases[new]
78 self.writer_factory = import_item(new)
78 self.writer_factory = import_item(new)
79
79
80
80
81 #Other configurable variables
81 #Other configurable variables
82 export_format = Unicode(
82 export_format = Unicode(
83 "", config=True,
83 "", config=True,
84 help="""If specified, nbconvert will convert the document(s) specified
84 help="""If specified, nbconvert will convert the document(s) specified
85 using this format.""")
85 using this format.""")
86
86
87 notebooks = List([], config=True, help="""List of notebooks to convert.
87 notebooks = List([], config=True, help="""List of notebooks to convert.
88 Search patterns are supported.""")
88 Search patterns are supported.""")
89
89
90 aliases = {'format':'NbConvertApp.export_format',
90 aliases = {'format':'NbConvertApp.export_format',
91 'notebooks':'NbConvertApp.notebooks',
91 'notebooks':'NbConvertApp.notebooks',
92 'writer':'NbConvertApp.writer_class'}
92 'writer':'NbConvertApp.writer_class'}
93
93
94
94
95 @catch_config_error
95 @catch_config_error
96 def initialize(self, argv=None):
96 def initialize(self, argv=None):
97 super(NbConvertApp, self).initialize(argv)
97 super(NbConvertApp, self).initialize(argv)
98
98
99 #Register class here to have help with help all
99 #Register class here to have help with help all
100 self.classes.insert(0, Exporter)
100 self.classes.insert(0, Exporter)
101 self.classes.insert(0, WriterBase)
101 self.classes.insert(0, WriterBase)
102 self.classes.insert(0, GlobalConfigurable)
102 self.classes.insert(0, GlobalConfigurable)
103
103
104 #Init
104 #Init
105 self.init_config(self.extra_args)
105 self.init_config(self.extra_args)
106 self.init_writer()
106 self.init_writer()
107
107
108
108
109 def init_config(self, extra_args):
109 def init_config(self, extra_args):
110 """
110 """
111 Add notebooks to the config if needed. Glob each notebook to replace
111 Add notebooks to the config if needed. Glob each notebook to replace
112 notebook patterns with filenames.
112 notebook patterns with filenames.
113 """
113 """
114
114
115 #Get any additional notebook patterns from the commandline
115 #Get any additional notebook patterns from the commandline
116 if len(extra_args) > 0:
116 if len(extra_args) > 0:
117 for pattern in extra_args:
117 for pattern in extra_args:
118 self.notebooks.append(pattern)
118 self.notebooks.append(pattern)
119
119
120 #Use glob to replace all the notebook patterns with filenames.
120 #Use glob to replace all the notebook patterns with filenames.
121 filenames = []
121 filenames = []
122 for pattern in self.notebooks:
122 for pattern in self.notebooks:
123 for filename in glob.glob(pattern):
123 for filename in glob.glob(pattern):
124 if not filename in filenames:
124 if not filename in filenames:
125 filenames.append(filename)
125 filenames.append(filename)
126 self.notebooks = filenames
126 self.notebooks = filenames
127
127
128
128
129 def init_writer(self):
129 def init_writer(self):
130 """
130 """
131 Initialize the writer (which is stateless)
131 Initialize the writer (which is stateless)
132 """
132 """
133 self._writer_class_changed(None, self.writer_class, self.writer_class)
133 self._writer_class_changed(None, self.writer_class, self.writer_class)
134 self.writer = self.writer_factory(parent=self)
134 self.writer = self.writer_factory(parent=self)
135
135
136
136
137 def start(self, argv=None):
137 def start(self, argv=None):
138 """
138 """
139 Entrypoint of NbConvert application.
139 Entrypoint of NbConvert application.
140 """
140 """
141
142 #Call base
143 super(NbConvertApp, self).start()
141 super(NbConvertApp, self).start()
142 self.convert_notebooks()
143
144
144
145 def convert_notebooks(self):
146 """
147 Convert the notebooks in the self.notebook traitlet
148 """
145 #Export each notebook
149 #Export each notebook
146 #TODO: Empty check
150 conversion_success = 0
147 for notebook_filename in self.notebooks:
151 for notebook_filename in self.notebooks:
148
152
149 #Get a unique key for the notebook and set it in the resources object.
153 #Get a unique key for the notebook and set it in the resources object.
150 basename = os.path.basename(notebook_filename)
154 basename = os.path.basename(notebook_filename)
151 notebook_name = basename[:basename.rfind('.')]
155 notebook_name = basename[:basename.rfind('.')]
152 resources = {}
156 resources = {}
153 resources['unique_key'] = notebook_name
157 resources['unique_key'] = notebook_name
154
158
155 #Try to export
159 #Try to export
156 try:
160 try:
157 output, resources = export_by_name(self.export_format,
161 output, resources = export_by_name(self.export_format,
158 notebook_filename,
162 notebook_filename,
159 resources=resources,
163 resources=resources,
160 config=self.config)
164 config=self.config)
161 except ExporterNameError as e:
165 except ExporterNameError as e:
162 print("Error: '%s' exporter not found." % self.export_format,
166 print("Error: '%s' exporter not found." % self.export_format,
163 file=sys.stderr)
167 file=sys.stderr)
164 print("Known exporters are:",
168 print("Known exporters are:",
165 "\n\t" + "\n\t".join(get_export_names()),
169 "\n\t" + "\n\t".join(get_export_names()),
166 file=sys.stderr)
170 file=sys.stderr)
167 sys.exit(-1)
171 sys.exit(-1)
168 except Exception as e:
172 #except Exception as e:
169 print("Error: could no export '%s'" % notebook_filename, file=sys.stderr)
173 #print("Error: could not export '%s'" % notebook_filename, file=sys.stderr)
170 print(e, file=sys.stderr)
174 #print(e, file=sys.stderr)
171
175 else:
172 #Write
176 self.writer.write(output, resources, notebook_name=notebook_name)
173 self.writer.write(output, resources, notebook_name=notebook_name)
177 conversion_success += 1
178
179 #If nothing was converted successfully, help the user.
180 if conversion_success == 0:
181
182 #No notebooks were specified, show help.
183 if len(self.notebooks) == 0:
184 self.print_help()
185
186 #Notebooks were specified, but not converted successfully. Show how
187 #to access help.
188 else:
189 print('For help, use "ipython nbconvert --help"')
174
190
175
191
176 #-----------------------------------------------------------------------------
192 #-----------------------------------------------------------------------------
177 # Main entry point
193 # Main entry point
178 #-----------------------------------------------------------------------------
194 #-----------------------------------------------------------------------------
179
195
180 launch_new_instance = NbConvertApp.launch_instance
196 launch_new_instance = NbConvertApp.launch_instance
General Comments 0
You need to be logged in to leave comments. Login now