272 lines
9.7 KiB
R
272 lines
9.7 KiB
R
# ==============================================================================
|
|
# DEBUG_REMOVE_DATE_TIFFS.R
|
|
# ==============================================================================
|
|
# PURPOSE:
|
|
# Remove all TIFFs of a specific date from multiple storage folders.
|
|
# Useful for debugging/re-running parts of the pipeline without full re-download.
|
|
#
|
|
# USAGE:
|
|
# Rscript DEBUG_remove_date_tiffs.R [project] [date] [--dry-run] [--skip-merged] [--skip-field-tiles] [--skip-field-tiles-ci] [--skip-daily-vals]
|
|
#
|
|
# EXAMPLES:
|
|
# # Remove 2026-02-08 from all folders (WITH CONFIRMATION)
|
|
# Rscript DEBUG_remove_date_tiffs.R angata 2026-02-08
|
|
#
|
|
# # Remove from all folders without confirmation
|
|
# Rscript DEBUG_remove_date_tiffs.R angata 2026-02-08 --no-confirm
|
|
#
|
|
# # Dry run - show what WOULD be deleted without deleting
|
|
# Rscript DEBUG_remove_date_tiffs.R angata 2026-02-08 --dry-run
|
|
#
|
|
# # Remove only from merged_tif and field_tiles, skip CI folders
|
|
# Rscript DEBUG_remove_date_tiffs.R angata 2026-02-08 --skip-field-tiles-ci --skip-daily-vals
|
|
#
|
|
# # Remove from field_tiles_CI only
|
|
# Rscript DEBUG_remove_date_tiffs.R angata 2026-02-08 --skip-merged --skip-field-tiles --skip-daily-vals
|
|
#
|
|
# ==============================================================================
|
|
|
|
# ==============================================================================
|
|
# CONFIGURATION - TOGGLE WHICH FOLDERS TO DELETE FROM (DEFAULT: ALL)
|
|
# ==============================================================================
|
|
|
|
# Set these to FALSE to skip deletion from that folder
|
|
DELETE_FROM_MERGED_TIF <- TRUE
|
|
DELETE_FROM_FIELD_TILES <- TRUE
|
|
DELETE_FROM_FIELD_TILES_CI <- TRUE
|
|
DELETE_FROM_DAILY_VALS <- TRUE
|
|
|
|
# Safety settings
|
|
DRY_RUN <- FALSE # Set to TRUE to preview deletions without actually deleting
|
|
REQUIRE_CONFIRMATION <- TRUE # Set to FALSE to delete without asking
|
|
|
|
# ==============================================================================
|
|
# MAIN FUNCTION
|
|
# ==============================================================================
|
|
|
|
main <- function() {
|
|
# Parse command-line arguments
|
|
args <- commandArgs(trailingOnly = TRUE)
|
|
|
|
# Validate minimum arguments
|
|
if (length(args) < 2) {
|
|
cat("\n[ERROR] Missing arguments\n")
|
|
cat("Usage: Rscript DEBUG_remove_date_tiffs.R [project] [date] [options]\n\n")
|
|
cat("Examples:\n")
|
|
cat(" Rscript DEBUG_remove_date_tiffs.R angata 2026-02-08\n")
|
|
cat(" Rscript DEBUG_remove_date_tiffs.R angata 2026-02-08 --dry-run\n")
|
|
cat(" Rscript DEBUG_remove_date_tiffs.R angata 2026-02-08 --skip-field-tiles-ci\n\n")
|
|
cat("Options:\n")
|
|
cat(" --dry-run Preview deletions without actually deleting\n")
|
|
cat(" --no-confirm Delete without confirmation\n")
|
|
cat(" --skip-merged Skip merged_tif folder\n")
|
|
cat(" --skip-field-tiles Skip field_tiles folder\n")
|
|
cat(" --skip-field-tiles-ci Skip field_tiles_CI folder\n")
|
|
cat(" --skip-daily-vals Skip daily_vals folder\n\n")
|
|
quit(status = 1)
|
|
}
|
|
|
|
# Parse positional arguments
|
|
project <- args[1]
|
|
date_str <- args[2]
|
|
|
|
# Parse optional flags
|
|
if (length(args) >= 3) {
|
|
for (i in 3:length(args)) {
|
|
arg <- args[i]
|
|
|
|
# Skip NA or empty arguments
|
|
if (is.na(arg) || nchar(arg) == 0) {
|
|
next
|
|
}
|
|
|
|
if (arg == "--dry-run") {
|
|
DRY_RUN <<- TRUE
|
|
} else if (arg == "--no-confirm") {
|
|
REQUIRE_CONFIRMATION <<- FALSE
|
|
} else if (arg == "--skip-merged") {
|
|
DELETE_FROM_MERGED_TIF <<- FALSE
|
|
} else if (arg == "--skip-field-tiles") {
|
|
DELETE_FROM_FIELD_TILES <<- FALSE
|
|
} else if (arg == "--skip-field-tiles-ci") {
|
|
DELETE_FROM_FIELD_TILES_CI <<- FALSE
|
|
} else if (arg == "--skip-daily-vals") {
|
|
DELETE_FROM_DAILY_VALS <<- FALSE
|
|
}
|
|
}
|
|
}
|
|
|
|
# Validate date format
|
|
date_obj <- tryCatch(
|
|
as.Date(date_str, format = "%Y-%m-%d"),
|
|
error = function(e) NULL
|
|
)
|
|
|
|
if (is.null(date_obj) || is.na(date_obj)) {
|
|
cat(sprintf("[ERROR] Invalid date format: %s (expected YYYY-MM-DD)\n", date_str))
|
|
quit(status = 1)
|
|
}
|
|
# ===========================================================================
|
|
# BUILD LIST OF FOLDERS & FILES TO DELETE
|
|
# ===========================================================================
|
|
|
|
base_path <- file.path("laravel_app", "storage", "app", project)
|
|
|
|
files_to_delete <- list()
|
|
|
|
# FOLDER 1: merged_tif/{DATE}.tif
|
|
if (DELETE_FROM_MERGED_TIF) {
|
|
merged_tif_file <- file.path(base_path, "merged_tif", paste0(date_str, ".tif"))
|
|
if (file.exists(merged_tif_file)) {
|
|
files_to_delete[["merged_tif"]] <- merged_tif_file
|
|
}
|
|
}
|
|
|
|
# FOLDER 2: field_tiles/{FIELD}/{DATE}.tif (per-field structure)
|
|
if (DELETE_FROM_FIELD_TILES) {
|
|
field_tiles_dir <- file.path(base_path, "field_tiles")
|
|
if (dir.exists(field_tiles_dir)) {
|
|
field_dirs <- list.dirs(field_tiles_dir, full.names = TRUE, recursive = FALSE)
|
|
for (field_dir in field_dirs) {
|
|
tif_file <- file.path(field_dir, paste0(date_str, ".tif"))
|
|
if (file.exists(tif_file)) {
|
|
folder_name <- basename(field_dir)
|
|
key <- paste0("field_tiles/", folder_name)
|
|
files_to_delete[[key]] <- tif_file
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# FOLDER 3: field_tiles_CI/{FIELD}/{DATE}.tif (per-field structure)
|
|
if (DELETE_FROM_FIELD_TILES_CI) {
|
|
field_tiles_ci_dir <- file.path(base_path, "field_tiles_CI")
|
|
if (dir.exists(field_tiles_ci_dir)) {
|
|
field_dirs <- list.dirs(field_tiles_ci_dir, full.names = TRUE, recursive = FALSE)
|
|
for (field_dir in field_dirs) {
|
|
tif_file <- file.path(field_dir, paste0(date_str, ".tif"))
|
|
if (file.exists(tif_file)) {
|
|
folder_name <- basename(field_dir)
|
|
key <- paste0("field_tiles_CI/", folder_name)
|
|
files_to_delete[[key]] <- tif_file
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# FOLDER 4: Data/extracted_ci/daily_vals/{SUBDIR}/{DATE}.rds (per-subdirectory structure)
|
|
if (DELETE_FROM_DAILY_VALS) {
|
|
daily_vals_dir <- file.path(base_path, "Data", "extracted_ci", "daily_vals")
|
|
if (dir.exists(daily_vals_dir)) {
|
|
subdirs <- list.dirs(daily_vals_dir, full.names = TRUE, recursive = FALSE)
|
|
for (subdir in subdirs) {
|
|
rds_file <- file.path(subdir, paste0(date_str, ".rds"))
|
|
if (file.exists(rds_file)) {
|
|
subdir_name <- basename(subdir)
|
|
key <- paste0("daily_vals/", subdir_name)
|
|
files_to_delete[[key]] <- rds_file
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# ===========================================================================
|
|
# SUMMARY & CONFIRMATION
|
|
# ===========================================================================
|
|
|
|
cat("\n")
|
|
cat(strrep("=", 70), "\n")
|
|
cat("DELETE DATE TIFFS - SUMMARY\n")
|
|
cat(strrep("=", 70), "\n")
|
|
cat(sprintf("Project: %s\n", project))
|
|
cat(sprintf("Date: %s\n", date_str))
|
|
cat(sprintf("Dry run: %s\n", if (DRY_RUN) "YES" else "NO"))
|
|
cat(sprintf("Files to delete: %d\n", length(files_to_delete)))
|
|
cat("\n")
|
|
|
|
if (length(files_to_delete) == 0) {
|
|
cat("[INFO] No files found to delete\n")
|
|
cat(strrep("=", 70), "\n\n")
|
|
quit(status = 0)
|
|
}
|
|
|
|
# Count files by folder type for compact summary
|
|
folder_counts <- table(sapply(names(files_to_delete), function(key) strsplit(key, "/")[[1]][1]))
|
|
cat("Files to delete by folder:\n")
|
|
for (folder in names(folder_counts)) {
|
|
cat(sprintf(" %s: %d file%s\n", folder, folder_counts[folder], if (folder_counts[folder] != 1) "s" else ""))
|
|
}
|
|
cat(sprintf(" Total: %d file%s\n", length(files_to_delete), if (length(files_to_delete) != 1) "s" else ""))
|
|
cat("\n")
|
|
|
|
# Ask for confirmation (unless --no-confirm flag was used)
|
|
if (REQUIRE_CONFIRMATION && !DRY_RUN) {
|
|
# Check if running in interactive mode
|
|
if (!interactive()) {
|
|
cat("\n[ERROR] Non-interactive mode detected (running via Rscript)\n")
|
|
cat("Cannot prompt for confirmation. Use --no-confirm flag to proceed:\n")
|
|
cat(" Rscript DEBUG_remove_date_tiffs.R angata 2026-02-08 --no-confirm\n\n")
|
|
cat(strrep("=", 70), "\n\n")
|
|
quit(status = 1)
|
|
}
|
|
|
|
cat("⚠️ This will PERMANENTLY DELETE the above files!\n")
|
|
cat("Use --no-confirm flag to skip this prompt\n")
|
|
|
|
# Use readline() for interactive input (only works in interactive R/RStudio)
|
|
response <- readline(prompt = "Type 'yes' to confirm, or anything else to cancel: ")
|
|
|
|
if (tolower(response) != "yes") {
|
|
cat("[CANCELLED] No files deleted\n")
|
|
cat(strrep("=", 70), "\n\n")
|
|
quit(status = 0)
|
|
}
|
|
}
|
|
|
|
# ===========================================================================
|
|
# DELETE OR DRY-RUN
|
|
# ===========================================================================
|
|
|
|
deleted_count <- 0
|
|
error_count <- 0
|
|
|
|
for (i in seq_along(files_to_delete)) {
|
|
folder_key <- names(files_to_delete)[i]
|
|
file_path <- files_to_delete[[i]]
|
|
|
|
if (!DRY_RUN) {
|
|
tryCatch({
|
|
file.remove(file_path)
|
|
deleted_count <- deleted_count + 1
|
|
}, error = function(e) {
|
|
error_count <<- error_count + 1
|
|
})
|
|
}
|
|
}
|
|
|
|
# ===========================================================================
|
|
# FINAL SUMMARY
|
|
# ===========================================================================
|
|
|
|
cat("\n")
|
|
if (DRY_RUN) {
|
|
cat(sprintf("[DRY RUN] Would have deleted %d files\n", length(files_to_delete)))
|
|
} else {
|
|
cat(sprintf("Deleted: %d files\n", deleted_count))
|
|
if (error_count > 0) {
|
|
cat(sprintf("Errors: %d files\n", error_count))
|
|
}
|
|
}
|
|
cat(strrep("=", 70), "\n\n")
|
|
|
|
quit(status = 0)
|
|
}
|
|
|
|
# ==============================================================================
|
|
# EXECUTE
|
|
# ==============================================================================
|
|
|
|
if (sys.nframe() == 0) {
|
|
main()
|
|
}
|