mirror of
https://github.com/rendercv/rendercv.git
synced 2026-05-24 08:40:00 -04:00
cli: simplify commands.py
This commit is contained in:
@@ -6,7 +6,7 @@ commands of RenderCV.
|
||||
import os
|
||||
import pathlib
|
||||
import shutil
|
||||
from typing import Annotated, Optional
|
||||
from typing import Annotated, Optional, Literal
|
||||
|
||||
import pydantic
|
||||
import typer
|
||||
@@ -140,9 +140,23 @@ def cli_command_render(
|
||||
"""Render a CV from a YAML input file."""
|
||||
printer.welcome()
|
||||
|
||||
input_file_path = pathlib.Path(input_file_name).absolute()
|
||||
# Get paths:
|
||||
input_file_path = utilities.string_to_file_path(input_file_name)
|
||||
output_directory = pathlib.Path.cwd() / output_folder_name
|
||||
|
||||
paths: dict[
|
||||
Literal["latex", "pdf", "markdown", "html", "png"], Optional[pathlib.Path]
|
||||
] = {
|
||||
"latex": latex_path,
|
||||
"pdf": pdf_path,
|
||||
"markdown": markdown_path,
|
||||
"html": html_path,
|
||||
"png": png_path,
|
||||
}
|
||||
for file_type, path in paths.items():
|
||||
if path:
|
||||
paths[file_type] = utilities.string_to_file_path(path)
|
||||
|
||||
# change the current working directory to the input file's directory (because
|
||||
# the template overrides are looked up in the current working directory):
|
||||
os.chdir(input_file_path.parent)
|
||||
@@ -158,6 +172,7 @@ def cli_command_render(
|
||||
if dont_generate_png:
|
||||
number_of_steps = number_of_steps - 1
|
||||
if dont_generate_markdown:
|
||||
# if the Markdown file is not generated, then the HTML file is not generated
|
||||
number_of_steps = number_of_steps - 2
|
||||
else:
|
||||
if dont_generate_html:
|
||||
@@ -168,23 +183,12 @@ def cli_command_render(
|
||||
data_model = data.read_input_file(input_file_path)
|
||||
|
||||
# update the data model if there are extra arguments:
|
||||
key_and_values = dict()
|
||||
|
||||
if extra_data_model_override_argumets:
|
||||
key_and_values = printer.parse_render_command_override_arguments(
|
||||
key_and_values = dict()
|
||||
key_and_values = utilities.parse_render_command_override_arguments(
|
||||
extra_data_model_override_argumets
|
||||
)
|
||||
for key, value in key_and_values.items():
|
||||
try:
|
||||
# set the key (for example, cv.sections.education.0.institution) to
|
||||
# the value
|
||||
data_model = utilities.set_or_update_a_value(data_model, key, value)
|
||||
except pydantic.ValidationError as e:
|
||||
raise e
|
||||
except (ValueError, KeyError, IndexError, AttributeError):
|
||||
raise ValueError(
|
||||
f'The key "{key}" does not exist in the data model!'
|
||||
)
|
||||
data_model = utilities.set_or_update_values(data_model, key_and_values)
|
||||
|
||||
progress.finish_the_current_step()
|
||||
|
||||
@@ -194,35 +198,25 @@ def cli_command_render(
|
||||
data_model, output_directory
|
||||
)
|
||||
)
|
||||
if latex_path:
|
||||
shutil.copy2(latex_file_path_in_output_folder, latex_path)
|
||||
if paths["latex"]:
|
||||
utilities.copy_files(latex_file_path_in_output_folder, paths["latex"])
|
||||
progress.finish_the_current_step()
|
||||
|
||||
progress.start_a_step("Rendering the LaTeX file to a PDF")
|
||||
pdf_file_path_in_output_folder = renderer.render_pdf_from_latex(
|
||||
latex_file_path_in_output_folder, use_local_latex_command
|
||||
)
|
||||
if pdf_path:
|
||||
shutil.copy2(pdf_file_path_in_output_folder, pdf_path)
|
||||
if paths["pdf"]:
|
||||
utilities.copy_files(pdf_file_path_in_output_folder, paths["pdf"])
|
||||
progress.finish_the_current_step()
|
||||
|
||||
if not dont_generate_png:
|
||||
progress.start_a_step("Rendering PNG files from the PDF")
|
||||
png_file_paths_in_output_folder = renderer.render_a_markdown_file(
|
||||
png_file_paths_in_output_folder = renderer.render_pngs_from_pdf(
|
||||
pdf_file_path_in_output_folder
|
||||
)
|
||||
if png_path:
|
||||
if len(png_file_paths_in_output_folder) == 1:
|
||||
shutil.copy2(png_file_paths_in_output_folder[0], png_path)
|
||||
else:
|
||||
for i, png_file_path in enumerate(png_file_paths_in_output_folder):
|
||||
# append the page number to the file name
|
||||
page_number = i + 1
|
||||
png_path_with_page_number = (
|
||||
pathlib.Path(png_path).parent
|
||||
/ f"{pathlib.Path(png_path).stem}_{page_number}.png"
|
||||
)
|
||||
shutil.copy2(png_file_path, png_path_with_page_number)
|
||||
if paths["png"]:
|
||||
utilities.copy_files(png_file_paths_in_output_folder, paths["png"])
|
||||
progress.finish_the_current_step()
|
||||
|
||||
if not dont_generate_markdown:
|
||||
@@ -231,7 +225,7 @@ def cli_command_render(
|
||||
data_model, output_directory
|
||||
)
|
||||
if markdown_path:
|
||||
shutil.copy2(markdown_file_path_in_output_folder, markdown_path)
|
||||
utilities.copy_files(markdown_file_path_in_output_folder, markdown_path)
|
||||
progress.finish_the_current_step()
|
||||
|
||||
if not dont_generate_html:
|
||||
@@ -242,7 +236,7 @@ def cli_command_render(
|
||||
markdown_file_path_in_output_folder
|
||||
)
|
||||
if html_path:
|
||||
shutil.copy2(html_file_path_in_output_folder, html_path)
|
||||
utilities.copy_files(html_file_path_in_output_folder, html_path)
|
||||
progress.finish_the_current_step()
|
||||
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ class LiveProgressReporter(rich.live.Live):
|
||||
|
||||
Args:
|
||||
number_of_steps (int): The number of steps to be finished.
|
||||
end_message (str, optional): The message to be printed when the progress is
|
||||
finished. Defaults to "Your CV is rendered!".
|
||||
"""
|
||||
|
||||
def __init__(self, number_of_steps: int, end_message: str = "Your CV is rendered!"):
|
||||
@@ -68,7 +70,11 @@ class LiveProgressReporter(rich.live.Live):
|
||||
return self
|
||||
|
||||
def start_a_step(self, step_name: str):
|
||||
"""Start a step and update the progress bars."""
|
||||
"""Start a step and update the progress bars.
|
||||
|
||||
Args:
|
||||
step_name (str): The name of the step.
|
||||
"""
|
||||
self.current_step_name = step_name
|
||||
self.current_step_id = self.step_progress.add_task(
|
||||
f"{self.current_step_name} has started."
|
||||
|
||||
@@ -13,6 +13,17 @@ import typer
|
||||
import pydantic
|
||||
|
||||
|
||||
def string_to_file_path(string: str) -> pathlib.Path:
|
||||
"""Convert a string to a pathlib.Path object.
|
||||
|
||||
Args:
|
||||
string (str): The string to be converted to a pathlib.Path object.
|
||||
Returns:
|
||||
pathlib.Path: The pathlib.Path object.
|
||||
"""
|
||||
return pathlib.Path(string).absolute()
|
||||
|
||||
|
||||
def set_or_update_a_value(
|
||||
data_model: pydantic.BaseModel | dict | list,
|
||||
key: str,
|
||||
@@ -86,6 +97,49 @@ def set_or_update_a_value(
|
||||
set_or_update_a_value(data_model, key, value, sub_model)
|
||||
|
||||
|
||||
def set_or_update_values(
|
||||
data_model: pydantic.BaseModel,
|
||||
key_and_values: dict[str, str],
|
||||
) -> pydantic.BaseModel:
|
||||
"""Set or update values in a data model for specific keys. It uses the
|
||||
`set_or_update_a_value` function to set or update the values.
|
||||
|
||||
Args:
|
||||
data_model (pydantic.BaseModel): The data model to set or update the values.
|
||||
key_and_values (dict[str, str]): The key and value pairs to set or update.
|
||||
"""
|
||||
for key, value in key_and_values.items():
|
||||
try:
|
||||
data_model = set_or_update_a_value(data_model, key_and_values)
|
||||
except pydantic.ValidationError as e:
|
||||
raise e
|
||||
except (ValueError, KeyError, IndexError, AttributeError):
|
||||
raise ValueError(f'The key "{key}" does not exist in the data model!')
|
||||
|
||||
return data_model
|
||||
|
||||
|
||||
def copy_files(paths: list[pathlib.Path], new_path: pathlib.Path):
|
||||
"""Copy files to the given path. If there are multiple files, then rename the new
|
||||
path by adding a number to the end of the path.
|
||||
|
||||
Args:
|
||||
paths (list[pathlib.Path]): The paths of the files to be copied.
|
||||
new_path (pathlib.Path): The path to copy the files to.
|
||||
"""
|
||||
if len(paths) == 1:
|
||||
shutil.copy2(paths[0], new_path)
|
||||
else:
|
||||
for i, file_path in enumerate(paths):
|
||||
# append a number to the end of the path:
|
||||
number = i + 1
|
||||
png_path_with_page_number = (
|
||||
pathlib.Path(new_path).parent
|
||||
/ f"{pathlib.Path(new_path).stem}_{number}.png"
|
||||
)
|
||||
shutil.copy2(file_path, png_path_with_page_number)
|
||||
|
||||
|
||||
def get_latest_version_number_from_pypi() -> Optional[str]:
|
||||
"""Get the latest version number of RenderCV from PyPI.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user