R/cmip-needs-download.R

Defines functions checksum_matches info_add_needs_download cmip_add_needs_download

cmip_add_needs_download <- function(results,
                                    root = cmip_root_get(),
                                    year_range = c(-Inf, Inf)) {
  if (is.null(results$info)) {
    infos <- cmip_add_info(results)$info
  } else {
    infos <- results$info
  }

  infos <- furrr::future_map(infos, info_add_needs_download,
                             root = root,
                             year_range = year_range)

  results$info <- infos
  return(results)
}

# Adds to columns to the info dataframe of each request.
# is_requested: whether the user requested that file (currently depends only
# on the date range)
# needs_download: whether the file needs to be downloaed.
info_add_needs_download <- function(info,
                                    root = cmip_root_get(),
                                    year_range = c(-Inf, Inf)) {
  overlaps <- year_range_overlaps(info$title, year_range = year_range)
  file <- file.path(result_dir(info, root = root), info$title)
  exists <- file.exists(file)

  matches_checksum <- vapply(seq_along(info$title), function(i) {
    if (overlaps[i] && exists[i]) {  # Only check if necessary.
      matches <- checksum_matches(file[i],
                                  checksum_type = tolower(info$checksum_type[[i]]),
                                  checksum = info$checksum[[i]])
      if (isTRUE(matches)) {
        message(tr_("Skipping %s (matching checksum).", file[i]))
      }
      return(matches)
    } else {
      return(FALSE)
    }
  }, logical(1))

  info$is_requested <- overlaps
  info$needs_download <- overlaps & !matches_checksum
  info
}


checksum_matches <- function(file, checksum_type, checksum) {
  checksum_file <- paste0(file, ".chksum")

  if (!file.exists(file)) {
    return(FALSE)
  }

  if (file.exists(checksum_file)) {
    local_checksum <- readLines(checksum_file)
  } else {
    local_checksum <- digest::digest(file = file, algo = tolower(checksum_type))
    writeLines(text = local_checksum, con = checksum_file)
  }

  return(local_checksum == checksum)
}
eliocamp/rcmip6 documentation built on Feb. 8, 2025, 4:26 p.m.