Skip to content

Commit

Permalink
Merge branch 'release/1.25.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
pbchase committed Oct 24, 2024
2 parents eee9051 + a618c56 commit 7c94b1c
Show file tree
Hide file tree
Showing 21 changed files with 239 additions and 103 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
*.zip
site
!inst/testdata/*.csv
report/*.html
report/*.pdf
report/*.txt



# env file
*.env
Expand Down
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: redcapcustodian
Type: Package
Title: Data automation for R-centric workflows with a nod towards REDCap
Version: 1.24.0
Version: 1.25.0
Authors@R: c(
person("Philip", "Chase",
email = "[email protected]",
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export(log_job_failure)
export(log_job_success)
export(mutate_columns_to_posixct)
export(quit_non_interactive_run)
export(render_report)
export(scrape_user_api_tokens)
export(send_email)
export(set_package_scope_var)
Expand Down
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# redcapcustodian 1.25.0 (released 2024-10-24)
- Add report crash logging to render_report.R (@ljwoodley, #166)
- Update render_report.R to use render_report() function (@ljwoodley, #166)
- Add render_report() (@ljwoodley, #166)

# redcapcustodian 1.24.0 (released 2024-10-17)
- Add job failure alerts with run_etl.R and updates to send_mail() (@ljwoodley, #100, #165)
- Add Sai as author in DESCRIPTION (@pbchase)
Expand Down
73 changes: 73 additions & 0 deletions R/reporting.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#' Render a Markdown Report from Rmd or Qmd Files
#'
#' This function renders a report from a R Markdown (.Rmd) or Quarto Markdown (.Qmd) script.
#' It is designed to be invoked from `render_report.R`. The rendered report is saved in either PDF or HTML format with a
#' timestamp appended to the filename.
#'
#' @param script_path The full path of the script to render
#
#' @return A list containing details about the operation's outcome:
#'
#' If rendering is successful, the list includes:
#' \itemize{
#' \item `success`: TRUE
#' \item `report_name`: The name of the report file.
#' \item `filepath`: The full path to the report.
#' }
#' If rendering fails, the list includes:
#' \itemize{
#' \item `success`: FALSE
#' \item `logfile`: The full path to the log file.
#' \item `error`: Error message returned from quarto_render.
#' }
#'
#' @export

#' @examples
#' \dontrun{
#' script_path <- here::here("report", "quarto_html_example.qmd")
#' render_results <- render_report(script_path)
#' }
#'
#'
render_report <- function(script_path) {

script_path_without_extension <- tools::file_path_sans_ext(script_path)
base_script_name <- basename(script_path_without_extension)
run_time <- format(redcapcustodian::get_script_run_time(), "%Y-%m-%d_%H%M%S")
logfile <- here::here("report", "log", paste0(base_script_name, "_", run_time, ".txt"))

result <- tryCatch({
capture.output(quarto::quarto_render(script_path), file = logfile)
list(success = TRUE)
}, error = function(e) {
list(success = FALSE, logfile = logfile, error = e$message)
})

if (!result$success) {
return(result)
stop("Report rendering failed: ", result$error)
}

default_filenames <- paste0(script_path_without_extension, c(".pdf", ".html"))

for (default_filename in default_filenames) {
if (file.exists(default_filename)) {
file_extension <- tools::file_ext(default_filename)

report_name <- paste0(
base_script_name,
"_",
run_time,
".",
file_extension
)

report_filepath <- here::here("report", "output", report_name)

file.rename(default_filename, report_filepath)

return(list(success = result$success, report_name = report_name, filepath = report_filepath))
}
}
}
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.24.0
1.25.0
40 changes: 40 additions & 0 deletions man/render_report.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions report/log/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
2 changes: 2 additions & 0 deletions report/output/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
68 changes: 20 additions & 48 deletions report/render_report.R
Original file line number Diff line number Diff line change
@@ -1,67 +1,39 @@
library(tidyverse)
library(dotenv)
library(REDCapR)
library(lubridate)
library(rmarkdown)
library(sendmailR)
library(redcapcustodian)
library(argparse)

init_etl("render_report")

parser <- ArgumentParser()
parser$add_argument("script_name", nargs=1, help="Script to be run")
parser$add_argument("script_path", nargs=1, help="The path of the script to be run")

if (!interactive()) {
args <- parser$parse_args()
script_name <- args$script_name
if(!fs::file_exists(script_name)) {
stop(sprintf("Specified file, %s, does not exist", script_name))
}
script_path <- args$script_path
} else {
script_name <- "report/sample_report.qmd"
if(!fs::file_exists(script_name)) {
stop(sprintf("Specified file, %s, does not exist", script_name))
}
script_path <- here::here("report", "sample_report.Rmd")
}

report_name <- word(script_name, 1, sep = "\\.")
report_type <- word(script_name, 2, sep = "\\.")
if(!fs::file_exists(script_path)) {
stop(sprintf("Specified file, %s, does not exist", script_path))
}

script_run_time <- set_script_run_time()
output_filename <-
paste0(
str_replace(report_name, ".*/", ""),
"_",
format(script_run_time, "%Y%m%d%H%M%S")
)
render_results <- render_report(script_path)

