[education/rkward] rkward/rbackend/rpackages/rkward: added new function rk.download_appimage()
m.eik michalke
null at kde.org
Thu Jul 18 10:46:32 BST 2024
Git commit 2985a7d5b251516c4237587938fbf2b5c93616e1 by m.eik michalke.
Committed on 18/07/2024 at 09:45.
Pushed by meikm into branch 'master'.
added new function rk.download_appimage()
M +8 -12 rkward/rbackend/rpackages/rkward/DESCRIPTION
M +1 -0 rkward/rbackend/rpackages/rkward/NAMESPACE
A +148 -0 rkward/rbackend/rpackages/rkward/R/rk.download_appimage.R
M +1 -1 rkward/rbackend/rpackages/rkward/R/rkward-package.R
A +71 -0 rkward/rbackend/rpackages/rkward/man/rk.download_appimage.Rd
M +1 -1 rkward/rbackend/rpackages/rkward/man/rkward-package.Rd
https://invent.kde.org/education/rkward/-/commit/2985a7d5b251516c4237587938fbf2b5c93616e1
diff --git a/rkward/rbackend/rpackages/rkward/DESCRIPTION b/rkward/rbackend/rpackages/rkward/DESCRIPTION
index e2d623345..e6009ba04 100755
--- a/rkward/rbackend/rpackages/rkward/DESCRIPTION
+++ b/rkward/rbackend/rpackages/rkward/DESCRIPTION
@@ -1,12 +1,9 @@
Package: rkward
Type: Package
Title: Provides functions related to the RKWard GUI
-Description: This package contains functions which are useful in
- combination with the RKWard GUI. Many of these functions are
- only needed for the internal communication between RKWard and
- R, but some are also useful in user scripts.
-Author: Thomas Friedrichsmeier <thomas.friedrichsmeier at kdemail.net> and
- the RKWard Team <rkward-devel at kde.org>
+Description: This package contains functions which are useful in combination with the RKWard GUI. Many of these functions are only needed for the internal communication between
+ RKWard and R, but some are also useful in user scripts.
+Author: Thomas Friedrichsmeier <thomas.friedrichsmeier at kdemail.net> and the RKWard Team <rkward-devel at kde.org>
Maintainer: RKWard-devel mailing list <rkward-devel at kde.org>
Depends: R (>= 2.9.0),methods
Suggests: Cairo,googleVis,htmlwidgets,lattice,R2HTML
@@ -15,12 +12,10 @@ BugReports: https://rkward.kde.org/Bugs.html
License: GPL (>= 2)
Encoding: UTF-8
LazyLoad: yes
-Authors at R: c(person(given="Thomas", family="Friedrichsmeier",
- email="thomas.friedrichsmeier at kdemail.net", role=c("aut")),
- person(given="the RKWard", family="team",
- email="rkward-devel at kde.org", role=c("cre","aut")))
-Version: 0.8.1
-Date: 2024-07-15
+Authors at R: c(person(given="Thomas", family="Friedrichsmeier", email="thomas.friedrichsmeier at kdemail.net", role=c("aut")), person(given="the RKWard", family="team",
+ email="rkward-devel at kde.org", role=c("cre","aut")))
+Version: 0.8.0
+Date: 2024-07-18
RoxygenNote: 7.3.1
Collate:
'base_overrides.R'
@@ -33,6 +28,7 @@ Collate:
'rk.check.for.pandoc.R'
'rk.completion-functions.R'
'rk.demo.R'
+ 'rk.download_appimage.R'
'rk.edit-functions.R'
'rk.filename-functions.R'
'rk.label-functions.R'
diff --git a/rkward/rbackend/rpackages/rkward/NAMESPACE b/rkward/rbackend/rpackages/rkward/NAMESPACE
index 96e3063a7..de67aaafc 100644
--- a/rkward/rbackend/rpackages/rkward/NAMESPACE
+++ b/rkward/rbackend/rpackages/rkward/NAMESPACE
@@ -55,6 +55,7 @@ export(rk.clear.plot.history)
export(rk.demo)
export(rk.describe.alternative)
export(rk.discard.preview.data)
+export(rk.download_appimage)
export(rk.duplicate.device)
export(rk.edit)
export(rk.edit.files)
diff --git a/rkward/rbackend/rpackages/rkward/R/rk.download_appimage.R b/rkward/rbackend/rpackages/rkward/R/rk.download_appimage.R
new file mode 100644
index 000000000..5310025ea
--- /dev/null
+++ b/rkward/rbackend/rpackages/rkward/R/rk.download_appimage.R
@@ -0,0 +1,148 @@
+# - This file is part of the RKWard project (https://rkward.kde.org).
+# SPDX-FileCopyrightText: by Thomas Friedrichsmeier <thomas.friedrichsmeier at kdemail.net>
+# SPDX-FileContributor: The RKWard Team <rkward-devel at kde.org>
+# SPDX-License-Identifier: GPL-2.0-or-later
+#' Install or update RKWard AppImage file
+#'
+#' Tries to download the latest AppImage of RKWard to a specified directory and
+#' makes it executable so it can be used for launching RKWard.
+#'
+#' This function uses functions of the \code{XiMpLe} package, allthough for technical
+#' reasons that package could not be declared a proper dependency. This means, if
+#' you use this function for the first time with the current R version and hadn't
+#' installed \code{XiMpLe} yet, you will be prompted to install it first. This
+#' behaviour is similar to using an RKWard plugin dialog with a \code{require()}
+#' call to a currently not installed package.
+#'
+#' @param dir File path to the target directory.
+#' @param filename Character string, filename for the downloaded AppImage.
+#' @param download Logical, whether to actually download the file or only return the full URL to it in a character string.
+#' @param overwrite Logical, should an existing file be overwritten?
+#' @param url Base URL to download the AppImage from.
+#' @param pattern Regular expression to find the AppImage file name in \code{url}.
+#' @param method See \code{\link[utils:download.file]{download.file}}.
+#' @param cacheOK See \code{\link[utils:download.file]{download.file}}.
+#' @param timeout Number of seconds to try finishing the download.
+#' @param ... Additionsl options for \code{\link[utils:download.file]{download.file}}.
+#' @return If \code{download = FALSE} returns the direct URL to the AppImage file.
+#' Otherwise returns the invisible file path to the installed AppImage if all went well,
+#' or invisible \code{NULL} if something went wrong.
+#' @author Meik Michalke \email{rkward-devel@@kde.org}
+#' @keywords utilities misc
+# # don't create additional dependencies for the rkward package
+# @importFrom XiMpLe parseXMLTree XMLScanDeep
+# @importFrom utils download.file
+#' @rdname rk.download_appimage
+#' @export
+#' @examples
+#' \dontrun{
+#' # install current AppImage from master branch to ~/bin
+#' rk.download_appimage(dir="~/bin")
+#'
+#' # update the AppImage
+#' rk.download_appimage(dir="~/bin", overwrite=TRUE)
+#' }
+
+rk.download_appimage <- function(
+ dir = dirname(Sys.getenv("APPIMAGE"))
+ , filename = "rkward-master-linux-gcc-x86_64.AppImage"
+ , download = TRUE
+ , overwrite = FALSE
+ , url = "https://cdn.kde.org/ci-builds/education/rkward/master/linux"
+ , pattern = "rkward-master.*linux-gcc-x86_64\\.AppImage"
+ , method = "auto"
+ , cacheOK = FALSE
+ , timeout = max(400, getOption("timeout"))
+ , ...
+){
+
+ # we are well aware that require() is not the method of choice
+ # this call will invoke rkward::require(), which should only be present
+ # in a running session of RKWard, and therefore ask for the installation
+ # of XiMpLe if the package is currently missing in the R version that
+ # is running at the moment
+ rkward::require(XiMpLe)
+ XiMpLe_version <- utils::packageVersion("XiMpLe")
+ if(isFALSE(XiMpLe_version >= "0.11.3")){
+ stop(simpleError(paste0("rk.download_appimage() requires XiMpLe >= 0.11.3, but only found ", XiMpLe_version, ". Please update XiMpLe.")))
+ } else {}
+ rk_ai_html <- XiMpLe::parseXMLTree(url, drop="empty_attributes")
+ rk_ai_hrefs <- XiMpLe::XMLScanDeep(rk_ai_html, find="href")
+ rk_ai_file <- rk_ai_hrefs[grepl(pattern=pattern, x=rk_ai_hrefs)][[1]]
+
+ rk_ai_full_url <- file.path(url, rk_ai_file)
+
+ if(isTRUE(download)){
+ if(!dir.exists(dir)){
+ stop(simpleError(paste0("Target directory does not exist:\n ", dir)))
+ } else {}
+ have_backup <- FALSE
+ target_file <- file.path(dir, filename)
+ if(file.exists(target_file)){
+ if(isFALSE(overwrite)){
+ stop(simpleError(paste0("Target file already exists, use the \"overwrite\" argument to replace it:\n ", target_file)))
+ } else {}
+ # create backup of current AppImage as a fallback
+ rk_ai_backup <- paste0(target_file, ".backup_", format(Sys.time(), "%Y-%m-%d_%H%M%S"))
+ message(paste0("Creating backup of current AppImage:\n ", rk_ai_backup))
+ file.rename(
+ from=target_file
+ , to=rk_ai_backup
+ )
+ have_backup <- TRUE
+ } else {}
+ timeout_orig <- getOption("timeout")
+ options(timeout = timeout)
+ dl_status <- tryCatch(
+ # value should be 0 if download was successful
+ utils::download.file(
+ url = rk_ai_full_url
+ , destfile = target_file
+ , method = method
+ , cacheOK = cacheOK
+ , quiet = FALSE
+ , ...
+ )
+ , error = function(cond){
+ if(isTRUE(have_backup)){
+ file.rename(
+ from=rk_ai_backup
+ , to=target_file
+ )
+ stop("Something went wrong with the download! Restored previous AppImage from backup.", call.=FALSE)
+ } else {
+ file.remove(target_file)
+ stop("Something went wrong with the download!", call.=FALSE)
+ }
+ }
+ , finally = options(timeout = timeout_orig)
+ )
+ if(isTRUE(dl_status == 0)){
+ message("Download successful, setting file permissions.")
+ Sys.chmod(
+ paths=target_file
+ , mode="0755"
+ , use_umask=TRUE
+ )
+ if(isTRUE(have_backup)){
+ message("Removing backup of previous AppImage.")
+ file.remove(rk_ai_backup)
+ } else {}
+ return(invisible(target_file))
+ } else {
+ if(isTRUE(have_backup)){
+ warning("Something went wrong with the download! Restoring previous AppImage from backup.", call.=FALSE)
+ file.rename(
+ from=rk_ai_backup
+ , to=target_file
+ )
+ } else {
+ warning("Something went wrong with the download!", call.=FALSE)
+ file.remove(target_file)
+ }
+ }
+ return(invisible(NULL))
+ } else {
+ return(rk_ai_full_url)
+ }
+}
diff --git a/rkward/rbackend/rpackages/rkward/R/rkward-package.R b/rkward/rbackend/rpackages/rkward/R/rkward-package.R
index e0103a470..5f63c8896 100644
--- a/rkward/rbackend/rpackages/rkward/R/rkward-package.R
+++ b/rkward/rbackend/rpackages/rkward/R/rkward-package.R
@@ -13,7 +13,7 @@
#' Package: \tab rkward\cr
#' Type: \tab Package\cr
#' Version: \tab 0.8.0\cr
-#' Date: \tab 2024-07-11\cr
+#' Date: \tab 2024-07-18\cr
#' Depends: \tab R (>= 2.9.0),methods\cr
#' Encoding: \tab UTF-8\cr
#' License: \tab GPL (>= 2)\cr
diff --git a/rkward/rbackend/rpackages/rkward/man/rk.download_appimage.Rd b/rkward/rbackend/rpackages/rkward/man/rk.download_appimage.Rd
new file mode 100644
index 000000000..9f9295a84
--- /dev/null
+++ b/rkward/rbackend/rpackages/rkward/man/rk.download_appimage.Rd
@@ -0,0 +1,71 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/rk.download_appimage.R
+\name{rk.download_appimage}
+\alias{rk.download_appimage}
+\title{Install or update RKWard AppImage file}
+\usage{
+rk.download_appimage(
+ dir = dirname(Sys.getenv("APPIMAGE")),
+ filename = "rkward-master-linux-gcc-x86_64.AppImage",
+ download = TRUE,
+ overwrite = FALSE,
+ url = "https://cdn.kde.org/ci-builds/education/rkward/master/linux",
+ pattern = "rkward-master.*linux-gcc-x86_64\\\\.AppImage",
+ method = "auto",
+ cacheOK = FALSE,
+ timeout = max(400, getOption("timeout")),
+ ...
+)
+}
+\arguments{
+\item{dir}{File path to the target directory.}
+
+\item{filename}{Character string, filename for the downloaded AppImage.}
+
+\item{download}{Logical, whether to actually download the file or only return the full URL to it in a character string.}
+
+\item{overwrite}{Logical, should an existing file be overwritten?}
+
+\item{url}{Base URL to download the AppImage from.}
+
+\item{pattern}{Regular expression to find the AppImage file name in \code{url}.}
+
+\item{method}{See \code{\link[utils:download.file]{download.file}}.}
+
+\item{cacheOK}{See \code{\link[utils:download.file]{download.file}}.}
+
+\item{timeout}{Number of seconds to try finishing the download.}
+
+\item{...}{Additionsl options for \code{\link[utils:download.file]{download.file}}.}
+}
+\value{
+If \code{download = FALSE} returns the direct URL to the AppImage file.
+ Otherwise returns the invisible file path to the installed AppImage if all went well,
+ or invisible \code{NULL} if something went wrong.
+}
+\description{
+Tries to download the latest AppImage of RKWard to a specified directory and
+makes it executable so it can be used for launching RKWard.
+}
+\details{
+This function uses functions of the \code{XiMpLe} package, allthough for technical
+reasons that package could not be declared a proper dependency. This means, if
+you use this function for the first time with the current R version and hadn't
+installed \code{XiMpLe} yet, you will be prompted to install it first. This
+behaviour is similar to using an RKWard plugin dialog with a \code{require()}
+call to a currently not installed package.
+}
+\examples{
+\dontrun{
+# install current AppImage from master branch to ~/bin
+rk.download_appimage(dir="~/bin")
+
+# update the AppImage
+rk.download_appimage(dir="~/bin", overwrite=TRUE)
+}
+}
+\author{
+Meik Michalke \email{rkward-devel at kde.org}
+}
+\keyword{misc}
+\keyword{utilities}
diff --git a/rkward/rbackend/rpackages/rkward/man/rkward-package.Rd b/rkward/rbackend/rpackages/rkward/man/rkward-package.Rd
index 32ce866f9..1ac26d448 100644
--- a/rkward/rbackend/rpackages/rkward/man/rkward-package.Rd
+++ b/rkward/rbackend/rpackages/rkward/man/rkward-package.Rd
@@ -14,7 +14,7 @@ The DESCRIPTION file:
Package: \tab rkward\cr
Type: \tab Package\cr
Version: \tab 0.8.0\cr
-Date: \tab 2024-07-11\cr
+Date: \tab 2024-07-18\cr
Depends: \tab R (>= 2.9.0),methods\cr
Encoding: \tab UTF-8\cr
License: \tab GPL (>= 2)\cr
More information about the rkward-tracker
mailing list