import os
import shutil
from traitlets import Unicode, List
from ipypublish.postprocessors.base import IPyPostProcessor
[docs]class WriteTextFile(IPyPostProcessor):
""" write the stream to a text based file
"""
@property
def allowed_mimetypes(self):
return (
"text/latex",
"text/restructuredtext",
"text/html",
"text/x-python",
"application/json",
"text/markdown",
)
@property
def requires_path(self):
return True
@property
def logger_name(self):
return "write-text-file"
encoding = Unicode("utf8", help="the encoding of the output file").tag(config=True)
[docs] def run_postprocess(self, stream, mimetype, filepath, resources):
self.logger.info("writing stream to file: {}".format(filepath))
with filepath.open("w", encoding=self.encoding) as fh:
fh.write(stream)
return stream, filepath, resources
[docs]class RemoveFolder(IPyPostProcessor):
""" remove a folder and all its contents
"""
@property
def allowed_mimetypes(self):
return None
@property
def requires_path(self):
return True
@property
def logger_name(self):
return "remove-folder"
files_folder = Unicode(
"_static", help="the path (relative to the main file path) to remove"
).tag(config=True)
[docs] def run_postprocess(self, stream, mimetype, filepath, resources):
remove_folder = filepath.parent.joinpath(self.files_folder)
if remove_folder.exists() and remove_folder.is_dir():
self.logger.info("removing folder: {0}".format(remove_folder))
shutil.rmtree(str(remove_folder))
return stream, filepath, resources
[docs]class WriteResourceFiles(IPyPostProcessor):
""" write content contained in the resources dict to file (as bytes)
"""
@property
def allowed_mimetypes(self):
return None
@property
def requires_path(self):
return True
@property
def logger_name(self):
return "write-resource-files"
resource_keys = List(
Unicode(),
["outputs"],
help="the key names in the resources dict that contain files",
).tag(config=True)
# The files already have a relative path
# files_folder = Unicode(
# "_static",
# help="the path (relative to the main file path) to write to"
# ).tag(config=True)
[docs] def run_postprocess(self, stream, mimetype, filepath, resources):
output_folder = filepath.parent
if not output_folder.exists():
output_folder.mkdir(parents=True)
for key in self.resource_keys:
if key not in resources:
continue
if not hasattr(resources[key], "items"):
self.handle_error(
"the value of resources[{0}] is not a mapping".format(key),
TypeError,
)
self.logger.info(
"writing files in resources[{0}] to: {1}".format(key, output_folder)
)
for filename, content in resources[key].items():
outpath = output_folder.joinpath(filename)
if not outpath.parent.exists():
outpath.parent.mkdir(parents=True)
with outpath.open("wb") as fh:
fh.write(content)
self.logger.debug("finished")
return stream, filepath, resources
[docs]class CopyResourcePaths(IPyPostProcessor):
""" copy filepaths in the resources dict to another folder
"""
@property
def allowed_mimetypes(self):
return None
@property
def requires_path(self):
return True
@property
def logger_name(self):
return "copy-resource-paths"
resource_keys = List(
Unicode(),
["external_file_paths"],
help="the key names in the resources dict that contain filepaths",
).tag(config=True)
files_folder = Unicode(
"_static", help="the path (relative to the main file path) to copy to"
).tag(config=True)
[docs] def run_postprocess(self, stream, mimetype, filepath, resources):
output_folder = filepath.parent.joinpath(self.files_folder)
if not output_folder.exists():
output_folder.mkdir(parents=True)
for key in self.resource_keys:
if key not in resources:
continue
if not isinstance(resources[key], (list, tuple, set)):
self.handle_error(
"the value of resources[{0}] is not an iterable".format(key),
TypeError,
)
self.logger.info(
"copying files in resources[{0}] to: {1}".format(key, output_folder)
)
for resfilepath in resources[key]:
shutil.copyfile(
resfilepath,
str(output_folder.joinpath(os.path.basename(resfilepath))),
)
return stream, filepath, resources