Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 54 additions & 1 deletion gui/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,13 @@


def create_run_vuegen(
is_dir, config_path, report_type, run_streamlit, output_dir_entry, python_dir_entry
is_dir,
config_path,
report_type,
run_streamlit,
output_dir_entry,
python_dir_entry,
max_depth: int,
):
def inner():
kwargs = {}
Expand All @@ -125,6 +131,8 @@ def inner():
print(f"{run_streamlit.get() = }")
kwargs["streamlit_autorun"] = run_streamlit.get()
kwargs["output_dir"] = output_dir_entry.get()
if max_depth.get():
kwargs["max_depth"] = int(max_depth.get())
print("kwargs:")
pprint(kwargs)

Expand All @@ -146,6 +154,16 @@ def inner():
messagebox.showwarning(
"warning", "Running locally. Ignoring set Python Path"
)
if kwargs["max_depth"] < 2:
messagebox.showwarning(
"warning", "Maximum depth must be at least 2. Setting to 2."
)
kwargs["max_depth"] = 2
elif kwargs["max_depth"] > 9:
messagebox.showwarning(
"warning", "Maximum depth must be at most 9. Setting to 9."
)
kwargs["max_depth"] = 9
try:
os.chdir(kwargs["output_dir"]) # Change the working directory
# Define logger suffix based on report type and name
Expand Down Expand Up @@ -316,6 +334,40 @@ def select_directory():
# output directory selection
ctk_label_outdir = customtkinter.CTkLabel(app, text="Select output directory:")
ctk_label_outdir.grid(row=row_count, column=0, columnspan=1, padx=10, pady=5)
CTK_ENTRY_MAX_DEPTH_DEFAULT = 2
# Maximum Depth input
ctk_label_max_depth = customtkinter.CTkLabel(
app,
text=f"Maximum Depth: (default {CTK_ENTRY_MAX_DEPTH_DEFAULT})",
)
ctk_label_max_depth.grid(
row=row_count, column=1, columnspan=1, padx=10, pady=5, sticky="e"
)


max_depth = tk.IntVar(value=CTK_ENTRY_MAX_DEPTH_DEFAULT)


def slider_event(value):
max_depth.set(value)
ctk_label_max_depth.configure(text=f"Maximum Depth: {int(value)}")


ctk_entry_max_depth = customtkinter.CTkSlider(
app,
from_=2,
to=9,
variable=max_depth,
width=150,
command=slider_event,
number_of_steps=7,
)
ctk_entry_max_depth.set(
CTK_ENTRY_MAX_DEPTH_DEFAULT
) # Set the initial value of the slider
ctk_entry_max_depth.grid(
row=row_count, column=2, columnspan=1, padx=10, pady=5, sticky="w"
)
row_count += 1
##########################################################################################
output_dir_entry = tk.StringVar(value=str(output_dir))
Expand Down Expand Up @@ -380,6 +432,7 @@ def select_directory():
run_streamlit=run_streamlit,
output_dir_entry=output_dir_entry,
python_dir_entry=python_dir_entry,
max_depth=max_depth,
)
run_button = customtkinter.CTkButton(
app,
Expand Down
10 changes: 4 additions & 6 deletions src/vuegen/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ def main():
config_path = args.config
dir_path = args.directory
report_type = args.report_type
output_dir = args.output_directory
streamlit_autorun = args.streamlit_autorun
quarto_cheks = args.quarto_checks

# Determine the report name for logger suffix
if config_path:
Expand Down Expand Up @@ -47,9 +44,10 @@ def main():
logger=logger,
config_path=config_path,
dir_path=dir_path,
output_dir=output_dir,
streamlit_autorun=streamlit_autorun,
quarto_checks=quarto_cheks,
output_dir=args.output_directory,
streamlit_autorun=args.streamlit_autorun,
quarto_checks=args.quarto_checks,
max_depth=args.max_depth,
)

# Print completion message
Expand Down
26 changes: 19 additions & 7 deletions src/vuegen/config_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,23 @@ class ConfigManager:
Class for handling metadata of reports from YAML config file and creating report objects.
"""

def __init__(self, logger: Optional[logging.Logger] = None):
def __init__(self, logger: Optional[logging.Logger] = None, max_depth: int = 2):
"""
Initializes the ConfigManager with a logger.

