diff --git a/.github/workflows/cdci.yml b/.github/workflows/cdci.yml index b21d669..2e67432 100644 --- a/.github/workflows/cdci.yml +++ b/.github/workflows/cdci.yml @@ -72,8 +72,8 @@ jobs: - name: quarto pdf report run: | cd docs - vuegen -dir example_data/Earth_microbiome_vuegen_demo_notebook -rt pdf - vuegen -c example_data/Earth_microbiome_vuegen_demo_notebook/Earth_microbiome_vuegen_demo_notebook_config.yaml -rt pdf + vuegen -dir example_data/Earth_microbiome_vuegen_demo_notebook -rt pdf -qt_checks + vuegen -c example_data/Earth_microbiome_vuegen_demo_notebook/Earth_microbiome_vuegen_demo_notebook_config.yaml -rt pdf -qt_checks - name: quarto docx report run: | cd docs diff --git a/gui/app.py b/gui/app.py index a9a2d9d..ee993b3 100644 --- a/gui/app.py +++ b/gui/app.py @@ -36,7 +36,7 @@ # from vuegen.__main__ import main from vuegen.report import ReportType -from vuegen.utils import get_logger, print_completion_message +from vuegen.utils import get_completion_message, get_logger customtkinter.set_appearance_mode("system") customtkinter.set_default_color_theme("dark-blue") @@ -159,6 +159,7 @@ def inner(): kwargs["logger"].info("logfile: %s", log_file) kwargs["logger"].debug("sys.path: %s", sys.path) kwargs["logger"].debug("PATH (in app): %s ", os.environ["PATH"]) + kwargs["quarto_checks"] = True # for gui check local quarto installation report_dir, gen_config_path = report_generator.get_report(**kwargs) kwargs["logger"].info("Report generated at %s", report_dir) messagebox.showinfo( @@ -169,7 +170,7 @@ def inner(): f"\n\nConfiguration file at:\n{gen_config_path}", ) global hash_config_app # ! fix this - print_completion_message(report_type.get()) + get_completion_message(report_type.get()) if hash(yaml.dump(config_app)) != hash_config_app: with open(config_file, "w", encoding="utf-8") as f: yaml.dump(config_app, f) diff --git a/src/vuegen/__main__.py b/src/vuegen/__main__.py index 100542f..3027556 100644 --- a/src/vuegen/__main__.py +++ b/src/vuegen/__main__.py @@ -2,7 +2,7 @@ from pathlib import Path from vuegen import report_generator -from vuegen.utils import get_logger, get_parser, print_completion_message +from vuegen.utils import get_completion_message, get_logger, get_parser def main(): @@ -14,7 +14,9 @@ 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: @@ -38,18 +40,21 @@ def main(): # Initialize logger logger, logfile = get_logger(f"{logger_suffix}") logger.info("logfile: %s", logfile) + # Generate the report _, _ = report_generator.get_report( report_type=report_type, logger=logger, config_path=config_path, dir_path=dir_path, + output_dir=output_dir, streamlit_autorun=streamlit_autorun, + quarto_checks=quarto_cheks, ) # Print completion message # ! Could use now report_dir and config_path as information - print_completion_message(report_type) + print(get_completion_message(report_type, config_path)) if __name__ == "__main__": diff --git a/src/vuegen/quarto_reportview.py b/src/vuegen/quarto_reportview.py index c7083e1..a19eb8d 100644 --- a/src/vuegen/quarto_reportview.py +++ b/src/vuegen/quarto_reportview.py @@ -20,8 +20,14 @@ class QuartoReportView(r.ReportView): BASE_DIR = Path("quarto_report") STATIC_FILES_DIR = BASE_DIR / "static" - def __init__(self, report: r.Report, report_type: r.ReportType): + def __init__( + self, + report: r.Report, + report_type: r.ReportType, + quarto_checks: bool = False, + ): super().__init__(report=report, report_type=report_type) + self.quarto_checks = quarto_checks self.BUNDLED_EXECUTION = False self.quarto_path = "quarto" # self.env_vars = os.environ.copy() @@ -186,11 +192,15 @@ def run_report(self, output_dir: str = BASE_DIR) -> None: self.report.logger.info( f"Running '{self.report.title}' '{self.report_type}' report with {args!r}" ) - if self.report_type in [ - r.ReportType.PDF, - r.ReportType.DOCX, - r.ReportType.ODT, - ]: + if ( + self.report_type + in [ + r.ReportType.PDF, + r.ReportType.DOCX, + r.ReportType.ODT, + ] + and self.quarto_checks + ): subprocess.run( [self.quarto_path, "install", "tinytex", "--no-prompt"], check=True, @@ -204,11 +214,17 @@ def run_report(self, output_dir: str = BASE_DIR) -> None: args, check=True, ) - out_path = file_path_to_qmd.with_suffix(f".{self.report_type.lower()}") - if self.report_type in [r.ReportType.REVEALJS, r.ReportType.JUPYTER]: + if self.report_type == r.ReportType.REVEALJS: + out_path = file_path_to_qmd.with_name( + f"{file_path_to_qmd.stem}_revealjs.html" + ) + elif self.report_type == r.ReportType.JUPYTER: out_path = file_path_to_qmd.with_suffix(".html") + else: + out_path = file_path_to_qmd.with_suffix(f".{self.report_type.lower()}") if not out_path.exists(): raise FileNotFoundError(f"Report file could not be created: {out_path}") + if self.report_type == r.ReportType.JUPYTER: args = [self.quarto_path, "convert", str(file_path_to_qmd)] subprocess.run( diff --git a/src/vuegen/report_generator.py b/src/vuegen/report_generator.py index c77d0c8..4eedf19 100644 --- a/src/vuegen/report_generator.py +++ b/src/vuegen/report_generator.py @@ -16,6 +16,7 @@ def get_report( config_path: str = None, dir_path: str = None, streamlit_autorun: bool = False, + quarto_checks: bool = False, output_dir: Path = None, ) -> tuple[str, str]: """ @@ -97,7 +98,9 @@ def get_report( ) report_dir = output_dir / "quarto_report" static_files_dir = report_dir / "static" - quarto_report = QuartoReportView(report=report, report_type=report_type) + quarto_report = QuartoReportView( + report=report, report_type=report_type, quarto_checks=quarto_checks + ) quarto_report.generate_report( output_dir=report_dir, static_dir=static_files_dir ) diff --git a/src/vuegen/utils.py b/src/vuegen/utils.py index 1af328e..e028974 100644 --- a/src/vuegen/utils.py +++ b/src/vuegen/utils.py @@ -225,6 +225,13 @@ def get_parser(prog_name: str, others: dict = {}) -> argparse.Namespace: default="streamlit", help="Type of the report to generate (streamlit, html, pdf, docx, odt, revealjs, pptx, or jupyter).", ) + parser.add_argument( + "-output_dir", + "--output_directory", + type=str, + default=None, + help="Path to the output directory for the generated report.", + ) parser.add_argument( "-st_autorun", "--streamlit_autorun", @@ -232,7 +239,13 @@ def get_parser(prog_name: str, others: dict = {}) -> argparse.Namespace: default=False, help="Automatically run the Streamlit app after report generation.", ) - + parser.add_argument( + "-qt_checks", + "--quarto_checks", + action="store_true", # Automatically sets True if the flag is passed + default=False, + help="Check if Quarto is installed and available for report generation.", + ) # Parse arguments return parser @@ -731,14 +744,26 @@ def get_logger( return logger, log_file -def print_completion_message(report_type: str): +def get_completion_message(report_type: str, config_path: str) -> str: """ - Prints a formatted completion message after report generation. + Generate a formatted completion message after report generation. + + Parameters + ---------- + report_type : str + The type of report generated (e.g., "streamlit", "html"). + config_path : str + The path to the configuration file used for generating the report. + + Returns + ------- + str + A formatted string containing the completion message. """ border = "─" * 65 # Creates a separator line + if report_type == "streamlit": - print( - """🚀 Streamlit Report Generated! + message = f"""🚀 Streamlit Report Generated! 📂 All scripts to build the Streamlit app are available at: streamlit_report/sections @@ -750,11 +775,12 @@ def print_completion_message(report_type: str): 🛠️ Advanced users can modify the Python scripts directly in: streamlit_report/sections + +⚙️ Configuration file used: + {config_path} """ - ) else: - print( - f"""🚀 {report_type.capitalize()} Report Generated! + message = f"""🚀 {report_type.capitalize()} Report Generated! 📂 Your {report_type} report is available at: quarto_report @@ -763,10 +789,12 @@ def print_completion_message(report_type: str): 🛠️ Advanced users can modify the report template directly in: quarto_report/quarto_report.qmd + +⚙️ Configuration file used: + {config_path} """ - ) - print(border) + return f"{message}\n{border}" ## REPORT FORMATTING