Sys.getenv("ART_BUCKETS_KEY_ID") # must be non-empty
Sys.getenv("ART_BUCKETS_KEY_SECRET") # must be non-emptyA hands-on walkthrough of every major operation in artcdn.
Setup
Ensure CDN credentials are set:
Upload a Single File
library(artcdn)
tmp <- tempfile(fileext = ".txt")
writeLines("hello artcdn", tmp)
cdn_upload("art-testing", "quickstart/demo.txt", tmp)
#> SUCCESS art-testing Uploaded => quickstart/demo.txtBy default, overwriting is blocked:
cdn_upload("art-testing", "quickstart/demo.txt", tmp)
#> Error: Object already exists: quickstart/demo.txt. Set overwrite = TRUE to replace.
cdn_upload("art-testing", "quickstart/demo.txt", tmp, overwrite = TRUE)
#> SUCCESS art-testing Uploaded => quickstart/demo.txtCheck Existence
cdn_has_object("art-testing", "quickstart/demo.txt")
#> [1] TRUE
cdn_has_object("art-testing", "quickstart/missing.txt")
#> [1] FALSE
cdn_has_prefix("art-testing", "quickstart")
#> [1] TRUEGenerate URLs
Public buckets return plain URLs. Private buckets are presigned automatically:
# Public bucket: unsigned URL
cdn_url("art-public", "thumbnails/artist/artwork.jpeg")
#> [1] "https://sfo3.digitaloceanspaces.com/art-public/thumbnails/artist/artwork.jpeg"
# Private bucket: presigned URL (1h expiry)
cdn_url("art-data", "processed/uuid-a/uuid-b/img.png")
#> [1] "https://sfo3.digitaloceanspaces.com/art-data/processed/...?X-Amz-Signature=..."List and Count
cdn_list_keys("art-testing", "quickstart")
#> [1] "quickstart/demo.txt"
cdn_count_keys("art-testing", "quickstart")
#> [1] 1Upload a Directory
dir <- tempfile("artdir_")
dir.create(dir)
writeLines("file a", file.path(dir, "a.txt"))
dir.create(file.path(dir, "sub"))
writeLines("file b", file.path(dir, "sub", "b.txt"))
cdn_upload_dir("art-testing", "quickstart/batch/", dir)
#> SUCCESS art-testing Uploaded => quickstart/batch/a.txt
#> SUCCESS art-testing Uploaded => quickstart/batch/sub/b.txt
cdn_list_keys("art-testing", "quickstart/batch")
#> [1] "quickstart/batch/a.txt" "quickstart/batch/sub/b.txt"Delete
# Single object
cdn_delete("art-testing", "quickstart/demo.txt")
# Directory (must be empty or use recursive)
cdn_delete_prefix("art-testing", "quickstart/batch", recursive = TRUE)
#> Deleted 2 objects under 'quickstart/batch/'Platform Write Helpers
These are purpose-built for the four platform buckets. They validate UUIDs, construct canonical key paths, and handle both single files and directories.
Upload Artwork Assets
artist <- "88000000-0000-0000-0000-000000000001"
artwork <- artcore::gen_artwork_id()
# Original files to art-vault
bundle_dir <- "path/to/bundle/"
write_art_vault(artist, artwork, bundle_dir)
#> SUCCESS art-vault Vault upload complete: 5 objects
# Processed files to art-data
write_art_data(artist, artwork, "path/to/processed/")
#> SUCCESS art-data Upload complete: 150 objects
# Artwork thumbnail to art-public
write_art_public(artist, artwork, "path/to/thumb.jpeg")
#> SUCCESS art-public thumbnails/88xxx.../99xxx....jpeg
# Certificate to art-coa
write_art_coa(artist, artwork, "path/to/certificate.pdf")
#> SUCCESS write_art_coa art-coa - issued/88xxx.../99xxx.../certificate.pdfVerify Uploads
cdn_has_prefix("art-vault", paste0("uploads/", artist, "/", artwork))
#> [1] TRUE
cdn_list_keys("art-data", paste0("processed/", artist, "/", artwork))
#> [1] "processed/88xxx.../99xxx.../frame_0001.png"
#> [2] "processed/88xxx.../99xxx.../frame_0002.png"
#> ...Soft Delete (Recommended for Artwork Removal)
Moves all artwork assets across all four platform buckets to _deleted- prefixes. Preserves files for recovery while hiding them from normal operations.
# Preview with dry run
cdn_soft_delete(artist, artwork, dry_run = TRUE)
#> DRY RUN => [art-vault] prefix 'uploads/88xxx.../99xxx../'=>'uploads/88xxx.../_deleted-99xxx.../'
#> DRY RUN => [art-data] prefix 'processed/88xxx.../99xxx../'=>'processed/88xxx.../_deleted-99xxx.../'
#> DRY RUN => [art-coa] prefix 'issued/88xxx.../99xxx../'=>'issued/88xxx.../_deleted-99xxx.../'
#> DRY RUN => [art-public] key '...' => '..._deleted-...'
# Execute
cdn_soft_delete(artist, artwork)
#> SUCCESS art-vault Moved 5 objects to 'uploads/88xxx.../_deleted-99xxx.../'
#> SUCCESS art-data Moved 150 objects to 'processed/88xxx.../_deleted-99xxx.../'
#> SUCCESS art-coa Moved 2 objects to 'issued/88xxx.../_deleted-99xxx.../'
#> SUCCESS art-public Moved thumbnail to thumbnails/88xxx.../_deleted-99xxx....jpegError Handling
All operations follow fail-fast principles:
# Missing credentials
cdn_upload("art-testing", "key", "file.txt")
#> Error: ART_BUCKETS_KEY_ID and/or ART_BUCKETS_KEY_SECRET are not set.
# Unknown bucket
cdn_upload("typo-bucket", "key", "file.txt")
#> Error: Unknown bucket 'typo-bucket'. Registered buckets: ...
# Invalid UUID
write_art_vault("not-a-uuid", artwork, "bundle/")
#> Error: Invalid Artist UUID
# Overwrite protection
write_art_vault(artist, artwork, "bundle/")
#> Error: Vault prefix already exists: uploads/88xxx.../99xxx.../