Hi @guido167,
Do you mean creating a link to edit via Enketo right ? You can create such link without R
?
Ahmadou
Hi @guido167,
Do you mean creating a link to edit via Enketo right ? You can create such link without R
?
Ahmadou
Yes, I mean the links to each submission form (via Enketo) to edit the input. How would I create these?
Hi @dickoa I was wondering if you were able to reproduce this issue?
Sorry for the delay @guido167, I tried several times on small projects and can’t reproduce it. I’ll love to have more detail and reproduce it. I’ll write to you on dm.
Ahmadou
Hi @dickoa I have sent you a dm to discuss further.
@dickoa unfortunately the above described problem is still persisting.
When I manually download images from the Kobo dashboard (through exporting as zip file) and compare file names with the survey forms these match (uid in file names match with the survey form and photos in the form on the dashboard are the same as the downloaded files). However, when I use the robotoolbox kobo_attachment_download() the file that is downloaded with this file name is completely different. Bottomline: kobo_attachment_download() shuffles media files and does not download the correct media files for the uid’s.
Manually downloading through Kobo export: correct uid/photo combination:
When using kobo_attachment_download(): the same photoname, but a different photo is downloaded!
Unfortunately this would mean I need to change the workflow completely and not rely on robotoolbox… Would you be able to look at this?
An edit of the kobo_attachment_download() and get_attachment_url() functions seemed to have resolved the issue. Attachments are now downloaded and sorted based on uuid to ensure that the correct files are downloaded for each uuid.
get_attachment_url_ <- function(uid) {
path <- paste0("api/v2/assets/", uid, "/data.json")
res <- xget(path = path,
args = list(fields = '["_attachments", "formhub/uuid", "_uuid"]'))
res <- fparse(res, max_simplify_lvl = "data_frame")
res <- res$result
attachment_list <- lapply(1:nrow(res), function(i) {
attachment_df <- res[["_attachments"]][[i]]
attachment_df[["_uuid"]] <- res[["_uuid"]][i]
return(attachment_df)
})
return(attachment_list)
}
kobo_attachment_download2 <- function(uid, folder) {
if (!dir.exists(folder)){
abort(paste(folder, "folder does not exist, create it first!"),
call = NULL)}
attachments <- get_attachment_url_(uid = uid)
bool <- sapply(attachments, is.null)
path <- character()
if (any(!bool)) {
urls <- attachments[!bool] |>
list_rbind() |>
mutate(id = .data$instance,
url = .data$download_url,
fname = basename(.data$filename),
fname_id = paste0(.data$id, "_", .data$fname),
uuid = .data$`_uuid`,
path = file.path(folder, `_uuid`, .data$fname),
.keep = "none") |>
distinct()
headers <- list(Authorization = paste("Token",
Sys.getenv("KOBOTOOLBOX_TOKEN")))
for(i in 1:length(unique(urls$uuid))){
sub <- urls[urls$uuid == unique(urls$uuid)[i],]
if(nrow(sub)>0){
if(dir.exists(file.path(folder, unique(urls$uuid)[i])) == F){
dir.create(file.path(folder, unique(urls$uuid)[i]))
reqs <- lapply(sub$url, function(url) {
req <- HttpRequest$new(url,
headers = headers)
req$retry("get",
times = 3,
retry_only_on = c(500, 502, 503),
terminate_on = 404)
})
res <- AsyncQueue$new(.list = reqs,
bucket_size = Inf,
sleep = 0.05)
res$request()
cond <- res$status_code() >= 300L
if (any(cond)) {
msg <- res$content()[cond]
abort(error_msg(msg[[1]]),
call = NULL)
}
walk2(res$content(), sub$path, \(x, y) writeBin(x, con = y))
}
}
}
}
}