Skip to content

Commit ed6d47f

Browse files
authored
Merge pull request #501 from massimoaria/develop
Develop
2 parents ad79574 + 689999c commit ed6d47f

File tree

4 files changed

+251
-18
lines changed

4 files changed

+251
-18
lines changed

inst/biblioshiny/biblioShot.R

+229
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
# Acknowledgment
2+
# This function is based on the source code of the webshot2 package.
3+
# We would like to acknowledge and express our gratitude to the authors
4+
# and contributors of webshot2 for their valuable work in developing tools
5+
# for web content capture.
6+
#
7+
# In this implementation, we have adapted and modified parts of the original
8+
# webshot2 code to address an issue where PNG files were being generated as
9+
# empty images when used on Windows systems. Our modifications aim to improve
10+
# compatibility and ensure reliable output across different platforms.
11+
#
12+
# Reference:
13+
# webshot2 package: https://github.com/rstudio/webshot2
14+
15+
biblioShot <- function(
16+
url = NULL,
17+
file = "biblioShot.png",
18+
vwidth = 992,
19+
vheight = 744,
20+
selector = NULL,
21+
cliprect = NULL,
22+
expand = NULL,
23+
delay = 0.2,
24+
zoom = 1,
25+
useragent = NULL,
26+
max_concurrent = getOption("biblioShot.concurrent", default = 6),
27+
verbose = FALSE
28+
) {
29+
30+
if (length(url) == 0) {
31+
stop("Need url.")
32+
}
33+
34+
url <- vapply(url,
35+
function(x) {
36+
if (!is_url(x)) {
37+
file_url(x)
38+
} else {
39+
x
40+
}
41+
},
42+
character(1)
43+
)
44+
45+
if (!is.null(cliprect) && !is.list(cliprect)) cliprect <- list(cliprect)
46+
if (!is.null(selector) && !is.list(selector)) selector <- list(selector)
47+
if (!is.null(expand) && !is.list(expand)) expand <- list(expand)
48+
49+
if (is.null(selector)) {
50+
selector <- "html"
51+
}
52+
53+
if (length(url) > 1 && length(file) == 1) {
54+
file <- vapply(1:length(url), FUN.VALUE = character(1), function(i) {
55+
replacement <- sprintf("%03d.\\1", i)
56+
gsub("\\.(.{3,4})$", replacement, file)
57+
})
58+
}
59+
60+
args_all <- list(
61+
url = url,
62+
file = file,
63+
vwidth = vwidth,
64+
vheight = vheight,
65+
selector = selector,
66+
cliprect = cliprect,
67+
expand = expand,
68+
delay = delay,
69+
zoom = zoom,
70+
useragent = useragent,
71+
verbose = verbose
72+
)
73+
74+
n_urls <- length(url)
75+
args_all <- mapply(args_all, names(args_all),
76+
FUN = function(arg, name) {
77+
if (length(arg) == 0) {
78+
return(vector(mode = "list", n_urls))
79+
} else if (length(arg) == 1) {
80+
return(rep(arg, n_urls))
81+
} else if (length(arg) == n_urls) {
82+
return(arg)
83+
} else {
84+
stop("Argument `", name, "` should be NULL, length 1, or same length as `url`.")
85+
}
86+
},
87+
SIMPLIFY = FALSE
88+
)
89+
90+
args_all <- long_to_wide(args_all)
91+
92+
cm <- default_chromote_object()
93+
94+
# A list of promises for the screenshots
95+
res <- lapply(args_all,
96+
function(args) {
97+
new_session_screenshot(cm,
98+
args$url, args$file, args$vwidth, args$vheight, args$selector,
99+
args$cliprect, args$expand, args$delay, args$zoom, args$useragent,
100+
verbose
101+
)
102+
}
103+
)
104+
105+
p <- promises::promise_all(.list = res)
106+
res <- cm$wait_for(p)
107+
res <- structure(unlist(res), class = "webshot")
108+
res
109+
}
110+
111+
112+
new_session_screenshot <- function(
113+
chromote,
114+
url,
115+
file,
116+
vwidth,
117+
vheight,
118+
selector,
119+
cliprect,
120+
expand,
121+
delay,
122+
zoom,
123+
useragent,
124+
verbose = FALSE
125+
) {
126+
127+
filetype <- tolower(tools::file_ext(file))
128+
if (filetype != "png" && filetype != "pdf") {
129+
stop("File extension must be 'png' or 'pdf'")
130+
}
131+
132+
if (is.null(selector)) {
133+
selector <- "html"
134+
}
135+
136+
if (is.character(cliprect)) {
137+
if (cliprect == "viewport") {
138+
cliprect <- c(0, 0, vwidth, vheight)
139+
} else {
140+
stop("Invalid value for cliprect: ", cliprect)
141+
}
142+
} else {
143+
if (!is.null(cliprect) && !(is.numeric(cliprect) && length(cliprect) == 4)) {
144+
stop("`cliprect` must be a vector with four numbers, or a list of such vectors")
145+
}
146+
}
147+
148+
s <- NULL
149+
150+
p <- chromote$new_session(wait_ = FALSE,
151+
width = vwidth,
152+
height = vheight
153+
)$
154+
then(function(session) {
155+
s <<- session
156+
157+
if (!is.null(useragent)) {
158+
s$Network$setUserAgentOverride(userAgent = useragent)
159+
}
160+
res <- s$Page$loadEventFired(wait_ = FALSE)
161+
s$Page$navigate(url, wait_ = FALSE)
162+
res
163+
})$
164+
then(function(value) {
165+
if (delay > 0) {
166+
promises::promise(function(resolve, reject) {
167+
later::later(
168+
function() {
169+
resolve(value)
170+
},
171+
delay
172+
)
173+
})
174+
} else {
175+
value
176+
}
177+
})$
178+
then(function(value) {
179+
if (filetype == "png") {
180+
s$screenshot(
181+
filename = file, selector = selector, cliprect = cliprect,
182+
expand = expand, scale = zoom,
183+
show = FALSE, wait_ = FALSE
184+
)
185+
186+
} else if (filetype == "pdf") {
187+
s$screenshot_pdf(filename = file, wait_ = FALSE)
188+
}
189+
})$
190+
then(function(value) {
191+
if (verbose) message(url, " screenshot completed")
192+
normalizePath(value)
193+
})$
194+
finally(function() {
195+
s$close()
196+
})
197+
198+
p
199+
}
200+
201+
is_url <- function(x) {
202+
grepl("^[a-zA-Z]+://", x)
203+
}
204+
205+
# Given the path to a file, return a file:// URL.
206+
file_url <- function(filename) {
207+
if (is_windows()) {
208+
paste0("file://", normalizePath(filename, mustWork = TRUE))
209+
} else {
210+
enc2utf8(paste0("file:///", normalizePath(filename, winslash = "/", mustWork = TRUE)))
211+
}
212+
}
213+
214+
is_windows <- function() .Platform$OS.type == "windows"
215+
216+
is_mac <- function() Sys.info()[["sysname"]] == "Darwin"
217+
218+
is_linux <- function() Sys.info()[["sysname"]] == "Linux"
219+
220+
long_to_wide <- function(x) {
221+
if (length(x) == 0)
222+
return(x)
223+
224+
lapply(seq_along(x[[1]]), function(n) {
225+
lapply(stats::setNames(names(x), names(x)), function(name) {
226+
x[[name]][[n]]
227+
})
228+
})
229+
}

