first commit

This commit is contained in:
Ayxan
2022-05-23 00:16:32 +04:00
commit d660f2a4ca
24786 changed files with 4428337 additions and 0 deletions

View File

@ -0,0 +1,4 @@
from .base import WriterBase
from .debug import DebugWriter
from .files import FilesWriter
from .stdout import StdoutWriter

View File

@ -0,0 +1,45 @@
"""
Contains writer base class.
"""
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
from traitlets import List
from ..utils.base import NbConvertBase
class WriterBase(NbConvertBase):
"""Consumes output from nbconvert export...() methods and writes to a
useful location."""
files = List(
[],
help="""
List of the files that the notebook references. Files will be
included with written output.""",
).tag(config=True)
def __init__(self, config=None, **kw):
"""
Constructor
"""
super().__init__(config=config, **kw)
def write(self, output, resources, **kw):
"""
Consume and write Jinja output.
Parameters
----------
output : string
Conversion results. This string contains the file contents of the
converted file.
resources : dict
Resources created and filled by the nbconvert conversion process.
Includes output from preprocessors, such as the extract figure
preprocessor.
"""
raise NotImplementedError()

View File

@ -0,0 +1,45 @@
"""
Contains debug writer.
"""
from pprint import pprint
from .base import WriterBase
# -----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# Imports
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# Classes
# -----------------------------------------------------------------------------
class DebugWriter(WriterBase):
"""Consumes output from nbconvert export...() methods and writes useful
debugging information to the stdout. The information includes a list of
resources that were extracted from the notebook(s) during export."""
def write(self, output, resources, notebook_name="notebook", **kw):
"""
Consume and write Jinja output.
See base for more...
"""
if isinstance(resources["outputs"], dict):
print("outputs extracted from %s" % notebook_name)
print("-" * 80)
pprint(resources["outputs"], indent=2, width=70)
else:
print("no outputs extracted from %s" % notebook_name)
print("=" * 80)

View File

@ -0,0 +1,135 @@
"""Contains writer for writing nbconvert output to filesystem."""
# Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
import glob
import os
from pathlib import Path
from traitlets import Unicode, observe
from nbconvert.utils.io import ensure_dir_exists, link_or_copy
from .base import WriterBase
class FilesWriter(WriterBase):
"""Consumes nbconvert output and produces files."""
build_directory = Unicode(
"",
help="""Directory to write output(s) to. Defaults
to output to the directory of each notebook. To recover
previous default behaviour (outputting to the current
working directory) use . as the flag value.""",
).tag(config=True)
relpath = Unicode(
help="""When copying files that the notebook depends on, copy them in
relation to this path, such that the destination filename will be
os.path.relpath(filename, relpath). If FilesWriter is operating on a
notebook that already exists elsewhere on disk, then the default will be
the directory containing that notebook."""
).tag(config=True)
# Make sure that the output directory exists.
@observe("build_directory")
def _build_directory_changed(self, change):
new = change["new"]
if new:
ensure_dir_exists(new)
def __init__(self, **kw):
super().__init__(**kw)
self._build_directory_changed({"new": self.build_directory})
def _makedir(self, path):
"""Make a directory if it doesn't already exist"""
if path:
self.log.info("Making directory %s", path)
ensure_dir_exists(path)
def write(self, output, resources, notebook_name=None, **kw):
"""
Consume and write Jinja output to the file system. Output directory
is set via the 'build_directory' variable of this instance (a
configurable).
See base for more...
"""
# Verify that a notebook name is provided.
if notebook_name is None:
raise TypeError("notebook_name")
# Pull the extension and subdir from the resources dict.
output_extension = resources.get("output_extension", None)
# Get the relative path for copying files
resource_path = resources.get("metadata", {}).get("path", "")
relpath = self.relpath or resource_path
build_directory = self.build_directory or resource_path
# Write all of the extracted resources to the destination directory.
# NOTE: WE WRITE EVERYTHING AS-IF IT'S BINARY. THE EXTRACT FIG
# PREPROCESSOR SHOULD HANDLE UNIX/WINDOWS LINE ENDINGS...
items = resources.get("outputs", {}).items()
if items:
self.log.info(
"Support files will be in %s",
os.path.join(resources.get("output_files_dir", ""), ""),
)
for filename, data in items:
# Determine where to write the file to
dest = os.path.join(build_directory, filename)
path = os.path.dirname(dest)
self._makedir(path)
# Write file
self.log.debug("Writing %i bytes to support file %s", len(data), dest)
with open(dest, "wb") as f:
f.write(data)
# Copy referenced files to output directory
if build_directory:
for filename in self.files:
# Copy files that match search pattern
for matching_filename in glob.glob(filename):
# compute the relative path for the filename
if relpath != "":
dest_filename = os.path.relpath(matching_filename, relpath)
else:
dest_filename = matching_filename
# Make sure folder exists.
dest = os.path.join(build_directory, dest_filename)
path = os.path.dirname(dest)
self._makedir(path)
# Copy if destination is different.
if not os.path.normpath(dest) == os.path.normpath(matching_filename):
self.log.info("Copying %s -> %s", matching_filename, dest)
link_or_copy(matching_filename, dest)
# Determine where to write conversion results.
if output_extension is not None:
dest = notebook_name + output_extension
else:
dest = notebook_name
dest = Path(build_directory) / dest
# Write conversion results.
self.log.info("Writing %i bytes to %s", len(output), dest)
if isinstance(output, str):
with open(dest, "w", encoding="utf-8") as f:
f.write(output)
else:
with open(dest, "wb") as f:
f.write(output)
return dest

