|
@@ -0,0 +1,108 @@
|
|
|
+import re
|
|
|
+from argparse import ArgumentParser
|
|
|
+from os.path import isfile, isdir, join, realpath, split, dirname, relpath
|
|
|
+import os
|
|
|
+import shutil
|
|
|
+
|
|
|
+
|
|
|
+def parse_and_get_arguments():
|
|
|
+ """Creates and returns an object with parsed arguments, using argparse."""
|
|
|
+ parser: ArgumentParser = ArgumentParser(
|
|
|
+ prog="move_rst_files",
|
|
|
+ description="Moves reST documents and their dependencies from one folder to another. Outputs required redirections in the ReadTheDocs backend.",
|
|
|
+ )
|
|
|
+ parser.add_argument(
|
|
|
+ "documents", nargs="+", help="Paths of documents to move.",
|
|
|
+ )
|
|
|
+ parser.add_argument(
|
|
|
+ "output_path", help="Path to the target output directory.",
|
|
|
+ )
|
|
|
+ return parser.parse_args()
|
|
|
+
|
|
|
+
|
|
|
+def find_project_root_path(document_path):
|
|
|
+ """Returns the path to the repository's root directory by looking for the file conf.py, starting
|
|
|
+from the path of any file in the project."""
|
|
|
+ full_path = realpath(document_path)
|
|
|
+ dirpath = split(full_path)[0]
|
|
|
+
|
|
|
+ root_path = ""
|
|
|
+ current = dirpath
|
|
|
+ iterations = 0
|
|
|
+ while root_path == "":
|
|
|
+ if isfile(join(current, "conf.py")):
|
|
|
+ root_path = current
|
|
|
+ else:
|
|
|
+ current = split(current)[0]
|
|
|
+ if current == "":
|
|
|
+ break
|
|
|
+ iterations += 1
|
|
|
+ if iterations > 20:
|
|
|
+ break
|
|
|
+ return root_path
|
|
|
+
|
|
|
+
|
|
|
+def find_images(document):
|
|
|
+ """Returns the list of image filepaths used by the `document`."""
|
|
|
+ images = []
|
|
|
+ for line in document:
|
|
|
+ match = re.match(r"\.\. image::\s+(img\/.+)", line)
|
|
|
+ if match:
|
|
|
+ images.append(match[1])
|
|
|
+ return list(set(images))
|
|
|
+
|
|
|
+
|
|
|
+def find_document_dependencies(documents):
|
|
|
+ """For each document path in `documents`, finds all pictures it depends on and returns a dict with the form { document: [images] }."""
|
|
|
+ data = {}
|
|
|
+ for path in documents:
|
|
|
+ with open(path, "r") as rst_file:
|
|
|
+ images = find_images(rst_file)
|
|
|
+ data[path] = images
|
|
|
+ return data
|
|
|
+
|
|
|
+
|
|
|
+def move_documents(paths, output_path):
|
|
|
+ """Moves .rst files and all their image dependencies to `output_path`"""
|
|
|
+ data = find_document_dependencies(paths)
|
|
|
+ for path in data:
|
|
|
+ directory = dirname(path)
|
|
|
+ shutil.move(path, output_path)
|
|
|
+ for image in data[path]:
|
|
|
+ image_in_path = join(directory, image)
|
|
|
+ image_out_path = join(output_path, image)
|
|
|
+ image_out_dirpath = dirname(image_out_path)
|
|
|
+ if not isdir(image_out_dirpath):
|
|
|
+ os.makedirs(image_out_dirpath)
|
|
|
+ shutil.move(image_in_path, image_out_path)
|
|
|
+
|
|
|
+
|
|
|
+def print_redirects(paths):
|
|
|
+ """Prints redirects we need to make on the ReadTheDocs backend with the form "input -> output".
|
|
|
+ Moving the file /learning/features/viewports/viewports.rst to /tutorials/viewports/viewports.rst
|
|
|
+ Requires the following redirect:
|
|
|
+ /learning/features/viewports/viewports.html -> /tutorials/viewports/viewports.html
|
|
|
+ """
|
|
|
+ redirects = ""
|
|
|
+ project_root_path = find_project_root_path(paths[0])
|
|
|
+ out_path_relative = relpath(args.output_path, project_root_path)
|
|
|
+ for document in paths:
|
|
|
+ in_path_relative = relpath(document, project_root_path)
|
|
|
+ in_directory, filename_rst = split(in_path_relative)
|
|
|
+ filename_html = filename_rst.rsplit(".rst", 1)[0] + ".html"
|
|
|
+
|
|
|
+ in_path = join(in_directory, filename_html)
|
|
|
+ out_path = join(out_path_relative, filename_html)
|
|
|
+ redirects += in_path + " -> " + out_path + "\n"
|
|
|
+ print(redirects)
|
|
|
+
|
|
|
+
|
|
|
+if __name__ == "__main__":
|
|
|
+ args = parse_and_get_arguments()
|
|
|
+ assert isdir(args.output_path)
|
|
|
+
|
|
|
+ documents = [
|
|
|
+ path for path in args.documents if isfile(path) and path.endswith(".rst")
|
|
|
+ ]
|
|
|
+ move_documents(documents, args.output_path)
|
|
|
+ print_redirects(documents)
|