inst/biblioshiny/libraries.R

+17-17
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,23 @@ libraries <- function(){
2121
if (!require(openxlsx, quietly=TRUE)){install.packages("openxlsx"); require(openxlsx, quietly=TRUE)}
2222
if (!require(shinyWidgets, quietly=TRUE)){install.packages("shinyWidgets"); require(shinyWidgets, quietly=TRUE)}
2323

24-
## Currently "webshot2" 0.1.1 generates empty screenshots on windows 10 for graphics created with visnetwork.
25-
## This workaround installs the previous version 0.1.0 to temporarily fix the problem.
26-
if (!require(webshot2,quietly=TRUE)){
27-
install.packages("webshot2")
28-
library(webshot2)
29-
detach("package:webshot2", unload = TRUE, force=TRUE)
30-
install.packages("https://cran.r-project.org/src/contrib/Archive/webshot2/webshot2_0.1.0.tar.gz",
31-
repos = NULL, type = "source", dependencies=c("Depends", "Imports"))
32-
}else{
33-
pkgs <- installed.packages()[, "Version"]
34-
vers <- pkgs["webshot2"]
35-
if (vers!="0.1.0"){
36-
detach("package:webshot2", unload = TRUE, force=TRUE)
37-
install.packages("https://cran.r-project.org/src/contrib/Archive/webshot2/webshot2_0.1.0.tar.gz",
38-
repos = NULL, type = "source", dependencies=c("Depends", "Imports"))
39-
}
40-
}
24+
# ## Currently "webshot2" 0.1.1 generates empty screenshots on windows 10 for graphics created with visnetwork.
25+
# ## This workaround installs the previous version 0.1.0 to temporarily fix the problem.
26+
# if (!require(webshot2,quietly=TRUE)){
27+
# install.packages("webshot2")
28+
# library(webshot2)
29+
# detach("package:webshot2", unload = TRUE, force=TRUE)
30+
# install.packages("https://cran.r-project.org/src/contrib/Archive/webshot2/webshot2_0.1.0.tar.gz",
31+
# repos = NULL, type = "source", dependencies=c("Depends", "Imports"))
32+
# }else{
33+
# pkgs <- installed.packages()[, "Version"]
34+
# vers <- pkgs["webshot2"]
35+
# if (vers!="0.1.0"){
36+
# detach("package:webshot2", unload = TRUE, force=TRUE)
37+
# install.packages("https://cran.r-project.org/src/contrib/Archive/webshot2/webshot2_0.1.0.tar.gz",
38+
# repos = NULL, type = "source", dependencies=c("Depends", "Imports"))
39+
# }
40+
# }
4141
##
4242

4343
if (!(require(chromote, quietly=TRUE))){install.packages("chromote"); require(chromote, quietly=TRUE)}

inst/biblioshiny/server.R

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
source("utils.R", local=TRUE)
22
source("libraries.R", local=TRUE)
3+
source("biblioShot.R", local=TRUE)
4+
35
suppressMessages(libraries())
46

57
#### SERVER ####
@@ -42,6 +44,8 @@ To ensure the functionality of Biblioshiny,
4244
footer = modalButton("Dismiss"),
4345
easyClose = TRUE
4446
))
47+
} else {
48+
Sys.setenv (CHROMOTE_CHROME = Chrome_url)
4549
}
4650

4751
## file upload max size

inst/biblioshiny/utils.R

+1-1
Original file line numberDiff line numberDiff line change
@@ -2231,7 +2231,7 @@ plot2png <- function(p, filename, zoom = 2, type="vis", tmpdir){
22312231
plotly={
22322232
htmlwidgets::saveWidget(p, file=html_name)
22332233
})
2234-
webshot2::webshot(url = html_name, zoom = zoom, file = filename)#, verbose=FALSE)
2234+
biblioShot(url = html_name, zoom = zoom, file = filename)#, verbose=FALSE)
22352235

22362236
popUpGeneric(title=NULL, type="success", color=c("#1d8fe1"),
22372237
subtitle=paste0("Plot was saved in the following path: ",filename),

0 commit comments

Comments
 (0)