View File

@ -0,0 +1,23 @@
"""
Contains Stdout writer
"""
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
from nbconvert.utils import io
from .base import WriterBase
class StdoutWriter(WriterBase):
"""Consumes output from nbconvert export...() methods and writes to the
stdout stream."""
def write(self, output, resources, **kw):
"""
Consume and write Jinja output.
See base for more...
"""
io.unicode_std_stream().write(output)

View File

@ -0,0 +1,51 @@
"""
Module with tests for debug
"""
# -----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# Imports
# -----------------------------------------------------------------------------
import sys
from io import StringIO
from ...tests.base import TestsBase
from ..debug import DebugWriter
# -----------------------------------------------------------------------------
# Class
# -----------------------------------------------------------------------------
class TestDebug(TestsBase):
"""Contains test functions for debug.py"""
def test_output(self):
"""Test debug writer output."""
# Capture the stdout. Remember original.
stdout = sys.stdout
stream = StringIO()
sys.stdout = stream
# Create stdout writer, get output
writer = DebugWriter()
writer.write("aaa", {"outputs": {"bbb": "ccc"}})
output = stream.getvalue()
# Check output. Make sure resources dictionary is dumped, but nothing
# else.
assert "aaa" not in output
assert "bbb" in output
assert "ccc" in output
# Revert stdout
sys.stdout = stdout

View File

