Service for downloading images from external URLs and storing them in the Storage module.
Handles HTTP download with proper error handling, content type detection, and integration with PhoenixKit.Modules.Storage for persistent storage.
Usage
# Download and store a single image
{:ok, file_uuid} = ImageDownloader.download_and_store(url, user_uuid)
# Download with options
{:ok, file_uuid} = ImageDownloader.download_and_store(url, user_uuid, timeout: 30_000)
# Batch download multiple images
results = ImageDownloader.download_batch(urls, user_uuid)
# => [{url, {:ok, file_uuid}}, {url, {:error, reason}}, ...]
Summary
Functions
Downloads an image from a URL and stores it in the Storage module.
Downloads and stores multiple images in batch.
Downloads an image from a URL to a temporary file.
Checks if a URL points to a valid image that can be downloaded.
Validates URLs are accessible before batch download.
Functions
@spec download_and_store(String.t(), String.t() | nil, keyword()) :: {:ok, String.t()} | {:error, atom() | String.t()}
Downloads an image from a URL and stores it in the Storage module.
Returns {:ok, file_uuid} where file_uuid is a UUID that can be used to reference
the stored file.
Options
:timeout- HTTP request timeout in milliseconds (default: 30_000):metadata- Additional metadata to store with the file
Examples
iex> download_and_store("https://cdn.shopify.com/image.jpg", user_uuid)
{:ok, "018f1234-5678-7890-abcd-ef1234567890"}
iex> download_and_store("https://example.com/404.jpg", user_uuid)
{:error, :not_found}
@spec download_batch([String.t()], String.t() | nil, keyword()) :: [ {String.t(), {:ok, String.t()} | {:error, atom() | String.t()}} ]
Downloads and stores multiple images in batch.
Returns a list of tuples {url, result} where result is either
{:ok, file_uuid} or {:error, reason}.
Options
:timeout- HTTP request timeout for each image (default: 30_000):concurrency- Number of concurrent downloads (default: 5):on_progress- Callback function called after each download:fn(url, result, index, total) -> :ok end
Examples
iex> download_batch(["url1", "url2", "url3"], user_uuid)
[{"url1", {:ok, "uuid-1"}}, {"url2", {:ok, "uuid-2"}}, {"url3", {:error, :timeout}}]
@spec download_image( String.t(), keyword() ) :: {:ok, String.t(), String.t(), non_neg_integer()} | {:error, atom() | String.t()}
Downloads an image from a URL to a temporary file.
Returns {:ok, temp_path, content_type, size} on success.
Options
:timeout- HTTP request timeout in milliseconds (default: 30_000)
Examples
iex> download_image("https://example.com/image.jpg")
{:ok, "/tmp/phx_img_abc123", "image/jpeg", 12345}
iex> download_image("https://example.com/404.jpg")
{:error, :not_found}
Checks if a URL points to a valid image that can be downloaded.
Performs a HEAD request to verify the URL is accessible and returns an image content type.
Examples
iex> valid_image_url?("https://example.com/image.jpg")
true
iex> valid_image_url?("https://example.com/document.pdf")
false
Validates URLs are accessible before batch download.
Performs HEAD requests to verify URLs are accessible and return valid
image content types. Returns a tuple of {valid_urls, invalid_urls}.
Options
:timeout- HTTP request timeout in milliseconds (default: 5_000):concurrency- Number of concurrent validations (default: 10)
Examples
iex> validate_urls(["https://example.com/image.jpg", "https://example.com/404.jpg"])
{["https://example.com/image.jpg"], ["https://example.com/404.jpg"]}