Parameters
----------
logger : logging.Logger, optional
A logger instance for the class. If not provided, a default logger will be created.
max_depth : int, optional
The maximum depth of the directory structure to consider when generating the report
config from a directory.
The default is 2, which means it will include sections and subsections.
"""
if logger is None:
logger, _ = get_logger("report")
self.logger = logger
self.max_depth = max_depth

def _create_title_fromdir(self, file_dirname: str) -> str:
"""
Expand Down Expand Up @@ -198,7 +203,7 @@ def _read_description_file(self, folder_path: Path) -> str:
return ""

def _create_subsect_config_fromdir(
self, subsection_dir_path: Path
self, subsection_dir_path: Path, level: int = 2
) -> Dict[str, Union[str, List[Dict]]]:
"""
Creates subsection config from a directory.
Expand All @@ -217,7 +222,6 @@ def _create_subsect_config_fromdir(
sorted_files = self._sort_paths_by_numprefix(
list(subsection_dir_path.iterdir())
)

components = []
for file in sorted_files:
if file.is_file():
Expand All @@ -227,9 +231,17 @@ def _create_subsect_config_fromdir(
continue
# Add component config to list
components.append(component_config)
# ! if folder go into folder and pull files out?
# nesting level already at point 2
# loop of components in a folder
elif file.is_dir():
if level >= self.max_depth:
self.logger.warning(
"Subsection nesting level exceeded: %s. Skipping.", file.name
)
continue
# components are added to subsection
# ! Alternatively, one could add (sub-)sections to the subsection
# ? Then one could remove differentiation between sections and subsections
nested_components = self._create_subsect_config_fromdir(file, level + 1)
components.extend(nested_components["components"])

subsection_config = {
"title": self._create_title_fromdir(subsection_dir_path.name),
Expand Down Expand Up @@ -316,7 +328,7 @@ def create_yamlconfig_fromdir(
sorted_sections = self._sort_paths_by_numprefix(list(base_dir_path.iterdir()))

main_section_config = {
"title": "", # self._create_title_fromdir("home_components"),
"title": "",
"description": "Components added to homepage.",
"components": [],
}
Expand Down
13 changes: 12 additions & 1 deletion src/vuegen/report_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def get_report(
streamlit_autorun: bool = False,
quarto_checks: bool = False,
output_dir: Path = None,
max_depth: int = 2, # section and subsection folders
) -> tuple[str, str]:
"""
Generate and run a report based on the specified engine.
Expand All @@ -34,6 +35,16 @@ def get_report(
Path to the directory from which to generate the configuration file.
streamlit_autorun : bool, optional
Whether to automatically run the Streamlit report after generation (default is False).
quarto_checks : bool, optional
Whether to perform checks for Quarto report generation for TeX and Chromium installation
(default is False).
output_dir : Path, optional
The directory where the report folder will be generated.
If not provided, the current directory will be used.
max_depth : int, optional
The maximum depth of the directory structure to consider when generating the report.
The default is 2, which means it will include sections and subsections. The parater
is only used when 'dir_path' is used.

Raises
------
Expand All @@ -57,7 +68,7 @@ def get_report(
logger, _ = get_logger("report", folder=_folder)

# Create the config manager object
config_manager = ConfigManager(logger)
config_manager = ConfigManager(logger, max_depth=max_depth)

if dir_path:
# Generate configuration from the provided directory
Expand Down
2 changes: 0 additions & 2 deletions src/vuegen/streamlit_reportview.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,6 @@ def _generate_sections(self, output_dir: str) -> None:

try:
for section in self.report.sections[1:]:
section_name_var = section.title.replace(" ", "_")
self.report.logger.debug(
f"Processing section '{section.id}': '{section.title}' - {len(section.subsections)} subsection(s)"
)
Expand Down Expand Up @@ -465,7 +464,6 @@ def _generate_sections(self, output_dir: str) -> None:
)
try:
# Create subsection file
_subsection_name = make_valid_identifier(subsection.title)
assert (
subsection.file_path is not None
), "Missing relative file path to subsection"
Expand Down
10 changes: 10 additions & 0 deletions src/vuegen/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,16 @@ def get_parser(prog_name: str, others: dict = {}) -> argparse.Namespace:
default=False,
help="Check if Quarto is installed and available for report generation.",
)
parser.add_argument(
"-mdep",
"--max_depth",
type=int,
default=2,
help=(
"Maximum depth for the recursive search of files in the input directory. "
"Ignored if a config file is provided."
),
)
# Parse arguments
return parser

Expand Down