Current section
Files
Jump to
Current section
Files
lib/oembed_providers.ex
defmodule OEmbedProviders do
@moduledoc """
Build OEmbed URLs with a list of providers.
"""
alias OEmbedProviders.Provider
@providers_file Application.app_dir(:oembed_providers) |> Path.join("priv/providers.json")
@providers Application.get_env(:oembed_providers, :providers_file, @providers_file)
|> File.read!()
|> Jason.decode!()
|> Enum.map(&Provider.from_map/1)
@doc """
Get a list of available providers.
```elixir
iex(1)> OEmbedProviders.list_providers()
[
%OEmbedProviders.Provider{
endpoints: [
%OEmbedProviders.Provider.Endpoint{
discovery: nil,
formats: [],
schemes: ["http://www.23hq.com/*/photo/*"],
url: "http://www.23hq.com/23/oembed"
}
],
provider_name: "23HQ",
provider_url: "http://www.23hq.com"
},
%OEmbedProviders.Provider{...},
%OEmbedProviders.Provider{...},
%OEmbedProviders.Provider{...},
...
]
```
"""
@spec list_providers() :: [Provider.t()]
def list_providers(), do: @providers
@doc """
Get the `OEmbedProviders.Provider` for a URL.
```elixir
iex(2)> OEmbedProviders.find_provider("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
%OEmbedProviders.Provider{
endpoints: [
%OEmbedProviders.Provider.Endpoint{
discovery: true,
formats: [],
schemes: ["https://*.youtube.com/watch*", "https://*.youtube.com/v/*",
"https://youtu.be/*"],
url: "https://www.youtube.com/oembed"
}
],
provider_name: "YouTube",
provider_url: "https://www.youtube.com/"
}
```
"""
@spec find_provider(url :: String.t()) :: Provider.t()
def find_provider(url) do
Enum.find(list_providers(), &Provider.matches?(&1, url))
end
@doc """
Construct the OEmbed endpoint URL for the given URL.
```elixir
iex(1)> OEmbedProviders.oembed_url("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
{:ok,
"https://www.youtube.com/oembed?format=json&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DdQw4w9WgXcQ"}
iex(2)> OEmbedProviders.oembed_url("https://gleasonator.com/@alex")
{:error, :no_provider}
```
"""
@spec oembed_url(url :: String.t()) :: {:ok, String.t()} | {:error, any()}
def oembed_url(url) do
with %Provider{} = provider <- find_provider(url),
{:ok, oembed_url} <- Provider.oembed_url(provider, url) do
{:ok, oembed_url}
else
{:error, error} -> {:error, error}
nil -> {:error, :no_provider}
error -> {:error, error}
end
end
end