Current section
Files
Jump to
Current section
Files
lib/nf/gravatar/utils.ex
defmodule Nf.Gravatar.Utils do
@moduledoc false
import URI, only: [parse: 1, append_path: 2, append_query: 2]
@type email :: String.t() | nil
@gravatar_url "https://gravatar.com/avatar/"
@w3c_email_regex ~r/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
@doc """
Hashes an email address into a Base16-encoded string.
This function computes a cryptographic hash of the given email address and returns a Base16
(hexadecimal) representation. If the input is invalid, an `ArgumentError` is raised.
"""
@spec hash_email!(String.t()) :: String.t()
def hash_email!(email) do
if Regex.match?(@w3c_email_regex, email) do
user_email = email |> String.trim() |> String.downcase()
:sha256 |> :crypto.hash(user_email) |> Base.encode16(case: :lower)
else
raise ArgumentError, "Invalid email address"
end
end
@doc """
Extracts the image size from display options.
Parses the given display options to determine the image size from 1 to 2048 pixel.
If no valid size is specified, the default 80 pixel value is used.
"""
@spec image_size(Keyword.t()) :: integer()
def image_size(opts) when is_list(opts) do
case Keyword.get(opts, :size, 80) do
nil -> 80
size when size in 1..2048 -> size
end
end
@doc """
Retrieves the default fallback image type from display options.
Parses the given options to determine the fallback image type used when generating a Gravatar URL.
"""
@spec default_fallback(Keyword.t()) :: String.t()
def default_fallback(opts) when is_list(opts) do
case Keyword.get(opts, :fallback, :identicon) do
nil -> "identicon"
:identicon -> "identicon"
:monsterid -> "monsterid"
:wavatar -> "wavatar"
:robohash -> "robohash"
end
end
@doc """
Generates a Gravatar URL for the given email address.
This function constructs a Gravatar URL using a hashed email, specified image size, and a
fallback image type.
"""
@spec generate_gravatar_url(email(), pos_integer(), String.t()) :: String.t()
def generate_gravatar_url(email, image_size, default_fallback) do
hashed_email =
if is_nil(email) do
random_email = "neo_faker_user_#{:rand.uniform(100_000)}@example.com"
hash_email!(random_email)
else
hash_email!(email)
end
@gravatar_url
|> parse()
|> append_path("/#{hashed_email}")
|> append_query("d=#{default_fallback}")
|> append_query("s=#{image_size}")
|> URI.to_string()
end
end