if (report_type == "qmd") {
full_path_to_output_file <- quarto::quarto_render(
script_name,
output_file = paste0(output_filename, ".pdf"),
output_format = "pdf"
)
if (render_results$success) {
email_subject <- paste(render_results$report_name)
attachment_object <- mime_part(render_results$filepath)
body <- "Please see the attached report."
email_body <- list(body, attachment_object)
send_email(email_body, email_subject)

attachment_object <- mime_part(paste0(output_filename, ".pdf"))
log_job_success(jsonlite::toJSON(basename(script_path)))
} else {
full_path_to_output_file <- render(
script_name,
output_file = output_filename
)

attachment_object <- mime_part(
full_path_to_output_file,
basename(full_path_to_output_file)
)
email_subject <- paste0("Failed | ", here::here(script_path), " | ", format(get_script_run_time(), "%Y-%m-%d"))
attachment_object <- mime_part(render_results$logfile)
body <- "Report failed to render."
email_body <- list(body, attachment_object)
send_email(email_body, email_subject)
}

email_subject <- paste(basename(report_name), "|", script_run_time)
body <- "Please see the attached report."

email_body <- list(body, attachment_object)

# send the email with the attached output file
send_email(email_body, email_subject)

set_script_name("render_report")
log_job_success(jsonlite::toJSON(script_name))
4 changes: 3 additions & 1 deletion report/sample_report.Rmd
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
title: "Sample Report"
output: pdf_document
format:
pdf:
self-contained: true
---

```{r setup, include=FALSE}
Expand Down
1 change: 1 addition & 0 deletions report/sample_report.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title: "sample_report"
format:
html:
toc: true
embed-resources: true
pdf:
toc: true
---
Expand Down
4 changes: 4 additions & 0 deletions study_template/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@
*.env
!examples/testing.env
output/
report/*.html
report/*.pdf
report/*.txt

2 changes: 2 additions & 0 deletions study_template/report/log/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
4 changes: 4 additions & 0 deletions study_template/report/output/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.csv
*.xlsx
*.html
*.pdf
3 changes: 2 additions & 1 deletion study_template/report/quarto_html_example.qmd
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
---
title: "Quarto HTML example"
title: "Quarto HTML Example"
author: "John Doe"
format: html
embed-resources: true
editor: visual
---

Expand Down
18 changes: 18 additions & 0 deletions study_template/report/quarto_html_fail_example.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: "Quarto HTML Fail Example"
format: html
embed-resources: true
editor: visual
---

## Quarto

Quarto enables you to weave together content and executable code into a finished document. To learn more about Quarto see <https://quarto.org>.

## Running Code

When you click the **Render** button a document will be generated that includes both content and the output of embedded code. You can embed code like this:

```{r}
1 + a
```
2 changes: 1 addition & 1 deletion study_template/report/quarto_pdf_example.qmd
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: "Quarto PDF example"
title: "Quarto PDF Example"
format: pdf
editor: visual
---
Expand Down
Loading

0 comments on commit 7c94b1c

Please sign in to comment.