@ -0,0 +1,296 @@
"""
Module with tests for files
"""
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
import os
from ...tests.base import TestsBase
from ..files import FilesWriter
class Testfiles(TestsBase):
"""Contains test functions for files.py"""
def test_basic_output(self):
"""Is FilesWriter basic output correct?"""
# Work in a temporary directory.
with self.create_temp_cwd():
# Create the resoruces dictionary
res = {}
# Create files writer, test output
writer = FilesWriter()
writer.write("y", res, notebook_name="z")
# Check the output of the file
with open("z") as f:
output = f.read()
self.assertEqual(output, "y")
def test_ext(self):
"""Does the FilesWriter add the correct extension to the output?"""
# Work in a temporary directory.
with self.create_temp_cwd():
# Create the resoruces dictionary
res = {"output_extension": ".txt"}
# Create files writer, test output
writer = FilesWriter()
writer.write("y", res, notebook_name="z")
# Check the output of the file
assert os.path.isfile("z.txt")
with open("z.txt") as f:
output = f.read()
self.assertEqual(output, "y")
def test_extract(self):
"""Can FilesWriter write extracted figures correctly?"""
# Work in a temporary directory.
with self.create_temp_cwd():
# Create the resoruces dictionary
res = {"outputs": {os.path.join("z_files", "a"): b"b"}}
# Create files writer, test output
writer = FilesWriter()
writer.write("y", res, notebook_name="z")
# Check the output of the file
with open("z") as f:
output = f.read()
self.assertEqual(output, "y")
# Check the output of the extracted file
extracted_file_dest = os.path.join("z_files", "a")
assert os.path.isfile(extracted_file_dest)
with open(extracted_file_dest) as f:
output = f.read()
self.assertEqual(output, "b")
def test_build_dir(self):
"""Can FilesWriter write to a build dir correctly?"""
# Work in a temporary directory.
with self.create_temp_cwd():
# Create the resoruces dictionary
res = {"outputs": {os.path.join("z_files", "a"): b"b"}}
# Create files writer, test output
writer = FilesWriter()
writer.build_directory = "build"
writer.write("y", res, notebook_name="z")
# Check the output of the file
assert os.path.isdir(writer.build_directory)
dest = os.path.join(writer.build_directory, "z")
with open(dest) as f:
output = f.read()
self.assertEqual(output, "y")
# Check the output of the extracted file
extracted_file_dest = os.path.join(writer.build_directory, "z_files", "a")
assert os.path.isfile(extracted_file_dest)
with open(extracted_file_dest) as f:
output = f.read()
self.assertEqual(output, "b")
def test_build_dir_default(self):
"""FilesWriter defaults to input path"""
with self.create_temp_cwd():
os.mkdir("sub")
resources = {"metadata": {"path": "sub"}}
writer = FilesWriter()
writer.write("content", resources, notebook_name="out")
dest = os.path.join("sub", "out")
assert os.path.isfile(dest)
with open(dest) as f:
self.assertEqual(f.read().strip(), "content")
def test_links(self):
"""Can the FilesWriter handle linked files correctly?"""
# Work in a temporary directory.
with self.create_temp_cwd():
# Create test file
os.mkdir("sub")
with open(os.path.join("sub", "c"), "w") as f:
f.write("d")
# Create the resoruces dictionary
res = {}
# Create files writer, test output
writer = FilesWriter()
writer.files = [os.path.join("sub", "c")]
writer.build_directory = "build"
writer.write("y", res, notebook_name="z")
# Check the output of the file
assert os.path.isdir(writer.build_directory)
dest = os.path.join(writer.build_directory, "z")
with open(dest) as f:
output = f.read()
self.assertEqual(output, "y")
# Check to make sure the linked file was copied
path = os.path.join(writer.build_directory, "sub")
assert os.path.isdir(path)
dest = os.path.join(path, "c")
assert os.path.isfile(dest)
with open(dest) as f:
output = f.read()
self.assertEqual(output, "d")
def test_glob(self):
"""Can the FilesWriter handle globbed files correctly?"""
# Work in a temporary directory.
with self.create_temp_cwd():
# Create test files
os.mkdir("sub")
with open(os.path.join("sub", "c"), "w") as f:
f.write("e")
with open(os.path.join("sub", "d"), "w") as f:
f.write("e")
# Create the resoruces dictionary
res = {}
# Create files writer, test output
writer = FilesWriter()
writer.files = ["sub/*"]
writer.build_directory = "build"
writer.write("y", res, notebook_name="z")
# Check the output of the file
assert os.path.isdir(writer.build_directory)
dest = os.path.join(writer.build_directory, "z")
with open(dest) as f:
output = f.read()
self.assertEqual(output, "y")
# Check to make sure the globbed files were copied
path = os.path.join(writer.build_directory, "sub")
assert os.path.isdir(path)
for filename in ["c", "d"]:
dest = os.path.join(path, filename)
assert os.path.isfile(dest)
with open(dest) as f:
output = f.read()
self.assertEqual(output, "e")
def test_relpath(self):
"""Can the FilesWriter handle relative paths for linked files correctly?"""
# Work in a temporary directory.
with self.create_temp_cwd():
# Create test file
os.mkdir("sub")
with open(os.path.join("sub", "c"), "w") as f:
f.write("d")
# Create the resoruces dictionary
res = {}
# Create files writer, test output
writer = FilesWriter()
writer.files = [os.path.join("sub", "c")]
writer.build_directory = "build"
writer.relpath = "sub"
writer.write("y", res, notebook_name="z")
# Check the output of the file
assert os.path.isdir(writer.build_directory)
dest = os.path.join(writer.build_directory, "z")
with open(dest) as f:
output = f.read()
self.assertEqual(output, "y")
# Check to make sure the linked file was copied
dest = os.path.join(writer.build_directory, "c")
assert os.path.isfile(dest)
with open(dest) as f:
output = f.read()
self.assertEqual(output, "d")
def test_relpath_default(self):
"""Is the FilesWriter default relative path correct?"""
# Work in a temporary directory.
with self.create_temp_cwd():
# Create test file
os.mkdir("sub")
with open(os.path.join("sub", "c"), "w") as f:
f.write("d")
# Create the resoruces dictionary
res = dict(metadata=dict(path="sub"))
# Create files writer, test output
writer = FilesWriter()
writer.files = [os.path.join("sub", "c")]
writer.build_directory = "build"
writer.write("y", res, notebook_name="z")
# Check the output of the file
assert os.path.isdir(writer.build_directory)
dest = os.path.join(writer.build_directory, "z")
with open(dest) as f:
output = f.read()
self.assertEqual(output, "y")
# Check to make sure the linked file was copied
dest = os.path.join(writer.build_directory, "c")
assert os.path.isfile(dest)
with open(dest) as f:
output = f.read()
self.assertEqual(output, "d")
def test_relpath_precedence(self):
"""Does the FilesWriter relpath option take precedence over the path?"""
# Work in a temporary directory.
with self.create_temp_cwd():
# Create test file
os.mkdir("sub")
with open(os.path.join("sub", "c"), "w") as f:
f.write("d")
# Create the resoruces dictionary
res = dict(metadata=dict(path="other_sub"))
# Create files writer, test output
writer = FilesWriter()
writer.files = [os.path.join("sub", "c")]
writer.build_directory = "build"
writer.relpath = "sub"
writer.write("y", res, notebook_name="z")
# Check the output of the file
assert os.path.isdir(writer.build_directory)
dest = os.path.join(writer.build_directory, "z")
with open(dest) as f:
output = f.read()
self.assertEqual(output, "y")
# Check to make sure the linked file was copied
dest = os.path.join(writer.build_directory, "c")
assert os.path.isfile(dest)
with open(dest) as f:
output = f.read()
self.assertEqual(output, "d")

View File

@ -0,0 +1,46 @@
"""
Module with tests for stdout
"""
# -----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# Imports
# -----------------------------------------------------------------------------
import sys
from io import StringIO
from ...tests.base import TestsBase
from ..stdout import StdoutWriter
# -----------------------------------------------------------------------------
# Class
# -----------------------------------------------------------------------------
class TestStdout(TestsBase):
"""Contains test functions for stdout.py"""
def test_output(self):
"""Test stdout writer output."""
# Capture the stdout. Remember original.
stdout = sys.stdout
stream = StringIO()
sys.stdout = stream
# Create stdout writer, test output
writer = StdoutWriter()
writer.write("a×", {"b": "c"})
output = stream.getvalue()
self.fuzzy_compare(output, "a×")
# Revert stdout
sys.stdout = stdout