Commit b31e78b4 authored by Jonathan Mang's avatar Jonathan Mang :bulb:
Browse files

Finished feedback-logic. Outsourcing to dqastats pending.

Showing with 384 additions and 93 deletions
+384 -93
Package: DQAgui
Title: DQA GUI
Version: 0.0.7
Version: 0.0.7.9001
Authors@R:
c(person(given = "Lorenz A.",
family = "Kapsner",
......@@ -38,5 +38,5 @@ Suggests:
processx,
lintr
Remotes:
url::https://gitlab.miracum.org/miracum/dqa/dqastats/-/archive/v0.0.7/miracum/dqa/dqastats-v0.0.7.zip
url::https://gitlab.miracum.org/miracum/dqa/dqastats/-/archive/development/miracum/dqa/dqastats-development.zip
RoxygenNote: 7.0.2
......@@ -120,7 +120,7 @@ get_db_settings <- function(input, target = T) {
#' @description This functino is to provide feedback for any kind of
#' information. This might be a simple info, a warning or an error.
#' The function can be used to select the output (console, ui, logfile).
#' If no output is selected, the printme string will be printed to the
#' If no output is selected, the print_this string will be printed to the
#' console and to logfile.
#' One of these must be a string with length > 0: print_me, console, ui
#' @param print_this (Optional, String)
......@@ -170,6 +170,7 @@ feedback <-
if (isTRUE(console) && isFALSE(print_this == "")) {
feedback_to_console(
print_this = print_this,
type = type,
findme = findme,
prefix = prefix,
suffix = suffix
......@@ -178,22 +179,16 @@ feedback <-
# If there is text defined in 'ui' and/or 'console', print this one
# (this is uesful if one will provide both, feedback to the ui AND
# feedback to the console but with different texts)
# feedback to the console but with different texts).
# Hint: Everything printed to the console will also
# be printed to the logfile.
if (isTRUE(typeof(ui) == "character")) {
feedback_to_ui(print_this = print_this, type = type)
}
if (isTRUE(typeof(console) == "character")) {
feedback_to_console(
print_this = print_this,
findme = findme,
prefix = prefix,
suffix = suffix
)
}
if(isTRUE(console)){
feedback_to_logfile(
print_this = print_this,
type = type,
findme = findme,
prefix = prefix,
suffix = suffix
......@@ -208,24 +203,43 @@ feedback <-
#'
#' @inheritParams feedback
#'
feedback_to_console <- function(print_this, findme, prefix, suffix) {
feedback_to_console <- function(print_this, type, findme, prefix, suffix) {
if (length(print_this) == 1) {
res <-
feedback_get_formatted_string(print_this, findme, prefix, suffix)
feedback_get_formatted_string(
print_this = print_this,
type = type,
findme = findme,
prefix = prefix,
suffix = suffix
)
message(res)
feedback_to_logfile(res)
feedback_to_logfile(
print_this = print_this,
type = type,
findme = findme,
prefix = prefix,
suffix = suffix
)
} else if (length(print_this) > 1) {
i <- 1
for (tmp in print_this) {
res <-
feedback_get_formatted_string(
print_this = tmp,
type = type,
findme = findme,
prefix = paste0(prefix, i, ": "),
suffix = suffix
)
message(res)
feedback_to_logfile(res)
feedback_to_logfile(
print_this = tmp,
type = type,
findme = findme,
prefix = prefix,
suffix = suffix
)
i <- i + 1
}
}
......@@ -254,19 +268,143 @@ feedback_to_ui <- function(print_this, type) {
#' Use the robust 'feedback' function instead.
#' @param input The input string to be added to the logfile.
#'
feedback_to_logfile <- function(print_this, findme, prefix, suffix) {
feedback_to_logfile <- function(print_this, type, findme, prefix, suffix) {
# Get the formatted string out of the parameters which looks like
# "[Info] System is running (1234567890)":
res <- feedback_get_formatted_string(print_this = print_this,
type = type,
findme = findme,
prefix = prefix,
suffix = suffix)
# Set the string for the logfile containing the current time and date:
res <- paste0("[", Sys.time(), "] ", res)
# Open the connection to the logfile:
log_con <- file("logfile.log", open = "a")
# Write to the logfile:
cat(res, file = log_con)
# Set the string for the logfile containing the current time and date
# and a linebreak at the end:
res <- paste0("[", Sys.time(), "] ", res, "\n")
# Check if last character of the path is a slash and add one if not:
if (substr(logfile_dir, nchar(logfile_dir), nchar(logfile_dir)) != "/") {
logfile_dir <- paste0(logfile_dir, "/")
}
path_with_file <- paste0(logfile_dir, "logfile.log")
# Check if logfile.log is already the logfile for this session:
if (isTRUE(check_file_current_runtime_id(path_with_file = path_with_file))) {
# There is a logfile for the current runtime id,
# so append the existing logfile:
# Open the connection to the logfile:
log_con <- file(path_with_file, open = "a")
# Write to the logfile:
cat(res, file = log_con)
# Close the connection to logfile:
close(log_con)
} else {
# There is no logfile for the current runtime id,
# so rename the logfile.log to logfile_2020-01-01-1234h and
# create a new logfile and write the current runtime id to it:
filename_datetime <- format(Sys.time(), "%Y-%m-%d-%H%M%OS")
path_with_file_datetime <-
paste0(logfile_dir, "logfile_", filename_datetime, ".log")
file.rename(from = path_with_file, to = path_with_file_datetime)
# ... create a new logfile.log and paste the current runtime_id here:
if (!file.exists(path_with_file)) {
# Open the connection to the logfile:
log_con <- file(path_with_file, open = "a")
# Write current runtime_id to the logfile:
runtime_id <- paste0("runtime_id=", get_runtime_id(), "\n\n")
cat(runtime_id, file = log_con)
# Write current message to the logfile:
cat(res, file = log_con)
# Close the connection to logfile:
close(log_con)
}
}
# # If there already is a logfile for this session,
# # search in the logfile_dir for the next free filename:
# count <- 0
#
# while (isTRUE(file.exists(path_with_file)) &&
# check_file_current_wd(path_with_file)) {
# if (count > 1000) {
# # If there are more than 1000 logfiles, delete the whole folder
# # and recreate it:
# unlink(logfile_dir, recursive = TRUE)
# dir.create(logfile_dir)
# path_with_file <- paste0(logfile_dir, "/logfile.log")
# } else {
# # Otherwise just increment the number of the logfile:
# count <- count + 1
# path_with_file <- paste0(logfile_dir, "/logfile", count, ".log")
# }
# }
#
# if (!file.exists(path_with_file)) {
# # Open the connection to the logfile:
# log_con <- file(path_with_file, open = "a")
# # Write working directory to the logfile:
# wd <- paste0("wd=", getwd(), "\n\n")
# cat(wd, file = log_con)
# # Close the connection to logfile:
# close(log_con)
# }
#
# # Open the connection to the logfile:
# log_con <- file(path_with_file, open = "a")
# # Write to the logfile:
# cat(res, file = log_con)
# # Close the connection to logfile:
# close(log_con)
}
#' @title Returns the current runtime_id and stores it to rv$runtime_id
#' @description Helper function for the feedback function, especially
#' the logfile function. If there is already a runtime_id, the current
#' one will be returned. Otherwise a new one will be set,
#' stored to rv$runtime_id and also be returned.
#' @param force If true, a new runtime_id will be created.
#' If false (default) it depends wether there already is one or not.
#'
get_runtime_id <- function(force = FALSE) {
runtime_id_length <- 20
if (isTRUE(exists("runtime_id") &&
!is.na(runtime_id)) &&
nchar(runtime_id) == runtime_id_length && isFALSE(force)) {
return(runtime_id)
} else {
print("Getting a new runtime_id...")
# runtime_id <- sample(x = 0:10e6, size = 1)
runtime_id <-
paste0(sample(c(0:9, LETTERS[1:6]), runtime_id_length, T), collapse = "")
return(runtime_id)
}
}
#' @title Is current runtime_id the one in this file?
#' @description Helper function for the feedback function, especially
#' the logfile function. Extracts the runtime_id from the
#' logfile and compares it to the current runtime_id.
#' If equal, return = TRUE.
#' @param path_with_file The path with the file to look at
#'
check_file_current_runtime_id <- function(path_with_file) {
tryCatch({
con <- file(path_with_file, "r")
first_line <- readLines(con, n = 1)
runtime_id_tmp <- gsub("([runtime_id\\=])", "", first_line)
if (isTRUE(runtime_id_tmp == runtime_id)) {
return(TRUE)
} else {
return(FALSE)
}
close(con)
},
error = function(cond) {
return(FALSE)
},
warning = function(cond) {
return(FALSE)
}, finally = close(con))
}
#' @title Format the feedback string
......@@ -278,7 +416,9 @@ feedback_to_logfile <- function(print_this, findme, prefix, suffix) {
#' Internal use. Use the robust 'feedback' function instead.
#' @inheritParams feedback
#'
feedback_get_formatted_string <- function(print_this, findme, prefix, suffix){
feedback_get_formatted_string <-
function(print_this, type, findme, prefix, suffix) {
if (length(print_this) == 1) {
if (findme == "") {
res <- paste0("[", type, "] ", prefix, print_this, suffix)
......@@ -370,8 +510,8 @@ validate_inputs <- function(rv) {
findme = "10d5e79d44",
ui = T
)
printme(
paste0(
feedback(
print_this = paste0(
"rv$source$settings$dir = ",
rv$source$settings$dir,
"(d9b43110bb)"
......@@ -387,7 +527,8 @@ validate_inputs <- function(rv) {
headless = rv$headless)
if (!is.null(rv$source$db_con)) {
# valid
printme("Source db-settings seem valid. (29cc920472)")
feedback(print_this = "Source db-settings seem valid.",
findme = "29cc920472")
} else {
# invalid:
feedback(
......@@ -396,11 +537,11 @@ validate_inputs <- function(rv) {
findme = "c63e1ccaf0",
ui = T
)
printme(paste0(
"rv$source$settings = ",
rv$source$settings,
"(2d47f163a9)"
))
feedback(
print_this = paste0("rv$source$settings = ",
rv$source$settings),
findme = "2d47f163a9"
)
error_tmp <- T
}
} else {
......@@ -455,11 +596,11 @@ validate_inputs <- function(rv) {
findme = "f4cc32e068",
ui = T
)
printme(paste0(
"rv$target$settings$dir = ",
rv$target$dir,
"(43c81cb723)"
))
feedback(
print_this = paste0("rv$target$settings$dir = ",
rv$target$dir),
findme = "(43c81cb723)"
)
error_tmp <- T
}
} else if (rv$target$system_type == "postgres") {
......@@ -470,7 +611,7 @@ validate_inputs <- function(rv) {
headless = rv$headless)
if (!is.null(rv$target$db_con)) {
# valid
printme("Target db-settings seem valid. (79234d2ba0)")
feedback("Target db-settings seem valid. (79234d2ba0)")
} else {
# invalid:
feedback(
......@@ -479,7 +620,7 @@ validate_inputs <- function(rv) {
findme = "096341c4c1",
ui = T
)
printme(paste0(
feedback(paste0(
"rv$target$settings = ",
rv$target$settings,
"(2d47f163a9)"
......
......@@ -37,13 +37,15 @@
#' is stored in the default settings file and correspsondingly in the MDR)
#' with the following format: *SYSTEMNAME*_PASSWORD, where *SYSTEMNAME*
#' should be replaced with the name of the datasystem.
#' @param logfile_dir Is the absolute path to the directory where the logfile
#' will be stored. If not path is provided the tempdir() will be used.
#'
#' @return DQAgui Shiny application
#'
#' @import shiny shinydashboard
#' @importFrom magrittr "%>%"
#' @importFrom data.table .N ":="
#' @importFrom DQAstats feedback
# @importFrom DQAstats feedback
#'
#' @export
#'
......@@ -55,8 +57,8 @@ launch_app <- function(port = 3838,
config_file = system.file(
"demo_data/utilities/settings/demo_settings.yml",
package = "DQAstats"),
use_env_credentials = FALSE) {
use_env_credentials = FALSE,
logfile_dir = tempdir()) {
global_env_hack <- function(key,
val,
......@@ -92,6 +94,18 @@ launch_app <- function(port = 3838,
pos = 1L
)
global_env_hack(
key = "logfile_dir",
val = logfile_dir,
pos = 1L
)
global_env_hack(
key = "runtime_id",
val = get_runtime_id(force = T),
pos = 1L
)
options(shiny.port = port)
shiny::shinyAppDir(
......
......@@ -122,13 +122,13 @@ module_config_server <-
eventExpr = input_re()[["moduleConfig-config_load_mdr"]],
handlerExpr = {
if (is.null(rv$mdr)) {
printme("Reading MDR ...")
feedback("Reading MDR ...")
if (debugging) {
printme(paste0("MDR-Filename:", rv$mdr_filename))
feedback(paste0("MDR-Filename:", rv$mdr_filename))
}
if (debugging) {
printme(paste0("rv$utilspath:", rv$utilspath))
feedback(paste0("rv$utilspath:", rv$utilspath))
}
rv$mdr <- button_mdr(utils_path = rv$utilspath,
mdr_filename = rv$mdr_filename)
......@@ -214,10 +214,10 @@ module_config_server <-
}
if (!("postgres" %in% tolower(rv$system_types))) {
# Remove Postgres-Tabs:
printme("Removing postgres-tab from source ...")
feedback("Removing postgres-tab from source ...")
removeTab(inputId = "source_tabs", target = "PostgreSQL")
printme("Removing postgres-tab from target ...")
feedback("Removing postgres-tab from target ...")
removeTab(inputId = "target_tabs", target = "PostgreSQL")
} else{
# Fill the tab with presettings
......@@ -283,19 +283,24 @@ module_config_server <-
# observeEvent(input$source_pg_presettings_btn, {
observeEvent(input$source_pg_presettings_list, {
feedback(
paste0(
"Input-preset ",
input$source_pg_presettings_list,
" was chosen as SOURCE.",
" Loading presets ..."
), findme = "e9832b3092"
print_this =
paste0(
"Input-preset ",
input$source_pg_presettings_list,
" was chosen as SOURCE.",
" Loading presets ..."
),
findme = "e9832b3092"
)
config_stuff <- rv$settings[[tolower(input$source_pg_presettings_list)]]
feedback(paste(
"Loaded successfully.",
"Filling presets to global rv-object and UI ..."
), findme = "3c9136d49f")
feedback(
print_this = paste(
"Loaded successfully.",
"Filling presets to global rv-object and UI ..."
),
findme = "3c9136d49f"
)
if (length(config_stuff) != 0) {
updateTextInput(session = session,
inputId = "config_sourcedb_dbname",
......
......@@ -8,6 +8,7 @@ utils_path = DQAstats::clean_path_name(system.file("application/_utilities",
mdr_filename = "mdr.csv"
config_file = system.file("application/_settings/demo_settings_INTERNAL.yml",
package = "DQAgui")
logfile_dir = "~/share/logfiles/"
## ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
......@@ -34,7 +35,8 @@ launch_app(
port = port,
utils_path = utils_path,
mdr_filename = mdr_filename,
config_file = config_file
config_file = config_file,
logfile_dir = logfile_dir
)
# with environment variables
......
......@@ -29,7 +29,7 @@ my_desc$set("Copyright", "Universitätsklinikum Erlangen")
# Remove some author fields
my_desc$del("Maintainer")
# Set the version
my_desc$set_version("0.0.7")
my_desc$set_version("0.0.7.9001")
# The title of your package
my_desc$set(Title = "DQA GUI")
# The description of your package
......@@ -82,7 +82,7 @@ usethis::use_package("processx", type = "Suggests")
usethis::use_package("lintr", type = "Suggests")
# Development package
mytag <- "v0.0.7"
mytag <- "development"
devtools::install_git(url = "https://gitlab.miracum.org/miracum/dqa/dqastats.git", ref = mytag, upgrade = "always")
# usethis::use_dev_package("DQAstats", type = "Imports")
# https://cran.r-project.org/web/packages/devtools/vignettes/dependencies.html
......
......@@ -23,6 +23,8 @@ shiny::shinyServer(
config_file = config_file,
mdr_filename = mdr_filename,
use_env_credentials = use_env_credentials,
logfile_dir = logfile_dir,
runtime_id = runtime_id,
utilspath = DQAstats::clean_path_name(utils_path),
current_date = format(Sys.Date(), "%d. %B %Y", tz = "CET")
)
......
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/app_utils.R
\name{check_file_current_runtime_id}
\alias{check_file_current_runtime_id}
\title{Is current runtime_id the one in this file?}
\usage{
check_file_current_runtime_id(path_with_file)
}
\arguments{
\item{path_with_file}{The path with the file to look at}
}
\description{
Helper function for the feedback function, especially
the logfile function. Extracts the runtime_id from the
logfile and compares it to the current runtime_id.
If equal, return = TRUE.
}
......@@ -2,39 +2,46 @@
% Please edit documentation in R/app_utils.R
\name{feedback}
\alias{feedback}
\title{Simple method to feedback messages either to the user and/or to the
console.}
\title{Simply prints stuff to the console.}
\usage{
feedback(
print_this,
print_this = "",
type = "Info",
ui = FALSE,
console = TRUE,
logfile = TRUE,
prefix = "",
suffix = "",
findme = ""
)
}
\arguments{
\item{print_this}{The string to be printed.}
\item{print_this}{(Optional, String)}
\item{type}{(Optional) The type of message as string.
If type is e.g. "Warning" the printed line will be "[Warning] print_this".}
\item{type}{(Optional, String)}
\item{ui}{(Optional) If true, the message will also be printed
to the user in form of a modal.}
\item{ui}{(Optional, Boolean/String) If true, the message will
also be printed to the user in form of a modal. Can also be a string.}
\item{console}{(Optional) If true, the message will also be printed
to the console as is.}
\item{console}{(Optional, Boolean/String) If true, the message will also
be printed to the console as is. Can also be a string.}
\item{prefix}{Prefix (String)}
\item{prefix}{Prefix (Optional, String) This is useful if
print_this is an array/list.
Each entry will then be new row with this prefix.}
\item{suffix}{Suffix (String)}
\item{suffix}{Suffix (Optional, String). Same like prefix but at the
end of each line.}
\item{findme}{(Optional) String to find the message in the code.
\item{findme}{(Optional, String) String to find the message in the code.
E.g. 10-digit random hex from https://www.browserling.com/tools/random-hex
or https://onlinerandomtools.com/generate-random-hexadecimal-numbers}
}
\description{
Extended version of the printme-function.
This functino is to provide feedback for any kind of
information. This might be a simple info, a warning or an error.
The function can be used to select the output (console, ui, logfile).
If no output is selected, the print_this string will be printed to the
console and to logfile.
One of these must be a string with length > 0: print_me, console, ui
}
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/app_utils.R
\name{feedback_get_formatted_string}
\alias{feedback_get_formatted_string}
\title{Format the feedback string}
\usage{
feedback_get_formatted_string(print_this, type, findme, prefix, suffix)
}
\arguments{
\item{print_this}{(Optional, String)}
\item{type}{(Optional, String)}
\item{findme}{(Optional, String) String to find the message in the code.
E.g. 10-digit random hex from https://www.browserling.com/tools/random-hex
or https://onlinerandomtools.com/generate-random-hexadecimal-numbers}
\item{prefix}{Prefix (Optional, String) This is useful if
print_this is an array/list.
Each entry will then be new row with this prefix.}
\item{suffix}{Suffix (Optional, String). Same like prefix but at the
end of each line.}
}
\description{
Helper function for the feedback function to combine the input
parameters in proper manner to ge a pretty and informative string which
than can be added to the logfile and/or be displayed in the console.
CAUTION: 'print_this' must be of length 1! For arrays loop through them
by hand and call this function several times!
Internal use. Use the robust 'feedback' function instead.
}
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/app_utils.R
\name{feedback_to_console}
\alias{feedback_to_console}
\title{Print to the console. Internal use.}
\usage{
feedback_to_console(print_this, type, findme, prefix, suffix)
}
\arguments{
\item{print_this}{(Optional, String)}
\item{type}{(Optional, String)}
\item{findme}{(Optional, String) String to find the message in the code.
E.g. 10-digit random hex from https://www.browserling.com/tools/random-hex
or https://onlinerandomtools.com/generate-random-hexadecimal-numbers}
\item{prefix}{Prefix (Optional, String) This is useful if
print_this is an array/list.
Each entry will then be new row with this prefix.}
\item{suffix}{Suffix (Optional, String). Same like prefix but at the
end of each line.}
}
\description{
Helper function for the feedback function to print
stuff to the console. Everything will also be added to the logfile.
Internal use. Use the robust 'feedback' function instead.
}
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/app_utils.R
\name{feedback_to_logfile}
\alias{feedback_to_logfile}
\title{Add to the logfile. Internal use.}
\usage{
feedback_to_logfile(print_this, type, findme, prefix, suffix)
}
\arguments{
\item{input}{The input string to be added to the logfile.}
}
\description{
Helper function for the feedback function to add content
to the logfile. Internal use.
Use the robust 'feedback' function instead.
}
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/app_utils.R
\name{feedback_to_ui}
\alias{feedback_to_ui}
\title{Feedback to the user with a modal. Internal use.}
\usage{
feedback_to_ui(print_this, type)
}
\arguments{
\item{print_this}{(Optional, String)}
\item{type}{(Optional, String)}
}
\description{
Helper function for the feedback function to show modals
to the gui/user. Everything will also be added to the logfile.
Internal use. Use the robust 'feedback' function instead.
}
......@@ -12,6 +12,9 @@ feedback_txt(system, type)
\item{type}{(String) "source" or "target"}
}
\value{
String containing the input params in a propper manner
}
\description{
This function is used in the config-tab and displays the selected
system to the user.
......
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/app_utils.R
\name{get_runtime_id}
\alias{get_runtime_id}
\title{Returns the current runtime_id and stores it to rv$runtime_id}
\usage{
get_runtime_id(force = FALSE)
}
\arguments{
\item{force}{If true, a new runtime_id will be created.
If false (default) it depends wether there already is one or not.}
}
\description{
Helper function for the feedback function, especially
the logfile function. If there is already a runtime_id, the current
one will be returned. Otherwise a new one will be set,
stored to rv$runtime_id and also be returned.
}
......@@ -10,7 +10,8 @@ launch_app(
mdr_filename = "mdr_example_data.csv",
config_file = system.file("demo_data/utilities/settings/demo_settings.yml", package =
"DQAstats"),
use_env_credentials = FALSE
use_env_credentials = FALSE,
logfile_dir = tempdir()
)
}
\arguments{
......@@ -37,6 +38,9 @@ provide one variable for the respective data system (the name, which
is stored in the default settings file and correspsondingly in the MDR)
with the following format: *SYSTEMNAME*_PASSWORD, where *SYSTEMNAME*
should be replaced with the name of the datasystem.}
\item{logfile_dir}{Is the absolute path to the directory where the logfile
will be stored. If not path is provided the tempdir() will be used.}
}
\value{
DQAgui Shiny application
......
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/app_utils.R
\name{printme}
\alias{printme}
\title{Simply prints stuff to the console.}
\usage{
printme(print_this, type = "Info")
}
\arguments{
\item{print_this}{The string to be printed.}
\item{type}{(Optional) The type of message as string.
If type is e.g. "Warning" the printed line will be "[Warning] print_this".}
}
\description{
Simply prints stuff to the console.
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment